Compare commits

..

5 Commits

Author SHA1 Message Date
Copilot
30e1e5e9dc Reorganize Group names in build system for clarity and IDE integration #10923 2025-11-16 11:40:53 +08:00
Chuan
ae2a5758bc bsp: k230: add spi driver
Requirement: The BSP for the k230 platform in the RT-Thread repository does not yet have an spi driver.

Solution: Provide spi driver for the k230 platform in the RT-Thread repository.

- Supports SPI0(OSPI) controller with 1/2/4/8 data lines.
- Supports SPI1(QSPI0) and SPI2(QSPI1) controllers with 1/2/4 data lines.
- Implements DMA-based transfers for OSPI, QSPI, and DSPI modes.
- Falls back to standard IRQ-driven transfers for legacy SPI mode (single line).
- Updates documentation in bsp/README.md

Signed-off-by: ChuanN-sudo <fjchuanil@gmail.com>
2025-11-16 11:37:32 +08:00
Chuan
ee20484759 docs(utest):Add standardized documentation for Drivers Core Test
Signed-off-by: ChuanN-sudo <fjchuanil@gmail.com>
2025-11-16 10:28:46 +08:00
ibvqeibob
4e41e700f0 doxygen: add comments for lwp shared memory APIs
Add Doxygen-style comments for the lwp shared memory public APIs
in components/lwp/lwp_shm.c and the related control structure.
This change is documentation-only and does not modify any runtime
behavior or logic.

Signed-off-by: ibvqeibob <2601187225@qq.com>
2025-11-15 14:20:36 +08:00
CYFS
327006cb88 [docs][utest]:Add standardized utest documentation block for serialv2_tc 2025-11-15 14:18:44 +08:00
115 changed files with 2068 additions and 114 deletions

View File

@@ -760,9 +760,9 @@ This document is based on the RT-Thread mainline repository and categorizes the
#### 🟢 K230 (RT-Smart)
| BSP Name | GPIO | UART | I2C | RTC | ADC | PWM | SDIO | HWTimer | WDT |
|----------|------|------|-----|-----|-----|-----|------|---------|-----|
| [k230](k230) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| BSP Name | GPIO | UART | I2C | RTC | ADC | PWM | SDIO | HWTimer | WDT | SPI |
|----------|------|------|-----|-----|-----|-----|------|---------|-----|-----|
| [k230](k230) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
#### 🟢 Xuantie (RT-Smart)

View File

@@ -1,6 +1,12 @@
scons.args: &scons
scons_arg:
- '--strict'
devices.spi:
<<: *scons
kconfig:
- CONFIG_RT_USING_SPI=y
- CONFIG_BSP_USING_SPI=y
- CONFIG_BSP_USING_SPI0=y
devices.i2c:
<<: *scons
kconfig:

View File

@@ -534,8 +534,6 @@ CONFIG_RT_USING_ADT_REF=y
# CONFIG_RT_USING_RT_LINK is not set
# end of Utilities
# CONFIG_RT_USING_VBUS is not set
#
# Memory management
#
@@ -943,6 +941,7 @@ CONFIG_RT_USING_VDSO=y
# CONFIG_PKG_USING_R_RHEALSTONE is not set
# CONFIG_PKG_USING_HEARTBEAT is not set
# CONFIG_PKG_USING_MICRO_ROS_RTTHREAD_PACKAGE is not set
# CONFIG_PKG_USING_CHERRYECAT is not set
# end of system packages
#
@@ -1100,6 +1099,12 @@ CONFIG_RT_USING_VDSO=y
# CONFIG_PKG_USING_GD32_ARM_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_GD32_ARM_SERIES_DRIVER is not set
# end of GD32 Drivers
#
# HPMicro SDK
#
# CONFIG_PKG_USING_HPM_SDK is not set
# end of HPMicro SDK
# end of HAL & SDK Drivers
#
@@ -1619,6 +1624,7 @@ CONFIG_PKG_ZLIB_VER="latest"
#
# Drivers Configuration
#
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_I2C is not set
# CONFIG_BSP_USING_RTC is not set
# CONFIG_BSP_USING_ADC is not set

View File

@@ -1,4 +1,31 @@
menu "Drivers Configuration"
menuconfig BSP_USING_SPI
bool "Enable SPI"
select RT_USING_SPI
select RT_USING_QSPI
default n
if BSP_USING_SPI
config BSP_USING_SPI0
bool "Enable SPI0"
help
Support 1, 2, 4 and 8 lines, Max clock frequency is 200 Mhz.
default n
config BSP_USING_SPI1
bool "Enable SPI1"
help
Support 1, 2, and 4 lines, Max clock frequency is 100 Mhz.
default n
config BSP_USING_SPI2
bool "Enable SPI2"
help
Support 1, 2, and 4 lines, Max clock frequency is 100 Mhz.
default n
endif
menuconfig BSP_USING_I2C
bool "Enable I2C"
select RT_USING_I2C

View File

