Compare commits

...

7 Commits

Author SHA1 Message Date
MuChenger
8286196d9f [bsp/xuantie][fix] 修正Bsp Kconfig配置 2025-11-13 18:44:24 +08:00
Ze-Hou
ec5e72c59a feature: utest: add standardized utest documentation to thread_tc
Signed-off-by: Ze-Hou <yingkezhou@qq.com>
2025-11-13 18:42:13 +08:00
Ze-Hou
538e5ff6d5 feature: utest: add standardized utest documentation to hooklist_tc
Signed-off-by: Ze-Hou <yingkezhou@qq.com>
2025-11-13 16:23:15 +08:00
wdfk-prog
ddfe2cd61c feat[spi]: enable interrupt-safe operations using spinlocks 2025-11-13 15:41:41 +08:00
wdfk-prog
ec27e09df8 feat:[stm32][can]: enhance control logic and refactor sendmsg 2025-11-13 15:31:05 +08:00
wdfk-prog
f56875fff5 fix[components]: 修复日志输出的gcc编译警告 2025-11-13 15:16:49 +08:00
rcitach
9150317539 Fixed PWM assertion error caused by using DM 2025-11-13 11:11:59 +08:00
21 changed files with 271 additions and 264 deletions

View File

@@ -472,11 +472,23 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
argval = (rt_uint32_t) arg;
if (argval == 0)
{
HAL_CAN_Stop(&drv_can->CanHandle);
if (HAL_CAN_DeInit(&drv_can->CanHandle) != HAL_OK)
{
LOG_E("CAN deinitialization failed");
return -RT_ERROR;
}
}
else
{
HAL_CAN_Start(&drv_can->CanHandle);
rt_err_t result = _can_config(&drv_can->device, &drv_can->device.config);
if (result != RT_EOK)
{
return result;
}
if (HAL_CAN_Start(&drv_can->CanHandle) != HAL_OK)
{
return -RT_ERROR;
}
}
break;
@@ -515,32 +527,31 @@ static rt_ssize_t _can_sendmsg(struct rt_can_device *can, const void *buf, rt_ui
(state == HAL_CAN_STATE_LISTENING))
{
/*check select mailbox is empty */
uint32_t mailbox_mask;
uint32_t tme_flag;
switch (1 << box_num)
{
case CAN_TX_MAILBOX0:
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0) != SET)
{
/* Return function status */
return -RT_ERROR;
}
mailbox_mask = CAN_TX_MAILBOX0;
tme_flag = CAN_TSR_TME0;
break;
case CAN_TX_MAILBOX1:
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1) != SET)
{
/* Return function status */
return -RT_ERROR;
}
mailbox_mask = CAN_TX_MAILBOX1;
tme_flag = CAN_TSR_TME1;
break;
case CAN_TX_MAILBOX2:
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2) != SET)
{
/* Return function status */
return -RT_ERROR;
}
mailbox_mask = CAN_TX_MAILBOX2;
tme_flag = CAN_TSR_TME2;
break;
default:
RT_ASSERT(0);
break;
return -RT_ERROR;
}
if (HAL_IS_BIT_SET(hcan->Instance->TSR, tme_flag) != SET)
{
return -RT_ERROR;
}
if (RT_CAN_STDID == pmsg->ide)

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_SMARTL_E902
bool
@@ -30,6 +13,6 @@ config XUANTIAN_SMARTL_E902
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_SMARTL_E906
bool
@@ -30,6 +13,6 @@ config XUANTIAN_SMARTL_E906
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_SMARTL_E907
bool
@@ -30,6 +13,6 @@ config XUANTIAN_SMARTL_E907
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_XIAOHUI_C906
bool
@@ -30,6 +13,6 @@ config ENV_DIR
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_XIAOHUI_C907
bool
@@ -30,6 +13,6 @@ config ENV_DIR
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_XIAOHUI_C908
bool
@@ -30,6 +13,6 @@ config ENV_DIR
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_XIAOHUI_C910
bool
@@ -30,6 +13,6 @@ config ENV_DIR
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_XIAOHUI_R908
bool
@@ -30,6 +13,6 @@ config ENV_DIR
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_XIAOHUI_R910
bool
@@ -30,6 +13,6 @@ config ENV_DIR
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -1,27 +1,10 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
BSP_DIR := .
config RTT_DIR
string
option env="RTT_ROOT"
default "rt-thread"
RTT_DIR := ../../../../
# you can change the RTT_ROOT default "rt-thread"
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config ENV_DIR
string
option env="ENV_ROOT"
default "/"
PKGS_DIR := packages
config XUANTIAN_XIAOHUI_R920
bool
@@ -30,6 +13,6 @@ config ENV_DIR
select RT_USING_USER_MAIN
default y
source "$RTT_DIR/Kconfig"
source "$(RTT_DIR)/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$BSP_DIR/board/Kconfig"

