diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/rtatomic.h | 141 | ||||
| -rw-r--r-- | include/rttypes.h | 8 |
2 files changed, 149 insertions, 0 deletions
diff --git a/include/rtatomic.h b/include/rtatomic.h index 4719339d26..96c906f74b 100644 --- a/include/rtatomic.h +++ b/include/rtatomic.h @@ -7,6 +7,7 @@ * Date Author Notes * 2023-03-14 WangShun first version * 2023-05-20 Bernard add stdc atomic detection. + * 2026-03-09 wdfk-prog add 8/16-bit atomic operations support */ #ifndef __RT_ATOMIC_H__ #define __RT_ATOMIC_H__ @@ -17,8 +18,16 @@ rt_atomic_t rt_hw_atomic_load(volatile rt_atomic_t *ptr); void rt_hw_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val); +rt_atomic8_t rt_hw_atomic_load8(volatile rt_atomic8_t *ptr); +void rt_hw_atomic_store8(volatile rt_atomic8_t *ptr, rt_atomic8_t val); +rt_atomic16_t rt_hw_atomic_load16(volatile rt_atomic16_t *ptr); +void rt_hw_atomic_store16(volatile rt_atomic16_t *ptr, rt_atomic16_t val); rt_atomic_t rt_hw_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val); rt_atomic_t rt_hw_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val); +rt_atomic8_t rt_hw_atomic_and8(volatile rt_atomic8_t *ptr, rt_atomic8_t val); +rt_atomic8_t rt_hw_atomic_or8(volatile rt_atomic8_t *ptr, rt_atomic8_t val); +rt_atomic16_t rt_hw_atomic_and16(volatile rt_atomic16_t *ptr, rt_atomic16_t val); +rt_atomic16_t rt_hw_atomic_or16(volatile rt_atomic16_t *ptr, rt_atomic16_t val); rt_atomic_t rt_hw_atomic_and(volatile rt_atomic_t *ptr, rt_atomic_t val); rt_atomic_t rt_hw_atomic_or(volatile rt_atomic_t *ptr, rt_atomic_t val); rt_atomic_t rt_hw_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val); @@ -32,8 +41,16 @@ rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_a #ifndef __STDC_NO_ATOMICS__ #define rt_atomic_load(ptr) atomic_load(ptr) #define rt_atomic_store(ptr, v) atomic_store(ptr, v) +#define rt_atomic_load8(ptr) atomic_load(ptr) +#define rt_atomic_store8(ptr, v) atomic_store(ptr, v) +#define rt_atomic_load16(ptr) atomic_load(ptr) +#define rt_atomic_store16(ptr, v) atomic_store(ptr, v) #define rt_atomic_add(ptr, v) atomic_fetch_add(ptr, v) #define rt_atomic_sub(ptr, v) atomic_fetch_sub(ptr, v) +#define rt_atomic_and8(ptr, v) atomic_fetch_and(ptr, v) +#define rt_atomic_or8(ptr, v) atomic_fetch_or(ptr, v) +#define rt_atomic_and16(ptr, v) atomic_fetch_and(ptr, v) +#define rt_atomic_or16(ptr, v) atomic_fetch_or(ptr, v) #define rt_atomic_and(ptr, v) atomic_fetch_and(ptr, v) #define rt_atomic_or(ptr, v) atomic_fetch_or(ptr, v) #define rt_atomic_xor(ptr, v) atomic_fetch_xor(ptr, v) @@ -48,6 +65,28 @@ rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_a #elif defined(RT_USING_HW_ATOMIC) #define rt_atomic_load(ptr) rt_hw_atomic_load(ptr) #define rt_atomic_store(ptr, v) rt_hw_atomic_store(ptr, v) +#if defined(ARCH_USING_HW_ATOMIC_8) +#define rt_atomic_load8(ptr) rt_hw_atomic_load8(ptr) +#define rt_atomic_store8(ptr, v) rt_hw_atomic_store8(ptr, v) +#define rt_atomic_and8(ptr, v) rt_hw_atomic_and8(ptr, v) +#define rt_atomic_or8(ptr, v) rt_hw_atomic_or8(ptr, v) +#else +#define rt_atomic_load8(ptr) rt_soft_atomic_load8(ptr) +#define rt_atomic_store8(ptr, v) rt_soft_atomic_store8(ptr, v) +#define rt_atomic_and8(ptr, v) rt_soft_atomic_and8(ptr, v) +#define rt_atomic_or8(ptr, v) rt_soft_atomic_or8(ptr, v) +#endif +#if defined(ARCH_USING_HW_ATOMIC_16) +#define rt_atomic_load16(ptr) rt_hw_atomic_load16(ptr) +#define rt_atomic_store16(ptr, v) rt_hw_atomic_store16(ptr, v) +#define rt_atomic_and16(ptr, v) rt_hw_atomic_and16(ptr, v) +#define rt_atomic_or16(ptr, v) rt_hw_atomic_or16(ptr, v) +#else +#define rt_atomic_load16(ptr) rt_soft_atomic_load16(ptr) +#define rt_atomic_store16(ptr, v) rt_soft_atomic_store16(ptr, v) +#define rt_atomic_and16(ptr, v) rt_soft_atomic_and16(ptr, v) +#define rt_atomic_or16(ptr, v) rt_soft_atomic_or16(ptr, v) +#endif #define rt_atomic_add(ptr, v) rt_hw_atomic_add(ptr, v) #define rt_atomic_sub(ptr, v) rt_hw_atomic_sub(ptr, v) #define rt_atomic_and(ptr, v) rt_hw_atomic_and(ptr, v) @@ -62,8 +101,16 @@ rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_a #include <rthw.h> #define rt_atomic_load(ptr) rt_soft_atomic_load(ptr) #define rt_atomic_store(ptr, v) rt_soft_atomic_store(ptr, v) +#define rt_atomic_load8(ptr) rt_soft_atomic_load8(ptr) +#define rt_atomic_store8(ptr, v) rt_soft_atomic_store8(ptr, v) +#define rt_atomic_load16(ptr) rt_soft_atomic_load16(ptr) +#define rt_atomic_store16(ptr, v) rt_soft_atomic_store16(ptr, v) #define rt_atomic_add(ptr, v) rt_soft_atomic_add(ptr, v) #define rt_atomic_sub(ptr, v) rt_soft_atomic_sub(ptr, v) +#define rt_atomic_and8(ptr, v) rt_soft_atomic_and8(ptr, v) +#define rt_atomic_or8(ptr, v) rt_soft_atomic_or8(ptr, v) +#define rt_atomic_and16(ptr, v) rt_soft_atomic_and16(ptr, v) +#define rt_atomic_or16(ptr, v) rt_soft_atomic_or16(ptr, v) #define rt_atomic_and(ptr, v) rt_soft_atomic_and(ptr, v) #define rt_atomic_or(ptr, v) rt_soft_atomic_or(ptr, v) #define rt_atomic_xor(ptr, v) rt_soft_atomic_xor(ptr, v) @@ -72,6 +119,100 @@ rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_a #define rt_atomic_flag_test_and_set(ptr) rt_soft_atomic_flag_test_and_set(ptr) #define rt_atomic_compare_exchange_strong(ptr, v,des) rt_soft_atomic_compare_exchange_strong(ptr, v ,des) +rt_inline rt_atomic8_t rt_soft_atomic_load8(volatile rt_atomic8_t *ptr) +{ + rt_base_t level; + rt_atomic8_t temp; + + level = rt_hw_interrupt_disable(); + temp = *ptr; + rt_hw_interrupt_enable(level); + + return temp; +} + +rt_inline void rt_soft_atomic_store8(volatile rt_atomic8_t *ptr, rt_atomic8_t val) +{ + rt_base_t level; + + level = rt_hw_interrupt_disable(); + *ptr = val; + rt_hw_interrupt_enable(level); +} + +rt_inline rt_atomic16_t rt_soft_atomic_load16(volatile rt_atomic16_t *ptr) +{ + rt_base_t level; + rt_atomic16_t temp; + + level = rt_hw_interrupt_disable(); + temp = *ptr; + rt_hw_interrupt_enable(level); + + return temp; +} + +rt_inline void rt_soft_atomic_store16(volatile rt_atomic16_t *ptr, rt_atomic16_t val) +{ + rt_base_t level; + + level = rt_hw_interrupt_disable(); + *ptr = val; + rt_hw_interrupt_enable(level); +} + +rt_inline rt_atomic8_t rt_soft_atomic_and8(volatile rt_atomic8_t *ptr, rt_atomic8_t val) +{ + rt_base_t level; + rt_atomic8_t temp; + + level = rt_hw_interrupt_disable(); + temp = *ptr; + *ptr = temp & val; + rt_hw_interrupt_enable(level); + + return temp; +} + +rt_inline rt_atomic8_t rt_soft_atomic_or8(volatile rt_atomic8_t *ptr, rt_atomic8_t val) +{ + rt_base_t level; + rt_atomic8_t temp; + + level = rt_hw_interrupt_disable(); + temp = *ptr; + *ptr = temp | val; + rt_hw_interrupt_enable(level); + + return temp; +} + +rt_inline rt_atomic16_t rt_soft_atomic_and16(volatile rt_atomic16_t *ptr, rt_atomic16_t val) +{ + rt_base_t level; + rt_atomic16_t temp; + + level = rt_hw_interrupt_disable(); + temp = *ptr; + *ptr = temp & val; + rt_hw_interrupt_enable(level); + + return temp; +} + +rt_inline rt_atomic16_t rt_soft_atomic_or16(volatile rt_atomic16_t *ptr, rt_atomic16_t val) +{ + rt_base_t level; + rt_atomic16_t temp; + + level = rt_hw_interrupt_disable(); + temp = *ptr; + *ptr = temp | val; + rt_hw_interrupt_enable(level); + + return temp; +} + rt_inline rt_atomic_t rt_soft_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val) { rt_base_t level; diff --git a/include/rttypes.h b/include/rttypes.h index cfbaec8bdb..110e39df0e 100644 --- a/include/rttypes.h +++ b/include/rttypes.h @@ -99,14 +99,22 @@ typedef rt_base_t rt_off_t; /**< Type for offset */ #endif #ifdef __cplusplus + typedef rt_uint8_t rt_atomic8_t; + typedef rt_uint16_t rt_atomic16_t; typedef rt_base_t rt_atomic_t; #else #if defined(RT_USING_STDC_ATOMIC) #include <stdatomic.h> + typedef _Atomic(rt_uint8_t) rt_atomic8_t; + typedef _Atomic(rt_uint16_t) rt_atomic16_t; typedef _Atomic(rt_base_t) rt_atomic_t; #elif defined(RT_USING_HW_ATOMIC) + typedef rt_uint8_t rt_atomic8_t; + typedef rt_uint16_t rt_atomic16_t; typedef rt_base_t rt_atomic_t; #else + typedef rt_uint8_t rt_atomic8_t; + typedef rt_uint16_t rt_atomic16_t; typedef rt_base_t rt_atomic_t; #endif /* RT_USING_STDC_ATOMIC */ #endif /* __cplusplus */ |
