Compare commits

...

6 Commits

Author SHA1 Message Date
wdfk-prog
44cf90a4ef fix(can): Resolve potential race condition in message transmission
Setting the send status flag `sndchange` after calling the can->ops->sendmsg function
could lead to a race condition if a transmission timeout occurs, resulting in incorrect state handling.
This patch moves the operation of setting the `sndchange` flag to before the call to can->ops->sendmsg.
This ensures that the mailbox's status is correctly marked as "sending" before the hardware begins transmission,
making the driver's state management more robust and reliable, especially in handling exceptions like timeouts.

Additionally, new macros for CAN filter modes have been added in dev_can.h.
2025-11-08 11:52:25 +08:00
Rbb666
2c9257831e utest:Fix signal info node leak in signal_tc when running multiple times. 2025-11-08 10:41:55 +08:00
RyanCW
6e184553d1 [bsp][gd32] 串口 tx buf应该可以设置为0 (#10908) 2025-11-08 10:39:25 +08:00
CYFS
cbe9f5d82c fix:stm32 can build error (#10909) 2025-11-08 10:38:42 +08:00
ChengyangMa
5b87ac609e [libc][syscall] add detailed function comments for memory management 2025-11-07 20:52:08 -05:00
Liu Changjie
8153fe5fd9 [libc][syscalls] 新手PR任务_增加文件操作相关函数的文档注释 2025-11-07 20:50:13 -05:00
7 changed files with 118 additions and 21 deletions

View File

@@ -56,7 +56,7 @@ menu "On-chip Peripheral Drivers"
config BSP_UART0_TX_BUFSIZE
int "Set UART0 TX buffer size"
range 64 65535
range 0 65535
depends on BSP_USING_UART0 && RT_USING_SERIAL_V2
default 128
@@ -88,7 +88,7 @@ menu "On-chip Peripheral Drivers"
config BSP_UART1_TX_BUFSIZE
int "Set UART1 TX buffer size"
range 64 65535
range 0 65535
depends on BSP_USING_UART1 && RT_USING_SERIAL_V2
default 128
@@ -120,7 +120,7 @@ menu "On-chip Peripheral Drivers"
config BSP_UART2_TX_BUFSIZE
int "Set UART2 TX buffer size"
range 64 65535
range 0 65535
depends on BSP_USING_UART2 && RT_USING_SERIAL_V2
default 128
@@ -152,7 +152,7 @@ menu "On-chip Peripheral Drivers"
config BSP_UART3_TX_BUFSIZE
int "Set UART3 TX buffer size"
range 64 65535
range 0 65535
depends on BSP_USING_UART3 && RT_USING_SERIAL_V2
default 128
@@ -184,7 +184,7 @@ menu "On-chip Peripheral Drivers"
config BSP_UART4_TX_BUFSIZE
int "Set UART4 TX buffer size"
range 64 65535
range 0 65535
depends on BSP_USING_UART4 && RT_USING_SERIAL_V2
default 128
@@ -216,7 +216,7 @@ menu "On-chip Peripheral Drivers"
config BSP_UART5_TX_BUFSIZE
int "Set UART5 TX buffer size"
range 64 65535
range 0 65535
depends on BSP_USING_UART5 && RT_USING_SERIAL_V2
default 128
@@ -248,7 +248,7 @@ menu "On-chip Peripheral Drivers"
config BSP_UART6_TX_BUFSIZE
int "Set UART6 TX buffer size"
range 64 65535
range 0 65535
depends on BSP_USING_UART6 && RT_USING_SERIAL_V2
default 128
@@ -280,7 +280,7 @@ menu "On-chip Peripheral Drivers"
config BSP_UART7_TX_BUFSIZE
int "Set UART7 TX buffer size"
range 64 65535
range 0 65535
depends on BSP_USING_UART7 && RT_USING_SERIAL_V2
default 128
endif

View File

@@ -500,7 +500,7 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
*
* @return `RT_EOK` on success, or an error code on failure.
*/
static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
static rt_ssize_t _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
{
CAN_HandleTypeDef *hcan;
hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
@@ -649,7 +649,7 @@ static rt_ssize_t _can_sendmsg_nonblocking(struct rt_can_device *can, const void
return RT_EOK;
}
static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
static rt_ssize_t _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
{
HAL_StatusTypeDef status;
CAN_HandleTypeDef *hcan;

View File

@@ -186,6 +186,7 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
no = ((rt_ubase_t)tx_tosnd - (rt_ubase_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list);
tx_tosnd->result = RT_CAN_SND_RESULT_WAIT;
rt_completion_init(&tx_tosnd->completion);
can->status.sndchange |= 1<<no;
if (can->ops->sendmsg(can, data, no) != RT_EOK)
{
/* send failed. */
@@ -196,7 +197,6 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
goto err_ret;
}
can->status.sndchange |= 1<<no;
if (rt_completion_wait(&(tx_tosnd->completion), RT_CANSND_MSG_TIMEOUT) != RT_EOK)
{
level = rt_hw_local_irq_disable();
@@ -286,11 +286,12 @@ rt_inline int _can_int_tx_priv(struct rt_can_device *can, const struct rt_can_ms
tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_WAIT;
rt_hw_local_irq_enable(level);
can->status.sndchange |= 1<<no;
if (can->ops->sendmsg(can, data, no) != RT_EOK)
{
continue;
}
can->status.sndchange |= 1<<no;
if (rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_CANSND_MSG_TIMEOUT) != RT_EOK)
{
can->status.sndchange &= ~ (1<<no);

View File

@@ -68,6 +68,9 @@ enum CANBAUD
#define RT_CAN_MODE_PRIV 0x01
#define RT_CAN_MODE_NOPRIV 0x00
#define RT_CAN_MODE_MASK 0x00
#define RT_CAN_MODE_LIST 0x01
/**
* @defgroup group_drivers_can CAN Driver
* @brief CAN driver api

View File

@@ -27,6 +27,21 @@
#pragma import(__use_no_heap)
#endif /* __CC_ARM */
/**
* @brief Allocate memory block
*
* Allocates a block of size bytes of memory, returning a pointer to the
* beginning of the block. The content of the newly allocated block of
* memory is not initialized, remaining with indeterminate values.
*
* @param[in] n the size of the memory block, in bytes.
*
* @return On success, a pointer to the memory block allocated by the function.
* If the system is configured without heap (RT_USING_HEAP is not defined),
* the function will assert and return RT_NULL.
*
* @note The returned pointer is always suitably aligned for any built-in type.
*/
void *malloc(size_t n)
{
#ifdef RT_USING_HEAP
@@ -38,6 +53,28 @@ void *malloc(size_t n)
}
RTM_EXPORT(malloc);
/**
* @brief Reallocate memory block
*
* Changes the size of the memory block pointed to by rmem.
* The function may move the memory block to a new location
* (whose address is returned by the function).
* The content of the memory block is preserved up to the
* lesser of the new and old sizes, even if the block is
* moved to a new location. If the new size is larger,
* the value of the newly allocated portion is indeterminate.
*
* @param[in,out] rmem pointer to a memory block previously allocated with
* malloc, calloc or realloc to be reallocated.
* If this is RT_NULL, a new block is allocated and
* a pointer to it is returned by the function.
* @param[in] newsize new size for the memory block, in bytes.
*
* @return A pointer to the reallocated memory block, which may be either
* the same as the rmem pointer or a new location.
* If the system is configured without heap (RT_USING_HEAP is not defined),
* the function will assert and return RT_NULL.
*/
void *realloc(void *rmem, size_t newsize)
{
#ifdef RT_USING_HEAP
@@ -49,6 +86,21 @@ void *realloc(void *rmem, size_t newsize)
}
RTM_EXPORT(realloc);
/**
* @brief Allocate and zero-initialize array
*
* Allocates a block of memory for an array of nelem elements, each of them
* elsize bytes long, and initializes all its bits to zero.
* The effective result is the allocation of a zero-initialized memory block
* of (nelem*elsize) bytes.
*
* @param[in] nelem number of elements to allocate.
* @param[in] elsize size of each element.
*
* @return On success, a pointer to the memory block allocated by the function.
* If the system is configured without heap (RT_USING_HEAP is not defined),
* the function will assert and return RT_NULL.
*/
void *calloc(size_t nelem, size_t elsize)
{
#ifdef RT_USING_HEAP
@@ -60,6 +112,19 @@ void *calloc(size_t nelem, size_t elsize)
}
RTM_EXPORT(calloc);
/**
* @brief Deallocate memory block
*
* A block of memory previously allocated by a call to malloc, calloc or realloc
* is deallocated, making it available again for further allocations.
*
* @param[in] rmem pointer to a memory block previously allocated with malloc,
* calloc or realloc to be deallocated. If a null pointer is
* passed as argument, no action occurs.
*
* @note If the system is configured without heap (RT_USING_HEAP is not defined),
* the function will assert.
*/
void free(void *rmem)
{
#ifdef RT_USING_HEAP

View File

@@ -27,23 +27,23 @@
#endif /* RT_USING_POSIX_STDIO */
#include <posix/stdlib.h>
#define DBG_TAG "armlibc.syscalls"
#define DBG_LVL DBG_INFO
#define DBG_TAG "armlibc.syscalls"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef __clang__
__asm(".global __use_no_semihosting\n\t");
__asm(".global __use_no_semihosting\n\t");
#else
#pragma import(__use_no_semihosting_swi)
#pragma import(__use_no_semihosting_swi)
#endif
/* Standard IO device handles. */
#define STDIN 0
#define STDOUT 1
#define STDERR 2
#define STDIN 0
#define STDOUT 1
#define STDERR 2
/* Standard IO device name defines. */
const char __stdin_name[] = "STDIN";
const char __stdin_name[] = "STDIN";
const char __stdout_name[] = "STDOUT";
const char __stderr_name[] = "STDERR";
@@ -314,7 +314,8 @@ void _ttywrch(int ch)
rt_weak void _sys_exit(int return_code)
{
__rt_libc_exit(return_code);
while (1);
while (1)
;
}
/**
@@ -339,6 +340,12 @@ long _sys_flen(FILEHANDLE fh)
#endif /* DFS_USING_POSIX */
}
/**
* check whether the file is a terminal device.
*
* @param fh - file handle
* @return 1 if is a terminal device, 0 if not
*/
int _sys_istty(FILEHANDLE fh)
{
if ((STDIN <= fh) && (fh <= STDERR))
@@ -347,6 +354,12 @@ int _sys_istty(FILEHANDLE fh)
return 0;
}
/**
* remove a file
*
* @param filename - file name with path
* @return 0 on success, -1 on failed
*/
int remove(const char *filename)
{
#ifdef DFS_USING_POSIX
@@ -360,6 +373,13 @@ int remove(const char *filename)
#ifdef __MICROLIB
#include <stdio.h>
/**
* write a character to file
*
* @param c - character to write
* @param fh - file handle
* @return 1 on success, 0 on failed
*/
int fputc(int c, FILE *f)
{
#ifdef RT_USING_CONSOLE
@@ -370,6 +390,12 @@ int fputc(int c, FILE *f)
#endif /* RT_USING_CONSOLE */
}
/**
* get a character from file
*
* @param fh - file handle
* @return character read, or -1 on failed
*/
int fgetc(FILE *f)
{
#ifdef RT_USING_POSIX_STDIO

View File

@@ -84,6 +84,8 @@ static void rt_signal_unmask_test(void)
uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK);
rt_thread_mdelay(1);
uassert_int_not_equal(recive_sig, signo);
/* unmask to allow pending signal to be delivered and released */
rt_signal_unmask(signo);
}
return;