@@ -0,0 +1,11 @@
# RT-Thread building script for SPI component
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('SPI', src, depend = ['BSP_USING_SPI'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -0,0 +1,734 @@
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_spi.h"
#include <drivers/dev_spi.h>
#include <string.h>
#include "drv_gpio.h"
#include "riscv_io.h"
#include "board.h"
#include "ioremap.h"
#include "sysctl_rst.h"
#include "sysctl_clk.h"
#include "cache.h"
#define DBG_TAG "spi"
#include <rtdbg.h>
struct k230_spi_dev
{
struct rt_spi_bus dev;
void *base;
const char *name;
const char *event_name;
rt_ubase_t pa_base;
rt_uint32_t size;
rt_uint8_t idx;
rt_uint8_t rdse;
rt_uint8_t rdsd;
rt_uint8_t max_line;
rt_uint32_t max_hz;
struct rt_event event;
void *send_buf;
void *recv_buf;
rt_size_t send_length;
rt_size_t recv_length;
rt_uint8_t cell_size;
int vector;
};
static rt_err_t k230_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL);
struct k230_spi_dev *qspi_bus = (struct k230_spi_dev *)device->bus;
k230_spi_reg_t *qspi_reg = (k230_spi_reg_t *)qspi_bus->base;
struct rt_qspi_device *dev = (struct rt_qspi_device *)device;
struct rt_qspi_configuration *qspi_cfg = &dev->config;
struct rt_spi_configuration *qspi_cfg_parent = &dev->config.parent;
rt_uint8_t dfs, mode, spi_ff;
rt_uint32_t max_hz, qspi_clk;
if (qspi_cfg->qspi_dl_width > qspi_bus->max_line || qspi_cfg->qspi_dl_width == 0)
{
return -RT_EINVAL;
}
if (qspi_cfg_parent->data_width < 4 || qspi_cfg_parent->data_width > 32)
{
return -RT_EINVAL;
}
/* Check if the clock frequency exceeds the hardware limits */
max_hz = qspi_cfg_parent->max_hz;
if (max_hz > qspi_bus->max_hz)
{
max_hz = qspi_bus->max_hz;
}
/* Get QSPI Controller Clock Frequency */
if (qspi_bus->idx == 0)
{
qspi_clk = sysctl_clk_get_leaf_freq(SYSCTL_CLK_SSI0);
}
else if (qspi_bus->idx == 1)
{
qspi_clk = sysctl_clk_get_leaf_freq(SYSCTL_CLK_SSI1);
}
else if (qspi_bus->idx == 2)
{
qspi_clk = sysctl_clk_get_leaf_freq(SYSCTL_CLK_SSI2);
}
else
{
return -RT_EINVAL;
}
/* Set SPI_FRF to config SPI mode*/
if (qspi_cfg->qspi_dl_width == 1)
{
spi_ff = SPI_FRF_STD_SPI;
}
else if (qspi_cfg->qspi_dl_width == 2)
{
spi_ff = SPI_FRF_DUAL_SPI;
}
else if (qspi_cfg->qspi_dl_width == 4)
{
spi_ff = SPI_FRF_QUAD_SPI;
}
else if (qspi_cfg->qspi_dl_width == 8)
{
spi_ff = SPI_FRF_OCT_SPI;
}
else
{
return -RT_EINVAL;
}
/*
* dfs: Data Frame Size, Write dfs into bits 8-9 of the register ctrlr0
* mode: SPI mode(CPOL and CPHA)Write mode into bits 0-4 of the register ctrlr0
*/
mode = qspi_cfg_parent->mode & RT_SPI_MODE_3;
dfs = qspi_cfg_parent->data_width - 1;
qspi_reg->ssienr = 0;
qspi_reg->ser = 0;
qspi_reg->baudr = qspi_clk / max_hz;
qspi_reg->rx_sample_delay = qspi_bus->rdse << 16 | qspi_bus->rdsd;
qspi_reg->axiawlen = SSIC_AXI_BLW << 8;
qspi_reg->axiarlen = SSIC_AXI_BLW << 8;
qspi_reg->ctrlr0 = (dfs) | (mode << 8) | (spi_ff << 22);
return RT_EOK;
}
static rt_ssize_t k230_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
struct k230_spi_dev *qspi_bus = (struct k230_spi_dev *)device->bus;
k230_spi_reg_t *qspi_reg = (k230_spi_reg_t *)qspi_bus->base;
struct rt_qspi_device *dev = (struct rt_qspi_device *)device;
struct rt_qspi_configuration *qspi_cfg = &dev->config;
struct rt_spi_configuration *qspi_cfg_parent = &dev->config.parent;
struct rt_qspi_message *msg = (struct rt_qspi_message *)message;
struct rt_spi_message *msg_parent = message;
/* Multi-line SPI transfers (2, 4, or 8 lines) DSPI QSPI OSPI */
if (msg->qspi_data_lines > 1)
{
rt_uint8_t trans_type = 0;
if (msg->qspi_data_lines > qspi_cfg->qspi_dl_width)
{
LOG_E("data line is invalid");
return 0;
}
/* Check other parameters */
if (qspi_cfg_parent->data_width & (msg->qspi_data_lines - 1))
{
LOG_E("data line and data width do not match");
return 0;
}
if (msg->instruction.qspi_lines != 1 && msg->instruction.qspi_lines != msg->qspi_data_lines)
{
LOG_E("instruction line is invalid");
return 0;
}
if (msg->address.size & 3 || msg->address.size > 32)
{
LOG_E("address size is invalid");
return 0;
}
if (msg->address.size && msg->address.qspi_lines != 1 && msg->address.qspi_lines != msg->qspi_data_lines)
{
LOG_E("address line is invalid");
return 0;
}
if (msg_parent->length > 0x10000)
{
LOG_E("data length is invalid, more than 0x10000");
return 0;
}
if (msg->instruction.qspi_lines != 1)
{
trans_type = 2;
}
if (msg->address.size)
{
if (msg->address.qspi_lines != 1)
{
trans_type = trans_type ? trans_type : 1;
}
else if (trans_type != 0)
{
LOG_E("instruction or address line is invalid");
return 0;
}
}
if (msg->dummy_cycles > 31)
{
LOG_E("dummy cycle is invalid");
return 0;
}
rt_uint8_t tmod = msg_parent->recv_buf ? SPI_TMOD_RO : SPI_TMOD_TO;
rt_size_t length = msg_parent->length;
rt_size_t txfthr = length > (SSIC_TX_ABW / 2) ? (SSIC_TX_ABW / 2) : length - 1;
rt_uint8_t cell_size = (qspi_cfg_parent->data_width + 7) >> 3;
rt_uint8_t *buf = RT_NULL;
/* Allocate buffer for DMA transfer */
if (length)
{
buf = rt_malloc_align(CACHE_ALIGN_TOP(length * cell_size), L1_CACHE_BYTES);
if (buf == RT_NULL)
{
LOG_E("alloc mem error");
return 0;
}
}
/* msg->address.size & ~0x03: Round address.size down to the nearest multiple of 4 and write it to ADDR_L[5:2] */
qspi_reg->spi_ctrlr0 = trans_type | (msg->address.size & ~0x03) | (0x2 << 8) | (msg->dummy_cycles << 11);
qspi_reg->ctrlr0 &= ~((3 << 22) | (3 << 10));
/* Config SPI frame format and transmission mode */
if (length)
{
qspi_reg->ctrlr0 |= (tmod << 10);
qspi_reg->txftlr = (txfthr << 16) | (SSIC_TX_ABW / 2);
qspi_reg->rxftlr = (SSIC_RX_ABW - 1);
qspi_reg->imr = (1 << 11) | (1 << 8);
qspi_reg->dmacr = (1 << 6) | (3 << 3) | (1 << 2);
qspi_reg->ctrlr1 = length - 1;
qspi_reg->spidr = msg->instruction.content;
qspi_reg->spiar = msg->address.content;
if (tmod == SPI_TMOD_TO)
{
rt_memcpy(buf, msg_parent->send_buf, length * cell_size);
rt_hw_cpu_dcache_clean(buf, CACHE_ALIGN_TOP(length * cell_size));
}
qspi_reg->axiar0 = (rt_uint32_t)((uint64_t)buf);
qspi_reg->axiar1 = (rt_uint32_t)((uint64_t)buf >> 32);
}
else
{
tmod = SPI_TMOD_TO;
qspi_reg->ctrlr0 |= (tmod << 10);
qspi_reg->txftlr = ((SSIC_TX_ABW - 1) << 16) | (SSIC_TX_ABW - 1);
qspi_reg->rxftlr = (SSIC_RX_ABW - 1);
qspi_reg->imr = 0;
qspi_reg->dmacr = 0;
}
rt_event_control(&qspi_bus->event, RT_IPC_CMD_RESET, 0);
qspi_reg->ser = 1;
qspi_reg->ssienr = 1;
rt_uint32_t event;
rt_err_t err;
/*
* Config QSPI address and instruction,
* if data is empty, unable dma and send address and instruction by write data register.
*/
if (length)
{
err = rt_event_recv(&qspi_bus->event, BIT(SSI_DONE) | BIT(SSI_AXIE),
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 1000, &event);
}
else
{
err = RT_EOK;
event = 0;
qspi_reg->dr[0] = msg->instruction.content;
length++;
if (msg->address.size)
{
qspi_reg->dr[0] = msg->address.content;
length++;
}
qspi_reg->txftlr = 0;
/* Wait for SPI transfer to complete (busy-wait) */
while ((qspi_reg->sr & 0x5) != 0x4)
{
/* Busy wait */
}
}
qspi_reg->ser = 0;
qspi_reg->ssienr = 0;
if (err == -RT_ETIMEOUT)
{
LOG_E("qspi%d transfer data timeout", qspi_bus->idx);
if (buf)
{
rt_free_align(buf);
}
return 0;
}
if (event & BIT(SSI_AXIE))
{
LOG_E("qspi%d dma error", qspi_bus->idx);
if (buf)
{
rt_free_align(buf);
}
return 0;
}
/* Read data from FIFO */
if (tmod == SPI_TMOD_RO)
{
rt_hw_cpu_dcache_invalidate(buf, CACHE_ALIGN_TOP(length * cell_size));
rt_memcpy(msg_parent->recv_buf, buf, length * cell_size);
}
if (buf)
{
rt_free_align(buf);
}
return length;
}
/* Standard SPI transfers */
else
{
if (msg_parent->length == 0)
{
return 0;
}
rt_uint8_t cell_size = (qspi_cfg_parent->data_width + 7) >> 3;
rt_size_t length = msg_parent->length;
rt_size_t count = length > 0x10000 ? 0x10000 : length;
rt_size_t send_single = 0, send_length = 0, recv_single = 0, recv_length = 0;
void *send_buf = (void *)msg_parent->send_buf;
void *recv_buf = msg_parent->recv_buf;
rt_uint8_t tmod = send_buf ? SPI_TMOD_TO : SPI_TMOD_EPROMREAD;
tmod = recv_buf ? tmod & SPI_TMOD_RO : tmod;
/* Check Qspi Parameters */
if (tmod == SPI_TMOD_EPROMREAD)
{
LOG_E("send_buf and recv_buf cannot both be empty");
return 0;
}
if (tmod == SPI_TMOD_RO && qspi_cfg_parent->data_width == 8)
{
if ((msg->address.size & 7) || (msg->dummy_cycles & 7))
{
LOG_E("instruction, address, dummy_cycles invalid");
LOG_E("For read-only mode the instruction, address, dummy_cycles must be set to zero");
LOG_E("For eeprom-read mode the instruction, address, dummy_cycles must be set to multiples of 8");
return 0;
}
else if (msg->address.size)
{
if (length > 0x10000)
{
LOG_E("For eeprom-read mode, data length cannot exceed 0x10000");
return 0;
}
tmod = SPI_TMOD_EPROMREAD;
}
}
/* Prepare the send buffer*/
if (send_buf)
{
send_single = count;
send_buf = rt_malloc(count * cell_size);
if (send_buf == RT_NULL)
{
LOG_E("alloc mem error");
return 0;
}
rt_memcpy(send_buf, msg_parent->send_buf, count * cell_size);
}
else if (tmod == SPI_TMOD_EPROMREAD)
{
send_single = 1 + msg->address.size / 8 + msg->dummy_cycles / 8;
send_buf = rt_malloc(send_single);
if (send_buf == RT_NULL)
{
LOG_E("alloc mem error");
return 0;
}
rt_uint8_t *temp = send_buf;
*temp++ = msg->instruction.content;
for (int i = msg->address.size / 8; i; i--)
{
*temp++ = msg->address.content >> ((i - 1) * 8);
}
for (int i = msg->dummy_cycles / 8; i; i--)
{
*temp++ = 0xFF;
}
}
/* Prepare the receive buffer*/
if (recv_buf)
{
recv_single = count;
recv_buf = rt_malloc(count * cell_size);
if (recv_buf == RT_NULL)
{
LOG_E("alloc mem error");
if (send_buf)
{
rt_free(send_buf);
}
return 0;
}
}
send_length = 0;
recv_length = 0;
qspi_bus->cell_size = cell_size;
qspi_bus->send_buf = send_buf;
qspi_bus->recv_buf = recv_buf;
qspi_bus->send_length = send_single;
qspi_bus->recv_length = recv_single;
qspi_reg->ctrlr0 &= ~((3 << 22) | (3 << 10));
qspi_reg->ctrlr0 |= (tmod << 10);
qspi_reg->ctrlr1 = count - 1;
qspi_reg->txftlr = ((SSIC_TX_ABW / 2) << 16) | (SSIC_TX_ABW / 2);
qspi_reg->rxftlr = count >= (SSIC_RX_ABW / 2) ? (SSIC_RX_ABW / 2 - 1) : count - 1;
qspi_reg->dmacr = 0;
/* Interrupt transmit or receive */
qspi_reg->imr = (1 << 4) | (1 << 0);
rt_event_control(&qspi_bus->event, RT_IPC_CMD_RESET, 0);
qspi_reg->ser = 1;
qspi_reg->ssienr = 1;
if (tmod == SPI_TMOD_RO)
qspi_reg->dr[0] = 0;
rt_uint32_t event;
rt_err_t err;
while (RT_TRUE)
{
/* Waiting for transfer events */
err = rt_event_recv(&qspi_bus->event, BIT(SSI_TXE) | BIT(SSI_RXF),
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 10000, &event);
if (err == -RT_ETIMEOUT)
{
LOG_E("qspi%d transfer data timeout", qspi_bus->idx);
length = 0;
if (send_buf)
{
rt_free(send_buf);
}
if (recv_buf)
{
rt_free(recv_buf);
}
return 0;
}
/* Handle Transmit buffer empty */
if (event & BIT(SSI_TXE))
{
send_length += send_single;
if (send_length < length && tmod <= SPI_TMOD_TO)
{
count = length - send_length;
count = count > 0x10000 ? 0x10000 : count;
rt_memcpy(send_buf, msg_parent->send_buf + send_length * cell_size, count * cell_size);
qspi_bus->send_buf = send_buf;
qspi_bus->send_length = count;
send_single = count;
qspi_reg->txftlr = ((SSIC_TX_ABW / 2) << 16) | (SSIC_TX_ABW / 2);
if (tmod == SPI_TMOD_TO)
qspi_reg->imr |= (1 << 0);
}
else if (tmod == SPI_TMOD_TO)
{
/* Wait for SPI transfer to complete (busy-wait) */
while ((qspi_reg->sr & 0x5) != 0x4)
{
/* Busy wait */
}
break;
}
}
/* Handle receive buffer full */
if (event & BIT(SSI_RXF))
{
rt_memcpy(msg_parent->recv_buf + recv_length * cell_size, recv_buf, recv_single * cell_size);
recv_length += recv_single;
if (recv_length >= length)
{
break;
}
count = length - recv_length;
count = count > 0x10000 ? 0x10000 : count;
qspi_bus->recv_buf = recv_buf;
qspi_bus->recv_length = count;
recv_single = count;
qspi_reg->rxftlr = count >= (SSIC_RX_ABW / 2) ? (SSIC_RX_ABW / 2 - 1) : count - 1;
if (tmod == SPI_TMOD_TR)
{
qspi_reg->imr |= (1 << 0) | (1 << 4);
}
else if (tmod == SPI_TMOD_RO)
{
qspi_reg->imr |= (1 << 4);
qspi_reg->ssienr = 0;
qspi_reg->ctrlr1 = count - 1;
qspi_reg->ssienr = 1;
/* Trigger two dummy transfers to restart SPI read in read-only mode.
* This is required by the hardware to ensure correct data reception.
*/
qspi_reg->dr[0] = 0;
qspi_reg->dr[0] = 0;
}
}
}
qspi_reg->ser = 0;
qspi_reg->ssienr = 0;
if (send_buf)
{
rt_free(send_buf);
}
if (recv_buf)
{
rt_free(recv_buf);
}
return length;
}
return 0;
}
static const struct rt_spi_ops k230_qspi_ops =
{
.configure = k230_spi_configure,
.xfer = k230_spi_xfer,
};
static void k230_spi_irq(int vector, void *param)
{
struct k230_spi_dev *qspi_bus = param;
k230_spi_reg_t *qspi_reg = (k230_spi_reg_t *)qspi_bus->base;
vector -= IRQN_SPI0;
vector %= (IRQN_SPI1 - IRQN_SPI0);
/* Handle transmit buffer empty interrupt */
if (vector == SSI_TXE)
{
if (qspi_bus->send_buf == RT_NULL)
{
qspi_reg->imr &= ~1;
}
else if (qspi_bus->cell_size == 1)
{
while ((qspi_bus->send_length) && (qspi_reg->sr & 2))
{
qspi_reg->dr[0] = *((rt_uint8_t *)qspi_bus->send_buf);
qspi_bus->send_buf++;
qspi_bus->send_length--;
}
}
else if (qspi_bus->cell_size == 2)
{
while ((qspi_bus->send_length) && (qspi_reg->sr & 2))
{
qspi_reg->dr[0] = *((rt_uint16_t *)qspi_bus->send_buf);
qspi_bus->send_buf += 2;
qspi_bus->send_length--;
}
}
else if (qspi_bus->cell_size == 4)
{
while ((qspi_bus->send_length) && (qspi_reg->sr & 2))
{
qspi_reg->dr[0] = *((rt_uint32_t *)qspi_bus->send_buf);
qspi_bus->send_buf += 4;
qspi_bus->send_length--;
}
}
else
{
LOG_E("qspi%d datawidth error", qspi_bus->idx);
}
if (qspi_bus->send_length == 0)
{
if (((qspi_reg->ctrlr0 >> 10) & SPI_TMOD_EPROMREAD) == SPI_TMOD_TO)
{
if (qspi_reg->txftlr)
return;
}
qspi_reg->txftlr = 0;
qspi_reg->imr &= ~1;
rt_event_send(&qspi_bus->event, BIT(SSI_TXE));
}
}
/* Handle receive buffer full interrupt */
else if (vector == SSI_RXF)
{
if (qspi_bus->recv_buf == RT_NULL)
{
qspi_reg->imr &= ~0x10;
}
else if (qspi_bus->cell_size == 1)
{
while ((qspi_bus->recv_length) && (qspi_reg->sr & 8))
{
*((rt_uint8_t *)qspi_bus->recv_buf) = qspi_reg->dr[0];
qspi_bus->recv_buf++;
qspi_bus->recv_length--;
}
}
else if (qspi_bus->cell_size == 2)
{
while ((qspi_bus->recv_length) && (qspi_reg->sr & 8))
{
*((rt_uint16_t *)qspi_bus->recv_buf) = qspi_reg->dr[0];
qspi_bus->recv_buf += 2;
qspi_bus->recv_length--;
}
}
else if (qspi_bus->cell_size == 4)
{
while ((qspi_bus->recv_length) && (qspi_reg->sr & 8))
{
*((rt_uint32_t *)qspi_bus->recv_buf) = qspi_reg->dr[0];
qspi_bus->recv_buf += 4;
qspi_bus->recv_length--;
}
}
else
{
LOG_E("qspi%d datawidth error", qspi_bus->idx);
}
if (qspi_bus->recv_length == 0)
{
qspi_reg->imr &= ~0x10;
rt_event_send(&qspi_bus->event, BIT(SSI_RXF));
}
else if (qspi_bus->recv_length <= qspi_reg->rxftlr)
{
qspi_reg->rxftlr = qspi_bus->recv_length - 1;
}
}
/* Handle transfer complete interrupt */
else if (vector == SSI_DONE)
{
/* Clear transfer done interrupt by reading donecr register */
(void)qspi_reg->donecr;
rt_event_send(&qspi_bus->event, BIT(SSI_DONE));
}
/* Handle DMA error interrupt */
else if (vector == SSI_AXIE)
{
/* Clear AXI error interrupt by reading axiecr register */
(void)qspi_reg->axiecr;
rt_event_send(&qspi_bus->event, BIT(SSI_AXIE));
}
}
static struct k230_spi_dev k230_spi_devs[] =
{
#ifdef BSP_USING_SPI0
{
.name = "spi0",
.event_name = "spi0_event",
.pa_base = SPI_OPI_BASE_ADDR,
.size = SPI_OPI_IO_SIZE,
.vector = IRQN_SPI0,
.idx = 0,
.rdse = 0,
.rdsd = 0,
.max_line = 8,
.max_hz = 200000000,
},
#endif
#ifdef BSP_USING_SPI1
{
.name = "spi1",
.event_name = "spi1_event",
.pa_base = SPI_QOPI_BASE_ADDR,
.size = SPI_QOPI_IO_SIZE / 2,
.vector = IRQN_SPI1,
.idx = 1,
.rdse = 0,
.rdsd = 0,
.max_line = 4,
.max_hz = 100000000,
},
#endif
#ifdef BSP_USING_SPI2
{
.name = "spi2",
.event_name = "spi2_event",
.pa_base = SPI_QOPI_BASE_ADDR + SPI_QOPI_IO_SIZE / 2,
.size = SPI_QOPI_IO_SIZE / 2,
.vector = IRQN_SPI2,
.idx = 2,
.rdse = 0,
.rdsd = 0,
.max_line = 4,
.max_hz = 100000000,
},
#endif
};
int rt_hw_qspi_bus_init(void)
{
rt_err_t ret;
int i;
for (i = 0; i < sizeof(k230_spi_devs) / sizeof(k230_spi_devs[0]); i++)
{
k230_spi_devs[i].base = rt_ioremap((void *)k230_spi_devs[i].pa_base, k230_spi_devs[i].size);
ret = rt_qspi_bus_register(&k230_spi_devs[i].dev, k230_spi_devs[i].name, &k230_qspi_ops);
if (ret)
{
LOG_E("%s register fail", k230_spi_devs[i].name);
return ret;
}
rt_event_init(&k230_spi_devs[i].event, k230_spi_devs[i].event_name, RT_IPC_FLAG_PRIO);
rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_TXE, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_TXE);
rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_RXF, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_RXF);
rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_DONE, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_DONE);
rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_AXIE, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_AXIE);
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_qspi_bus_init);

