我为我的 MCU 创建了一个循环缓冲区结构,其中结构元素是:
- 事件缓冲区[m]
- 头
- 尾巴
我使用这些事件来驱动状态机。对于我的应用程序,ISR 是生产者,而我的主要是消费者。ISR 不能互相抢占,每个 ISR 具有相同的优先级。ISR 将事件推送到事件缓冲区的头部索引并增加头部变量,而我的主要代码从事件缓冲区的尾部索引弹出事件并增加尾部变量。如果头或尾指针到达缓冲区的末尾,它们只会环绕。
在主代码中,我检查缓冲区,如:
CircBuffer.Head = 0;
CircBuffer.Tail = 0;
enable_ISRs();
while(1){
if(CircBuffer.Head == CircBuffer.Tail)
{
//Low power mode
}
else
{
statemachine_dispatch(CircBuffer.EventBuff[CircBuffer.Tail])
increment CircBuffer.Tail & BUFFLEN_MASK
}
}
在 ISR 中,我将事件添加到缓冲区,例如:
void example_ISR1()
{
clear flag
CircBuffer.EventBuff[CircBuffer.Head] = example_EVENT1;
increment CircBuffer.Head & BUFFLEN_MASK
}
void example_ISR2()
{
clear flag
CircBuffer.EventBuff[CircBuffer.Head] = example_EVENT2;
increment CircBuffer.Head & BUFFLEN_MASK
}
如果我必须从 main 将事件发布到事件缓冲区,我会禁用并启用中断。
我想知道这个结构是否是线程安全的,或者我是否必须在检查缓冲区是否为空(Head==Tail,没有要处理的事件)或调度事件或增加 tail 变量时禁用和启用主循环中的中断?我错过了什么吗?