View File

@@ -183,7 +183,7 @@ int dfs_filesystem_get_partition(struct dfs_partition *part,
part->offset = *(dpt + 8) | *(dpt + 9) << 8 | *(dpt + 10) << 16 | *(dpt + 11) << 24;
part->size = *(dpt + 12) | *(dpt + 13) << 8 | *(dpt + 14) << 16 | *(dpt + 15) << 24;
rt_kprintf("found part[%d], begin: %d, size: ",
rt_kprintf("found part[%ld], begin: %ld, size: ",
pindex, part->offset * 512);
if ((part->size >> 11) == 0)
rt_kprintf("%d%s", part->size >> 1, "KB\n"); /* KB */
@@ -636,7 +636,7 @@ int df(const char *path)
if (rt_get_errno() == -ENOSYS)
rt_kprintf("The function is not implemented.\n");
else
rt_kprintf("statfs failed: errno=%d.\n", rt_get_errno());
rt_kprintf("statfs failed: errno=%ld.\n", rt_get_errno());
return -1;
}
@@ -649,7 +649,7 @@ int df(const char *path)
cap = cap / 1024;
}
rt_kprintf("disk free: %d.%d %s [ %d block, %d bytes per block ]\n",
rt_kprintf("disk free: %ld.%d %s [ %d block, %d bytes per block ]\n",
(unsigned long)cap, minor, unit_str[unit_index], buffer.f_bfree, buffer.f_bsize);
return 0;
}

View File

@@ -8,6 +8,7 @@
* 2012-11-23 Bernard Add extern "C"
* 2020-06-13 armink fix the 3 wires issue
* 2022-09-01 liYony fix api rt_spi_sendrecv16 about MSB and LSB bug
* 2025-10-30 wdfk-prog enable interrupt-safe operations using spinlocks
*/
#ifndef __DEV_SPI_H__
@@ -181,6 +182,10 @@ struct rt_spi_bus
#endif /* RT_USING_DM */
struct rt_mutex lock;
#ifdef RT_USING_SPI_ISR
rt_base_t _isr_lvl;
struct rt_spinlock _spinlock;
#endif /* RT_USING_SPI_ISR */
struct rt_spi_device *owner;
};

View File