View File

@@ -0,0 +1,203 @@
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include <stdint.h>
#include <stdbool.h>
#define SSIC_HAS_DMA 2
#define SSIC_AXI_BLW 8
#define SSIC_TX_ABW 256
#define SSIC_RX_ABW 256
#define IRQN_SPI0 146
#define IRQN_SPI1 155
#define IRQN_SPI2 164
#ifndef L1_CACHE_BYTES
#define L1_CACHE_BYTES 64
#endif
#define CACHE_ALIGN_TOP(x) (((x) + L1_CACHE_BYTES - 1) & ~(L1_CACHE_BYTES - 1))
#define CACHE_ALIGN_BOTTOM(x) ((x) & ~(L1_CACHE_BYTES - 1))
#define BIT(n) (1UL << (n))
enum
{
SSI_TXE = 0,
SSI_TXO,
SSI_RXF,
SSI_RXO,
SSI_TXU,
SSI_RXU,
SSI_MST,
SSI_DONE,
SSI_AXIE,
};
/* SPI mode */
enum
{
SPI_FRF_STD_SPI,
SPI_FRF_DUAL_SPI,
SPI_FRF_QUAD_SPI,
SPI_FRF_OCT_SPI,
};
/* SPI transmit mode */
enum
{
SPI_TMOD_TR,
SPI_TMOD_TO,
SPI_TMOD_RO,
SPI_TMOD_EPROMREAD,
};
/* Qspi register */
typedef struct
{
/* SPI Control Register 0 (0x00)*/
volatile uint32_t ctrlr0;
/* SPI Control Register 1 (0x04)*/
volatile uint32_t ctrlr1;
/* SPI Enable Register (0x08)*/
volatile uint32_t ssienr;
/* SPI Microwire Control Register (0x0c)*/
volatile uint32_t mwcr;
/* SPI Slave Enable Register (0x10)*/
volatile uint32_t ser;
/* SPI Baud Rate Select (0x14)*/
volatile uint32_t baudr;
/* SPI Transmit FIFO Threshold Level (0x18)*/
volatile uint32_t txftlr;
/* SPI Receive FIFO Threshold Level (0x1c)*/
volatile uint32_t rxftlr;
/* SPI Transmit FIFO Level Register (0x20)*/
volatile uint32_t txflr;
/* SPI Receive FIFO Level Register (0x24)*/
volatile uint32_t rxflr;
/* SPI Status Register (0x28)*/
volatile uint32_t sr;
/* SPI Interrupt Mask Register (0x2c)*/
volatile uint32_t imr;
/* SPI Interrupt Status Register (0x30)*/
volatile uint32_t isr;
/* SPI Raw Interrupt Status Register (0x34)*/
volatile uint32_t risr;
/* SPI Transmit FIFO Underflow Interrupt Clear Register (0x38)*/
volatile uint32_t txeicr;
/* SPI Receive FIFO Overflow Interrupt Clear Register (0x3c)*/
volatile uint32_t rxoicr;
/* SPI Receive FIFO Underflow Interrupt Clear Register (0x40)*/
volatile uint32_t rxuicr;
/* SPI Multi-Master Interrupt Clear Register (0x44)*/
volatile uint32_t msticr;
/* SPI Interrupt Clear Register (0x48)*/
volatile uint32_t icr;
/* SPI DMA Control Register (0x4c)*/
volatile uint32_t dmacr;
#if SSIC_HAS_DMA == 1
/* SPI DMA Transmit Data Level (0x50)*/
volatile uint32_t dmatdlr;
/* SPI DMA Receive Data Level (0x54)*/
volatile uint32_t dmardlr;
#elif SSIC_HAS_DMA == 2
/* SPI Destination Burst Length (0x50)*/
volatile uint32_t axiawlen;
/* SPI Source Burst Length (0x54)*/
volatile uint32_t axiarlen;
#else
uint32_t resv0[2];
#endif
/* SPI Identification Register (0x58)*/
volatile const uint32_t idr;
/* SPI DWC_ssi component version (0x5c)*/
volatile uint32_t ssic_version_id;
/* SPI Data Register 0-36 (0x60 -- 0xec)*/
volatile uint32_t dr[36];
/* SPI RX Sample Delay Register (0xf0)*/
volatile uint32_t rx_sample_delay;
/* SPI SPI Control Register (0xf4)*/
volatile uint32_t spi_ctrlr0;
/* SPI Transmit Drive Edge Register (0xf8)*/
volatile uint32_t ddr_drive_edge;
/* SPI XIP Mode bits (0xfc)*/
volatile uint32_t xip_mode_bits;
/* SPI XIP INCR transfer opcode (0x100)*/
volatile uint32_t xip_incr_inst;
/* SPI XIP WRAP transfer opcode (0x104)*/
volatile uint32_t xip_wrap_inst;
#if SSIC_CONCURRENT_XIP_EN
/* SPI XIP Control Register (0x108)*/
volatile uint32_t xip_ctrl;
/* SPI XIP Slave Enable Register (0x10c)*/
volatile uint32_t xip_ser;
/* SPI XIP Receive FIFO Overflow Interrupt Clear Register (0x110)*/
volatile uint32_t xrxoicr;
/* SPI XIP time out register for continuous transfers (0x114)*/
volatile uint32_t xip_cnt_time_out;
/* not support dyn ws (0x118)*/
uint32_t resv1[1];
/* SPI Transmit Error Interrupt Clear Register (0x11c)*/
volatile uint32_t spitecr;
#else
uint32_t resv1[6];
#endif
#if SSIC_HAS_DMA == 2
/* SPI Device Register (0x120)*/
volatile uint32_t spidr;
/* SPI Device Address Register (0x124)*/
volatile uint32_t spiar;
/* AXI Address Register 0 (0x128)*/
volatile uint32_t axiar0;
/* AXI Address Register 1 (0x12c)*/
volatile uint32_t axiar1;
/* AXI Master Error Interrupt Clear Register (0x130)*/
volatile uint32_t axiecr;
/* Transfer Done Clear Interrupt Clear Register (0x134)*/
volatile uint32_t donecr;
#endif
/* This register will not be used and is reserved. (0x138 ~ 0x13c)*/
uint32_t resv3[2];
#if SSIC_XIP_WRITE_REG_EN
/* XIP_WRITE_INCR_INST - XIP Write INCR transfer opcode (0x140)*/
volatile uint32_t xip_write_incr_inst;
/* XIP_WRITE_WRAP_INST - XIP Write WRAP transfer opcode (0x144)*/
volatile uint32_t xip_write_wrap_inst;
/* XIP_WRITE_CTRL - XIP Write Control Register (0x148)*/
volatile uint32_t xip_write_ctrl;
#else
uint32_t resv4[3];
#endif
// volatile uint32_t endian;
} __attribute__((packed, aligned(4))) k230_spi_reg_t;
#endif

