我们继承了我一直在关注的针对瑞萨 RX231 微控制器的项目。
这个 uC 只有一条指令可以锁定总线原子性 (XCHG)。
因为处理器是访问 RAM 内存的唯一组件(不使用 DMA 或 DTC),所以要操作与中断共享的用户代码中的变量,在访问时间内禁用中断(在处理器状态字寄存器中),即
disable_interrupts(); /* set_psw(get_psw() & ~(1 << 16)); */
/* access or modify shared variables */
enable_interrupts(); /* set_psw(get_psw() | (1 << 16)); */
但是,也有一些“标志”在没有保护的情况下被共享,它们在中断中设置并在用户代码中通过以下方式轮询:
volatile unsigned char event_request_message = 0;
unsigned char condition_sending_message = 0;
#pragma interrupt
void on_request_message()
{
...
event_request_message = 1; // mov.l #0x3df5, r14
// mov.b #1, [r14]
...
}
void user_code()
{
for(;;)
{
...
/* might be evaluated multiple times before transmit message is completed */
if(event_request_message && !condition_sending_message) // mov.l #0x3df5, r14
// movu.b [r14], r14
// cmp #0, r14
// beq.b 0xfff8e17b <user_code+185>
// mov.l #0x5990, r14
// movu.b [r14], r14
// cmp #0, r14
// bne.b 0xfff8e16f <user_code+173>
{
event_request_message = 0; // mov.l #0x3df5, r14
// mov.b #0, [r14]
condition_sending_message = 1; // mov.l #0x5990, r14
// mov.b #1, [r14]
/* transmit message */
...
}
...
}
}
在这种情况下,我对无保护(通过禁用用户代码中的中断)的理解是:
- 要读取、设置或清除“标志”,总是使用两条指令,一条将内存地址放入寄存器,一条用于读取/设置/清除
- 内存地址始终相同,因此可以不考虑
- 然后每个读取/设置/清除操作都是一条指令,因此访问/操作是原子的
问题是:我的理解正确吗?在这种情况下,这样的“标志”变量访问和操作是否安全?
或者可能有任何可能的错误/错误?
- 假设使用的编译器和编译器选项始终相同。
- 假设所描述的操作是访问/操作此类“标志”的唯一方式(设置为 0 或 1,读取(全部以汇编代码显示))(无加法、乘法等)
如果我们需要升级编译器或更改编译器选项怎么办?
如此简单的操作会导致不止“一条指令”吗?
在没有保护的情况下使用此类“标志”的理由过于限制了禁用中断的时间。
查看代码逻辑,预期的行为是您可以请求一次或多次消息,但您只能得到一个答案。
PS。我尝试使用以下附加标签:“cc-rx”、“rxv2-instruction-set”、“rx231”。