幻影书记 发表于 2025-9-24 09:40

原子操作

在CMSIS模块中已经提供了原子操作宏,用于操作16位或32位变量,包括ATOMIC_SET_BIT、ATOMIC_CLEAR_BIT、ATOMIC_MODIFY_REG。该功能是使用LDREX和STREX指令来实现的。可以通过对原子操作的封装实现互斥。LDREX和STREX指令是Thumb指令集提供的排他加载和排他访问指令,用以实现排他性访问。我以APM32F407为例分享一下源代码:    /* Use of CMSIS compiler intrinsics for register exclusive access */
    /* Atomic 32-bit register access macro to set one or several bits */
    #define ATOMIC_SET_BIT(REG, BIT)                           \
      do {                                                       \
      uint32_t val;                                          \
      do {                                                   \
          val = __LDREXW((__IO uint32_t *)&(REG)) | (BIT);       \
      } while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
      } while(0)
      
    /* Atomic 32-bit register access macro to clear one or several bits */
    #define ATOMIC_CLEAR_BIT(REG, BIT)                           \
      do {                                                       \
      uint32_t val;                                          \
      do {                                                   \
          val = __LDREXW((__IO uint32_t *)&(REG)) & ~(BIT);      \
      } while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
      } while(0)
      
    /* Atomic 32-bit register access macro to clear and set one or several bits */
    #define ATOMIC_MODIFY_REG(REG, CLEARMSK, SETMASK)                        \
      do {                                                                     \
      uint32_t val;                                                          \
      do {                                                                   \
          val = (__LDREXW((__IO uint32_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \
      } while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U);               \
      } while(0)



雾里闲逛 发表于 2025-9-24 20:08

很少使用原子操作。
都是在状态机里面完成。
原子操作太费神了

夜幕叙事曲 发表于 2025-10-4 10:09

以前使用原子操作是关闭全部中断来处理的

涡流远见者 发表于 2025-10-5 09:11

FreeRTOS里面中断临界区如何实现的啊
页: [1]
查看完整版本: 原子操作