View File

@@ -33,6 +33,9 @@ if GetDepend('BSP_UTEST_DRIVERS'):
if GetDepend('BSP_USING_I2C'):
src += ['test_i2c.c']
if GetDepend('BSP_USING_SPI'):
src += ['test_spi.c']
group = DefineGroup('utestcases', src, depend = [''])
Return('group')

View File

@@ -0,0 +1,222 @@
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <rtdbg.h>
#include <utest.h>
#include "drv_spi.h"
#include <string.h>
#include "drv_pinctrl.h"
#include "drv_gpio.h"
/*
* 测试 SPI0 在标准SPI模式下的数据发送功能
*
* 功能说明:
* - 查找名为 "spi0" 的SPI总线设备
* - 挂载SPI设备到总线
* - 配置SPI设备参数
* - 模式标准SPI模式0 (RT_SPI_MODE_0)
* - 数据位8位
* - 最大频率1MHz
* - 数据线宽度1标准SPI
* - 准备测试数据(递增序列);
* - 创建SPI消息并发送16字节数据
* - 发送完成接收从机的16字节数据
* - 发送完成后卸载SPI设备。
*
* 硬件说明:
* - 本测试基于 K230 平台;
* - 测试SPI0(OSPI)的标准SPI模式TX和RX功能,使用硬件CS
* - 对应的引脚配置为:
* - CS: GPIO14
* - CLK: GPIO15
* - D0: GPIO16
* - D1: GPIO17
* - 需要连接SPI从设备如SPI调试器等来验证数据传输本测试文件使用一块stm32制作的SPI调试器
* - 如果没有实际从设备可以使用逻辑分析仪或示波器观察SPI波形(但是只能验证TX功能,接收到会是16bit的0xff)
*/
#define SPI0_BUS_NAME "spi0"
#define SPI0_DEV_NAME0 "spi00"
#define TEST_DATA_LENGTH 16
#define SPI0_CS_PIN 14
#define SPI0_CLK_PIN 15
#define SPI0_D0_PIN 16
#define SPI0_D1_PIN 17
#define SPI0_CS_PIN_AF IOMUX_FUNC2
#define SPI0_CLK_PIN_AF IOMUX_FUNC2
#define SPI0_D0_PIN_AF IOMUX_FUNC2
#define SPI0_D1_PIN_AF IOMUX_FUNC2
static void spi_gpio_init(void)
{
LOG_I("SPI demo: initializing SPI0 GPIO...");
k230_pinctrl_set_function(SPI0_CS_PIN, SPI0_CS_PIN_AF);
k230_pinctrl_set_function(SPI0_CLK_PIN, SPI0_CLK_PIN_AF);
k230_pinctrl_set_function(SPI0_D0_PIN, SPI0_D0_PIN_AF);
k230_pinctrl_set_function(SPI0_D1_PIN, SPI0_D1_PIN_AF);
k230_pinctrl_set_oe(SPI0_CS_PIN, 1);
k230_pinctrl_set_oe(SPI0_CLK_PIN, 1);
k230_pinctrl_set_oe(SPI0_D0_PIN, 1);
k230_pinctrl_set_oe(SPI0_D1_PIN, 1);
k230_pinctrl_set_ie(SPI0_CS_PIN, 1);
k230_pinctrl_set_ie(SPI0_CLK_PIN, 1);
k230_pinctrl_set_ie(SPI0_D0_PIN, 1);
k230_pinctrl_set_ie(SPI0_D1_PIN, 1);
}
static void spi_device_demo(void)
{
struct rt_qspi_device *qspi_dev;
LOG_I("Using rt_qspi_device to transmit");
rt_err_t ret;
uint8_t tx_data[TEST_DATA_LENGTH];
uint8_t rx_data[TEST_DATA_LENGTH];
for (int i = 0; i < TEST_DATA_LENGTH; i++)
{
tx_data[i] = i;
}
rt_memset(rx_data, 0, sizeof(rx_data));
/* Find QSPI Bus */
struct rt_spi_bus *spi_bus = (struct rt_spi_bus *)rt_device_find(SPI0_BUS_NAME);
if (!spi_bus)
{
LOG_E("Failed to find SPI bus: %s", SPI0_BUS_NAME);
return;
}
LOG_I("Success to find SPI bus: %s", SPI0_BUS_NAME);
qspi_dev = (struct rt_qspi_device *)rt_malloc(sizeof(struct rt_qspi_device));
if (!qspi_dev)
{
LOG_E("Failed to allocate SPI device memory");
return;
}
LOG_I("Success to allocate QSPI device memory");
/* Attach SPI Device */
ret = rt_spi_bus_attach_device(&(qspi_dev->parent), SPI0_DEV_NAME0, SPI0_BUS_NAME, RT_NULL);
if (ret != RT_EOK)
{
LOG_E("Failed to attach SPI device: %d", ret);
rt_free(qspi_dev);
return;
}
LOG_I("SPI device attached successfully");
/* SPI Device Config*/
struct rt_qspi_configuration qspi_cfg;
qspi_cfg.parent.mode = RT_SPI_MODE_0 | RT_SPI_MSB;
qspi_cfg.parent.data_width = 8;
qspi_cfg.parent.max_hz = 1000000;
qspi_cfg.parent.reserved = 0;
qspi_cfg.qspi_dl_width = 1;
qspi_cfg.medium_size = 0;
qspi_cfg.ddr_mode = 0;
ret = rt_qspi_configure(qspi_dev, &qspi_cfg);
if (ret != RT_EOK)
{
LOG_E("SPI configuration failed: %d", ret);
rt_free(qspi_dev);
return;
}
LOG_I("SPI configuration: Standard SPI, mode=0, data_width=8, max_hz=%d, data_lines=%d",
qspi_cfg.parent.max_hz, qspi_cfg.qspi_dl_width);
LOG_I("Sending test data (length=%d):", TEST_DATA_LENGTH);
for (int i = 0; i < TEST_DATA_LENGTH; i++)
{
rt_kprintf("%02X ", tx_data[i]);
}
rt_kprintf("\n");
/* Create SPI Message */
struct rt_qspi_message msg;
rt_memset(&msg, 0, sizeof(msg));
/*Using Standard SPI*/
msg.instruction.content = 0;
msg.instruction.qspi_lines = 1;
msg.address.content = 0;
msg.address.size = 0;
msg.address.qspi_lines = 1;
msg.qspi_data_lines = 1;
msg.dummy_cycles = 0;
/* SPI Message Config */
msg.parent.send_buf = tx_data;
msg.parent.recv_buf = rx_data;
msg.parent.length = TEST_DATA_LENGTH;
msg.parent.cs_take = 1;
msg.parent.cs_release = 1;
msg.parent.next = RT_NULL;
/* Transfer Data */
ret = rt_qspi_transfer_message(qspi_dev, &msg);
if (ret != TEST_DATA_LENGTH)
{
LOG_E("SPI transfer failed, returned: %d", ret);
}
uassert_int_equal(ret, TEST_DATA_LENGTH);
LOG_I("SPI TX demo: sent %d bytes successfully", ret);
LOG_I("Received data from slave (length=%d):", TEST_DATA_LENGTH);
for (int i = 0; i < TEST_DATA_LENGTH; i++)
{
rt_kprintf("%02X ", rx_data[i]);
}
rt_kprintf("\n");
/* Detach SPI Device */
ret = rt_spi_bus_detach_device(&(qspi_dev->parent));
uassert_int_equal(ret, RT_EOK);
rt_free(qspi_dev);
}
static void testcase(void)
{
UTEST_UNIT_RUN(spi_gpio_init);
UTEST_UNIT_RUN(spi_device_demo);
}
static rt_err_t utest_tc_init(void)
{
LOG_I("SPI test case initialization");
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
LOG_I("SPI test case cleanup");
return RT_EOK;
}
UTEST_TC_EXPORT(testcase, "bsp.k230.drivers.spi", utest_tc_init, utest_tc_cleanup, 10);

View File

@@ -503,6 +503,10 @@
/* GD32 Drivers */
/* end of GD32 Drivers */
/* HPMicro SDK */
/* end of HPMicro SDK */
/* end of HAL & SDK Drivers */
/* sensors drivers */

View File

@@ -6,7 +6,39 @@
* Change Logs:
* Date Author Notes
* 2024-05-20 Shell the first version
* 2025-11-13 ChuanN Add standardized utest documentation block
*/
/**
* Test Case Name: Drivers Core Test
*
* Test Objectives:
* - Validate the correctness and consistency of the rt_device_find() API in the RT-Thread device management subsystem.
* - Test rt_device_find() and rt_console_get_device().
*
* Test Scenarios:
* - Locate a known console device by its actual name retrieved at runtime.
* - Attempt to find the same device using the predefined macro RT_CONSOLE_DEVICE_NAME.
* - Verify identity consistency when querying the same device through different but equivalent name sources.
*
* Verification Metrics:
* - rt_device_find() must return a non-NULL pointer when a valid device name is provided.
* - Pointers returned for the same logical device (via different name expressions) must be identical.
* - When RT_CONSOLE_DEVICE_NAME differs from the actual console name, two distinct but valid devices must be found.
* - All assertions must pass without triggering test failure.
*
* Dependencies:
* - Hardware requirements: QEMU emulator or any hardware platform that supports RT-Thread with console device registration.
* - Software configuration:
* - RT_USING_UTEST must be enabled (select "RT-Thread Utestcases" in menuconfig).
* - BSP_UTEST_DRIVERS_CORE must be enabled (enable via: RT-Thread Utestcases -> Kernel components -> drivers -> Driver core Test).
* - Environmental assumptions: The system has initialized the console device before test execution.
*
* Expected Results:
* - The test will pass silently if all assertions hold.
* - Console will output: "[ PASSED ] [ result ] testcase (components.drivers.core.device_find)".
*/
#include <rtthread.h>
#include <stdlib.h>
#include "utest.h"

