如何使用C/gcc从外设IO寄存器读取?

Rob*_*ugs 6 gcc avr volatile isr

我在AVR32上有一个中断服务路由.我需要从中断状态寄存器中读取以取消中断.但是我没有使用读取的结果.我宁愿不使用asm指令,但我担心gcc会将读取优化为虚拟变量.什么是正确的方法?

目前我有:

uint32_t tmp = *(volatile uint32_t *)INTERRUPT_STATUS_REG_ADDRESS;
Run Code Online (Sandbox Code Playgroud)

tmp也应该波动吗?我担心如果没有使用tmp,gcc会跳过读取.

dbr*_*nk0 6

通过指针转换到(volatile uint32_t*)读取中断状态寄存器告诉编译器读取此表达式(指定地址处的变量)会产生副作用,因此它总是需要计算此表达式.

由于您的tmp变量不是易失性的,编译器可以自由地优化将寄存器的值存储到变量中.

我认为C标准的第5.1.2.3章(见这里)足够相关.

另外第6.7.3章解释了:

具有volatile限定类型的对象可能以实现未知的方式进行修改,或者具有其他未知的副作用.因此,任何涉及这种对象的表达都应严格按照抽象机的规则进行评估,如5.1.2.3所述.此外,在每个序列点,最后存储在对象中的值应与抽象机器规定的值一致,除非由前面提到的未知因素修改.116)什么构成对具有volatile限定类型的对象的访问是实现定义的.

你实际上可以省略tmp并且只写:

*(volatile uint32_t *)INTERRUPT_STATUS_REG_ADDRESS;
Run Code Online (Sandbox Code Playgroud)

这将只读取位于INTERRUPT_STATUS_REG_ADDRESS的uint32_t寄存器;