@@ -116,7 +116,9 @@ rt_err_t rt_device_pwm_register(struct rt_device_pwm *device, const char *name,
{
rt_err_t result = RT_EOK;
#ifndef RT_USING_DM
rt_memset(device, 0, sizeof(struct rt_device_pwm));
#endif
#ifdef RT_USING_DEVICE_OPS
device->parent.ops = &pwm_device_ops;

View File

@@ -4,6 +4,10 @@ menuconfig RT_USING_SPI
if RT_USING_SPI
menuconfig RT_USING_SPI_ISR
bool "Enable interrupt-safe SPI operations (using spinlocks in ISR context)"
default y
menuconfig RT_USING_SOFT_SPI
bool "Use GPIO to simulate SPI"
default n

View File

@@ -11,6 +11,7 @@
* 2012-05-18 bernard Changed SPI message to message list.
* Added take/release SPI device/bus interface.
* 2012-09-28 aozima fixed rt_spi_release_bus assert error.
* 2025-10-30 wdfk-prog enable interrupt-safe operations using spinlocks
*/
#include "drivers/dev_spi.h"
@@ -38,6 +39,9 @@ rt_err_t spi_bus_register(struct rt_spi_bus *bus,
/* initialize mutex lock */
rt_mutex_init(&(bus->lock), name, RT_IPC_FLAG_PRIO);
#ifdef RT_USING_SPI_ISR
rt_spin_lock_init(&bus->_spinlock);
#endif /* RT_USING_SPI_ISR */
/* set ops */
bus->ops = ops;
/* initialize owner */
@@ -164,13 +168,53 @@ rt_err_t rt_spi_bus_detach_device(struct rt_spi_device *device)
return rt_spi_bus_detach_device_cspin(device);
}
static rt_err_t spi_lock(struct rt_spi_bus *bus)
{
RT_ASSERT(bus);
rt_err_t ret = -RT_ERROR;
/* If the scheduler is started and in thread context */
if (rt_scheduler_is_available())
{
ret = rt_mutex_take(&(bus->lock), RT_WAITING_FOREVER);
}
else
{
#ifdef RT_USING_SPI_ISR
bus->_isr_lvl = rt_spin_lock_irqsave(&bus->_spinlock);
ret = RT_EOK;
#endif /* RT_USING_SPI_ISR */
}
return ret;
}
static rt_err_t spi_unlock(struct rt_spi_bus *bus)
{
RT_ASSERT(bus);
rt_err_t ret = -RT_ERROR;
/* If the scheduler is started and in thread context */
if (rt_scheduler_is_available())
{
ret = rt_mutex_release(&(bus->lock));
}
else
{
#ifdef RT_USING_SPI_ISR
rt_spin_unlock_irqrestore(&bus->_spinlock, bus->_isr_lvl);
ret = RT_EOK;
#endif /* RT_USING_SPI_ISR */
}
return ret;
}
rt_err_t rt_spi_bus_configure(struct rt_spi_device *device)
{
rt_err_t result = -RT_ERROR;
if (device->bus != RT_NULL)
{
result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
result = spi_lock(device->bus);
if (result == RT_EOK)
{
if (device->bus->owner == device)
@@ -191,7 +235,7 @@ rt_err_t rt_spi_bus_configure(struct rt_spi_device *device)
result = -RT_EBUSY;
}
/* release lock */
rt_mutex_release(&(device->bus->lock));
spi_unlock(device->bus);
}
}
else
@@ -211,7 +255,7 @@ rt_err_t rt_spi_configure(struct rt_spi_device *device,
/* reset the CS pin */
if (device->cs_pin != PIN_NONE)
{
rt_err_t result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
rt_err_t result = spi_lock(device->bus);
if (result == RT_EOK)
{
if (cfg->mode & RT_SPI_CS_HIGH)
@@ -222,7 +266,7 @@ rt_err_t rt_spi_configure(struct rt_spi_device *device,
{
rt_pin_write(device->cs_pin, PIN_HIGH);
}
rt_mutex_release(&(device->bus->lock));
spi_unlock(device->bus);
}
else
{
@@ -258,7 +302,7 @@ rt_err_t rt_spi_send_then_send(struct rt_spi_device *device,
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
result = spi_lock(device->bus);
if (result == RT_EOK)
{
if (device->bus->owner != device)
@@ -316,7 +360,7 @@ rt_err_t rt_spi_send_then_send(struct rt_spi_device *device,
}
__exit:
rt_mutex_release(&(device->bus->lock));
spi_unlock(device->bus);
return result;
}
@@ -333,7 +377,7 @@ rt_err_t rt_spi_send_then_recv(struct rt_spi_device *device,
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
result = spi_lock(device->bus);
if (result == RT_EOK)
{
if (device->bus->owner != device)
@@ -391,7 +435,7 @@ rt_err_t rt_spi_send_then_recv(struct rt_spi_device *device,
}
__exit:
rt_mutex_release(&(device->bus->lock));
spi_unlock(device->bus);
return result;
}
@@ -407,7 +451,7 @@ rt_ssize_t rt_spi_transfer(struct rt_spi_device *device,
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
result = spi_lock(device->bus);
if (result == RT_EOK)
{
if (device->bus->owner != device)
@@ -449,7 +493,7 @@ rt_ssize_t rt_spi_transfer(struct rt_spi_device *device,
}
__exit:
rt_mutex_release(&(device->bus->lock));
spi_unlock(device->bus);
return result;
}
@@ -510,7 +554,7 @@ struct rt_spi_message *rt_spi_transfer_message(struct rt_spi_device *device,
if (index == RT_NULL)
return index;
result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
result = spi_lock(device->bus);
if (result != RT_EOK)
{
return index;
@@ -548,7 +592,7 @@ struct rt_spi_message *rt_spi_transfer_message(struct rt_spi_device *device,
__exit:
/* release bus lock */
rt_mutex_release(&(device->bus->lock));
spi_unlock(device->bus);
return index;
}
@@ -560,7 +604,7 @@ rt_err_t rt_spi_take_bus(struct rt_spi_device *device)
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
result = spi_lock(device->bus);
if (result != RT_EOK)
{
return -RT_EBUSY;
@@ -579,7 +623,7 @@ rt_err_t rt_spi_take_bus(struct rt_spi_device *device)
else
{
/* configure SPI bus failed */
rt_mutex_release(&(device->bus->lock));
spi_unlock(device->bus);
return result;
}
@@ -595,7 +639,7 @@ rt_err_t rt_spi_release_bus(struct rt_spi_device *device)
RT_ASSERT(device->bus->owner == device);
/* release lock */
return rt_mutex_release(&(device->bus->lock));
return spi_unlock(device->bus);
}
rt_err_t rt_spi_take(struct rt_spi_device *device)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -7,6 +7,7 @@
* Date Author Notes
* 2016/5/20 bernard the first version
* 2020/1/7 redoc add include
* 2025-10-30 wdfk-prog enable interrupt-safe operations using spinlocks
*/
#ifndef __DEV_SPI_FLASH_H__
@@ -20,6 +21,10 @@ struct spi_flash_device
struct rt_device_blk_geometry geometry;
struct rt_spi_device * rt_spi_device;
struct rt_mutex lock;
#ifdef RT_USING_SPI_ISR
rt_base_t _isr_lvl;
struct rt_spinlock _spinlock;
#endif /* RT_USING_SPI_ISR */
void * user_data;
};

View File

@@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2016-09-28 armink first version.
* 2025-10-30 wdfk-prog enable interrupt-safe operations using spinlocks
*/
#include <stdint.h>
@@ -233,7 +234,17 @@ static void spi_lock(const sfud_spi *spi) {
RT_ASSERT(sfud_dev);
RT_ASSERT(rtt_dev);
rt_mutex_take(&(rtt_dev->lock), RT_WAITING_FOREVER);
/* If the scheduler is started and in thread context */
if (rt_scheduler_is_available())
{
rt_mutex_take(&(rtt_dev->lock), RT_WAITING_FOREVER);
}
else
{
#ifdef RT_USING_SPI_ISR
rtt_dev->_isr_lvl = rt_spin_lock_irqsave(&rtt_dev->_spinlock);
#endif /* RT_USING_SPI_ISR */
}
}
static void spi_unlock(const sfud_spi *spi) {
@@ -244,12 +255,32 @@ static void spi_unlock(const sfud_spi *spi) {
RT_ASSERT(sfud_dev);
RT_ASSERT(rtt_dev);
rt_mutex_release(&(rtt_dev->lock));
/* If the scheduler is started and in thread context */
if (rt_scheduler_is_available())
{
rt_mutex_release(&(rtt_dev->lock));
}
else
{
#ifdef RT_USING_SPI_ISR
rt_spin_unlock_irqrestore(&rtt_dev->_spinlock, rtt_dev->_isr_lvl);
#endif /* RT_USING_SPI_ISR */
}
}
static void retry_delay_100us(void) {
/* 100 microsecond delay */
rt_thread_delay((RT_TICK_PER_SECOND * 1 + 9999) / 10000);
if (rt_scheduler_is_available())
{
rt_thread_delay((RT_TICK_PER_SECOND * 1 + 9999) / 10000);
}
else
{
#ifdef RT_USING_SPI_ISR
extern void rt_hw_us_delay(rt_uint32_t us);
rt_hw_us_delay(100);
#endif /* RT_USING_SPI_ISR */
}
}
sfud_err sfud_spi_port_init(sfud_flash *flash) {
@@ -320,6 +351,9 @@ rt_spi_flash_device_t rt_sfud_flash_probe_ex(const char *spi_flash_dev_name, con
if (rtt_dev) {
rt_memset(rtt_dev, 0, sizeof(struct spi_flash_device));
/* initialize lock */
#ifdef RT_USING_SPI_ISR
rt_spin_lock_init(&rtt_dev->_spinlock);
#endif /* RT_USING_SPI_ISR */
rt_mutex_init(&(rtt_dev->lock), spi_flash_dev_name, RT_IPC_FLAG_PRIO);
}
@@ -569,9 +603,9 @@ static void sf(uint8_t argc, char **argv) {
sfud_dev = (sfud_flash_t)rtt_dev->user_data;
if (sfud_dev->chip.capacity < 1024 * 1024) {
rt_kprintf("%d KB %s is current selected device.\n", sfud_dev->chip.capacity / 1024, sfud_dev->name);
rt_kprintf("%ld KB %s is current selected device.\n", sfud_dev->chip.capacity / 1024, sfud_dev->name);
} else {
rt_kprintf("%d MB %s is current selected device.\n", sfud_dev->chip.capacity / 1024 / 1024,
rt_kprintf("%ld MB %s is current selected device.\n", sfud_dev->chip.capacity / 1024 / 1024,
sfud_dev->name);
}
}
@@ -591,12 +625,12 @@ static void sf(uint8_t argc, char **argv) {
if (data) {
result = sfud_read(sfud_dev, addr, size, data);
if (result == SFUD_SUCCESS) {
rt_kprintf("Read the %s flash data success. Start from 0x%08X, size is %ld. The data is:\n",
rt_kprintf("Read the %s flash data success. Start from 0x%08lX, size is %ld. The data is:\n",
sfud_dev->name, addr, size);
rt_kprintf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
for (i = 0; i < size; i += HEXDUMP_WIDTH)
{
rt_kprintf("[%08X] ", addr + i);
rt_kprintf("[%08lX] ", addr + i);
/* dump hex */
for (j = 0; j < HEXDUMP_WIDTH; j++) {
if (i + j < size) {
@@ -634,7 +668,7 @@ static void sf(uint8_t argc, char **argv) {
}
result = sfud_write(sfud_dev, addr, size, data);
if (result == SFUD_SUCCESS) {
rt_kprintf("Write the %s flash data success. Start from 0x%08X, size is %ld.\n",
rt_kprintf("Write the %s flash data success. Start from 0x%08lX, size is %ld.\n",
sfud_dev->name, addr, size);
rt_kprintf("Write data: ");
for (i = 0; i < size; i++) {
@@ -656,7 +690,7 @@ static void sf(uint8_t argc, char **argv) {
size = strtol(argv[3], NULL, 0);
result = sfud_erase(sfud_dev, addr, size);
if (result == SFUD_SUCCESS) {
rt_kprintf("Erase the %s flash data success. Start from 0x%08X, size is %ld.\n", sfud_dev->name,
rt_kprintf("Erase the %s flash data success. Start from 0x%08lX, size is %ld.\n", sfud_dev->name,
addr, size);
}
}
@@ -700,7 +734,7 @@ static void sf(uint8_t argc, char **argv) {
result = sfud_erase(sfud_dev, addr, size);
if (result == SFUD_SUCCESS) {
time_cast = rt_tick_get() - start_time;
rt_kprintf("Erase benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND,
rt_kprintf("Erase benchmark success, total time: %ld.%03ldS.\n", time_cast / RT_TICK_PER_SECOND,
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
} else {
rt_kprintf("Erase benchmark has an error. Error code: %d.\n", result);
@@ -716,13 +750,13 @@ static void sf(uint8_t argc, char **argv) {
}
result = sfud_write(sfud_dev, addr + i, cur_op_size, write_data);
if (result != SFUD_SUCCESS) {
rt_kprintf("Writing %s failed, already wr for %lu bytes, write %d each time\n", sfud_dev->name, i, write_size);
rt_kprintf("Writing %s failed, already wr for %u bytes, write %d each time\n", sfud_dev->name, i, write_size);
break;
}
}
if (result == SFUD_SUCCESS) {
time_cast = rt_tick_get() - start_time;
rt_kprintf("Write benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND,
rt_kprintf("Write benchmark success, total time: %ld.%03ldS.\n", time_cast / RT_TICK_PER_SECOND,
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
} else {
rt_kprintf("Write benchmark has an error. Error code: %d.\n", result);
@@ -745,13 +779,13 @@ static void sf(uint8_t argc, char **argv) {
}
if (result != SFUD_SUCCESS) {
rt_kprintf("Read %s failed, already rd for %lu bytes, read %d each time\n", sfud_dev->name, i, read_size);
rt_kprintf("Read %s failed, already rd for %u bytes, read %d each time\n", sfud_dev->name, i, read_size);
break;
}
}
if (result == SFUD_SUCCESS) {
time_cast = rt_tick_get() - start_time;
rt_kprintf("Read benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND,
rt_kprintf("Read benchmark success, total time: %ld.%03ldS.\n", time_cast / RT_TICK_PER_SECOND,
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
} else {
rt_kprintf("Read benchmark has an error. Error code: %d.\n", result);

View File

@@ -796,7 +796,7 @@ static int cmd_tail(int argc, char **argv)
}
}
rt_kprintf("\nTotal Number of lines:%d\n", total_lines);
rt_kprintf("\nTotal Number of lines:%ld\n", total_lines);
if (start_line != 0)
{
@@ -818,7 +818,7 @@ static int cmd_tail(int argc, char **argv)
close(fd);
return -1;
}
rt_kprintf("Required Number of lines:%d\n", required_lines);
rt_kprintf("Required Number of lines:%ld\n", required_lines);
target_line = total_lines - required_lines;
lseek(fd, 0, SEEK_SET); /* back to head */

View File

@@ -6,6 +6,35 @@
* Change Logs:
* Date Author Notes
* 2023-12-22 Shell Support hook list
* 2025-11-11 Ze-Hou Add standardized utest documentation block
*/
/**
* Test Case Name: Kernel Core Hook List Test
*
* Test Objectives:
* - Validate the RT-Thread hook list mechanism for thread initialization events
* - Test registration, invocation, and removal of thread-initialized hooks
*
* Test Scenarios:
* - Register two hook nodes for thread initialization
* - Initialize a thread and check that both hooks are called
* - Remove one hook and re-initialize the thread, verifying only the remaining hook is called
* - Detach thread and clean up hooks after test
*
* Verification Metrics:
* - hooker1_ent_count and hooker2_ent_count increment as expected
* - After first thread init: both counters == 1
* - After second thread init (with one hook removed): hooker1_ent_count == 2, hooker2_ent_count == 1
* - After running this test case, check whether all assertions pass.
*
* Dependencies:
* - Enable Hook List Test (RT-Thread Utestcases -> Kernel Core -> Hook List Test)
* - Test on any RT-Thread supported platform (e.g., qemu-virt64-riscv)
*
* Expected Results:
* - After executing this test in msh, the expected output should be:
* "[ PASSED ] [ result ] testcase (core.hooklist)"
*/
#include <rtthread.h>

View File

@@ -5,8 +5,51 @@
*
* Change Logs:
* Date Author Notes
* 2021-09.01 yangjie the firet version
* 2021-09.01 yangjie the first version
* 2021-10.11 mazhiyuan add idle, yield, suspend, control, priority, delay_until
* 2025-11-12 Ze-Hou add standardized utest documentation block
*/
/**
* Test Case Name: Kernel Core Thread Test
*
* Test Objectives:
* - Validate the core thread management features of the RT-Thread kernel:
* 1. Thread creation methods (dynamic and static)
* 2. Timing accuracy (resolution) of the rt_thread_delay API
* 3. Use of the idle hook
* 4. RT-Threads thread yield mechanism
* 5. RT-Threads thread control interfaces
* 6. Thread priorities
* 7. Absolute delay functionality
* 8. Time-slice scheduling among threads with the same priority
*
* Test Scenarios:
* - Create, start, and delete a dynamic thread to verify dynamic thread lifecycle management
* - Initialize, start, and detach a static thread to verify static thread lifecycle management
* - Delay a thread for a specific tick count and check timing accuracy
* - Register and remove an idle hook, verifying it is called as expected
* - Use thread yield to test scheduler fairness among threads of the same priority
* - Use thread control APIs to start, change priority, and close a thread, verifying each operation
* - Create a thread with a specific priority and verify it runs as expected
* - Use rt_thread_delay_until to test absolute delay and periodic task timing
* - Create multiple threads with the same priority and test time-slice scheduling fairness
*
* Verification Metrics:
* - Threads are created, started, deleted, and detached successfully
* - The precision of both relative delay and absolute delay is correct.
* - Idle hook is invoked as expected during thread idle periods
* - Thread yield causes correct scheduling among threads of the same priority
* - Thread control APIs (startup, change priority, close) work as intended and update thread state correctly
* - Time-slice scheduling distributes CPU time fairly among threads of the same priority (difference < 30%)
*
* Dependencies:
* - Enable Thread Test (RT-Thread Utestcases -> Kernel Core -> Thread Test)
* - Test on any RT-Thread supported platform (e.g., qemu-virt64-riscv)
*
* Expected Results:
* - After executing this test in msh, the expected output should be:
* "[ PASSED ] [ result ] testcase (core.thread_tc)"
*/
#define __RT_IPC_SOURCE__ /* include internal API for utest */