View File

@@ -19,6 +19,6 @@ if rtconfig.PLATFORM in ['gcc', 'armclang']:
elif rtconfig.PLATFORM in ['armcc']:
LOCAL_CCFLAGS += ' --c99 --gnu'
group = DefineGroup('ktime', src, depend=['RT_USING_KTIME'], CPPPATH=CPPPATH, LOCAL_CCFLAGS = LOCAL_CCFLAGS)
group = DefineGroup('DeviceDrivers', src, depend=['RT_USING_KTIME'], CPPPATH=CPPPATH, LOCAL_CCFLAGS = LOCAL_CCFLAGS)
Return('group')

View File

@@ -1,11 +1,39 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-16 KyleChan the first version
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART POSIX Blocking Echo Test
*
* Test Objectives:
* - Validate POSIX blocking serial IO paths with multi-threaded send/receive verification
* - Verify APIs: open/close, tcgetattr/tcsetattr, cfsetispeed/cfsetospeed, fcntl clearing O_NONBLOCK,
* read, write, rt_thread_create/startup
*
* Test Scenarios:
* - **Scenario 1 (Length Sweep Echo / tc_uart_api):**
* 1. Open POSIX serial device, configure canonical settings, and enforce blocking mode.
* 2. Launch sender/receiver threads; sender streams sequential byte patterns while receiver checks ordering until quota met.
* 3. Iterate through deterministic and random lengths, mirroring behavior of kernel-space blocking tests, and monitor global flags for errors.
*
* Verification Metrics:
* - Received data remains sequential; `uart_result` stays RT_TRUE; `uart_over_flag` raised after completion.
* - No termios or fcntl calls fail; thread creation succeeds.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with POSIX serial device `RT_SERIAL_POSIX_TC_DEVICE_NAME` looped back.
* - Host environment must provide POSIX termios/fcntl APIs; adequate heap for buffers and thread stacks.
*
* Expected Results:
* - Test completes without assertions; logs reflect pass counts for each payload length.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_posix_echo_block)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,39 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-16 KyleChan the first version
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART POSIX Non-Blocking Test
*
* Test Objectives:
* - Validate POSIX-layer non-blocking serial operations using termios configuration
* - Verify APIs: open/close, tcgetattr/tcsetattr, cfsetispeed/cfsetospeed, fcntl(O_NONBLOCK),
* read, write, rt_thread_mdelay
*
* Test Scenarios:
* - **Scenario 1 (Non-Blocking Echo / tc_uart_api):**
* 1. Open POSIX device `RT_SERIAL_POSIX_TC_DEVICE_NAME`, configure baud, frame format, and disable flow control.
* 2. Enable O_NONBLOCK mode and allocate small TX/RX buffer.
* 3. Loop `RT_SERIAL_TC_SEND_ITERATIONS` times, issuing fixed-size and random-length writes, followed by reads after short delays to confirm echo data availability.
*
* Verification Metrics:
* - Each write/read pair returns the expected number of bytes.
* - No system calls fail; routine returns RT_TRUE signalling success.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with POSIX device exposure (`RT_SERIAL_POSIX_TC_DEVICE_NAME`) and loopback wiring.
* - Operating environment must provide termios/fcntl APIs (e.g., RT-Thread POSIX layer or Linux host).
*
* Expected Results:
* - Test executes without assertions; logs remain quiet unless errors occur.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_posix_nonblock)`.
*/
#include <rtthread.h>

View File

@@ -1,3 +1,42 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART QEMU Echo Loopback Test
*
* Test Objectives:
* - Validate dual-UART echo behavior under QEMU by cross-linking uart1 and uart2
* - Verify APIs: rt_device_find, rt_device_open, rt_device_write, rt_device_read,
* rt_device_control(RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT), rt_thread_create/startup
*
* Test Scenarios:
* - **Scenario 1 (Cross-Echo Stress / uart_test_nonblocking_tx):**
* 1. Open uart1/uart2 in blocking mode and spawn threads to mirror RX→TX on uart2 while recording statistics.
* 2. Simultaneously read uart1 in a dedicated thread to monitor inbound bytes.
* 3. Send random-length payloads up to 1 KB for 1000 iterations, periodically comparing TX/RX counters across both devices.
* 4. Signal threads to exit once validation completes and ensure device handles close cleanly.
*
* Verification Metrics:
* - u1/u2 TX and RX counters remain equal; send total matches aggregated transmit length.
* - No allocation failures; `echo_test()` returns RT_TRUE when counters align.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` running under QEMU with uart1↔uart2 interconnected.
* - UART driver must support unread-bytes query and blocking modes.
* - Threads need 2 KB stacks; dynamic buffers sized at 1 KB per UART.
*
* Expected Results:
* - Test completes without assertions; logs show synchronized counter updates.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_qemu_echo)`.
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "utest.h"

View File

@@ -1,3 +1,40 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Blocking Receive Echo Test
*
* Test Objectives:
* - Demonstrate blocking read semantics while capturing multiple user inputs
* - Verify APIs: rt_device_find, rt_device_open with RT_DEVICE_FLAG_RX_BLOCKING,
* rt_device_read, rt_device_write, rt_device_close
*
* Test Scenarios:
* - **Scenario 1 (Interactive Echo / uart_test_blocking_rx):**
* 1. Restart UART in fully blocking RX/TX mode.
* 2. Prompt user (or loopback source) for data, then execute several blocking reads of identical size, echoing results to console.
* 3. Track cumulative bytes received and log progress after each read.
*
* Verification Metrics:
* - Each blocking read returns the requested buffer length; totals increment accordingly.
* - Test helper returns RT_TRUE once sequence completes.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with loopback or external stimulus on `RT_SERIAL_TC_DEVICE_NAME`.
* - UART driver must support blocking reads and repeated open/close operations.
*
* Expected Results:
* - No assertions triggered; console displays prompts and echo logs.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_blocking_rx)`.
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "utest.h"

View File

@@ -1,3 +1,41 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Blocking Transmit Throughput Test
*
* Test Objectives:
* - Measure blocking transmit throughput across varied burst sizes
* - Verify APIs: rt_device_find, rt_device_open with RT_DEVICE_FLAG_TX_BLOCKING,
* rt_device_write, rt_device_close, rt_tick_get
*
* Test Scenarios:
* - **Scenario 1 (Burst Size Sweep / uart_test_blocking_tx):**
* 1. Re-open the UART in blocking TX mode.
* 2. Perform 100 iterations of 1024-byte writes followed by single bursts of 8, 32, 128, 512, and 1024 bytes,
* capturing elapsed ticks and bytes transferred.
* 3. Log throughput metrics for later comparison against non-blocking mode.
*
* Verification Metrics:
* - Each write call returns the full requested length; accumulated counts match expectations.
* - Timing data captured for every burst; helper returns RT_TRUE on success.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` and loopback wiring on `RT_SERIAL_TC_DEVICE_NAME`.
* - UART driver must support blocking writes and open/close sequences.
*
* Expected Results:
* - Test finishes without assertions; logs show per-size timing statistics.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_blocking_tx)`.
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "utest.h"

View File

@@ -1,11 +1,39 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART RX Buffer Flush Test
*
* Test Objectives:
* - Verify RX flush control clears buffered data and preserves integrity of subsequent transfers
* - Confirm APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_RX_FLUSH),
* rt_device_open with RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING,
* rt_device_read, rt_device_write
*
* Test Scenarios:
* - **Scenario 1 (Flush Validation / tc_uart_api):**
* 1. Configure UART buffers and allocate test pattern spanning multiple RX buffer lengths.
* 2. Send payload, consume a single byte, invoke RX flush, and ensure next read returns no residual data.
* 3. Resend partial payloads of varying sizes to confirm data after flush matches original pattern.
*
* Verification Metrics:
* - Initial read after flush returns zero bytes; subsequent reads match transmitted data byte-for-byte.
* - All iterations across deterministic and random lengths complete with RT_EOK.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2`, loopback wiring, and RX flush support on `RT_SERIAL_TC_DEVICE_NAME`.
* - Optional DMA ping buffer configuration honored when `RT_SERIAL_USING_DMA` enabled.
*
* Expected Results:
* - No assertions triggered; logs show flush operations with payload sizes.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_flush_rx)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,39 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART TX Blocking Flush Test
*
* Test Objectives:
* - Validate TX flush completion timing in blocking mode and ensure subsequent RX integrity
* - Verify APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_TX_FLUSH / _SET_TX_TIMEOUT / RT_SERIAL_CTRL_RX_FLUSH),
* rt_device_open with RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING,
* rt_device_write, rt_device_read
*
* Test Scenarios:
* - **Scenario 1 (Flush Timing & Data Integrity / tc_uart_api):**
* 1. Configure enlarged TX buffer and set TX timeout guard.
* 2. Perform multiple iterations with varied payload sizes (aligned and unaligned), recording ticks needed to flush queued bytes and verifying they fall within `[expect_time, expect_time + 10]`.
* 3. After each flush, resend small samples and confirm received data matches transmitted pattern.
*
* Verification Metrics:
* - `rt_device_write` returns full payload length; measured tick difference respects expected window.
* - Post-flush RX comparisons succeed for all sample sizes.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with hardware loopback and TX flush capability on `RT_SERIAL_TC_DEVICE_NAME`.
* - Optional DMA ping buffer configuration supported.
*
* Expected Results:
* - Test completes without assertions; logs show flush durations per payload.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_flush_txb)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,39 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART TX Non-Blocking Flush Test
*
* Test Objectives:
* - Validate flush completion timing for non-blocking transmit mode and verify subsequent RX integrity
* - Verify APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_TX_FLUSH / _SET_TX_TIMEOUT / RT_SERIAL_CTRL_RX_FLUSH),
* rt_device_open with RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING,
* rt_device_write, rt_device_read
*
* Test Scenarios:
* - **Scenario 1 (Flush Timing & Data Integrity / tc_uart_api):**
* 1. Configure UART with expanded buffer sizes and minimal TX timeout to emulate non-blocking semantics.
* 2. Iterate across varied payload lengths (including random lengths), measuring ticks between write and flush completion; ensure timing lies within expected band.
* 3. After each flush, resend small samples and check received bytes for equality.
*
* Verification Metrics:
* - Flushed transmissions complete within `[expect_time, expect_time + 10]` tick window.
* - Post-flush RX comparisons succeed for all sample sizes.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2`, loopback wiring, and TX flush support for non-blocking mode on `RT_SERIAL_TC_DEVICE_NAME`.
* - Optional DMA ping buffer configuration honored.
*
* Expected Results:
* - Test runs without assertions; logs report flush timing per payload.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_flush_txnb)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,39 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Unread Bytes Count Test
*
* Test Objectives:
* - Validate query of unread RX bytes and flush interaction in non-blocking receive mode
* - Verify APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT / RT_SERIAL_CTRL_RX_FLUSH),
* rt_device_open with RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING,
* rt_device_write
*
* Test Scenarios:
* - **Scenario 1 (Unread Count Verification / tc_uart_api):**
* 1. Configure UART buffers and send varying payload lengths, some exceeding RX buffer capacity.
* 2. After each transfer, query unread byte count and ensure it saturates at `min(send_size, RT_SERIAL_TC_RXBUF_SIZE)`.
* 3. Flush RX buffer and verify unread count resets to zero before next iteration.
*
* Verification Metrics:
* - `RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT` returns expected length; subsequent flush yields zero.
* - All iterations covering large and random payloads complete with RT_EOK.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2`, RX count control support, and loopback wiring on `RT_SERIAL_TC_DEVICE_NAME`.
* - Optional DMA ping buffer configuration honored.
*
* Expected Results:
* - Test ends without assertions; logs may remain silent unless failures occur.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_get_unread_bytes_count)`.
*/
#include <rtthread.h>

