|
我以往写调度器都会用 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 写法却不会丢失任何一次置位。请问问题出在哪里? |
使用 HAL 库通过串口以 ASCII 形式发送整型数据
USB Host 外部中断按键失效
调用HAL_FLASH_OB_Unlock()直接进入 HardFaultHandler
STM32 增加 WiFi + 以太网的低成本方案
NUCLEO G474RE无法运行程序
STM32F407VGT6 开发板Beak at address "0x0" with no debug information our outside
BootLoader 与 DFU 模式的区别
运行到 WRITE_REG (FLASH->OPTKEYR, FLASH_OPTKEY1)跳转 HardFaultHandler
STM32F417IG 单端外部时钟旁路HSE Bypass问题
STM32L4A6 SDMMC 无法使用 1.8V IO 驱动 microSD 卡
微信公众号
手机版
你遇到的不是“内存屏障”或“原子类型”的逻辑问题,而是标准库实现层 的问题。 最佳实践 :在嵌入式 RTOS 或裸机调度器中,中断设置标志位、主循环查询标志位 ,使用
volatile uint8_t或volatile sig_atomic_t就足够了,无需画蛇添足改为 C11 原子类型。C11 原子更适合多核多线程间的激烈竞争,对于单核中断上下文,反而是笨重且容易引入隐藏依赖的“陷阱”。deepseek 说的
把相关代码的反汇编贴出来