我一直在写代码与SAMV71Q20B上的硬件寄存器接口。所讨论的函数是:
// Reads current MII link busy status
u32 mii_is_busy(void)
{
return !GMAC->GMAC_NSR.bit.IDLE;
}
Compiled to Assembly
4B03 ldr r3, =0x40050000
6898 ldr r0, [r3, #8]
F3C00080 ubfx r0, r0, #2, #1
F0800001 eor r0, r0, #1
4770 bx lr
BF00 nop
40050000 .word 0x40050000
Inline version 1
4A05 ldr r2, =0x40050000
6891 ldr r1, [r2, #8]
0749 lsls r1, r1, #29
D1FA bne 0x0042392C
Inline verison 2
4A08 ldr r2, =0x40050000
6890 ldr r0, [r2, #8]
0740 lsls r0, r0, #29
D507 bpl 0x0042399C
字符串
如果我把它改成
// Reads current MII link busy status
u32 __attribute__ ((noinline)) mii_is_busy(void)
{
return !GMAC->GMAC_NSR.bit.IDLE;
}
型
那么它工作正常,程序集是一样的,但是没有内联版本
我们注意到这一点是因为该函数曾经是:
// Reads current MII link busy status
u32 mii_is_busy(void)
{
return !(GMAC->GMAC_NSR.reg & GMAC_NSR_IDLE);
}
Compiled to Assembly
4B03 ldr r3, =0x40050000
6898 ldr r0, [r3, #8]
F0800004 eor r0, r0, #4
F3C00080 ubfx r0, r0, #2, #1
4770 bx lr
BF00 nop
40050000 .word 0x40050000
型
不管是什么原因,它没有被内联,而且工作正常
我所说的工作正常是指我们的整个以太网堆栈对ping有响应,但是做这个小的改变会导致以太网不再工作。
我使用的寄存器的定义来自芯片的CMSIS头。下面是相关的片段
/* -------- GMAC_NSR : (GMAC Offset: 0x08) (R/ 32) Network Status Register -------- */
#if !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__))
#if COMPONENT_TYPEDEF_STYLE == 'N'
typedef union {
struct {
uint32_t :1; /**< bit: 0 Reserved */
uint32_t MDIO:1; /**< bit: 1 MDIO Input Status */
uint32_t IDLE:1; /**< bit: 2 PHY Management Logic Idle */
uint32_t :4; /**< bit: 3..6 Reserved */
uint32_t RXLPIS:1; /**< bit: 7 LPI Indication */
uint32_t :24; /**< bit: 8..31 Reserved */
} bit; /**< Structure used for bit access */
uint32_t reg; /**< Type used for register access */
} GMAC_NSR_Type;
#endif
#endif /* !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */
#define GMAC_NSR_OFFSET (0x08) /**< (GMAC_NSR) Network Status Register Offset */
#define GMAC_NSR_MDIO_Pos 1 /**< (GMAC_NSR) MDIO Input Status Position */
#define GMAC_NSR_MDIO_Msk (_U_(0x1) << GMAC_NSR_MDIO_Pos) /**< (GMAC_NSR) MDIO Input Status Mask */
#define GMAC_NSR_MDIO GMAC_NSR_MDIO_Msk /**< \deprecated Old style mask definition for 1 bit bitfield. Use GMAC_NSR_MDIO_Msk instead */
#define GMAC_NSR_IDLE_Pos 2 /**< (GMAC_NSR) PHY Management Logic Idle Position */
#define GMAC_NSR_IDLE_Msk (_U_(0x1) << GMAC_NSR_IDLE_Pos) /**< (GMAC_NSR) PHY Management Logic Idle Mask */
#define GMAC_NSR_IDLE GMAC_NSR_IDLE_Msk /**< \deprecated Old style mask definition for 1 bit bitfield. Use GMAC_NSR_IDLE_Msk instead */
#define GMAC_NSR_RXLPIS_Pos 7 /**< (GMAC_NSR) LPI Indication Position */
#define GMAC_NSR_RXLPIS_Msk (_U_(0x1) << GMAC_NSR_RXLPIS_Pos) /**< (GMAC_NSR) LPI Indication Mask */
#define GMAC_NSR_RXLPIS GMAC_NSR_RXLPIS_Msk /**< \deprecated Old style mask definition for 1 bit bitfield. Use GMAC_NSR_RXLPIS_Msk instead */
#define GMAC_NSR_MASK _U_(0x86) /**< \deprecated (GMAC_NSR) Register MASK (Use GMAC_NSR_Msk instead) */
#define GMAC_NSR_Msk _U_(0x86) /**< (GMAC_NSR) Register Mask */
型
我的问题是,我的编译器检查出来了吗,比如它产生了正确的汇编代码吗?因为如果是这样的话,我假设这一定是硬件中的一些微妙之处导致了这一点。我可以只使用我所介绍的两个工作版本中的一个,但我不喜欢在不理解为什么一个工作而另一个不工作的情况下这样做。
1条答案
按热度按时间vd8tlhqk1#
我想通了,一点也不像寻求帮助,几分钟后就发现了问题。
我的同事写了这段代码:
字符串
因此,内联版本的失败是由于执行时间过快,导致循环耗尽迭代。