View File

@@ -1,3 +1,40 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Non-Blocking Receive Echo Test
*
* Test Objectives:
* - Demonstrate non-blocking receive behavior paired with blocking transmit output
* - Verify APIs: rt_device_find, rt_device_open with RT_DEVICE_FLAG_RX_NON_BLOCKING,
* rt_device_read (non-blocking), rt_device_write, rt_device_close
*
* Test Scenarios:
* - **Scenario 1 (Interactive Echo / uart_test_nonblocking_rx):**
* 1. Restart UART in RX non-blocking / TX blocking mode.
* 2. Prompt user (or loopback peer) to send data while issuing countdown markers to MSH.
* 3. Perform successive non-blocking reads of varying sizes (256/128 bytes), echoing captured data back and logging totals.
*
* Verification Metrics:
* - Each read returns immediately with available data (may be zero); totals accumulate without overflow.
* - Function returns RT_TRUE after final log, indicating no failures during sequence.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with loopback or user-provided input on `RT_SERIAL_TC_DEVICE_NAME`.
* - UART driver must support non-blocking reads and reversible open/close.
*
* Expected Results:
* - No assertions triggered; terminal displays countdown prompts and mirrored input.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_nonblocking_rx)`.
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "utest.h"

View File

@@ -1,3 +1,41 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Non-Blocking Transmit Throughput Test
*
* Test Objectives:
* - Measure and validate non-blocking transmit behavior across varying burst sizes
* - Verify APIs: rt_device_find, rt_device_open with RT_DEVICE_FLAG_TX_NON_BLOCKING,
* rt_device_write, rt_device_close, rt_tick_get
*
* Test Scenarios:
* - **Scenario 1 (Burst Size Sweep / uart_test_nonblocking_tx):**
* 1. Re-open the UART in fully non-blocking mode after ensuring it is closed.
* 2. Issue sequential write loops for payloads of 8, 32, 128, 512, and 1024 bytes, plus 100 iterations of 1024 bytes,
* collecting total bytes written and elapsed ticks.
* 3. Log throughput metrics for each run to detect stalls or partial transfers.
*
* Verification Metrics:
* - Each loop writes the exact number of requested bytes; cumulative counters match expectations.
* - Measured tick deltas are captured for post-run performance analysis; function returns RT_TRUE.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with loopback wiring for `RT_SERIAL_TC_DEVICE_NAME`.
* - UART driver must support non-blocking write semantics and allow repeated open/close.
*
* Expected Results:
* - Test completes without assertion failures; logs show per-size throughput data.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_nonblocking_tx)`.
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "utest.h"

View File

@@ -1,11 +1,41 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART RX Buffer Overflow Handling Test
*
* Test Objectives:
* - Validate UART behavior when RX FIFO exceeds configured buffer size under blocking operation
* - Verify APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_SET_RX_TIMEOUT),
* rt_device_open with RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING,
* rt_device_read, rt_device_write, rt_thread_create/startup
*
* Test Scenarios:
* - **Scenario 1 (Overflow Stress / tc_uart_api):**
* 1. Configure UART buffers and spawn sender thread to push large monotonic sequences while receiver drains in buffer-sized chunks.
* 2. Delay receiver startup to force RX queue saturation, then verify data either restarts from zero (drop strategy) or continues modulo 256.
* 3. Iterate across deterministic and random payload lengths, monitoring flags for misordered data.
*
* Verification Metrics:
* - Receiver reads exactly `RT_SERIAL_TC_RXBUF_SIZE` bytes per chunk.
* - Data pattern matches expected strategy (`RT_SERIAL_BUF_STRATEGY_DROP` or wraparound).
* - `uart_result` remains `RT_TRUE`; `uart_over_flag` set before loop exit.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with loopback wiring and optional DMA ping buffer support.
* - UART driver must implement overflow strategy macros and blocking modes.
* - Adequate heap for large TX/RX buffers and 2 KB thread stacks.
*
* Expected Results:
* - No assertions triggered; logs report pass counts for each length.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_overflow_rxb_txb)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,43 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-16 KyleChan the first version
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Blocking RX & TX Integration Test
*
* Test Objectives:
* - Validate simultaneous blocking receive/transmit operation with sequential integrity checks
* - Verify APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_SET_RX_TIMEOUT),
* rt_device_open with RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING,
* rt_device_read, rt_device_write, rt_thread_create/startup
*
* Test Scenarios:
* - **Scenario 1 (Length Sweep & Randomized Payloads / tc_uart_api):**
* 1. Reconfigure UART to known buffer sizes (optional DMA ping buffer) and set generous RX timeout.
* 2. Spawn paired producer/consumer threads; sender streams monotonically increasing bytes while receiver validates ordering until quota met.
* 3. Iterate over deterministic payload lengths based on TX buffer, RX buffer, and random samples until `RT_SERIAL_TC_SEND_ITERATIONS` reached.
* 4. Monitor flags for allocation failures or data mismatches; terminate threads once reception quota per iteration satisfied.
*
* Verification Metrics:
* - Each transfer completes with ordered byte sequence and total receive length equals requested count.
* - `uart_result` remains `RT_TRUE`; `uart_over_flag` set per iteration before teardown.
* - Device open/close succeeds across all iterations without lingering handles.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with loopback wiring on `RT_SERIAL_TC_DEVICE_NAME`.
* - Blocking mode support plus optional DMA ping buffer configuration.
* - Thread stack allocations (2 × 1 KB) and send buffers must be available from heap.
*
* Expected Results:
* - Unit test passes without assertions; logs show progressive length coverage.
* - Utest framework prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_rxb_txb)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,43 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-16 KyleChan the first version
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Blocking RX & Non-Blocking TX Integration Test
*
* Test Objectives:
* - Validate receive-blocking / transmit-non-blocking coexistence including TX completion callbacks
* - Verify APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_SET_RX_TIMEOUT),
* rt_device_open with RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING,
* rt_device_set_tx_complete, rt_device_read, rt_device_write, rt_sem APIs
*
* Test Scenarios:
* - **Scenario 1 (Length Sweep with Callback Synchronization / tc_uart_api):**
* 1. Configure UART buffers (optional DMA ping buffer) and create TX completion semaphore.
* 2. Register `uart_tx_completion` to release semaphore for each non-blocking write fragment.
* 3. Iterate through deterministic and random payload lengths, launching paired sender/receiver threads.
* 4. Sender waits on semaphore between partial writes; receiver verifies ordered payload to detect loss or reordering.
*
* Verification Metrics:
* - All expected bytes received in sequence; `uart_result` remains `RT_TRUE`.
* - Semaphore operations succeed (`rt_sem_take` returns RT_EOK); `uart_over_flag` toggles once quota met.
* - Device configuration/open/close calls complete without error; resources freed in cleanup.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` and loopback wiring for `RT_SERIAL_TC_DEVICE_NAME`.
* - Non-blocking TX mode must support completion callback registration.
* - Dynamic memory for payload buffers, semaphore, and two 1 KB threads must be available.
*
* Expected Results:
* - Test finishes without assertions; logs show length coverage and success counts.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_rxb_txnb)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,43 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-16 KyleChan the first version
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Non-Blocking RX & Blocking TX Integration Test
*
* Test Objectives:
* - Validate RX interrupt/callback based reception paired with blocking transmit path
* - Verify APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_SET_RX_TIMEOUT),
* rt_device_open with RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING,
* rt_device_set_rx_indicate, rt_device_read, rt_device_write, rt_sem APIs
*
* Test Scenarios:
* - **Scenario 1 (Callback-Driven Reception / tc_uart_api):**
* 1. Configure UART buffers (optional DMA ping buffer) and create RX semaphore.
* 2. Register `uart_rx_indicate` callback to signal semaphore whenever new bytes arrive.
* 3. For a sweep of deterministic and random lengths, launch sender/receiver threads.
* 4. Receiver waits on semaphore, drains available bytes, and enforces monotonic data ordering until quota met.
*
* Verification Metrics:
* - Received data remains sequential; `uart_result` stays `RT_TRUE`.
* - Semaphore take operations succeed; `uart_over_flag` flips upon completion.
* - UART open/close and callback registration succeed without leaks; resources cleaned in teardown.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with loopback for `RT_SERIAL_TC_DEVICE_NAME`.
* - Non-blocking RX must support callback indication.
* - Heap must provide buffers and semaphore; two 1 KB thread stacks required.
*
* Expected Results:
* - Test executes without assertion failures; logs show iteration counts and lengths.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_rxnb_txb)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,42 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-16 KyleChan the first version
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Non-Blocking RX & TX Integration Test
*
* Test Objectives:
* - Validate fully non-blocking UART workflow leveraging TX completion and RX indication callbacks
* - Verify APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_SET_RX_TIMEOUT),
* rt_device_open with RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING,
* rt_device_set_rx_indicate, rt_device_set_tx_complete, rt_device_read, rt_device_write, rt_sem APIs
*
* Test Scenarios:
* - **Scenario 1 (Callback-Synchronized Duplex Transfer / tc_uart_api):**
* 1. Configure UART buffers (optional DMA ping buffer) and create paired RX/TX semaphores.
* 2. Register RX indication and TX completion callbacks to release semaphores on asynchronous events.
* 3. Launch sender/receiver threads for deterministic and random payload sizes; sender fragments writes, waiting on TX semaphore, while receiver waits on RX semaphore before draining data.
* 4. Verify data ordering continuously and stop once requested byte count satisfied per iteration.
*
* Verification Metrics:
* - Received bytes maintain sequential increments; `uart_result` never flips to RT_FALSE.
* - Semaphore waits succeed; non-blocking read/write calls progress without deadlock.
* - UART handles close cleanly; semaphores deleted during cleanup.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2`, loopback on `RT_SERIAL_TC_DEVICE_NAME`, and callback-capable UART driver.
* - Adequate heap for buffers, semaphores, and two 1 KB thread stacks.
*
* Expected Results:
* - Unit test completes without assertions; logs reflect pass counts across length sweep.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_rxnb_txnb)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,42 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Blocking RX Timeout Test
*
* Test Objectives:
* - Validate blocking receive timeout behavior while TX operates non-blocking
* - Verify APIs: rt_device_find, rt_device_control(RT_SERIAL_CTRL_SET_RX_TIMEOUT / _TX_FLUSH),
* rt_device_open with RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING,
* rt_device_write, rt_device_read
*
* Test Scenarios:
* - **Scenario 1 (RX Timeout Sweep / tc_uart_api):**
* 1. Reconfigure UART buffers (optional DMA ping buffer) and open in RX blocking / TX non-blocking mode.
* 2. Allocate reusable TX buffer and iterate `RT_SERIAL_TC_SEND_ITERATIONS` times.
* 3. For each iteration, randomize burst length (1024~2047 bytes), program RX timeout, transmit payload,
* then read back and ensure received size reflects timeout truncation.
* 4. Flush TX FIFO and delay to allow residual bytes to drain before next iteration.
*
* Verification Metrics:
* - Each receive length lies within `[rx_timeout_send_size - 70, send_size - 80]`.
* - Transmission always completes full burst; overall loop exits with RT_EOK and device closes successfully.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` with UART loopback (`RT_SERIAL_TC_DEVICE_NAME` TX shorted to RX).
* - Serial driver must support RX timeout control and optional DMA ping buffer configuration.
* - Random number generator and system tick used for timeout computation.
*
* Expected Results:
* - No assertions triggered; log traces show per-iteration timeout measurements.
* - Utest framework prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_timeout_rxb)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,41 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Blocking Timeout RX/TX Test
*
* Test Objectives:
* - Validate combined blocking receive/transmit timeout behavior for the serial v2 driver
* - Verify APIs: rt_device_find, rt_device_control(RT_SERIAL_CTRL_SET_RX_TIMEOUT / _SET_TX_TIMEOUT / _RX_FLUSH / _TX_FLUSH),
* rt_device_open with RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING, rt_device_read, rt_device_write
*
* Test Scenarios:
* - **Scenario 1 (Timeout Verification / tc_uart_api):**
* 1. Discover and reconfigure the target UART with loopback (TX shorted to RX) and known buffer sizes.
* 2. Spawn concurrent TX and RX worker threads; RX thread configures 100-tick blocking timeout and repeatedly validates measured wait time.
* 3. Switch to TX timeout mode (10 ticks) and push oversized bursts to ensure write calls block for the configured window.
* 4. Monitor status flags to detect allocation failures, timeout violations, or thread termination.
*
* Verification Metrics:
* - RX blocking reads must complete within [100, 101] ticks and return expected lengths across 10 iterations.
* - TX blocking writes must complete within [10, 11] ticks with successful flush between iterations.
* - No allocation or control failures occur; master loop exits with `uart_over_flag == RT_TRUE`.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` enabled and a loopbacked UART defined by `RT_SERIAL_TC_DEVICE_NAME`.
* - Serial driver must support blocking mode and timeout controls; optional RX DMA segment size is set via `RT_SERIAL_USING_DMA`.
* - Two 2 KB threads plus dynamic buffers (~RT_SERIAL_TC_RXBUF_SIZE*10) must be allocatable from the heap.
*
* Expected Results:
* - Test completes without assertions, device handles close cleanly, logs show timeout measurements within tolerance.
* - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_timeout_rxb_txb)`.
*/
#include <rtthread.h>

View File

@@ -1,11 +1,41 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-11-13 CYFS Add standardized utest documentation block
*/
/**
* Test Case Name: UART Blocking TX Timeout Test
*
* Test Objectives:
* - Validate blocking transmit timeout handling when RX operates non-blocking
* - Verify APIs: rt_device_find, rt_device_control(RT_SERIAL_CTRL_SET_TX_TIMEOUT / _TX_FLUSH),
* rt_device_open with RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING, rt_device_write
*
* Test Scenarios:
* - **Scenario 1 (TX Timeout Sweep / tc_uart_api):**
* 1. Configure UART buffers and open the device in RX non-blocking / TX blocking mode.
* 2. Allocate a reusable TX buffer and iterate `RT_SERIAL_TC_SEND_ITERATIONS` times.
* 3. For each iteration, randomize burst length (1024~2047 bytes), set expected TX timeout,
* issue write, and ensure returned write size falls into tolerated range.
* 4. Flush TX FIFO and delay to allow loopback RX to complete reception.
*
* Verification Metrics:
* - Each write returns size within `[tx_timeout_send_size - 70, send_size - 80]`.
* - No allocation failures; all iterations exit via RT_EOK and device closes cleanly.
*
* Dependencies:
* - Requires `RT_UTEST_SERIAL_V2` enabled and loopback wiring of `RT_SERIAL_TC_DEVICE_NAME`.
* - Excludes configurations with `BSP_UART2_TX_USING_DMA` (DMA write timeout unsupported).
* - Needs random number generator and system tick for duration calculations.
*
* Expected Results:
* - Test completes without assertion failures; logs show sequence of timeout send sizes.
* - Utest framework prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_timeout_txb)`.
*/
#include <rtthread.h>

