From 3906f3b948100bfafe03daecf9bc7b1d1ce9fb0b Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Mon, 10 May 2021 20:34:33 +0800 Subject: [add] auto test ci. --- examples/utest/README.md | 79 ++++++++ examples/utest/configs/utest_self/config.h | 297 +++++++++++++++++++++++++++++ examples/utest/testcases/Kconfig | 14 ++ examples/utest/testcases/SConscript | 15 ++ examples/utest/testcases/utest/Kconfig | 7 + examples/utest/testcases/utest/SConscript | 14 ++ examples/utest/testcases/utest/pass_tc.c | 46 +++++ 7 files changed, 472 insertions(+) create mode 100644 examples/utest/README.md create mode 100644 examples/utest/configs/utest_self/config.h create mode 100644 examples/utest/testcases/Kconfig create mode 100644 examples/utest/testcases/SConscript create mode 100644 examples/utest/testcases/utest/Kconfig create mode 100644 examples/utest/testcases/utest/SConscript create mode 100644 examples/utest/testcases/utest/pass_tc.c (limited to 'examples') diff --git a/examples/utest/README.md b/examples/utest/README.md new file mode 100644 index 0000000000..eb54ff170e --- /dev/null +++ b/examples/utest/README.md @@ -0,0 +1,79 @@ +# RT-Thread 测试用例集合 + +## 简介 + +为了保证某一部分代码的质量,通常可以通过编写测试用例的方式,验证此代码的功能。为了保证 RT-Thread 的代码质量,我们搭建了一套简易的自动化测试环境。每当向 RT-Thread 提交代码时,都应该编写对应的测试用例,来保证提交的代码能够正常工作。 + +## 目录结构 + +| 目录 | 用途 | +| --------- | ------------------------------------------------------------ | +| configs | 配置文件集合(每一个目录代表一种功能集合,如:kernel,net等) | +| testcases | 测试用例源代码 | + +## 如何贡献 + +### 1. 编写测试用例 + +参考已有的测试用例在 examples\utest\testcases 目录下添加自己的测试用例。测试用例的编写方法参考文档中心《utest 测试框架》章节。 + +### 2. 本地测试 + +1. 在 bsp\qemu-vexpress-a9 目录下打开 menuconfig,使能对应的测试用例,如下: + +``` +RT-Thread Utestcases ---> + [*] RT-Thread Utestcases + Utest Self Testcase ---> + [*] Pass test +``` + +2. 保存并退出,输入 scons 编译当前 bsp。 + +3. 输入 .\qemu.bat 运行当前 bsp,在 msh 环境下执行 utest_run 命令,验证代码运行是否正常。 + +``` +msh />utest_run +[I/utest] [==========] [ utest ] loop 1/1 +[I/utest] [==========] [ utest ] started +[I/utest] [----------] [ testcase ] (testcases.utest.pass_tc) started +[D/utest] [ OK ] [ unit ] (test_assert_pass:16) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:17) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:19) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:20) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:22) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:23) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:25) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:26) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:28) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:29) is passed +[I/utest] [ PASSED ] [ result ] testcase (testcases.utest.pass_tc) +[I/utest] [----------] [ testcase ] (testcases.utest.pass_tc) finished +[I/utest] [==========] [ utest ] finished +``` + +### 3. 提交 + +1. 如果是对已有测试集合的完善,需要把添加的测试用例的配置项添加到对应测试集合的配置文件里,如:`examples\utest\configs\utest_self\config.h`。 + +``` +/* RT-Thread Utestcases */ + +#define RT_USING_UTESTCASES + +/* Utest Self Testcase */ + +#define UTEST_SELF_PASS_TC + +/* xxx Testcase */ +#define UTEST_XXX_TC +``` + +2. 如果要添加新的测试集合,需要参考已有的测试集合,在 `examples\utest\configs` 目录下添加新的测试集合配置项。并更新 `.github\workflows\action_utest.yml` 内的测试集合。 + +``` +- {UTEST: "kernel/ipc", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"} +- {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"} +``` + +3. 向 RT-Thread 主仓库提交合并请求。 \ No newline at end of file diff --git a/examples/utest/configs/utest_self/config.h b/examples/utest/configs/utest_self/config.h new file mode 100644 index 0000000000..287f0f539d --- /dev/null +++ b/examples/utest/configs/utest_self/config.h @@ -0,0 +1,297 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_USING_SMP +#define RT_CPUS_NR 2 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 1024 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 1024 + +/* kservice optimization */ + +#define RT_DEBUG +#define RT_DEBUG_COLOR + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE +#define RT_USING_SIGNALS + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_MEMHEAP +#define RT_USING_SMALL_MEM +#define RT_USING_MEMTRACE +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_DEVICE_OPS +#define RT_USING_INTERRUPT_INFO +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart0" +#define RT_VER_NUM 0x40004 +#define ARCH_ARM +#define ARCH_ARM_CORTEX_A +#define ARCH_ARM_CORTEX_A9 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + +#define RT_USING_CPLUSPLUS + +/* Command shell */ + +#define RT_USING_FINSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 2 +#define DFS_FILESYSTEM_TYPES_MAX 8 +#define DFS_FD_MAX 16 +#define RT_USING_DFS_ELMFAT + +/* elm-chan's FatFs, Generic FAT Filesystem Module */ + +#define RT_DFS_ELM_CODE_PAGE 437 +#define RT_DFS_ELM_WORD_ACCESS +#define RT_DFS_ELM_USE_LFN_3 +#define RT_DFS_ELM_USE_LFN 3 +#define RT_DFS_ELM_LFN_UNICODE_0 +#define RT_DFS_ELM_LFN_UNICODE 0 +#define RT_DFS_ELM_MAX_LFN 255 +#define RT_DFS_ELM_DRIVES 2 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 +#define RT_DFS_ELM_REENTRANT +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_ROMFS +#define RT_USING_DFS_RAMFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS +#define RT_USING_PIN +#define RT_USING_MTD_NOR +#define RT_USING_MTD_NAND +#define RT_MTD_NAND_DEBUG +#define RT_USING_RTC +#define RT_USING_SOFT_RTC +#define RT_USING_SDIO +#define RT_SDIO_STACK_SIZE 512 +#define RT_SDIO_THREAD_PRIORITY 15 +#define RT_MMCSD_STACK_SIZE 1024 +#define RT_MMCSD_THREAD_PREORITY 22 +#define RT_MMCSD_MAX_PARTITION 16 +#define RT_USING_SPI +#define RT_USING_SPI_MSD +#define RT_USING_SFUD +#define RT_SFUD_USING_SFDP +#define RT_SFUD_USING_FLASH_INFO_TABLE +#define RT_SFUD_SPI_MAX_HZ 50000000 +#define RT_USING_WDT + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC +#define RT_USING_PTHREADS +#define PTHREAD_NUM_MAX 8 +#define RT_USING_POSIX +#define RT_USING_POSIX_MMAP +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_AIO +#define RT_LIBC_FIXED_TIMEZONE 8 + +/* Network */ + +/* Socket abstraction layer */ + +#define RT_USING_SAL +#define SAL_INTERNET_CHECK + +/* protocol stack implement */ + +#define SAL_USING_LWIP +#define SAL_USING_POSIX + +/* Network interface device */ + +#define RT_USING_NETDEV +#define NETDEV_USING_IFCONFIG +#define NETDEV_USING_PING +#define NETDEV_USING_NETSTAT +#define NETDEV_USING_AUTO_DEFAULT +#define NETDEV_IPV4 1 +#define NETDEV_IPV6 0 + +/* light weight TCP/IP stack */ + +#define RT_USING_LWIP +#define RT_USING_LWIP202 +#define RT_LWIP_MEM_ALIGNMENT 4 +#define RT_LWIP_ICMP +#define RT_LWIP_DNS +#define RT_LWIP_DHCP +#define IP_SOF_BROADCAST 1 +#define IP_SOF_BROADCAST_RECV 1 + +/* Static IPv4 Address */ + +#define RT_LWIP_IPADDR "192.168.1.30" +#define RT_LWIP_GWADDR "192.168.1.1" +#define RT_LWIP_MSKADDR "255.255.255.0" +#define RT_LWIP_UDP +#define RT_LWIP_TCP +#define RT_LWIP_RAW +#define RT_MEMP_NUM_NETCONN 8 +#define RT_LWIP_PBUF_NUM 16 +#define RT_LWIP_RAW_PCB_NUM 4 +#define RT_LWIP_UDP_PCB_NUM 4 +#define RT_LWIP_TCP_PCB_NUM 4 +#define RT_LWIP_TCP_SEG_NUM 40 +#define RT_LWIP_TCP_SND_BUF 8196 +#define RT_LWIP_TCP_WND 8196 +#define RT_LWIP_TCPTHREAD_PRIORITY 10 +#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 +#define RT_LWIP_TCPTHREAD_STACKSIZE 1024 +#define RT_LWIP_ETHTHREAD_PRIORITY 12 +#define RT_LWIP_ETHTHREAD_STACKSIZE 1024 +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 +#define RT_LWIP_REASSEMBLY_FRAG +#define LWIP_NETIF_STATUS_CALLBACK 1 +#define LWIP_NETIF_LINK_CALLBACK 1 +#define SO_REUSE 1 +#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_SNDTIMEO 1 +#define LWIP_SO_RCVBUF 1 +#define LWIP_SO_LINGER 0 +#define LWIP_NETIF_LOOPBACK 0 +#define RT_LWIP_USING_PING + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 4096 +#define UTEST_THR_PRIORITY 20 +#define RT_USING_LWP + +/* RT-Thread Utestcases */ + +#define RT_USING_UTESTCASES + +/* Utest Self Testcase */ + +#define UTEST_SELF_PASS_TC + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + + +/* AI packages */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + +#define SOC_VEXPRESS_A9 +#define RT_USING_UART0 +#define RT_USING_UART1 +#define BSP_DRV_EMAC + +#endif diff --git a/examples/utest/testcases/Kconfig b/examples/utest/testcases/Kconfig new file mode 100644 index 0000000000..da80eb30ae --- /dev/null +++ b/examples/utest/testcases/Kconfig @@ -0,0 +1,14 @@ +menu "RT-Thread Utestcases" + +config RT_USING_UTESTCASES + bool "RT-Thread Utestcases" + default n + select RT_USING_UTEST + +if RT_USING_UTESTCASES + +source "$RTT_DIR/examples/utest/testcases/utest/Kconfig" + +endif + +endmenu diff --git a/examples/utest/testcases/SConscript b/examples/utest/testcases/SConscript new file mode 100644 index 0000000000..4c815c49b8 --- /dev/null +++ b/examples/utest/testcases/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/examples/utest/testcases/utest/Kconfig b/examples/utest/testcases/utest/Kconfig new file mode 100644 index 0000000000..85b4d796bd --- /dev/null +++ b/examples/utest/testcases/utest/Kconfig @@ -0,0 +1,7 @@ +menu "Utest Self Testcase" + +config UTEST_SELF_PASS_TC + bool "Pass test" + default y + +endmenu diff --git a/examples/utest/testcases/utest/SConscript b/examples/utest/testcases/utest/SConscript new file mode 100644 index 0000000000..362de4d949 --- /dev/null +++ b/examples/utest/testcases/utest/SConscript @@ -0,0 +1,14 @@ +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = [] + +if GetDepend('UTEST_SELF_PASS_TC'): + src += ['pass_tc.c'] + +CPPPATH = [cwd] + +group = DefineGroup('utestcases', src, depend = ['UTEST_SELF_PASS_TC'], CPPPATH = CPPPATH) + +Return('group') diff --git a/examples/utest/testcases/utest/pass_tc.c b/examples/utest/testcases/utest/pass_tc.c new file mode 100644 index 0000000000..8e93e35b9b --- /dev/null +++ b/examples/utest/testcases/utest/pass_tc.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-01-16 MurphyZhao the first version + */ + +#include +#include "utest.h" + +static void test_assert_pass(void) +{ + uassert_true(1); + uassert_false(0); + + uassert_null(RT_NULL); + uassert_not_null(!RT_NULL); + + uassert_int_equal(1, 1); + uassert_int_not_equal(1, 2); + + uassert_str_equal("Hello RT-Thread!", "Hello RT-Thread!"); + uassert_str_not_equal("Hello RT-Thread!", "Hello"); + + uassert_in_range(2048, 1024, 4096); + uassert_not_in_range(0, 1024, 4096); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_assert_pass); +} +UTEST_TC_EXPORT(testcase, "testcases.utest.pass_tc", utest_tc_init, utest_tc_cleanup, 10); \ No newline at end of file -- cgit v1.3.1 From 7d57170a686fb16e3222f1fac750bc20f7d56963 Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Tue, 11 May 2021 09:22:49 +0800 Subject: 【更新】README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/utest/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/utest/README.md b/examples/utest/README.md index eb54ff170e..f2fe327473 100644 --- a/examples/utest/README.md +++ b/examples/utest/README.md @@ -2,7 +2,7 @@ ## 简介 -为了保证某一部分代码的质量,通常可以通过编写测试用例的方式,验证此代码的功能。为了保证 RT-Thread 的代码质量,我们搭建了一套简易的自动化测试环境。每当向 RT-Thread 提交代码时,都应该编写对应的测试用例,来保证提交的代码能够正常工作。 +为了保证某一部分代码的质量,通常可以通过编写测试用例的方式,验证此代码的功能。为了保证 RT-Thread 相关仓库的代码质量,我们基于 utest 框架搭建了一套简易的自动化测试环境。有兴趣,有精力的小伙伴可以利用这套机制完善自己的代码检查。如果有意愿让社区上更多的小伙伴收益,也可以在提交代码的时候,把对应的测试用例也提交上来。 ## 目录结构 @@ -15,11 +15,11 @@ ### 1. 编写测试用例 -参考已有的测试用例在 examples\utest\testcases 目录下添加自己的测试用例。测试用例的编写方法参考文档中心《utest 测试框架》章节。 +参考已有的测试用例在 `examples\utest\testcases` 目录下添加自己的测试用例。测试用例的编写方法参考文档中心《utest 测试框架》章节。 ### 2. 本地测试 -1. 在 bsp\qemu-vexpress-a9 目录下打开 menuconfig,使能对应的测试用例,如下: +1. 在 `bsp\qemu-vexpress-a9` 目录下打开 `menuconfig`,使能对应的测试用例,如下: ``` RT-Thread Utestcases ---> -- cgit v1.3.1 From e3ee4f2846d89d1b33d414bba79e2bbcac191c7e Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Tue, 11 May 2021 18:43:05 +0800 Subject: [更新]补充文档链接 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/utest/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/utest/README.md b/examples/utest/README.md index f2fe327473..cc84651966 100644 --- a/examples/utest/README.md +++ b/examples/utest/README.md @@ -15,7 +15,7 @@ ### 1. 编写测试用例 -参考已有的测试用例在 `examples\utest\testcases` 目录下添加自己的测试用例。测试用例的编写方法参考文档中心《utest 测试框架》章节。 +参考已有的测试用例在 [examples\utest\testcases](./testcases) 目录下添加自己的测试用例。测试用例的编写方法参考文档中心《utest 测试框架》章节。 ### 2. 本地测试 @@ -54,7 +54,7 @@ msh />utest_run ### 3. 提交 -1. 如果是对已有测试集合的完善,需要把添加的测试用例的配置项添加到对应测试集合的配置文件里,如:`examples\utest\configs\utest_self\config.h`。 +1. 如果是对已有测试集合的完善,需要把添加的测试用例的配置项添加到对应测试集合的配置文件里,如:[examples\utest\configs\utest_self\config.h](./configs/utest_self/config.h)。 ``` /* RT-Thread Utestcases */ @@ -69,7 +69,7 @@ msh />utest_run #define UTEST_XXX_TC ``` -2. 如果要添加新的测试集合,需要参考已有的测试集合,在 `examples\utest\configs` 目录下添加新的测试集合配置项。并更新 `.github\workflows\action_utest.yml` 内的测试集合。 +2. 如果要添加新的测试集合,需要参考已有的测试集合,在 [examples\utest\configs](./configs) 目录下添加新的测试集合配置项。并更新 [.github\workflows\action_utest.yml](../../.github/workflows/action_utest.yml) 内的测试集合。 ``` - {UTEST: "kernel/ipc", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"} -- cgit v1.3.1 From 5767c2e0f4792adfe7d8031591bfdf95ba004bdb Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Wed, 12 May 2021 09:50:40 +0800 Subject: 【完善】SConscript 脚本文件 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/utest/testcases/utest/SConscript | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/utest/testcases/utest/SConscript b/examples/utest/testcases/utest/SConscript index 362de4d949..1b35042e44 100644 --- a/examples/utest/testcases/utest/SConscript +++ b/examples/utest/testcases/utest/SConscript @@ -2,10 +2,9 @@ Import('rtconfig') from building import * cwd = GetCurrentDir() -src = [] - -if GetDepend('UTEST_SELF_PASS_TC'): - src += ['pass_tc.c'] +src = Split(''' +pass_tc.c +''') CPPPATH = [cwd] -- cgit v1.3.1 From 1523e4680d6b17a788314cb38386fd391daad819 Mon Sep 17 00:00:00 2001 From: zhouji <956133287@qq.com> Date: Sat, 1 May 2021 19:15:37 +0800 Subject: [add] 添加gicv3中断控制器代码,更新menuconfig配置选项与utest的config.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/utest/configs/utest_self/config.h | 1 + libcpu/Kconfig | 20 + libcpu/arm/cortex-a/SConscript | 23 +- libcpu/arm/cortex-a/gicv3.c | 708 +++++++++++++++++++++++++++++ libcpu/arm/cortex-a/gicv3.h | 194 ++++++++ libcpu/arm/cortex-a/interrupt.c | 40 +- 6 files changed, 983 insertions(+), 3 deletions(-) create mode 100644 libcpu/arm/cortex-a/gicv3.c create mode 100644 libcpu/arm/cortex-a/gicv3.h (limited to 'examples') diff --git a/examples/utest/configs/utest_self/config.h b/examples/utest/configs/utest_self/config.h index 287f0f539d..2080a544b0 100644 --- a/examples/utest/configs/utest_self/config.h +++ b/examples/utest/configs/utest_self/config.h @@ -55,6 +55,7 @@ #define RT_VER_NUM 0x40004 #define ARCH_ARM #define ARCH_ARM_CORTEX_A +#define RT_USING_GIC_V2 #define ARCH_ARM_CORTEX_A9 /* RT-Thread Components */ diff --git a/libcpu/Kconfig b/libcpu/Kconfig index 974c421138..bb54b487c7 100644 --- a/libcpu/Kconfig +++ b/libcpu/Kconfig @@ -58,6 +58,26 @@ config ARCH_ARM_CORTEX_A bool select ARCH_ARM + if ARCH_ARM_CORTEX_A + config RT_SMP_AUTO_BOOT + bool + default n + + choice + prompt "GIC controller selection" + default RT_USING_GIC_V2 + + config RT_USING_GIC_V2 + bool " Gic version 2 " + + config RT_USING_GIC_V3 + bool " Gic version 3 " + + config RT_NO_USING_GIC + bool " GIC controller is not used " + endchoice + endif + config ARCH_ARM_CORTEX_A5 bool select ARCH_ARM_CORTEX_A diff --git a/libcpu/arm/cortex-a/SConscript b/libcpu/arm/cortex-a/SConscript index 28af7ba651..a9fe6f0bc9 100644 --- a/libcpu/arm/cortex-a/SConscript +++ b/libcpu/arm/cortex-a/SConscript @@ -5,9 +5,27 @@ from building import * Import('rtconfig') cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') +src = Split(''' +cache.c +cpu.c +gtimer.c +mmu.c +pmu.c +stack.c + +''') CPPPATH = [cwd] +if GetDepend('RT_USING_GIC_V2'): + src += ['interrupt.c'] + src += ['gic.c'] + src += ['trap.c'] + +if GetDepend('RT_USING_GIC_V3'): + src += ['interrupt.c'] + src += ['gicv3.c'] + src += ['trap.c'] + if rtconfig.PLATFORM == 'armcc': src += Glob('*_rvds.S') @@ -18,6 +36,9 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-a/gicv3.c b/libcpu/arm/cortex-a/gicv3.c new file mode 100644 index 0000000000..a3fb0e767b --- /dev/null +++ b/libcpu/arm/cortex-a/gicv3.c @@ -0,0 +1,708 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + * 2014-04-03 Grissiom many enhancements + * 2018-11-22 Jesven add rt_hw_ipi_send() + * add rt_hw_ipi_handler_install() + */ + +#include +#include + +#include "gicv3.h" +#include "cp15.h" + +#ifndef RT_CPUS_NR +#define RT_CPUS_NR 1 +#endif + +struct arm_gic_v3 +{ + rt_uint32_t offset; /* the first interrupt index in the vector table */ + rt_uint32_t redist_hw_base[RT_CPUS_NR]; /* the pointer of the gic redistributor */ + rt_uint32_t dist_hw_base; /* the base address of the gic distributor */ + rt_uint32_t cpu_hw_base[RT_CPUS_NR]; /* the base addrees of the gic cpu interface */ +}; + +/* 'ARM_GIC_MAX_NR' is the number of cores */ +static struct arm_gic_v3 _gic_table[ARM_GIC_MAX_NR]; +static unsigned int _gic_max_irq; + +/** + * @name: arm_gic_cpumask_to_affval + * @msg: + * @in param cpu_mask: + * @out param cluster_id: aff1 [0:7],aff2 [8:15],aff3 [16:23] + * @out param target_list: Target List. The set of PEs for which SGI interrupts will be generated. Each bit corresponds to the + * PE within a cluster with an Affinity 0 value equal to the bit number. + * @return {rt_uint32_t} 0 is finish , 1 is data valid + */ +RT_WEAK rt_uint32_t arm_gic_cpumask_to_affval(rt_uint32_t *cpu_mask, rt_uint32_t *cluster_id, rt_uint32_t *target_list) +{ + return 0; +} + +RT_WEAK rt_uint64_t get_main_cpu_affval(void) +{ + return 0; +} + +int arm_gic_get_active_irq(rt_uint32_t index) +{ + int irq; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + __get_gicv3_reg(ICC_IAR1, irq); + + irq = (irq & 0x1FFFFFF) + _gic_table[index].offset; + return irq; +} + +void arm_gic_ack(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT(irq >= 0U); + + __asm__ volatile("dsb 0xF" :: + : "memory"); + __set_gicv3_reg(ICC_EOIR1, irq); +} + +void arm_gic_mask(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1U << (irq % 32U); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq < 32U) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + GIC_RDISTSGI_ICENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask; + } + else + { + GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +void arm_gic_umask(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1U << (irq % 32U); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq < 32U) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + GIC_RDISTSGI_ISENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask; + } + else + { + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +rt_uint32_t arm_gic_get_pending_irq(rt_uint32_t index, int irq) +{ + rt_uint32_t pend; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq >= 16U) + { + pend = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + pend = (GIC_DIST_SPENDSGI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; + /* No CPU identification offered */ + if (pend != 0U) + { + pend = 1U; + } + else + { + pend = 0U; + } + } + + return (pend); +} + +void arm_gic_set_pending_irq(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq >= 16U) + { + GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) = 1U << (irq % 32U); + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + /* Forward the interrupt to the CPU interface that requested it */ + GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = (irq | 0x02000000U); + } +} + +void arm_gic_clear_pending_irq(rt_uint32_t index, int irq) +{ + rt_uint32_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq >= 16U) + { + mask = 1U << (irq % 32U); + GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + } + else + { + mask = 1U << ((irq % 4U) * 8U); + GIC_DIST_CPENDSGI(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +void arm_gic_set_configuration(rt_uint32_t index, int irq, uint32_t config) +{ + rt_uint32_t icfgr; + rt_uint32_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + icfgr = GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq); + shift = (irq % 16U) << 1U; + + icfgr &= (~(3U << shift)); + icfgr |= (config << shift); + + GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) = icfgr; +} + +rt_uint32_t arm_gic_get_configuration(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) >> ((irq % 16U) >> 1U)); +} + +void arm_gic_clear_active(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1U << (irq % 32U); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; +} + +/* Set up the cpu mask for the specific interrupt */ +void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask) +{ + rt_uint32_t old_tgt; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq); + + old_tgt &= ~(0x0FFUL << ((irq % 4U) * 8U)); + old_tgt |= cpumask << ((irq % 4U) * 8U); + + GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt; +} + +rt_uint32_t arm_gic_get_target_cpu(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; +} + +void arm_gic_set_priority(rt_uint32_t index, int irq, rt_uint32_t priority) +{ + rt_uint32_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq < 32U) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + + mask = GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq); + mask &= ~(0xFFUL << ((irq % 4U) * 8U)); + mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U)); + GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) = mask; + } + else + { + mask = GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq); + mask &= ~(0xFFUL << ((irq % 4U) * 8U)); + mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U)); + GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +rt_uint32_t arm_gic_get_priority(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq < 32U) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + + RT_ASSERT((cpu_id) < RT_CPUS_NR); + return (GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) >> ((irq % 4U) * 8U)) & 0xFFUL; + } + else + { + return (GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; + } +} + +void arm_gic_set_system_register_enable_mask(rt_uint32_t index, rt_uint32_t value) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + value &= 0xFFUL; + /* set priority mask */ + __set_gicv3_reg(ICC_SRE, value); + __asm__ volatile ("isb 0xF":: + :"memory"); +} + +rt_uint32_t arm_gic_get_system_register_enable_mask(rt_uint32_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + rt_uint32_t value; + + __get_gicv3_reg(ICC_SRE, value); + return value; +} + +void arm_gic_set_interface_prior_mask(rt_uint32_t index, rt_uint32_t priority) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + priority &= 0xFFUL; + /* set priority mask */ + __set_gicv3_reg(ICC_PMR, priority); +} + +rt_uint32_t arm_gic_get_interface_prior_mask(rt_uint32_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + rt_uint32_t priority; + + __get_gicv3_reg(ICC_PMR, priority); + return priority; +} + +void arm_gic_set_binary_point(rt_uint32_t index, rt_uint32_t binary_point) +{ + index = index; + binary_point &= 0x7U; + + __set_gicv3_reg(ICC_BPR1, binary_point); +} + +rt_uint32_t arm_gic_get_binary_point(rt_uint32_t index) +{ + rt_uint32_t binary_point; + + index = index; + __get_gicv3_reg(ICC_BPR1, binary_point); + return binary_point; +} + +rt_uint32_t arm_gic_get_irq_status(rt_uint32_t index, int irq) +{ + rt_uint32_t pending; + rt_uint32_t active; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + active = (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + pending = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + + return ((active << 1U) | pending); +} + +void arm_gic_send_affinity_sgi(rt_uint32_t index, int irq, rt_uint32_t cpu_mask, rt_uint32_t routing_mode) +{ + rt_uint64_t sgi_val; + + if (routing_mode) + { + sgi_val = (1ULL << 40) | ((irq & 0x0FULL) << 24); //Interrupts routed to all PEs in the system, excluding "self". + /* Write the ICC_SGI1R registers */ + __asm__ volatile("dsb 0xF" :: + : "memory"); + __set_cp64(15, 0, sgi_val, 12); + __asm__ volatile("isb 0xF" :: + : "memory"); + } + else + { + rt_uint32_t cluster_id, target_list; + while (arm_gic_cpumask_to_affval(&cpu_mask, &cluster_id, &target_list)) + { + sgi_val = ((irq & 0x0FULL) << 24 | + target_list | + ((cluster_id >> 8) & 0xFFULL) << GIC_RSGI_AFF1_OFFSET | + ((cluster_id >> 16) & 0xFFULL) << GIC_RSGI_AFF2_OFFSET | + ((cluster_id >> 24) & 0xFFull) << GIC_RSGI_AFF3_OFFSET); + + __asm__ volatile("dsb 0xF" :: + : "memory"); + __set_cp64(15, 0, sgi_val, 12); + __asm__ volatile("isb 0xF" :: + : "memory"); + } + } +} + +rt_uint32_t arm_gic_get_high_pending_irq(rt_uint32_t index) +{ + rt_uint32_t irq; + RT_ASSERT(index < ARM_GIC_MAX_NR); + + index = index; + __get_gicv3_reg(ICC_HPPIR1, irq); + return irq; +} + +rt_uint32_t arm_gic_get_interface_id(rt_uint32_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + return GIC_CPU_IIDR(_gic_table[index].cpu_hw_base); +} + +void arm_gic_set_group(rt_uint32_t index, int irq, rt_uint32_t group) +{ + uint32_t igroupr; + uint32_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT(group <= 1U); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + igroupr = GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq); + shift = (irq % 32U); + igroupr &= (~(1U << shift)); + igroupr |= ((group & 0x1U) << shift); + + GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) = igroupr; +} + +rt_uint32_t arm_gic_get_group(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; +} + +static int arm_gicv3_wait_rwp(rt_uint32_t index, rt_uint32_t irq) +{ + rt_uint32_t rwp_bit; + rt_uint32_t base; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + if (irq < 32u) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + + RT_ASSERT((cpu_id) < RT_CPUS_NR); + base = _gic_table[index].redist_hw_base[cpu_id]; + rwp_bit = GICR_CTLR_RWP; + } + else + { + base = _gic_table[index].dist_hw_base; + rwp_bit = GICD_CTLR_RWP; + } + + while (__REG32(base) & rwp_bit) + { + ; + } + + return 0; +} + +int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start) +{ + rt_uint64_t cpu0_affval; + unsigned int gic_type, i; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + _gic_table[index].dist_hw_base = dist_base; + _gic_table[index].offset = irq_start; + + /* Find out how many interrupts are supported. */ + gic_type = GIC_DIST_TYPE(dist_base); + _gic_max_irq = ((gic_type & 0x1fU) + 1U) * 32U; + + /* + * The GIC only supports up to 1020 interrupt sources. + * Limit this to either the architected maximum, or the + * platform maximum. + */ + if (_gic_max_irq > 1020U) + _gic_max_irq = 1020U; + if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */ + _gic_max_irq = ARM_GIC_NR_IRQS; + + GIC_DIST_CTRL(dist_base) = 0x0U; + /* Wait for register write pending */ + arm_gicv3_wait_rwp(0, 32); + + /* Set all global interrupts to be level triggered, active low. */ + for (i = 32U; i < _gic_max_irq; i += 16U) + GIC_DIST_CONFIG(dist_base, i) = 0x0U; + + arm_gicv3_wait_rwp(0, 32); + + cpu0_affval = get_main_cpu_affval(); + /* Set all global interrupts to this CPU only. */ + for (i = 32U; i < _gic_max_irq; i++) + { + GIC_DIST_IROUTER_LOW(dist_base, i) = cpu0_affval; + GIC_DIST_IROUTER_HIGH(dist_base, i) = cpu0_affval >> 32; + } + + arm_gicv3_wait_rwp(0, 32); + + /* Set priority on spi interrupts. */ + for (i = 32U; i < _gic_max_irq; i += 4U) + GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0U; + + arm_gicv3_wait_rwp(0, 32); + /* Disable all interrupts. */ + for (i = 0U; i < _gic_max_irq; i += 32U) + { + GIC_DIST_PENDING_CLEAR(dist_base, i) = 0xffffffffU; + GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffffU; + } + + arm_gicv3_wait_rwp(0, 32); + /* All interrupts defaults to IGROUP1(IRQ). */ + for (i = 0U; i < _gic_max_irq; i += 32U) + GIC_DIST_IGROUP(dist_base, i) = 0xffffffffU; + + arm_gicv3_wait_rwp(0, 32); + + /* + The Distributor control register (GICD_CTLR) must be configured to enable the interrupt groups and to set the routing mode. + Enable Affinity routing (ARE bits) The ARE bits in GICD_CTLR control whether affinity routing is enabled. + If affinity routing is not enabled, GICv3 can be configured for legacy operation. + Whether affinity routing is enabled or not can be controlled separately for Secure and Non-secure state. + Enables GICD_CTLR contains separate enable bits for Group 0, Secure Group 1 and Non-secure Group 1: + GICD_CTLR.EnableGrp1S enables distribution of Secure Group 1 interrupts. + GICD_CTLR.EnableGrp1NS enables distribution of Non-secure Group 1 interrupts. + GICD_CTLR.EnableGrp0 enables distribution of Group 0 interrupts. + */ + GIC_DIST_CTRL(dist_base) = GICD_CTLR_ARE_NS | GICD_CTLR_ENGRP1NS; + + return 0; +} + +int arm_gic_redist_address_set(rt_uint32_t index, rt_uint32_t redist_addr, rt_uint32_t cpu_id) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + _gic_table[index].redist_hw_base[cpu_id] = redist_addr; + + return 0; +} + +int arm_gic_cpu_interface_address_set(rt_uint32_t index, rt_uint32_t interface_addr, rt_uint32_t cpu_id) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + _gic_table[index].cpu_hw_base[cpu_id] = interface_addr; + + return 0; +} + +int arm_gic_redist_init(rt_uint32_t index) +{ + unsigned int i; + rt_uint32_t base; + rt_int32_t cpu_id = rt_hw_cpu_id(); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT((cpu_id) < RT_CPUS_NR); + + base = _gic_table[index].redist_hw_base[cpu_id]; + /* redistributor enable */ + GIC_RDIST_WAKER(base) &= ~(1U << 1); + while (GIC_RDIST_WAKER(base) & (1 << 2)) + { + ; + } + + /* Disable all sgi and ppi interrupt */ + GIC_RDISTSGI_ICENABLER0(base) = 0xFFFFFFFF; + arm_gicv3_wait_rwp(0, 0); + + /* Clear all inetrrupt pending */ + GIC_RDISTSGI_ICPENDR0(base) = 0xFFFFFFFF; + + /* the corresponding interrupt is Group 1 or Non-secure Group 1. */ + GIC_RDISTSGI_IGROUPR0(base, 0) = 0xFFFFFFFF; + GIC_RDISTSGI_IGRPMODR0(base, 0) = 0xFFFFFFFF; + + /* Configure default priorities for SGI 0:15 and PPI 16:31. */ + for (i = 0; i < 32; i += 4) + { + GIC_RDISTSGI_IPRIORITYR(base, i) = 0xa0a0a0a0U; + } + + /* Trigger level for PPI interrupts*/ + GIC_RDISTSGI_ICFGR1(base) = 0x0U; // PPI is level-sensitive. + return 0; +} + +int arm_gic_cpu_init(rt_uint32_t index) +{ + rt_uint32_t value; + RT_ASSERT(index < ARM_GIC_MAX_NR); + + value = arm_gic_get_system_register_enable_mask(index); + value |= (1U << 0); + arm_gic_set_system_register_enable_mask(index, value); + __set_gicv3_reg(ICC_CTLR, 0); + + arm_gic_set_interface_prior_mask(index, 0xFFU); + + /* Enable group1 interrupt */ + value = 0x1U; + __set_gicv3_reg(ICC_IGRPEN1, value); + + arm_gic_set_binary_point(0, 0); + + /* ICC_BPR0_EL1 determines the preemption group for both + Group 0 and Group 1 interrupts. + */ + value = 0x1U; + __set_gicv3_reg(ICC_CTLR, value); + + return 0; +} + +#ifdef RT_USING_SMP +void arm_gic_secondary_cpu_init(void) +{ + arm_gic_redist_init(0); + + arm_gic_cpu_init(0); +} +#endif + +void arm_gic_dump_type(rt_uint32_t index) +{ + unsigned int gic_type; + + gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); + rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", + (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4U) & 0xfUL, + _gic_table[index].dist_hw_base, + _gic_max_irq, + gic_type & (1U << 10U) ? "has" : "no", + gic_type); +} + +void arm_gic_dump(rt_uint32_t index) +{ + unsigned int i, k; + + k = arm_gic_get_high_pending_irq(0); + rt_kprintf("--- high pending priority: %d(%08x)\n", k, k); + rt_kprintf("--- hw mask ---\n"); + for (i = 0U; i < _gic_max_irq / 32U; i++) + { + rt_kprintf("0x%08x, ", + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, + i * 32U)); + } + rt_kprintf("\n--- hw pending ---\n"); + for (i = 0U; i < _gic_max_irq / 32U; i++) + { + rt_kprintf("0x%08x, ", + GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, + i * 32U)); + } + rt_kprintf("\n--- hw active ---\n"); + for (i = 0U; i < _gic_max_irq / 32U; i++) + { + rt_kprintf("0x%08x, ", + GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, + i * 32U)); + } + rt_kprintf("\n"); +} + +long gic_dump(void) +{ + arm_gic_dump_type(0); + arm_gic_dump(0); + + return 0; +} +MSH_CMD_EXPORT(gic_dump, show gic status); diff --git a/libcpu/arm/cortex-a/gicv3.h b/libcpu/arm/cortex-a/gicv3.h new file mode 100644 index 0000000000..813a4f4c8d --- /dev/null +++ b/libcpu/arm/cortex-a/gicv3.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + */ + +#ifndef __GIC_V3_H__ +#define __GIC_V3_H__ + +#include +#include + +#define __get_gicv3_reg(CR, Rt) __asm__ volatile("MRC " CR \ + : "=r"(Rt) \ + : \ + : "memory") +#define __set_gicv3_reg(CR, Rt) __asm__ volatile("MCR " CR \ + : \ + : "r"(Rt) \ + : "memory") + + +/* AArch32 System register interface to GICv3 */ +#define ICC_IAR0 "p15, 0, %0, c12, c8, 0" +#define ICC_IAR1 "p15, 0, %0, c12, c12, 0" +#define ICC_EOIR0 "p15, 0, %0, c12, c8, 1" +#define ICC_EOIR1 "p15, 0, %0, c12, c12, 1" +#define ICC_HPPIR0 "p15, 0, %0, c12, c8, 2" +#define ICC_HPPIR1 "p15, 0, %0, c12, c12, 2" +#define ICC_BPR0 "p15, 0, %0, c12, c8, 3" +#define ICC_BPR1 "p15, 0, %0, c12, c12, 3" +#define ICC_DIR "p15, 0, %0, c12, c11, 1" +#define ICC_PMR "p15, 0, %0, c4, c6, 0" +#define ICC_RPR "p15, 0, %0, c12, c11, 3" +#define ICC_CTLR "p15, 0, %0, c12, c12, 4" +#define ICC_MCTLR "p15, 6, %0, c12, c12, 4" +#define ICC_SRE "p15, 0, %0, c12, c12, 5" +#define ICC_HSRE "p15, 4, %0, c12, c9, 5" +#define ICC_MSRE "p15, 6, %0, c12, c12, 5" +#define ICC_IGRPEN0 "p15, 0, %0, c12, c12, 6" +#define ICC_IGRPEN1 "p15, 0, %0, c12, c12, 7" +#define ICC_MGRPEN1 "p15, 6, %0, c12, c12, 7" + +#define __REG32(x) (*((volatile unsigned int*)((rt_uint32_t)x))) + +#define ROUTED_TO_ALL (1) +#define ROUTED_TO_SPEC (0) + +/** Macro to access the Distributor Control Register (GICD_CTLR) +*/ +#define GICD_CTLR_RWP (1<<31) +#define GICD_CTLR_E1NWF (1<<7) +#define GICD_CTLR_DS (1<<6) +#define GICD_CTLR_ARE_NS (1<<5) +#define GICD_CTLR_ARE_S (1<<4) +#define GICD_CTLR_ENGRP1S (1<<2) +#define GICD_CTLR_ENGRP1NS (1<<1) +#define GICD_CTLR_ENGRP0 (1<<0) + +/** Macro to access the Redistributor Control Register (GICR_CTLR) +*/ +#define GICR_CTLR_UWP (1<<31) +#define GICR_CTLR_DPG1S (1<<26) +#define GICR_CTLR_DPG1NS (1<<25) +#define GICR_CTLR_DPG0 (1<<24) +#define GICR_CTLR_RWP (1<<3) +#define GICR_CTLR_IR (1<<2) +#define GICR_CTLR_CES (1<<1) +#define GICR_CTLR_EnableLPI (1<<0) + +/** Macro to access the Generic Interrupt Controller Interface (GICC) +*/ +#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00U) +#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04U) +#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08U) +#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0cU) +#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10U) +#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14U) +#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18U) +#define GIC_CPU_IIDR(hw_base) __REG32((hw_base) + 0xFCU) + +/** Macro to access the Generic Interrupt Controller Distributor (GICD) +*/ +#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) +#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004U) +#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380U + ((n)/32U) * 4U) +#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400U + ((n)/4U) * 4U) +#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800U + ((n)/4U) * 4U) +#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00U + ((n)/16U) * 4U) +#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00U) +#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10U + ((n)/4U) * 4U) +#define GIC_DIST_SPENDSGI(hw_base, n) __REG32((hw_base) + 0xf20U + ((n)/4U) * 4U) +#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8U) +#define GIC_DIST_IROUTER_LOW(hw_base, n) __REG32((hw_base) + 0x6000U + (n)*8U) +#define GIC_DIST_IROUTER_HIGH(hw_base, n) __REG32((hw_base) + 0x6000U + (n)*8U + 4) + +/* SGI base address is at 64K offset from Redistributor base address */ +#define GIC_RSGI_OFFSET 0x10000 + +/** Macro to access the Generic Interrupt Controller Redistributor (GICD) +*/ +#define GIC_RDIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) +#define GIC_RDIST_IIDR(hw_base) __REG32((hw_base) + 0x004U) +#define GIC_RDIST_TYPER(hw_base) __REG32((hw_base) + 0x008U) +#define GIC_RDIST_TSTATUSR(hw_base) __REG32((hw_base) + 0x010U) +#define GIC_RDIST_WAKER(hw_base) __REG32((hw_base) + 0x014U) +#define GIC_RDIST_SETLPIR(hw_base) __REG32((hw_base) + 0x040U) +#define GIC_RDIST_CLRLPIR(hw_base) __REG32((hw_base) + 0x048U) +#define GIC_RDIST_PROPBASER(hw_base) __REG32((hw_base) + 0x070U) +#define GIC_RDIST_PENDBASER(hw_base) __REG32((hw_base) + 0x078U) +#define GIC_RDIST_INVLPIR(hw_base) __REG32((hw_base) + 0x0A0U) +#define GIC_RDIST_INVALLR(hw_base) __REG32((hw_base) + 0x0B0U) +#define GIC_RDIST_SYNCR(hw_base) __REG32((hw_base) + 0x0C0U) + +#define GIC_RDISTSGI_IGROUPR0(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x080U + (n)*4U) +#define GIC_RDISTSGI_ISENABLER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x100U) +#define GIC_RDISTSGI_ICENABLER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x180U) +#define GIC_RDISTSGI_ISPENDR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x200U) +#define GIC_RDISTSGI_ICPENDR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x280U) +#define GIC_RDISTSGI_ISACTIVER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x300U) +#define GIC_RDISTSGI_ICACTIVER0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x380U) +#define GIC_RDISTSGI_IPRIORITYR(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0x400U + ((n) / 4U) * 4U) +#define GIC_RDISTSGI_ICFGR0(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U) +#define GIC_RDISTSGI_ICFGR1(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U) +#define GIC_RDISTSGI_IGRPMODR0(hw_base, n) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n)*4) +#define GIC_RDISTSGI_NSACR(hw_base) __REG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U) + +#define GIC_RSGI_AFF1_OFFSET 16 +#define GIC_RSGI_AFF2_OFFSET 32 +#define GIC_RSGI_AFF3_OFFSET 48 + +rt_uint32_t arm_gic_cpumask_to_affval(rt_uint32_t *cpu_mask, rt_uint32_t *cluster_id, rt_uint32_t *target_list); +rt_uint64_t get_main_cpu_affval(void); +int arm_gic_get_active_irq(rt_uint32_t index); +void arm_gic_ack(rt_uint32_t index, int irq); + +void arm_gic_mask(rt_uint32_t index, int irq); +void arm_gic_umask(rt_uint32_t index, int irq); + +rt_uint32_t arm_gic_get_pending_irq(rt_uint32_t index, int irq); +void arm_gic_set_pending_irq(rt_uint32_t index, int irq); +void arm_gic_clear_pending_irq(rt_uint32_t index, int irq); + +void arm_gic_set_configuration(rt_uint32_t index, int irq, uint32_t config); +rt_uint32_t arm_gic_get_configuration(rt_uint32_t index, int irq); + +void arm_gic_clear_active(rt_uint32_t index, int irq); + +void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask); +rt_uint32_t arm_gic_get_target_cpu(rt_uint32_t index, int irq); + +void arm_gic_set_priority(rt_uint32_t index, int irq, rt_uint32_t priority); +rt_uint32_t arm_gic_get_priority(rt_uint32_t index, int irq); + +void arm_gic_set_interface_prior_mask(rt_uint32_t index, rt_uint32_t priority); +rt_uint32_t arm_gic_get_interface_prior_mask(rt_uint32_t index); + +void arm_gic_set_binary_point(rt_uint32_t index, rt_uint32_t binary_point); +rt_uint32_t arm_gic_get_binary_point(rt_uint32_t index); + +rt_uint32_t arm_gic_get_irq_status(rt_uint32_t index, int irq); + +void arm_gic_send_affinity_sgi(rt_uint32_t index, int irq, rt_uint32_t cpu_mask, rt_uint32_t routing_mode); +rt_uint32_t arm_gic_get_high_pending_irq(rt_uint32_t index); + +rt_uint32_t arm_gic_get_interface_id(rt_uint32_t index); + +void arm_gic_set_group(rt_uint32_t index, int irq, rt_uint32_t group); +rt_uint32_t arm_gic_get_group(rt_uint32_t index, int irq); + +int arm_gic_redist_address_set(rt_uint32_t index, rt_uint32_t redist_addr, rt_uint32_t cpu_id); +int arm_gic_cpu_interface_address_set(rt_uint32_t index, rt_uint32_t interface_addr, rt_uint32_t cpu_id); +int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start); +int arm_gic_cpu_init(rt_uint32_t index); +int arm_gic_redist_init(rt_uint32_t index); + +void arm_gic_dump_type(rt_uint32_t index); +void arm_gic_dump(rt_uint32_t index); + +void arm_gic_set_system_register_enable_mask(rt_uint32_t index, rt_uint32_t value); +rt_uint32_t arm_gic_get_system_register_enable_mask(rt_uint32_t index); +void arm_gic_secondary_cpu_init(void); +#endif + diff --git a/libcpu/arm/cortex-a/interrupt.c b/libcpu/arm/cortex-a/interrupt.c index 65e51fa3ae..474a23fee1 100644 --- a/libcpu/arm/cortex-a/interrupt.c +++ b/libcpu/arm/cortex-a/interrupt.c @@ -12,8 +12,12 @@ #include #include #include "interrupt.h" -#include "gic.h" +#ifdef RT_USING_GIC_V2 +#include "gic.h" +#else +#include "gicv3.h" +#endif /* exception and interrupt handler table */ struct rt_irq_desc isr_table[MAX_HANDLERS]; @@ -34,6 +38,7 @@ void rt_hw_vector_init(void) rt_cpu_vector_set_base((unsigned int)&system_vectors); } +#ifdef RT_USING_GIC_V2 /** * This function will initialize hardware interrupt */ @@ -58,6 +63,33 @@ void rt_hw_interrupt_init(void) arm_gic_dist_init(0, gic_dist_base, gic_irq_start); arm_gic_cpu_init(0, gic_cpu_base); } +#else +/** + * This function will initialize hardware interrupt + * Called by the primary cpu(cpu0) + */ +void rt_hw_interrupt_init(void) +{ + rt_uint32_t gic_dist_base; + rt_uint32_t gic_irq_start; + + /* initialize vector table */ + rt_hw_vector_init(); + + /* initialize exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + + /* initialize ARM GIC */ + gic_dist_base = platform_get_gic_dist_base(); + gic_irq_start = GIC_IRQ_START; + + arm_gic_dist_init(0, gic_dist_base, gic_irq_start); + + arm_gic_cpu_init(0); + arm_gic_redist_init(0); +} + +#endif /** * This function will mask a interrupt. @@ -245,7 +277,7 @@ unsigned int rt_hw_interrupt_get_prior_group_bits(void) * @param old_handler the old interrupt service routine */ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, - void *param, const char *name) + void *param, const char *name) { rt_isr_handler_t old_handler = RT_NULL; @@ -269,7 +301,11 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, #ifdef RT_USING_SMP void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) { +#ifdef RT_USING_GIC_V2 arm_gic_send_sgi(0, ipi_vector, cpu_mask, 0); +#else + arm_gic_send_affinity_sgi(0, ipi_vector, cpu_mask, ROUTED_TO_SPEC); +#endif } void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) -- cgit v1.3.1 From 21f9e5625357265245968061079e1c72ffa25ee4 Mon Sep 17 00:00:00 2001 From: Sherman Date: Sat, 15 May 2021 16:52:49 +0800 Subject: [add] add new component: rt-link --- components/utilities/Kconfig | 2 + components/utilities/rt-link/Kconfig | 40 + components/utilities/rt-link/SConscript | 15 + components/utilities/rt-link/hw_port/SConscript | 14 + .../rt-link/hw_port/uart/rtlink_port_uart.c | 73 ++ components/utilities/rt-link/inc/rtlink.h | 175 +++ components/utilities/rt-link/inc/rtlink_hw.h | 24 + components/utilities/rt-link/inc/rtlink_port.h | 31 + components/utilities/rt-link/inc/rtlink_utils.h | 21 + components/utilities/rt-link/src/SConscript | 13 + components/utilities/rt-link/src/rtlink.c | 1192 ++++++++++++++++++++ components/utilities/rt-link/src/rtlink_hw.c | 256 +++++ components/utilities/rt-link/src/rtlink_utils.c | 90 ++ examples/rt-link/rtlink_example.c | 189 ++++ 14 files changed, 2135 insertions(+) create mode 100644 components/utilities/rt-link/Kconfig create mode 100644 components/utilities/rt-link/SConscript create mode 100644 components/utilities/rt-link/hw_port/SConscript create mode 100644 components/utilities/rt-link/hw_port/uart/rtlink_port_uart.c create mode 100644 components/utilities/rt-link/inc/rtlink.h create mode 100644 components/utilities/rt-link/inc/rtlink_hw.h create mode 100644 components/utilities/rt-link/inc/rtlink_port.h create mode 100644 components/utilities/rt-link/inc/rtlink_utils.h create mode 100644 components/utilities/rt-link/src/SConscript create mode 100644 components/utilities/rt-link/src/rtlink.c create mode 100644 components/utilities/rt-link/src/rtlink_hw.c create mode 100644 components/utilities/rt-link/src/rtlink_utils.c create mode 100644 examples/rt-link/rtlink_example.c (limited to 'examples') diff --git a/components/utilities/Kconfig b/components/utilities/Kconfig index 8b733ecf5c..39bb970f6b 100644 --- a/components/utilities/Kconfig +++ b/components/utilities/Kconfig @@ -205,4 +205,6 @@ config RT_USING_UTEST default 20 endif +source "$RTT_DIR/components/utilities/rt-link/Kconfig" + endmenu diff --git a/components/utilities/rt-link/Kconfig b/components/utilities/rt-link/Kconfig new file mode 100644 index 0000000000..10ed129e69 --- /dev/null +++ b/components/utilities/rt-link/Kconfig @@ -0,0 +1,40 @@ +# Kconfig file for rt_link +menuconfig RT_USING_RT_LINK + bool "RT-Link" + default n + +if RT_USING_RT_LINK + choice + prompt"use hw crc device or not" + default RT_LINK_USING_SF_CRC + + config RT_LINK_USING_SF_CRC + bool "use software crc table" + config RT_LINK_USING_HW_CRC + bool "use hardware crc device" + endchoice + + menu "rt-link hardware device configuration" + config RT_LINK_HW_DEVICE_NAME + string "the name of base actual device" + default "uart2" + + choice + prompt"hardware device is spi, uart or usb" + default RT_LINK_USING_UART + + config RT_LINK_USING_UART + bool "use UART" + endchoice + + endmenu + + menu "rt link debug option" + config USING_RT_LINK_DEBUG + bool "Enable RT-Link debug" + default n + config USING_RT_LINK_HW_DEBUG + bool "Enable RT-Link hw debug" + default n + endmenu +endif diff --git a/components/utilities/rt-link/SConscript b/components/utilities/rt-link/SConscript new file mode 100644 index 0000000000..4c815c49b8 --- /dev/null +++ b/components/utilities/rt-link/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/components/utilities/rt-link/hw_port/SConscript b/components/utilities/rt-link/hw_port/SConscript new file mode 100644 index 0000000000..e34243ebda --- /dev/null +++ b/components/utilities/rt-link/hw_port/SConscript @@ -0,0 +1,14 @@ +import os +from building import * +import rtconfig + +cwd = GetCurrentDir() +src = [] +CPPPATH = [] + +if GetDepend('RT_LINK_USING_UART'): + src += ['uart/rtlink_port_uart.c'] + +group = DefineGroup('rt-link-port', src, depend = ['RT_USING_RT_LINK'], CPPPATH = CPPPATH) + +Return('group') diff --git a/components/utilities/rt-link/hw_port/uart/rtlink_port_uart.c b/components/utilities/rt-link/hw_port/uart/rtlink_port_uart.c new file mode 100644 index 0000000000..48fbb91bc3 --- /dev/null +++ b/components/utilities/rt-link/hw_port/uart/rtlink_port_uart.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-09 xiangxistu the first version + */ + +#include +#include + +#include + +#ifndef RT_LINK_HW_DEVICE_NAME + #define RT_LINK_HW_DEVICE_NAME "uart2" +#endif + +#define DBG_TAG "rtlink_port" +#define DBG_LVL DBG_INFO +#include + +static struct rt_device *hw_device = RT_NULL; +rt_err_t rt_link_port_rx_ind(rt_device_t device, rt_size_t size) +{ + RT_ASSERT(device != RT_NULL); + + rt_uint8_t buffer[RT_SERIAL_RB_BUFSZ] = {0}; + rt_size_t length = 0; + length = rt_device_read(device, 0, buffer, sizeof(buffer)); + rt_link_hw_write_cb(&buffer, length); + return RT_EOK; +} + +rt_size_t rt_link_port_send(void *data, rt_size_t length) +{ + rt_size_t size = 0; + size = rt_device_write(hw_device, 0, data, length); + return size; +} + +int rt_link_port_init(void) +{ + hw_device = rt_device_find(RT_LINK_HW_DEVICE_NAME); + if (hw_device) + { + rt_device_open(hw_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); + rt_device_set_rx_indicate(hw_device, rt_link_port_rx_ind); + } + else + { + LOG_E("Not find device %s", RT_LINK_HW_DEVICE_NAME); + return -RT_ERROR; + } + return RT_EOK; +} + +int rt_link_port_deinit(void) +{ + hw_device = rt_device_find(RT_LINK_HW_DEVICE_NAME); + if (hw_device) + { + rt_device_close(hw_device); + rt_device_set_rx_indicate(hw_device, RT_NULL); + } + else + { + LOG_E("Not find device %s", RT_LINK_HW_DEVICE_NAME); + return -RT_ERROR; + } + return RT_EOK; +} diff --git a/components/utilities/rt-link/inc/rtlink.h b/components/utilities/rt-link/inc/rtlink.h new file mode 100644 index 0000000000..dd98b57c30 --- /dev/null +++ b/components/utilities/rt-link/inc/rtlink.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-02-02 xiangxistu the first version + * 2021-03-19 Sherman Streamline the struct rt_link_session + */ + +#ifndef __RT_LINK_H__ +#define __RT_LINK_H__ + +#include + +#define RT_LINK_AUTO_INIT + +#define RT_LINK_FRAME_HEAD 0x15 +#define RT_LINK_FRAME_HEAD_MASK 0x1F +#define RT_LINK_MAX_DATA_LENGTH 2044 /*can exact divide by 4 bytes*/ +#define RT_LINK_FRAMES_MAX 0x03 /* The maximum number of split frames for a long package*/ + +#define RT_LINK_ACK_MAX 0x07 +#define RT_LINK_CRC_LENGTH 4 +#define RT_LINK_HEAD_LENGTH 4 +#define RT_LINK_MAX_EXTEND_LENGTH 4 +#define RT_LINK_MAX_FRAME_LENGTH (RT_LINK_HEAD_LENGTH + RT_LINK_MAX_EXTEND_LENGTH + RT_LINK_MAX_DATA_LENGTH + RT_LINK_CRC_LENGTH) +#define RT_LINK_RECEIVE_BUFFER_LENGTH (RT_LINK_MAX_FRAME_LENGTH * RT_LINK_FRAMES_MAX + RT_LINK_HEAD_LENGTH + RT_LINK_MAX_EXTEND_LENGTH) + +typedef enum +{ + RT_LINK_SERVICE_RTLINK = 0, + RT_LINK_SERVICE_LINK_SOCKET = 1, + RT_LINK_SERVICE_LINK_WIFI = 2, + RT_LINK_SERVICE_LINK_MNGT = 3, + RT_LINK_SERVICE_LINK_MSHTOOLS = 4, + RT_LINK_SERVICE_MAX +} rt_link_service_t; + +enum +{ + FRAME_EXTEND = 1 << 0, + FRAME_CRC = 1 << 1, + FRAME_ACK = 1 << 2 +}; + +typedef enum +{ + RT_LINK_RESERVE_FRAME = 0, + + RT_LINK_RESEND_FRAME, + RT_LINK_CONFIRM_FRAME, + RT_LINK_SHORT_DATA_FRAME, + RT_LINK_LONG_DATA_FRAME, + RT_LINK_SESSION_END, /* The retring failed to end the session */ + + RT_LINK_HANDSHAKE_FRAME +} rt_link_frame_attribute_t; + +typedef enum +{ + /* receive event */ + RT_LINK_READ_CHECK_EVENT = 1 << 0, + RT_LINK_RECV_TIMEOUT_FRAME_EVENT = 1 << 1, + RT_LINK_RECV_TIMEOUT_LONG_EVENT = 1 << 2, + + /* send event */ + RT_LINK_SEND_READY_EVENT = 1 << 4, + RT_LINK_SEND_OK_EVENT = 1 << 5, + RT_LINK_SEND_FAILED_EVENT = 1 << 6, + RT_LINK_SEND_TIMEOUT_EVENT = 1 << 7 +} rt_link_notice_t; + +typedef enum +{ + RT_LINK_ESTABLISHING = 0, + RT_LINK_NO_RESPONSE, + RT_LINK_CONNECT_DONE, +} rt_link_linkstatus_t; + +typedef enum +{ + RECVTIMER_NONE = 0, + RECVTIMER_FRAME, + RECVTIMER_LONGFRAME +} rt_link_recvtimer_status_t; + +struct rt_link_receive_buffer +{ + rt_uint8_t data[RT_LINK_RECEIVE_BUFFER_LENGTH]; /* rt-link receive data buffer */ + rt_uint8_t *read_point; + rt_uint8_t *write_point; + rt_uint8_t *end_point; +}; + +struct rt_link_frame_head +{ + rt_uint8_t magicid : 5; + rt_uint8_t extend : 1; + rt_uint8_t crc : 1; + rt_uint8_t ack : 1; + rt_uint8_t sequence; + rt_uint16_t channel: 5; + rt_uint16_t length : 11; +}; + +/* record frame information that opposite */ +struct rt_link_record +{ + rt_uint8_t rx_seq; /* record the opposite sequence */ + rt_uint8_t total; /* the number of long frame number */ + rt_uint8_t long_count; /* long packet recv counter */ + rt_uint8_t *dataspace; /* the space of long frame */ +}; + +struct rt_link_extend +{ + rt_uint16_t attribute; /* rt_link_frame_attribute_t */ + rt_uint16_t parameter; +}; + +struct rt_link_frame +{ + struct rt_link_frame_head head; /* frame head */ + struct rt_link_extend extend; /* frame extend data */ + rt_uint8_t *real_data; /* the origin data */ + rt_uint32_t crc; /* CRC result */ + + rt_uint16_t data_len; /* the length of frame length */ + rt_uint16_t attribute; /* this will show frame attribute , rt_link_frame_attribute_t */ + + rt_uint8_t index; /* the index frame for long frame */ + rt_uint8_t total; /* the total frame for long frame */ + + rt_slist_t slist; /* the frame will hang on the send list on session */ +}; + +struct rt_link_service +{ + rt_err_t (*upload_callback)(void *data, rt_size_t size); +}; + +struct rt_link_session +{ + rt_link_linkstatus_t link_status; /* Link connection status*/ + struct rt_event event; /* the event that core logic */ + struct rt_link_service channel[RT_LINK_SERVICE_MAX]; /* thansfer to app layer */ + + rt_slist_t tx_data_slist; + rt_uint8_t tx_seq; /* sequence for frame */ + struct rt_mutex tx_lock; /* protect send data interface, only one thread can hold it */ + struct rt_timer sendtimer; /* send function timer for rt link */ + + struct rt_link_record rx_record; /* the memory of receive status */ + struct rt_timer recvtimer; /* receive a frame timer for rt link */ + struct rt_timer longframetimer; /* receive long frame timer for rt link */ + + struct rt_link_receive_buffer *rx_buffer; /* the buffer will store data */ + rt_uint32_t (*calculate_crc)(rt_uint8_t using_buffer_ring, rt_uint8_t *data, rt_size_t size); /* this function will calculate crc */ +}; + +/* rtlink init and deinit */ +int rt_link_init(void); +rt_err_t rt_link_deinit(void); +/* rtlink send data interface */ +rt_size_t rt_link_send(rt_link_service_t service, void *data, rt_size_t size); +/* rtlink service attach and detach */ +rt_err_t rt_link_service_attach(rt_link_service_t service, rt_err_t (*function)(void *data, rt_size_t size)); +rt_err_t rt_link_service_detach(rt_link_service_t service); + +/* Private operator function */ +struct rt_link_session *rt_link_get_scb(void); + +#endif /* __RT_LINK_H__ */ diff --git a/components/utilities/rt-link/inc/rtlink_hw.h b/components/utilities/rt-link/inc/rtlink_hw.h new file mode 100644 index 0000000000..c75609a23a --- /dev/null +++ b/components/utilities/rt-link/inc/rtlink_hw.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-02-02 xiangxistu the first version + * + */ +#ifndef __RT_LINK_HW_H__ +#define __RT_LINK_HW_H__ + +#include + +rt_size_t rt_link_hw_recv_len(struct rt_link_receive_buffer *buffer); +void rt_link_hw_copy(rt_uint8_t *dst, rt_uint8_t *src, rt_size_t count); +void rt_link_hw_buffer_point_shift(rt_uint8_t **pointer_address, rt_size_t length); + +rt_err_t rt_link_hw_init(void); +rt_err_t rt_link_hw_deinit(void); +rt_err_t rt_link_hw_send(void *data, rt_size_t length); + +#endif /* _RT_LINK_PORT_INTERNAL_H_ */ diff --git a/components/utilities/rt-link/inc/rtlink_port.h b/components/utilities/rt-link/inc/rtlink_port.h new file mode 100644 index 0000000000..54a064d117 --- /dev/null +++ b/components/utilities/rt-link/inc/rtlink_port.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-02-02 xiangxistu the first version + * 2021-05-15 Sherman function rename + */ +#ifndef __RT_LINK_PORT_H__ +#define __RT_LINK_PORT_H__ + +#include + +/* Functions that need to be implemented at the hardware */ +int rt_link_port_init(void); +int rt_link_port_deinit(void); +rt_size_t rt_link_port_send(void *data, rt_size_t length); + +#ifdef RT_LINK_USING_HW_CRC + rt_err_t rt_link_hw_crc32_init(void); + rt_err_t rt_link_hw_crc32_deinit(void); + rt_err_t rt_link_hw_crc32_reset(void); + rt_uint32_t rt_link_hw_crc32(rt_uint8_t *data, rt_size_t u32_size) +#endif + +/* Called when the hardware receives data and the data is transferred to RTLink */ +rt_size_t rt_link_hw_write_cb(void *data, rt_size_t length); + +#endif /* __RT_LINK_PORT_H__ */ diff --git a/components/utilities/rt-link/inc/rtlink_utils.h b/components/utilities/rt-link/inc/rtlink_utils.h new file mode 100644 index 0000000000..564039c390 --- /dev/null +++ b/components/utilities/rt-link/inc/rtlink_utils.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-15 Sherman the first version + */ +#ifndef __RT_LINK_UTILITIES_H__ +#define __RT_LINK_UTILITIES_H__ + +#include + +/* Calculate the number of '1' */ +int rt_link_utils_num1(rt_uint32_t n); + +rt_err_t rt_link_sf_crc32_reset(void); +rt_uint32_t rt_link_sf_crc32(rt_uint8_t *data, rt_size_t len); + +#endif /* __RT_LINK_UTILITIES_H__ */ diff --git a/components/utilities/rt-link/src/SConscript b/components/utilities/rt-link/src/SConscript new file mode 100644 index 0000000000..8bbb969b2a --- /dev/null +++ b/components/utilities/rt-link/src/SConscript @@ -0,0 +1,13 @@ +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd + '/../inc'] + +group = DefineGroup('rt-link', src, depend = ['RT_USING_RT_LINK'], CPPPATH = CPPPATH) + +if os.path.isfile(os.path.join(cwd, 'hw', 'SConscript')): + group = group + SConscript(os.path.join('hw', 'SConscript')) + +Return('group') diff --git a/components/utilities/rt-link/src/rtlink.c b/components/utilities/rt-link/src/rtlink.c new file mode 100644 index 0000000000..37a99538b6 --- /dev/null +++ b/components/utilities/rt-link/src/rtlink.c @@ -0,0 +1,1192 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-02-02 xiangxistu the first version + * 2021-03-19 Sherman Optimize the transfer process + * 2021-04-20 Sherman Optimize memory footprint + * 2021-05-10 Sherman Add rtlink_status MSH command; Optimize transmission timer Settings; Fix known bugs + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define DBG_ENABLE +#ifdef USING_RT_LINK_DEBUG + #define DBG_LVL DBG_LOG +#else + #define DBG_LVL DBG_INFO +#endif +#define DBG_TAG "rtlink" +#define DBG_COLOR +#include + +#ifdef RT_LINK_USING_SPI + #define RT_LINK_LONG_FRAME_TIMEOUT 50 + #define RT_LINK_SENT_FRAME_TIMEOUT 100 +#else + #define RT_LINK_LONG_FRAME_TIMEOUT 100 + #define RT_LINK_SENT_FRAME_TIMEOUT 200 +#endif /* RT_LINK_USING_SPI */ + +#define RT_LINK_RECV_DATA_SEQUENCE 0 +#define RT_LINK_INIT_FRAME_SEQENCE 129 + +#define RT_LINK_THREAD_NAME "rtlink" +#define RT_LINK_THREAD_TICK 20 +#define RT_LINK_THREAD_PRIORITY 15 +#define RT_LINK_THREAD_STACK_SIZE 832 /* 32 bytes aligned */ + +typedef enum +{ + FIND_FRAME_HEAD = 0, + PARSE_FRAME_HEAD, + PARSE_FRAME_EXTEND, + PARSE_FRAME_SEQ, + CHECK_FRAME_CRC, + HEADLE_FRAME_DATA, +} rt_link_frame_parse_t; + +/* rtlink SCB(Session control block) */ +static struct rt_link_session *rt_link_scb = RT_NULL; +struct rt_link_session *rt_link_get_scb(void) +{ + return rt_link_scb; +} + +static rt_int16_t rt_link_check_seq(rt_uint8_t new, rt_uint8_t used) +{ + rt_int16_t compare_seq = 0; + compare_seq = new - used; + if (compare_seq < 0) + { + compare_seq = compare_seq + 256; + } + return compare_seq; +} + +static int rt_link_frame_init(struct rt_link_frame *frame, rt_uint8_t config) +{ + if (frame == RT_NULL) + { + return -RT_ERROR; + } + + /* set frame control information */ + rt_memset(&frame->head, 0, sizeof(struct rt_link_frame_head)); + if (config & FRAME_CRC) + { + frame->head.crc = 1; + } + if (config & FRAME_ACK) + { + frame->head.ack = 1; + } + + frame->head.magicid = RT_LINK_FRAME_HEAD; + /* frame data information */ + rt_memset(&frame->extend, 0, sizeof(struct rt_link_extend)); + frame->crc = 0; + frame->real_data = RT_NULL; + frame->data_len = 0; + frame->index = 0; + frame->total = 0; + frame->attribute = RT_LINK_RESERVE_FRAME; + + rt_slist_init(&frame->slist); + + return RT_EOK; +} + +static rt_err_t rt_link_frame_free(struct rt_link_frame *frame) +{ + if (frame == RT_NULL) + { + return -RT_ERROR; + } + + if (frame->real_data != RT_NULL) + { + rt_free(frame->real_data); + frame->real_data = RT_NULL; + } + rt_memset(frame, 0, sizeof(struct rt_link_frame)); + rt_free(frame); + return RT_EOK; +} + +/* performs data transmission */ +static rt_err_t rt_link_frame_send(rt_slist_t *slist) +{ + struct rt_link_frame *frame = RT_NULL; + rt_uint8_t *origin_data = RT_NULL; + rt_uint8_t *data = RT_NULL; + rt_size_t length = 0; + rt_uint8_t send_max = RT_LINK_ACK_MAX; /* The number of '1' in the binary number */ + + /* if slist is tx_data_slist, we should send all data on the slist*/ + if (slist == &rt_link_scb->tx_data_slist) + { + slist = rt_slist_next(&rt_link_scb->tx_data_slist); + } + if (slist == RT_NULL) + { + LOG_W("tx_data_slist NULL"); + return -RT_ERROR; + } + data = rt_malloc(RT_LINK_MAX_FRAME_LENGTH); + if (data == RT_NULL) + { + LOG_E("rt link alloc memory(%d B) failed, send frame failed.", RT_LINK_MAX_FRAME_LENGTH); + return -RT_ENOMEM; + } + origin_data = data; + + do + { + /* get frame for send */ + frame = rt_container_of(slist, struct rt_link_frame, slist); + slist = rt_slist_next(slist); + + length = RT_LINK_HEAD_LENGTH; + if (frame->head.crc) + { + length += RT_LINK_CRC_LENGTH; + } + if (frame->head.extend) + { + length += RT_LINK_MAX_EXTEND_LENGTH; + } + + length += frame->data_len; + frame->head.length = frame->data_len; + rt_memcpy(data, &frame->head, RT_LINK_HEAD_LENGTH); + data = data + RT_LINK_HEAD_LENGTH; + if (frame->head.extend) + { + rt_memcpy(data, &frame->extend, RT_LINK_MAX_EXTEND_LENGTH); + data = data + RT_LINK_MAX_EXTEND_LENGTH; + } + if (frame->attribute == RT_LINK_SHORT_DATA_FRAME || frame->attribute == RT_LINK_LONG_DATA_FRAME) + { + rt_memcpy(data, frame->real_data, frame->data_len); + data = data + frame->data_len; + } + if (frame->head.crc) + { + frame->crc = rt_link_scb->calculate_crc(RT_FALSE, origin_data, length - RT_LINK_CRC_LENGTH); + rt_memcpy(data, &frame->crc, RT_LINK_CRC_LENGTH); + } + + LOG_D("frame send(%d) len(%d) attr:(%d), crc:(0x%08x).", frame->head.sequence, length, frame->attribute, frame->crc); + rt_link_hw_send(origin_data, length); + + data = origin_data; + if (slist == RT_NULL) + { + send_max = 0; + } + send_max >>= 1; + }while (send_max); + rt_free(origin_data); + return RT_EOK; +} + +static void _stop_recv_long(void) +{ + rt_timer_stop(&rt_link_scb->longframetimer); + if (rt_link_scb->rx_record.dataspace != RT_NULL) + { + rt_free(rt_link_scb->rx_record.dataspace); + rt_link_scb->rx_record.dataspace = RT_NULL; + } + rt_link_scb->rx_record.long_count = 0; + rt_link_scb->rx_record.total = 0; +} + +static rt_err_t rt_link_frame_stop_receive(struct rt_link_frame *frame) +{ + rt_memset(frame, 0, sizeof(struct rt_link_frame)); + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, rt_link_hw_recv_len(rt_link_scb->rx_buffer)); + return RT_EOK; +} + +/* Configure the extended field of the frame */ +static rt_err_t rt_link_frame_extend_config(struct rt_link_frame *frame, rt_link_frame_attribute_t attribute, rt_uint16_t parameter) +{ + frame->head.extend = 1; + frame->extend.attribute = attribute; + frame->extend.parameter = parameter; + return RT_EOK; +} + +static int rt_link_command_frame_send(rt_uint8_t sequence, rt_link_frame_attribute_t attribute, rt_uint16_t parameter) +{ + struct rt_link_frame command_frame = {0}; + rt_uint8_t extend_flag = RT_FALSE; + + /* command frame don't need crc and ack ability */ + rt_link_frame_init(&command_frame, RT_NULL); + command_frame.head.sequence = sequence; + command_frame.head.length = RT_LINK_MAX_EXTEND_LENGTH; + command_frame.attribute = attribute; + switch (attribute) + { + case RT_LINK_RESEND_FRAME: + extend_flag = RT_TRUE; + LOG_D("send RESEND_FRAME(%d).", command_frame.head.sequence); + break; + + case RT_LINK_HANDSHAKE_FRAME: + extend_flag = RT_TRUE; + LOG_D("send HANDSHAKE_FRAME(%d).", command_frame.head.sequence); + break; + + case RT_LINK_CONFIRM_FRAME: + LOG_D("send CONFIRM_FRAME(%d).", command_frame.head.sequence); + break; + + default: + break; + } + + if (extend_flag) + { + rt_link_frame_extend_config(&command_frame, attribute, parameter); + } + rt_link_frame_send(&command_frame.slist); + return RT_EOK; +} + +static rt_err_t rt_link_resend_handle(struct rt_link_frame *receive_frame) +{ + struct rt_link_frame *find_frame = RT_NULL; + rt_slist_t *tem_list = RT_NULL; + + tem_list = rt_slist_first(&rt_link_scb->tx_data_slist); + while (tem_list != RT_NULL) + { + find_frame = rt_container_of(tem_list, struct rt_link_frame, slist); + if (find_frame->head.sequence == receive_frame->head.sequence) + { + LOG_D("resend frame(%d)", find_frame->head.sequence); + rt_link_frame_send(&find_frame->slist); + break; + } + tem_list = tem_list->next; + } + + if (tem_list == RT_NULL) + { + LOG_D("frame resent failed, can't find(%d).", receive_frame->head.sequence); + rt_link_command_frame_send(receive_frame->head.sequence, RT_LINK_SESSION_END, RT_NULL); + } + return RT_EOK; +} + +static rt_err_t rt_link_confirm_handle(struct rt_link_frame *receive_frame) +{ + static struct rt_link_frame *send_frame = RT_NULL; + struct rt_link_frame *find_frame = RT_NULL; + rt_slist_t *tem_list = RT_NULL; + rt_uint16_t seq_offset = 0; + + LOG_D("confirm seq(%d) frame", receive_frame->head.sequence); + if (rt_link_scb->link_status == RT_LINK_NO_RESPONSE) + { + /* The handshake success and resends the data frame */ + LOG_D("link_status RT_LINK_CONNECT_DONE, resend data"); + rt_link_scb->link_status = RT_LINK_CONNECT_DONE; + if (rt_slist_first(&rt_link_scb->tx_data_slist)) + { + rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT); + } + return RT_EOK; + } + + /* Check to see if the frame is send for confirm */ + tem_list = rt_slist_first(&rt_link_scb->tx_data_slist); + if (tem_list == RT_NULL) + { + return -RT_ERROR; + } + + send_frame = rt_container_of(tem_list, struct rt_link_frame, slist); + seq_offset = rt_link_check_seq(receive_frame->head.sequence, + rt_link_scb->tx_seq); + if (seq_offset <= send_frame->total) + { + LOG_D("confirm frame (%d)", receive_frame->head.sequence); + for (int i = 0; i < seq_offset; i++) + { + find_frame = rt_container_of(tem_list, struct rt_link_frame, slist); + LOG_D("confirm(%d), remove(%d)", receive_frame->head.sequence, find_frame->head.sequence); + + rt_enter_critical(); + rt_slist_remove(&rt_link_scb->tx_data_slist, &find_frame->slist); + rt_exit_critical(); + find_frame->real_data = RT_NULL; + rt_link_frame_free(find_frame); + + tem_list = rt_slist_first(&rt_link_scb->tx_data_slist); + if (tem_list == RT_NULL) + { + break; + } + } + rt_link_scb->tx_seq = receive_frame->head.sequence; + rt_link_scb->link_status = RT_LINK_CONNECT_DONE; + if (tem_list == RT_NULL) + { + LOG_D("SEND_OK"); + rt_event_send(&rt_link_scb->event, RT_LINK_SEND_OK_EVENT); + } + else + { + LOG_D("Continue sending"); + rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT); + } + } + return RT_EOK; +} + +static rt_err_t rt_link_short_handle(struct rt_link_frame *receive_frame) +{ + LOG_D("Seq(%d) short data", receive_frame->head.sequence); + rt_link_scb->rx_record.dataspace = rt_malloc(receive_frame->data_len); + if (rt_link_scb->rx_record.dataspace != RT_NULL) + { + rt_link_command_frame_send(receive_frame->head.sequence, RT_LINK_CONFIRM_FRAME, RT_NULL); + rt_link_scb->rx_record.rx_seq = receive_frame->head.sequence; + + if (rt_link_scb->channel[receive_frame->head.channel].upload_callback == RT_NULL) + { + rt_free(rt_link_scb->rx_record.dataspace); + LOG_E("Channel %d has not been registered", receive_frame->head.channel); + } + else + { + rt_enter_critical(); + rt_link_hw_copy(rt_link_scb->rx_record.dataspace, receive_frame->real_data, receive_frame->data_len); + rt_exit_critical(); + rt_link_scb->channel[receive_frame->head.channel].upload_callback(rt_link_scb->rx_record.dataspace, receive_frame->data_len); + } + rt_link_scb->rx_record.dataspace = RT_NULL; + rt_link_frame_stop_receive(receive_frame); + } + else + { + LOG_W("short data %dB alloc failed", receive_frame->data_len); + } + receive_frame->real_data = RT_NULL; + return 0; +} + +static void _long_handle_first(struct rt_link_frame *receive_frame, rt_uint8_t *count_mask) +{ + if (receive_frame->extend.parameter % RT_LINK_MAX_DATA_LENGTH == 0) + { + receive_frame->total = receive_frame->extend.parameter / RT_LINK_MAX_DATA_LENGTH; + } + else + { + receive_frame->total = receive_frame->extend.parameter / RT_LINK_MAX_DATA_LENGTH + 1; + } + + rt_link_scb->rx_record.total = receive_frame->total; + rt_link_scb->rx_record.dataspace = rt_malloc(receive_frame->extend.parameter); + if (rt_link_scb->rx_record.dataspace == RT_NULL) + { + LOG_W("long data %dB alloc failed.", receive_frame->extend.parameter); + } + +} + +static void _long_handle_second(struct rt_link_frame *receive_frame, rt_uint8_t count_mask) +{ + static rt_uint8_t ack_mask = RT_LINK_ACK_MAX; + + void *data = RT_NULL; + rt_size_t size = 0; + rt_uint16_t serve = 0; + rt_size_t offset = 0; /* offset, count from 0 */ + + receive_frame->index = rt_link_check_seq(receive_frame->head.sequence, rt_link_scb->rx_record.rx_seq) - 1; + LOG_D("index= %d, count= 0x%x, seq(%d), rxseq(%d)", receive_frame->index, rt_link_scb->rx_record.long_count, receive_frame->head.sequence, rt_link_scb->rx_record.rx_seq); + + if ((receive_frame->index > RT_LINK_FRAMES_MAX) || (rt_link_scb->rx_record.long_count & (0x01 << receive_frame->index))) + { + LOG_D("ERR:index %d, rx_seq %d", receive_frame->index, rt_link_scb->rx_record.rx_seq); + } + else if (rt_link_scb->rx_record.dataspace != RT_NULL) + { + LOG_D("long_count (0x%02x)index(%d)total(%d) seq(%d)", rt_link_scb->rx_record.long_count, receive_frame->index, receive_frame->total, receive_frame->head.sequence); + rt_link_scb->rx_record.long_count |= (0x01 << receive_frame->index); + offset = RT_LINK_MAX_DATA_LENGTH * receive_frame->index; + + rt_enter_critical(); + rt_link_hw_copy(rt_link_scb->rx_record.dataspace + offset, receive_frame->real_data, receive_frame->data_len); + rt_exit_critical(); + + if (rt_link_utils_num1(rt_link_scb->rx_record.long_count) == rt_link_scb->rx_record.total) + { + rt_link_command_frame_send((rt_link_scb->rx_record.rx_seq + rt_link_scb->rx_record.total), RT_LINK_CONFIRM_FRAME, RT_NULL); + } + else if ((rt_link_scb->rx_record.long_count & ack_mask) == ack_mask) + { + rt_link_command_frame_send((rt_link_scb->rx_record.rx_seq + rt_link_utils_num1(ack_mask)), RT_LINK_CONFIRM_FRAME, RT_NULL); + ack_mask |= ack_mask << rt_link_utils_num1(RT_LINK_ACK_MAX); + } + + /* receive a complete package */ + if (rt_link_utils_num1(rt_link_scb->rx_record.long_count) == rt_link_scb->rx_record.total) + { + rt_timer_stop(&rt_link_scb->longframetimer); + + rt_enter_critical(); + data = rt_link_scb->rx_record.dataspace; + size = receive_frame->extend.parameter; + serve = receive_frame->head.channel; + /* empty rx_record */ + rt_link_scb->rx_record.rx_seq += rt_link_scb->rx_record.total; + rt_link_scb->rx_record.dataspace = RT_NULL; + rt_link_scb->rx_record.long_count = 0; + rt_link_scb->rx_record.total = 0; + ack_mask = RT_LINK_ACK_MAX; + rt_link_frame_stop_receive(receive_frame); + rt_exit_critical(); + + if (rt_link_scb->channel[serve].upload_callback == RT_NULL) + { + rt_free(data); + LOG_E("channel %d haven't been registered.", serve); + } + else + { + rt_link_scb->channel[serve].upload_callback(data, size); + } + } + else if (rt_link_hw_recv_len(rt_link_scb->rx_buffer) < (receive_frame->data_len % RT_LINK_MAX_DATA_LENGTH)) + { + rt_int32_t timeout = RT_LINK_LONG_FRAME_TIMEOUT; + rt_timer_control(&rt_link_scb->longframetimer, RT_TIMER_CTRL_SET_TIME, &timeout); + rt_timer_start(&rt_link_scb->longframetimer); + } + } +} + +static rt_err_t rt_link_long_handle(struct rt_link_frame *receive_frame) +{ + static rt_uint8_t count_mask = 0; + if (rt_link_scb->rx_record.long_count == 0) + { + /* Receive this long package for the first time: + * calculates the total number of frames, + * requests space, and turns on the receive timer */ + _long_handle_first(receive_frame, &count_mask); + } + if (rt_link_scb->rx_record.total > 0) + { + /* Intermediate frame processing: + * serial number repeated check, + * receive completion check, reply to ACK */ + _long_handle_second(receive_frame, count_mask); + } + receive_frame->real_data = RT_NULL; + return RT_EOK; +} + +static rt_err_t rt_link_handshake_handle(struct rt_link_frame *receive_frame) +{ + LOG_D("Sequence(%d) is a connect handshake frame.", receive_frame->head.sequence); + rt_link_scb->link_status = RT_LINK_CONNECT_DONE; + /* sync requester tx seq, responder rx seq = requester tx seq */ + rt_link_scb->rx_record.rx_seq = receive_frame->head.sequence; + /* sync requester rx seq, responder tx seq = requester rx seq */ + rt_link_scb->tx_seq = receive_frame->extend.parameter; + rt_link_command_frame_send(receive_frame->head.sequence, RT_LINK_CONFIRM_FRAME, RT_NULL); + return RT_EOK; +} + +/* Discriminate frame type */ +static rt_err_t rt_link_parse_frame(struct rt_link_frame *receive_frame) +{ + switch (receive_frame->attribute) + { + case RT_LINK_RESEND_FRAME: + rt_link_resend_handle(receive_frame); + break; + case RT_LINK_CONFIRM_FRAME: + rt_link_confirm_handle(receive_frame); + break; + case RT_LINK_SHORT_DATA_FRAME: + rt_link_short_handle(receive_frame); + break; + case RT_LINK_LONG_DATA_FRAME: + rt_link_long_handle(receive_frame); + break; + case RT_LINK_HANDSHAKE_FRAME: + rt_link_handshake_handle(receive_frame); + break; + case RT_LINK_SESSION_END: + rt_link_frame_stop_receive(receive_frame); + break; + default: + break; + } + return RT_EOK; +} + +/* Empty the sending list */ +static void rt_link_datalist_empty(void) +{ + struct rt_link_frame *find_frame = RT_NULL; + rt_slist_t *tem_list = rt_slist_first(&rt_link_scb->tx_data_slist); + while (tem_list != RT_NULL) + { + find_frame = rt_container_of(tem_list, struct rt_link_frame, slist); + tem_list = rt_slist_next(tem_list); + rt_enter_critical(); + rt_slist_remove(&rt_link_scb->tx_data_slist, &find_frame->slist); + rt_exit_critical(); + + find_frame->real_data = RT_NULL; + rt_link_frame_free(find_frame); + } +} + +/* RT_LINK_READ_CHECK_EVENT handle */ +static void rt_link_frame_check(void) +{ + static struct rt_link_frame receive_frame = {0}; + static rt_link_frame_parse_t analysis_status = FIND_FRAME_HEAD; + static rt_uint8_t *data = RT_NULL; + static rt_uint16_t buff_len = RT_LINK_HEAD_LENGTH; + + struct rt_link_frame *send_frame = RT_NULL; + rt_tick_t timeout = 0; + rt_uint8_t *real_data = RT_NULL; + rt_uint32_t temporary_crc = 0; + + rt_uint8_t offset = 0; + rt_size_t recv_len = rt_link_hw_recv_len(rt_link_scb->rx_buffer); + while (recv_len > 0) + { + switch (analysis_status) + { + case FIND_FRAME_HEAD: + { + /* if we can't find frame head, throw that data */ + if ((*rt_link_scb->rx_buffer->read_point & RT_LINK_FRAME_HEAD_MASK) == RT_LINK_FRAME_HEAD) + { + analysis_status = PARSE_FRAME_HEAD; + break; + } + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1); + break; + } + + case PARSE_FRAME_HEAD: + { + if (recv_len < buff_len) + { + LOG_D("The length is not enough,recv=%d buff=%d", recv_len, buff_len); + return ; + } + /* Data is an offset address */ + data = rt_link_scb->rx_buffer->read_point; + rt_link_frame_init(&receive_frame, RT_NULL); + rt_link_hw_copy((rt_uint8_t *)&receive_frame.head, data, sizeof(struct rt_link_frame_head)); + rt_link_hw_buffer_point_shift(&data, sizeof(struct rt_link_frame_head)); + receive_frame.data_len = receive_frame.head.length; + LOG_D("check seq(%d) data len(%d).", receive_frame.head.sequence, receive_frame.data_len); + + if (receive_frame.head.extend) + { + buff_len += RT_LINK_MAX_EXTEND_LENGTH; + analysis_status = PARSE_FRAME_EXTEND; + } + else + { + analysis_status = PARSE_FRAME_SEQ; + } + } + + case PARSE_FRAME_EXTEND: + { + if (receive_frame.head.extend) + { + if (recv_len < buff_len) + { + LOG_D("PARSE_FRAME_EXTEND: actual: %d, need: %d.", recv_len, buff_len); + + /* should set timer, control receive frame timeout, one shot */ + timeout = 50; + rt_timer_control(&rt_link_scb->recvtimer, RT_TIMER_CTRL_SET_TIME, &timeout); + rt_timer_start(&rt_link_scb->recvtimer); + return; + } + rt_link_hw_copy((rt_uint8_t *)&receive_frame.extend, data, sizeof(struct rt_link_extend)); + rt_link_hw_buffer_point_shift(&data, sizeof(struct rt_link_extend)); + switch (receive_frame.extend.attribute) + { + case RT_LINK_RESEND_FRAME: + case RT_LINK_LONG_DATA_FRAME: + case RT_LINK_HANDSHAKE_FRAME: + receive_frame.attribute = receive_frame.extend.attribute; + break; + default: + receive_frame.attribute = RT_LINK_RESERVE_FRAME; + break; + } + } + else + { + if (receive_frame.head.crc) + { + receive_frame.attribute = RT_LINK_SHORT_DATA_FRAME; + } + else + { + receive_frame.attribute = RT_LINK_CONFIRM_FRAME; + } + } + if (receive_frame.attribute == RT_LINK_RESERVE_FRAME) + { + LOG_D("quick filter error frame."); + rt_link_frame_stop_receive(&receive_frame); + buff_len = RT_LINK_HEAD_LENGTH; + analysis_status = FIND_FRAME_HEAD; + break; + } + analysis_status = PARSE_FRAME_SEQ; + } + + case PARSE_FRAME_SEQ: + { + if ((receive_frame.attribute == RT_LINK_CONFIRM_FRAME) || (receive_frame.attribute == RT_LINK_RESEND_FRAME)) + { + offset = rt_link_check_seq(receive_frame.head.sequence, rt_link_scb->tx_seq); + if (rt_slist_first(&rt_link_scb->tx_data_slist) != RT_NULL) + { + send_frame = rt_container_of(rt_link_scb->tx_data_slist.next, struct rt_link_frame, slist); + if (offset > send_frame->total) + { + /* exceptional frame, ignore it */ + LOG_D("seq (%d) failed, tx_seq (%d).offset=(%d) total= (%d)", receive_frame.head.sequence, rt_link_scb->tx_seq, offset, send_frame->total); + rt_link_frame_stop_receive(&receive_frame); + buff_len = RT_LINK_HEAD_LENGTH; + analysis_status = FIND_FRAME_HEAD; + break; + } + } + } + else + { + offset = rt_link_check_seq(receive_frame.head.sequence, rt_link_scb->rx_record.rx_seq) - 1; + if ((offset > RT_LINK_FRAMES_MAX) && (receive_frame.attribute != RT_LINK_HANDSHAKE_FRAME)) + { + /* exceptional frame, ignore it */ + LOG_D("seq (%d) failed, rx_seq (%d) offset=(%d) attr= (%d) status (%d)", receive_frame.head.sequence, rt_link_scb->rx_record.rx_seq, offset, receive_frame.attribute, rt_link_scb->link_status); + rt_link_frame_stop_receive(&receive_frame); + buff_len = RT_LINK_HEAD_LENGTH; + analysis_status = FIND_FRAME_HEAD; + break; + } + } + + buff_len += receive_frame.data_len; + if (receive_frame.head.crc) + { + buff_len += RT_LINK_CRC_LENGTH; + analysis_status = CHECK_FRAME_CRC; + } + else + { + analysis_status = HEADLE_FRAME_DATA; + } + } + + case CHECK_FRAME_CRC: + { + if (receive_frame.head.crc) + { + if (recv_len < buff_len) + { + /* should set timer, control receive frame timeout, one shot */ + timeout = 50; + rt_timer_control(&rt_link_scb->recvtimer, RT_TIMER_CTRL_SET_TIME, &timeout); + rt_timer_start(&rt_link_scb->recvtimer); + return; + } + + real_data = data; + rt_timer_stop(&rt_link_scb->recvtimer); + rt_link_hw_buffer_point_shift(&data, receive_frame.data_len); + rt_link_hw_copy((rt_uint8_t *)&receive_frame.crc, data, RT_LINK_CRC_LENGTH); + temporary_crc = rt_link_scb->calculate_crc(RT_TRUE, rt_link_scb->rx_buffer->read_point, buff_len - RT_LINK_CRC_LENGTH); + if (receive_frame.crc != temporary_crc) + { + /* check failed. ready resent */ + LOG_D("CRC: calc:(0x%08x) ,recv:(0x%08x).", temporary_crc, receive_frame.crc); + /* quick resent, when sequence is right, we can ask for reset this frame */ + rt_link_command_frame_send(receive_frame.head.sequence, RT_LINK_RESEND_FRAME, RT_NULL); + + /* throw the error frame */ + buff_len = RT_LINK_HEAD_LENGTH; + rt_link_frame_stop_receive(&receive_frame); + + /* clear the frame information */ + analysis_status = FIND_FRAME_HEAD; + break; + } + /* fill real data point */ + receive_frame.real_data = real_data; + } + analysis_status = HEADLE_FRAME_DATA; + } + + case HEADLE_FRAME_DATA: + { + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, buff_len); + rt_link_parse_frame(&receive_frame); + data = RT_NULL; + buff_len = RT_LINK_HEAD_LENGTH; + analysis_status = FIND_FRAME_HEAD; + break; + } + + default: + LOG_E("analysis_status is error."); + break; + } + recv_len = rt_link_hw_recv_len(rt_link_scb->rx_buffer); + } +} + +static void rt_link_send_ready(void) +{ + if (rt_link_scb->link_status != RT_LINK_CONNECT_DONE) + { + rt_link_scb->link_status = RT_LINK_NO_RESPONSE; + rt_link_command_frame_send(rt_link_scb->tx_seq, RT_LINK_HANDSHAKE_FRAME, rt_link_scb->rx_record.rx_seq); + } + else + { + if (RT_EOK != rt_link_frame_send(&rt_link_scb->tx_data_slist)) + { + rt_event_send(&rt_link_scb->event, RT_LINK_SEND_FAILED_EVENT); + } + } +} + +static void rt_link_frame_recv_timeout(void) +{ + /* The receiving frame timeout and a new receive begins */ + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, rt_link_hw_recv_len(rt_link_scb->rx_buffer)); +} + +static void rt_link_send_timeout(void) +{ + static rt_uint8_t count = 0; + if (count++ > 5) + { + LOG_W("Send timeout, please check the link status!"); + count = 0; + rt_event_send(&rt_link_scb->event, RT_LINK_SEND_FAILED_EVENT); + } + else + { + rt_timer_start(&rt_link_scb->sendtimer); + rt_link_command_frame_send(rt_link_scb->tx_seq, RT_LINK_HANDSHAKE_FRAME, rt_link_scb->rx_record.rx_seq); + } +} + +static int rt_link_long_recv_timeout(void) +{ + static rt_uint8_t count = 0; + if (count++ > 5) + { + LOG_W("long package receive timeout"); + count = 0; + _stop_recv_long(); + } + else + { + for (rt_uint8_t total = rt_link_scb->rx_record.total; total > 0; total--) + { + if (((rt_link_scb->rx_record.long_count >> (total - 1)) & 0x01) == 0x00) + { + /* resend command */ + rt_link_command_frame_send((rt_link_scb->rx_record.rx_seq + total), RT_LINK_RESEND_FRAME, RT_NULL); + } + } + } + return RT_EOK; +} + +void rt_link_thread(void *parameter) +{ + rt_uint32_t recved = 0; + while (1) + { + rt_event_recv(&rt_link_scb->event, RT_LINK_READ_CHECK_EVENT | + RT_LINK_SEND_READY_EVENT | + RT_LINK_SEND_TIMEOUT_EVENT | + RT_LINK_RECV_TIMEOUT_FRAME_EVENT | + RT_LINK_RECV_TIMEOUT_LONG_EVENT, + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, + &recved); + + if (recved & RT_LINK_READ_CHECK_EVENT) + { + rt_link_frame_check(); + } + + if (recved & RT_LINK_SEND_READY_EVENT) + { + rt_link_send_ready(); + } + + if (recved & RT_LINK_SEND_TIMEOUT_EVENT) + { + rt_link_send_timeout(); + } + + if (recved & RT_LINK_RECV_TIMEOUT_FRAME_EVENT) + { + rt_link_frame_recv_timeout(); + } + + if (recved & RT_LINK_RECV_TIMEOUT_LONG_EVENT) + { + rt_link_long_recv_timeout(); + } + } +} + +static void rt_link_sendtimer_callback(void *parameter) +{ + rt_event_send(&rt_link_scb->event, RT_LINK_SEND_TIMEOUT_EVENT); +} + +static void rt_link_recvtimer_callback(void *parameter) +{ + rt_event_send(&rt_link_scb->event, RT_LINK_RECV_TIMEOUT_FRAME_EVENT); +} + +static void rt_link_receive_long_frame_callback(void *parameter) +{ + rt_event_send(&rt_link_scb->event, RT_LINK_RECV_TIMEOUT_LONG_EVENT); +} + +/** + * rtlink send data interface + * @param service Registered service channel, choose enum rt_link_service_t + * @param data send data + * @param size send data size + * @return The actual size of the data sent + * */ +rt_size_t rt_link_send(rt_link_service_t service, void *data, rt_size_t size) +{ + if ((size == 0) || (data == RT_NULL) || (service >= RT_LINK_SERVICE_MAX)) + { + return 0; + } + rt_mutex_take(&rt_link_scb->tx_lock, RT_WAITING_FOREVER); + + rt_uint32_t recved = 0; + rt_err_t result = RT_EOK; + rt_uint32_t timeout = 0; + + rt_uint8_t total = 0; /* The total number of frames to send */ + rt_uint8_t index = 0; /* The index of the split packet */ + rt_size_t offset = 0; /* The offset of the send data */ + + struct rt_link_frame *send_frame = RT_NULL; + rt_link_frame_attribute_t attribute; + if (size % RT_LINK_MAX_DATA_LENGTH == 0) + { + total = size / RT_LINK_MAX_DATA_LENGTH; + } + else + { + total = size / RT_LINK_MAX_DATA_LENGTH + 1; + } + + if (total > RT_LINK_FRAMES_MAX) + { + result = -RT_ENOMEM; + goto __exit; + } + else if (total > 1) + { + attribute = RT_LINK_LONG_DATA_FRAME; + } + else + { + attribute = RT_LINK_SHORT_DATA_FRAME; + } + + do + { + send_frame = rt_malloc(sizeof(struct rt_link_frame)); + rt_link_frame_init(send_frame, FRAME_CRC | FRAME_ACK); + send_frame->head.sequence = rt_link_scb->tx_seq + 1 + index; + send_frame->head.channel = service; + send_frame->real_data = (rt_uint8_t *)data + offset; + send_frame->index = index; + send_frame->total = total; + + if (attribute == RT_LINK_LONG_DATA_FRAME) + { + send_frame->attribute = RT_LINK_LONG_DATA_FRAME; + if (offset + RT_LINK_MAX_DATA_LENGTH > size) + { + send_frame->data_len = size - offset; + } + else + { + send_frame->data_len = RT_LINK_MAX_DATA_LENGTH; + offset += RT_LINK_MAX_DATA_LENGTH; + } + + rt_link_frame_extend_config(send_frame, RT_LINK_LONG_DATA_FRAME, size); + } + else + { + send_frame->attribute = RT_LINK_SHORT_DATA_FRAME; + send_frame->data_len = size; + } + + /* append the frame on the tail of list */ + LOG_D("new data append on the send slist, seq(%d), len(%d).", send_frame->head.sequence, send_frame->data_len); + rt_slist_append(&rt_link_scb->tx_data_slist, &send_frame->slist); + + index++; + }while(total > index); + + timeout = RT_LINK_SENT_FRAME_TIMEOUT * total; + rt_timer_control(&rt_link_scb->sendtimer, RT_TIMER_CTRL_SET_TIME, &timeout); + rt_timer_start(&rt_link_scb->sendtimer); + /* Notify the core thread to send packet */ + rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT); + + /* Wait for the packet to be sent successfully */ + rt_event_recv(&rt_link_scb->event, RT_LINK_SEND_OK_EVENT | RT_LINK_SEND_FAILED_EVENT, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved); + + if (recved & RT_LINK_SEND_OK_EVENT) + { + result = RT_EOK; + } + else if (recved & RT_LINK_SEND_FAILED_EVENT) + { + LOG_E("the data (%dB) send failed", size); + result = -RT_ERROR; + } + else + { + LOG_E("unexpected event."); + result = -RT_ERROR; + } +__exit: + rt_timer_stop(&rt_link_scb->sendtimer); + /* Empty the sending list */ + rt_link_datalist_empty(); + rt_mutex_release(&rt_link_scb->tx_lock); + if (result == RT_EOK) + { + return size; + } + return result; +} + +void rtlink_status(void) +{ + rt_kprintf("rtlink status:\n"); + if (rt_link_scb != RT_NULL) + { + rt_kprintf("\tlink status=%d\n", rt_link_scb->link_status); + + rt_kprintf("\trx seq=%d\n", rt_link_scb->rx_record.rx_seq); + rt_kprintf("\ttx seq=%d\n", rt_link_scb->tx_seq); + rt_kprintf("\trecv len=%d\n", rt_link_hw_recv_len(rt_link_scb->rx_buffer)); + + rt_tick_t state = 0; + rt_timer_control(&rt_link_scb->longframetimer, RT_TIMER_CTRL_GET_STATE, &state); + rt_kprintf("\tlong timer state=%d\n", state); + rt_timer_control(&rt_link_scb->sendtimer, RT_TIMER_CTRL_GET_STATE, &state); + rt_kprintf("\tsend timer state=%d\n", state); + + rt_kprintf("\tevent set=0x%08x\n", rt_link_scb->event.set); + if (rt_link_scb->tx_data_slist.next) + { + rt_slist_t *data = RT_NULL; + rt_slist_for_each(data, &rt_link_scb->tx_data_slist) + { + rt_kprintf("\tsend data list: serv %u\t", ((struct rt_link_frame_head *)data)->channel); + rt_kprintf(" seq %u\t", ((struct rt_link_frame_head *)data)->sequence); + rt_kprintf(" len %u\n", ((struct rt_link_frame_head *)data)->length); + } + } + else + { + rt_kprintf("\tsend data list: NULL\n"); + } + + rt_uint8_t serv = sizeof(rt_link_scb->channel) / sizeof(struct rt_link_service); + while (serv--) + { + rt_kprintf("\tservices [%d](0x%p)\n", serv, rt_link_scb->channel[serv]); + } + } + else + { + rt_kprintf("status NULL, please check the initialization status!\n"); + } +} +MSH_CMD_EXPORT(rtlink_status, Display RTLINK status); + +/** + * rtlink deinit the interface + * */ +rt_err_t rt_link_deinit(void) +{ + rt_enter_critical(); + rt_link_hw_deinit(); + if (rt_link_scb) + { + rt_timer_detach(&rt_link_scb->longframetimer); + rt_timer_detach(&rt_link_scb->sendtimer); + rt_timer_detach(&rt_link_scb->recvtimer); + rt_mutex_detach(&rt_link_scb->tx_lock); + rt_event_detach(&rt_link_scb->event); + rt_free(rt_link_scb); + rt_link_scb = RT_NULL; + } + rt_thread_t thread = rt_thread_find(RT_LINK_THREAD_NAME); + if (thread) + { + rt_thread_delete(thread); + } + rt_exit_critical(); + return RT_EOK; +} +MSH_CMD_EXPORT(rt_link_deinit, rt link deinit); + +/** + * rtlink initializes the interface, usually automatically. + * @return int Function Execution Result + * */ +int rt_link_init(void) +{ + rt_err_t result = RT_EOK; + rt_thread_t thread = RT_NULL; + + if (rt_link_scb != RT_NULL) + { + goto __exit; + } + + rt_link_scb = rt_malloc(sizeof(struct rt_link_session)); + if (rt_link_scb == RT_NULL) + { + result = -RT_ENOMEM; + goto __exit; + } + + rt_memset(rt_link_scb, 0, sizeof(struct rt_link_session)); + rt_event_init(&rt_link_scb->event, "lny_event", RT_IPC_FLAG_FIFO); + rt_event_control(&rt_link_scb->event, RT_IPC_CMD_RESET, RT_NULL); + + rt_mutex_init(&rt_link_scb->tx_lock, "tx_lock", RT_IPC_FLAG_FIFO); + rt_timer_init(&rt_link_scb->sendtimer, "tx_time", rt_link_sendtimer_callback, + RT_NULL, 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_PERIODIC); + rt_timer_init(&rt_link_scb->recvtimer, "rx_time", rt_link_recvtimer_callback, + RT_NULL, 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT); + rt_timer_init(&rt_link_scb->longframetimer, "rxl_time", rt_link_receive_long_frame_callback, + RT_NULL, 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_PERIODIC); + + rt_link_scb->link_status = RT_LINK_ESTABLISHING; + + rt_link_scb->rx_record.rx_seq = 255; + + rt_slist_init(&rt_link_scb->tx_data_slist); + rt_link_scb->tx_seq = RT_LINK_INIT_FRAME_SEQENCE; + + /* create rtlink core work thread */ + thread = rt_thread_create(RT_LINK_THREAD_NAME, + rt_link_thread, + RT_NULL, + RT_LINK_THREAD_STACK_SIZE, + RT_LINK_THREAD_PRIORITY, + RT_LINK_THREAD_TICK); + if (thread == RT_NULL) + { + result = -RT_ENOMEM; + goto __exit; + } + rt_thread_startup(thread); + result = rt_link_hw_init(); + +__exit: + if (result != RT_EOK) + { + LOG_E("rtlink init failed."); + rt_link_deinit(); + } + else + { + LOG_I("rtlink init success."); + } + return result; +} +#ifdef RT_LINK_AUTO_INIT + INIT_ENV_EXPORT(rt_link_init); +#endif +MSH_CMD_EXPORT(rt_link_init, rt link init); + +/** + * rtlink service attach + * @param service Registered service channel, choose enum rt_link_service_t + * @param function receive callback function + * @return Function Execution Result + * */ +rt_err_t rt_link_service_attach(rt_link_service_t service, rt_err_t (*function)(void *data, rt_size_t size)) +{ + if (service >= RT_LINK_SERVICE_MAX) + { + LOG_W("Invalid parameter."); + return -RT_ERROR; + } + rt_link_scb->channel[service].upload_callback = function; + LOG_I("rt link attach service[%02d].", service); + return RT_EOK; +} + +/** + * rtlink service detach + * @param service Registered service channel, choose enum rt_link_service_t + * @return rt_err_t Function Execution Result + * */ +rt_err_t rt_link_service_detach(rt_link_service_t service) +{ + if (service >= RT_LINK_SERVICE_MAX) + { + LOG_W("Invalid parameter."); + return -RT_ERROR; + } + rt_link_scb->channel[service].upload_callback = RT_NULL; + LOG_I("rt link detach service[%02d].", service); + return RT_EOK; +} diff --git a/components/utilities/rt-link/src/rtlink_hw.c b/components/utilities/rt-link/src/rtlink_hw.c new file mode 100644 index 0000000000..9c4567ab63 --- /dev/null +++ b/components/utilities/rt-link/src/rtlink_hw.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-02-02 xiangxistu the first version + * 2021-05-08 Sherman Optimize the operation function on the rt_link_receive_buffer + */ + +#include + +#include +#include +#include +#include + +#define DBG_TAG "rtlink_hw" +#ifdef USING_RT_LINK_HW_DEBUG + #define DBG_LVL DBG_LOG +#else + #define DBG_LVL DBG_INFO +#endif +#define DBG_COLOR +#include + +static struct rt_link_receive_buffer *rx_buffer = RT_NULL; + +struct rt_link_receive_buffer *rt_link_hw_buffer_init(void *parameter) +{ + rx_buffer = rt_malloc(sizeof(struct rt_link_receive_buffer)); + if (rx_buffer != RT_NULL) + { + rt_memset(rx_buffer, 0, sizeof(struct rt_link_receive_buffer)); + rx_buffer->read_point = rx_buffer->data; + rx_buffer->write_point = rx_buffer->data; + rx_buffer->end_point = rx_buffer->data + RT_LINK_RECEIVE_BUFFER_LENGTH; /* Point to memory that has no access rights */ + } + else + { + LOG_E("receive buffer alloc failed, init failed."); + } + + return rx_buffer; +} + +static rt_size_t rt_link_hw_buffer_write(void *data, rt_size_t count) +{ + int surplus = 0; + if (rx_buffer == RT_NULL) + { + return 0; + } + /* (data)----(r)----(w)----(end) */ + if (rx_buffer->write_point >= rx_buffer->read_point) + { + rt_size_t w2end = rx_buffer->end_point - rx_buffer->write_point; + surplus = RT_LINK_RECEIVE_BUFFER_LENGTH - (rx_buffer->write_point - rx_buffer->read_point); + count = count > surplus ? surplus : count; + if (count >= w2end) + { + rt_memcpy(rx_buffer->write_point, data, w2end); + rx_buffer->write_point = rx_buffer->data; + + rt_memcpy(rx_buffer->write_point, (rt_uint8_t *)data + w2end, (count - w2end)); + rx_buffer->write_point += (count - w2end); + } + else + { + rt_memcpy(rx_buffer->write_point, data, count); + rx_buffer->write_point += count; + } + } + else /* (data)----(w)----(r)----(end) */ + { + surplus = rx_buffer->read_point - rx_buffer->write_point; + count = count > surplus ? surplus : count; + rt_memcpy(rx_buffer->write_point, data, count); + rx_buffer->write_point += count; + } + return count; +} + +/* increases buffer pointer by one and circle around if necessary */ +void rt_link_hw_buffer_point_shift(rt_uint8_t **pointer_address, rt_size_t length) +{ + rt_uint8_t *pointer = RT_NULL; + + pointer = *pointer_address + length; + if (pointer >= rx_buffer->end_point) + { + rt_size_t offset = 0; + offset = pointer - rx_buffer->end_point; + *pointer_address = rx_buffer->data + offset; + } + else + { + *pointer_address = *pointer_address + length; + } +} + +/* copy data from receive buffer */ +void rt_link_hw_copy(rt_uint8_t *dst, rt_uint8_t *src, rt_size_t count) +{ + rt_uint8_t *pointer = RT_NULL; + + pointer = src + count; + if (pointer >= rx_buffer->end_point) + { + rt_size_t offset = 0; + offset = rx_buffer->end_point - src; + rt_memcpy(dst, src, offset); + rt_memcpy(dst + offset, rx_buffer->data, pointer - rx_buffer->end_point); + } + else + { + rt_memcpy(dst, src, count); + } +} + +/* Tells, how many chars are saved into the buffer */ +rt_size_t rt_link_hw_recv_len(struct rt_link_receive_buffer *buffer) +{ + if (buffer->write_point >= buffer->read_point) + { + return (buffer->write_point - buffer->read_point); + } + else + { + return (RT_LINK_RECEIVE_BUFFER_LENGTH - (buffer->read_point - buffer->write_point)); + } +} + +rt_err_t rt_link_reset_crc32(void) +{ +#ifdef RT_LINK_USING_HW_CRC + return rt_link_hw_crc32_reset(); +#else + return rt_link_sf_crc32_reset(); +#endif +} + +rt_uint32_t rt_link_crc32(rt_uint8_t *data, rt_size_t u32_size) +{ +#ifdef RT_LINK_USING_HW_CRC + return rt_link_hw_crc32(data, u32_size); +#else + return rt_link_sf_crc32(data, u32_size); +#endif +} + +rt_uint32_t rt_link_get_crc(rt_uint8_t using_buffer_ring, rt_uint8_t *data, rt_size_t size) +{ + rt_uint32_t crc32 = 0x0; + rt_size_t surplus = 0; + + if (data == RT_NULL) + { + LOG_D("warning, the parameter error: %d, data: 0x%08d.", size, data); + return 0; + } + + rt_link_reset_crc32(); + if (using_buffer_ring == 1) + { + /* modify the missing character */ + surplus = rx_buffer->end_point - data; + if (surplus >= size) + { + crc32 = rt_link_crc32(data, size); + } + else + { + rt_link_crc32(data, surplus); + crc32 = rt_link_crc32(rx_buffer->data, size - surplus); + } + } + else + { + crc32 = rt_link_crc32(data, size); + } + return crc32; +} + +rt_err_t rt_link_hw_send(void *data, rt_size_t length) +{ + rt_size_t send_len = 0; + send_len = rt_link_port_send(data, length); + LOG_D("hw_send len= %d", send_len); + return send_len; +} + +/* provide this function to hardware spi/uart/usb to store data */ +rt_size_t rt_link_hw_write_cb(void *data, rt_size_t length) +{ + /* write real data into rtlink receive buffer */ + rt_size_t len = rt_link_hw_buffer_write(data, length); + struct rt_link_session *scb = rt_link_get_scb(); + if (scb) + { + rt_event_send(&scb->event, RT_LINK_READ_CHECK_EVENT); + } + return len; +} + +rt_err_t rt_link_hw_init(void) +{ + struct rt_link_session *scb = rt_link_get_scb(); + if ((rx_buffer != RT_NULL) || (scb == RT_NULL)) + { + return -RT_ERROR; + } + + /* alloc receive buffer to store data */ + if (rt_link_hw_buffer_init(RT_NULL) == RT_NULL) + { + return -RT_ENOMEM; + } + scb->rx_buffer = rx_buffer; + scb->calculate_crc = rt_link_get_crc; + + rt_link_port_init(); + +#ifdef LINK_LAYER_USING_HW_CRC + /* crc hardware device for mcu and node */ + rt_link_hw_crc32_init(); +#endif + + LOG_I("link layer hardware environment init successful."); + return RT_EOK; +} + +rt_err_t rt_link_hw_deinit(void) +{ + if (rx_buffer) + { + rt_free(rx_buffer); + rx_buffer = RT_NULL; + } + struct rt_link_session *scb = rt_link_get_scb(); + if (scb) + { + scb->rx_buffer = rx_buffer; + scb->calculate_crc = RT_NULL; + } + rt_link_port_deinit(); + +#ifdef LINK_LAYER_USING_HW_CRC + /* crc hardware device for mcu and node */ + rt_link_hw_crc32_deinit(); +#endif + + LOG_I("rtlink hardware deinit successful."); + return RT_EOK; +} diff --git a/components/utilities/rt-link/src/rtlink_utils.c b/components/utilities/rt-link/src/rtlink_utils.c new file mode 100644 index 0000000000..c5cfbb9422 --- /dev/null +++ b/components/utilities/rt-link/src/rtlink_utils.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-15 Sherman the first version + */ + +#include + +/* Calculate the number of '1' */ +int rt_link_utils_num1(rt_uint32_t n) +{ + int ret = 0; + while (n) + { + n &= n - 1; + ret++; + } + return ret; +} + +#ifdef RT_LINK_USING_SF_CRC + +static rt_uint32_t crc = 0xffffffff; +const rt_uint32_t crc_table[256] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, + 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, + 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, + 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, + 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, + 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, + 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, + 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, + 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, + 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, + 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, + 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, + 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, + 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, + 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, + 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, + 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, + 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, + 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, + 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, + 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, + 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, + 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, + 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, + 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +rt_err_t rt_link_sf_crc32_reset(void) +{ + crc = 0xffffffff; + return RT_EOK; +} + +rt_uint32_t rt_link_sf_crc32(rt_uint8_t *data, rt_size_t len) +{ + rt_uint32_t x, y; + x = 0; + y = 0; + rt_size_t i; + + for (i = 0; i < len; i++) + { + y = (crc ^ data[i]) & 0xff; + x = crc_table[y]; + crc = (crc >> 8) ^ x; + } + return (crc ^ 0xffffffff); +} +#endif /* RT_LINK_USING_SF_CRC */ diff --git a/examples/rt-link/rtlink_example.c b/examples/rt-link/rtlink_example.c new file mode 100644 index 0000000000..7c70c25e6f --- /dev/null +++ b/examples/rt-link/rtlink_example.c @@ -0,0 +1,189 @@ + +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-15 Sherman the first version + */ + +#include +#include +#include +#include + +#define DBG_ENABLE +#define DBG_TAG "rtlink_exam" +#define DBG_LVL DBG_INFO +#include + +#define TEST_CONTEXT "This message is sent by RT-Link" + +enum +{ + NONE_TEST = 0, + SHORT_FRAME_TEST, + LONG_FRAME_TEST +}; + +void rt_link_speed_test(void *paremeter); +static rt_uint8_t speed_test_type = NONE_TEST; + +rt_err_t rt_link_receive_example_callback(void *data, rt_size_t length) +{ + LOG_I("recv data %d",length); + LOG_HEX("example",8,data,length); + rt_free(data); + return RT_EOK; +} + +void create_thead_to_test_speed(rt_uint8_t mutil_num) +{ + rt_uint8_t i = 0; + + LOG_D("Speed test type [%02d], mutil [%02d]", speed_test_type, mutil_num); + for(i = 0; i< mutil_num; i++) + { + rt_thread_t tid; + char tid_name[RT_NAME_MAX + 1] = {0}; + + rt_snprintf(tid_name, sizeof(tid_name), "lny_s%03d", i + 1); + tid = rt_thread_create(tid_name, rt_link_speed_test, RT_NULL, 1024, 20, 10); + rt_thread_startup(tid); + LOG_I("Speed test thread[%s] startup", tid_name); + } +} + +void rt_link_speed_test(void *paremeter) +{ + int ret; + rt_uint8_t *send_buf, *data; + rt_size_t bufflen = 0; + rt_size_t sentlen = 0; + rt_size_t count = 0; + rt_tick_t tick1, tick2; + rt_size_t total = 0; + rt_uint32_t integer, decimal; + + if(speed_test_type == SHORT_FRAME_TEST) + { + bufflen = 2044; + } + else + { + bufflen = 6132; + } + + send_buf = rt_malloc(bufflen); + if(send_buf != RT_NULL) + { + data = send_buf; + for(count = 0;count < bufflen; count++) + { + *data++ = (count % 93 + 33); + } + } + else + { + rt_kprintf("speed of send buffer malloc failed."); + return; + } + + tick1 = rt_tick_get(); + while (speed_test_type) + { + ret = rt_link_send(RT_LINK_SERVICE_RTLINK, send_buf, bufflen); + if(ret > 0) + { + sentlen += ret; + } + + tick2 = rt_tick_get(); + if (tick2 - tick1 >= RT_TICK_PER_SECOND)//* 10 + { + total = sentlen * RT_TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = total/1000; + decimal = total%1000; + LOG_I("%d.%03d0 Mbps!", integer, decimal); + sentlen = 0; + tick1 = tick2; + } + } + rt_free(send_buf); + LOG_W("speed test end, type %d",speed_test_type); +} + + +int rt_link_example_send(int argc, char **argv) +{ + char *receive = RT_NULL; + rt_size_t length = 0; + rt_uint16_t count = 0; + + if(argc == 1) + { + receive = rt_malloc(sizeof(TEST_CONTEXT)); + rt_memcpy(receive, TEST_CONTEXT, sizeof(TEST_CONTEXT) - 1); + length = rt_link_send(RT_LINK_SERVICE_RTLINK, receive, sizeof(TEST_CONTEXT) - 1); + LOG_I("send data length: %d.", length); + rt_free(receive); + } + else if(argc >= 3) + { + if(strcmp(argv[1], "-l") == 0) + { + receive = rt_malloc(atoi((const char *)argv[2])); + for(count = 0;count < atoi((const char *)argv[2]); count++) + { + *receive++ = (count % 93 + 33); + } + length = rt_link_send(RT_LINK_SERVICE_RTLINK, receive - atoi((const char *)argv[2]), atoi((const char *)argv[2])); + rt_free(receive - atoi((const char *)argv[2])); + + LOG_I("send data length: %d.", length); + } + else if(strcmp(argv[1], "-s") == 0) + { + if(speed_test_type == NONE_TEST) + { + rt_uint8_t mutil_num = 1; + if(argc > 3) + { + mutil_num = atoi((const char *)argv[3]); + } + + if(strncmp(argv[2], "-s", rt_strlen(argv[2])) == 0) + { + speed_test_type = SHORT_FRAME_TEST; + } + else if(strncmp(argv[2], "-l", rt_strlen(argv[2])) == 0) + { + speed_test_type = LONG_FRAME_TEST; + } + create_thead_to_test_speed(mutil_num); + } + else + { + speed_test_type = NONE_TEST; + LOG_I("set NONE_TEST"); + } + } + else + { + LOG_E("Invalid parameter."); + } + } + + return 0; +} +MSH_CMD_EXPORT(rt_link_example_send, rt link layer send test); + +int rt_link_example_init(void) +{ + + rt_link_service_attach(RT_LINK_SERVICE_RTLINK, rt_link_receive_example_callback); + return RT_EOK; +} +MSH_CMD_EXPORT(rt_link_example_init, rt link layer example init); -- cgit v1.3.1 From ce0c36422c87318ba2750b78f997722e6a17f17a Mon Sep 17 00:00:00 2001 From: Sherman Date: Sat, 15 May 2021 17:21:05 +0800 Subject: [fix] 修改格式错误 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/rt-link/rtlink_example.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/rt-link/rtlink_example.c b/examples/rt-link/rtlink_example.c index 7c70c25e6f..841e56b17e 100644 --- a/examples/rt-link/rtlink_example.c +++ b/examples/rt-link/rtlink_example.c @@ -35,7 +35,7 @@ rt_err_t rt_link_receive_example_callback(void *data, rt_size_t length) { LOG_I("recv data %d",length); LOG_HEX("example",8,data,length); - rt_free(data); + rt_free(data); return RT_EOK; } @@ -115,7 +115,6 @@ void rt_link_speed_test(void *paremeter) LOG_W("speed test end, type %d",speed_test_type); } - int rt_link_example_send(int argc, char **argv) { char *receive = RT_NULL; @@ -175,7 +174,6 @@ int rt_link_example_send(int argc, char **argv) LOG_E("Invalid parameter."); } } - return 0; } MSH_CMD_EXPORT(rt_link_example_send, rt link layer send test); -- cgit v1.3.1 From a5f7635f31b237ad8ce09610ee76a75f4072e7d4 Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Sat, 22 May 2021 02:50:35 +0800 Subject: remove libc_errno.h & libc_limits.h --- components/dfs/include/dfs_fs.h | 2 +- .../libc/compilers/common/none-gcc/sys/errno.h | 199 ++++++++++++++++++++ components/libc/compilers/common/time.c | 1 + components/libc/getline/posix_getline.c | 6 +- components/libc/pthreads/posix_types.h | 2 +- components/libc/termios/posix_termios.c | 2 +- .../net/lwip-1.4.1/src/arch/include/arch/cc.h | 2 +- .../net/lwip-2.0.2/src/arch/include/arch/cc.h | 2 +- components/net/lwip-2.0.2/src/lwipopts.h | 2 + .../net/lwip-2.1.2/src/arch/include/arch/cc.h | 2 +- components/net/lwip-2.1.2/src/include/lwip/errno.h | 2 +- components/net/lwip-2.1.2/src/lwipopts.h | 1 + components/net/sal_socket/socket/net_sockets.c | 2 +- examples/libc/ex3.c | 2 +- examples/libc/ex6.c | 2 +- examples/libc/ex7.c | 2 +- examples/libc/file.c | 2 +- examples/libc/memory.c | 2 +- include/libc/libc_errno.h | 206 --------------------- include/libc/libc_limits.h | 25 --- include/rtlibc.h | 2 - 21 files changed, 219 insertions(+), 249 deletions(-) create mode 100644 components/libc/compilers/common/none-gcc/sys/errno.h delete mode 100644 include/libc/libc_errno.h delete mode 100644 include/libc/libc_limits.h (limited to 'examples') diff --git a/components/dfs/include/dfs_fs.h b/components/dfs/include/dfs_fs.h index 828f15a0f5..3d194515df 100644 --- a/components/dfs/include/dfs_fs.h +++ b/components/dfs/include/dfs_fs.h @@ -15,7 +15,7 @@ #ifdef RT_USING_LIBC #include #endif - +#include #ifdef __cplusplus extern "C" { #endif diff --git a/components/libc/compilers/common/none-gcc/sys/errno.h b/components/libc/compilers/common/none-gcc/sys/errno.h new file mode 100644 index 0000000000..bdc3a3c9da --- /dev/null +++ b/components/libc/compilers/common/none-gcc/sys/errno.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-22 Meco Man The first version. + */ +#ifndef _SYS_ERRNO_H +#define _SYS_ERRNO_H + +#if defined(__CC_ARM) +/* +defined in armcc/errno.h + +#define EDOM 1 +#define ERANGE 2 +#define EILSEQ 4 +#define ESIGNUM 3 +#define EINVAL 5 +#define ENOMEM 6 +*/ + +#define ERROR_BASE_NO 7 + +#elif defined(__IAR_SYSTEMS_ICC__) +/* defined in iar/errno.h +#define EDOM 33 +#define ERANGE 34 +#define EFPOS 35 +#define EILSEQ 36 +*/ +#define ERROR_BASE_NO 36 + +#else +#define ERROR_BASE_NO 0 +#endif + +#if !defined(_WIN32) + +#include + +#define EPERM (ERROR_BASE_NO + 1) +#define ENOENT (ERROR_BASE_NO + 2) +#define ESRCH (ERROR_BASE_NO + 3) +#define EINTR (ERROR_BASE_NO + 4) +#define EIO (ERROR_BASE_NO + 5) +#define ENXIO (ERROR_BASE_NO + 6) +#define E2BIG (ERROR_BASE_NO + 7) +#define ENOEXEC (ERROR_BASE_NO + 8) +#define EBADF (ERROR_BASE_NO + 9) +#define ECHILD (ERROR_BASE_NO + 10) +#define EAGAIN (ERROR_BASE_NO + 11) + +#ifndef ENOMEM +#define ENOMEM (ERROR_BASE_NO + 12) +#endif + +#define EACCES (ERROR_BASE_NO + 13) +#define EFAULT (ERROR_BASE_NO + 14) +#define ENOTBLK (ERROR_BASE_NO + 15) +#define EBUSY (ERROR_BASE_NO + 16) +#define EEXIST (ERROR_BASE_NO + 17) +#define EXDEV (ERROR_BASE_NO + 18) +#define ENODEV (ERROR_BASE_NO + 19) +#define ENOTDIR (ERROR_BASE_NO + 20) +#define EISDIR (ERROR_BASE_NO + 21) + +#ifndef EINVAL +#define EINVAL (ERROR_BASE_NO + 22) +#endif + +#define ENFILE (ERROR_BASE_NO + 23) +#define EMFILE (ERROR_BASE_NO + 24) +#define ENOTTY (ERROR_BASE_NO + 25) +#define ETXTBSY (ERROR_BASE_NO + 26) +#define EFBIG (ERROR_BASE_NO + 27) +#define ENOSPC (ERROR_BASE_NO + 28) +#define ESPIPE (ERROR_BASE_NO + 29) +#define EROFS (ERROR_BASE_NO + 30) +#define EMLINK (ERROR_BASE_NO + 31) +#define EPIPE (ERROR_BASE_NO + 32) + +#ifndef EDOM +#define EDOM (ERROR_BASE_NO + 33) +#endif + +#ifndef ERANGE +#define ERANGE (ERROR_BASE_NO + 34) +#endif + +#define EDEADLK (ERROR_BASE_NO + 35) +#define ENAMETOOLONG (ERROR_BASE_NO + 36) +#define ENOLCK (ERROR_BASE_NO + 37) +#define ENOSYS (ERROR_BASE_NO + 38) +#define ENOTEMPTY (ERROR_BASE_NO + 39) +#define ELOOP (ERROR_BASE_NO + 40) +#define EWOULDBLOCK EAGAIN +#define ENOMSG (ERROR_BASE_NO + 42) +#define EIDRM (ERROR_BASE_NO + 43) +#define ECHRNG (ERROR_BASE_NO + 44) +#define EL2NSYNC (ERROR_BASE_NO + 45) +#define EL3HLT (ERROR_BASE_NO + 46) +#define EL3RST (ERROR_BASE_NO + 47) +#define ELNRNG (ERROR_BASE_NO + 48) +#define EUNATCH (ERROR_BASE_NO + 49) +#define ENOCSI (ERROR_BASE_NO + 50) +#define EL2HLT (ERROR_BASE_NO + 51) +#define EBADE (ERROR_BASE_NO + 52) +#define EBADR (ERROR_BASE_NO + 53) +#define EXFULL (ERROR_BASE_NO + 54) +#define ENOANO (ERROR_BASE_NO + 55) +#define EBADRQC (ERROR_BASE_NO + 56) +#define EBADSLT (ERROR_BASE_NO + 57) +#define EDEADLOCK EDEADLK +#define EBFONT (ERROR_BASE_NO + 59) +#define ENOSTR (ERROR_BASE_NO + 60) +#define ENODATA (ERROR_BASE_NO + 61) +#define ETIME (ERROR_BASE_NO + 62) +#define ENOSR (ERROR_BASE_NO + 63) +#define ENONET (ERROR_BASE_NO + 64) +#define ENOPKG (ERROR_BASE_NO + 65) +#define EREMOTE (ERROR_BASE_NO + 66) +#define ENOLINK (ERROR_BASE_NO + 67) +#define EADV (ERROR_BASE_NO + 68) +#define ESRMNT (ERROR_BASE_NO + 69) +#define ECOMM (ERROR_BASE_NO + 70) +#define EPROTO (ERROR_BASE_NO + 71) +#define EMULTIHOP (ERROR_BASE_NO + 72) +#define EDOTDOT (ERROR_BASE_NO + 73) +#define EBADMSG (ERROR_BASE_NO + 74) +#define EOVERFLOW (ERROR_BASE_NO + 75) +#define ENOTUNIQ (ERROR_BASE_NO + 76) +#define EBADFD (ERROR_BASE_NO + 77) +#define EREMCHG (ERROR_BASE_NO + 78) +#define ELIBACC (ERROR_BASE_NO + 79) +#define ELIBBAD (ERROR_BASE_NO + 80) +#define ELIBSCN (ERROR_BASE_NO + 81) +#define ELIBMAX (ERROR_BASE_NO + 82) +#define ELIBEXEC (ERROR_BASE_NO + 83) + +#ifndef EILSEQ +#define EILSEQ (ERROR_BASE_NO + 84) +#endif + +#define ERESTART (ERROR_BASE_NO + 85) +#define ESTRPIPE (ERROR_BASE_NO + 86) +#define EUSERS (ERROR_BASE_NO + 87) +#define ENOTSOCK (ERROR_BASE_NO + 88) +#define EDESTADDRREQ (ERROR_BASE_NO + 89) +#define EMSGSIZE (ERROR_BASE_NO + 90) +#define EPROTOTYPE (ERROR_BASE_NO + 91) +#define ENOPROTOOPT (ERROR_BASE_NO + 92) +#define EPROTONOSUPPORT (ERROR_BASE_NO + 93) +#define ESOCKTNOSUPPORT (ERROR_BASE_NO + 94) +#define EOPNOTSUPP (ERROR_BASE_NO + 95) +#define ENOTSUP EOPNOTSUPP +#define EPFNOSUPPORT (ERROR_BASE_NO + 96) +#define EAFNOSUPPORT (ERROR_BASE_NO + 97) +#define EADDRINUSE (ERROR_BASE_NO + 98) +#define EADDRNOTAVAIL (ERROR_BASE_NO + 99) +#define ENETDOWN (ERROR_BASE_NO + 100) +#define ENETUNREACH (ERROR_BASE_NO + 101) +#define ENETRESET (ERROR_BASE_NO + 102) +#define ECONNABORTED (ERROR_BASE_NO + 103) +#define ECONNRESET (ERROR_BASE_NO + 104) +#define ENOBUFS (ERROR_BASE_NO + 105) +#define EISCONN (ERROR_BASE_NO + 106) +#define ENOTCONN (ERROR_BASE_NO + 107) +#define ESHUTDOWN (ERROR_BASE_NO + 108) +#define ETOOMANYREFS (ERROR_BASE_NO + 109) +#define ETIMEDOUT (ERROR_BASE_NO + 110) +#define ECONNREFUSED (ERROR_BASE_NO + 111) +#define EHOSTDOWN (ERROR_BASE_NO + 112) +#define EHOSTUNREACH (ERROR_BASE_NO + 113) +#define EALREADY (ERROR_BASE_NO + 114) +#define EINPROGRESS (ERROR_BASE_NO + 115) +#define ESTALE (ERROR_BASE_NO + 116) +#define EUCLEAN (ERROR_BASE_NO + 117) +#define ENOTNAM (ERROR_BASE_NO + 118) +#define ENAVAIL (ERROR_BASE_NO + 119) +#define EISNAM (ERROR_BASE_NO + 120) +#define EREMOTEIO (ERROR_BASE_NO + 121) +#define EDQUOT (ERROR_BASE_NO + 122) +#define ENOMEDIUM (ERROR_BASE_NO + 123) +#define EMEDIUMTYPE (ERROR_BASE_NO + 124) +#define ECANCELED (ERROR_BASE_NO + 125) +#define ENOKEY (ERROR_BASE_NO + 126) +#define EKEYEXPIRED (ERROR_BASE_NO + 127) +#define EKEYREVOKED (ERROR_BASE_NO + 128) +#define EKEYREJECTED (ERROR_BASE_NO + 129) +#define EOWNERDEAD (ERROR_BASE_NO + 130) +#define ENOTRECOVERABLE (ERROR_BASE_NO + 131) +#define ERFKILL (ERROR_BASE_NO + 132) +#define EHWPOISON (ERROR_BASE_NO + 133) +#endif + +#endif diff --git a/components/libc/compilers/common/time.c b/components/libc/compilers/common/time.c index 9996212444..4cdfe77343 100644 --- a/components/libc/compilers/common/time.c +++ b/components/libc/compilers/common/time.c @@ -21,6 +21,7 @@ */ #include "sys/time.h" +#include #include #ifdef RT_USING_DEVICE diff --git a/components/libc/getline/posix_getline.c b/components/libc/getline/posix_getline.c index 794ac3a07d..da80242ecc 100644 --- a/components/libc/getline/posix_getline.c +++ b/components/libc/getline/posix_getline.c @@ -11,8 +11,8 @@ #include "posix_getline.h" #include -#include -#include +#include +#include ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream) { char *cur_pos, *new_lineptr; @@ -43,7 +43,7 @@ ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream) { break; if ((*lineptr + *n - cur_pos) < 2) { - if (SSIZE_MAX / 2 < *n) { + if (LONG_MAX / 2 < *n) { #ifdef EOVERFLOW errno = EOVERFLOW; #else diff --git a/components/libc/pthreads/posix_types.h b/components/libc/pthreads/posix_types.h index 942657ef39..5838e8b370 100644 --- a/components/libc/pthreads/posix_types.h +++ b/components/libc/pthreads/posix_types.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #endif diff --git a/components/libc/termios/posix_termios.c b/components/libc/termios/posix_termios.c index 01ba010c86..10a1f466d6 100644 --- a/components/libc/termios/posix_termios.c +++ b/components/libc/termios/posix_termios.c @@ -11,7 +11,7 @@ #include #include #include - +#include #include int tcgetattr(int fd, struct termios *tio) diff --git a/components/net/lwip-1.4.1/src/arch/include/arch/cc.h b/components/net/lwip-1.4.1/src/arch/include/arch/cc.h index 8dd59e8dee..880366d1f8 100644 --- a/components/net/lwip-1.4.1/src/arch/include/arch/cc.h +++ b/components/net/lwip-1.4.1/src/arch/include/arch/cc.h @@ -105,7 +105,7 @@ void sys_arch_assert(const char* file, int line); #define LWIP_PLATFORM_DIAG(x) do {rt_kprintf x;} while(0) #define LWIP_PLATFORM_ASSERT(x) do {rt_kprintf(x); sys_arch_assert(__FILE__, __LINE__);}while(0) -#include "string.h" +#include #define SYS_ARCH_DECL_PROTECT(level) #define SYS_ARCH_PROTECT(level) rt_enter_critical() diff --git a/components/net/lwip-2.0.2/src/arch/include/arch/cc.h b/components/net/lwip-2.0.2/src/arch/include/arch/cc.h index e3014f552c..a17b162805 100644 --- a/components/net/lwip-2.0.2/src/arch/include/arch/cc.h +++ b/components/net/lwip-2.0.2/src/arch/include/arch/cc.h @@ -84,7 +84,7 @@ void sys_arch_assert(const char* file, int line); #define LWIP_PLATFORM_DIAG(x) do {rt_kprintf x;} while(0) #define LWIP_PLATFORM_ASSERT(x) do {rt_kprintf(x); sys_arch_assert(__FILE__, __LINE__);}while(0) -#include "string.h" +#include #define SYS_ARCH_DECL_PROTECT(level) #define SYS_ARCH_PROTECT(level) rt_enter_critical() diff --git a/components/net/lwip-2.0.2/src/lwipopts.h b/components/net/lwip-2.0.2/src/lwipopts.h index 09bd223aa4..b334c5ac17 100644 --- a/components/net/lwip-2.0.2/src/lwipopts.h +++ b/components/net/lwip-2.0.2/src/lwipopts.h @@ -5,6 +5,8 @@ #define ERRNO 1 +#define LWIP_ERRNO_STDINCLUDE + #define LWIP_IPV4 1 #ifdef RT_USING_LWIP_IPV6 diff --git a/components/net/lwip-2.1.2/src/arch/include/arch/cc.h b/components/net/lwip-2.1.2/src/arch/include/arch/cc.h index 413fef65df..e85ca1d085 100644 --- a/components/net/lwip-2.1.2/src/arch/include/arch/cc.h +++ b/components/net/lwip-2.1.2/src/arch/include/arch/cc.h @@ -46,7 +46,7 @@ #define X32_F "lx" #ifdef RT_USING_LIBC -#include +#include #ifndef ENSRNOTFOUND #define ENSRNOTFOUND 163 /* Domain name not found */ #endif diff --git a/components/net/lwip-2.1.2/src/include/lwip/errno.h b/components/net/lwip-2.1.2/src/include/lwip/errno.h index 48d6b539d8..9fd88fc91a 100644 --- a/components/net/lwip-2.1.2/src/include/lwip/errno.h +++ b/components/net/lwip-2.1.2/src/include/lwip/errno.h @@ -181,7 +181,7 @@ extern int errno; /* Define LWIP_ERRNO_STDINCLUDE if you want to include here */ #ifdef LWIP_ERRNO_STDINCLUDE -#include +#include #else /* LWIP_ERRNO_STDINCLUDE */ /* Define LWIP_ERRNO_INCLUDE to an equivalent of to include the error defines here */ #ifdef LWIP_ERRNO_INCLUDE diff --git a/components/net/lwip-2.1.2/src/lwipopts.h b/components/net/lwip-2.1.2/src/lwipopts.h index 220bb6fa41..8c2bfbdd76 100644 --- a/components/net/lwip-2.1.2/src/lwipopts.h +++ b/components/net/lwip-2.1.2/src/lwipopts.h @@ -5,6 +5,7 @@ #define ERRNO 1 +#define LWIP_ERRNO_STDINCLUDE #define LWIP_SOCKET_SELECT 1 #define LWIP_SOCKET_POLL 1 diff --git a/components/net/sal_socket/socket/net_sockets.c b/components/net/sal_socket/socket/net_sockets.c index 3637635d50..7d4db34327 100644 --- a/components/net/sal_socket/socket/net_sockets.c +++ b/components/net/sal_socket/socket/net_sockets.c @@ -13,7 +13,7 @@ #include #include #include - +#include #include int accept(int s, struct sockaddr *addr, socklen_t *addrlen) diff --git a/examples/libc/ex3.c b/examples/libc/ex3.c index 1697e7145b..615ed8f35c 100644 --- a/examples/libc/ex3.c +++ b/examples/libc/ex3.c @@ -9,7 +9,7 @@ /* Multi-thread searching. Illustrates: thread cancellation, cleanup handlers. */ -#include +#include #include #include #include diff --git a/examples/libc/ex6.c b/examples/libc/ex6.c index ac6319d74c..ba687aa46f 100644 --- a/examples/libc/ex6.c +++ b/examples/libc/ex6.c @@ -6,7 +6,7 @@ * Change Logs: * Date Author Notes */ -#include +#include #include #include #include diff --git a/examples/libc/ex7.c b/examples/libc/ex7.c index e885f79c57..d1f05dbdcd 100644 --- a/examples/libc/ex7.c +++ b/examples/libc/ex7.c @@ -11,7 +11,7 @@ * Test case that illustrates a timed wait on a condition variable. */ -#include +#include #include #include #include diff --git a/examples/libc/file.c b/examples/libc/file.c index 79cdce3092..878d3a98d7 100644 --- a/examples/libc/file.c +++ b/examples/libc/file.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/libc/memory.c b/examples/libc/memory.c index 063d90cfdc..4a31b69017 100644 --- a/examples/libc/memory.c +++ b/examples/libc/memory.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include static int errors = 0; static void merror(const char *msg) diff --git a/include/libc/libc_errno.h b/include/libc/libc_errno.h deleted file mode 100644 index 30d6092e33..0000000000 --- a/include/libc/libc_errno.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016-11-12 Bernard The first version - */ - -#ifndef LIBC_ERRNO_H__ -#define LIBC_ERRNO_H__ - -#include - -#if defined(RT_USING_NEWLIB) || defined(_WIN32) || (defined( __GNUC__ ) && !defined(__ARMCC_VERSION)) -/* use errno.h file in toolchains */ -#include -#endif - -#if defined(__CC_ARM) -/* -defined in armcc/errno.h - -#define EDOM 1 -#define ERANGE 2 -#define EILSEQ 4 -#define ESIGNUM 3 -#define EINVAL 5 -#define ENOMEM 6 -*/ -#define ERROR_BASE_NO 7 - -#elif defined(__IAR_SYSTEMS_ICC__) -/* defined in iar/errno.h -#define EDOM 33 -#define ERANGE 34 -#define EFPOS 35 -#define EILSEQ 36 -*/ -#define ERROR_BASE_NO 36 - -#else - -#define ERROR_BASE_NO 0 -#endif - -#if !defined(RT_USING_NEWLIB) && !defined(_WIN32) && !(defined( __GNUC__ ) && !defined(__ARMCC_VERSION)) - -#define EPERM (ERROR_BASE_NO + 1) -#define ENOENT (ERROR_BASE_NO + 2) -#define ESRCH (ERROR_BASE_NO + 3) -#define EINTR (ERROR_BASE_NO + 4) -#define EIO (ERROR_BASE_NO + 5) -#define ENXIO (ERROR_BASE_NO + 6) -#define E2BIG (ERROR_BASE_NO + 7) -#define ENOEXEC (ERROR_BASE_NO + 8) -#define EBADF (ERROR_BASE_NO + 9) -#define ECHILD (ERROR_BASE_NO + 10) -#define EAGAIN (ERROR_BASE_NO + 11) - -#ifndef ENOMEM -#define ENOMEM (ERROR_BASE_NO + 12) -#endif - -#define EACCES (ERROR_BASE_NO + 13) -#define EFAULT (ERROR_BASE_NO + 14) -#define ENOTBLK (ERROR_BASE_NO + 15) -#define EBUSY (ERROR_BASE_NO + 16) -#define EEXIST (ERROR_BASE_NO + 17) -#define EXDEV (ERROR_BASE_NO + 18) -#define ENODEV (ERROR_BASE_NO + 19) -#define ENOTDIR (ERROR_BASE_NO + 20) -#define EISDIR (ERROR_BASE_NO + 21) - -#ifndef EINVAL -#define EINVAL (ERROR_BASE_NO + 22) -#endif - -#define ENFILE (ERROR_BASE_NO + 23) -#define EMFILE (ERROR_BASE_NO + 24) -#define ENOTTY (ERROR_BASE_NO + 25) -#define ETXTBSY (ERROR_BASE_NO + 26) -#define EFBIG (ERROR_BASE_NO + 27) -#define ENOSPC (ERROR_BASE_NO + 28) -#define ESPIPE (ERROR_BASE_NO + 29) -#define EROFS (ERROR_BASE_NO + 30) -#define EMLINK (ERROR_BASE_NO + 31) -#define EPIPE (ERROR_BASE_NO + 32) - -#ifndef EDOM -#define EDOM (ERROR_BASE_NO + 33) -#endif - -#ifndef ERANGE -#define ERANGE (ERROR_BASE_NO + 34) -#endif - -#define EDEADLK (ERROR_BASE_NO + 35) -#define ENAMETOOLONG (ERROR_BASE_NO + 36) -#define ENOLCK (ERROR_BASE_NO + 37) -#define ENOSYS (ERROR_BASE_NO + 38) -#define ENOTEMPTY (ERROR_BASE_NO + 39) -#define ELOOP (ERROR_BASE_NO + 40) -#define EWOULDBLOCK EAGAIN -#define ENOMSG (ERROR_BASE_NO + 42) -#define EIDRM (ERROR_BASE_NO + 43) -#define ECHRNG (ERROR_BASE_NO + 44) -#define EL2NSYNC (ERROR_BASE_NO + 45) -#define EL3HLT (ERROR_BASE_NO + 46) -#define EL3RST (ERROR_BASE_NO + 47) -#define ELNRNG (ERROR_BASE_NO + 48) -#define EUNATCH (ERROR_BASE_NO + 49) -#define ENOCSI (ERROR_BASE_NO + 50) -#define EL2HLT (ERROR_BASE_NO + 51) -#define EBADE (ERROR_BASE_NO + 52) -#define EBADR (ERROR_BASE_NO + 53) -#define EXFULL (ERROR_BASE_NO + 54) -#define ENOANO (ERROR_BASE_NO + 55) -#define EBADRQC (ERROR_BASE_NO + 56) -#define EBADSLT (ERROR_BASE_NO + 57) -#define EDEADLOCK EDEADLK -#define EBFONT (ERROR_BASE_NO + 59) -#define ENOSTR (ERROR_BASE_NO + 60) -#define ENODATA (ERROR_BASE_NO + 61) -#define ETIME (ERROR_BASE_NO + 62) -#define ENOSR (ERROR_BASE_NO + 63) -#define ENONET (ERROR_BASE_NO + 64) -#define ENOPKG (ERROR_BASE_NO + 65) -#define EREMOTE (ERROR_BASE_NO + 66) -#define ENOLINK (ERROR_BASE_NO + 67) -#define EADV (ERROR_BASE_NO + 68) -#define ESRMNT (ERROR_BASE_NO + 69) -#define ECOMM (ERROR_BASE_NO + 70) -#define EPROTO (ERROR_BASE_NO + 71) -#define EMULTIHOP (ERROR_BASE_NO + 72) -#define EDOTDOT (ERROR_BASE_NO + 73) -#define EBADMSG (ERROR_BASE_NO + 74) -#define EOVERFLOW (ERROR_BASE_NO + 75) -#define ENOTUNIQ (ERROR_BASE_NO + 76) -#define EBADFD (ERROR_BASE_NO + 77) -#define EREMCHG (ERROR_BASE_NO + 78) -#define ELIBACC (ERROR_BASE_NO + 79) -#define ELIBBAD (ERROR_BASE_NO + 80) -#define ELIBSCN (ERROR_BASE_NO + 81) -#define ELIBMAX (ERROR_BASE_NO + 82) -#define ELIBEXEC (ERROR_BASE_NO + 83) - -#ifndef EILSEQ -#define EILSEQ (ERROR_BASE_NO + 84) -#endif - -#define ERESTART (ERROR_BASE_NO + 85) -#define ESTRPIPE (ERROR_BASE_NO + 86) -#define EUSERS (ERROR_BASE_NO + 87) -#define ENOTSOCK (ERROR_BASE_NO + 88) -#define EDESTADDRREQ (ERROR_BASE_NO + 89) -#define EMSGSIZE (ERROR_BASE_NO + 90) -#define EPROTOTYPE (ERROR_BASE_NO + 91) -#define ENOPROTOOPT (ERROR_BASE_NO + 92) -#define EPROTONOSUPPORT (ERROR_BASE_NO + 93) -#define ESOCKTNOSUPPORT (ERROR_BASE_NO + 94) -#define EOPNOTSUPP (ERROR_BASE_NO + 95) -#define ENOTSUP EOPNOTSUPP -#define EPFNOSUPPORT (ERROR_BASE_NO + 96) -#define EAFNOSUPPORT (ERROR_BASE_NO + 97) -#define EADDRINUSE (ERROR_BASE_NO + 98) -#define EADDRNOTAVAIL (ERROR_BASE_NO + 99) -#define ENETDOWN (ERROR_BASE_NO + 100) -#define ENETUNREACH (ERROR_BASE_NO + 101) -#define ENETRESET (ERROR_BASE_NO + 102) -#define ECONNABORTED (ERROR_BASE_NO + 103) -#define ECONNRESET (ERROR_BASE_NO + 104) -#define ENOBUFS (ERROR_BASE_NO + 105) -#define EISCONN (ERROR_BASE_NO + 106) -#define ENOTCONN (ERROR_BASE_NO + 107) -#define ESHUTDOWN (ERROR_BASE_NO + 108) -#define ETOOMANYREFS (ERROR_BASE_NO + 109) -#define ETIMEDOUT (ERROR_BASE_NO + 110) -#define ECONNREFUSED (ERROR_BASE_NO + 111) -#define EHOSTDOWN (ERROR_BASE_NO + 112) -#define EHOSTUNREACH (ERROR_BASE_NO + 113) -#define EALREADY (ERROR_BASE_NO + 114) -#define EINPROGRESS (ERROR_BASE_NO + 115) -#define ESTALE (ERROR_BASE_NO + 116) -#define EUCLEAN (ERROR_BASE_NO + 117) -#define ENOTNAM (ERROR_BASE_NO + 118) -#define ENAVAIL (ERROR_BASE_NO + 119) -#define EISNAM (ERROR_BASE_NO + 120) -#define EREMOTEIO (ERROR_BASE_NO + 121) -#define EDQUOT (ERROR_BASE_NO + 122) -#define ENOMEDIUM (ERROR_BASE_NO + 123) -#define EMEDIUMTYPE (ERROR_BASE_NO + 124) -#define ECANCELED (ERROR_BASE_NO + 125) -#define ENOKEY (ERROR_BASE_NO + 126) -#define EKEYEXPIRED (ERROR_BASE_NO + 127) -#define EKEYREVOKED (ERROR_BASE_NO + 128) -#define EKEYREJECTED (ERROR_BASE_NO + 129) -#define EOWNERDEAD (ERROR_BASE_NO + 130) -#define ENOTRECOVERABLE (ERROR_BASE_NO + 131) -#define ERFKILL (ERROR_BASE_NO + 132) -#define EHWPOISON (ERROR_BASE_NO + 133) - -#endif - -#endif diff --git a/include/libc/libc_limits.h b/include/libc/libc_limits.h deleted file mode 100644 index 36b8dbb202..0000000000 --- a/include/libc/libc_limits.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-09-05 Meco Man the first version - */ - -#ifndef LIBC_LIMITS_H__ -#define LIBC_LIMITS_H__ - -#include -#include - -#ifdef RT_USING_POSIX - -#ifndef SSIZE_MAX -# define SSIZE_MAX LONG_MAX -#endif - -#endif - -#endif diff --git a/include/rtlibc.h b/include/rtlibc.h index 50bddc6ee8..a62051e157 100644 --- a/include/rtlibc.h +++ b/include/rtlibc.h @@ -13,14 +13,12 @@ /* definitions for libc if toolchain has no these definitions */ #include "libc/libc_stat.h" -#include "libc/libc_errno.h" #include "libc/libc_fcntl.h" #include "libc/libc_ioctl.h" #include "libc/libc_dirent.h" #include "libc/libc_signal.h" #include "libc/libc_fdset.h" -#include "libc/libc_limits.h" #include "libc/libc_stdio.h" #ifndef RT_USING_LIBC -- cgit v1.3.1 From 3350b0ba4e091f21537c89ecc727a05d56d112be Mon Sep 17 00:00:00 2001 From: zhouji <956133287@qq.com> Date: Mon, 24 May 2021 17:19:05 +0800 Subject: [update] 整理cortex-a kconfig菜单,并更新相关BSP的配置。 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/ft2004/.config | 3 +-- bsp/ft2004/Kconfig | 1 + bsp/ft2004/rtconfig.h | 1 + bsp/imx6ul/.config | 3 +-- bsp/imx6ul/Kconfig | 1 + bsp/imx6ul/rtconfig.h | 1 + bsp/qemu-vexpress-a9/.config | 3 +-- bsp/qemu-vexpress-a9/Kconfig | 1 + bsp/qemu-vexpress-a9/rtconfig.h | 1 + examples/utest/configs/utest_self/config.h | 1 + libcpu/Kconfig | 21 ++++++++++----------- 11 files changed, 20 insertions(+), 17 deletions(-) (limited to 'examples') diff --git a/bsp/ft2004/.config b/bsp/ft2004/.config index 1a27a6c8b4..1bd8c76ede 100644 --- a/bsp/ft2004/.config +++ b/bsp/ft2004/.config @@ -77,12 +77,11 @@ CONFIG_RT_CONSOLEBUF_SIZE=4096 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" CONFIG_RT_VER_NUM=0x40004 CONFIG_ARCH_ARM=y -# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_RT_USING_CPU_FFS=y CONFIG_ARCH_ARM_CORTEX_A=y # CONFIG_RT_SMP_AUTO_BOOT is not set # CONFIG_RT_USING_GIC_V2 is not set CONFIG_RT_USING_GIC_V3=y -# CONFIG_RT_NO_USING_GIC is not set # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set # diff --git a/bsp/ft2004/Kconfig b/bsp/ft2004/Kconfig index 1bee562e48..6470d41804 100644 --- a/bsp/ft2004/Kconfig +++ b/bsp/ft2004/Kconfig @@ -24,6 +24,7 @@ config FT2004 select ARCH_ARM_CORTEX_A select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN + select RT_USING_GIC_V3 default y diff --git a/bsp/ft2004/rtconfig.h b/bsp/ft2004/rtconfig.h index 20bba6a139..17f4dd20e8 100644 --- a/bsp/ft2004/rtconfig.h +++ b/bsp/ft2004/rtconfig.h @@ -50,6 +50,7 @@ #define RT_CONSOLE_DEVICE_NAME "uart1" #define RT_VER_NUM 0x40004 #define ARCH_ARM +#define RT_USING_CPU_FFS #define ARCH_ARM_CORTEX_A #define RT_USING_GIC_V3 diff --git a/bsp/imx6ul/.config b/bsp/imx6ul/.config index 4fa2072fb4..6d71016845 100644 --- a/bsp/imx6ul/.config +++ b/bsp/imx6ul/.config @@ -74,12 +74,11 @@ CONFIG_RT_CONSOLEBUF_SIZE=128 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" CONFIG_RT_VER_NUM=0x40004 CONFIG_ARCH_ARM=y -# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_RT_USING_CPU_FFS=y CONFIG_ARCH_ARM_CORTEX_A=y # CONFIG_RT_SMP_AUTO_BOOT is not set CONFIG_RT_USING_GIC_V2=y # CONFIG_RT_USING_GIC_V3 is not set -# CONFIG_RT_NO_USING_GIC is not set CONFIG_ARCH_ARM_CORTEX_A7=y # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set diff --git a/bsp/imx6ul/Kconfig b/bsp/imx6ul/Kconfig index 9fbc95e841..9cd9ab8dd5 100644 --- a/bsp/imx6ul/Kconfig +++ b/bsp/imx6ul/Kconfig @@ -18,6 +18,7 @@ config PKGS_DIR config BOARD_IMX6UL bool select ARCH_ARM_CORTEX_A7 + select RT_USING_GIC_V2 default y source "$RTT_DIR/Kconfig" diff --git a/bsp/imx6ul/rtconfig.h b/bsp/imx6ul/rtconfig.h index 4cc1b24df0..e48a4fe0aa 100644 --- a/bsp/imx6ul/rtconfig.h +++ b/bsp/imx6ul/rtconfig.h @@ -45,6 +45,7 @@ #define RT_CONSOLE_DEVICE_NAME "uart1" #define RT_VER_NUM 0x40004 #define ARCH_ARM +#define RT_USING_CPU_FFS #define ARCH_ARM_CORTEX_A #define RT_USING_GIC_V2 #define ARCH_ARM_CORTEX_A7 diff --git a/bsp/qemu-vexpress-a9/.config b/bsp/qemu-vexpress-a9/.config index f9fa185ce7..290cddd947 100644 --- a/bsp/qemu-vexpress-a9/.config +++ b/bsp/qemu-vexpress-a9/.config @@ -77,12 +77,11 @@ CONFIG_RT_CONSOLEBUF_SIZE=256 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" CONFIG_RT_VER_NUM=0x40004 CONFIG_ARCH_ARM=y -# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_RT_USING_CPU_FFS=y CONFIG_ARCH_ARM_CORTEX_A=y # CONFIG_RT_SMP_AUTO_BOOT is not set CONFIG_RT_USING_GIC_V2=y # CONFIG_RT_USING_GIC_V3 is not set -# CONFIG_RT_NO_USING_GIC is not set CONFIG_ARCH_ARM_CORTEX_A9=y # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set diff --git a/bsp/qemu-vexpress-a9/Kconfig b/bsp/qemu-vexpress-a9/Kconfig index 25921e6e7c..b2bdfe704d 100644 --- a/bsp/qemu-vexpress-a9/Kconfig +++ b/bsp/qemu-vexpress-a9/Kconfig @@ -23,6 +23,7 @@ config SOC_VEXPRESS_A9 select ARCH_ARM_CORTEX_A9 select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN + select RT_USING_GIC_V2 default y source "$BSP_DIR/drivers/Kconfig" diff --git a/bsp/qemu-vexpress-a9/rtconfig.h b/bsp/qemu-vexpress-a9/rtconfig.h index eb7b915d86..047e6f929c 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.h +++ b/bsp/qemu-vexpress-a9/rtconfig.h @@ -54,6 +54,7 @@ #define RT_CONSOLE_DEVICE_NAME "uart0" #define RT_VER_NUM 0x40004 #define ARCH_ARM +#define RT_USING_CPU_FFS #define ARCH_ARM_CORTEX_A #define RT_USING_GIC_V2 #define ARCH_ARM_CORTEX_A9 diff --git a/examples/utest/configs/utest_self/config.h b/examples/utest/configs/utest_self/config.h index 2080a544b0..fa94023c42 100644 --- a/examples/utest/configs/utest_self/config.h +++ b/examples/utest/configs/utest_self/config.h @@ -54,6 +54,7 @@ #define RT_CONSOLE_DEVICE_NAME "uart0" #define RT_VER_NUM 0x40004 #define ARCH_ARM +#define RT_USING_CPU_FFS #define ARCH_ARM_CORTEX_A #define RT_USING_GIC_V2 #define ARCH_ARM_CORTEX_A9 diff --git a/libcpu/Kconfig b/libcpu/Kconfig index bb54b487c7..d0fa40d1bd 100644 --- a/libcpu/Kconfig +++ b/libcpu/Kconfig @@ -57,25 +57,24 @@ config ARCH_ARM_ARM11 config ARCH_ARM_CORTEX_A bool select ARCH_ARM + select RT_USING_CPU_FFS if ARCH_ARM_CORTEX_A config RT_SMP_AUTO_BOOT bool default n - choice - prompt "GIC controller selection" - default RT_USING_GIC_V2 - - config RT_USING_GIC_V2 - bool " Gic version 2 " + config RT_USING_GIC_V2 + bool + default n - config RT_USING_GIC_V3 - bool " Gic version 3 " + config RT_USING_GIC_V3 + bool + default n - config RT_NO_USING_GIC - bool " GIC controller is not used " - endchoice + config RT_NO_USING_GIC + bool + default y if !RT_USING_GIC_V2 && !RT_USING_GIC_V3 endif config ARCH_ARM_CORTEX_A5 -- cgit v1.3.1 From 2c119a5c481d16c416358f62bd5fde8210a96c46 Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Thu, 3 Jun 2021 14:57:26 +0800 Subject: add memheap testcase for ac6 Oz optimization. --- examples/utest/testcases/Kconfig | 1 + examples/utest/testcases/kernel/Kconfig | 8 +++ examples/utest/testcases/kernel/SConscript | 15 ++++ examples/utest/testcases/kernel/memheap_tc.c | 100 +++++++++++++++++++++++++++ examples/utest/testcases/utest/pass_tc.c | 2 +- 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 examples/utest/testcases/kernel/Kconfig create mode 100644 examples/utest/testcases/kernel/SConscript create mode 100644 examples/utest/testcases/kernel/memheap_tc.c (limited to 'examples') diff --git a/examples/utest/testcases/Kconfig b/examples/utest/testcases/Kconfig index da80eb30ae..a9b556f1e3 100644 --- a/examples/utest/testcases/Kconfig +++ b/examples/utest/testcases/Kconfig @@ -8,6 +8,7 @@ config RT_USING_UTESTCASES if RT_USING_UTESTCASES source "$RTT_DIR/examples/utest/testcases/utest/Kconfig" +source "$RTT_DIR/examples/utest/testcases/kernel/Kconfig" endif diff --git a/examples/utest/testcases/kernel/Kconfig b/examples/utest/testcases/kernel/Kconfig new file mode 100644 index 0000000000..14334af16f --- /dev/null +++ b/examples/utest/testcases/kernel/Kconfig @@ -0,0 +1,8 @@ +menu "Kernel Testcase" + +config UTEST_MEMHEAP_TC + bool "memheap stability test" + default y + depends on RT_USING_MEMHEAP + +endmenu diff --git a/examples/utest/testcases/kernel/SConscript b/examples/utest/testcases/kernel/SConscript new file mode 100644 index 0000000000..9411cdd9a0 --- /dev/null +++ b/examples/utest/testcases/kernel/SConscript @@ -0,0 +1,15 @@ +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Split(''' +''') + +if GetDepend(['UTEST_MEMHEAP_TC']): + src += ['memheap_tc.c'] + +CPPPATH = [cwd] + +group = DefineGroup('utestcases', src, depend = [], CPPPATH = CPPPATH) + +Return('group') diff --git a/examples/utest/testcases/kernel/memheap_tc.c b/examples/utest/testcases/kernel/memheap_tc.c new file mode 100644 index 0000000000..ee52bdb185 --- /dev/null +++ b/examples/utest/testcases/kernel/memheap_tc.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-01-16 flybreak the first version + */ + +#include +#include +#include "utest.h" + +#define HEAP_SIZE (64 * 1024) +#define HEAP_ALIGN (4) +#define SLICE_NUM (40) +#define TEST_TIMES (100000) +#define HEAP_NAME "heap1" +#define SLICE_SIZE_MAX (HEAP_SIZE/SLICE_NUM) + +static void memheap_test(void) +{ + struct rt_memheap heap1; + rt_uint32_t ptr_start; + void *ptr[SLICE_NUM]; + int i, cnt = 0; + + /* init heap */ + ptr_start = (rt_uint32_t)rt_malloc_align(HEAP_SIZE, HEAP_ALIGN); + if (ptr_start == RT_NULL) + { + rt_kprintf("totle size too big,can not malloc memory!"); + return; + } + + rt_memheap_init(&heap1, HEAP_NAME, (void *)ptr_start, HEAP_SIZE); + + /* test start */ + for (i = 0; i < SLICE_NUM; i++) + { + ptr[i] = 0; + } + /* test alloc */ + for (i = 0; i < SLICE_NUM; i++) + { + rt_uint32_t slice_size = rand() % SLICE_SIZE_MAX; + ptr[i] = rt_memheap_alloc(&heap1, slice_size); + } + /* test realloc */ + while (cnt < TEST_TIMES) + { + rt_uint32_t slice_size = rand() % SLICE_SIZE_MAX; + rt_uint32_t ptr_index = rand() % SLICE_NUM; + rt_uint32_t operation = rand() % 2; + + if (ptr[ptr_index]) + { + if (operation == 0) /* free and malloc */ + { + if (ptr[ptr_index]) + { + rt_memheap_free(ptr[ptr_index]); + } + ptr[ptr_index] = rt_memheap_alloc(&heap1, slice_size); + } + else /* realloc */ + { + ptr[ptr_index] = rt_memheap_realloc(&heap1, ptr[ptr_index], slice_size); + } + } + cnt ++; + if (cnt % (TEST_TIMES / 10) == 0) + { + rt_kprintf(">"); + } + } + + rt_kprintf("test OK!\n"); + + /* test end */ + rt_memheap_detach(&heap1); + rt_free_align((void *)ptr_start); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(memheap_test); +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.memheap_tc", utest_tc_init, utest_tc_cleanup, 10); diff --git a/examples/utest/testcases/utest/pass_tc.c b/examples/utest/testcases/utest/pass_tc.c index 8e93e35b9b..c9ee912fbf 100644 --- a/examples/utest/testcases/utest/pass_tc.c +++ b/examples/utest/testcases/utest/pass_tc.c @@ -43,4 +43,4 @@ static void testcase(void) { UTEST_UNIT_RUN(test_assert_pass); } -UTEST_TC_EXPORT(testcase, "testcases.utest.pass_tc", utest_tc_init, utest_tc_cleanup, 10); \ No newline at end of file +UTEST_TC_EXPORT(testcase, "testcases.utest.pass_tc", utest_tc_init, utest_tc_cleanup, 10); -- cgit v1.3.1 From 4d213254c334e8c54f1b45edab47b77d22ca28b8 Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Thu, 3 Jun 2021 15:06:33 +0800 Subject: [ci] add kernel/mem testcase. --- .github/workflows/action_utest.yml | 2 +- examples/utest/configs/kernel/config.h | 304 +++++++++++++++++++++++++++++++++ 2 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 examples/utest/configs/kernel/config.h (limited to 'examples') diff --git a/.github/workflows/action_utest.yml b/.github/workflows/action_utest.yml index b8fea056e1..bfa9778554 100644 --- a/.github/workflows/action_utest.yml +++ b/.github/workflows/action_utest.yml @@ -11,7 +11,7 @@ jobs: fail-fast: false matrix: legs: - - {UTEST: "kernel/ipc", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"} + - {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/kernel/config.h"} - {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"} env: diff --git a/examples/utest/configs/kernel/config.h b/examples/utest/configs/kernel/config.h new file mode 100644 index 0000000000..c7fcb763fb --- /dev/null +++ b/examples/utest/configs/kernel/config.h @@ -0,0 +1,304 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_USING_SMP +#define RT_CPUS_NR 2 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 1024 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 1024 + +/* kservice optimization */ + +#define RT_DEBUG +#define RT_DEBUG_COLOR + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE +#define RT_USING_SIGNALS + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_MEMHEAP +#define RT_USING_SMALL_MEM +#define RT_USING_MEMTRACE +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_DEVICE_OPS +#define RT_USING_INTERRUPT_INFO +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart0" +#define RT_VER_NUM 0x40004 +#define ARCH_ARM +#define RT_USING_CPU_FFS +#define ARCH_ARM_CORTEX_A +#define RT_USING_GIC_V2 +#define ARCH_ARM_CORTEX_A9 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + +#define RT_USING_CPLUSPLUS + +/* Command shell */ + +#define RT_USING_FINSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 8 +#define DFS_FD_MAX 32 +#define RT_USING_DFS_ELMFAT + +/* elm-chan's FatFs, Generic FAT Filesystem Module */ + +#define RT_DFS_ELM_CODE_PAGE 437 +#define RT_DFS_ELM_WORD_ACCESS +#define RT_DFS_ELM_USE_LFN_3 +#define RT_DFS_ELM_USE_LFN 3 +#define RT_DFS_ELM_LFN_UNICODE_0 +#define RT_DFS_ELM_LFN_UNICODE 0 +#define RT_DFS_ELM_MAX_LFN 255 +#define RT_DFS_ELM_DRIVES 2 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 +#define RT_DFS_ELM_REENTRANT +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_ROMFS +#define RT_USING_DFS_RAMFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS +#define RT_USING_PIN +#define RT_USING_MTD_NOR +#define RT_USING_MTD_NAND +#define RT_MTD_NAND_DEBUG +#define RT_USING_RTC +#define RT_USING_SOFT_RTC +#define RT_USING_SDIO +#define RT_SDIO_STACK_SIZE 512 +#define RT_SDIO_THREAD_PRIORITY 15 +#define RT_MMCSD_STACK_SIZE 1024 +#define RT_MMCSD_THREAD_PREORITY 22 +#define RT_MMCSD_MAX_PARTITION 16 +#define RT_USING_SPI +#define RT_USING_SPI_MSD +#define RT_USING_SFUD +#define RT_SFUD_USING_SFDP +#define RT_SFUD_USING_FLASH_INFO_TABLE +#define RT_SFUD_SPI_MAX_HZ 50000000 +#define RT_USING_WDT + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC +#define RT_USING_PTHREADS +#define PTHREAD_NUM_MAX 8 +#define RT_USING_POSIX +#define RT_USING_POSIX_MMAP +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_GETLINE +#define RT_USING_POSIX_AIO +#define RT_LIBC_FIXED_TIMEZONE 8 + +/* Network */ + +/* Socket abstraction layer */ + +#define RT_USING_SAL +#define SAL_INTERNET_CHECK + +/* protocol stack implement */ + +#define SAL_USING_LWIP +#define SAL_USING_POSIX + +/* Network interface device */ + +#define RT_USING_NETDEV +#define NETDEV_USING_IFCONFIG +#define NETDEV_USING_PING +#define NETDEV_USING_NETSTAT +#define NETDEV_USING_AUTO_DEFAULT +#define NETDEV_IPV4 1 +#define NETDEV_IPV6 0 + +/* light weight TCP/IP stack */ + +#define RT_USING_LWIP +#define RT_USING_LWIP202 +#define RT_LWIP_MEM_ALIGNMENT 4 +#define RT_LWIP_ICMP +#define RT_LWIP_DNS +#define RT_LWIP_DHCP +#define IP_SOF_BROADCAST 1 +#define IP_SOF_BROADCAST_RECV 1 + +/* Static IPv4 Address */ + +#define RT_LWIP_IPADDR "192.168.1.30" +#define RT_LWIP_GWADDR "192.168.1.1" +#define RT_LWIP_MSKADDR "255.255.255.0" +#define RT_LWIP_UDP +#define RT_LWIP_TCP +#define RT_LWIP_RAW +#define RT_MEMP_NUM_NETCONN 8 +#define RT_LWIP_PBUF_NUM 16 +#define RT_LWIP_RAW_PCB_NUM 4 +#define RT_LWIP_UDP_PCB_NUM 4 +#define RT_LWIP_TCP_PCB_NUM 4 +#define RT_LWIP_TCP_SEG_NUM 40 +#define RT_LWIP_TCP_SND_BUF 8196 +#define RT_LWIP_TCP_WND 8196 +#define RT_LWIP_TCPTHREAD_PRIORITY 10 +#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 +#define RT_LWIP_TCPTHREAD_STACKSIZE 1024 +#define RT_LWIP_ETHTHREAD_PRIORITY 12 +#define RT_LWIP_ETHTHREAD_STACKSIZE 1024 +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 +#define RT_LWIP_REASSEMBLY_FRAG +#define LWIP_NETIF_STATUS_CALLBACK 1 +#define LWIP_NETIF_LINK_CALLBACK 1 +#define SO_REUSE 1 +#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_SNDTIMEO 1 +#define LWIP_SO_RCVBUF 1 +#define LWIP_SO_LINGER 0 +#define LWIP_NETIF_LOOPBACK 0 +#define RT_LWIP_USING_PING + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 4096 +#define UTEST_THR_PRIORITY 20 +#define RT_USING_LWP + +/* RT-Thread Utestcases */ + +#define RT_USING_UTESTCASES + +/* Utest Self Testcase */ + +#define UTEST_SELF_PASS_TC + +/* Kernel memheap stability Testcase */ + +#define UTEST_MEMHEAP_TC + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + + +/* AI packages */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + +#define SOC_VEXPRESS_A9 +#define RT_USING_UART0 +#define RT_USING_UART1 +#define BSP_DRV_EMAC + +#endif -- cgit v1.3.1 From a3b1caf952717fc79a589a870a0caf50538bc76d Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Sat, 12 Jun 2021 16:08:22 +0800 Subject: [example] 解决潜在内存泄漏问题 重新解决冲突,源自:https://gitee.com/rtthread/rt-thread/pulls/48/files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/file/listdir.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/file/listdir.c b/examples/file/listdir.c index 98fbc5ea2c..06c746a642 100644 --- a/examples/file/listdir.c +++ b/examples/file/listdir.c @@ -13,7 +13,7 @@ void list_dir(const char* path) { - char * fullpath; + char * fullpath = RT_NULL; DIR *dir; dir = opendir(path); @@ -57,7 +57,10 @@ void list_dir(const char* path) rt_kprintf("open %s directory failed\n", path); } - rt_free(fullpath); + if (RT_NULL != fullpath) + { + rt_free(fullpath); + } } #ifdef RT_USING_FINSH @@ -80,6 +83,6 @@ static void cmd_list_dir(int argc, char *argv[]) } list_dir(filename); } -FINSH_FUNCTION_EXPORT_ALIAS(cmd_list_dir, __cmd_list_dir, list directory); +MSH_CMD_EXPORT_ALIAS(cmd_list_dir, list_dir, list directory); #endif /* FINSH_USING_MSH */ #endif /* RT_USING_FINSH */ -- cgit v1.3.1 From 89717a4546fc3c03d930b96640677e2e51621234 Mon Sep 17 00:00:00 2001 From: Henson Date: Thu, 17 Jun 2021 21:50:46 +0800 Subject: [ci] add riscv64 autotest. --- .github/workflows/action_utest.yml | 51 +++++-- examples/utest/configs/kernel/config_riscv64.h | 200 +++++++++++++++++++++++++ 2 files changed, 238 insertions(+), 13 deletions(-) create mode 100644 examples/utest/configs/kernel/config_riscv64.h (limited to 'examples') diff --git a/.github/workflows/action_utest.yml b/.github/workflows/action_utest.yml index 22e4505177..d8a6cae754 100644 --- a/.github/workflows/action_utest.yml +++ b/.github/workflows/action_utest.yml @@ -11,33 +11,58 @@ jobs: fail-fast: false matrix: legs: - - {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/kernel/config.h"} - - {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"} - + - {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/config.h", SD_FILE: "sd.bin"} + - {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "utest_self/config.h", SD_FILE: "sd.bin"} + - {UTEST: "kernel/mem/riscv64", RTT_BSP: "bsp/qemu-riscv-virt64", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", CONFIG_FILE: "kernel/config_riscv64.h", SD_FILE: "None"} env: + TEST_QEMU_ARCH: ${{ matrix.legs.QEMU_ARCH }} + TEST_QEMU_MACHINE: ${{ matrix.legs.QEMU_MACHINE }} TEST_BSP_ROOT: ${{ matrix.legs.RTT_BSP }} TEST_CONFIG_FILE: ${{ matrix.legs.CONFIG_FILE }} + TEST_SD_FILE: ${{ matrix.legs.SD_FILE }} steps: - uses: actions/checkout@v1 - - name: Prepare env + + - name: Install Tools + shell: bash + run: | + sudo apt-get update + sudo apt-get -yqq install scons qemu-system git + + - name: Install Arm ToolChains + if: ${{ matrix.legs.QEMU_ARCH == 'arm' && success() }} + shell: bash run: | - sudo apt-get update > /dev/null - sudo apt-get -yqq install scons qemu-system-arm git wget -q https://developer.arm.com/-/media/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 sudo tar xjf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -C /opt - - name: Build bsp - run: | - export RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-10-2020-q4-major/bin /opt/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc --version - cp $TEST_CONFIG_FILE $TEST_BSP_ROOT/rtconfig.h + echo "RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-10-2020-q4-major/bin" >> $GITHUB_ENV + + - name: Install RISC-V ToolChains + if: ${{ matrix.legs.QEMU_ARCH == 'riscv64' && success() }} + run: | + wget -q https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz + sudo tar zxvf riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz -C /opt + /opt/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-gcc --version + echo "RTT_EXEC_PATH=/opt/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin" >> $GITHUB_ENV + + - name: Build BSP + run: | + cp examples/utest/configs/$TEST_CONFIG_FILE $TEST_BSP_ROOT/rtconfig.h scons -j$(nproc) -C $TEST_BSP_ROOT - - name: Start test + + - name: Start Test + if: ${{ success() }} run: | git clone https://github.com/armink/UtestRunner.git pushd $TEST_BSP_ROOT dd if=/dev/zero of=sd.bin bs=1024 count=65536 popd pushd UtestRunner - python3 qemu_runner.py --elf ../$TEST_BSP_ROOT/rtthread.elf --sd ../$TEST_BSP_ROOT/sd.bin + if [ $TEST_SD_FILE != "None" ]; then + python3 qemu_runner.py --system $TEST_QEMU_ARCH --machine $TEST_QEMU_MACHINE --elf ../$TEST_BSP_ROOT/rtthread.elf --sd ../$TEST_BSP_ROOT/$TEST_SD_FILE + else + python3 qemu_runner.py --system $TEST_QEMU_ARCH --machine $TEST_QEMU_MACHINE --elf ../$TEST_BSP_ROOT/rtthread.elf + fi cat rtt_console.log - popd + popd \ No newline at end of file diff --git a/examples/utest/configs/kernel/config_riscv64.h b/examples/utest/configs/kernel/config_riscv64.h new file mode 100644 index 0000000000..c166beefec --- /dev/null +++ b/examples/utest/configs/kernel/config_riscv64.h @@ -0,0 +1,200 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 20 +#define RT_ALIGN_SIZE 8 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 16384 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 16384 + +/* kservice optimization */ + +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_MEMHEAP +#define RT_USING_SMALL_MEM +#define RT_USING_MEMTRACE +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart" +#define RT_VER_NUM 0x40004 +#define ARCH_CPU_64BIT +#define ARCH_RISCV +#define ARCH_RISCV64 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 16384 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + + +/* Command shell */ + +#define RT_USING_FINSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_USING_MSH_ONLY +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 2 +#define DFS_FILESYSTEM_TYPES_MAX 2 +#define DFS_FD_MAX 32 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_ROMFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SERIAL +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_PIN + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC +#define RT_USING_POSIX +#define RT_LIBC_FIXED_TIMEZONE 8 + +/* Network */ + +/* Socket abstraction layer */ + + +/* Network interface device */ + + +/* light weight TCP/IP stack */ + + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 4096 +#define UTEST_THR_PRIORITY 20 + +/* RT-Thread Utestcases */ + +#define RT_USING_UTESTCASES + +/* Utest Self Testcase */ + +#define UTEST_SELF_PASS_TC + +/* Kernel Testcase */ + +#define UTEST_MEMHEAP_TC + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + + +/* AI packages */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + +#define BOARD_virt +#define RT_USING_USERSPACE + +/* RISCV qemu virt64 configs */ + +#define BSP_USING_UART1 +#define BSP_UART1_TXD_PIN 20 +#define BSP_UART1_RXD_PIN 21 +#define __STACKSIZE__ 16384 + +#endif -- cgit v1.3.1 From cc5fa682cde2f3c5cbd264e18ebc13be52cc8418 Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Fri, 18 Jun 2021 19:25:29 +0800 Subject: [ci] Simplified configuration files. --- .github/workflows/action_utest.yml | 10 +- examples/utest/configs/kernel/config.h | 304 ------------------------- examples/utest/configs/kernel/config_riscv64.h | 200 ---------------- examples/utest/configs/kernel/mem.conf | 2 + examples/utest/configs/utest_self/config.h | 299 ------------------------ examples/utest/configs/utest_self/self.conf | 1 + 6 files changed, 9 insertions(+), 807 deletions(-) delete mode 100644 examples/utest/configs/kernel/config.h delete mode 100644 examples/utest/configs/kernel/config_riscv64.h create mode 100644 examples/utest/configs/kernel/mem.conf delete mode 100644 examples/utest/configs/utest_self/config.h create mode 100644 examples/utest/configs/utest_self/self.conf (limited to 'examples') diff --git a/.github/workflows/action_utest.yml b/.github/workflows/action_utest.yml index d8a6cae754..7d0e2c44d8 100644 --- a/.github/workflows/action_utest.yml +++ b/.github/workflows/action_utest.yml @@ -11,9 +11,9 @@ jobs: fail-fast: false matrix: legs: - - {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/config.h", SD_FILE: "sd.bin"} - - {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "utest_self/config.h", SD_FILE: "sd.bin"} - - {UTEST: "kernel/mem/riscv64", RTT_BSP: "bsp/qemu-riscv-virt64", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", CONFIG_FILE: "kernel/config_riscv64.h", SD_FILE: "None"} + - {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "sd.bin"} + - {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "utest_self/self.conf", SD_FILE: "sd.bin"} + - {UTEST: "kernel/mem/riscv64", RTT_BSP: "bsp/qemu-riscv-virt64", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "None"} env: TEST_QEMU_ARCH: ${{ matrix.legs.QEMU_ARCH }} TEST_QEMU_MACHINE: ${{ matrix.legs.QEMU_MACHINE }} @@ -48,7 +48,9 @@ jobs: - name: Build BSP run: | - cp examples/utest/configs/$TEST_CONFIG_FILE $TEST_BSP_ROOT/rtconfig.h + echo CONFIG_RT_USING_UTESTCASES=y >> $TEST_BSP_ROOT/.config + cat examples/utest/configs/$TEST_CONFIG_FILE >> $TEST_BSP_ROOT/.config + scons --pyconfig-silent -C $TEST_BSP_ROOT scons -j$(nproc) -C $TEST_BSP_ROOT - name: Start Test diff --git a/examples/utest/configs/kernel/config.h b/examples/utest/configs/kernel/config.h deleted file mode 100644 index c7fcb763fb..0000000000 --- a/examples/utest/configs/kernel/config.h +++ /dev/null @@ -1,304 +0,0 @@ -#ifndef RT_CONFIG_H__ -#define RT_CONFIG_H__ - -/* Automatically generated file; DO NOT EDIT. */ -/* RT-Thread Project Configuration */ - -/* RT-Thread Kernel */ - -#define RT_NAME_MAX 8 -#define RT_USING_SMP -#define RT_CPUS_NR 2 -#define RT_ALIGN_SIZE 4 -#define RT_THREAD_PRIORITY_32 -#define RT_THREAD_PRIORITY_MAX 32 -#define RT_TICK_PER_SECOND 100 -#define RT_USING_OVERFLOW_CHECK -#define RT_USING_HOOK -#define RT_USING_IDLE_HOOK -#define RT_IDLE_HOOK_LIST_SIZE 4 -#define IDLE_THREAD_STACK_SIZE 1024 -#define RT_USING_TIMER_SOFT -#define RT_TIMER_THREAD_PRIO 4 -#define RT_TIMER_THREAD_STACK_SIZE 1024 - -/* kservice optimization */ - -#define RT_DEBUG -#define RT_DEBUG_COLOR - -/* Inter-Thread communication */ - -#define RT_USING_SEMAPHORE -#define RT_USING_MUTEX -#define RT_USING_EVENT -#define RT_USING_MAILBOX -#define RT_USING_MESSAGEQUEUE -#define RT_USING_SIGNALS - -/* Memory Management */ - -#define RT_USING_MEMPOOL -#define RT_USING_MEMHEAP -#define RT_USING_SMALL_MEM -#define RT_USING_MEMTRACE -#define RT_USING_HEAP - -/* Kernel Device Object */ - -#define RT_USING_DEVICE -#define RT_USING_DEVICE_OPS -#define RT_USING_INTERRUPT_INFO -#define RT_USING_CONSOLE -#define RT_CONSOLEBUF_SIZE 256 -#define RT_CONSOLE_DEVICE_NAME "uart0" -#define RT_VER_NUM 0x40004 -#define ARCH_ARM -#define RT_USING_CPU_FFS -#define ARCH_ARM_CORTEX_A -#define RT_USING_GIC_V2 -#define ARCH_ARM_CORTEX_A9 - -/* RT-Thread Components */ - -#define RT_USING_COMPONENTS_INIT -#define RT_USING_USER_MAIN -#define RT_MAIN_THREAD_STACK_SIZE 2048 -#define RT_MAIN_THREAD_PRIORITY 10 - -/* C++ features */ - -#define RT_USING_CPLUSPLUS - -/* Command shell */ - -#define RT_USING_FINSH -#define FINSH_THREAD_NAME "tshell" -#define FINSH_USING_HISTORY -#define FINSH_HISTORY_LINES 5 -#define FINSH_USING_SYMTAB -#define FINSH_USING_DESCRIPTION -#define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 -#define FINSH_CMD_SIZE 80 -#define FINSH_USING_MSH -#define FINSH_USING_MSH_DEFAULT -#define FINSH_ARG_MAX 10 - -/* Device virtual file system */ - -#define RT_USING_DFS -#define DFS_USING_WORKDIR -#define DFS_FILESYSTEMS_MAX 4 -#define DFS_FILESYSTEM_TYPES_MAX 8 -#define DFS_FD_MAX 32 -#define RT_USING_DFS_ELMFAT - -/* elm-chan's FatFs, Generic FAT Filesystem Module */ - -#define RT_DFS_ELM_CODE_PAGE 437 -#define RT_DFS_ELM_WORD_ACCESS -#define RT_DFS_ELM_USE_LFN_3 -#define RT_DFS_ELM_USE_LFN 3 -#define RT_DFS_ELM_LFN_UNICODE_0 -#define RT_DFS_ELM_LFN_UNICODE 0 -#define RT_DFS_ELM_MAX_LFN 255 -#define RT_DFS_ELM_DRIVES 2 -#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 -#define RT_DFS_ELM_REENTRANT -#define RT_USING_DFS_DEVFS -#define RT_USING_DFS_ROMFS -#define RT_USING_DFS_RAMFS - -/* Device Drivers */ - -#define RT_USING_DEVICE_IPC -#define RT_PIPE_BUFSZ 512 -#define RT_USING_SYSTEM_WORKQUEUE -#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 -#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 -#define RT_USING_SERIAL -#define RT_SERIAL_USING_DMA -#define RT_SERIAL_RB_BUFSZ 64 -#define RT_USING_I2C -#define RT_USING_I2C_BITOPS -#define RT_USING_PIN -#define RT_USING_MTD_NOR -#define RT_USING_MTD_NAND -#define RT_MTD_NAND_DEBUG -#define RT_USING_RTC -#define RT_USING_SOFT_RTC -#define RT_USING_SDIO -#define RT_SDIO_STACK_SIZE 512 -#define RT_SDIO_THREAD_PRIORITY 15 -#define RT_MMCSD_STACK_SIZE 1024 -#define RT_MMCSD_THREAD_PREORITY 22 -#define RT_MMCSD_MAX_PARTITION 16 -#define RT_USING_SPI -#define RT_USING_SPI_MSD -#define RT_USING_SFUD -#define RT_SFUD_USING_SFDP -#define RT_SFUD_USING_FLASH_INFO_TABLE -#define RT_SFUD_SPI_MAX_HZ 50000000 -#define RT_USING_WDT - -/* Using USB */ - - -/* POSIX layer and C standard library */ - -#define RT_USING_LIBC -#define RT_USING_PTHREADS -#define PTHREAD_NUM_MAX 8 -#define RT_USING_POSIX -#define RT_USING_POSIX_MMAP -#define RT_USING_POSIX_TERMIOS -#define RT_USING_POSIX_GETLINE -#define RT_USING_POSIX_AIO -#define RT_LIBC_FIXED_TIMEZONE 8 - -/* Network */ - -/* Socket abstraction layer */ - -#define RT_USING_SAL -#define SAL_INTERNET_CHECK - -/* protocol stack implement */ - -#define SAL_USING_LWIP -#define SAL_USING_POSIX - -/* Network interface device */ - -#define RT_USING_NETDEV -#define NETDEV_USING_IFCONFIG -#define NETDEV_USING_PING -#define NETDEV_USING_NETSTAT -#define NETDEV_USING_AUTO_DEFAULT -#define NETDEV_IPV4 1 -#define NETDEV_IPV6 0 - -/* light weight TCP/IP stack */ - -#define RT_USING_LWIP -#define RT_USING_LWIP202 -#define RT_LWIP_MEM_ALIGNMENT 4 -#define RT_LWIP_ICMP -#define RT_LWIP_DNS -#define RT_LWIP_DHCP -#define IP_SOF_BROADCAST 1 -#define IP_SOF_BROADCAST_RECV 1 - -/* Static IPv4 Address */ - -#define RT_LWIP_IPADDR "192.168.1.30" -#define RT_LWIP_GWADDR "192.168.1.1" -#define RT_LWIP_MSKADDR "255.255.255.0" -#define RT_LWIP_UDP -#define RT_LWIP_TCP -#define RT_LWIP_RAW -#define RT_MEMP_NUM_NETCONN 8 -#define RT_LWIP_PBUF_NUM 16 -#define RT_LWIP_RAW_PCB_NUM 4 -#define RT_LWIP_UDP_PCB_NUM 4 -#define RT_LWIP_TCP_PCB_NUM 4 -#define RT_LWIP_TCP_SEG_NUM 40 -#define RT_LWIP_TCP_SND_BUF 8196 -#define RT_LWIP_TCP_WND 8196 -#define RT_LWIP_TCPTHREAD_PRIORITY 10 -#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 -#define RT_LWIP_TCPTHREAD_STACKSIZE 1024 -#define RT_LWIP_ETHTHREAD_PRIORITY 12 -#define RT_LWIP_ETHTHREAD_STACKSIZE 1024 -#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 -#define RT_LWIP_REASSEMBLY_FRAG -#define LWIP_NETIF_STATUS_CALLBACK 1 -#define LWIP_NETIF_LINK_CALLBACK 1 -#define SO_REUSE 1 -#define LWIP_SO_RCVTIMEO 1 -#define LWIP_SO_SNDTIMEO 1 -#define LWIP_SO_RCVBUF 1 -#define LWIP_SO_LINGER 0 -#define LWIP_NETIF_LOOPBACK 0 -#define RT_LWIP_USING_PING - -/* AT commands */ - - -/* VBUS(Virtual Software BUS) */ - - -/* Utilities */ - -#define RT_USING_UTEST -#define UTEST_THR_STACK_SIZE 4096 -#define UTEST_THR_PRIORITY 20 -#define RT_USING_LWP - -/* RT-Thread Utestcases */ - -#define RT_USING_UTESTCASES - -/* Utest Self Testcase */ - -#define UTEST_SELF_PASS_TC - -/* Kernel memheap stability Testcase */ - -#define UTEST_MEMHEAP_TC - -/* RT-Thread online packages */ - -/* IoT - internet of things */ - - -/* Wi-Fi */ - -/* Marvell WiFi */ - - -/* Wiced WiFi */ - - -/* IoT Cloud */ - - -/* security packages */ - - -/* language packages */ - - -/* multimedia packages */ - - -/* tools packages */ - - -/* system packages */ - - -/* Micrium: Micrium software products porting for RT-Thread */ - - -/* peripheral libraries and drivers */ - - -/* AI packages */ - - -/* miscellaneous packages */ - - -/* samples: kernel and components samples */ - - -/* entertainment: terminal games and other interesting software packages */ - -#define SOC_VEXPRESS_A9 -#define RT_USING_UART0 -#define RT_USING_UART1 -#define BSP_DRV_EMAC - -#endif diff --git a/examples/utest/configs/kernel/config_riscv64.h b/examples/utest/configs/kernel/config_riscv64.h deleted file mode 100644 index c166beefec..0000000000 --- a/examples/utest/configs/kernel/config_riscv64.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef RT_CONFIG_H__ -#define RT_CONFIG_H__ - -/* Automatically generated file; DO NOT EDIT. */ -/* RT-Thread Project Configuration */ - -/* RT-Thread Kernel */ - -#define RT_NAME_MAX 20 -#define RT_ALIGN_SIZE 8 -#define RT_THREAD_PRIORITY_32 -#define RT_THREAD_PRIORITY_MAX 32 -#define RT_TICK_PER_SECOND 100 -#define RT_USING_HOOK -#define RT_USING_IDLE_HOOK -#define RT_IDLE_HOOK_LIST_SIZE 4 -#define IDLE_THREAD_STACK_SIZE 16384 -#define RT_USING_TIMER_SOFT -#define RT_TIMER_THREAD_PRIO 4 -#define RT_TIMER_THREAD_STACK_SIZE 16384 - -/* kservice optimization */ - -#define RT_DEBUG - -/* Inter-Thread communication */ - -#define RT_USING_SEMAPHORE -#define RT_USING_MUTEX -#define RT_USING_EVENT -#define RT_USING_MAILBOX -#define RT_USING_MESSAGEQUEUE - -/* Memory Management */ - -#define RT_USING_MEMPOOL -#define RT_USING_MEMHEAP -#define RT_USING_SMALL_MEM -#define RT_USING_MEMTRACE -#define RT_USING_HEAP - -/* Kernel Device Object */ - -#define RT_USING_DEVICE -#define RT_USING_CONSOLE -#define RT_CONSOLEBUF_SIZE 256 -#define RT_CONSOLE_DEVICE_NAME "uart" -#define RT_VER_NUM 0x40004 -#define ARCH_CPU_64BIT -#define ARCH_RISCV -#define ARCH_RISCV64 - -/* RT-Thread Components */ - -#define RT_USING_COMPONENTS_INIT -#define RT_USING_USER_MAIN -#define RT_MAIN_THREAD_STACK_SIZE 16384 -#define RT_MAIN_THREAD_PRIORITY 10 - -/* C++ features */ - - -/* Command shell */ - -#define RT_USING_FINSH -#define FINSH_THREAD_NAME "tshell" -#define FINSH_USING_HISTORY -#define FINSH_HISTORY_LINES 5 -#define FINSH_USING_SYMTAB -#define FINSH_USING_DESCRIPTION -#define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 -#define FINSH_CMD_SIZE 80 -#define FINSH_USING_MSH -#define FINSH_USING_MSH_DEFAULT -#define FINSH_USING_MSH_ONLY -#define FINSH_ARG_MAX 10 - -/* Device virtual file system */ - -#define RT_USING_DFS -#define DFS_USING_WORKDIR -#define DFS_FILESYSTEMS_MAX 2 -#define DFS_FILESYSTEM_TYPES_MAX 2 -#define DFS_FD_MAX 32 -#define RT_USING_DFS_DEVFS -#define RT_USING_DFS_ROMFS - -/* Device Drivers */ - -#define RT_USING_DEVICE_IPC -#define RT_PIPE_BUFSZ 512 -#define RT_USING_SERIAL -#define RT_SERIAL_USING_DMA -#define RT_SERIAL_RB_BUFSZ 64 -#define RT_USING_PIN - -/* Using USB */ - - -/* POSIX layer and C standard library */ - -#define RT_USING_LIBC -#define RT_USING_POSIX -#define RT_LIBC_FIXED_TIMEZONE 8 - -/* Network */ - -/* Socket abstraction layer */ - - -/* Network interface device */ - - -/* light weight TCP/IP stack */ - - -/* AT commands */ - - -/* VBUS(Virtual Software BUS) */ - - -/* Utilities */ - -#define RT_USING_UTEST -#define UTEST_THR_STACK_SIZE 4096 -#define UTEST_THR_PRIORITY 20 - -/* RT-Thread Utestcases */ - -#define RT_USING_UTESTCASES - -/* Utest Self Testcase */ - -#define UTEST_SELF_PASS_TC - -/* Kernel Testcase */ - -#define UTEST_MEMHEAP_TC - -/* RT-Thread online packages */ - -/* IoT - internet of things */ - - -/* Wi-Fi */ - -/* Marvell WiFi */ - - -/* Wiced WiFi */ - - -/* IoT Cloud */ - - -/* security packages */ - - -/* language packages */ - - -/* multimedia packages */ - - -/* tools packages */ - - -/* system packages */ - - -/* Micrium: Micrium software products porting for RT-Thread */ - - -/* peripheral libraries and drivers */ - - -/* AI packages */ - - -/* miscellaneous packages */ - - -/* samples: kernel and components samples */ - - -/* entertainment: terminal games and other interesting software packages */ - -#define BOARD_virt -#define RT_USING_USERSPACE - -/* RISCV qemu virt64 configs */ - -#define BSP_USING_UART1 -#define BSP_UART1_TXD_PIN 20 -#define BSP_UART1_RXD_PIN 21 -#define __STACKSIZE__ 16384 - -#endif diff --git a/examples/utest/configs/kernel/mem.conf b/examples/utest/configs/kernel/mem.conf new file mode 100644 index 0000000000..80a0259a4c --- /dev/null +++ b/examples/utest/configs/kernel/mem.conf @@ -0,0 +1,2 @@ +CONFIG_RT_USING_MEMHEAP=y +CONFIG_UTEST_MEMHEAP_TC=y diff --git a/examples/utest/configs/utest_self/config.h b/examples/utest/configs/utest_self/config.h deleted file mode 100644 index fa94023c42..0000000000 --- a/examples/utest/configs/utest_self/config.h +++ /dev/null @@ -1,299 +0,0 @@ -#ifndef RT_CONFIG_H__ -#define RT_CONFIG_H__ - -/* Automatically generated file; DO NOT EDIT. */ -/* RT-Thread Project Configuration */ - -/* RT-Thread Kernel */ - -#define RT_NAME_MAX 8 -#define RT_USING_SMP -#define RT_CPUS_NR 2 -#define RT_ALIGN_SIZE 4 -#define RT_THREAD_PRIORITY_32 -#define RT_THREAD_PRIORITY_MAX 32 -#define RT_TICK_PER_SECOND 100 -#define RT_USING_OVERFLOW_CHECK -#define RT_USING_HOOK -#define RT_USING_IDLE_HOOK -#define RT_IDLE_HOOK_LIST_SIZE 4 -#define IDLE_THREAD_STACK_SIZE 1024 -#define RT_USING_TIMER_SOFT -#define RT_TIMER_THREAD_PRIO 4 -#define RT_TIMER_THREAD_STACK_SIZE 1024 - -/* kservice optimization */ - -#define RT_DEBUG -#define RT_DEBUG_COLOR - -/* Inter-Thread communication */ - -#define RT_USING_SEMAPHORE -#define RT_USING_MUTEX -#define RT_USING_EVENT -#define RT_USING_MAILBOX -#define RT_USING_MESSAGEQUEUE -#define RT_USING_SIGNALS - -/* Memory Management */ - -#define RT_USING_MEMPOOL -#define RT_USING_MEMHEAP -#define RT_USING_SMALL_MEM -#define RT_USING_MEMTRACE -#define RT_USING_HEAP - -/* Kernel Device Object */ - -#define RT_USING_DEVICE -#define RT_USING_DEVICE_OPS -#define RT_USING_INTERRUPT_INFO -#define RT_USING_CONSOLE -#define RT_CONSOLEBUF_SIZE 256 -#define RT_CONSOLE_DEVICE_NAME "uart0" -#define RT_VER_NUM 0x40004 -#define ARCH_ARM -#define RT_USING_CPU_FFS -#define ARCH_ARM_CORTEX_A -#define RT_USING_GIC_V2 -#define ARCH_ARM_CORTEX_A9 - -/* RT-Thread Components */ - -#define RT_USING_COMPONENTS_INIT -#define RT_USING_USER_MAIN -#define RT_MAIN_THREAD_STACK_SIZE 2048 -#define RT_MAIN_THREAD_PRIORITY 10 - -/* C++ features */ - -#define RT_USING_CPLUSPLUS - -/* Command shell */ - -#define RT_USING_FINSH -#define FINSH_THREAD_NAME "tshell" -#define FINSH_USING_HISTORY -#define FINSH_HISTORY_LINES 5 -#define FINSH_USING_SYMTAB -#define FINSH_USING_DESCRIPTION -#define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 -#define FINSH_CMD_SIZE 80 -#define FINSH_USING_MSH -#define FINSH_USING_MSH_DEFAULT -#define FINSH_ARG_MAX 10 - -/* Device virtual file system */ - -#define RT_USING_DFS -#define DFS_USING_WORKDIR -#define DFS_FILESYSTEMS_MAX 2 -#define DFS_FILESYSTEM_TYPES_MAX 8 -#define DFS_FD_MAX 16 -#define RT_USING_DFS_ELMFAT - -/* elm-chan's FatFs, Generic FAT Filesystem Module */ - -#define RT_DFS_ELM_CODE_PAGE 437 -#define RT_DFS_ELM_WORD_ACCESS -#define RT_DFS_ELM_USE_LFN_3 -#define RT_DFS_ELM_USE_LFN 3 -#define RT_DFS_ELM_LFN_UNICODE_0 -#define RT_DFS_ELM_LFN_UNICODE 0 -#define RT_DFS_ELM_MAX_LFN 255 -#define RT_DFS_ELM_DRIVES 2 -#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 -#define RT_DFS_ELM_REENTRANT -#define RT_USING_DFS_DEVFS -#define RT_USING_DFS_ROMFS -#define RT_USING_DFS_RAMFS - -/* Device Drivers */ - -#define RT_USING_DEVICE_IPC -#define RT_PIPE_BUFSZ 512 -#define RT_USING_SYSTEM_WORKQUEUE -#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 -#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 -#define RT_USING_SERIAL -#define RT_SERIAL_USING_DMA -#define RT_SERIAL_RB_BUFSZ 64 -#define RT_USING_I2C -#define RT_USING_I2C_BITOPS -#define RT_USING_PIN -#define RT_USING_MTD_NOR -#define RT_USING_MTD_NAND -#define RT_MTD_NAND_DEBUG -#define RT_USING_RTC -#define RT_USING_SOFT_RTC -#define RT_USING_SDIO -#define RT_SDIO_STACK_SIZE 512 -#define RT_SDIO_THREAD_PRIORITY 15 -#define RT_MMCSD_STACK_SIZE 1024 -#define RT_MMCSD_THREAD_PREORITY 22 -#define RT_MMCSD_MAX_PARTITION 16 -#define RT_USING_SPI -#define RT_USING_SPI_MSD -#define RT_USING_SFUD -#define RT_SFUD_USING_SFDP -#define RT_SFUD_USING_FLASH_INFO_TABLE -#define RT_SFUD_SPI_MAX_HZ 50000000 -#define RT_USING_WDT - -/* Using USB */ - - -/* POSIX layer and C standard library */ - -#define RT_USING_LIBC -#define RT_USING_PTHREADS -#define PTHREAD_NUM_MAX 8 -#define RT_USING_POSIX -#define RT_USING_POSIX_MMAP -#define RT_USING_POSIX_TERMIOS -#define RT_USING_POSIX_AIO -#define RT_LIBC_FIXED_TIMEZONE 8 - -/* Network */ - -/* Socket abstraction layer */ - -#define RT_USING_SAL -#define SAL_INTERNET_CHECK - -/* protocol stack implement */ - -#define SAL_USING_LWIP -#define SAL_USING_POSIX - -/* Network interface device */ - -#define RT_USING_NETDEV -#define NETDEV_USING_IFCONFIG -#define NETDEV_USING_PING -#define NETDEV_USING_NETSTAT -#define NETDEV_USING_AUTO_DEFAULT -#define NETDEV_IPV4 1 -#define NETDEV_IPV6 0 - -/* light weight TCP/IP stack */ - -#define RT_USING_LWIP -#define RT_USING_LWIP202 -#define RT_LWIP_MEM_ALIGNMENT 4 -#define RT_LWIP_ICMP -#define RT_LWIP_DNS -#define RT_LWIP_DHCP -#define IP_SOF_BROADCAST 1 -#define IP_SOF_BROADCAST_RECV 1 - -/* Static IPv4 Address */ - -#define RT_LWIP_IPADDR "192.168.1.30" -#define RT_LWIP_GWADDR "192.168.1.1" -#define RT_LWIP_MSKADDR "255.255.255.0" -#define RT_LWIP_UDP -#define RT_LWIP_TCP -#define RT_LWIP_RAW -#define RT_MEMP_NUM_NETCONN 8 -#define RT_LWIP_PBUF_NUM 16 -#define RT_LWIP_RAW_PCB_NUM 4 -#define RT_LWIP_UDP_PCB_NUM 4 -#define RT_LWIP_TCP_PCB_NUM 4 -#define RT_LWIP_TCP_SEG_NUM 40 -#define RT_LWIP_TCP_SND_BUF 8196 -#define RT_LWIP_TCP_WND 8196 -#define RT_LWIP_TCPTHREAD_PRIORITY 10 -#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 -#define RT_LWIP_TCPTHREAD_STACKSIZE 1024 -#define RT_LWIP_ETHTHREAD_PRIORITY 12 -#define RT_LWIP_ETHTHREAD_STACKSIZE 1024 -#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 -#define RT_LWIP_REASSEMBLY_FRAG -#define LWIP_NETIF_STATUS_CALLBACK 1 -#define LWIP_NETIF_LINK_CALLBACK 1 -#define SO_REUSE 1 -#define LWIP_SO_RCVTIMEO 1 -#define LWIP_SO_SNDTIMEO 1 -#define LWIP_SO_RCVBUF 1 -#define LWIP_SO_LINGER 0 -#define LWIP_NETIF_LOOPBACK 0 -#define RT_LWIP_USING_PING - -/* AT commands */ - - -/* VBUS(Virtual Software BUS) */ - - -/* Utilities */ - -#define RT_USING_UTEST -#define UTEST_THR_STACK_SIZE 4096 -#define UTEST_THR_PRIORITY 20 -#define RT_USING_LWP - -/* RT-Thread Utestcases */ - -#define RT_USING_UTESTCASES - -/* Utest Self Testcase */ - -#define UTEST_SELF_PASS_TC - -/* RT-Thread online packages */ - -/* IoT - internet of things */ - - -/* Wi-Fi */ - -/* Marvell WiFi */ - - -/* Wiced WiFi */ - - -/* IoT Cloud */ - - -/* security packages */ - - -/* language packages */ - - -/* multimedia packages */ - - -/* tools packages */ - - -/* system packages */ - - -/* Micrium: Micrium software products porting for RT-Thread */ - - -/* peripheral libraries and drivers */ - - -/* AI packages */ - - -/* miscellaneous packages */ - - -/* samples: kernel and components samples */ - - -/* entertainment: terminal games and other interesting software packages */ - -#define SOC_VEXPRESS_A9 -#define RT_USING_UART0 -#define RT_USING_UART1 -#define BSP_DRV_EMAC - -#endif diff --git a/examples/utest/configs/utest_self/self.conf b/examples/utest/configs/utest_self/self.conf new file mode 100644 index 0000000000..b155a551d2 --- /dev/null +++ b/examples/utest/configs/utest_self/self.conf @@ -0,0 +1 @@ +CONFIG_UTEST_SELF_PASS_TC=y -- cgit v1.3.1 From 312753686b7c64dfabf02d38ecca28c59ebc2810 Mon Sep 17 00:00:00 2001 From: chenjh Date: Thu, 17 Jun 2021 15:56:04 +0800 Subject: [testcase] 增加serial_v2的测试用例 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/utest/testcases/Kconfig | 1 + examples/utest/testcases/drivers/SConscript | 15 ++ examples/utest/testcases/drivers/serial_v2/Kconfig | 7 + .../utest/testcases/drivers/serial_v2/README.md | 120 +++++++++ .../utest/testcases/drivers/serial_v2/SConscript | 16 ++ .../testcases/drivers/serial_v2/uart_rxb_txb.c | 230 ++++++++++++++++ .../testcases/drivers/serial_v2/uart_rxb_txnb.c | 263 ++++++++++++++++++ .../testcases/drivers/serial_v2/uart_rxnb_txb.c | 266 +++++++++++++++++++ .../testcases/drivers/serial_v2/uart_rxnb_txnb.c | 294 +++++++++++++++++++++ 9 files changed, 1212 insertions(+) create mode 100644 examples/utest/testcases/drivers/SConscript create mode 100644 examples/utest/testcases/drivers/serial_v2/Kconfig create mode 100644 examples/utest/testcases/drivers/serial_v2/README.md create mode 100644 examples/utest/testcases/drivers/serial_v2/SConscript create mode 100644 examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c create mode 100644 examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c create mode 100644 examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c create mode 100644 examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c (limited to 'examples') diff --git a/examples/utest/testcases/Kconfig b/examples/utest/testcases/Kconfig index a9b556f1e3..5dc1c6c420 100644 --- a/examples/utest/testcases/Kconfig +++ b/examples/utest/testcases/Kconfig @@ -9,6 +9,7 @@ if RT_USING_UTESTCASES source "$RTT_DIR/examples/utest/testcases/utest/Kconfig" source "$RTT_DIR/examples/utest/testcases/kernel/Kconfig" +source "$RTT_DIR/examples/utest/testcases/drivers/serial_v2/Kconfig" endif diff --git a/examples/utest/testcases/drivers/SConscript b/examples/utest/testcases/drivers/SConscript new file mode 100644 index 0000000000..4c815c49b8 --- /dev/null +++ b/examples/utest/testcases/drivers/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/examples/utest/testcases/drivers/serial_v2/Kconfig b/examples/utest/testcases/drivers/serial_v2/Kconfig new file mode 100644 index 0000000000..3c8d480b3a --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/Kconfig @@ -0,0 +1,7 @@ +menu "Utest Serial Testcase" + +config UTEST_SERIAL_TC + bool "Serial testcase" + default n + +endmenu diff --git a/examples/utest/testcases/drivers/serial_v2/README.md b/examples/utest/testcases/drivers/serial_v2/README.md new file mode 100644 index 0000000000..38d71ce8e8 --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/README.md @@ -0,0 +1,120 @@ +## 1、介绍 + +该目录下 c 文件是新版本串口的测试用例,在 `examples/utest/testcases/drivers/serial_v2` 目录结构里,该测试用例用来测试串口的各个操作模式是否正常工作。 + +## 2、 文件说明 + +| 文件 | 描述 | +| ---------------- | ----------------------------------------- | +| uart_rxb_txb.c | 串口接收阻塞和发送阻塞模式 的测试用例 | +| uart_rxb_txnb.c | 串口接收阻塞和发送非阻塞模式 的测试用例 | +| uart_rxnb_txb.c | 串口接收非阻塞和发送阻塞模式 的测试用例 | +| uart_rxnb_txnb.c | 串口接收非阻塞和发送非阻塞模式 的测试用例 | + +## 3、软硬件环境 + +硬件上需要支持 RT-Thread 的完整版操作系统,版本为4.0.4及以上,且硬件有串口硬件外设,软件上需要支持 内核接口、IPC 、Device 框架。 + +## 4、测试项 + +### 4.1 测试说明 + +上文所提及的模式是指串口使用时的操作模式,不涉及硬件的工作模式的配置情况(硬件工作模式一般有轮询POLL、中断INT、DMA),因此使用时需要结合具体的硬件工作模式去配置使用。例如 发送阻塞和接收非阻塞模式 ,这个测试有很多种硬件配置,配置情况例如:DMA发送阻塞和DMA接收非阻塞,INT发送阻塞和DMA接收非阻塞,POLL发送阻塞和DMA接收非阻塞等等。因此通过排列组合后的测试场景有4*9=36种,有意义的组合方式为20种。如下表: + + +| 接收非阻塞 | 发送阻塞 | 组合 | 有意义的组合方式 | +| ---------- | -------- | ----------------- | ---------------- | +| POLL | POLL | RX_POLL + TX_POLL | | +| | INT | RX_POLL + TX_INT | | +| | DMA | RX_POLL + TX_DMA | | +| INT | POLL | RX_INT + TX_POLL | ✔ | +| | INT | RX_INT + TX_INT | ✔ | +| | DMA | RX_INT + TX_DMA | ✔ | +| DMA | POLL | RX_DMA + TX_POLL | ✔ | +| | INT | RX_DMA + TX_INT | ✔ | +| | DMA | RX_DMA + TX_DMA | ✔ | + +| 接收非阻塞 | 发送非阻塞 | 组合 | 有意义的组合方式 | +| ---------- | ---------- | ----------------- | ---------------- | +| POLL | POLL | RX_POLL + TX_POLL | | +| | INT | RX_POLL + TX_INT | | +| | DMA | RX_POLL + TX_DMA | | +| INT | POLL | RX_INT + TX_POLL | | +| | INT | RX_INT + TX_INT | ✔ | +| | DMA | RX_INT + TX_DMA | ✔ | +| DMA | POLL | RX_DMA + TX_POLL | | +| | INT | RX_DMA + TX_INT | ✔ | +| | DMA | RX_DMA + TX_DMA | ✔ | + +| 接收阻塞 | 发送阻塞 | 组合 | 有意义的组合方式 | +| -------- | -------- | ----------------- | ---------------- | +| POLL | POLL | RX_POLL + TX_POLL | | +| | INT | RX_POLL + TX_INT | | +| | DMA | RX_POLL + TX_DMA | | +| INT | POLL | RX_INT + TX_POLL | ✔ | +| | INT | RX_INT + TX_INT | ✔ | +| | DMA | RX_INT + TX_DMA | ✔ | +| DMA | POLL | RX_DMA + TX_POLL | ✔ | +| | INT | RX_DMA + TX_INT | ✔ | +| | DMA | RX_DMA + TX_DMA | ✔ | + +| 接收阻塞 | 发送非阻塞 | 组合 | 有意义的组合方式 | +| -------- | ---------- | ----------------- | ---------------- | +| POLL | POLL | RX_POLL + TX_POLL | | +| | INT | RX_POLL + TX_INT | | +| | DMA | RX_POLL + TX_DMA | | +| INT | POLL | RX_INT + TX_POLL | | +| | INT | RX_INT + TX_INT | ✔ | +| | DMA | RX_INT + TX_DMA | ✔ | +| DMA | POLL | RX_DMA + TX_POLL | | +| | INT | RX_DMA + TX_INT | ✔ | +| | DMA | RX_DMA + TX_DMA | ✔ | + +需要解释的是,为什么会存在无意义的组合模式,举个例子,非阻塞模式下,肯定是不会出现POLL(轮询)方式的,因为POLL方式已经表明是阻塞方式了。 +该测试用例在测试多种组合时,需要通过更改`rtconfig.h`文件对硬件模式进行静态配置。 + +### 4.2 测试思路 + +这四个测试用例的测试思路基本一致。 + +硬件上:**短接串口的发送TX引脚和接收RX引脚,完成自发自收的回路**。 + +软件上:创建两个线程A和B,A为接收线程,B为发送线程,设置A线程优先级比B线程优先级高。发送线程发送随机长度(长度范围是 0 到 1000)的数据,接收线程接收到数据进行校验,数据正确则测试通过,默认测试100次。 + +## 5、配置 + +使用该测试用例需要在 `env` 工具的 `menuconfig` 中做相关配置,配置如下所示(使用 RT-Thread-Studio 的配置路径一致 ): + +``` +RT-Thread Utestcases ---> + [*] RT-Thread Utestcases ---> + Utest Serial Testcase ---> + [*] Serial testcase +``` + +## 6、使用 + +\- 编译下载。 + +\- 在 MSH 中输入 `utest_run testcases.drivers.uart_rxb_txb` 运行串口接收阻塞和发送阻塞测试用例。 + +\- 在 MSH 中输入 `utest_run testcases.drivers.uart_rxb_txb` 运行串口接收阻塞和发送阻塞测试用例。 + +\- 在 MSH 中输入 `utest_run testcases.drivers.uart_rxb_txb` 运行串口接收阻塞和发送阻塞测试用例。 + +\- 在 MSH 中输入 `utest_run testcases.drivers.uart_rxb_txb` 运行串口接收阻塞和发送阻塞测试用例。 + +如果仅仅配置了 `Serial testcase` 相关的测试用例,则直接输入 `utest_run` 运行即可将上述测试用例按序测试。 + +## 7、注意事项 + +\- 需配置正确的测试用例。 + +\- 如有需要,可开启 ULOG 查看测试用例日志信息。 + +\- 需在 MSH 中输入正确的命令行。 + +\- 测试用例默认的测试数据长度范围最大为1000字节,如果接收端的缓冲区大小配置为小于1000字节时,那么在测试接收阻塞模式时,将会由于获取不了1000字节长度导致线程持续阻塞(因为测试用例是按 `recv_len` 长度去接收的,而不是按照单字节去接收的),因此建议接收端的缓冲区大小 (对应宏例如为 `BSP_UART2_RX_BUFSIZE`)设置为1024即可;当然也可按需减小测试的最大数据长度。 + +\- 该测试用例需要结合硬件具体的工作模式(POLL 、INT、DMA)进行测试,而硬件工作模式只能选择一种,因此需要在 `rtconfig.h` 中对串口相应的宏进行配置,来选择不同的工作模式去进行测试。 + diff --git a/examples/utest/testcases/drivers/serial_v2/SConscript b/examples/utest/testcases/drivers/serial_v2/SConscript new file mode 100644 index 0000000000..a7a46e656a --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/SConscript @@ -0,0 +1,16 @@ +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Split(''' +uart_rxb_txnb.c +uart_rxb_txb.c +uart_rxnb_txb.c +uart_rxnb_txnb.c +''') + +CPPPATH = [cwd] + +group = DefineGroup('utestcases', src, depend = ['UTEST_SERIAL_TC'], CPPPATH = CPPPATH) + +Return('group') diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c new file mode 100644 index 0000000000..8b2205ee1a --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include +#include "utest.h" +#include +#include + +#define TC_UART_DEVICE_NAME "uart2" +#define TC_UART_SEND_TIMES 100 + + +#ifdef UTEST_SERIAL_TC + +#define TEST_UART_NAME TC_UART_DEVICE_NAME + +static struct rt_serial_device *serial; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", TEST_UART_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_uint16_t send_len; + + rt_uint32_t i = 0; + send_len = *(rt_uint16_t *)parameter; + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + /* send buffer */ + if (rt_device_write(&serial->parent, 0, uart_write_buffer, send_len) != send_len) + { + LOG_E("device write failed\r\n"); + } + rt_free(uart_write_buffer); + +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint16_t rev_len; + + rev_len = *(rt_uint16_t *)parameter; + rt_uint8_t *ch; + ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; + rt_uint32_t all_receive_length = 0; + + + while (1) + { + cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + if (cnt == 0) + { + continue; + } + + if (fisrt_flag != RT_TRUE) + { + if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + { + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + else + { + fisrt_flag = RT_FALSE; + } + + for (i = 0; i < cnt - 1; i++) + { + if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + { + LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + all_receive_length += cnt; + if (all_receive_length >= rev_len) + break; + else + last_old_data = ch[cnt - 1]; + } + rt_free(ch); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint16_t length) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = BSP_UART2_RX_BUFSIZE; + config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + thread_send = rt_thread_create("uart_send", uart_send_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); + if ((thread_send != RT_NULL) && (thread_recv != RT_NULL)) + { + rt_thread_startup(thread_send); + rt_thread_startup(thread_recv); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } +__exit: + rt_device_close(&serial->parent); + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t times = 0; + rt_uint16_t num = 0; + while (TC_UART_SEND_TIMES - times) + { + num = (rand() % 1000) + 1; + if(uart_api(num) == RT_EOK) + LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + else + { + LOG_E("uart test error"); + break; + } + } + uassert_true(uart_over_flag == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxb_txb", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c new file mode 100644 index 0000000000..f03a24fe13 --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include +#include "utest.h" +#include +#include + +#define TC_UART_DEVICE_NAME "uart2" +#define TC_UART_SEND_TIMES 100 + + +#ifdef UTEST_SERIAL_TC + +#define TEST_UART_NAME TC_UART_DEVICE_NAME + +static struct rt_serial_device *serial; +static rt_sem_t tx_sem; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", TEST_UART_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t uart_tx_completion(rt_device_t device, void *buffer) +{ + rt_sem_release(tx_sem); + + return RT_EOK; +} + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_uint16_t send_len, len = 0; + rt_err_t result; + + rt_uint32_t i = 0; + send_len = *(rt_uint16_t *)parameter; + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + /* send buffer */ + while (send_len - len) + { + len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len); + result = rt_sem_take(tx_sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + LOG_E("take sem err in send."); + } + } + rt_free(uart_write_buffer); + +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint16_t rev_len; + + rev_len = *(rt_uint16_t *)parameter; + rt_uint8_t *ch; + ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; + rt_uint32_t all_receive_length = 0; + + while (1) + { + cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + if (cnt != rev_len) + { + continue; + } + + if (fisrt_flag != RT_TRUE) + { + if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + { + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + else + { + fisrt_flag = RT_FALSE; + } + + for (i = 0; i < cnt - 1; i++) + { + if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + { + LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + all_receive_length += cnt; + if (all_receive_length >= rev_len) + break; + else + last_old_data = ch[cnt - 1]; + } + rt_free(ch); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint16_t test_buf) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + tx_sem = rt_sem_create("tx_sem", 0, RT_IPC_FLAG_PRIO); + if (tx_sem == RT_NULL) + { + LOG_E("Init sem failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = BSP_UART2_RX_BUFSIZE; + config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING); + + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* set receive callback function */ + result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion); + if (result != RT_EOK) + { + goto __exit; + } + + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); + thread_send = rt_thread_create("uart_send", uart_send_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); + + if (thread_send != RT_NULL && thread_recv != RT_NULL) + { + rt_thread_startup(thread_recv); + rt_thread_startup(thread_send); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } +__exit: + if (tx_sem) + rt_sem_delete(tx_sem); + + rt_device_close(&serial->parent); + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t times = 0; + rt_uint16_t num = 0; + while (TC_UART_SEND_TIMES - times) + { + num = (rand() % 1000) + 1; + if(uart_api(num) == RT_EOK) + LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + else + { + LOG_E("uart test error"); + break; + } + } + uassert_true(uart_over_flag == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + tx_sem = RT_NULL; + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxb_txnb", utest_tc_init, utest_tc_cleanup, 30); + +#endif diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c new file mode 100644 index 0000000000..c1c88ddc9f --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include +#include "utest.h" +#include +#include + +#define TC_UART_DEVICE_NAME "uart2" +#define TC_UART_SEND_TIMES 100 + + +#ifdef UTEST_SERIAL_TC + +#define TEST_UART_NAME TC_UART_DEVICE_NAME + +static struct rt_serial_device *serial; +static rt_sem_t rx_sem; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", TEST_UART_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t uart_rx_indicate(rt_device_t device, rt_size_t size) +{ + rt_sem_release(rx_sem); + + return RT_EOK; +} + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_uint16_t send_len; + + rt_uint32_t i = 0; + send_len = *(rt_uint16_t *)parameter; + + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + + /* send buffer */ + if (rt_device_write(&serial->parent, 0, uart_write_buffer, send_len) != send_len) + { + LOG_E("device write failed\r\n"); + } + rt_free(uart_write_buffer); +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint16_t rev_len; + + rev_len = *(rt_uint16_t *)parameter; + rt_uint8_t *ch; + ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; + rt_uint32_t all_receive_length = 0; + + while (1) + { + rt_err_t result; + + result = rt_sem_take(rx_sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + LOG_E("take sem err in recv."); + } + + cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + if (cnt == 0) + { + continue; + } + + if (fisrt_flag != RT_TRUE) + { + if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + { + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + else + { + fisrt_flag = RT_FALSE; + } + + for (i = 0; i < cnt - 1; i++) + { + if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + { + LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + all_receive_length += cnt; + if (all_receive_length >= rev_len) + break; + else + last_old_data = ch[cnt - 1]; + } + rt_free(ch); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint16_t test_buf) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + rx_sem = rt_sem_create("rx_sem", 0, RT_IPC_FLAG_PRIO); + if (rx_sem == RT_NULL) + { + LOG_E("Init sem failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = BSP_UART2_RX_BUFSIZE; + config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + uart_result = RT_FALSE; + rt_sem_delete(rx_sem); + return -RT_ERROR; + } + + /* set receive callback function */ + result = rt_device_set_rx_indicate(&serial->parent, uart_rx_indicate); + if (result != RT_EOK) + { + goto __exit; + } + + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); + thread_send = rt_thread_create("uart_send", uart_send_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); + + if (thread_send != RT_NULL && thread_recv != RT_NULL) + { + rt_thread_startup(thread_recv); + rt_thread_startup(thread_send); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } +__exit: + if (rx_sem) + rt_sem_delete(rx_sem); + rt_device_close(&serial->parent); + uart_over_flag = RT_FALSE; + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t times = 0; + rt_uint16_t num = 0; + while (TC_UART_SEND_TIMES - times) + { + num = (rand() % 1000) + 1; + if(uart_api(num) == RT_EOK) + LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + else + { + LOG_E("uart test error"); + break; + } + } + uassert_true(uart_result == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + rx_sem = RT_NULL; + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxnb_txb", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c new file mode 100644 index 0000000000..ad8d20b8cf --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include +#include "utest.h" +#include +#include + +#define TC_UART_DEVICE_NAME "uart2" +#define TC_UART_SEND_TIMES 100 + + +#ifdef UTEST_SERIAL_TC + +#define TEST_UART_NAME TC_UART_DEVICE_NAME + +static struct rt_serial_device *serial; +static rt_sem_t tx_sem; +static rt_sem_t rx_sem; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", TEST_UART_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t uart_tx_completion(rt_device_t device, void *buffer) +{ + rt_sem_release(tx_sem); + return RT_EOK; +} + +static rt_err_t uart_rx_indicate(rt_device_t device, rt_size_t size) +{ + rt_sem_release(rx_sem); + return RT_EOK; +} + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_uint16_t send_len, len = 0; + rt_err_t result; + + rt_uint32_t i = 0; + send_len = *(rt_uint16_t *)parameter; + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + /* send buffer */ + while (send_len - len) + { + len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len); + result = rt_sem_take(tx_sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + LOG_E("take sem err in send."); + } + } + rt_free(uart_write_buffer); + +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint16_t rev_len; + + rev_len = *(rt_uint16_t *)parameter; + rt_uint8_t *ch; + ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; + rt_uint32_t all_receive_length = 0; + + while (1) + { + rt_err_t result; + + result = rt_sem_take(rx_sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + LOG_E("take sem err in recv."); + } + + cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + if (cnt == 0) + { + continue; + } + + if (fisrt_flag != RT_TRUE) + { + if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + { + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + else + { + fisrt_flag = RT_FALSE; + } + + for (i = 0; i < cnt - 1; i++) + { + if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + { + LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + all_receive_length += cnt; + if (all_receive_length >= rev_len) + break; + else + last_old_data = ch[cnt - 1]; + } + rt_free(ch); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint16_t test_buf) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + rx_sem = rt_sem_create("rx_sem", 0, RT_IPC_FLAG_PRIO); + if (rx_sem == RT_NULL) + { + LOG_E("Init rx_sem failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + tx_sem = rt_sem_create("tx_sem", 0, RT_IPC_FLAG_PRIO); + if (tx_sem == RT_NULL) + { + LOG_E("Init tx_sem failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = BSP_UART2_RX_BUFSIZE; + config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING); + + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* set receive callback function */ + result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion); + if (result != RT_EOK) + { + goto __exit; + } + + result = rt_device_set_rx_indicate(&serial->parent, uart_rx_indicate); + if (result != RT_EOK) + { + goto __exit; + } + + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); + thread_send = rt_thread_create("uart_send", uart_send_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); + + if (thread_send != RT_NULL && thread_recv != RT_NULL) + { + rt_thread_startup(thread_recv); + rt_thread_startup(thread_send); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } +__exit: + if (tx_sem) + rt_sem_delete(tx_sem); + + if (rx_sem) + rt_sem_delete(rx_sem); + + rt_device_close(&serial->parent); + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t times = 0; + rt_uint16_t num = 0; + while (TC_UART_SEND_TIMES - times) + { + num = (rand() % 1000) + 1; + if(uart_api(num) == RT_EOK) + LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + else + { + LOG_E("uart test error"); + break; + } + } + uassert_true(uart_over_flag == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + tx_sem = RT_NULL; + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxnb_txnb", utest_tc_init, utest_tc_cleanup, 30); + +#endif -- cgit v1.3.1 From e0b00b21f5be26e1b48fca491c65a38165e4d225 Mon Sep 17 00:00:00 2001 From: DavidLin1577 Date: Tue, 6 Jul 2021 18:03:12 +0800 Subject: [examples/test]update rtc_test.c --- examples/test/rtc_test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/test/rtc_test.c b/examples/test/rtc_test.c index 4ed1349de4..79ea8450f9 100644 --- a/examples/test/rtc_test.c +++ b/examples/test/rtc_test.c @@ -20,7 +20,7 @@ int rtc_test(void) rt_kprintf("[RTC Test]RTC Test Start...\n"); rt_thread_delay(RT_TICK_PER_SECOND); - rt_kprintf("[RTC Test]Set RTC 2017-04-01 12:30:46\n\n"); + rt_kprintf("[RTC Test]Set RTC 2017-04-01 12:30:46\n"); rt_thread_delay(RT_TICK_PER_SECOND); ret = set_date(2017, 4, 1); @@ -45,7 +45,7 @@ int rtc_test(void) { rt_kprintf("[RTC Test]Read RTC Date and Time: "); now = time(RT_NULL); - rt_kprintf("%s", ctime(&now)); + rt_kprintf("%s\n", ctime(&now)); rt_thread_delay(RT_TICK_PER_SECOND); } @@ -56,6 +56,6 @@ int rtc_test(void) } #ifdef RT_USING_FINSH #include -FINSH_FUNCTION_EXPORT(rtc_test, rtc drive test. e.g: rtc_test()); -MSH_CMD_EXPORT(rtc_test, rtc drive test. e.g: rtc_test()); +FINSH_FUNCTION_EXPORT(rtc_test, rtc driver test. e.g: rtc_test()); +MSH_CMD_EXPORT(rtc_test, rtc driver test. e.g: rtc_test()); #endif -- cgit v1.3.1 From 3bc6d7c41434c2007f7ba110e209ce470f1ed046 Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Thu, 8 Jul 2021 13:38:29 +0800 Subject: [utestcase] 完善测试用例集合的 README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/utest/README.md | 18 ++++++------------ examples/utest/configs/kernel/mem.conf | 4 +++- 2 files changed, 9 insertions(+), 13 deletions(-) (limited to 'examples') diff --git a/examples/utest/README.md b/examples/utest/README.md index cc84651966..bde3bd4b80 100644 --- a/examples/utest/README.md +++ b/examples/utest/README.md @@ -54,26 +54,20 @@ msh />utest_run ### 3. 提交 -1. 如果是对已有测试集合的完善,需要把添加的测试用例的配置项添加到对应测试集合的配置文件里,如:[examples\utest\configs\utest_self\config.h](./configs/utest_self/config.h)。 +1. 如果是对已有测试集合的完善,需要把添加的测试用例的配置项,以及对应的依赖项添加到对应测试集合的配置文件里,如:[examples\utest\configs\kernel\mem.conf](./configs/kernel/mem.conf)。 ``` -/* RT-Thread Utestcases */ +CONFIG_UTEST_MEMHEAP_TC=y -#define RT_USING_UTESTCASES - -/* Utest Self Testcase */ - -#define UTEST_SELF_PASS_TC - -/* xxx Testcase */ -#define UTEST_XXX_TC +# dependencies +CONFIG_RT_USING_MEMHEAP=y ``` 2. 如果要添加新的测试集合,需要参考已有的测试集合,在 [examples\utest\configs](./configs) 目录下添加新的测试集合配置项。并更新 [.github\workflows\action_utest.yml](../../.github/workflows/action_utest.yml) 内的测试集合。 ``` -- {UTEST: "kernel/ipc", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"} -- {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"} +- {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "sd.bin"} +- {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "utest_self/self.conf", SD_FILE: "sd.bin"} ``` 3. 向 RT-Thread 主仓库提交合并请求。 \ No newline at end of file diff --git a/examples/utest/configs/kernel/mem.conf b/examples/utest/configs/kernel/mem.conf index 80a0259a4c..1a311ab9dd 100644 --- a/examples/utest/configs/kernel/mem.conf +++ b/examples/utest/configs/kernel/mem.conf @@ -1,2 +1,4 @@ -CONFIG_RT_USING_MEMHEAP=y CONFIG_UTEST_MEMHEAP_TC=y + +# dependencies +CONFIG_RT_USING_MEMHEAP=y -- cgit v1.3.1 From 98c72007d2f15f4e4314f7c820d2d58e625c0d5d Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Sun, 18 Jul 2021 12:52:04 +0800 Subject: [example] replace RT_IPC_FLAG_FIFO with RT_IPC_FLAG_PRIO --- examples/kernel/event_simple.c | 2 +- examples/kernel/mbox_send_wait.c | 2 +- examples/kernel/mbox_simple.c | 2 +- examples/kernel/messageq_simple.c | 2 +- examples/kernel/mutex_priority.c | 2 +- examples/kernel/mutex_simple.c | 2 +- examples/kernel/semaphore_buffer_worker.c | 2 +- examples/kernel/semaphore_dynamic.c | 2 +- examples/kernel/semaphore_producer_consumer.c | 6 +++--- examples/kernel/semaphore_static.c | 2 +- examples/kernel/tc_comm.c | 2 +- examples/kernel/timer_timeout.c | 2 +- examples/pm/wakeup_app.c | 2 +- 13 files changed, 15 insertions(+), 15 deletions(-) (limited to 'examples') diff --git a/examples/kernel/event_simple.c b/examples/kernel/event_simple.c index d2a2948fc7..8b2f966d3d 100644 --- a/examples/kernel/event_simple.c +++ b/examples/kernel/event_simple.c @@ -83,7 +83,7 @@ static void thread3_entry(void *param) int event_simple_init() { /* 初始化事件对象 */ - rt_event_init(&event, "event", RT_IPC_FLAG_FIFO); + rt_event_init(&event, "event", RT_IPC_FLAG_PRIO); /* 创建线程1 */ tid1 = rt_thread_create("t1", diff --git a/examples/kernel/mbox_send_wait.c b/examples/kernel/mbox_send_wait.c index 67f358ecea..919ceca31d 100644 --- a/examples/kernel/mbox_send_wait.c +++ b/examples/kernel/mbox_send_wait.c @@ -82,7 +82,7 @@ int mbox_send_wait_init() "mbt", /* 名称是mbt */ &mb_pool[0], /* 邮箱用到的内存池是mb_pool */ sizeof(mb_pool)/4, /* 大小是mb_pool大小除以4,因为一封邮件的大小是4字节 */ - RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */ + RT_IPC_FLAG_PRIO); /* 采用PRIO方式进行线程等待 */ /* 创建线程1 */ tid1 = rt_thread_create("t1", diff --git a/examples/kernel/mbox_simple.c b/examples/kernel/mbox_simple.c index 3f39bc0016..373c5f2817 100644 --- a/examples/kernel/mbox_simple.c +++ b/examples/kernel/mbox_simple.c @@ -80,7 +80,7 @@ int mbox_simple_init() "mbt", /* 名称是mbt */ &mb_pool[0], /* 邮箱用到的内存池是mb_pool */ sizeof(mb_pool)/4, /* 大小是mb_pool大小除以4,因为一封邮件的大小是4字节 */ - RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */ + RT_IPC_FLAG_PRIO); /* 采用PRIO方式进行线程等待 */ /* 创建线程1 */ tid1 = rt_thread_create("t1", diff --git a/examples/kernel/messageq_simple.c b/examples/kernel/messageq_simple.c index 62504bebb7..90bed7dd82 100644 --- a/examples/kernel/messageq_simple.c +++ b/examples/kernel/messageq_simple.c @@ -98,7 +98,7 @@ int messageq_simple_init() &msg_pool[0], /* 内存池指向msg_pool */ 128 - sizeof(void*), /* 每个消息的大小是 128 - void* */ sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */ - RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */ + RT_IPC_FLAG_PRIO); /* 如果有多个线程等待,按照优先级由高到低的方法分配消息 */ /* 创建线程1 */ tid1 = rt_thread_create("t1", diff --git a/examples/kernel/mutex_priority.c b/examples/kernel/mutex_priority.c index c1db934157..a7702eed6f 100755 --- a/examples/kernel/mutex_priority.c +++ b/examples/kernel/mutex_priority.c @@ -281,7 +281,7 @@ static void thread29_entry(void* parameter) static int mutex_simple_init() { /* 创建互斥锁 */ - mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO); + mutex = rt_mutex_create("mutex", RT_IPC_FLAG_PRIO); if (mutex == RT_NULL) { tc_stat(TC_STAT_END | TC_STAT_FAILED); diff --git a/examples/kernel/mutex_simple.c b/examples/kernel/mutex_simple.c index 4f6c5d7d28..ee875cca7d 100644 --- a/examples/kernel/mutex_simple.c +++ b/examples/kernel/mutex_simple.c @@ -87,7 +87,7 @@ static void thread3_entry(void* parameter) int mutex_simple_init() { /* 创建互斥锁 */ - mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO); + mutex = rt_mutex_create("mutex", RT_IPC_FLAG_PRIO); if (mutex == RT_NULL) { tc_stat(TC_STAT_END | TC_STAT_FAILED); diff --git a/examples/kernel/semaphore_buffer_worker.c b/examples/kernel/semaphore_buffer_worker.c index 5e4723b417..bd5a488460 100644 --- a/examples/kernel/semaphore_buffer_worker.c +++ b/examples/kernel/semaphore_buffer_worker.c @@ -209,7 +209,7 @@ int semaphore_buffer_worker_init() rb_init(&working_rb, working_buffer, BUFFER_SIZE); /* 创建信号量 */ - sem = rt_sem_create("sem", 1, RT_IPC_FLAG_FIFO); + sem = rt_sem_create("sem", 1, RT_IPC_FLAG_PRIO); if (sem == RT_NULL) { tc_stat(TC_STAT_END | TC_STAT_FAILED); diff --git a/examples/kernel/semaphore_dynamic.c b/examples/kernel/semaphore_dynamic.c index 564d73c496..dacdf10c37 100644 --- a/examples/kernel/semaphore_dynamic.c +++ b/examples/kernel/semaphore_dynamic.c @@ -78,7 +78,7 @@ static void thread_entry(void* parameter) int semaphore_dynamic_init() { /* 创建一个信号量,初始值是0 */ - sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO); + sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO); if (sem == RT_NULL) { tc_stat(TC_STAT_END | TC_STAT_FAILED); diff --git a/examples/kernel/semaphore_producer_consumer.c b/examples/kernel/semaphore_producer_consumer.c index b6f996ff57..4d9eb24e44 100644 --- a/examples/kernel/semaphore_producer_consumer.c +++ b/examples/kernel/semaphore_producer_consumer.c @@ -98,9 +98,9 @@ void consumer_thread_entry(void* parameter) int semaphore_producer_consumer_init() { /* 初始化3个信号量 */ - rt_sem_init(&sem_lock , "lock", 1, RT_IPC_FLAG_FIFO); - rt_sem_init(&sem_empty, "empty", MAXSEM, RT_IPC_FLAG_FIFO); - rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_FIFO); + rt_sem_init(&sem_lock , "lock", 1, RT_IPC_FLAG_PRIO); + rt_sem_init(&sem_empty, "empty", MAXSEM, RT_IPC_FLAG_PRIO); + rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_PRIO); /* 创建线程1 */ producer_tid = rt_thread_create("producer", diff --git a/examples/kernel/semaphore_static.c b/examples/kernel/semaphore_static.c index 641b0bc7c9..16b043db9c 100644 --- a/examples/kernel/semaphore_static.c +++ b/examples/kernel/semaphore_static.c @@ -81,7 +81,7 @@ int semaphore_static_init(void) rt_err_t result; /* 初始化信号量,初始值是0 */ - result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO); + result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_PRIO); if (result != RT_EOK) { tc_stat(TC_STAT_END | TC_STAT_FAILED); diff --git a/examples/kernel/tc_comm.c b/examples/kernel/tc_comm.c index 7153412aa0..b98c97d9b3 100644 --- a/examples/kernel/tc_comm.c +++ b/examples/kernel/tc_comm.c @@ -35,7 +35,7 @@ void tc_thread_entry(void* parameter) struct finsh_syscall* index; /* create tc semaphore */ - rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO); + rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_PRIO); do { for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index)) diff --git a/examples/kernel/timer_timeout.c b/examples/kernel/timer_timeout.c index 40bbbf2831..f72b45be3c 100644 --- a/examples/kernel/timer_timeout.c +++ b/examples/kernel/timer_timeout.c @@ -73,7 +73,7 @@ int timer_timeout_init() &msg_pool[0], /* 内存池指向msg_pool */ 128 - sizeof(void*), /* 每个消息的大小是 128 - void* */ sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */ - RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */ + RT_IPC_FLAG_PRIO); /* 如果有多个线程等待,按照优先级由高到低的方法分配消息 */ /* 创建线程 */ tid = rt_thread_create("t", diff --git a/examples/pm/wakeup_app.c b/examples/pm/wakeup_app.c index d287bf74ec..230d30ac4e 100644 --- a/examples/pm/wakeup_app.c +++ b/examples/pm/wakeup_app.c @@ -61,7 +61,7 @@ static int wakeup_app(void) { rt_thread_t tid; - wakeup_event = rt_event_create("wakup", RT_IPC_FLAG_FIFO); + wakeup_event = rt_event_create("wakup", RT_IPC_FLAG_PRIO); RT_ASSERT(wakeup_event != RT_NULL); tid = rt_thread_create("wakeup_app", wakeup_app_entry, RT_NULL, -- cgit v1.3.1 From 141e6a03e90671ec8f451e401fee099e1d30697d Mon Sep 17 00:00:00 2001 From: tyustli <1225613647@qq.com> Date: Thu, 12 Aug 2021 11:43:15 +0800 Subject: [add] add semaphore testcase src code and Kconfig --- examples/utest/testcases/kernel/Kconfig | 5 + examples/utest/testcases/kernel/SConscript | 3 + examples/utest/testcases/kernel/semaphore_tc.c | 559 +++++++++++++++++++++++++ 3 files changed, 567 insertions(+) create mode 100644 examples/utest/testcases/kernel/semaphore_tc.c (limited to 'examples') diff --git a/examples/utest/testcases/kernel/Kconfig b/examples/utest/testcases/kernel/Kconfig index 14334af16f..97464ecd8a 100644 --- a/examples/utest/testcases/kernel/Kconfig +++ b/examples/utest/testcases/kernel/Kconfig @@ -5,4 +5,9 @@ config UTEST_MEMHEAP_TC default y depends on RT_USING_MEMHEAP +config UTEST_SEMAPHORE_TC + bool "semaphore test" + default n + depends on RT_USING_SEMAPHORE + endmenu diff --git a/examples/utest/testcases/kernel/SConscript b/examples/utest/testcases/kernel/SConscript index 9411cdd9a0..ad6c959f4c 100644 --- a/examples/utest/testcases/kernel/SConscript +++ b/examples/utest/testcases/kernel/SConscript @@ -8,6 +8,9 @@ src = Split(''' if GetDepend(['UTEST_MEMHEAP_TC']): src += ['memheap_tc.c'] +if GetDepend(['UTEST_SEMAPHORE_TC']): + src += ['semaphore_tc.c'] + CPPPATH = [cwd] group = DefineGroup('utestcases', src, depend = [], CPPPATH = CPPPATH) diff --git a/examples/utest/testcases/kernel/semaphore_tc.c b/examples/utest/testcases/kernel/semaphore_tc.c new file mode 100644 index 0000000000..2992831d87 --- /dev/null +++ b/examples/utest/testcases/kernel/semaphore_tc.c @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-12 luckyzjq the first version + */ + +#include +#include +#include "utest.h" + +static struct rt_semaphore static_semaphore; +#ifdef RT_USING_HEAP +static rt_sem_t dynamic_semaphore; +#endif /* RT_USING_HEAP */ + +static void test_static_semaphore_init(void) +{ + rt_err_t result; + int rand_num = rand() % 0x10000; + + for (int i = 0; i < rand_num; i++) + { + result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + rt_sem_detach(&static_semaphore); + + result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_FIFO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + rt_sem_detach(&static_semaphore); + } + + uassert_true(RT_TRUE); +} + +static void test_static_semaphore_detach(void) +{ + rt_err_t result; + int rand_num = rand() % 0x10000; + + for (int i = 0; i < rand_num; i++) + { + result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + break; + } + + result = rt_sem_detach(&static_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + + result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_FIFO); + if (RT_EOK != result) + { + break; + } + result = rt_sem_detach(&static_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + } + + uassert_true(RT_TRUE); +} + +static void test_static_semaphore_take(void) +{ + rt_err_t result; + result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + /* first take */ + result = rt_sem_take(&static_semaphore, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + /* second take */ + result = rt_sem_take(&static_semaphore, 100); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_detach(&static_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_static_semaphore_trytake(void) +{ + rt_err_t result; + result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + /* first take */ + result = rt_sem_trytake(&static_semaphore); + if (RT_EOK != result) + uassert_true(RT_FALSE); + /* second take */ + result = rt_sem_trytake(&static_semaphore); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_detach(&static_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_static_semaphore_release(void) +{ + rt_err_t result; + result = rt_sem_init(&static_semaphore, "static_sem", 0, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + /* first take */ + result = rt_sem_take(&static_semaphore, 100); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + + /* release */ + result = rt_sem_release(&static_semaphore); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + /* second take */ + result = rt_sem_take(&static_semaphore, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_detach(&static_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_static_semaphore_control(void) +{ + rt_err_t result; + int value = 0; + + value = rand() % 100; + result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + result = rt_sem_control(&static_semaphore, RT_IPC_CMD_RESET, &value); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + else + { + return; + } + + for (int i = 0; i < value; i++) + { + result = rt_sem_take(&static_semaphore, 10); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + + rt_sem_detach(&static_semaphore); + uassert_true(RT_TRUE); +} + +static void static_release_isr_hardware_callback(void *param) +{ + rt_err_t result; + + result = rt_sem_release(&static_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} + +static void static_release_isr_software_callback(void *param) +{ + rt_err_t result; + + result = rt_sem_release(&static_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} + +static void test_static_semaphore_release_isr(void) +{ + rt_err_t result; + rt_timer_t hardware_timer; + rt_timer_t software_timer; + + /* create timer */ + hardware_timer = rt_timer_create("release_isr", + static_release_isr_hardware_callback, + RT_NULL, + 100, + RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_ONE_SHOT); + software_timer = rt_timer_create("release_isr", + static_release_isr_software_callback, + RT_NULL, + 100, + RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT); + /* start tiemr */ + if (hardware_timer) + rt_timer_start(hardware_timer); + if (software_timer) + rt_timer_start(software_timer); + + result = rt_sem_init(&static_semaphore, "static_sem", 0, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + for (int i = 0; i < 2; i++) + { + result = rt_sem_take(&static_semaphore, 1000); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + } + else + { + return; + } + + rt_sem_detach(&static_semaphore); + rt_timer_delete(hardware_timer); + rt_timer_delete(software_timer); + + uassert_true(RT_TRUE); +} + +#ifdef RT_USING_HEAP +static void test_dynamic_semaphore_create(void) +{ + rt_err_t result; + int rand_num = rand() % 0x10000; + + for (int i = 0; i < rand_num; i++) + { + dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_PRIO); + if (RT_NULL == dynamic_semaphore) + { + uassert_true(RT_FALSE); + break; + } + rt_sem_delete(dynamic_semaphore); + + dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_FIFO); + if (RT_NULL == dynamic_semaphore) + { + uassert_true(RT_FALSE); + break; + } + rt_sem_delete(dynamic_semaphore); + } + + uassert_true(RT_TRUE); +} + +static void test_dynamic_semaphore_delete(void) +{ + rt_err_t result; + int rand_num = rand() % 0x10000; + + for (int i = 0; i < rand_num; i++) + { + dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_PRIO); + if (RT_NULL == dynamic_semaphore) + { + break; + } + + result = rt_sem_delete(dynamic_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + + dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_FIFO); + if (RT_NULL == dynamic_semaphore) + { + break; + } + result = rt_sem_delete(dynamic_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + } + + uassert_true(RT_TRUE); +} + +static void test_dynamic_semaphore_take(void) +{ + rt_err_t result; + dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + /* first take */ + result = rt_sem_take(dynamic_semaphore, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + /* second take */ + result = rt_sem_take(dynamic_semaphore, 100); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_delete(dynamic_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_dynamic_semaphore_trytake(void) +{ + rt_err_t result; + dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + /* first take */ + result = rt_sem_trytake(dynamic_semaphore); + if (RT_EOK != result) + uassert_true(RT_FALSE); + /* second take */ + result = rt_sem_trytake(dynamic_semaphore); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_delete(dynamic_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_dynamic_semaphore_release(void) +{ + rt_err_t result; + dynamic_semaphore = rt_sem_create("static_sem", 0, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + /* first take */ + result = rt_sem_take(dynamic_semaphore, 100); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + + /* release */ + result = rt_sem_release(dynamic_semaphore); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + /* second take */ + result = rt_sem_take(dynamic_semaphore, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_delete(dynamic_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_dynamic_semaphore_control(void) +{ + rt_err_t result; + int value = 0; + + value = rand() % 100; + dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + result = rt_sem_control(dynamic_semaphore, RT_IPC_CMD_RESET, &value); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + else + { + return; + } + + for (int i = 0; i < value; i++) + { + result = rt_sem_take(dynamic_semaphore, 10); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + + rt_sem_delete(dynamic_semaphore); + uassert_true(RT_TRUE); +} + +static void dynamic_release_isr_hardware_callback(void *param) +{ + rt_err_t result; + + result = rt_sem_release(dynamic_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} + +static void dynamic_release_isr_software_callback(void *param) +{ + rt_err_t result; + + result = rt_sem_release(dynamic_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} + +static void test_dynamic_semaphore_release_isr(void) +{ + rt_err_t result; + rt_timer_t hardware_timer; + rt_timer_t software_timer; + + /* create timer */ + hardware_timer = rt_timer_create("release_isr", + dynamic_release_isr_hardware_callback, + RT_NULL, + 100, + RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_ONE_SHOT); + software_timer = rt_timer_create("release_isr", + dynamic_release_isr_software_callback, + RT_NULL, + 100, + RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT); + /* start tiemr */ + if (hardware_timer) + rt_timer_start(hardware_timer); + if (software_timer) + rt_timer_start(software_timer); + + dynamic_semaphore = rt_sem_create("static_sem", 0, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + for (int i = 0; i < 2; i++) + { + result = rt_sem_take(dynamic_semaphore, 1000); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + } + else + { + return; + } + + rt_sem_delete(dynamic_semaphore); + rt_timer_delete(hardware_timer); + rt_timer_delete(software_timer); + + uassert_true(RT_TRUE); +} + +#endif /* RT_USING_HEAP */ + +static rt_err_t utest_tc_init(void) +{ +#ifdef RT_USING_HEAP + dynamic_semaphore = RT_NULL; +#endif /* RT_USING_HEAP */ + + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ +#ifdef RT_USING_HEAP + dynamic_semaphore = RT_NULL; +#endif /* RT_USING_HEAP */ + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_static_semaphore_init); + UTEST_UNIT_RUN(test_static_semaphore_take); + UTEST_UNIT_RUN(test_static_semaphore_release); + UTEST_UNIT_RUN(test_static_semaphore_detach); + UTEST_UNIT_RUN(test_static_semaphore_trytake); + UTEST_UNIT_RUN(test_static_semaphore_control); + UTEST_UNIT_RUN(test_static_semaphore_release_isr); + +#ifdef RT_USING_HEAP + UTEST_UNIT_RUN(test_dynamic_semaphore_create); + UTEST_UNIT_RUN(test_dynamic_semaphore_take); + UTEST_UNIT_RUN(test_dynamic_semaphore_release); + UTEST_UNIT_RUN(test_dynamic_semaphore_delete); + UTEST_UNIT_RUN(test_dynamic_semaphore_trytake); + UTEST_UNIT_RUN(test_dynamic_semaphore_control); + UTEST_UNIT_RUN(test_dynamic_semaphore_release_isr); +#endif /* RT_USING_HEAP */ +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.semaphore_tc", utest_tc_init, utest_tc_cleanup, 1000); -- cgit v1.3.1 From 491524cb9621f85c011215748d30709fc4578adf Mon Sep 17 00:00:00 2001 From: Sherman Date: Wed, 23 Jun 2021 18:35:19 +0800 Subject: [components]rt-link v0.2.0 新特性: 1. service 通道增加【连接状态】属性 2. service 通道增加发送消息质量配置,ACK、CRC 可配置开关; 3. 发送接口支持阻塞、非阻塞两种发送方式; 4. 已对接到 device 框架,支持 rt_device 接口操作 5. 已对接到 DFS 框架,支持 POSIX 接口操作 6. 移除 hw_port 目录,改为软件包方式添加 hw_port 7. 修复已知 BUG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/utilities/rt-link/Kconfig | 15 - components/utilities/rt-link/hw_port/SConscript | 14 - .../rt-link/hw_port/uart/rtlink_port_uart.c | 73 -- components/utilities/rt-link/inc/rtlink.h | 179 +++-- components/utilities/rt-link/inc/rtlink_dev.h | 41 + components/utilities/rt-link/inc/rtlink_hw.h | 4 +- components/utilities/rt-link/inc/rtlink_port.h | 6 +- components/utilities/rt-link/src/rtlink.c | 874 ++++++++++++--------- components/utilities/rt-link/src/rtlink_dev.c | 396 ++++++++++ components/utilities/rt-link/src/rtlink_hw.c | 70 +- examples/rt-link/rtlink_dev_example.c | 395 ++++++++++ examples/rt-link/rtlink_example.c | 119 +-- 12 files changed, 1575 insertions(+), 611 deletions(-) delete mode 100644 components/utilities/rt-link/hw_port/SConscript delete mode 100644 components/utilities/rt-link/hw_port/uart/rtlink_port_uart.c create mode 100644 components/utilities/rt-link/inc/rtlink_dev.h create mode 100644 components/utilities/rt-link/src/rtlink_dev.c create mode 100644 examples/rt-link/rtlink_dev_example.c (limited to 'examples') diff --git a/components/utilities/rt-link/Kconfig b/components/utilities/rt-link/Kconfig index 10ed129e69..d20c2f01d4 100644 --- a/components/utilities/rt-link/Kconfig +++ b/components/utilities/rt-link/Kconfig @@ -14,21 +14,6 @@ if RT_USING_RT_LINK bool "use hardware crc device" endchoice - menu "rt-link hardware device configuration" - config RT_LINK_HW_DEVICE_NAME - string "the name of base actual device" - default "uart2" - - choice - prompt"hardware device is spi, uart or usb" - default RT_LINK_USING_UART - - config RT_LINK_USING_UART - bool "use UART" - endchoice - - endmenu - menu "rt link debug option" config USING_RT_LINK_DEBUG bool "Enable RT-Link debug" diff --git a/components/utilities/rt-link/hw_port/SConscript b/components/utilities/rt-link/hw_port/SConscript deleted file mode 100644 index e34243ebda..0000000000 --- a/components/utilities/rt-link/hw_port/SConscript +++ /dev/null @@ -1,14 +0,0 @@ -import os -from building import * -import rtconfig - -cwd = GetCurrentDir() -src = [] -CPPPATH = [] - -if GetDepend('RT_LINK_USING_UART'): - src += ['uart/rtlink_port_uart.c'] - -group = DefineGroup('rt-link-port', src, depend = ['RT_USING_RT_LINK'], CPPPATH = CPPPATH) - -Return('group') diff --git a/components/utilities/rt-link/hw_port/uart/rtlink_port_uart.c b/components/utilities/rt-link/hw_port/uart/rtlink_port_uart.c deleted file mode 100644 index 48fbb91bc3..0000000000 --- a/components/utilities/rt-link/hw_port/uart/rtlink_port_uart.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-12-09 xiangxistu the first version - */ - -#include -#include - -#include - -#ifndef RT_LINK_HW_DEVICE_NAME - #define RT_LINK_HW_DEVICE_NAME "uart2" -#endif - -#define DBG_TAG "rtlink_port" -#define DBG_LVL DBG_INFO -#include - -static struct rt_device *hw_device = RT_NULL; -rt_err_t rt_link_port_rx_ind(rt_device_t device, rt_size_t size) -{ - RT_ASSERT(device != RT_NULL); - - rt_uint8_t buffer[RT_SERIAL_RB_BUFSZ] = {0}; - rt_size_t length = 0; - length = rt_device_read(device, 0, buffer, sizeof(buffer)); - rt_link_hw_write_cb(&buffer, length); - return RT_EOK; -} - -rt_size_t rt_link_port_send(void *data, rt_size_t length) -{ - rt_size_t size = 0; - size = rt_device_write(hw_device, 0, data, length); - return size; -} - -int rt_link_port_init(void) -{ - hw_device = rt_device_find(RT_LINK_HW_DEVICE_NAME); - if (hw_device) - { - rt_device_open(hw_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); - rt_device_set_rx_indicate(hw_device, rt_link_port_rx_ind); - } - else - { - LOG_E("Not find device %s", RT_LINK_HW_DEVICE_NAME); - return -RT_ERROR; - } - return RT_EOK; -} - -int rt_link_port_deinit(void) -{ - hw_device = rt_device_find(RT_LINK_HW_DEVICE_NAME); - if (hw_device) - { - rt_device_close(hw_device); - rt_device_set_rx_indicate(hw_device, RT_NULL); - } - else - { - LOG_E("Not find device %s", RT_LINK_HW_DEVICE_NAME); - return -RT_ERROR; - } - return RT_EOK; -} diff --git a/components/utilities/rt-link/inc/rtlink.h b/components/utilities/rt-link/inc/rtlink.h index dd98b57c30..941c35a359 100644 --- a/components/utilities/rt-link/inc/rtlink.h +++ b/components/utilities/rt-link/inc/rtlink.h @@ -14,81 +14,102 @@ #include +#define RT_LINK_VER "0.2.0" + #define RT_LINK_AUTO_INIT -#define RT_LINK_FRAME_HEAD 0x15 -#define RT_LINK_FRAME_HEAD_MASK 0x1F -#define RT_LINK_MAX_DATA_LENGTH 2044 /*can exact divide by 4 bytes*/ -#define RT_LINK_FRAMES_MAX 0x03 /* The maximum number of split frames for a long package*/ +#define RT_LINK_FLAG_ACK 0x01 +#define RT_LINK_FLAG_CRC 0x02 + +#define RT_LINK_FRAME_HEAD 0x15 +#define RT_LINK_FRAME_HEAD_MASK 0x1F +/* The maximum number of split frames for a long package */ +#define RT_LINK_FRAMES_MAX 0x03 +/* The length in the rt_link_frame_head structure occupies 11 bits, +so the value range after 4-byte alignment is 0-2044.*/ +#define RT_LINK_MAX_FRAME_LENGTH 1024 -#define RT_LINK_ACK_MAX 0x07 +#define RT_LINK_ACK_MAX 0x07 #define RT_LINK_CRC_LENGTH 4 #define RT_LINK_HEAD_LENGTH 4 -#define RT_LINK_MAX_EXTEND_LENGTH 4 -#define RT_LINK_MAX_FRAME_LENGTH (RT_LINK_HEAD_LENGTH + RT_LINK_MAX_EXTEND_LENGTH + RT_LINK_MAX_DATA_LENGTH + RT_LINK_CRC_LENGTH) -#define RT_LINK_RECEIVE_BUFFER_LENGTH (RT_LINK_MAX_FRAME_LENGTH * RT_LINK_FRAMES_MAX + RT_LINK_HEAD_LENGTH + RT_LINK_MAX_EXTEND_LENGTH) +#define RT_LINK_EXTEND_LENGTH 4 + +#define RT_LINK_MAX_DATA_LENGTH (RT_LINK_MAX_FRAME_LENGTH - \ + RT_LINK_HEAD_LENGTH - \ + RT_LINK_EXTEND_LENGTH - \ + RT_LINK_CRC_LENGTH) +#define RT_LINK_RECEIVE_BUFFER_LENGTH (RT_LINK_MAX_FRAME_LENGTH * \ + RT_LINK_FRAMES_MAX + \ + RT_LINK_HEAD_LENGTH + \ + RT_LINK_EXTEND_LENGTH) typedef enum { - RT_LINK_SERVICE_RTLINK = 0, - RT_LINK_SERVICE_LINK_SOCKET = 1, - RT_LINK_SERVICE_LINK_WIFI = 2, - RT_LINK_SERVICE_LINK_MNGT = 3, - RT_LINK_SERVICE_LINK_MSHTOOLS = 4, - RT_LINK_SERVICE_MAX -} rt_link_service_t; + RT_LINK_SERVICE_RTLINK = 0, + RT_LINK_SERVICE_SOCKET = 1, + RT_LINK_SERVICE_WIFI = 2, + RT_LINK_SERVICE_MNGT = 3, + RT_LINK_SERVICE_MSHTOOLS = 4, -enum -{ - FRAME_EXTEND = 1 << 0, - FRAME_CRC = 1 << 1, - FRAME_ACK = 1 << 2 -}; + /* Expandable to a maximum of 31 */ + RT_LINK_SERVICE_MAX +} rt_link_service_e; typedef enum { - RT_LINK_RESERVE_FRAME = 0, + RT_LINK_RESEND_FRAME = 0, + RT_LINK_CONFIRM_FRAME = 1, + + RT_LINK_HANDSHAKE_FRAME = 2, + RT_LINK_DETACH_FRAME = 3, /* service is not online */ + RT_LINK_SESSION_END = 4, /* The retring failed to end the session */ - RT_LINK_RESEND_FRAME, - RT_LINK_CONFIRM_FRAME, - RT_LINK_SHORT_DATA_FRAME, - RT_LINK_LONG_DATA_FRAME, - RT_LINK_SESSION_END, /* The retring failed to end the session */ + RT_LINK_LONG_DATA_FRAME = 5, + RT_LINK_SHORT_DATA_FRAME = 6, - RT_LINK_HANDSHAKE_FRAME -} rt_link_frame_attribute_t; + RT_LINK_RESERVE_FRAME = 7 +} rt_link_frame_attr_e; typedef enum { /* receive event */ - RT_LINK_READ_CHECK_EVENT = 1 << 0, - RT_LINK_RECV_TIMEOUT_FRAME_EVENT = 1 << 1, - RT_LINK_RECV_TIMEOUT_LONG_EVENT = 1 << 2, + RT_LINK_READ_CHECK_EVENT = 1 << 0, + RT_LINK_RECV_TIMEOUT_FRAME_EVENT = 1 << 1, + RT_LINK_RECV_TIMEOUT_LONG_EVENT = 1 << 2, /* send event */ RT_LINK_SEND_READY_EVENT = 1 << 4, RT_LINK_SEND_OK_EVENT = 1 << 5, RT_LINK_SEND_FAILED_EVENT = 1 << 6, RT_LINK_SEND_TIMEOUT_EVENT = 1 << 7 -} rt_link_notice_t; +} rt_link_notice_e; typedef enum { - RT_LINK_ESTABLISHING = 0, - RT_LINK_NO_RESPONSE, - RT_LINK_CONNECT_DONE, -} rt_link_linkstatus_t; + RT_LINK_INIT = 0, + RT_LINK_DISCONN = 1, + RT_LINK_CONNECT = 2, +} rt_link_linkstate_e; typedef enum { - RECVTIMER_NONE = 0, - RECVTIMER_FRAME, - RECVTIMER_LONGFRAME -} rt_link_recvtimer_status_t; + RT_LINK_EOK = 0, + RT_LINK_ERR = 1, + RT_LINK_ETIMEOUT = 2, + RT_LINK_EFULL = 3, + RT_LINK_EEMPTY = 4, + RT_LINK_ENOMEM = 5, + RT_LINK_EIO = 6, + RT_LINK_ESESSION = 7, + RT_LINK_ESERVICE = 8, + + RT_LINK_EMAX +} rt_link_err_e; struct rt_link_receive_buffer { - rt_uint8_t data[RT_LINK_RECEIVE_BUFFER_LENGTH]; /* rt-link receive data buffer */ + /* rt-link receive data buffer */ + rt_uint8_t data[RT_LINK_RECEIVE_BUFFER_LENGTH]; rt_uint8_t *read_point; rt_uint8_t *write_point; rt_uint8_t *end_point; @@ -100,15 +121,16 @@ struct rt_link_frame_head rt_uint8_t extend : 1; rt_uint8_t crc : 1; rt_uint8_t ack : 1; + rt_uint8_t sequence; - rt_uint16_t channel: 5; - rt_uint16_t length : 11; + rt_uint16_t service: 5; + rt_uint16_t length : 11; /* range 0~2047 */ }; /* record frame information that opposite */ struct rt_link_record { - rt_uint8_t rx_seq; /* record the opposite sequence */ + rt_uint8_t rx_seq; /* record the opposite sequence */ rt_uint8_t total; /* the number of long frame number */ rt_uint8_t long_count; /* long packet recv counter */ rt_uint8_t *dataspace; /* the space of long frame */ @@ -116,58 +138,71 @@ struct rt_link_record struct rt_link_extend { - rt_uint16_t attribute; /* rt_link_frame_attribute_t */ + rt_uint16_t attribute; /* rt_link_frame_attr_e */ rt_uint16_t parameter; }; struct rt_link_frame { - struct rt_link_frame_head head; /* frame head */ - struct rt_link_extend extend; /* frame extend data */ - rt_uint8_t *real_data; /* the origin data */ - rt_uint32_t crc; /* CRC result */ + struct rt_link_frame_head head; /* frame head */ + struct rt_link_extend extend; /* frame extend data */ + rt_uint8_t *real_data; /* the origin data */ + rt_uint32_t crc; /* CRC result */ - rt_uint16_t data_len; /* the length of frame length */ - rt_uint16_t attribute; /* this will show frame attribute , rt_link_frame_attribute_t */ + rt_uint16_t data_len; /* the length of frame length */ + rt_uint16_t attribute; /* rt_link_frame_attr_e */ - rt_uint8_t index; /* the index frame for long frame */ - rt_uint8_t total; /* the total frame for long frame */ + rt_uint8_t issent; + rt_uint8_t index; /* the index frame for long frame */ + rt_uint8_t total; /* the total frame for long frame */ - rt_slist_t slist; /* the frame will hang on the send list on session */ + rt_slist_t slist; /* the frame will hang on the send list on session */ }; struct rt_link_service { - rt_err_t (*upload_callback)(void *data, rt_size_t size); + rt_int32_t timeout_tx; + void (*send_cb)(struct rt_link_service *service, void *buffer); + void (*recv_cb)(struct rt_link_service *service, void *data, rt_size_t size); + void *user_data; + + rt_uint8_t flag; /* Whether to use the CRC and ACK */ + rt_link_service_e service; + rt_link_linkstate_e state; /* channel link state */ + rt_link_err_e err; }; struct rt_link_session { - rt_link_linkstatus_t link_status; /* Link connection status*/ - struct rt_event event; /* the event that core logic */ - struct rt_link_service channel[RT_LINK_SERVICE_MAX]; /* thansfer to app layer */ + struct rt_event event; + struct rt_link_service *service[RT_LINK_SERVICE_MAX]; + rt_uint8_t tx_seq; /* Sequence number of the send data frame */ rt_slist_t tx_data_slist; - rt_uint8_t tx_seq; /* sequence for frame */ - struct rt_mutex tx_lock; /* protect send data interface, only one thread can hold it */ - struct rt_timer sendtimer; /* send function timer for rt link */ + rt_uint8_t sendbuffer[RT_LINK_MAX_FRAME_LENGTH]; + struct rt_event sendevent; + struct rt_timer sendtimer; - struct rt_link_record rx_record; /* the memory of receive status */ - struct rt_timer recvtimer; /* receive a frame timer for rt link */ - struct rt_timer longframetimer; /* receive long frame timer for rt link */ + struct rt_link_record rx_record; /* the memory of receive status */ + struct rt_timer recvtimer; /* receive a frame timer for rt link */ + struct rt_timer longframetimer; /* receive long frame timer for rt link */ - struct rt_link_receive_buffer *rx_buffer; /* the buffer will store data */ - rt_uint32_t (*calculate_crc)(rt_uint8_t using_buffer_ring, rt_uint8_t *data, rt_size_t size); /* this function will calculate crc */ + struct rt_link_receive_buffer *rx_buffer; + rt_uint32_t (*calculate_crc)(rt_uint8_t using_buffer_ring, rt_uint8_t *data, rt_size_t size); + rt_link_linkstate_e state; /* Link status */ }; -/* rtlink init and deinit */ +#define SERV_ERR_GET(service) (service->err) + +/* rtlink init and deinit, default is automatic initialization*/ int rt_link_init(void); rt_err_t rt_link_deinit(void); -/* rtlink send data interface */ -rt_size_t rt_link_send(rt_link_service_t service, void *data, rt_size_t size); + +rt_size_t rt_link_send(struct rt_link_service *service, const void *data, rt_size_t size); + /* rtlink service attach and detach */ -rt_err_t rt_link_service_attach(rt_link_service_t service, rt_err_t (*function)(void *data, rt_size_t size)); -rt_err_t rt_link_service_detach(rt_link_service_t service); +rt_err_t rt_link_service_attach(struct rt_link_service *service); +rt_err_t rt_link_service_detach(struct rt_link_service *service); /* Private operator function */ struct rt_link_session *rt_link_get_scb(void); diff --git a/components/utilities/rt-link/inc/rtlink_dev.h b/components/utilities/rt-link/inc/rtlink_dev.h new file mode 100644 index 0000000000..01fd04373c --- /dev/null +++ b/components/utilities/rt-link/inc/rtlink_dev.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-15 Sherman the first version + */ + +#include +#include + +#define RT_LINK_RX_NONBLOCKING 0x1000 +#define RT_LINK_RX_BLOCKING 0x2000 +#define RT_LINK_TX_NONBLOCKING 0x4000 +#define RT_LINK_TX_BLOCKING 0x8000 +#define RT_LINK_DEVICE_MASK 0xf000 + +struct rtlink_recv_list +{ + void *data; + rt_size_t size; + rt_size_t index; + struct rt_slist_node list; +}; + +struct rt_link_device +{ + struct rt_device parent; + struct rt_link_service service; + struct rt_slist_node recv_head; /* recv data list, struct rtlink_recv_list */ +}; + +/* + * rtlink device register + */ +rt_err_t rt_link_dev_register(struct rt_link_device *rtlink, + const char *name, + rt_uint32_t flag, + void *data); diff --git a/components/utilities/rt-link/inc/rtlink_hw.h b/components/utilities/rt-link/inc/rtlink_hw.h index c75609a23a..d0a56fe98c 100644 --- a/components/utilities/rt-link/inc/rtlink_hw.h +++ b/components/utilities/rt-link/inc/rtlink_hw.h @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2021-02-02 xiangxistu the first version + * 2021-07-13 Sherman add reconnect API * */ #ifndef __RT_LINK_HW_H__ @@ -19,6 +20,7 @@ void rt_link_hw_buffer_point_shift(rt_uint8_t **pointer_address, rt_size_t lengt rt_err_t rt_link_hw_init(void); rt_err_t rt_link_hw_deinit(void); -rt_err_t rt_link_hw_send(void *data, rt_size_t length); +rt_err_t rt_link_hw_reconnect(void); +rt_size_t rt_link_hw_send(void *data, rt_size_t length); #endif /* _RT_LINK_PORT_INTERNAL_H_ */ diff --git a/components/utilities/rt-link/inc/rtlink_port.h b/components/utilities/rt-link/inc/rtlink_port.h index 54a064d117..b22f19072a 100644 --- a/components/utilities/rt-link/inc/rtlink_port.h +++ b/components/utilities/rt-link/inc/rtlink_port.h @@ -7,6 +7,7 @@ * Date Author Notes * 2021-02-02 xiangxistu the first version * 2021-05-15 Sherman function rename + * 2021-07-13 Sherman add reconnect API */ #ifndef __RT_LINK_PORT_H__ #define __RT_LINK_PORT_H__ @@ -14,8 +15,9 @@ #include /* Functions that need to be implemented at the hardware */ -int rt_link_port_init(void); -int rt_link_port_deinit(void); +rt_err_t rt_link_port_init(void); +rt_err_t rt_link_port_deinit(void); +rt_err_t rt_link_port_reconnect(void); rt_size_t rt_link_port_send(void *data, rt_size_t length); #ifdef RT_LINK_USING_HW_CRC diff --git a/components/utilities/rt-link/src/rtlink.c b/components/utilities/rt-link/src/rtlink.c index 37a99538b6..010083aaa5 100644 --- a/components/utilities/rt-link/src/rtlink.c +++ b/components/utilities/rt-link/src/rtlink.c @@ -8,7 +8,11 @@ * 2021-02-02 xiangxistu the first version * 2021-03-19 Sherman Optimize the transfer process * 2021-04-20 Sherman Optimize memory footprint - * 2021-05-10 Sherman Add rtlink_status MSH command; Optimize transmission timer Settings; Fix known bugs + * 2021-05-10 Sherman Add rtlink_status MSH command; + * Optimize transmission timer Settings; + * Fix known bugs + * 2021-08-06 Sherman Add NACK, NCRC, non-blocking transmit mode; + * Add service connection status; */ #include @@ -35,25 +39,28 @@ #define RT_LINK_SENT_FRAME_TIMEOUT 100 #else #define RT_LINK_LONG_FRAME_TIMEOUT 100 - #define RT_LINK_SENT_FRAME_TIMEOUT 200 + #define RT_LINK_SENT_FRAME_TIMEOUT 100 #endif /* RT_LINK_USING_SPI */ #define RT_LINK_RECV_DATA_SEQUENCE 0 #define RT_LINK_INIT_FRAME_SEQENCE 129 -#define RT_LINK_THREAD_NAME "rtlink" -#define RT_LINK_THREAD_TICK 20 -#define RT_LINK_THREAD_PRIORITY 15 -#define RT_LINK_THREAD_STACK_SIZE 832 /* 32 bytes aligned */ +#define RT_LINK_THREAD_NAME "rtlink" +#define RT_LINK_THREAD_TICK 20 +#define RT_LINK_THREAD_PRIORITY 25 +#define RT_LINK_THREAD_STACK_SIZE 1024 /* 32 bytes aligned */ + +#define RT_LINK_FRAME_SENT 1 +#define RT_LINK_FRAME_NOSEND 0 typedef enum { - FIND_FRAME_HEAD = 0, - PARSE_FRAME_HEAD, - PARSE_FRAME_EXTEND, - PARSE_FRAME_SEQ, - CHECK_FRAME_CRC, - HEADLE_FRAME_DATA, + FIND_FRAME_HEAD = 0, + PARSE_FRAME_HEAD = 1, + PARSE_FRAME_EXTEND = 2, + PARSE_FRAME_SEQ = 3, + CHECK_FRAME_CRC = 4, + HEADLE_FRAME_DATA = 5, } rt_link_frame_parse_t; /* rtlink SCB(Session control block) */ @@ -83,11 +90,11 @@ static int rt_link_frame_init(struct rt_link_frame *frame, rt_uint8_t config) /* set frame control information */ rt_memset(&frame->head, 0, sizeof(struct rt_link_frame_head)); - if (config & FRAME_CRC) + if (config & RT_LINK_FLAG_CRC) { frame->head.crc = 1; } - if (config & FRAME_ACK) + if (config & RT_LINK_FLAG_ACK) { frame->head.ack = 1; } @@ -101,37 +108,153 @@ static int rt_link_frame_init(struct rt_link_frame *frame, rt_uint8_t config) frame->index = 0; frame->total = 0; frame->attribute = RT_LINK_RESERVE_FRAME; + frame->issent = RT_LINK_FRAME_NOSEND; rt_slist_init(&frame->slist); return RT_EOK; } -static rt_err_t rt_link_frame_free(struct rt_link_frame *frame) +/* remove the sending list node*/ +static void rt_link_frame_remove(struct rt_link_service *service) { - if (frame == RT_NULL) + RT_ASSERT(service != RT_NULL); + struct rt_link_frame *find_frame = RT_NULL; + rt_uint8_t total = 0; + rt_slist_t *tem_list = rt_slist_first(&rt_link_scb->tx_data_slist); + if (tem_list != RT_NULL) { - return -RT_ERROR; + do + { + find_frame = rt_container_of(tem_list, struct rt_link_frame, slist); + tem_list = rt_slist_next(tem_list); + if (find_frame->head.service == service->service) + { + if (total == 0) + { + total = find_frame->total; + } + /* The data frame order is appended to the list, + with total counting starting at 1 and index counting from 0 */ + LOG_D("remove seq(%d) serv (%d)", find_frame->head.sequence, service->service); + rt_enter_critical(); + rt_slist_remove(&rt_link_scb->tx_data_slist, &find_frame->slist); + rt_exit_critical(); + total--; + rt_memset(find_frame, 0, sizeof(struct rt_link_frame)); + rt_free(find_frame); + } + } while ((total > 0) && (tem_list != RT_NULL)); + } +} + +/* Configure the extended field of the frame */ +static rt_err_t rt_link_frame_extend_config(struct rt_link_frame *frame, rt_link_frame_attr_e attribute, rt_uint16_t parameter) +{ + frame->head.extend = 1; + frame->extend.attribute = attribute; + frame->extend.parameter = parameter; + return RT_EOK; +} + +static int rt_link_command_frame_send(rt_uint8_t serv, rt_uint8_t sequence, rt_link_frame_attr_e attribute, rt_uint16_t parameter) +{ + struct rt_link_frame command_frame = {0}; + rt_uint8_t data[sizeof(command_frame.head) + sizeof(command_frame.extend)] = {0}; + rt_uint8_t data_len = 0; + + /* command frame don't need crc and ack ability */ + rt_link_frame_init(&command_frame, RT_NULL); + data_len += sizeof(command_frame.head); + + rt_link_frame_extend_config(&command_frame, attribute, parameter); + rt_memcpy(data + data_len, &command_frame.extend, sizeof(command_frame.extend)); + data_len += sizeof(command_frame.extend); + + command_frame.head.sequence = sequence; + command_frame.head.service = serv; + rt_memcpy(data, &command_frame.head, sizeof(command_frame.head)); + + rt_link_hw_send(data, data_len); + return RT_EOK; +} + +static void rt_link_service_send_finish(rt_link_err_e err) +{ + struct rt_link_frame *frame = RT_NULL; + rt_uint8_t service = RT_LINK_SERVICE_MAX; + void *buffer = RT_NULL; + rt_slist_t *tem_list = rt_slist_first(&rt_link_scb->tx_data_slist); + if (tem_list == RT_NULL) + { + return ; + } + frame = rt_container_of(tem_list, struct rt_link_frame, slist); + if (frame) + { + service = frame->head.service; + buffer = frame->real_data - (frame->index * RT_LINK_MAX_DATA_LENGTH); + rt_link_scb->service[service]->err = err; + rt_link_scb->sendtimer.parameter = 0; + rt_link_frame_remove(rt_link_scb->service[service]); + if (rt_link_scb->service[service]->timeout_tx != RT_WAITING_NO) + { + rt_event_send(&rt_link_scb->sendevent, (0x01 << service)); + } + else + { + rt_link_scb->service[service]->send_cb(rt_link_scb->service[service], buffer); + } } +} + +static rt_size_t frame_send(struct rt_link_frame *frame) +{ + rt_size_t length = 0; + rt_uint8_t *data = RT_NULL; - if (frame->real_data != RT_NULL) + rt_memset(rt_link_scb->sendbuffer, 0, sizeof(rt_link_scb->sendbuffer)); + data = rt_link_scb->sendbuffer; + length = RT_LINK_HEAD_LENGTH; + if (frame->head.crc) { - rt_free(frame->real_data); - frame->real_data = RT_NULL; + length += RT_LINK_CRC_LENGTH; } - rt_memset(frame, 0, sizeof(struct rt_link_frame)); - rt_free(frame); - return RT_EOK; + if (frame->head.extend) + { + length += RT_LINK_EXTEND_LENGTH; + } + + length += frame->data_len; + frame->head.length = frame->data_len; + rt_memcpy(data, &frame->head, RT_LINK_HEAD_LENGTH); + data = data + RT_LINK_HEAD_LENGTH; + if (frame->head.extend) + { + rt_memcpy(data, &frame->extend, RT_LINK_EXTEND_LENGTH); + data = data + RT_LINK_EXTEND_LENGTH; + } + if (frame->attribute == RT_LINK_SHORT_DATA_FRAME || frame->attribute == RT_LINK_LONG_DATA_FRAME) + { + rt_memcpy(data, frame->real_data, frame->data_len); + data = data + frame->data_len; + } + if (frame->head.crc) + { + frame->crc = rt_link_scb->calculate_crc(RT_FALSE, rt_link_scb->sendbuffer, length - RT_LINK_CRC_LENGTH); + rt_memcpy(data, &frame->crc, RT_LINK_CRC_LENGTH); + } + + LOG_D("frame send seq(%d) len(%d) attr:(%d), crc:(0x%08x).", frame->head.sequence, length, frame->attribute, frame->crc); + return rt_link_hw_send(rt_link_scb->sendbuffer, length); } /* performs data transmission */ static rt_err_t rt_link_frame_send(rt_slist_t *slist) { + rt_uint8_t is_finish = RT_FALSE; struct rt_link_frame *frame = RT_NULL; - rt_uint8_t *origin_data = RT_NULL; - rt_uint8_t *data = RT_NULL; - rt_size_t length = 0; - rt_uint8_t send_max = RT_LINK_ACK_MAX; /* The number of '1' in the binary number */ + rt_uint8_t send_max = RT_LINK_ACK_MAX; /* if slist is tx_data_slist, we should send all data on the slist*/ if (slist == &rt_link_scb->tx_data_slist) @@ -140,16 +263,9 @@ static rt_err_t rt_link_frame_send(rt_slist_t *slist) } if (slist == RT_NULL) { - LOG_W("tx_data_slist NULL"); + LOG_W("send data list NULL"); return -RT_ERROR; } - data = rt_malloc(RT_LINK_MAX_FRAME_LENGTH); - if (data == RT_NULL) - { - LOG_E("rt link alloc memory(%d B) failed, send frame failed.", RT_LINK_MAX_FRAME_LENGTH); - return -RT_ENOMEM; - } - origin_data = data; do { @@ -157,48 +273,42 @@ static rt_err_t rt_link_frame_send(rt_slist_t *slist) frame = rt_container_of(slist, struct rt_link_frame, slist); slist = rt_slist_next(slist); - length = RT_LINK_HEAD_LENGTH; - if (frame->head.crc) + if (frame_send(frame) == 0) { - length += RT_LINK_CRC_LENGTH; + rt_link_scb->service[frame->head.service]->err = RT_LINK_EIO; + goto __err; } - if (frame->head.extend) + frame->issent = RT_LINK_FRAME_SENT; + if ((slist == RT_NULL) || (frame->index + 1 >= frame->total)) { - length += RT_LINK_MAX_EXTEND_LENGTH; - } - - length += frame->data_len; - frame->head.length = frame->data_len; - rt_memcpy(data, &frame->head, RT_LINK_HEAD_LENGTH); - data = data + RT_LINK_HEAD_LENGTH; - if (frame->head.extend) - { - rt_memcpy(data, &frame->extend, RT_LINK_MAX_EXTEND_LENGTH); - data = data + RT_LINK_MAX_EXTEND_LENGTH; - } - if (frame->attribute == RT_LINK_SHORT_DATA_FRAME || frame->attribute == RT_LINK_LONG_DATA_FRAME) - { - rt_memcpy(data, frame->real_data, frame->data_len); - data = data + frame->data_len; + send_max = 0; + is_finish = RT_TRUE; } - if (frame->head.crc) + else { - frame->crc = rt_link_scb->calculate_crc(RT_FALSE, origin_data, length - RT_LINK_CRC_LENGTH); - rt_memcpy(data, &frame->crc, RT_LINK_CRC_LENGTH); + send_max >>= 1; } + }while (send_max); - LOG_D("frame send(%d) len(%d) attr:(%d), crc:(0x%08x).", frame->head.sequence, length, frame->attribute, frame->crc); - rt_link_hw_send(origin_data, length); - - data = origin_data; - if (slist == RT_NULL) + if ((is_finish) && (frame->head.ack == 0)) + { + /* NACK frame send finish, remove after sending */ + rt_link_service_send_finish(RT_LINK_EOK); + if (slist != RT_NULL) { - send_max = 0; + LOG_D("Continue sending"); + rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT); } - send_max >>= 1; - }while (send_max); - rt_free(origin_data); + } + else + { + rt_int32_t timeout = RT_LINK_SENT_FRAME_TIMEOUT; + rt_timer_control(&rt_link_scb->sendtimer, RT_TIMER_CTRL_SET_TIME, &timeout); + rt_timer_start(&rt_link_scb->sendtimer); + } return RT_EOK; +__err: + return -RT_ERROR; } static void _stop_recv_long(void) @@ -216,54 +326,16 @@ static void _stop_recv_long(void) static rt_err_t rt_link_frame_stop_receive(struct rt_link_frame *frame) { rt_memset(frame, 0, sizeof(struct rt_link_frame)); - rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, rt_link_hw_recv_len(rt_link_scb->rx_buffer)); - return RT_EOK; -} - -/* Configure the extended field of the frame */ -static rt_err_t rt_link_frame_extend_config(struct rt_link_frame *frame, rt_link_frame_attribute_t attribute, rt_uint16_t parameter) -{ - frame->head.extend = 1; - frame->extend.attribute = attribute; - frame->extend.parameter = parameter; - return RT_EOK; -} - -static int rt_link_command_frame_send(rt_uint8_t sequence, rt_link_frame_attribute_t attribute, rt_uint16_t parameter) -{ - struct rt_link_frame command_frame = {0}; - rt_uint8_t extend_flag = RT_FALSE; - - /* command frame don't need crc and ack ability */ - rt_link_frame_init(&command_frame, RT_NULL); - command_frame.head.sequence = sequence; - command_frame.head.length = RT_LINK_MAX_EXTEND_LENGTH; - command_frame.attribute = attribute; - switch (attribute) + if (rt_link_scb->rx_record.dataspace) { - case RT_LINK_RESEND_FRAME: - extend_flag = RT_TRUE; - LOG_D("send RESEND_FRAME(%d).", command_frame.head.sequence); - break; - - case RT_LINK_HANDSHAKE_FRAME: - extend_flag = RT_TRUE; - LOG_D("send HANDSHAKE_FRAME(%d).", command_frame.head.sequence); - break; - - case RT_LINK_CONFIRM_FRAME: - LOG_D("send CONFIRM_FRAME(%d).", command_frame.head.sequence); - break; - - default: - break; + rt_free(rt_link_scb->rx_record.dataspace); } + rt_link_scb->rx_record.dataspace = RT_NULL; + rt_link_scb->rx_record.long_count = 0; + rt_link_scb->rx_record.total = 0; - if (extend_flag) - { - rt_link_frame_extend_config(&command_frame, attribute, parameter); - } - rt_link_frame_send(&command_frame.slist); + rt_timer_stop(&rt_link_scb->recvtimer); + rt_link_scb->recvtimer.parameter = 0; return RT_EOK; } @@ -279,7 +351,7 @@ static rt_err_t rt_link_resend_handle(struct rt_link_frame *receive_frame) if (find_frame->head.sequence == receive_frame->head.sequence) { LOG_D("resend frame(%d)", find_frame->head.sequence); - rt_link_frame_send(&find_frame->slist); + frame_send(find_frame); break; } tem_list = tem_list->next; @@ -288,7 +360,9 @@ static rt_err_t rt_link_resend_handle(struct rt_link_frame *receive_frame) if (tem_list == RT_NULL) { LOG_D("frame resent failed, can't find(%d).", receive_frame->head.sequence); - rt_link_command_frame_send(receive_frame->head.sequence, RT_LINK_SESSION_END, RT_NULL); + rt_link_command_frame_send(receive_frame->head.service, + receive_frame->head.sequence, + RT_LINK_SESSION_END, RT_NULL); } return RT_EOK; } @@ -296,16 +370,21 @@ static rt_err_t rt_link_resend_handle(struct rt_link_frame *receive_frame) static rt_err_t rt_link_confirm_handle(struct rt_link_frame *receive_frame) { static struct rt_link_frame *send_frame = RT_NULL; - struct rt_link_frame *find_frame = RT_NULL; rt_slist_t *tem_list = RT_NULL; rt_uint16_t seq_offset = 0; - LOG_D("confirm seq(%d) frame", receive_frame->head.sequence); - if (rt_link_scb->link_status == RT_LINK_NO_RESPONSE) + + rt_timer_stop(&rt_link_scb->sendtimer); + + if (rt_link_scb->service[receive_frame->head.service] != RT_NULL) + { + rt_link_scb->service[receive_frame->head.service]->state = RT_LINK_CONNECT; + } + + if (rt_link_scb->state != RT_LINK_CONNECT) { /* The handshake success and resends the data frame */ - LOG_D("link_status RT_LINK_CONNECT_DONE, resend data"); - rt_link_scb->link_status = RT_LINK_CONNECT_DONE; + rt_link_scb->state = RT_LINK_CONNECT; if (rt_slist_first(&rt_link_scb->tx_data_slist)) { rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT); @@ -319,38 +398,15 @@ static rt_err_t rt_link_confirm_handle(struct rt_link_frame *receive_frame) { return -RT_ERROR; } - send_frame = rt_container_of(tem_list, struct rt_link_frame, slist); - seq_offset = rt_link_check_seq(receive_frame->head.sequence, - rt_link_scb->tx_seq); + seq_offset = rt_link_check_seq(receive_frame->head.sequence, send_frame->head.sequence); if (seq_offset <= send_frame->total) { - LOG_D("confirm frame (%d)", receive_frame->head.sequence); - for (int i = 0; i < seq_offset; i++) - { - find_frame = rt_container_of(tem_list, struct rt_link_frame, slist); - LOG_D("confirm(%d), remove(%d)", receive_frame->head.sequence, find_frame->head.sequence); - - rt_enter_critical(); - rt_slist_remove(&rt_link_scb->tx_data_slist, &find_frame->slist); - rt_exit_critical(); - find_frame->real_data = RT_NULL; - rt_link_frame_free(find_frame); + rt_link_service_send_finish(RT_LINK_EOK); + rt_link_scb->state = RT_LINK_CONNECT; - tem_list = rt_slist_first(&rt_link_scb->tx_data_slist); - if (tem_list == RT_NULL) - { - break; - } - } - rt_link_scb->tx_seq = receive_frame->head.sequence; - rt_link_scb->link_status = RT_LINK_CONNECT_DONE; - if (tem_list == RT_NULL) - { - LOG_D("SEND_OK"); - rt_event_send(&rt_link_scb->event, RT_LINK_SEND_OK_EVENT); - } - else + tem_list = rt_slist_first(&rt_link_scb->tx_data_slist); + if (tem_list != RT_NULL) { LOG_D("Continue sending"); rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT); @@ -359,29 +415,42 @@ static rt_err_t rt_link_confirm_handle(struct rt_link_frame *receive_frame) return RT_EOK; } +/* serv type rt_link_service_e */ +static void rt_link_recv_finish(rt_uint8_t serv, void *data, rt_size_t size) +{ + if (rt_link_scb->service[serv] == RT_NULL) + { + rt_link_command_frame_send(serv, 0, RT_LINK_DETACH_FRAME, RT_NULL); + return; + } + + if (rt_link_scb->service[serv]->recv_cb == RT_NULL) + { + rt_free(data); + LOG_W("service %d haven't been registered.", serv); + } + else + { + rt_link_scb->service[serv]->recv_cb(rt_link_scb->service[serv], data, size); + } +} + static rt_err_t rt_link_short_handle(struct rt_link_frame *receive_frame) { LOG_D("Seq(%d) short data", receive_frame->head.sequence); rt_link_scb->rx_record.dataspace = rt_malloc(receive_frame->data_len); if (rt_link_scb->rx_record.dataspace != RT_NULL) { - rt_link_command_frame_send(receive_frame->head.sequence, RT_LINK_CONFIRM_FRAME, RT_NULL); - rt_link_scb->rx_record.rx_seq = receive_frame->head.sequence; - - if (rt_link_scb->channel[receive_frame->head.channel].upload_callback == RT_NULL) + if (receive_frame->head.ack) { - rt_free(rt_link_scb->rx_record.dataspace); - LOG_E("Channel %d has not been registered", receive_frame->head.channel); - } - else - { - rt_enter_critical(); - rt_link_hw_copy(rt_link_scb->rx_record.dataspace, receive_frame->real_data, receive_frame->data_len); - rt_exit_critical(); - rt_link_scb->channel[receive_frame->head.channel].upload_callback(rt_link_scb->rx_record.dataspace, receive_frame->data_len); + rt_link_command_frame_send(receive_frame->head.service, + receive_frame->head.sequence, + RT_LINK_CONFIRM_FRAME, RT_NULL); } + rt_link_scb->rx_record.rx_seq = receive_frame->head.sequence; + rt_link_hw_copy(rt_link_scb->rx_record.dataspace, receive_frame->real_data, receive_frame->data_len); + rt_link_recv_finish(receive_frame->head.service, rt_link_scb->rx_record.dataspace, receive_frame->data_len); rt_link_scb->rx_record.dataspace = RT_NULL; - rt_link_frame_stop_receive(receive_frame); } else { @@ -391,7 +460,7 @@ static rt_err_t rt_link_short_handle(struct rt_link_frame *receive_frame) return 0; } -static void _long_handle_first(struct rt_link_frame *receive_frame, rt_uint8_t *count_mask) +static void _long_handle_first(struct rt_link_frame *receive_frame) { if (receive_frame->extend.parameter % RT_LINK_MAX_DATA_LENGTH == 0) { @@ -406,22 +475,22 @@ static void _long_handle_first(struct rt_link_frame *receive_frame, rt_uint8_t * rt_link_scb->rx_record.dataspace = rt_malloc(receive_frame->extend.parameter); if (rt_link_scb->rx_record.dataspace == RT_NULL) { - LOG_W("long data %dB alloc failed.", receive_frame->extend.parameter); + LOG_W("long data (%dB) alloc failed.", receive_frame->extend.parameter); } - } -static void _long_handle_second(struct rt_link_frame *receive_frame, rt_uint8_t count_mask) +static void _long_handle_second(struct rt_link_frame *receive_frame) { static rt_uint8_t ack_mask = RT_LINK_ACK_MAX; - - void *data = RT_NULL; - rt_size_t size = 0; - rt_uint16_t serve = 0; rt_size_t offset = 0; /* offset, count from 0 */ receive_frame->index = rt_link_check_seq(receive_frame->head.sequence, rt_link_scb->rx_record.rx_seq) - 1; - LOG_D("index= %d, count= 0x%x, seq(%d), rxseq(%d)", receive_frame->index, rt_link_scb->rx_record.long_count, receive_frame->head.sequence, rt_link_scb->rx_record.rx_seq); + LOG_D("seq(%d), rxseq(%d), index(%d), total(%d), count(0x%x)" + , receive_frame->head.sequence + , rt_link_scb->rx_record.rx_seq + , receive_frame->index + , receive_frame->total + , rt_link_scb->rx_record.long_count); if ((receive_frame->index > RT_LINK_FRAMES_MAX) || (rt_link_scb->rx_record.long_count & (0x01 << receive_frame->index))) { @@ -429,51 +498,41 @@ static void _long_handle_second(struct rt_link_frame *receive_frame, rt_uint8_t } else if (rt_link_scb->rx_record.dataspace != RT_NULL) { - LOG_D("long_count (0x%02x)index(%d)total(%d) seq(%d)", rt_link_scb->rx_record.long_count, receive_frame->index, receive_frame->total, receive_frame->head.sequence); rt_link_scb->rx_record.long_count |= (0x01 << receive_frame->index); offset = RT_LINK_MAX_DATA_LENGTH * receive_frame->index; - - rt_enter_critical(); rt_link_hw_copy(rt_link_scb->rx_record.dataspace + offset, receive_frame->real_data, receive_frame->data_len); - rt_exit_critical(); - if (rt_link_utils_num1(rt_link_scb->rx_record.long_count) == rt_link_scb->rx_record.total) - { - rt_link_command_frame_send((rt_link_scb->rx_record.rx_seq + rt_link_scb->rx_record.total), RT_LINK_CONFIRM_FRAME, RT_NULL); - } - else if ((rt_link_scb->rx_record.long_count & ack_mask) == ack_mask) + if (receive_frame->head.ack) { - rt_link_command_frame_send((rt_link_scb->rx_record.rx_seq + rt_link_utils_num1(ack_mask)), RT_LINK_CONFIRM_FRAME, RT_NULL); - ack_mask |= ack_mask << rt_link_utils_num1(RT_LINK_ACK_MAX); + if (rt_link_utils_num1(rt_link_scb->rx_record.long_count) == rt_link_scb->rx_record.total) + { + rt_link_command_frame_send(receive_frame->head.service, + (rt_link_scb->rx_record.rx_seq + rt_link_scb->rx_record.total), + RT_LINK_CONFIRM_FRAME, RT_NULL); + } + else if ((rt_link_scb->rx_record.long_count & ack_mask) == ack_mask) + { + rt_link_command_frame_send(receive_frame->head.service, + (rt_link_scb->rx_record.rx_seq + rt_link_utils_num1(ack_mask)), + RT_LINK_CONFIRM_FRAME, RT_NULL); + ack_mask |= ack_mask << rt_link_utils_num1(RT_LINK_ACK_MAX); + } } /* receive a complete package */ if (rt_link_utils_num1(rt_link_scb->rx_record.long_count) == rt_link_scb->rx_record.total) { rt_timer_stop(&rt_link_scb->longframetimer); + rt_link_recv_finish(receive_frame->head.service, rt_link_scb->rx_record.dataspace, receive_frame->extend.parameter); rt_enter_critical(); - data = rt_link_scb->rx_record.dataspace; - size = receive_frame->extend.parameter; - serve = receive_frame->head.channel; /* empty rx_record */ rt_link_scb->rx_record.rx_seq += rt_link_scb->rx_record.total; rt_link_scb->rx_record.dataspace = RT_NULL; rt_link_scb->rx_record.long_count = 0; rt_link_scb->rx_record.total = 0; ack_mask = RT_LINK_ACK_MAX; - rt_link_frame_stop_receive(receive_frame); rt_exit_critical(); - - if (rt_link_scb->channel[serve].upload_callback == RT_NULL) - { - rt_free(data); - LOG_E("channel %d haven't been registered.", serve); - } - else - { - rt_link_scb->channel[serve].upload_callback(data, size); - } } else if (rt_link_hw_recv_len(rt_link_scb->rx_buffer) < (receive_frame->data_len % RT_LINK_MAX_DATA_LENGTH)) { @@ -486,20 +545,19 @@ static void _long_handle_second(struct rt_link_frame *receive_frame, rt_uint8_t static rt_err_t rt_link_long_handle(struct rt_link_frame *receive_frame) { - static rt_uint8_t count_mask = 0; if (rt_link_scb->rx_record.long_count == 0) { /* Receive this long package for the first time: * calculates the total number of frames, * requests space, and turns on the receive timer */ - _long_handle_first(receive_frame, &count_mask); + _long_handle_first(receive_frame); } if (rt_link_scb->rx_record.total > 0) { /* Intermediate frame processing: * serial number repeated check, * receive completion check, reply to ACK */ - _long_handle_second(receive_frame, count_mask); + _long_handle_second(receive_frame); } receive_frame->real_data = RT_NULL; return RT_EOK; @@ -507,13 +565,41 @@ static rt_err_t rt_link_long_handle(struct rt_link_frame *receive_frame) static rt_err_t rt_link_handshake_handle(struct rt_link_frame *receive_frame) { - LOG_D("Sequence(%d) is a connect handshake frame.", receive_frame->head.sequence); - rt_link_scb->link_status = RT_LINK_CONNECT_DONE; + LOG_D("HANDSHAKE: seq(%d) param(%d)", receive_frame->head.sequence, receive_frame->extend.parameter); + rt_link_scb->state = RT_LINK_CONNECT; /* sync requester tx seq, responder rx seq = requester tx seq */ rt_link_scb->rx_record.rx_seq = receive_frame->head.sequence; /* sync requester rx seq, responder tx seq = requester rx seq */ rt_link_scb->tx_seq = receive_frame->extend.parameter; - rt_link_command_frame_send(receive_frame->head.sequence, RT_LINK_CONFIRM_FRAME, RT_NULL); + + if (rt_link_scb->service[receive_frame->head.service] != RT_NULL) + { + rt_link_scb->service[receive_frame->head.service]->state = RT_LINK_CONNECT; + rt_link_command_frame_send(receive_frame->head.service, + receive_frame->head.sequence, + RT_LINK_CONFIRM_FRAME, RT_NULL); + } + else + { + rt_link_command_frame_send(receive_frame->head.service, + receive_frame->head.sequence, + RT_LINK_DETACH_FRAME, RT_NULL); + } + return RT_EOK; +} + +static rt_err_t rt_link_detach_handle(struct rt_link_frame *receive_frame) +{ + if (rt_link_scb->service[receive_frame->head.service] != RT_NULL) + { + rt_link_scb->service[receive_frame->head.service]->state = RT_LINK_DISCONN; + } + return RT_EOK; +} + +static rt_err_t rt_link_session_end_handle(struct rt_link_frame *receive_frame) +{ + rt_link_frame_stop_receive(receive_frame); return RT_EOK; } @@ -528,40 +614,27 @@ static rt_err_t rt_link_parse_frame(struct rt_link_frame *receive_frame) case RT_LINK_CONFIRM_FRAME: rt_link_confirm_handle(receive_frame); break; - case RT_LINK_SHORT_DATA_FRAME: - rt_link_short_handle(receive_frame); - break; - case RT_LINK_LONG_DATA_FRAME: - rt_link_long_handle(receive_frame); - break; case RT_LINK_HANDSHAKE_FRAME: rt_link_handshake_handle(receive_frame); break; case RT_LINK_SESSION_END: - rt_link_frame_stop_receive(receive_frame); + rt_link_session_end_handle(receive_frame); break; - default: + case RT_LINK_DETACH_FRAME: + rt_link_detach_handle(receive_frame); break; - } - return RT_EOK; -} -/* Empty the sending list */ -static void rt_link_datalist_empty(void) -{ - struct rt_link_frame *find_frame = RT_NULL; - rt_slist_t *tem_list = rt_slist_first(&rt_link_scb->tx_data_slist); - while (tem_list != RT_NULL) - { - find_frame = rt_container_of(tem_list, struct rt_link_frame, slist); - tem_list = rt_slist_next(tem_list); - rt_enter_critical(); - rt_slist_remove(&rt_link_scb->tx_data_slist, &find_frame->slist); - rt_exit_critical(); + case RT_LINK_SHORT_DATA_FRAME: + rt_link_short_handle(receive_frame); + break; + case RT_LINK_LONG_DATA_FRAME: + rt_link_long_handle(receive_frame); + break; - find_frame->real_data = RT_NULL; - rt_link_frame_free(find_frame); + default: + return -RT_ERROR; } + return RT_EOK; } /* RT_LINK_READ_CHECK_EVENT handle */ @@ -574,7 +647,6 @@ static void rt_link_frame_check(void) struct rt_link_frame *send_frame = RT_NULL; rt_tick_t timeout = 0; - rt_uint8_t *real_data = RT_NULL; rt_uint32_t temporary_crc = 0; rt_uint8_t offset = 0; @@ -599,7 +671,7 @@ static void rt_link_frame_check(void) { if (recv_len < buff_len) { - LOG_D("The length is not enough,recv=%d buff=%d", recv_len, buff_len); + LOG_D("HEAD: actual: %d, need: %d.", recv_len, buff_len); return ; } /* Data is an offset address */ @@ -607,16 +679,32 @@ static void rt_link_frame_check(void) rt_link_frame_init(&receive_frame, RT_NULL); rt_link_hw_copy((rt_uint8_t *)&receive_frame.head, data, sizeof(struct rt_link_frame_head)); rt_link_hw_buffer_point_shift(&data, sizeof(struct rt_link_frame_head)); + + LOG_D("HEAD: seq(%d) serv(%d) ack(%d) crc(%d) ext(%d) len(%d) attr(%d)(0x%x)" + , receive_frame.head.sequence + , receive_frame.head.service + , receive_frame.head.ack + , receive_frame.head.crc + , receive_frame.head.extend + , receive_frame.head.length + , receive_frame.extend.attribute + , receive_frame.extend.parameter); + receive_frame.data_len = receive_frame.head.length; - LOG_D("check seq(%d) data len(%d).", receive_frame.head.sequence, receive_frame.data_len); + if (receive_frame.head.service >= RT_LINK_SERVICE_MAX) + { + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1); + goto __find_head; + } if (receive_frame.head.extend) { - buff_len += RT_LINK_MAX_EXTEND_LENGTH; + buff_len += RT_LINK_EXTEND_LENGTH; analysis_status = PARSE_FRAME_EXTEND; } else { + receive_frame.attribute = RT_LINK_SHORT_DATA_FRAME; analysis_status = PARSE_FRAME_SEQ; } } @@ -627,54 +715,38 @@ static void rt_link_frame_check(void) { if (recv_len < buff_len) { - LOG_D("PARSE_FRAME_EXTEND: actual: %d, need: %d.", recv_len, buff_len); - + LOG_D("EXTEND: actual: %d, need: %d.", recv_len, buff_len); /* should set timer, control receive frame timeout, one shot */ timeout = 50; rt_timer_control(&rt_link_scb->recvtimer, RT_TIMER_CTRL_SET_TIME, &timeout); rt_timer_start(&rt_link_scb->recvtimer); return; } + rt_timer_stop(&rt_link_scb->recvtimer); rt_link_hw_copy((rt_uint8_t *)&receive_frame.extend, data, sizeof(struct rt_link_extend)); rt_link_hw_buffer_point_shift(&data, sizeof(struct rt_link_extend)); - switch (receive_frame.extend.attribute) + if (receive_frame.extend.attribute < RT_LINK_RESERVE_FRAME) { - case RT_LINK_RESEND_FRAME: - case RT_LINK_LONG_DATA_FRAME: - case RT_LINK_HANDSHAKE_FRAME: receive_frame.attribute = receive_frame.extend.attribute; - break; - default: - receive_frame.attribute = RT_LINK_RESERVE_FRAME; - break; - } - } - else - { - if (receive_frame.head.crc) - { - receive_frame.attribute = RT_LINK_SHORT_DATA_FRAME; } else { - receive_frame.attribute = RT_LINK_CONFIRM_FRAME; + LOG_D("EXTEND: attr(%d) err", receive_frame.extend.attribute); + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1); + goto __find_head; } } - if (receive_frame.attribute == RT_LINK_RESERVE_FRAME) - { - LOG_D("quick filter error frame."); - rt_link_frame_stop_receive(&receive_frame); - buff_len = RT_LINK_HEAD_LENGTH; - analysis_status = FIND_FRAME_HEAD; - break; - } analysis_status = PARSE_FRAME_SEQ; } case PARSE_FRAME_SEQ: { - if ((receive_frame.attribute == RT_LINK_CONFIRM_FRAME) || (receive_frame.attribute == RT_LINK_RESEND_FRAME)) + switch (receive_frame.attribute) + { + case RT_LINK_CONFIRM_FRAME: + case RT_LINK_RESEND_FRAME: { + /* Check the send sequence */ offset = rt_link_check_seq(receive_frame.head.sequence, rt_link_scb->tx_seq); if (rt_slist_first(&rt_link_scb->tx_data_slist) != RT_NULL) { @@ -683,27 +755,36 @@ static void rt_link_frame_check(void) { /* exceptional frame, ignore it */ LOG_D("seq (%d) failed, tx_seq (%d).offset=(%d) total= (%d)", receive_frame.head.sequence, rt_link_scb->tx_seq, offset, send_frame->total); - rt_link_frame_stop_receive(&receive_frame); - buff_len = RT_LINK_HEAD_LENGTH; - analysis_status = FIND_FRAME_HEAD; - break; + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1); + goto __find_head; } } + break; } - else + case RT_LINK_LONG_DATA_FRAME: + case RT_LINK_SHORT_DATA_FRAME: + case RT_LINK_SESSION_END: { + /* Check the receive sequence */ offset = rt_link_check_seq(receive_frame.head.sequence, rt_link_scb->rx_record.rx_seq) - 1; - if ((offset > RT_LINK_FRAMES_MAX) && (receive_frame.attribute != RT_LINK_HANDSHAKE_FRAME)) + if (offset > RT_LINK_FRAMES_MAX) { /* exceptional frame, ignore it */ - LOG_D("seq (%d) failed, rx_seq (%d) offset=(%d) attr= (%d) status (%d)", receive_frame.head.sequence, rt_link_scb->rx_record.rx_seq, offset, receive_frame.attribute, rt_link_scb->link_status); - rt_link_frame_stop_receive(&receive_frame); - buff_len = RT_LINK_HEAD_LENGTH; - analysis_status = FIND_FRAME_HEAD; - break; + LOG_D("seq (%d) failed, rx_seq (%d) offset=(%d) attr= (%d) status (%d)", receive_frame.head.sequence, rt_link_scb->rx_record.rx_seq, offset, receive_frame.attribute, rt_link_scb->state); + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1); + goto __find_head; } } + case RT_LINK_HANDSHAKE_FRAME: + case RT_LINK_DETACH_FRAME: + analysis_status = HEADLE_FRAME_DATA; + break; + default: + LOG_D("quick filter error frame."); + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1); + goto __find_head; + } buff_len += receive_frame.data_len; if (receive_frame.head.crc) { @@ -714,6 +795,8 @@ static void rt_link_frame_check(void) { analysis_status = HEADLE_FRAME_DATA; } + /* fill real data point */ + receive_frame.real_data = data; } case CHECK_FRAME_CRC: @@ -722,6 +805,7 @@ static void rt_link_frame_check(void) { if (recv_len < buff_len) { + LOG_D("CRC: actual: %d, need: %d.", recv_len, buff_len); /* should set timer, control receive frame timeout, one shot */ timeout = 50; rt_timer_control(&rt_link_scb->recvtimer, RT_TIMER_CTRL_SET_TIME, &timeout); @@ -729,7 +813,6 @@ static void rt_link_frame_check(void) return; } - real_data = data; rt_timer_stop(&rt_link_scb->recvtimer); rt_link_hw_buffer_point_shift(&data, receive_frame.data_len); rt_link_hw_copy((rt_uint8_t *)&receive_frame.crc, data, RT_LINK_CRC_LENGTH); @@ -738,25 +821,28 @@ static void rt_link_frame_check(void) { /* check failed. ready resent */ LOG_D("CRC: calc:(0x%08x) ,recv:(0x%08x).", temporary_crc, receive_frame.crc); - /* quick resent, when sequence is right, we can ask for reset this frame */ - rt_link_command_frame_send(receive_frame.head.sequence, RT_LINK_RESEND_FRAME, RT_NULL); - - /* throw the error frame */ - buff_len = RT_LINK_HEAD_LENGTH; - rt_link_frame_stop_receive(&receive_frame); - - /* clear the frame information */ - analysis_status = FIND_FRAME_HEAD; - break; + rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1); + goto __find_head; } - /* fill real data point */ - receive_frame.real_data = real_data; } analysis_status = HEADLE_FRAME_DATA; } case HEADLE_FRAME_DATA: { + if (recv_len < buff_len) + { + LOG_D("PARSE: actual: %d, need: %d.", recv_len, buff_len); + /* should set timer, control receive frame timeout, one shot */ + timeout = 50; + rt_timer_control(&rt_link_scb->recvtimer, RT_TIMER_CTRL_SET_TIME, &timeout); + rt_timer_start(&rt_link_scb->recvtimer); + return; + } + LOG_D("PARSE: buff_len (%d) r (0x%p) w (0x%p)" + , buff_len, rt_link_scb->rx_buffer->read_point + , rt_link_scb->rx_buffer->write_point); + rt_timer_stop(&rt_link_scb->recvtimer); rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, buff_len); rt_link_parse_frame(&receive_frame); data = RT_NULL; @@ -766,25 +852,47 @@ static void rt_link_frame_check(void) } default: - LOG_E("analysis_status is error."); +__find_head: + LOG_D("to find head (%d)", analysis_status); + rt_link_frame_stop_receive(&receive_frame); + buff_len = RT_LINK_HEAD_LENGTH; + analysis_status = FIND_FRAME_HEAD; break; } + recv_len = rt_link_hw_recv_len(rt_link_scb->rx_buffer); } } static void rt_link_send_ready(void) { - if (rt_link_scb->link_status != RT_LINK_CONNECT_DONE) + struct rt_link_frame *frame = RT_NULL; + rt_uint8_t seq = rt_link_scb->tx_seq; + if (rt_slist_next(&rt_link_scb->tx_data_slist)) + { + frame = rt_container_of(rt_slist_next(&rt_link_scb->tx_data_slist), struct rt_link_frame, slist); + } + + if (rt_link_scb->state != RT_LINK_CONNECT) { - rt_link_scb->link_status = RT_LINK_NO_RESPONSE; - rt_link_command_frame_send(rt_link_scb->tx_seq, RT_LINK_HANDSHAKE_FRAME, rt_link_scb->rx_record.rx_seq); + rt_link_scb->state = RT_LINK_DISCONN; + rt_link_command_frame_send(RT_LINK_SERVICE_RTLINK, seq, + RT_LINK_HANDSHAKE_FRAME, rt_link_scb->rx_record.rx_seq); + + rt_int32_t timeout = 50; + rt_timer_control(&rt_link_scb->sendtimer, RT_TIMER_CTRL_SET_TIME, &timeout); + rt_timer_start(&rt_link_scb->sendtimer); } else { - if (RT_EOK != rt_link_frame_send(&rt_link_scb->tx_data_slist)) + /* Avoid sending the first data frame multiple times */ + if ((frame != RT_NULL) && (frame->issent == RT_LINK_FRAME_NOSEND)) { - rt_event_send(&rt_link_scb->event, RT_LINK_SEND_FAILED_EVENT); + if (RT_EOK != rt_link_frame_send(&rt_link_scb->tx_data_slist)) + { + rt_link_scb->state = RT_LINK_DISCONN; + rt_link_service_send_finish(RT_LINK_EIO); + } } } } @@ -797,41 +905,51 @@ static void rt_link_frame_recv_timeout(void) static void rt_link_send_timeout(void) { - static rt_uint8_t count = 0; - if (count++ > 5) + LOG_D("send count(%d)", (rt_uint32_t)rt_link_scb->sendtimer.parameter); + if ((rt_uint32_t)rt_link_scb->sendtimer.parameter >= 5) { + rt_timer_stop(&rt_link_scb->sendtimer); LOG_W("Send timeout, please check the link status!"); - count = 0; - rt_event_send(&rt_link_scb->event, RT_LINK_SEND_FAILED_EVENT); + rt_link_scb->sendtimer.parameter = 0x00; + rt_link_service_send_finish(RT_LINK_ETIMEOUT); } else { - rt_timer_start(&rt_link_scb->sendtimer); - rt_link_command_frame_send(rt_link_scb->tx_seq, RT_LINK_HANDSHAKE_FRAME, rt_link_scb->rx_record.rx_seq); + if (rt_slist_next(&rt_link_scb->tx_data_slist)) + { + struct rt_link_frame *frame = rt_container_of(rt_slist_next(&rt_link_scb->tx_data_slist), struct rt_link_frame, slist); + frame->issent = RT_LINK_FRAME_NOSEND; + rt_link_command_frame_send(RT_LINK_SERVICE_RTLINK, + frame->head.sequence, + RT_LINK_HANDSHAKE_FRAME, + rt_link_scb->rx_record.rx_seq); + } } } -static int rt_link_long_recv_timeout(void) +static void rt_link_long_recv_timeout(void) { - static rt_uint8_t count = 0; - if (count++ > 5) + if ((rt_uint32_t)rt_link_scb->longframetimer.parameter >= 5) { LOG_W("long package receive timeout"); - count = 0; + rt_link_scb->longframetimer.parameter = 0x00; _stop_recv_long(); + rt_timer_stop(&rt_link_scb->longframetimer); } else { - for (rt_uint8_t total = rt_link_scb->rx_record.total; total > 0; total--) + rt_uint8_t total = rt_link_scb->rx_record.total; + for (; total > 0; total--) { if (((rt_link_scb->rx_record.long_count >> (total - 1)) & 0x01) == 0x00) { /* resend command */ - rt_link_command_frame_send((rt_link_scb->rx_record.rx_seq + total), RT_LINK_RESEND_FRAME, RT_NULL); + rt_link_command_frame_send(RT_LINK_SERVICE_RTLINK, + (rt_link_scb->rx_record.rx_seq + total), + RT_LINK_RESEND_FRAME, RT_NULL); } } } - return RT_EOK; } void rt_link_thread(void *parameter) @@ -839,7 +957,8 @@ void rt_link_thread(void *parameter) rt_uint32_t recved = 0; while (1) { - rt_event_recv(&rt_link_scb->event, RT_LINK_READ_CHECK_EVENT | + rt_event_recv(&rt_link_scb->event, + RT_LINK_READ_CHECK_EVENT | RT_LINK_SEND_READY_EVENT | RT_LINK_SEND_TIMEOUT_EVENT | RT_LINK_RECV_TIMEOUT_FRAME_EVENT | @@ -877,6 +996,8 @@ void rt_link_thread(void *parameter) static void rt_link_sendtimer_callback(void *parameter) { + rt_uint32_t count = (rt_uint32_t)rt_link_scb->sendtimer.parameter + 1; + rt_link_scb->sendtimer.parameter = (void *)count; rt_event_send(&rt_link_scb->event, RT_LINK_SEND_TIMEOUT_EVENT); } @@ -887,34 +1008,38 @@ static void rt_link_recvtimer_callback(void *parameter) static void rt_link_receive_long_frame_callback(void *parameter) { + rt_uint32_t count = (rt_uint32_t)rt_link_scb->longframetimer.parameter + 1; + rt_link_scb->longframetimer.parameter = (void *)count; rt_event_send(&rt_link_scb->event, RT_LINK_RECV_TIMEOUT_LONG_EVENT); } /** * rtlink send data interface - * @param service Registered service channel, choose enum rt_link_service_t + * @param service Registered service channel, struct rt_link_service * @param data send data * @param size send data size * @return The actual size of the data sent * */ -rt_size_t rt_link_send(rt_link_service_t service, void *data, rt_size_t size) +rt_size_t rt_link_send(struct rt_link_service *service, const void *data, rt_size_t size) { - if ((size == 0) || (data == RT_NULL) || (service >= RT_LINK_SERVICE_MAX)) - { - return 0; - } - rt_mutex_take(&rt_link_scb->tx_lock, RT_WAITING_FOREVER); + RT_ASSERT(service != RT_NULL); rt_uint32_t recved = 0; - rt_err_t result = RT_EOK; - rt_uint32_t timeout = 0; - rt_uint8_t total = 0; /* The total number of frames to send */ rt_uint8_t index = 0; /* The index of the split packet */ rt_size_t offset = 0; /* The offset of the send data */ + rt_size_t send_len = 0; struct rt_link_frame *send_frame = RT_NULL; - rt_link_frame_attribute_t attribute; + rt_link_frame_attr_e attribute = RT_LINK_SHORT_DATA_FRAME; + + if ((size == 0) || (data == RT_NULL)) + { + service->err = RT_LINK_ERR; + goto __exit; + } + + service->err = RT_LINK_EOK; if (size % RT_LINK_MAX_DATA_LENGTH == 0) { total = size / RT_LINK_MAX_DATA_LENGTH; @@ -926,24 +1051,25 @@ rt_size_t rt_link_send(rt_link_service_t service, void *data, rt_size_t size) if (total > RT_LINK_FRAMES_MAX) { - result = -RT_ENOMEM; + service->err = RT_LINK_ENOMEM; goto __exit; } else if (total > 1) { attribute = RT_LINK_LONG_DATA_FRAME; } - else - { - attribute = RT_LINK_SHORT_DATA_FRAME; - } do { send_frame = rt_malloc(sizeof(struct rt_link_frame)); - rt_link_frame_init(send_frame, FRAME_CRC | FRAME_ACK); - send_frame->head.sequence = rt_link_scb->tx_seq + 1 + index; - send_frame->head.channel = service; + if (send_frame == RT_NULL) + { + service->err = RT_LINK_ENOMEM; + goto __exit; + } + rt_link_frame_init(send_frame, service->flag); + send_frame->head.sequence = ++rt_link_scb->tx_seq; + send_frame->head.service = service->service; send_frame->real_data = (rt_uint8_t *)data + offset; send_frame->index = index; send_frame->total = total; @@ -970,53 +1096,39 @@ rt_size_t rt_link_send(rt_link_service_t service, void *data, rt_size_t size) } /* append the frame on the tail of list */ - LOG_D("new data append on the send slist, seq(%d), len(%d).", send_frame->head.sequence, send_frame->data_len); + LOG_D("append send slist, seq(%d), len(%d)", send_frame->head.sequence, send_frame->data_len); rt_slist_append(&rt_link_scb->tx_data_slist, &send_frame->slist); index++; + send_len += send_frame->data_len; }while(total > index); - timeout = RT_LINK_SENT_FRAME_TIMEOUT * total; - rt_timer_control(&rt_link_scb->sendtimer, RT_TIMER_CTRL_SET_TIME, &timeout); - rt_timer_start(&rt_link_scb->sendtimer); /* Notify the core thread to send packet */ rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT); - /* Wait for the packet to be sent successfully */ - rt_event_recv(&rt_link_scb->event, RT_LINK_SEND_OK_EVENT | RT_LINK_SEND_FAILED_EVENT, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved); - - if (recved & RT_LINK_SEND_OK_EVENT) - { - result = RT_EOK; - } - else if (recved & RT_LINK_SEND_FAILED_EVENT) + if (service->timeout_tx != RT_WAITING_NO) { - LOG_E("the data (%dB) send failed", size); - result = -RT_ERROR; - } - else - { - LOG_E("unexpected event."); - result = -RT_ERROR; + /* Wait for the packet to send the result */ + rt_err_t ret = rt_event_recv(&rt_link_scb->sendevent, (0x01 << service->service), + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + service->timeout_tx, &recved); + if (ret == -RT_ETIMEOUT) + { + service->err = RT_LINK_ETIMEOUT; + send_len = 0; + } } + __exit: - rt_timer_stop(&rt_link_scb->sendtimer); - /* Empty the sending list */ - rt_link_datalist_empty(); - rt_mutex_release(&rt_link_scb->tx_lock); - if (result == RT_EOK) - { - return size; - } - return result; + return send_len; } void rtlink_status(void) { - rt_kprintf("rtlink status:\n"); + rt_kprintf("rtlink(v%s) status:\n", RT_LINK_VER); if (rt_link_scb != RT_NULL) { - rt_kprintf("\tlink status=%d\n", rt_link_scb->link_status); + rt_kprintf("\tlink status=%d\n", rt_link_scb->state); rt_kprintf("\trx seq=%d\n", rt_link_scb->rx_record.rx_seq); rt_kprintf("\ttx seq=%d\n", rt_link_scb->tx_seq); @@ -1034,7 +1146,7 @@ void rtlink_status(void) rt_slist_t *data = RT_NULL; rt_slist_for_each(data, &rt_link_scb->tx_data_slist) { - rt_kprintf("\tsend data list: serv %u\t", ((struct rt_link_frame_head *)data)->channel); + rt_kprintf("\tsend data list: serv %u\t", ((struct rt_link_frame_head *)data)->service); rt_kprintf(" seq %u\t", ((struct rt_link_frame_head *)data)->sequence); rt_kprintf(" len %u\n", ((struct rt_link_frame_head *)data)->length); } @@ -1044,10 +1156,10 @@ void rtlink_status(void) rt_kprintf("\tsend data list: NULL\n"); } - rt_uint8_t serv = sizeof(rt_link_scb->channel) / sizeof(struct rt_link_service); + rt_uint8_t serv = RT_LINK_SERVICE_MAX - 1; while (serv--) { - rt_kprintf("\tservices [%d](0x%p)\n", serv, rt_link_scb->channel[serv]); + rt_kprintf("\tservices [%d](0x%p)\n", serv, rt_link_scb->service[serv]); } } else @@ -1069,7 +1181,6 @@ rt_err_t rt_link_deinit(void) rt_timer_detach(&rt_link_scb->longframetimer); rt_timer_detach(&rt_link_scb->sendtimer); rt_timer_detach(&rt_link_scb->recvtimer); - rt_mutex_detach(&rt_link_scb->tx_lock); rt_event_detach(&rt_link_scb->event); rt_free(rt_link_scb); rt_link_scb = RT_NULL; @@ -1106,10 +1217,12 @@ int rt_link_init(void) } rt_memset(rt_link_scb, 0, sizeof(struct rt_link_session)); - rt_event_init(&rt_link_scb->event, "lny_event", RT_IPC_FLAG_FIFO); + rt_event_init(&rt_link_scb->event, "rtlink", RT_IPC_FLAG_FIFO); rt_event_control(&rt_link_scb->event, RT_IPC_CMD_RESET, RT_NULL); - rt_mutex_init(&rt_link_scb->tx_lock, "tx_lock", RT_IPC_FLAG_FIFO); + rt_event_init(&rt_link_scb->sendevent, "send_rtlink", RT_IPC_FLAG_FIFO); + rt_event_control(&rt_link_scb->sendevent, RT_IPC_CMD_RESET, RT_NULL); + rt_timer_init(&rt_link_scb->sendtimer, "tx_time", rt_link_sendtimer_callback, RT_NULL, 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_PERIODIC); rt_timer_init(&rt_link_scb->recvtimer, "rx_time", rt_link_recvtimer_callback, @@ -1117,8 +1230,6 @@ int rt_link_init(void) rt_timer_init(&rt_link_scb->longframetimer, "rxl_time", rt_link_receive_long_frame_callback, RT_NULL, 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_PERIODIC); - rt_link_scb->link_status = RT_LINK_ESTABLISHING; - rt_link_scb->rx_record.rx_seq = 255; rt_slist_init(&rt_link_scb->tx_data_slist); @@ -1137,8 +1248,8 @@ int rt_link_init(void) goto __exit; } rt_thread_startup(thread); - result = rt_link_hw_init(); + rt_link_scb->state = RT_LINK_INIT; __exit: if (result != RT_EOK) { @@ -1147,7 +1258,7 @@ __exit: } else { - LOG_I("rtlink init success."); + LOG_I("rtlink init success(VER:%s).", RT_LINK_VER); } return result; } @@ -1158,35 +1269,52 @@ MSH_CMD_EXPORT(rt_link_init, rt link init); /** * rtlink service attach - * @param service Registered service channel, choose enum rt_link_service_t - * @param function receive callback function + * @param service Registered service channel, struct rt_link_service * @return Function Execution Result * */ -rt_err_t rt_link_service_attach(rt_link_service_t service, rt_err_t (*function)(void *data, rt_size_t size)) +rt_err_t rt_link_service_attach(struct rt_link_service *serv) { - if (service >= RT_LINK_SERVICE_MAX) + RT_ASSERT(serv != RT_NULL); + if (serv->service >= RT_LINK_SERVICE_MAX) { LOG_W("Invalid parameter."); - return -RT_ERROR; + return -RT_EINVAL; } - rt_link_scb->channel[service].upload_callback = function; - LOG_I("rt link attach service[%02d].", service); + rt_uint8_t seq = rt_link_scb->tx_seq; + rt_link_hw_init(); + rt_link_scb->service[serv->service] = serv; + serv->state = RT_LINK_INIT; + LOG_I("rt link attach service[%02d].", serv->service); + + if (rt_slist_next(&rt_link_scb->tx_data_slist)) + { + struct rt_link_frame *frame = rt_container_of(rt_slist_next(&rt_link_scb->tx_data_slist), struct rt_link_frame, slist); + seq = frame->head.sequence; + } + rt_link_command_frame_send(serv->service, seq, RT_LINK_HANDSHAKE_FRAME, rt_link_scb->rx_record.rx_seq); return RT_EOK; } /** * rtlink service detach - * @param service Registered service channel, choose enum rt_link_service_t + * @param service Registered service channel, struct rt_link_service * @return rt_err_t Function Execution Result * */ -rt_err_t rt_link_service_detach(rt_link_service_t service) +rt_err_t rt_link_service_detach(struct rt_link_service *serv) { - if (service >= RT_LINK_SERVICE_MAX) + RT_ASSERT(serv != RT_NULL); + if (serv->service >= RT_LINK_SERVICE_MAX) { LOG_W("Invalid parameter."); - return -RT_ERROR; + return -RT_EINVAL; } - rt_link_scb->channel[service].upload_callback = RT_NULL; - LOG_I("rt link detach service[%02d].", service); + rt_link_command_frame_send(serv->service, + rt_link_scb->tx_seq, + RT_LINK_DETACH_FRAME, + rt_link_scb->rx_record.rx_seq); + + serv->state = RT_LINK_DISCONN; + rt_link_scb->service[serv->service] = RT_NULL; + LOG_I("rt link detach service[%02d].", serv->service); return RT_EOK; } diff --git a/components/utilities/rt-link/src/rtlink_dev.c b/components/utilities/rt-link/src/rtlink_dev.c new file mode 100644 index 0000000000..5eff1f9782 --- /dev/null +++ b/components/utilities/rt-link/src/rtlink_dev.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-15 Sherman the first version + */ + +#define DBG_TAG "RTLINK_DEV" +#define DBG_LVL DBG_LOG +#include + +#include +#include +#include +#include + +#define RTLINK_SERV(dev) (((struct rt_link_device*)dev)->service) + +#ifdef RT_USING_POSIX +#include +#include + +int rtlink_fops_open(struct dfs_fd *fd) +{ + rt_uint16_t flags = 0; + rt_device_t device; + + switch (fd->flags & O_ACCMODE) + { + case O_RDONLY: + LOG_D("fops open: O_RDONLY!"); + flags = RT_DEVICE_FLAG_RDONLY; + break; + case O_WRONLY: + LOG_D("fops open: O_WRONLY!"); + flags = RT_DEVICE_FLAG_WRONLY; + break; + case O_RDWR: + LOG_D("fops open: O_RDWR!"); + flags = RT_DEVICE_FLAG_RDWR; + break; + default: + LOG_E("fops open: unknown mode - %d!", fd->flags & O_ACCMODE); + break; + } + + device = (rt_device_t)fd->data; + if (fd->flags & O_NONBLOCK) + { + rt_device_control(device, RT_LINK_TX_NONBLOCKING | RT_LINK_RX_NONBLOCKING, RT_NULL); + } + + return rt_device_open(device, flags); +} + +int rtlink_fops_close(struct dfs_fd *fd) +{ + rt_device_t device; + device = (rt_device_t)fd->data; + + rt_device_set_rx_indicate(device, RT_NULL); + return rt_device_close(device); +} + +int rtlink_fops_ioctl(struct dfs_fd *fd, int cmd, void *args) +{ + rt_device_t device; + device = (rt_device_t)fd->data; + + if (cmd == O_NONBLOCK) + { + return rt_device_control(device, RT_LINK_TX_NONBLOCKING | RT_LINK_RX_NONBLOCKING, RT_NULL); + } + else + { + return rt_device_control(device, cmd, args); + } +} + +int rtlink_fops_read(struct dfs_fd *fd, void *buf, size_t count) +{ + int size = 0; + rt_device_t device; + device = (rt_device_t)fd->data; + + size = rt_device_read(device, -1, buf, count); + if (size <= 0) + { + size = -EAGAIN; + } + return size; +} + +int rtlink_fops_write(struct dfs_fd *fd, const void *buf, size_t count) +{ + int size = 0; + rt_device_t device; + device = (rt_device_t)fd->data; + + size = rt_device_write(device, -1, buf, count); + if (size <= 0) + { + size = -EAGAIN; + } + return size; +} + +int rtlink_fops_poll(struct dfs_fd *fd, struct rt_pollreq *req) +{ + int mask = 0; + int flags = 0; + rt_device_t device; + struct rt_link_device *rtlink_dev; + + device = (rt_device_t)fd->data; + RT_ASSERT(device != RT_NULL); + + rtlink_dev = (struct rt_link_device *)device; + + flags = fd->flags & O_ACCMODE; + if (flags == O_RDONLY || flags == O_RDWR) + { + rt_base_t level; + rt_poll_add(&(device->wait_queue), req); + + level = rt_hw_interrupt_disable(); + if (RT_NULL != rt_slist_first(&rtlink_dev->recv_head)) + mask |= POLLIN; + rt_hw_interrupt_enable(level); + } + mask |= POLLOUT; + + return mask; +} + +const static struct dfs_file_ops _rtlink_fops = +{ + rtlink_fops_open, + rtlink_fops_close, + rtlink_fops_ioctl, + rtlink_fops_read, + rtlink_fops_write, + RT_NULL, /* flush */ + RT_NULL, /* lseek */ + RT_NULL, /* getdents */ + rtlink_fops_poll, +}; +#endif /* RT_USING_POSIX */ + +/* The event type for the service channel number, + * which is used to wake up the service thread in blocking receive mode */ +struct rt_event recv_event; + +static rt_err_t rt_link_event_send(struct rt_link_service *serv) +{ + RT_ASSERT(serv != RT_NULL); + RT_ASSERT(serv->service < RT_LINK_SERVICE_MAX); + rt_uint32_t set = 0x01 << serv->service; + return rt_event_send(&recv_event, set); +} + +static rt_err_t rt_link_event_recv(struct rt_link_service *service) +{ + RT_ASSERT(service != RT_NULL); + RT_ASSERT(service->service < RT_LINK_SERVICE_MAX); + + rt_uint32_t set = 0x01 << service->service; + rt_uint32_t recved = 0; + rt_err_t ret = rt_event_recv(&recv_event, + set, + RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, + &recved); + if (recved & set) + { + return ret; + } + return RT_ERROR; +} + +static void send_cb(struct rt_link_service *service, void *buffer) +{ + RT_ASSERT(service != RT_NULL); + RT_ASSERT(buffer != RT_NULL); + struct rt_link_device *rtlink = (struct rt_link_device *)service->user_data; + + if (rtlink && rtlink->parent.tx_complete) + { + rtlink->parent.tx_complete(&rtlink->parent, buffer); + } +} + +static void recv_cb(struct rt_link_service *service, void *data, rt_size_t size) +{ + RT_ASSERT(service != RT_NULL); + struct rt_link_device *rtlink = (struct rt_link_device *)service->user_data; + + if (rtlink) + { + struct rtlink_recv_list *node = rt_malloc(sizeof(struct rtlink_recv_list)); + node->data = data; + node->size = size; + node->index = 0; + rt_slist_append(&rtlink->recv_head, &node->list); + rt_link_event_send(service); + + if (rtlink->parent.rx_indicate) + { + rtlink->parent.rx_indicate(&rtlink->parent, size); + } + } + else + { + rt_free(data); + } +} + +rt_err_t rt_link_dev_init(rt_device_t dev) +{ + RT_ASSERT(dev != RT_NULL); + + dev->rx_indicate = RT_NULL; + dev->tx_complete = RT_NULL; + + struct rt_link_device *rtlink = (struct rt_link_device *)dev; + rtlink->service.service = RT_LINK_SERVICE_MAX; + rtlink->service.recv_cb = RT_NULL; + rtlink->service.send_cb = RT_NULL; + rtlink->service.timeout_tx = RT_WAITING_NO; + rtlink->service.user_data = (void *)dev; + + rt_slist_init(&rtlink->recv_head); + return RT_EOK; +} + +rt_err_t rt_link_dev_open(rt_device_t dev, rt_uint16_t oflag) +{ + RT_ASSERT(dev != RT_NULL); + struct rt_link_device *rtlink = (struct rt_link_device *)dev; + + rtlink->service.recv_cb = recv_cb; + rtlink->service.send_cb = send_cb; + + dev->open_flag = oflag & RT_DEVICE_OFLAG_MASK; + if (dev->open_flag == RT_DEVICE_OFLAG_RDONLY) + { + rtlink->service.send_cb = RT_NULL; + } + else if (dev->open_flag == RT_DEVICE_OFLAG_WRONLY) + { + rtlink->service.recv_cb = RT_NULL; + } + return rt_link_service_attach(&rtlink->service); +} + +rt_err_t rt_link_dev_close(rt_device_t dev) +{ + RT_ASSERT(dev != RT_NULL); + struct rt_link_device *rtlink = (struct rt_link_device *)dev; + return rt_link_service_detach(&rtlink->service); +} + +rt_size_t rt_link_dev_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + RT_ASSERT(dev != RT_NULL); + RT_ASSERT(buffer != RT_NULL); + RT_ASSERT(size != 0); + + struct rt_link_device *rtlink = (struct rt_link_device *)dev; + struct rtlink_recv_list *node; + rt_size_t read_len = 0; + rt_size_t unread_len = 0; + + if (dev->rx_indicate == RT_NULL) + { + /* RT_LINK_RX_BLOCKING, wait service receive data event */ + rt_link_event_recv(&rtlink->service); + } + + if (rt_slist_first(&rtlink->recv_head) != RT_NULL) + { + node = rt_container_of(rt_slist_next(&rtlink->recv_head), struct rtlink_recv_list, list); + unread_len = (node->size) - (node->index); + read_len = (size > unread_len) ? unread_len : size; + rt_memcpy(buffer, (rt_uint8_t *)node->data + node->index, read_len); + node->index += read_len; + + if (node->index >= node->size) + { + rt_slist_remove(&rtlink->recv_head, &node->list); + node->index = 0; + rt_free(node->data); + rt_free(node); + } + if (rt_slist_first(&rtlink->recv_head) != RT_NULL) + { + rt_link_event_send(&rtlink->service); + } + } + return read_len; +} + +rt_size_t rt_link_dev_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + RT_ASSERT(dev != RT_NULL); + RT_ASSERT(buffer != RT_NULL); + RT_ASSERT(size != 0); + + return rt_link_send(&RTLINK_SERV(dev), buffer, size); +} + +rt_err_t rt_link_dev_control(rt_device_t dev, int cmd, void *args) +{ + RT_ASSERT(dev != RT_NULL); + + if (cmd & RT_DEVICE_CTRL_CONFIG) + { + if (args == RT_NULL) + return RT_EINVAL; + RTLINK_SERV(dev).service = ((struct rt_link_service *)args)->service; + RTLINK_SERV(dev).timeout_tx = ((struct rt_link_service *)args)->timeout_tx; + RTLINK_SERV(dev).flag = ((struct rt_link_service *)args)->flag; + } + + if (cmd & RT_LINK_RX_BLOCKING) + { + dev->rx_indicate = RT_NULL; + } + if (cmd & RT_LINK_TX_BLOCKING) + { + RTLINK_SERV(dev).timeout_tx = RT_WAITING_FOREVER; + dev->tx_complete = RT_NULL; + } + if (cmd & RT_LINK_TX_NONBLOCKING) + { + RTLINK_SERV(dev).timeout_tx = RT_WAITING_NO; + } + + return RT_EOK; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops rtlink_ops = +{ + rt_link_dev_init, + rt_link_dev_open, + rt_link_dev_close, + rt_link_dev_read, + rt_link_dev_write, + rt_link_dev_control +}; +#endif /* RT_USING_DEVICE_OPS */ + +/* + * rtlink device register + */ +rt_err_t rt_link_dev_register(struct rt_link_device *rtlink, + const char *name, + rt_uint32_t flag, + void *data) +{ + rt_err_t ret; + struct rt_device *device; + RT_ASSERT(rtlink != RT_NULL); + + device = (struct rt_device *)rtlink; + device->type = RT_Device_Class_Char; + device->rx_indicate = RT_NULL; + device->tx_complete = RT_NULL; + +#ifdef RT_USING_DEVICE_OPS + device->ops = &rtlink_ops; +#else + device->init = rt_link_dev_init; + device->open = rt_link_dev_open; + device->close = rt_link_dev_close; + device->read = rt_link_dev_read; + device->write = rt_link_dev_write; + device->control = rt_link_dev_control; +#endif + device->user_data = data; + + /* register a character device */ + ret = rt_device_register(device, name, flag); + +#if defined(RT_USING_POSIX) + /* set fops */ + device->fops = &_rtlink_fops; +#endif + + rt_event_init(&recv_event, "rtlink_dev", RT_IPC_FLAG_FIFO); + return ret; +} diff --git a/components/utilities/rt-link/src/rtlink_hw.c b/components/utilities/rt-link/src/rtlink_hw.c index 9c4567ab63..696ab5b78a 100644 --- a/components/utilities/rt-link/src/rtlink_hw.c +++ b/components/utilities/rt-link/src/rtlink_hw.c @@ -85,18 +85,39 @@ static rt_size_t rt_link_hw_buffer_write(void *data, rt_size_t count) /* increases buffer pointer by one and circle around if necessary */ void rt_link_hw_buffer_point_shift(rt_uint8_t **pointer_address, rt_size_t length) { - rt_uint8_t *pointer = RT_NULL; + rt_uint8_t *pointer = *pointer_address + length; - pointer = *pointer_address + length; - if (pointer >= rx_buffer->end_point) + if (rx_buffer->write_point >= rx_buffer->read_point) { - rt_size_t offset = 0; - offset = pointer - rx_buffer->end_point; - *pointer_address = rx_buffer->data + offset; + if (pointer >= rx_buffer->write_point) + { + *pointer_address = rx_buffer->write_point; + } + else + { + *pointer_address = pointer; + } } else { - *pointer_address = *pointer_address + length; + if (pointer >= rx_buffer->end_point) + { + *pointer_address = rx_buffer->data; + pointer = pointer - rx_buffer->end_point + rx_buffer->data; + + if (pointer >= rx_buffer->write_point) + { + *pointer_address = rx_buffer->write_point; + } + else + { + *pointer_address = pointer; + } + } + else + { + *pointer_address = pointer; + } } } @@ -119,9 +140,13 @@ void rt_link_hw_copy(rt_uint8_t *dst, rt_uint8_t *src, rt_size_t count) } } -/* Tells, how many chars are saved into the buffer */ +/* Length of data received */ rt_size_t rt_link_hw_recv_len(struct rt_link_receive_buffer *buffer) { + if (buffer == RT_NULL) + { + return 0; + } if (buffer->write_point >= buffer->read_point) { return (buffer->write_point - buffer->read_point); @@ -183,15 +208,18 @@ rt_uint32_t rt_link_get_crc(rt_uint8_t using_buffer_ring, rt_uint8_t *data, rt_s return crc32; } -rt_err_t rt_link_hw_send(void *data, rt_size_t length) +rt_size_t rt_link_hw_send(void *data, rt_size_t length) { rt_size_t send_len = 0; send_len = rt_link_port_send(data, length); - LOG_D("hw_send len= %d", send_len); + if (send_len <= 0) + { + rt_link_port_reconnect(); + send_len = rt_link_port_send(data, length); + } return send_len; } -/* provide this function to hardware spi/uart/usb to store data */ rt_size_t rt_link_hw_write_cb(void *data, rt_size_t length) { /* write real data into rtlink receive buffer */ @@ -220,11 +248,17 @@ rt_err_t rt_link_hw_init(void) scb->rx_buffer = rx_buffer; scb->calculate_crc = rt_link_get_crc; - rt_link_port_init(); + if (RT_EOK != rt_link_port_init()) + { + return -RT_ERROR; + } #ifdef LINK_LAYER_USING_HW_CRC /* crc hardware device for mcu and node */ - rt_link_hw_crc32_init(); + if (RT_EOK != rt_link_hw_crc32_init()) + { + return -RT_ERROR; + } #endif LOG_I("link layer hardware environment init successful."); @@ -244,11 +278,17 @@ rt_err_t rt_link_hw_deinit(void) scb->rx_buffer = rx_buffer; scb->calculate_crc = RT_NULL; } - rt_link_port_deinit(); + if (RT_EOK != rt_link_port_deinit()) + { + return -RT_ERROR; + } #ifdef LINK_LAYER_USING_HW_CRC /* crc hardware device for mcu and node */ - rt_link_hw_crc32_deinit(); + if (RT_EOK != rt_link_hw_crc32_deinit()) + { + return -RT_ERROR; + } #endif LOG_I("rtlink hardware deinit successful."); diff --git a/examples/rt-link/rtlink_dev_example.c b/examples/rt-link/rtlink_dev_example.c new file mode 100644 index 0000000000..0a026bcb3d --- /dev/null +++ b/examples/rt-link/rtlink_dev_example.c @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-19 Sherman the first version + */ + +#include +#include + +#define DBG_TAG "example" +#define DBG_LVL DBG_LOG +#include +#include + +enum +{ + NONE_TEST = 0, + SHORT_FRAME_TEST, + LONG_FRAME_TEST +}; +static rt_uint8_t speed_test_type = NONE_TEST; + +static struct rt_link_device rtlink_dev = {0}; +#define RTLINK01 "rtlink01" +#define TEST_CONTEXT "This message is sent by RT-Link" +rt_uint8_t test_buff[1024] = {0}; + +static rt_err_t rtlink_dev_rx_ind(rt_device_t dev, rt_size_t size) +{ + RT_ASSERT(dev != RT_NULL); + LOG_I("rx_ind: dev name %s, rx size %d", dev->parent.name, size); + return RT_EOK; +} + +static rt_err_t rtlink_dev_tx_done(rt_device_t dev, void *buffer) +{ + RT_ASSERT(dev != RT_NULL); + struct rt_link_device *rtlink_dev = (struct rt_link_device *)dev; + LOG_I("tx_done: dev name %s, buffer 0x%p errno %d", dev->parent.name, buffer, rtlink_dev->service.err); + rt_free(buffer); + return RT_EOK; +} + +#ifdef RT_USING_POSIX +#include +#include +#include + +#define RTLINK01_PATH "/dev/rtlink01" +int fd = -1; + +static void rtlink_fopen(int argc, char *argv[]) +{ + fd = open(RTLINK01_PATH, O_RDWR | O_NONBLOCK); + + if (fd < 0) + { + LOG_E("open rt_link failed!"); + } +} +MSH_CMD_EXPORT(rtlink_fopen, rtlink posix interface example); + +static void rtlink_fclose(int argc, char *argv[]) +{ + LOG_D("colse %d", fd); + close(fd); + fd = -1; +} +MSH_CMD_EXPORT(rtlink_fclose, rtlink posix interface example); + +static void rtlink_fread(int argc, char *argv[]) +{ + int read_len; + read_len = read(fd, test_buff, sizeof(test_buff)); + LOG_D("read len %d", read_len); + LOG_HEX("read", 8, test_buff, 32); +} +MSH_CMD_EXPORT(rtlink_fread, rtlink posix interface example); + +static void rtlink_fwrite(int argc, char *argv[]) +{ + char *data = RT_NULL; + rt_size_t length = 0; + rt_uint16_t count = 0; + rt_size_t ret = 0; + + if (argc == 1) + { + data = rt_malloc(sizeof(TEST_CONTEXT)); + if (data) + { + length = sizeof(TEST_CONTEXT) - 1; + rt_memcpy(data, TEST_CONTEXT, sizeof(TEST_CONTEXT) - 1); + ret = write(fd, data, length); + } + LOG_I("write data(0x%p) result: %d.", data, ret); + } + else if (argc >= 3) + { + if (strcmp(argv[1], "-l") == 0) + { + data = rt_malloc(atoi((const char *)argv[2])); + if (data) + { + for (count = 0; count < atoi((const char *)argv[2]); count++) + { + data[count] = (count % 93 + 33); + } + length = atoi((const char *)argv[2]); + ret = write(fd, data, length); + } + LOG_I("write data(0x%p) result: %d.", data, ret); + } + else + { + LOG_E("Invalid parameter."); + } + } +} +MSH_CMD_EXPORT(rtlink_fwrite, rtlink posix interface example); + +#define RTLINK02 "rtlink02" +#define RTLINK02_PATH "/dev/rtlink02" +static struct rt_link_device rtlink_fd = {0}; +rt_uint8_t fd_buff[1024] = {0}; + +static void listen_thread(void *param) +{ + int fd = open(RTLINK02_PATH, O_RDWR | O_NONBLOCK); + if (fd < 0) + { + LOG_E("open (%s) failed", RTLINK02); + return; + } + while (1) + { + rt_uint8_t *write_buf = RT_NULL; + int write_len = 0; + fd_set readfds, writefds; + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_SET(fd, &readfds); + FD_SET(fd, &writefds); + + int ret = select(fd + 1, &readfds, &writefds, RT_NULL, RT_NULL); + LOG_D("select ret(%d), read (%d), write (%d)", ret, readfds, writefds); + if (FD_ISSET(fd, &readfds)) + { + LOG_I("POLLIN"); + int read_len = read(fd, fd_buff, sizeof(test_buff)); + LOG_D("read len %d", read_len); + LOG_HEX("read", 8, test_buff, 32); + } + + if (FD_ISSET(fd, &writefds)) + { + LOG_I("POLLOUT"); + write_buf = rt_malloc(1024); + if (write_buf) + { + write_len = write(fd, write_buf, 1024); + LOG_D("write %d", write_len); + } + } + + rt_thread_delay(500); + } + LOG_I("fd (%s) listen thread exit", RTLINK02); +} + +static void rtlink_fselect() +{ + /* step1: register rtlink to to the device framework */ + rt_link_dev_register(&rtlink_fd, RTLINK02, + RT_DEVICE_FLAG_RDWR | + RT_DEVICE_FLAG_REMOVABLE | + RT_DEVICE_FLAG_STANDALONE, + RT_NULL); + + /* step2: Initialize the rlink device as the default configuration, */ + rt_device_t device = rt_device_find(RTLINK02); + if (device == RT_NULL) + { + LOG_E("device not find!"); + return ; + } + rt_device_init(device); + + /* step3: config rtlink device rx/tx callback, channel, send timeout */ + rt_device_set_rx_indicate(device, rtlink_dev_rx_ind); + rt_device_set_tx_complete(device, rtlink_dev_tx_done); + struct rt_link_service service; + service.service = RT_LINK_SERVICE_MNGT; + service.timeout_tx = RT_WAITING_NO; + rt_device_control(device, RT_DEVICE_CTRL_CONFIG, &service); + + rt_thread_t tid = rt_thread_create(RTLINK02, listen_thread, RT_NULL, 1024, 21, 20); + if (tid) + { + rt_thread_startup(tid); + } +} +MSH_CMD_EXPORT(rtlink_fselect, rtlink posix interface example); +#endif /* RT_USING_POSIX */ + +static void rtlink_dread(void) +{ + rt_size_t read_len = 0; + rt_device_t dev = rt_device_find(RTLINK01); + if (dev == RT_NULL) + { + LOG_E("dev %s not find ", RTLINK01); + return; + } + + read_len = rt_device_read(dev, 0, test_buff, sizeof(test_buff)); + + LOG_D("read len %d", read_len); + LOG_HEX("read", 8, test_buff, 32); +} +MSH_CMD_EXPORT(rtlink_dread, rtlink device interface example); + +void rt_link_speed_test(void *paremeter) +{ + int ret; + rt_uint8_t *send_buf, *data; + rt_size_t bufflen = 0; + rt_size_t sentlen = 0; + rt_size_t count = 0; + rt_tick_t tick1, tick2; + rt_size_t total = 0; + rt_uint32_t integer, decimal; + rt_device_t dev = rt_device_find(RTLINK01); + if (dev == RT_NULL) + { + LOG_E("dev %s not find!", RTLINK01); + return ; + } + + if (speed_test_type == SHORT_FRAME_TEST) + { + bufflen = 988; + } + else + { + bufflen = 3036; + } + + send_buf = rt_malloc(bufflen); + if (send_buf != RT_NULL) + { + data = send_buf; + for (count = 0; count < bufflen; count++) + { + *data++ = (count % 93 + 33); + } + } + else + { + rt_kprintf("speed of send buffer malloc failed."); + return; + } + + tick1 = rt_tick_get(); + while (speed_test_type) + { + ret = rt_device_write(dev, 0, send_buf, bufflen); + + if (ret == RT_EOK) + { + sentlen += bufflen; + } + + tick2 = rt_tick_get(); + if (tick2 - tick1 >= RT_TICK_PER_SECOND) + { + total = sentlen * RT_TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = total / 1000; + decimal = total % 1000; + LOG_I("%d.%03d0 Mbps!", integer, decimal); + sentlen = 0; + tick1 = tick2; + } + } + rt_free(send_buf); + LOG_W("speed test end, type %d", speed_test_type); +} + +void create_thead_to_test_speed(rt_uint8_t mutil_num) +{ + rt_uint8_t i = 0; + + LOG_D("Speed test type [%02d], mutil [%02d]", speed_test_type, mutil_num); + for (i = 0; i < mutil_num; i++) + { + rt_thread_t tid; + char tid_name[RT_NAME_MAX + 1] = {0}; + + rt_snprintf(tid_name, sizeof(tid_name), "lny_s%03d", i + 1); + tid = rt_thread_create(tid_name, rt_link_speed_test, RT_NULL, 1024, 20, 10); + rt_thread_startup(tid); + LOG_I("Speed test thread[%s] startup", tid_name); + } +} + +static void rtlink_dwrite(int argc, char *argv[]) +{ + char *data = RT_NULL; + rt_size_t length = 0; + rt_uint16_t count = 0; + rt_size_t ret = RT_ERROR; + + rt_device_t dev = rt_device_find(RTLINK01); + if (dev == RT_NULL) + { + LOG_E("device not find!"); + return ; + } + + if (argc == 1) + { + data = rt_malloc(sizeof(TEST_CONTEXT)); + length = sizeof(TEST_CONTEXT) - 1; + rt_memcpy(data, TEST_CONTEXT, sizeof(TEST_CONTEXT) - 1); + + ret = rt_device_write(dev, 0, data, length); + LOG_I("write data(0x%p) result: %d.", data, ret); + } + else if (argc >= 3) + { + if (strcmp(argv[1], "-l") == 0) + { + data = rt_malloc(atoi((const char *)argv[2])); + for (count = 0; count < atoi((const char *)argv[2]); count++) + { + data[count] = (count % 93 + 33); + } + length = atoi((const char *)argv[2]); + ret = rt_device_write(dev, 0, data, length); + LOG_I("write data(0x%p) result: %d.", data, ret); + } + else + { + LOG_E("Invalid parameter."); + } + } +} +MSH_CMD_EXPORT(rtlink_dwrite, rtlink device interface example); + +static void rtlink_dinit(void) +{ + /* step1: register rtlink to to the device framework */ + rt_link_dev_register(&rtlink_dev, RTLINK01, + RT_DEVICE_FLAG_RDWR | + RT_DEVICE_FLAG_REMOVABLE | + RT_DEVICE_FLAG_STANDALONE, + RT_NULL); + + /* step2: Initialize the rlink device as the default configuration, */ + rt_device_t device = rt_device_find(RTLINK01); + if (device == RT_NULL) + { + LOG_E("device not find!"); + return ; + } + rt_device_init(device); + + /* step3: config rtlink device rx/tx callback, channel, send timeout */ + rt_device_set_rx_indicate(device, rtlink_dev_rx_ind); + rt_device_set_tx_complete(device, rtlink_dev_tx_done); + struct rt_link_service service; + service.service = RT_LINK_SERVICE_SOCKET; + service.timeout_tx = RT_WAITING_FOREVER; + service.flag = RT_LINK_FLAG_ACK | RT_LINK_FLAG_CRC; + rt_device_control(device, RT_DEVICE_CTRL_CONFIG, &service); +} +MSH_CMD_EXPORT(rtlink_dinit, rtlink device interface example); + +static void rtlink_dopen() +{ + /* step4: open rtlink device, attach the service channel */ + rt_device_t device = rt_device_find(RTLINK01); + if (device == RT_NULL) + { + LOG_E("device not find!"); + return ; + } + rt_err_t ret = rt_device_open(device, RT_DEVICE_OFLAG_RDWR); + LOG_I("dev open ret %d", ret); +} +MSH_CMD_EXPORT(rtlink_dopen, rtlink device interface example); diff --git a/examples/rt-link/rtlink_example.c b/examples/rt-link/rtlink_example.c index 841e56b17e..4c9b9c54fb 100644 --- a/examples/rt-link/rtlink_example.c +++ b/examples/rt-link/rtlink_example.c @@ -1,4 +1,3 @@ - /* * Copyright (c) 2006-2021, RT-Thread Development Team * @@ -7,6 +6,7 @@ * Change Logs: * Date Author Notes * 2021-05-15 Sherman the first version + * 2021-08-04 Sherman Adapted to new version of rt-link API */ #include @@ -30,33 +30,25 @@ enum void rt_link_speed_test(void *paremeter); static rt_uint8_t speed_test_type = NONE_TEST; +static struct rt_link_service serv_socket; +static struct rt_link_service serv_wifi; -rt_err_t rt_link_receive_example_callback(void *data, rt_size_t length) +static void send_cb(struct rt_link_service *service, void *buffer) { - LOG_I("recv data %d",length); - LOG_HEX("example",8,data,length); - rt_free(data); - return RT_EOK; + LOG_I("send_cb: service (%d) buffer (0x%p) err(%d)", service->service, buffer, service->err); } -void create_thead_to_test_speed(rt_uint8_t mutil_num) +static void recv_cb(struct rt_link_service *service, void *data, rt_size_t size) { - rt_uint8_t i = 0; + LOG_I("service (%d) size (%d) data(0x%p)", service->service, size, data); - LOG_D("Speed test type [%02d], mutil [%02d]", speed_test_type, mutil_num); - for(i = 0; i< mutil_num; i++) + if (size) { - rt_thread_t tid; - char tid_name[RT_NAME_MAX + 1] = {0}; - - rt_snprintf(tid_name, sizeof(tid_name), "lny_s%03d", i + 1); - tid = rt_thread_create(tid_name, rt_link_speed_test, RT_NULL, 1024, 20, 10); - rt_thread_startup(tid); - LOG_I("Speed test thread[%s] startup", tid_name); + rt_free(data); } } -void rt_link_speed_test(void *paremeter) +static void rt_link_speed_test(void *paremeter) { int ret; rt_uint8_t *send_buf, *data; @@ -67,20 +59,20 @@ void rt_link_speed_test(void *paremeter) rt_size_t total = 0; rt_uint32_t integer, decimal; - if(speed_test_type == SHORT_FRAME_TEST) + if (speed_test_type == SHORT_FRAME_TEST) { - bufflen = 2044; + bufflen = RT_LINK_MAX_DATA_LENGTH; } else { - bufflen = 6132; + bufflen = RT_LINK_MAX_DATA_LENGTH * RT_LINK_FRAMES_MAX; } send_buf = rt_malloc(bufflen); - if(send_buf != RT_NULL) + if (send_buf != RT_NULL) { data = send_buf; - for(count = 0;count < bufflen; count++) + for (count = 0; count < bufflen; count++) { *data++ = (count % 93 + 33); } @@ -94,70 +86,94 @@ void rt_link_speed_test(void *paremeter) tick1 = rt_tick_get(); while (speed_test_type) { - ret = rt_link_send(RT_LINK_SERVICE_RTLINK, send_buf, bufflen); - if(ret > 0) + ret = rt_link_send(&serv_socket, send_buf, bufflen); + if (ret > 0) { sentlen += ret; } + else + { + log_w("send err %d", ret); + } tick2 = rt_tick_get(); - if (tick2 - tick1 >= RT_TICK_PER_SECOND)//* 10 + if (tick2 - tick1 >= RT_TICK_PER_SECOND) { total = sentlen * RT_TICK_PER_SECOND / 125 / (tick2 - tick1); - integer = total/1000; - decimal = total%1000; + integer = total / 1000; + decimal = total % 1000; LOG_I("%d.%03d0 Mbps!", integer, decimal); sentlen = 0; tick1 = tick2; } } rt_free(send_buf); - LOG_W("speed test end, type %d",speed_test_type); + LOG_W("speed test end, type %d", speed_test_type); +} + +static void create_thead_to_test_speed(rt_uint8_t mutil_num) +{ + rt_uint8_t i = 0; + + LOG_D("Speed test type [%02d], mutil [%02d]", speed_test_type, mutil_num); + for (i = 0; i < mutil_num; i++) + { + rt_thread_t tid; + char tid_name[RT_NAME_MAX + 1] = {0}; + + rt_snprintf(tid_name, sizeof(tid_name), "lny_s%03d", i + 1); + tid = rt_thread_create(tid_name, rt_link_speed_test, RT_NULL, 1024, 20, 10); + if (tid) + { + rt_thread_startup(tid); + LOG_I("Speed test thread[%s] startup", tid_name); + } + } } -int rt_link_example_send(int argc, char **argv) +static int rtlink_exsend(int argc, char **argv) { char *receive = RT_NULL; rt_size_t length = 0; rt_uint16_t count = 0; - if(argc == 1) + if (argc == 1) { receive = rt_malloc(sizeof(TEST_CONTEXT)); rt_memcpy(receive, TEST_CONTEXT, sizeof(TEST_CONTEXT) - 1); - length = rt_link_send(RT_LINK_SERVICE_RTLINK, receive, sizeof(TEST_CONTEXT) - 1); + length = rt_link_send(&serv_socket, receive, sizeof(TEST_CONTEXT) - 1); LOG_I("send data length: %d.", length); rt_free(receive); } - else if(argc >= 3) + else if (argc >= 3) { - if(strcmp(argv[1], "-l") == 0) + if (strcmp(argv[1], "-l") == 0) { receive = rt_malloc(atoi((const char *)argv[2])); - for(count = 0;count < atoi((const char *)argv[2]); count++) + for (count = 0; count < atoi((const char *)argv[2]); count++) { *receive++ = (count % 93 + 33); } - length = rt_link_send(RT_LINK_SERVICE_RTLINK, receive - atoi((const char *)argv[2]), atoi((const char *)argv[2])); + length = rt_link_send(&serv_socket, receive - atoi((const char *)argv[2]), atoi((const char *)argv[2])); rt_free(receive - atoi((const char *)argv[2])); LOG_I("send data length: %d.", length); } - else if(strcmp(argv[1], "-s") == 0) + else if (strcmp(argv[1], "-s") == 0) { - if(speed_test_type == NONE_TEST) + if (speed_test_type == NONE_TEST) { rt_uint8_t mutil_num = 1; - if(argc > 3) + if (argc > 3) { mutil_num = atoi((const char *)argv[3]); } - if(strncmp(argv[2], "-s", rt_strlen(argv[2])) == 0) + if (strncmp(argv[2], "-s", rt_strlen(argv[2])) == 0) { speed_test_type = SHORT_FRAME_TEST; } - else if(strncmp(argv[2], "-l", rt_strlen(argv[2])) == 0) + else if (strncmp(argv[2], "-l", rt_strlen(argv[2])) == 0) { speed_test_type = LONG_FRAME_TEST; } @@ -176,12 +192,23 @@ int rt_link_example_send(int argc, char **argv) } return 0; } -MSH_CMD_EXPORT(rt_link_example_send, rt link layer send test); +MSH_CMD_EXPORT(rtlink_exsend, rt link layer send test); -int rt_link_example_init(void) +int rtlink_exinit(void) { - - rt_link_service_attach(RT_LINK_SERVICE_RTLINK, rt_link_receive_example_callback); + serv_socket.service = RT_LINK_SERVICE_SOCKET; + serv_socket.timeout_tx = RT_WAITING_FOREVER; + serv_socket.flag = RT_LINK_FLAG_ACK | RT_LINK_FLAG_CRC; + serv_socket.recv_cb = recv_cb; + serv_socket.send_cb = send_cb; + rt_link_service_attach(&serv_socket); + + serv_wifi.service = RT_LINK_SERVICE_WIFI; + serv_wifi.timeout_tx = RT_WAITING_FOREVER; + serv_wifi.flag = RT_NULL; + serv_wifi.recv_cb = recv_cb; + serv_wifi.send_cb = send_cb; + rt_link_service_attach(&serv_wifi); return RT_EOK; } -MSH_CMD_EXPORT(rt_link_example_init, rt link layer example init); +MSH_CMD_EXPORT(rtlink_exinit, rt link example init); -- cgit v1.3.1 From 8d1f0758d695d84c536a4b3f12c0bc7a97d1df7c Mon Sep 17 00:00:00 2001 From: tyustli <1225613647@qq.com> Date: Thu, 12 Aug 2021 19:48:27 +0800 Subject: [add] semaphore testcase ci config --- .github/workflows/action_utest.yml | 1 + examples/utest/configs/kernel/mem.conf | 2 ++ 2 files changed, 3 insertions(+) (limited to 'examples') diff --git a/.github/workflows/action_utest.yml b/.github/workflows/action_utest.yml index 7d0e2c44d8..985b82e831 100644 --- a/.github/workflows/action_utest.yml +++ b/.github/workflows/action_utest.yml @@ -12,6 +12,7 @@ jobs: matrix: legs: - {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "sd.bin"} + - {UTEST: "kernel/semaphore", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "sd.bin"} - {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "utest_self/self.conf", SD_FILE: "sd.bin"} - {UTEST: "kernel/mem/riscv64", RTT_BSP: "bsp/qemu-riscv-virt64", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "None"} env: diff --git a/examples/utest/configs/kernel/mem.conf b/examples/utest/configs/kernel/mem.conf index 1a311ab9dd..786532195d 100644 --- a/examples/utest/configs/kernel/mem.conf +++ b/examples/utest/configs/kernel/mem.conf @@ -1,4 +1,6 @@ CONFIG_UTEST_MEMHEAP_TC=y +CONFIG_UTEST_SEMAPHORE_TC=y # dependencies CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_USING_SEMAPHORE=y -- cgit v1.3.1 From 5074c86dcebc13cefa11114b29c918971d4da3b6 Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Sun, 15 Aug 2021 16:16:00 +0800 Subject: [ci][autotest] add ipc.conf --- .github/workflows/action_utest.yml | 2 +- examples/utest/configs/kernel/ipc.conf | 4 ++++ examples/utest/configs/kernel/mem.conf | 2 -- 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 examples/utest/configs/kernel/ipc.conf (limited to 'examples') diff --git a/.github/workflows/action_utest.yml b/.github/workflows/action_utest.yml index 985b82e831..2ff0bd8185 100644 --- a/.github/workflows/action_utest.yml +++ b/.github/workflows/action_utest.yml @@ -12,7 +12,7 @@ jobs: matrix: legs: - {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "sd.bin"} - - {UTEST: "kernel/semaphore", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "sd.bin"} + - {UTEST: "kernel/ipc", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/ipc.conf", SD_FILE: "sd.bin"} - {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "utest_self/self.conf", SD_FILE: "sd.bin"} - {UTEST: "kernel/mem/riscv64", RTT_BSP: "bsp/qemu-riscv-virt64", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "None"} env: diff --git a/examples/utest/configs/kernel/ipc.conf b/examples/utest/configs/kernel/ipc.conf new file mode 100644 index 0000000000..0dcb6bd052 --- /dev/null +++ b/examples/utest/configs/kernel/ipc.conf @@ -0,0 +1,4 @@ +CONFIG_UTEST_SEMAPHORE_TC=y + +# dependencies +CONFIG_RT_USING_SEMAPHORE=y diff --git a/examples/utest/configs/kernel/mem.conf b/examples/utest/configs/kernel/mem.conf index 786532195d..1a311ab9dd 100644 --- a/examples/utest/configs/kernel/mem.conf +++ b/examples/utest/configs/kernel/mem.conf @@ -1,6 +1,4 @@ CONFIG_UTEST_MEMHEAP_TC=y -CONFIG_UTEST_SEMAPHORE_TC=y # dependencies CONFIG_RT_USING_MEMHEAP=y -CONFIG_RT_USING_SEMAPHORE=y -- cgit v1.3.1