Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions include/rtatomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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 = (*ptr) & 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 = (*ptr) | 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 = (*ptr) & 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 = (*ptr) | 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;
Expand Down
8 changes: 8 additions & 0 deletions include/rttypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
24 changes: 24 additions & 0 deletions libcpu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ config RT_USING_HW_ATOMIC
bool
default n

config ARCH_USING_HW_ATOMIC_8
bool
default n

config ARCH_USING_HW_ATOMIC_16
bool
default n

config ARCH_CPU_BIG_ENDIAN
bool

Expand Down Expand Up @@ -60,6 +68,8 @@ config ARCH_ARM_CORTEX_M3
select ARCH_ARM_CORTEX_M
select RT_USING_CPU_FFS
select RT_USING_HW_ATOMIC
select ARCH_USING_HW_ATOMIC_8
select ARCH_USING_HW_ATOMIC_16

config ARCH_ARM_MPU
bool
Expand All @@ -71,35 +81,47 @@ config ARCH_ARM_CORTEX_M4
select ARCH_ARM_CORTEX_M
select RT_USING_CPU_FFS
select RT_USING_HW_ATOMIC
select ARCH_USING_HW_ATOMIC_8
select ARCH_USING_HW_ATOMIC_16

config ARCH_ARM_CORTEX_M7
bool
select ARCH_ARM_CORTEX_M
select RT_USING_CPU_FFS
select RT_USING_CACHE
select RT_USING_HW_ATOMIC
select ARCH_USING_HW_ATOMIC_8
select ARCH_USING_HW_ATOMIC_16

config ARCH_ARM_CORTEX_M85
bool
select ARCH_ARM_CORTEX_M
select RT_USING_CPU_FFS
select RT_USING_HW_ATOMIC
select ARCH_USING_HW_ATOMIC_8
select ARCH_USING_HW_ATOMIC_16

config ARCH_ARM_CORTEX_M23
bool
select ARCH_ARM_CORTEX_M
select RT_USING_HW_ATOMIC
select ARCH_USING_HW_ATOMIC_8
select ARCH_USING_HW_ATOMIC_16

config ARCH_ARM_CORTEX_M33
bool
select ARCH_ARM_CORTEX_M
select RT_USING_CPU_FFS
select RT_USING_HW_ATOMIC
select ARCH_USING_HW_ATOMIC_8
select ARCH_USING_HW_ATOMIC_16

config ARCH_ARM_CORTEX_R
bool
select ARCH_ARM
select RT_USING_HW_ATOMIC
select ARCH_USING_HW_ATOMIC_8
select ARCH_USING_HW_ATOMIC_16

config ARCH_ARM_CORTEX_R52
bool
Expand Down Expand Up @@ -141,6 +163,8 @@ config ARCH_ARM_CORTEX_A
select ARCH_ARM_MMU
select RT_USING_CPU_FFS
select RT_USING_HW_ATOMIC
select ARCH_USING_HW_ATOMIC_8
select ARCH_USING_HW_ATOMIC_16

if ARCH_ARM_CORTEX_A
config RT_SMP_AUTO_BOOT
Expand Down
Loading