|
我以往写调度器都会用 volatile 修饰标志位,写法非常简单: volatile uint8_t myflag; uint8_t ticks; void Func(void){ ++ticks; if(!(ticks % 5)){ myflag = true; } } void User(void){ if(myflag) { myflag = false; //执行任务 } } 网上普遍观点认为上面这种写法并不安全 —— 缺少内存屏障。正确方案应该使用原子类型,于是我改成了原子变量实现: atomic_bool myflag = ATOMIC_VAR_INIT(false); uint8_t ticks; void Func(void){ ++ticks; if(!(ticks % 5)){ atomic_store(&myflag ,true); } } void User(void){ if(atomic_load(&myflag)) { atomic_store(&myflag ,false); //执行任务 } } 但这套代码无法正常工作,User函数会经常性漏掉标志置位事件,不只是延迟,而是直接丢失一整轮标志。 我试过把原子变量再加 volatile 修饰,也试过atomic_flag,都会丢标志;但老式 volatile 写法却不会丢失任何一次置位。请问问题出在哪里? |
终于找到了STM32C542RC开发板的官方实例
使用我自己写的 IAP 跳转到 FLASH 应用程序时,串口上出现无关字节
说说我今天使用CUBEMX2的感受
Error[Lp015]: section placement failure内容占用溢出
STM32F7由USB FS读写QSPI flash
STM8L050J3使用SWIM下载方式,无法下载,总是报错
用SDRAM刷ltdc有白线会出现是啥情况
在keil中仿真程序时,结构体变量出现错乱
什么是 GPIO 事件?如何将事件关联到外设
中断服务程序抖动
微信公众号
手机版
你遇到的不是“内存屏障”或“原子类型”的逻辑问题,而是标准库实现层 的问题。 最佳实践 :在嵌入式 RTOS 或裸机调度器中,中断设置标志位、主循环查询标志位 ,使用
volatile uint8_t或volatile sig_atomic_t就足够了,无需画蛇添足改为 C11 原子类型。C11 原子更适合多核多线程间的激烈竞争,对于单核中断上下文,反而是笨重且容易引入隐藏依赖的“陷阱”。deepseek 说的
把相关代码的反汇编贴出来