View File

@@ -320,7 +320,7 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
src += Glob('platform/rtthread/usb_msh.c')
src += Glob('platform/rtthread/usb_check.c')
group = DefineGroup('CherryUSB', src, depend = ['RT_USING_CHERRYUSB'], LIBS = LIBS, LIBPATH=LIBPATH, CPPPATH = path, CPPDEFINES = CPPDEFINES)
group = DefineGroup('UsbStack', src, depend = ['RT_USING_CHERRYUSB'], LIBS = LIBS, LIBPATH=LIBPATH, CPPPATH = path, CPPDEFINES = CPPDEFINES)
Return('group')

View File

@@ -7,6 +7,6 @@ group = []
if rtconfig.PLATFORM in ['armcc', 'armclang']:
CPPDEFINES = ['RT_USING_ARMLIBC', 'RT_USING_LIBC', '__STDC_LIMIT_MACROS']
AddDepend(['RT_USING_ARMLIBC', 'RT_USING_LIBC'])
group = DefineGroup('Compiler', src, depend = [''], CPPDEFINES = CPPDEFINES)
group = DefineGroup('Libc', src, depend = [''], CPPDEFINES = CPPDEFINES)
Return('group')

View File

@@ -16,7 +16,7 @@ elif rtconfig.PLATFORM in ['gcc'] and rtconfig.CPU in ['posix']:
src += Glob('*.c')
group = DefineGroup('Compiler', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
group = DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
list = os.listdir(cwd)
for item in list:

View File

@@ -10,7 +10,7 @@ group = []
src += Glob('*.c')
if rtconfig.PLATFORM not in ['gcc', 'llvm-arm']:
group = DefineGroup('Compiler', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH)
list = os.listdir(cwd)
for d in list:

View File

@@ -7,5 +7,5 @@ CPPPATH = [cwd]
group = []
if rtconfig.CROSS_TOOL == 'msvc':
group = DefineGroup('Compiler', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -7,5 +7,5 @@ CPPPATH = [cwd]
group = []
if rtconfig.PLATFORM in ['armcc', 'armclang', 'iccarm']:
group = DefineGroup('Compiler', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -17,6 +17,6 @@ if rtconfig.PLATFORM in ['iccarm']:
if iar_version != LooseVersion("0.0") and iar_version < LooseVersion("8.20.1"):
CPPDEFINES = CPPDEFINES + ['_DLIB_THREAD_SUPPORT']
group = DefineGroup('Compiler', src, depend = [''], CPPDEFINES = CPPDEFINES)
group = DefineGroup('Libc', src, depend = [''], CPPDEFINES = CPPDEFINES)
Return('group')

View File

@@ -19,7 +19,7 @@ if musllibc_version:
LINKFLAGS = ' --specs=kernel.specs'
AddDepend(['RT_USING_MUSLLIBC', 'RT_USING_LIBC'])
group = group + DefineGroup('Compiler', src, depend = [''], CPPPATH = CPPPATH, LINKFLAGS = LINKFLAGS, CPPDEFINES = CPPDEFINES, LIBS = LIBS)
group = group + DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH, LINKFLAGS = LINKFLAGS, CPPDEFINES = CPPDEFINES, LIBS = LIBS)
list = os.listdir(cwd)
for d in list:

View File

@@ -18,7 +18,7 @@ if newlib_version and not GetDepend('RT_USING_EXTERNAL_LIBC'):
LIBS = ['c', 'm'] # link libc and libm
AddDepend(['RT_USING_NEWLIBC', 'RT_USING_LIBC'])
group = group + DefineGroup('Compiler', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES, LIBS = LIBS)
group = group + DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES, LIBS = LIBS)
list = os.listdir(cwd)
for d in list:

View File

@@ -24,7 +24,7 @@ if picolibc_version and not GetDepend('RT_USING_EXTERNAL_LIBC'):
# LIBS = ['c', 'm'] # link libc and libm
AddDepend(['RT_USING_PICOLIBC', 'RT_USING_LIBC'])
group = group + DefineGroup('Compiler', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)#, LIBS = LIBS)
group = group + DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)#, LIBS = LIBS)
list = os.listdir(cwd)
for d in list:

View File

