From de4f23748212dbba7d0250fdac3ae583e74fcbed Mon Sep 17 00:00:00 2001 From: Yaochenger <75192526+Yaochenger@users.noreply.github.com> Date: Thu, 23 Mar 2023 20:06:50 +0800 Subject: [PATCH] =?UTF-8?q?[atomic]=E6=B7=BB=E5=8A=A0arm=E4=B8=8Erisc-v?= =?UTF-8?q?=E4=B8=8B=E7=9A=84=E5=B8=B8=E7=94=A8=E5=8E=9F=E5=AD=90=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E5=87=BD=E6=95=B0=20(#7053)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update Kconfig * Update trap_gcc.S * Update bsp/hifive1/drivers/SConscript Co-authored-by: Man, Jianting (Meco) <920369182@qq.com> * Update SConscript * [atomic]提交一份arm与risc-v架构下的常用原子操作函数 * 修改变量类型 * 更新rtatomic.h与atomic_port.c * 更新rt-thread\libcpu\arm\common\atomic_port.c * 更新include/rtatomic.h与libcpu/arm/common/SConscript * 更新include/rtatomic.h * 修正格式与Kconfig * 修正格式与文件结构 * 规范文件格式与文件重命名 * 添加测试用例与CI * 添加函数声明 * 修改virt64/SConscript 添加atomic_riscv.c * 1.规范代码风格 * 2.添加RISC-V64原子指令支持 解决在RV64下编译器将32-bit运算结果扩展为64-bit 导致判断错误 * 添加C11标准库原子操作测试 --------- Co-authored-by: Man, Jianting (Meco) <920369182@qq.com> --- .github/workflows/action_utest.yml | 4 + bsp/gd32/risc-v/libraries/Kconfig | 1 + bsp/gd32vf103v-eval/board/Kconfig | 1 + bsp/hifive1/Kconfig | 1 + bsp/hpmicro/hpm6750evk/board/Kconfig | 1 + bsp/hpmicro/hpm6750evkmini/.config | 308 ++++++++++++++++-- .../hpm6750evkmini/applications/main.c | 3 - bsp/hpmicro/hpm6750evkmini/board/Kconfig | 1 + bsp/hpmicro/hpm6750evkmini/rtconfig.h | 37 ++- bsp/k210/drivers/Kconfig | 1 + bsp/nuclei/gd32vf103_rvstar/board/Kconfig | 1 + bsp/nuclei/nuclei_fpga_eval/board/Kconfig | 1 + bsp/qemu-virt64-riscv/Kconfig | 1 + bsp/sparkfun-redv/Kconfig | 1 + bsp/wch/risc-v/Libraries/Kconfig | 5 + examples/utest/configs/kernel/atomic.conf | 4 + examples/utest/configs/kernel/atomic_c11.conf | 5 + examples/utest/testcases/kernel/Kconfig | 4 + examples/utest/testcases/kernel/SConscript | 3 + examples/utest/testcases/kernel/atomic_tc.c | 147 +++++++++ include/rtatomic.h | 195 +++++++++++ include/rtdef.h | 7 + libcpu/Kconfig | 11 + libcpu/arm/common/SConscript | 3 + libcpu/arm/common/atomic_arm.c | 184 +++++++++++ libcpu/arm/common/showmem.c | 2 +- libcpu/risc-v/common/SConscript | 3 + libcpu/risc-v/common/atomic_riscv.c | 159 +++++++++ libcpu/risc-v/virt64/SConscript | 1 + src/Kconfig | 4 + 30 files changed, 1070 insertions(+), 29 deletions(-) create mode 100644 examples/utest/configs/kernel/atomic.conf create mode 100644 examples/utest/configs/kernel/atomic_c11.conf create mode 100644 examples/utest/testcases/kernel/atomic_tc.c create mode 100644 include/rtatomic.h create mode 100644 libcpu/arm/common/atomic_arm.c create mode 100644 libcpu/risc-v/common/atomic_riscv.c diff --git a/.github/workflows/action_utest.yml b/.github/workflows/action_utest.yml index dc1e0e4204..a5e7bc4f91 100644 --- a/.github/workflows/action_utest.yml +++ b/.github/workflows/action_utest.yml @@ -37,9 +37,13 @@ jobs: - {UTEST: "kernel/irq", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/irq.conf", SD_FILE: "sd.bin", RUN: "yes"} - {UTEST: "kernel/timer", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/timer.conf", SD_FILE: "sd.bin", RUN: "yes"} - {UTEST: "kernel/thread", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/thread.conf", SD_FILE: "sd.bin", RUN: "yes"} + - {UTEST: "kernel/atomic", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/atomic.conf", SD_FILE: "sd.bin", RUN: "yes"} + - {UTEST: "kernel/atomic_c11", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/atomic_c11.conf", SD_FILE: "sd.bin", RUN: "yes"} - {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "utest_self/self.conf", SD_FILE: "sd.bin", RUN: "yes"} - {UTEST: "components/cpp11", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "cpp11/cpp11.conf", SD_FILE: "sd.bin", RUN: "yes"} - {UTEST: "kernel/mem/riscv64", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "None", RUN: "yes"} + - {UTEST: "kernel/atomic/riscv64", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", CONFIG_FILE: "kernel/atomic.conf", SD_FILE: "None", RUN: "yes"} + - {UTEST: "kernel/atomic_c11/riscv64", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", CONFIG_FILE: "kernel/atomic_c11.conf", SD_FILE: "None", RUN: "yes"} - {UTEST: "rtsmart/arm", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "rtsmart/base.conf", SD_FILE: "sd.bin", RUN: "no"} - {UTEST: "rtsmart/aarch64", RTT_BSP: "bsp/qemu-virt64-aarch64", QEMU_ARCH: "aarch64", QEMU_MACHINE: "virt", CONFIG_FILE: "rtsmart/base.conf", SD_FILE: "sd.bin", RUN: "no"} - {UTEST: "rtsmart/riscv64", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", CONFIG_FILE: "rtsmart/base.conf", SD_FILE: "None", RUN: "yes"} diff --git a/bsp/gd32/risc-v/libraries/Kconfig b/bsp/gd32/risc-v/libraries/Kconfig index 5145a8f332..682e10d342 100644 --- a/bsp/gd32/risc-v/libraries/Kconfig +++ b/bsp/gd32/risc-v/libraries/Kconfig @@ -5,4 +5,5 @@ config SOC_GD32VF103V bool select SOC_SERIES_GD32VF103V select SOC_FAMILY_GD32 + select RT_USING_HW_ATOMIC diff --git a/bsp/gd32vf103v-eval/board/Kconfig b/bsp/gd32vf103v-eval/board/Kconfig index 6c09e736da..6ca5167e6a 100644 --- a/bsp/gd32vf103v-eval/board/Kconfig +++ b/bsp/gd32vf103v-eval/board/Kconfig @@ -3,6 +3,7 @@ menu "Hardware Drivers Config" config SOC_GD32VF103V bool select SOC_SERIES_GD32VF103V + select RT_USING_HW_ATOMIC default y menu "Onboard Peripheral Drivers" diff --git a/bsp/hifive1/Kconfig b/bsp/hifive1/Kconfig index 739d102c82..887426c706 100644 --- a/bsp/hifive1/Kconfig +++ b/bsp/hifive1/Kconfig @@ -22,4 +22,5 @@ config SOC_FE310 bool select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN + select RT_USING_HW_ATOMIC default y diff --git a/bsp/hpmicro/hpm6750evk/board/Kconfig b/bsp/hpmicro/hpm6750evk/board/Kconfig index 429cfbe87d..a04a99388e 100644 --- a/bsp/hpmicro/hpm6750evk/board/Kconfig +++ b/bsp/hpmicro/hpm6750evk/board/Kconfig @@ -5,6 +5,7 @@ config SOC_HPM6000 select SOC_SERIES_HPM6000 select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN + select RT_USING_HW_ATOMIC default y menu "On-chip Peripheral Drivers" diff --git a/bsp/hpmicro/hpm6750evkmini/.config b/bsp/hpmicro/hpm6750evkmini/.config index 270be34aba..b082708b33 100644 --- a/bsp/hpmicro/hpm6750evkmini/.config +++ b/bsp/hpmicro/hpm6750evkmini/.config @@ -47,6 +47,7 @@ CONFIG_RT_USING_MESSAGEQUEUE=y # # Memory Management # +CONFIG_RT_PAGE_MAX_ORDER=11 CONFIG_RT_USING_MEMPOOL=y CONFIG_RT_USING_SMALL_MEM=y # CONFIG_RT_USING_SLAB is not set @@ -65,13 +66,18 @@ CONFIG_RT_USING_HEAP=y # CONFIG_RT_USING_DEVICE=y # CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set # CONFIG_RT_USING_INTERRUPT_INFO is not set CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=128 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" CONFIG_RT_VER_NUM=0x50000 -# CONFIG_RT_USING_CPU_FFS is not set +# CONFIG_RT_USING_STDC_ATOMIC is not set +# CONFIG_RT_USING_CACHE is not set +CONFIG_RT_USING_HW_ATOMIC=y +# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +# CONFIG_RT_USING_CPU_FFS is not set # # RT-Thread Components @@ -103,6 +109,7 @@ CONFIG_FINSH_ARG_MAX=10 # Device Drivers # CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 # CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set CONFIG_RT_USING_SERIAL=y CONFIG_RT_USING_SERIAL_V1=y @@ -117,10 +124,14 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64 CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_ADC is not set # CONFIG_RT_USING_DAC is not set +# CONFIG_RT_USING_NULL is not set +# CONFIG_RT_USING_ZERO is not set +# CONFIG_RT_USING_RANDOM is not set # CONFIG_RT_USING_PWM is not set # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set # CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set CONFIG_RT_USING_RTC=y # CONFIG_RT_USING_ALARM is not set # CONFIG_RT_USING_SOFT_RTC is not set @@ -130,10 +141,13 @@ CONFIG_RT_USING_RTC=y # CONFIG_RT_USING_AUDIO is not set # CONFIG_RT_USING_SENSOR is not set # CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set # CONFIG_RT_USING_HWCRYPTO is not set # CONFIG_RT_USING_PULSE_ENCODER is not set # CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set # CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set # # Using USB @@ -184,6 +198,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_VAR_EXPORT is not set +# CONFIG_RT_USING_ADT is not set # CONFIG_RT_USING_RT_LINK is not set # CONFIG_RT_USING_VBUS is not set @@ -278,6 +293,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_AGILE_FTP is not set # CONFIG_PKG_USING_EMBEDDEDPROTO is not set # CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_RYANMQTT is not set # CONFIG_PKG_USING_LORA_PKT_FWD is not set # CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set # CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set @@ -285,6 +301,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_SMALL_MODBUS is not set # CONFIG_PKG_USING_NET_SERVER is not set # CONFIG_PKG_USING_ZFTP is not set +# CONFIG_PKG_USING_WOL is not set # # security packages @@ -375,7 +392,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_SEGGER_RTT is not set # CONFIG_PKG_USING_RDB is not set # CONFIG_PKG_USING_ULOG_EASYFLASH is not set -# CONFIG_PKG_USING_ULOG_FILE is not set # CONFIG_PKG_USING_LOGMGR is not set # CONFIG_PKG_USING_ADBD is not set # CONFIG_PKG_USING_COREMARK is not set @@ -409,7 +425,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_CBOX is not set # CONFIG_PKG_USING_SNOWFLAKE is not set # CONFIG_PKG_USING_HASH_MATCH is not set -# CONFIG_PKG_USING_FIRE_PID_CURVE is not set # CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set # CONFIG_PKG_USING_VOFA_PLUS is not set @@ -481,15 +496,88 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_KMULTI_RTIMER is not set # CONFIG_PKG_USING_TFDB is not set # CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set # # peripheral libraries and drivers # -# CONFIG_PKG_USING_SENSORS_DRIVERS is not set -# CONFIG_PKG_USING_REALTEK_AMEBA is not set + +# +# sensors drivers +# +# CONFIG_PKG_USING_FINGERPRINT is not set +# CONFIG_PKG_USING_LSM6DSM is not set +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BME680 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_MS5805 is not set +# CONFIG_PKG_USING_DA270 is not set +# CONFIG_PKG_USING_DF220 is not set +# CONFIG_PKG_USING_HSHCAL001 is not set +# CONFIG_PKG_USING_BH1750 is not set +# CONFIG_PKG_USING_MPU6XXX is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_TSL4531 is not set +# CONFIG_PKG_USING_DS18B20 is not set +# CONFIG_PKG_USING_DHT11 is not set +# CONFIG_PKG_USING_DHTXX is not set +# CONFIG_PKG_USING_GY271 is not set +# CONFIG_PKG_USING_GP2Y10 is not set +# CONFIG_PKG_USING_SGP30 is not set +# CONFIG_PKG_USING_HDC1000 is not set +# CONFIG_PKG_USING_BMP180 is not set +# CONFIG_PKG_USING_BMP280 is not set +# CONFIG_PKG_USING_SHTC1 is not set +# CONFIG_PKG_USING_BMI088 is not set +# CONFIG_PKG_USING_HMC5883 is not set +# CONFIG_PKG_USING_MAX6675 is not set +# CONFIG_PKG_USING_TMP1075 is not set +# CONFIG_PKG_USING_SR04 is not set +# CONFIG_PKG_USING_CCS811 is not set +# CONFIG_PKG_USING_PMSXX is not set +# CONFIG_PKG_USING_RT3020 is not set +# CONFIG_PKG_USING_MLX90632 is not set +# CONFIG_PKG_USING_MLX90393 is not set +# CONFIG_PKG_USING_MLX90392 is not set +# CONFIG_PKG_USING_MLX90397 is not set +# CONFIG_PKG_USING_MS5611 is not set +# CONFIG_PKG_USING_MAX31865 is not set +# CONFIG_PKG_USING_VL53L0X is not set +# CONFIG_PKG_USING_INA260 is not set +# CONFIG_PKG_USING_MAX30102 is not set +# CONFIG_PKG_USING_INA226 is not set +# CONFIG_PKG_USING_LIS2DH12 is not set +# CONFIG_PKG_USING_HS300X is not set +# CONFIG_PKG_USING_ZMOD4410 is not set +# CONFIG_PKG_USING_ISL29035 is not set +# CONFIG_PKG_USING_MMC3680KJ is not set +# CONFIG_PKG_USING_QMP6989 is not set +# CONFIG_PKG_USING_BALANCE is not set # CONFIG_PKG_USING_SHT2X is not set # CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AD7746 is not set # CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_MAX17048 is not set + +# +# touch drivers +# +# CONFIG_PKG_USING_GT9147 is not set +# CONFIG_PKG_USING_GT1151 is not set +# CONFIG_PKG_USING_GT917S is not set +# CONFIG_PKG_USING_GT911 is not set +# CONFIG_PKG_USING_FT6206 is not set +# CONFIG_PKG_USING_FT5426 is not set +# CONFIG_PKG_USING_FT6236 is not set +# CONFIG_PKG_USING_XPT2046_TOUCH is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set # CONFIG_PKG_USING_AS7341 is not set # CONFIG_PKG_USING_STM32_SDIO is not set # CONFIG_PKG_USING_ESP_IDF is not set @@ -516,12 +604,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_AGILE_LED is not set # CONFIG_PKG_USING_AT24CXX is not set # CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set -# CONFIG_PKG_USING_AD7746 is not set # CONFIG_PKG_USING_PCA9685 is not set # CONFIG_PKG_USING_I2C_TOOLS is not set # CONFIG_PKG_USING_NRF24L01 is not set -# CONFIG_PKG_USING_TOUCH_DRIVERS is not set -# CONFIG_PKG_USING_MAX17048 is not set # CONFIG_PKG_USING_RPLIDAR is not set # CONFIG_PKG_USING_AS608 is not set # CONFIG_PKG_USING_RC522 is not set @@ -571,6 +656,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_RFM300 is not set # CONFIG_PKG_USING_IO_INPUT_FILTER is not set # CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set +# CONFIG_PKG_USING_LRF_NV7LIDAR is not set # # AI packages @@ -585,6 +671,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_QUEST is not set # CONFIG_PKG_USING_NAXOS is not set +# +# Signal Processing and Control Algorithm Packages +# +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_UKAL is not set + # # miscellaneous packages # @@ -636,7 +728,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_VI is not set # CONFIG_PKG_USING_KI is not set # CONFIG_PKG_USING_ARMv7M_DWT is not set -# CONFIG_PKG_USING_UKAL is not set # CONFIG_PKG_USING_CRCLIB is not set # CONFIG_PKG_USING_LWGPS is not set # CONFIG_PKG_USING_STATE_MACHINE is not set @@ -647,6 +738,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_SLCAN2RTT is not set # CONFIG_PKG_USING_SOEM is not set # CONFIG_PKG_USING_QPARAM is not set +# CONFIG_PKG_USING_CorevMCU_CLI is not set # # Arduino libraries @@ -654,30 +746,204 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_RTDUINO is not set # -# Sensor libraries +# Projects # -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set -# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set # -# Display libraries +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set +# CONFIG_PKG_USING_SEEED_ITG3200 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set +# CONFIG_PKG_USING_SEEED_MP503 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set + +# +# Display # # CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_SEEED_TM1637 is not set # -# Timing libraries +# Timing # # CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set # -# Project libraries +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set + +# +# Other +# + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized # -# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set -# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set # # Hardware Drivers Config diff --git a/bsp/hpmicro/hpm6750evkmini/applications/main.c b/bsp/hpmicro/hpm6750evkmini/applications/main.c index b766dd547e..a82b3f2cfd 100644 --- a/bsp/hpmicro/hpm6750evkmini/applications/main.c +++ b/bsp/hpmicro/hpm6750evkmini/applications/main.c @@ -13,8 +13,6 @@ void thread_entry(void *arg); - - int main(void) { @@ -27,7 +25,6 @@ int main(void) return 0; } - void thread_entry(void *arg) { while(1){ diff --git a/bsp/hpmicro/hpm6750evkmini/board/Kconfig b/bsp/hpmicro/hpm6750evkmini/board/Kconfig index 26478a5cd2..2962d5d953 100644 --- a/bsp/hpmicro/hpm6750evkmini/board/Kconfig +++ b/bsp/hpmicro/hpm6750evkmini/board/Kconfig @@ -5,6 +5,7 @@ config SOC_HPM6000 select SOC_SERIES_HPM6000 select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN + select RT_USING_HW_ATOMIC default y menu "On-chip Peripheral Drivers" diff --git a/bsp/hpmicro/hpm6750evkmini/rtconfig.h b/bsp/hpmicro/hpm6750evkmini/rtconfig.h index 7e7fd18386..f4681e5329 100644 --- a/bsp/hpmicro/hpm6750evkmini/rtconfig.h +++ b/bsp/hpmicro/hpm6750evkmini/rtconfig.h @@ -34,6 +34,7 @@ /* Memory Management */ +#define RT_PAGE_MAX_ORDER 11 #define RT_USING_MEMPOOL #define RT_USING_SMALL_MEM #define RT_USING_SMALL_MEM_AS_HEAP @@ -46,6 +47,7 @@ #define RT_CONSOLEBUF_SIZE 128 #define RT_CONSOLE_DEVICE_NAME "uart0" #define RT_VER_NUM 0x50000 +#define RT_USING_HW_ATOMIC /* RT-Thread Components */ @@ -71,6 +73,7 @@ /* Device Drivers */ #define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 #define RT_SERIAL_RB_BUFSZ 64 @@ -159,6 +162,11 @@ /* peripheral libraries and drivers */ +/* sensors drivers */ + + +/* touch drivers */ + /* Kendryte SDK */ @@ -166,6 +174,9 @@ /* AI packages */ +/* Signal Processing and Control Algorithm Packages */ + + /* miscellaneous packages */ /* project laboratory */ @@ -179,18 +190,36 @@ /* Arduino libraries */ -/* Sensor libraries */ +/* Projects */ -/* Display libraries */ +/* Sensors */ -/* Timing libraries */ +/* Display */ -/* Project libraries */ +/* Timing */ +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + +/* Signal IO */ + + +/* Uncategorized */ + /* Hardware Drivers Config */ #define SOC_HPM6000 diff --git a/bsp/k210/drivers/Kconfig b/bsp/k210/drivers/Kconfig index 5442a9d61b..6ef0434039 100644 --- a/bsp/k210/drivers/Kconfig +++ b/bsp/k210/drivers/Kconfig @@ -3,6 +3,7 @@ config SOC_K210 select ARCH_RISCV64 select ARCH_RISCV_FPU_S select PKG_USING_K210_SDK + select RT_USING_HW_ATOMIC config BOARD_K210_EVB bool diff --git a/bsp/nuclei/gd32vf103_rvstar/board/Kconfig b/bsp/nuclei/gd32vf103_rvstar/board/Kconfig index efb38aeaf7..2e90c8d681 100644 --- a/bsp/nuclei/gd32vf103_rvstar/board/Kconfig +++ b/bsp/nuclei/gd32vf103_rvstar/board/Kconfig @@ -3,6 +3,7 @@ menu "Hardware Drivers Config" config SOC_GD32VF103V bool select SOC_SERIES_GD32VF103V + select RT_USING_HW_ATOMIC default y menu "Onboard Peripheral Drivers" diff --git a/bsp/nuclei/nuclei_fpga_eval/board/Kconfig b/bsp/nuclei/nuclei_fpga_eval/board/Kconfig index dd1bf98fbf..c698b8bfce 100644 --- a/bsp/nuclei/nuclei_fpga_eval/board/Kconfig +++ b/bsp/nuclei/nuclei_fpga_eval/board/Kconfig @@ -3,6 +3,7 @@ menu "Hardware Drivers Config" config SOC_HUMMINGBIRD bool select SOC_SERIES_HUMMINGBIRD + select RT_USING_HW_ATOMIC default y menu "Onboard Peripheral Drivers" diff --git a/bsp/qemu-virt64-riscv/Kconfig b/bsp/qemu-virt64-riscv/Kconfig index baba24be4a..8bf1c36af9 100644 --- a/bsp/qemu-virt64-riscv/Kconfig +++ b/bsp/qemu-virt64-riscv/Kconfig @@ -27,6 +27,7 @@ config BOARD_QEMU_VIRT_RV64 select RT_USING_USER_MAIN select RT_USING_CACHE select ARCH_MM_MMU + select RT_USING_HW_ATOMIC default y config ENABLE_FPU diff --git a/bsp/sparkfun-redv/Kconfig b/bsp/sparkfun-redv/Kconfig index 6343092c8c..852a689da5 100644 --- a/bsp/sparkfun-redv/Kconfig +++ b/bsp/sparkfun-redv/Kconfig @@ -22,5 +22,6 @@ config SOC_FE310 bool select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN + select RT_USING_HW_ATOMIC default y diff --git a/bsp/wch/risc-v/Libraries/Kconfig b/bsp/wch/risc-v/Libraries/Kconfig index 6cf71d3d55..054d8aabb5 100644 --- a/bsp/wch/risc-v/Libraries/Kconfig +++ b/bsp/wch/risc-v/Libraries/Kconfig @@ -5,21 +5,26 @@ config SOC_RISCV_SERIES_CH32V1 bool select ARCH_RISCV select SOC_RISCV_FAMILY_CH32 + select RT_USING_HW_ATOMIC config SOC_RISCV_SERIES_CH32V2 bool select ARCH_RISCV select SOC_RISCV_FAMILY_CH32 + select RT_USING_HW_ATOMIC config SOC_RISCV_SERIES_CH32V3 bool select ARCH_RISCV select SOC_RISCV_FAMILY_CH32 + select RT_USING_HW_ATOMIC config SOC_FAMILY_CH56X bool select ARCH_RISCV + select RT_USING_HW_ATOMIC config SOC_SERIES_CH569 bool select SOC_FAMILY_CH56X + select RT_USING_HW_ATOMIC diff --git a/examples/utest/configs/kernel/atomic.conf b/examples/utest/configs/kernel/atomic.conf new file mode 100644 index 0000000000..4255cc2d4f --- /dev/null +++ b/examples/utest/configs/kernel/atomic.conf @@ -0,0 +1,4 @@ +CONFIG_UTEST_ATOMIC_TC=y +# dependencies +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_USING_THREAD=y diff --git a/examples/utest/configs/kernel/atomic_c11.conf b/examples/utest/configs/kernel/atomic_c11.conf new file mode 100644 index 0000000000..d98963f491 --- /dev/null +++ b/examples/utest/configs/kernel/atomic_c11.conf @@ -0,0 +1,5 @@ +CONFIG_UTEST_ATOMIC_TC=y +# dependencies +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_USING_THREAD=y +CONFIG_RT_USING_STDC_ATOMIC=y diff --git a/examples/utest/testcases/kernel/Kconfig b/examples/utest/testcases/kernel/Kconfig index 0faa3622fb..543baf6fa7 100644 --- a/examples/utest/testcases/kernel/Kconfig +++ b/examples/utest/testcases/kernel/Kconfig @@ -55,4 +55,8 @@ config UTEST_THREAD_TC select RT_USING_TIMER_SOFT select RT_USING_THREAD +config UTEST_ATOMIC_TC + bool "atomic test" + default n + endmenu diff --git a/examples/utest/testcases/kernel/SConscript b/examples/utest/testcases/kernel/SConscript index 1cedc291c4..5d560e076b 100644 --- a/examples/utest/testcases/kernel/SConscript +++ b/examples/utest/testcases/kernel/SConscript @@ -41,6 +41,9 @@ if GetDepend(['UTEST_MAILBOX_TC']): if GetDepend(['UTEST_THREAD_TC']): src += ['thread_tc.c'] +if GetDepend(['UTEST_ATOMIC_TC']): + src += ['atomic_tc.c'] + group = DefineGroup('utestcases', src, depend = ['RT_USING_UTESTCASES'], CPPPATH = CPPPATH) Return('group') diff --git a/examples/utest/testcases/kernel/atomic_tc.c b/examples/utest/testcases/kernel/atomic_tc.c new file mode 100644 index 0000000000..53b1839e4f --- /dev/null +++ b/examples/utest/testcases/kernel/atomic_tc.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-07-27 flybreak the first version + * 2023-03-21 WangShun add atomic test + */ + +#include +#include "utest.h" +#include "rtatomic.h" +#include + +#define THREAD_PRIORITY 25 +#define THREAD_TIMESLICE 1 +#define THREAD_STACKSIZE 1024 + +/* convenience macro - return either 64-bit or 32-bit value */ +#define ATOMIC_WORD(val_if_64, val_if_32) \ + ((rt_atomic_t)((sizeof(void *) == sizeof(uint64_t)) ? (val_if_64) : (val_if_32))) + +static rt_atomic_t count = 0; +static rt_sem_t sem_t; + +static void test_atomic_api(void) +{ + rt_atomic_t base; + rt_atomic_t oldval; + + /* rt_atomic_t */ + uassert_true(sizeof(rt_atomic_t) == ATOMIC_WORD(sizeof(uint64_t), sizeof(uint32_t))); + + /* rt_atomic_add */ + base = 0; + rt_atomic_add(&base, 10); + uassert_true(base == 10); + /* rt_atomic_add negative */ + base = 2; + rt_atomic_add(&base, -4); + uassert_true(base == -2); + + /* rt_atomic_sub */ + base = 11; + rt_atomic_sub(&base, 10); + uassert_true(base == 1); + /* rt_atomic_sub negative */ + base = 2; + rt_atomic_sub(&base, -5); + uassert_true(base == 7); + + /* rt_atomic_or */ + base = 0xFF00; + rt_atomic_or(&base, 0x0F0F); + uassert_true(base == 0xFF0F); + + /* rt_atomic_xor */ + base = 0xFF00; + rt_atomic_xor(&base, 0x0F0F); + uassert_true(base == 0xF00F); + + /* rt_atomic_and */ + base = 0xFF00; + rt_atomic_and(&base, 0x0F0F); + uassert_true(base == 0x0F00); + + /* rt_atomic_exchange */ + base = 0xFF00; + rt_atomic_exchange(&base, 0x0F0F); + uassert_true(base == 0x0F0F); + + /* rt_atomic_flag_test_and_set */ + base = 0x0; + rt_atomic_flag_test_and_set(&base); + uassert_true(base == 0x1); + + /* rt_atomic_flag_clear */ + base = 0x1; + rt_atomic_flag_clear(&base); + uassert_true(base == 0x0); + + /* rt_atomic_load */ + base = 0xFF00; + rt_atomic_load(&base); + uassert_true(base == 0xFF00); + + /* rt_atomic_store */ + base = 0xFF00; + rt_atomic_store(&base, 0x0F0F); + uassert_true(base == 0x0F0F); + + /* rt_atomic_compare_exchange_strong */ + base = 10; + oldval = 10; + uassert_true(rt_atomic_compare_exchange_strong(&base, &oldval, 11) == 1); + uassert_true(base == 11); +} + +static void ture_entry(void *parameter) +{ + int i; + for(i = 0; i < 1000000; i++) + { + rt_atomic_add(&count, 1); + } + rt_sem_release(sem_t); +} + +static void test_atomic_add(void) +{ + rt_thread_t thread; + int i; + sem_t = rt_sem_create("atomic_sem", 0, RT_IPC_FLAG_PRIO); + + count = 0; + thread = rt_thread_create("t1", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(thread); + thread = rt_thread_create("t2", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(thread); + thread = rt_thread_create("t3", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(thread); + + for(i = 0; i < 3; i++) + { + rt_sem_take(sem_t, RT_WAITING_FOREVER); + } + uassert_true(count == 3000000); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_atomic_api); + UTEST_UNIT_RUN(test_atomic_add); +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.atomic_tc", utest_tc_init, utest_tc_cleanup, 10); diff --git a/include/rtatomic.h b/include/rtatomic.h new file mode 100644 index 0000000000..dc7c79e208 --- /dev/null +++ b/include/rtatomic.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-03-14 WangShun first version + */ +#ifndef __RT_ATOMIC_H__ +#define __RT_ATOMIC_H__ + +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_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_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); +rt_atomic_t rt_hw_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val); +void rt_hw_atomic_flag_clear(volatile rt_atomic_t *ptr); +rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr); +rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *old, rt_atomic_t new); + +#if defined(RT_USING_STDC_ATOMIC) +#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_add(ptr, v) atomic_fetch_add(ptr, v) +#define rt_atomic_sub(ptr, v) atomic_fetch_sub(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) +#define rt_atomic_exchange(ptr, v) atomic_exchange(ptr, v) +#define rt_atomic_flag_clear(ptr) atomic_flag_clear(ptr) +#define rt_atomic_flag_test_and_set(ptr) atomic_flag_test_and_set(ptr) +#define rt_atomic_compare_exchange_strong(ptr, v,des) atomic_compare_exchange_strong(ptr, v ,des) +#else +#error "The standard library C doesn't support the atomic operation" +#endif /* __STDC_NO_ATOMICS__ */ +#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) +#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) +#define rt_atomic_or(ptr, v) rt_hw_atomic_or(ptr, v) +#define rt_atomic_xor(ptr, v) rt_hw_atomic_xor(ptr, v) +#define rt_atomic_exchange(ptr, v) rt_hw_atomic_exchange(ptr, v) +#define rt_atomic_flag_clear(ptr) rt_hw_atomic_flag_clear(ptr) +#define rt_atomic_flag_test_and_set(ptr) rt_hw_atomic_flag_test_and_set(ptr) +#define rt_atomic_compare_exchange_strong(ptr, v,des) rt_hw_atomic_compare_exchange_strong(ptr, v ,des) +#else +#include +#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_add(ptr, v) rt_soft_atomic_add(ptr, v) +#define rt_atomic_sub(ptr, v) rt_soft_atomic_sub(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) +#define rt_atomic_exchange(ptr, v) rt_soft_atomic_exchange(ptr, v) +#define rt_atomic_flag_clear(ptr) rt_soft_atomic_flag_clear(ptr) +#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_atomic_t rt_soft_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_base_t level; + rt_atomic_t temp; + level = rt_hw_interrupt_disable(); + temp = *ptr; + *ptr = val; + rt_hw_interrupt_enable(level); + return temp; +} + +rt_inline rt_atomic_t rt_soft_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_base_t level; + rt_atomic_t temp; + level = rt_hw_interrupt_disable(); + temp = *ptr; + *ptr += val; + rt_hw_interrupt_enable(level); + return temp; +} + +rt_inline rt_atomic_t rt_soft_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_base_t level; + rt_atomic_t temp; + level = rt_hw_interrupt_disable(); + temp = *ptr; + *ptr -= val; + rt_hw_interrupt_enable(level); + return temp; +} + +rt_inline rt_atomic_t rt_soft_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_base_t level; + rt_atomic_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_and(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_base_t level; + rt_atomic_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_or(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_base_t level; + rt_atomic_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_load(volatile rt_atomic_t *ptr) +{ + rt_base_t level; + rt_atomic_t temp; + level = rt_hw_interrupt_disable(); + temp = *ptr; + rt_hw_interrupt_enable(level); + return temp; +} + +rt_inline void rt_soft_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_base_t level; + level = rt_hw_interrupt_disable(); + *ptr = val; + rt_hw_interrupt_enable(level); +} + +rt_inline rt_atomic_t rt_soft_atomic_flag_test_and_set(volatile rt_atomic_t *ptr) +{ + rt_base_t level; + rt_atomic_t temp; + level = rt_hw_interrupt_disable(); + if (*ptr == 0) + { + temp = 0; + *ptr = 1; + } + else + temp = 1; + rt_hw_interrupt_enable(level); + return temp; +} + +rt_inline void rt_soft_atomic_flag_clear(volatile rt_atomic_t *ptr) +{ + rt_base_t level; + level = rt_hw_interrupt_disable(); + *ptr = 0; + rt_hw_interrupt_enable(level); +} + +rt_inline rt_atomic_t rt_soft_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr1, rt_atomic_t *ptr2, + rt_atomic_t desired) +{ + rt_base_t level; + rt_atomic_t temp; + level = rt_hw_interrupt_disable(); + if ((*ptr1) != (*ptr2)) + { + *ptr2 = *ptr1; + temp = 0; + } + else + { + *ptr1 = desired; + temp = 1; + } + rt_hw_interrupt_enable(level); + return temp; +} +#endif /* RT_USING_STDC_ATOMIC */ +#endif /* __RT_ATOMIC_H__ */ diff --git a/include/rtdef.h b/include/rtdef.h index a292f2bc11..6941045c93 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -125,6 +125,13 @@ typedef rt_base_t rt_flag_t; /**< Type for flags */ typedef rt_ubase_t rt_dev_t; /**< Type for device */ typedef rt_base_t rt_off_t; /**< Type for offset */ +#if defined(RT_USING_STDC_ATOMIC) +#include +typedef atomic_size_t rt_atomic_t; +#else +typedef volatile rt_base_t rt_atomic_t; +#endif + /* boolean type definitions */ #define RT_TRUE 1 /**< boolean true */ #define RT_FALSE 0 /**< boolean fails */ diff --git a/libcpu/Kconfig b/libcpu/Kconfig index 17a57199b9..1de73b0a49 100644 --- a/libcpu/Kconfig +++ b/libcpu/Kconfig @@ -5,6 +5,10 @@ config RT_USING_CACHE bool default n +config RT_USING_HW_ATOMIC + bool + default n + config ARCH_CPU_BIG_ENDIAN bool @@ -47,6 +51,7 @@ config ARCH_ARM_CORTEX_M3 bool select ARCH_ARM_CORTEX_M select RT_USING_CPU_FFS + select RT_USING_HW_ATOMIC config ARCH_ARM_MPU bool @@ -57,21 +62,25 @@ config ARCH_ARM_CORTEX_M4 bool select ARCH_ARM_CORTEX_M select RT_USING_CPU_FFS + select RT_USING_HW_ATOMIC 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 config ARCH_ARM_CORTEX_M33 bool select ARCH_ARM_CORTEX_M select RT_USING_CPU_FFS + select RT_USING_HW_ATOMIC config ARCH_ARM_CORTEX_R bool select ARCH_ARM + select RT_USING_HW_ATOMIC config ARCH_ARM_MMU bool @@ -107,6 +116,7 @@ config ARCH_ARM_CORTEX_A select ARCH_ARM select ARCH_ARM_MMU select RT_USING_CPU_FFS + select RT_USING_HW_ATOMIC if ARCH_ARM_CORTEX_A config RT_SMP_AUTO_BOOT @@ -156,6 +166,7 @@ config ARCH_ARMV8 bool select ARCH_ARM select ARCH_ARM_MMU + select RT_USING_HW_ATOMIC config ARCH_MIPS bool diff --git a/libcpu/arm/common/SConscript b/libcpu/arm/common/SConscript index b259a94c94..9333c8de74 100644 --- a/libcpu/arm/common/SConscript +++ b/libcpu/arm/common/SConscript @@ -18,6 +18,9 @@ if rtconfig.PLATFORM in ['gcc']: if rtconfig.PLATFORM in ['iccarm']: src += Glob('*_iar.S') +if not GetDepend('RT_USING_HW_ATOMIC'): + SrcRemove(src, 'atomic_arm.c') + group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/common/atomic_arm.c b/libcpu/arm/common/atomic_arm.c new file mode 100644 index 0000000000..81ada079f3 --- /dev/null +++ b/libcpu/arm/common/atomic_arm.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-07-27 flybreak the first version + */ + +#include + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ +#define __LDREXW (rt_atomic_t)__builtin_arm_ldrex +#elif defined(__ARMCC_VERSION) /* ARM Compiler V5 */ +#if __ARMCC_VERSION < 5060020 +#define __LDREXW(ptr) ((rt_atomic_t ) __ldrex(ptr)) +#else +#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((rt_atomic_t ) __ldrex(ptr)) _Pragma("pop") +#endif +#elif defined (__IAR_SYSTEMS_ICC__) /* for IAR Compiler */ +_Pragma("inline=forced") __intrinsic rt_atomic_t __LDREXW(volatile rt_atomic_t volatile *ptr) +{ + return __LDREX((unsigned long *)ptr); +} +#elif defined (__GNUC__) /* GNU GCC Compiler */ +__attribute__((always_inline)) static inline rt_atomic_t __LDREXW(volatile rt_atomic_t *addr) +{ + rt_atomic_t result; + + __asm volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return result; +} +#endif + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ +#define __STREXW (rt_atomic_t)__builtin_arm_strex +#elif defined(__ARMCC_VERSION) /* ARM Compiler V5 */ +#if __ARMCC_VERSION < 5060020 +#define __STREXW(value, ptr) __strex(value, ptr) +#else +#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif +#elif defined (__IAR_SYSTEMS_ICC__) /* for IAR Compiler */ +_Pragma("inline=forced") __intrinsic rt_atomic_t __STREXW(rt_atomic_t value, volatile rt_atomic_t *ptr) +{ + return __STREX(value, (unsigned long *)ptr); +} +#elif defined (__GNUC__) /* GNU GCC Compiler */ +__attribute__((always_inline)) static inline rt_atomic_t __STREXW(volatile rt_atomic_t value, volatile rt_atomic_t *addr) +{ + rt_atomic_t result; + + __asm volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return result; +} +#endif + +rt_atomic_t rt_hw_atomic_load(volatile rt_atomic_t *ptr) +{ + rt_atomic_t oldval; + do + { + oldval = __LDREXW(ptr); + } while ((__STREXW(oldval, ptr)) != 0U); + return *ptr; +} + +void rt_hw_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + do + { + __LDREXW(ptr); + } while ((__STREXW(val, ptr)) != 0U); +} + +rt_atomic_t rt_hw_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t oldval; + do + { + oldval = __LDREXW(ptr); + } while ((__STREXW(oldval + val, ptr)) != 0U); + return oldval; +} + +rt_atomic_t rt_hw_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t oldval; + do + { + oldval = __LDREXW(ptr); + } while ((__STREXW(oldval - val, ptr)) != 0U); + return oldval; +} + +rt_atomic_t rt_hw_atomic_and(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t oldval; + do + { + oldval = __LDREXW(ptr); + } while ((__STREXW(oldval & val, ptr)) != 0U); + return oldval; +} + +rt_atomic_t rt_hw_atomic_or(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t oldval; + do + { + oldval = __LDREXW(ptr); + } while ((__STREXW(oldval | val, ptr)) != 0U); + return oldval; +} + +rt_atomic_t rt_hw_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t oldval; + do + { + oldval = __LDREXW(ptr); + } while ((__STREXW(oldval ^ val, ptr)) != 0U); + return oldval; +} + +rt_atomic_t rt_hw_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t oldval; + do + { + oldval = __LDREXW(ptr); + } while ((__STREXW(val, ptr)) != 0U); + return oldval; +} + +void rt_hw_atomic_flag_clear(volatile rt_atomic_t *ptr) +{ + do + { + __LDREXW(ptr); + } while ((__STREXW(0, ptr)) != 0U); +} + +rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr) +{ + rt_atomic_t oldval; + do + { + oldval = __LDREXW(ptr); + } while ((__STREXW(1, ptr)) != 0U); + return oldval; +} + +rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *old, rt_atomic_t new) +{ + rt_atomic_t result; + rt_atomic_t temp = *old; + do + { + result = __LDREXW(ptr); + if (result != temp) + { + *old = result; + __STREXW(result, ptr); + break; + } + } while ((__STREXW(new, ptr)) != 0U); + return (result == temp); +} diff --git a/libcpu/arm/common/showmem.c b/libcpu/arm/common/showmem.c index 2ece137a40..60a18a1969 100644 --- a/libcpu/arm/common/showmem.c +++ b/libcpu/arm/common/showmem.c @@ -10,7 +10,7 @@ #include -void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size) +void rt_hw_show_memory(rt_uint32_t addr, rt_size_t size) { unsigned int i = 0, j = 0; diff --git a/libcpu/risc-v/common/SConscript b/libcpu/risc-v/common/SConscript index ccd26ae518..814cfb01d5 100644 --- a/libcpu/risc-v/common/SConscript +++ b/libcpu/risc-v/common/SConscript @@ -7,6 +7,9 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = ' -I ' + cwd +if not GetDepend('RT_USING_HW_ATOMIC'): + SrcRemove(src, 'atomic_riscv.c') + group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/risc-v/common/atomic_riscv.c b/libcpu/risc-v/common/atomic_riscv.c new file mode 100644 index 0000000000..8a9ef2c8f5 --- /dev/null +++ b/libcpu/risc-v/common/atomic_riscv.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-03-14 WangShun first version + */ + +#include + +rt_atomic_t rt_hw_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t result; +#if __riscv_xlen == 32 + asm volatile ("amoswap.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoswap.d %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#endif + return result; +} + +rt_atomic_t rt_hw_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t result; +#if __riscv_xlen == 32 + asm volatile ("amoadd.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoadd.d %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#endif + return result; +} + +rt_atomic_t rt_hw_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t result; + val = -val; +#if __riscv_xlen == 32 + asm volatile ("amoadd.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoadd.d %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#endif + return result; +} + +rt_atomic_t rt_hw_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t result; +#if __riscv_xlen == 32 + asm volatile ("amoxor.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoxor.d %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#endif + return result; +} + +rt_atomic_t rt_hw_atomic_and(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t result; +#if __riscv_xlen == 32 + asm volatile ("amoand.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoand.d %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#endif + return result; +} + +rt_atomic_t rt_hw_atomic_or(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t result; +#if __riscv_xlen == 32 + asm volatile ("amoor.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoor.d %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#endif + return result; +} + +rt_atomic_t rt_hw_atomic_load(volatile rt_atomic_t *ptr) +{ + rt_atomic_t result; +#if __riscv_xlen == 32 + asm volatile ("amoxor.w %0, x0, (%1)" : "=r"(result) : "r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoxor.d %0, x0, (%1)" : "=r"(result) : "r"(ptr) : "memory"); +#endif + return result; +} + +void rt_hw_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val) +{ + rt_atomic_t result; +#if __riscv_xlen == 32 + asm volatile ("amoswap.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoswap.d %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory"); +#endif +} + +rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr) +{ + rt_atomic_t result; + rt_atomic_t temp = 1; +#if __riscv_xlen == 32 + asm volatile ("amoor.w %0, %1, (%2)" : "=r"(result) : "r"(temp), "r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoor.d %0, %1, (%2)" : "=r"(result) : "r"(temp), "r"(ptr) : "memory"); +#endif + return result; +} + +void rt_hw_atomic_flag_clear(volatile rt_atomic_t *ptr) +{ + rt_atomic_t result; +#if __riscv_xlen == 32 + asm volatile ("amoand.w %0, x0, (%1)" : "=r"(result) :"r"(ptr) : "memory"); +#elif __riscv_xlen == 64 + asm volatile ("amoand.d %0, x0, (%1)" : "=r"(result) :"r"(ptr) : "memory"); +#endif +} + +rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *old, rt_atomic_t new) +{ + rt_atomic_t tmp = *old; + rt_atomic_t result; +#if __riscv_xlen == 32 + asm volatile( + " fence iorw, ow\n" + "1: lr.w.aq %[result], (%[ptr])\n" + " bne %[result], %[tmp], 2f\n" + " sc.w.rl %[tmp], %[new], (%[ptr])\n" + " bnez %[tmp], 1b\n" + " li %[result], 1\n" + " j 3f\n" + " 2:sw %[result], (%[old])\n" + " li %[result], 0\n" + " 3:\n" + : [result]"+r" (result), [tmp]"+r" (tmp), [ptr]"+r" (ptr) + : [new]"r" (new), [old]"r"(old) + : "memory"); +#elif __riscv_xlen == 64 + asm volatile( + " fence iorw, ow\n" + "1: lr.d.aq %[result], (%[ptr])\n" + " bne %[result], %[tmp], 2f\n" + " sc.d.rl %[tmp], %[new], (%[ptr])\n" + " bnez %[tmp], 1b\n" + " li %[result], 1\n" + " j 3f\n" + " 2:sd %[result], (%[old])\n" + " li %[result], 0\n" + " 3:\n" + : [result]"+r" (result), [tmp]"+r" (tmp), [ptr]"+r" (ptr) + : [new]"r" (new), [old]"r"(old) + : "memory"); +#endif + return result; +} diff --git a/libcpu/risc-v/virt64/SConscript b/libcpu/risc-v/virt64/SConscript index b0ae20ba02..d1dfa79ec9 100644 --- a/libcpu/risc-v/virt64/SConscript +++ b/libcpu/risc-v/virt64/SConscript @@ -6,6 +6,7 @@ Import('rtconfig') cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +src = src + ['../common/atomic_riscv.c'] CPPPATH = [cwd] ASFLAGS = '' diff --git a/src/Kconfig b/src/Kconfig index 1be8222c81..eaf042790a 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -479,4 +479,8 @@ config RT_VER_NUM help RT-Thread version number +config RT_USING_STDC_ATOMIC + bool "Use atomic implemented in stdatomic.h" + default n + endmenu