|
我以往写调度器都会用 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 写法却不会丢失任何一次置位。请问问题出在哪里? |
运行到 WRITE_REG (FLASH->OPTKEYR, FLASH_OPTKEY1)跳转 HardFaultHandler
STM32F417IG 单端外部时钟旁路HSE Bypass问题
STM32L4A6 SDMMC 无法使用 1.8V IO 驱动 microSD 卡
STM32L4P5xx 系统内 Bootloader:RAM3 能否用作栈指针内存?
在 STM32CubeIDE 中生成 ioc 配置文件
CAN 总线多节点环境下进行固件升级
在 Bootloader 运行期间保持 GPIO 引脚电平状态不变
把 MCO1 时钟源选为 PLLCLK会怎样
I2C 错误代码含义
CubeIDE 下载程序时不整片擦除芯片
微信公众号
手机版
你遇到的不是“内存屏障”或“原子类型”的逻辑问题,而是标准库实现层 的问题。 最佳实践 :在嵌入式 RTOS 或裸机调度器中,中断设置标志位、主循环查询标志位 ,使用
volatile uint8_t或volatile sig_atomic_t就足够了,无需画蛇添足改为 C11 原子类型。C11 原子更适合多核多线程间的激烈竞争,对于单核中断上下文,反而是笨重且容易引入隐藏依赖的“陷阱”。deepseek 说的
把相关代码的反汇编贴出来