@@ -6,6 +6,6 @@ cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('POSIX', src, depend = ['RT_USING_POSIX_DELAY'], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = ['RT_USING_POSIX_DELAY'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -6,6 +6,6 @@ cwd = GetCurrentDir()
src = ['aio.c']
CPPPATH = [cwd]
group = DefineGroup('POSIX', src, depend = ['RT_USING_POSIX_AIO'], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = ['RT_USING_POSIX_AIO'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -9,6 +9,6 @@ CPPPATH = [cwd]
if GetDepend('RT_USING_POSIX_EPOLL'):
src += ['epoll.c']
group = DefineGroup('POSIX', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -9,6 +9,6 @@ CPPPATH = [cwd]
if GetDepend('RT_USING_POSIX_EVENTFD'):
src += ['eventfd.c']
group = DefineGroup('POSIX', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -6,6 +6,6 @@ cwd = GetCurrentDir()
src = ['mman.c']
CPPPATH = [cwd]
group = DefineGroup('POSIX', src, depend = ['RT_USING_POSIX_MMAN'], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = ['RT_USING_POSIX_MMAN'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -12,6 +12,6 @@ if GetDepend('RT_USING_POSIX_POLL'):
if GetDepend('RT_USING_POSIX_SELECT'):
src += ['select.c']
group = DefineGroup('POSIX', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -9,6 +9,6 @@ CPPPATH = [cwd]
if GetDepend('RT_USING_POSIX_SIGNALFD'):
src += ['signalfd.c']
group = DefineGroup('POSIX', src, depend = ['RT_USING_SMART','RT_USING_POSIX_SIGNALFD'], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = ['RT_USING_SMART','RT_USING_POSIX_SIGNALFD'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -1,6 +1,6 @@
from building import *
src = ['stdio.c']
group = DefineGroup('POSIX', src, depend = ['RT_USING_POSIX_STDIO'], CPPPATH = [GetCurrentDir()])
group = DefineGroup('Libc', src, depend = ['RT_USING_POSIX_STDIO'], CPPPATH = [GetCurrentDir()])
Return('group')

View File

@@ -6,6 +6,6 @@ cwd = GetCurrentDir()
src = ['termios.c']
CPPPATH = [cwd]
group = DefineGroup('POSIX', src, depend = ['RT_USING_POSIX_TERMIOS'], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = ['RT_USING_POSIX_TERMIOS'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -9,6 +9,6 @@ CPPPATH = [cwd]
if GetDepend('RT_USING_DFS'):
src += ['timerfd.c']
group = DefineGroup('POSIX', src, depend = ['RT_USING_POSIX_TIMERFD'], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = ['RT_USING_POSIX_TIMERFD'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -15,6 +15,6 @@ if GetDepend(['RT_USING_POSIX_MESSAGE_QUEUE', 'RT_USING_DFS_MQUEUE']):
if GetDepend('RT_USING_POSIX_MESSAGE_SEMAPHORE'):
src += ['semaphore.c']
group = DefineGroup('POSIX', src, depend = [''], CPPPATH = inc)
group = DefineGroup('Libc', src, depend = [''], CPPPATH = inc)
Return('group')

View File

@@ -7,6 +7,6 @@ group = []
CPPPATH = [cwd]
if rtconfig.PLATFORM in ['gcc']:
group = DefineGroup('POSIX', src, depend = ['RT_USING_MODULE'], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = ['RT_USING_MODULE'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -4,6 +4,6 @@ cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('POSIX', src, depend = ['RT_USING_PTHREADS'], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = ['RT_USING_PTHREADS'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -6,7 +6,7 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
group = DefineGroup('POSIX', src,
group = DefineGroup('Libc', src,
depend = ['RT_USING_SIGNALS', 'RT_USING_PTHREADS'],
CPPPATH = CPPPATH)

View File

@@ -4,6 +4,6 @@ cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('POSIX', src, depend = ['RT_USING_PTHREADS'], CPPPATH = CPPPATH)
group = DefineGroup('Libc', src, depend = ['RT_USING_PTHREADS'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -7,6 +7,7 @@
* Date Author Notes
* 2019-10-12 Jesven first version
* 2023-02-20 wangxiaoyao adapt to mm
* 2025-11-06 ibvqeibob add Doxygen comments for lwp shared memory APIs
*/
#include <rthw.h>
#include <rtthread.h>
@@ -19,14 +20,21 @@
#include <lwp_user_mm.h>
#include <mmu.h>
/* the kernel structure to represent a share-memory */
/**
* @brief Kernel control block for a shared memory segment.
*
* Each lwp_shm_struct represents one shared memory region. It records
* the physical address, size, reference count and key. The embedded
* mem_obj is used together with the aspace/varea mechanism to handle
* mapping and page faults for this segment.
*/
struct lwp_shm_struct
{
struct rt_mem_obj mem_obj;
size_t addr; /* point to the next item in the free list when not used */
size_t size;
int ref;
size_t key;
struct rt_mem_obj mem_obj; /**< Memory object interface used by aspace/varea */
size_t addr; /**< Physical address of the shared memory; used as next pointer in the free list when unused */
size_t size; /**< Size of the shared memory in bytes, page aligned */
int ref; /**< Reference count of mappings to this shared memory */
size_t key; /**< User-visible key used to look up the shared memory */
};
static struct lwp_avl_struct *shm_tree_key;
@@ -189,7 +197,22 @@ err:
return -1;
}
/* A wrapping function, get the shared memory with interrupts disabled. */
/**
* @brief Get or create a shared memory segment by key.
*
* Under the memory management lock, this function looks up an existing
* shared memory control block by key. If it does not exist and @p create
* is non-zero, a new segment is created with the requested size, physical
* pages are allocated and the segment is inserted into the internal index
* trees.
*
* @param[in] key Key used to identify the shared memory segment.
* @param[in] size Requested size in bytes; only effective when creating.
* @param[in] create Non-zero to allow creation; zero to only search.
*
* @return On success, returns a non-negative shared memory id.
* On failure, returns -1.
*/
int lwp_shmget(size_t key, size_t size, int create)
{
int ret = 0;
@@ -253,7 +276,19 @@ static int _lwp_shmrm(int id)
return 0;
}
/* A wrapping function, free the shared memory with interrupt disabled. */
/**
* @brief Remove a shared memory segment by id.
*
* The internal control block is located by @p id. If the reference count
* is zero, the physical pages, control block and AVL index nodes are freed.
* If the segment is still referenced, no memory is actually released.
*
* @param[in] id Shared memory id returned by lwp_shmget().
*
* @return Returns 0 on success. If @p id is invalid or internal checks
* fail, -1 is returned. When the reference count is non-zero,
* 0 is returned but the segment is not freed.
*/
int lwp_shmrm(int id)
{
int ret = 0;
@@ -300,7 +335,21 @@ static void *_lwp_shmat(int id, void *shm_vaddr)
return va;
}
/* A wrapping function: attach the shared memory to the specified address. */
/**
* @brief Map a shared memory segment into the current LWP.
*
* The shared memory control block is located by @p id and mapped into the
* user address space of the current LWP. If @p shm_vaddr is not RT_NULL,
* the system tries to map the segment at the specified virtual address,
* which must be page aligned.
*
* @param[in] id Shared memory id returned by lwp_shmget().
* @param[in] shm_vaddr Desired user virtual address; if RT_NULL, the
* system chooses an address. When not RT_NULL it
* must be page aligned.
*
* @return The mapped user virtual address on success, or RT_NULL on failure.
*/
void *lwp_shmat(int id, void *shm_vaddr)
{
void *ret = RT_NULL;
@@ -346,6 +395,19 @@ static int _lwp_shm_ref_inc(struct rt_lwp *lwp, void *shm_vaddr)
return -1;
}
/**
* @brief Increase the reference count of a shared memory segment.
*
* The shared memory control block is located according to the given
* @p lwp and the user virtual address @p shm_vaddr. If found, its
* reference count is increased by one.
*
* @param[in] lwp LWP object to operate on.
* @param[in] shm_vaddr User virtual address where the shared memory
* is mapped in this LWP.
*
* @return The new reference count on success, or -1 on failure.
*/
int lwp_shm_ref_inc(struct rt_lwp *lwp, void *shm_vaddr)
{
int ret = 0;
@@ -369,6 +431,19 @@ static int _lwp_shm_ref_dec(struct rt_lwp *lwp, void *shm_vaddr)
return -1;
}
/**
* @brief Decrease the reference count of a shared memory segment.
*
* The shared memory control block is located according to the given
* @p lwp and the user virtual address @p shm_vaddr. If it exists and
* the reference count is greater than zero, the count is decreased by one.
*
* @param[in] lwp LWP object to operate on.
* @param[in] shm_vaddr User virtual address where the shared memory
* is mapped in this LWP.
*
* @return The new reference count on success, or -1 on failure.
*/
int lwp_shm_ref_dec(struct rt_lwp *lwp, void *shm_vaddr)
{
int ret = 0;
@@ -400,7 +475,16 @@ int _lwp_shmdt(void *shm_vaddr)
return ret;
}
/* A wrapping function: detach the mapped shared memory. */
/**
* @brief Unmap a shared memory segment from the current LWP.
*
* The mapping at @p shm_vaddr in the current LWP address space is
* removed. Internal errors are translated into a generic error code.
*
* @param[in] shm_vaddr User virtual address of the shared memory mapping.
*
* @return Returns 0 on success, or -1 on failure.
*/
int lwp_shmdt(void *shm_vaddr)
{
int ret = 0;
@@ -429,7 +513,17 @@ void *_lwp_shminfo(int id)
return (void *)((char *)p->addr - PV_OFFSET); /* get the virtual address */
}
/* A wrapping function: get the virtual address of a shared memory. */
/**
* @brief Get the kernel virtual address of a shared memory segment.
*
* The internal control block is located by @p id and the kernel
* virtual address corresponding to that shared memory is returned.
*
* @param[in] id Shared memory id returned by lwp_shmget().
*
* @return Kernel virtual address of the shared memory on success,
* or RT_NULL on failure.
*/
void *lwp_shminfo(int id)
{
void *vaddr = RT_NULL;
@@ -451,6 +545,13 @@ static int _shm_info(struct lwp_avl_struct* node_key, void *data)
return 0;
}
/**
* @brief Print information of all shared memory segments.
*
* This function prints the key, physical address, size and id of each
* shared memory segment to the console. It is exported as the Finsh/Msh
* command @c list_shm for debugging and inspection.
*/
void list_shm(void)
{
rt_kprintf(" key paddr size id\n");

View File

@@ -11,6 +11,6 @@ if GetDepend('ARCH_ARM_CORTEX_A') or GetDepend('ARCH_ARMV8') or GetDepend('ARCH_
CPPPATH = [cwd]
group = DefineGroup('mm', src, depend = ['ARCH_MM_MMU'], CPPPATH = CPPPATH)
group = DefineGroup('Memm', src, depend = ['ARCH_MM_MMU'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -24,7 +24,7 @@ if GetDepend('RT_USING_PIC') == True:
if GetDepend('RT_HWTIMER_ARM_ARCH') == True:
SrcRemove(src, ['gtimer.c'])
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
# build for sub-directory
list = os.listdir(cwd)

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -4,6 +4,6 @@ cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -10,6 +10,6 @@ CPPPATH = [cwd]
src += Glob('*.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -20,6 +20,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -21,6 +21,6 @@ if rtconfig.PLATFORM in ['iccarm']:
if not GetDepend('RT_USING_HW_ATOMIC'):
SrcRemove(src, 'atomic_arm.c')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -39,6 +39,6 @@ if rtconfig.PLATFORM in ['iccarm']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -21,6 +21,6 @@ if rtconfig.PLATFORM in ['iccarm']:
if not GetDepend('RT_USING_MEM_PROTECTION') and not GetDepend('RT_USING_HW_STACK_GUARD'):
SrcRemove(src, 'mpu.c')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -21,6 +21,6 @@ if rtconfig.PLATFORM in ['gcc', 'llvm-arm']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -21,6 +21,6 @@ if rtconfig.PLATFORM in ['iccarm']:
if not GetDepend('RT_USING_MEM_PROTECTION') and not GetDepend('RT_USING_HW_STACK_GUARD'):
SrcRemove(src, 'mpu.c')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -11,6 +11,6 @@ CPPPATH = [cwd]
if rtconfig.PLATFORM in ['gcc', 'armclang', 'llvm-arm']:
src += Glob('*context_gcc.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -18,6 +18,6 @@ if rtconfig.PLATFORM in ['gcc']:
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_vdsp.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -8,6 +8,6 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -10,6 +10,6 @@ ASFLAGS = ' -I ' + cwd
if not GetDepend('RT_USING_HW_ATOMIC'):
SrcRemove(src, 'atomic_riscv.c')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
Return('group')

View File

@@ -7,6 +7,6 @@ CPPPATH = [cwd]
if not GetDepend('ARCH_USING_ASID'):
SrcRemove(src, ['asid.c'])
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -7,6 +7,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
ASFLAGS = ' -I ' + cwd
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
Return('group')

Some files were not shown because too many files have changed in this diff Show More