From a78a3a461b17ee7cf01e1bda8c500321bdb236f7 Mon Sep 17 00:00:00 2001 From: simbit18 Date: Thu, 4 Dec 2025 16:49:39 +0100 Subject: [PATCH 001/568] workflows/build.yml: fix fatal: write error: No space left on device Fixed error verified in this PR https://github.com/apache/nuttx/pull/17423 added to the workflow: - Show Disk Space - Free Disk Space (Ubuntu) Only Android runtime removed - Post-build Disk Space We can now monitor disk space. Signed-off-by: simbit18 --- .github/workflows/build.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ab5cd6875..779f458bc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -143,6 +143,16 @@ jobs: steps: + - name: Show Disk Space + run: df -h + + - name: Free Disk Space (Ubuntu) + run: | + sudo rm -rf /usr/local/lib/android + + - name: After CLEAN-UP Disk Space + run: df -h + - name: Download Source Artifact uses: actions/download-artifact@v6 with: @@ -183,6 +193,10 @@ jobs: ./cibuild.sh -c -A -N -R -S testlist/${{matrix.boards}}.dat fi + - name: Post-build Disk Space + if: always() + run: df -h + - uses: actions/upload-artifact@v5 if: ${{ always() }} with: From 8c5c506e4063749996e5e6a4dbf6bdfb442600b7 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Tue, 4 Nov 2025 12:49:38 +0100 Subject: [PATCH 002/568] testing/cachetest: fix compilation error for arm64 fix compilation error: cachetest_main.c:37:26: error: format '%u' expects argument of type 'unsigned int', but argument 5 has type 'size_t' {aka 'long unsigned int'} [-Werror=format=] 37 | #define CACHETEST_PREFIX "CACHE Test: " | ^~~~~~~~~~~~~~ cachetest_main.c:150:20: note: in expansion of macro 'CACHETEST_PREFIX' 150 | syslog(LOG_INFO, CACHETEST_PREFIX "waddr:%p, uncacheble addr start:%p," | ^~~~~~~~~~~~~~~~ cachetest_main.c:151:17: note: format string is defined here 151 | "size:%u\n", info->waddr, | ~^ | | | unsigned int | %lu Signed-off-by: raiden00pl --- testing/mm/cachetest/cachetest_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/mm/cachetest/cachetest_main.c b/testing/mm/cachetest/cachetest_main.c index bfe5dea71..4c0087aa8 100644 --- a/testing/mm/cachetest/cachetest_main.c +++ b/testing/mm/cachetest/cachetest_main.c @@ -148,7 +148,7 @@ static void cachetest_parse_commandline(int argc, FAR char **argv, } syslog(LOG_INFO, CACHETEST_PREFIX "waddr:%p, uncacheble addr start:%p," - "size:%u\n", info->waddr, + "size:%zu\n", info->waddr, (FAR char *)((uintptr_t)info->waddr | info->offset), info->size); } From 39cb6fefda23615d4f35ce71c9edccd5e5698983 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Thu, 27 Nov 2025 12:00:53 +0100 Subject: [PATCH 003/568] testing/memtester: add memtester.zip to gitignore add memtester.zip to gitignore Signed-off-by: raiden00pl --- testing/mm/memtester/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/mm/memtester/.gitignore b/testing/mm/memtester/.gitignore index 12d194f47..7314c9664 100644 --- a/testing/mm/memtester/.gitignore +++ b/testing/mm/memtester/.gitignore @@ -1 +1,2 @@ /memtester +memtester.zip From 5549f66dc19c8714bbde2cc39379d376a5065c2f Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Fri, 5 Dec 2025 13:39:23 +0100 Subject: [PATCH 004/568] testing/memtester: fix build error for cmake fix broken CMakeLists.txt for memtester Signed-off-by: raiden00pl --- testing/mm/memtester/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/mm/memtester/CMakeLists.txt b/testing/mm/memtester/CMakeLists.txt index c60eeb69a..74d99b9d0 100644 --- a/testing/mm/memtester/CMakeLists.txt +++ b/testing/mm/memtester/CMakeLists.txt @@ -30,7 +30,7 @@ if(CONFIG_UTILS_MEMTESTER) FetchContent_Declare( memtester_fetch - URL ${CONFIG_MEMTESTER_URL}SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/memtester + URL ${CONFIG_MEMTESTER_URL} SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/memtester BINARY_DIR ${CMAKE_BINARY_DIR}/apps/testing/memtester/memtester DOWNLOAD_NO_PROGRESS true TIMEOUT 30) From 641f7ced84fe7f2ec4b624296ffac1d714a68dd5 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Fri, 5 Dec 2025 13:51:06 +0100 Subject: [PATCH 005/568] testing/ltp: add ltp zip file to gitignore add ltp zip file to gitignore Signed-off-by: raiden00pl --- testing/ltp/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/ltp/.gitignore b/testing/ltp/.gitignore index ae3714a8c..82b8523ae 100644 --- a/testing/ltp/.gitignore +++ b/testing/ltp/.gitignore @@ -1 +1,2 @@ /ltp +/ltp-*.zip From 5eae4c8f15d5d142ea31e65f8865c7655ff0531d Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Sun, 27 Jul 2025 21:08:05 +0800 Subject: [PATCH 006/568] apps/fastboot: Enable network via ioctl during fastboot initialization Bring up the network when do fastboot tcp init. Signed-off-by: yangsong8 --- system/fastboot/Kconfig | 7 +++++++ system/fastboot/fastboot.c | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/system/fastboot/Kconfig b/system/fastboot/Kconfig index f5b14cd02..0842bcb0d 100644 --- a/system/fastboot/Kconfig +++ b/system/fastboot/Kconfig @@ -45,4 +45,11 @@ config SYSTEM_FASTBOOTD_SHELL e.g. fastboot oem shell ps e.g. fastboot oem shell "mkrd -m 10 -s 512 640" +config SYSTEM_FASTBOOTD_NET_INIT + bool "Network initialization" + default n + select NETUTILS_NETINIT + ---help--- + This option enables/disables all network initialization in fastboot server. + endif # SYSTEM_FASTBOOTD diff --git a/system/fastboot/fastboot.c b/system/fastboot/fastboot.c index b20be6b7d..2a24e9b9f 100644 --- a/system/fastboot/fastboot.c +++ b/system/fastboot/fastboot.c @@ -52,6 +52,10 @@ #include #include +#ifdef CONFIG_SYSTEM_FASTBOOTD_NET_INIT +# include "netutils/netinit.h" +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -1259,6 +1263,12 @@ static int fastboot_tcp_initialize(FAR struct fastboot_ctx_s *ctx) { struct sockaddr_in addr; +#ifdef CONFIG_SYSTEM_FASTBOOTD_NET_INIT + /* Bring up the network */ + + netinit_bringup(); +#endif + ctx->tran_fd[0] = socket(AF_INET, SOCK_STREAM, SOCK_CLOEXEC | SOCK_NONBLOCK); if (ctx->tran_fd[0] < 0) From 63c1767d3304b1905e29d4d6206afd17271732a2 Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Sun, 27 Jul 2025 21:17:23 +0800 Subject: [PATCH 007/568] apps/fastboot: organize an api for external apps to call add an interface fastboot_handler. This interface can be called when nsh is disable. Signed-off-by: yangsong8 --- system/fastboot/fastboot.c | 54 +++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/system/fastboot/fastboot.c b/system/fastboot/fastboot.c index 2a24e9b9f..c18081c40 100644 --- a/system/fastboot/fastboot.c +++ b/system/fastboot/fastboot.c @@ -991,11 +991,12 @@ static void fastboot_oem(FAR struct fastboot_ctx_s *ctx, FAR const char *arg) } } -static void fastboot_command_loop(FAR struct fastboot_ctx_s *ctx, - size_t nctx) +static int fastboot_command_loop(FAR struct fastboot_ctx_s *ctx, + size_t nctx) { FAR struct fastboot_ctx_s *c; struct epoll_event ev[nctx]; + int ret = OK; int epfd; int n; @@ -1003,14 +1004,15 @@ static void fastboot_command_loop(FAR struct fastboot_ctx_s *ctx, if (epfd < 0) { fb_err("open epoll failed %d", errno); - return; + return epfd; } for (c = ctx, n = nctx; n-- > 0; c++) { ev[n].events = EPOLLIN; ev[n].data.ptr = c; - if (epoll_ctl(epfd, EPOLL_CTL_ADD, c->tran_fd[0], &ev[n]) < 0) + ret = epoll_ctl(epfd, EPOLL_CTL_ADD, c->tran_fd[0], &ev[n]); + if (ret < 0) { fb_err("err add poll %d", c->tran_fd[0]); goto epoll_close; @@ -1019,7 +1021,8 @@ static void fastboot_command_loop(FAR struct fastboot_ctx_s *ctx, if (ctx->left > 0) { - if (epoll_wait(epfd, ev, nitems(ev), ctx->left) <= 0) + ret = epoll_wait(epfd, ev, nitems(ev), ctx->left); + if (ret <= 0) { goto epoll_close; } @@ -1074,6 +1077,7 @@ epoll_close: } close(epfd); + return ret; } static void fastboot_publish(FAR struct fastboot_ctx_s *ctx, @@ -1434,7 +1438,7 @@ static int fastboot_tcp_write(FAR struct fastboot_ctx_s *ctx, static int fastboot_context_initialize(FAR struct fastboot_ctx_s *ctx, size_t nctx) { - int ret; + int ret = ERROR; for (; nctx-- > 0; ctx++) { @@ -1465,7 +1469,7 @@ static int fastboot_context_initialize(FAR struct fastboot_ctx_s *ctx, } } - return 0; + return ret; } static void fastboot_context_deinit(FAR struct fastboot_ctx_s *ctx, @@ -1485,11 +1489,30 @@ static void fastboot_context_deinit(FAR struct fastboot_ctx_s *ctx, * Public Functions ****************************************************************************/ -int main(int argc, FAR char **argv) +int fastboot_handler(uint64_t timeout) { struct fastboot_ctx_s context[nitems(g_tran_ops)]; int ret; + context[0].left = timeout; + ret = fastboot_context_initialize(context, nitems(context)); + if (ret < 0) + { + return ret; + } + + fastboot_create_publish(context, nitems(context)); + ret = fastboot_command_loop(context, nitems(context)); + fastboot_free_publish(context, nitems(context)); + fastboot_context_deinit(context, nitems(context)); + + return ret; +} + +int main(int argc, FAR char **argv) +{ + uint64_t timeout = 0; + if (argc > 1) { if (strcmp(argv[1], "-h") == 0) @@ -1500,22 +1523,11 @@ int main(int argc, FAR char **argv) return 0; } - if (sscanf(argv[1], "%" SCNu64 , &context[0].left) != 1) + if (sscanf(argv[1], "%" SCNu64 , &timeout) != 1) { return -EINVAL; } } - ret = fastboot_context_initialize(context, nitems(context)); - if (ret < 0) - { - return ret; - } - - fastboot_create_publish(context, nitems(context)); - fastboot_command_loop(context, nitems(context)); - fastboot_free_publish(context, nitems(context)); - fastboot_context_deinit(context, nitems(context)); - - return ret; + return fastboot_handler(timeout); } From 9633580d2c7f64891729655edc1813d36e116c6a Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Thu, 31 Jul 2025 23:00:36 +0800 Subject: [PATCH 008/568] apps/fastboot: add switchboot command The switchboot command can be sent even without enabling sh Signed-off-by: yangsong8 --- system/fastboot/fastboot.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/system/fastboot/fastboot.c b/system/fastboot/fastboot.c index c18081c40..41e20b6d8 100644 --- a/system/fastboot/fastboot.c +++ b/system/fastboot/fastboot.c @@ -226,6 +226,10 @@ static void fastboot_filedump(FAR struct fastboot_ctx_s *ctx, static void fastboot_shell(FAR struct fastboot_ctx_s *ctx, FAR const char *arg); #endif +#ifdef CONFIG_BOARDCTL_SWITCH_BOOT +static void fastboot_switchboot(FAR struct fastboot_ctx_s *context, + FAR const char *arg); +#endif /* USB transport */ @@ -272,6 +276,9 @@ static const struct fastboot_cmd_s g_oem_cmd[] = #ifdef CONFIG_SYSTEM_FASTBOOTD_SHELL { "shell", fastboot_shell }, #endif +#ifdef CONFIG_BOARDCTL_SWITCH_BOOT + { "switchboot", fastboot_switchboot }, +#endif }; #ifdef CONFIG_BOARD_MEMORY_RANGE @@ -930,6 +937,21 @@ static void fastboot_shell(FAR struct fastboot_ctx_s *ctx, } #endif +#ifdef CONFIG_BOARDCTL_SWITCH_BOOT +static void fastboot_switchboot(FAR struct fastboot_ctx_s *context, + FAR const char *arg) +{ + if (!arg) + { + fastboot_fail(context, "Invalid argument"); + return; + } + + boardctl(BOARDIOC_SWITCH_BOOT, (uintptr_t)&arg[0]); + fastboot_okay(context, ""); +} +#endif + static void fastboot_upload(FAR struct fastboot_ctx_s *ctx, FAR const char *arg) { From e19d99022a426629a40d3b22b0b053f013e4badb Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Fri, 1 Aug 2025 15:25:06 +0800 Subject: [PATCH 009/568] apps/fastboot: fix build warning apps/system/fastboot/fastboot.c:351:43: error: '%s' directive output may be truncated writing up to 63 bytes into a region of size 60 [-Werror=format-truncation=] ...... apps/system/fastboot/fastboot.c:351:3: note: 'snprintf' output between 5 and 68 bytes into a destination of size 64 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ apps/system/fastboot/fastboot.c:351:43: error: '%s' directive output may be truncated writing up to 63 bytes into a region of size 60 [-Werror=format-truncation=] ...... apps/system/fastboot/fastboot.c:351:3: note: 'snprintf' output between 5 and 68 bytes into a destination of size 64 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: yangsong8 --- system/fastboot/fastboot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/fastboot/fastboot.c b/system/fastboot/fastboot.c index 41e20b6d8..4ba39b5d3 100644 --- a/system/fastboot/fastboot.c +++ b/system/fastboot/fastboot.c @@ -352,14 +352,14 @@ static int fastboot_write(int fd, FAR const void *buf, size_t len) static void fastboot_ack(FAR struct fastboot_ctx_s *ctx, FAR const char *code, FAR const char *reason) { - char response[FASTBOOT_MSG_LEN]; + char response[FASTBOOT_MSG_LEN + 4]; if (reason == NULL) { reason = ""; } - snprintf(response, FASTBOOT_MSG_LEN, "%s%s", code, reason); + snprintf(response, FASTBOOT_MSG_LEN + 4, "%s%s", code, reason); ctx->ops->write(ctx, response, strlen(response)); } From 24e1c4df6fb2cf17e8c768ff13f5d553b45b0ef6 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Fri, 16 May 2025 15:51:49 +0800 Subject: [PATCH 010/568] testing/ostest/smp_call.c: fix smp_call cpu_set inconsistency issue If we set CONFIG_SMP_DEFAULT_CPUSET=1 This will cause the value of cpuset to be 0x1, ((1 << CONFIG_SMP_NCPUS) - 1) will result in the cpuset being 0x11, leading to test case errors. Signed-off-by: hujun5 --- testing/ostest/smp_call.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/testing/ostest/smp_call.c b/testing/ostest/smp_call.c index 18f030977..9893cec9b 100644 --- a/testing/ostest/smp_call.c +++ b/testing/ostest/smp_call.c @@ -38,6 +38,7 @@ ****************************************************************************/ static struct smp_call_data_s g_call_data; +static cpu_set_t g_cpuset; /**************************************************************************** * Private Functions @@ -53,10 +54,8 @@ static int smp_call_func(void *arg) static void wdg_wdentry(wdparm_t arg) { - cpu_set_t cpus = (1 << CONFIG_SMP_NCPUS) - 1; - nxsched_smp_call_init(&g_call_data, smp_call_func, (FAR void *)arg); - nxsched_smp_call_async(cpus, &g_call_data); + nxsched_smp_call_async(g_cpuset, &g_call_data); } /**************************************************************************** @@ -65,7 +64,6 @@ static void wdg_wdentry(wdparm_t arg) void smp_call_test(void) { - cpu_set_t cpuset; struct smp_call_data_s call_data; sem_t sem; int cpucnt; @@ -111,10 +109,10 @@ void smp_call_test(void) printf("smp_call_test: Call multi cpu, nowait\n"); - sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); - cpucnt = CPU_COUNT(&cpuset); + sched_getaffinity(0, sizeof(cpu_set_t), &g_cpuset); + cpucnt = CPU_COUNT(&g_cpuset); - nxsched_smp_call_async(cpuset, &call_data); + nxsched_smp_call_async(g_cpuset, &call_data); for (cpu = 0; cpu < cpucnt; cpu++) { @@ -142,7 +140,7 @@ void smp_call_test(void) printf("smp_call_test: Call multi cpu, wait\n"); - nxsched_smp_call(cpuset, smp_call_func, &sem); + nxsched_smp_call(g_cpuset, smp_call_func, &sem); sem_getvalue(&sem, &value); if (value != cpucnt) From c3b5c6cedfa3496447739ebf04e47fafd1db7f21 Mon Sep 17 00:00:00 2001 From: Filipe Cavalcanti Date: Fri, 10 Oct 2025 10:21:37 -0300 Subject: [PATCH 011/568] boot/mcuboot: update MCUBoot version Updates default MCUBoot hash. Signed-off-by: Filipe Cavalcanti --- boot/mcuboot/CMakeLists.txt | 3 +++ boot/mcuboot/Kconfig | 4 ++-- boot/mcuboot/Makefile | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/boot/mcuboot/CMakeLists.txt b/boot/mcuboot/CMakeLists.txt index 2ea3e7137..49c02a133 100644 --- a/boot/mcuboot/CMakeLists.txt +++ b/boot/mcuboot/CMakeLists.txt @@ -45,6 +45,9 @@ if(CONFIG_BOOT_MCUBOOT) set(SRCS mcuboot/boot/bootutil/src/boot_record.c + mcuboot/boot/bootutil/src/bootutil_area.c + mcuboot/boot/bootutil/src/bootutil_img_hash.c + mcuboot/boot/bootutil/src/bootutil_loader.c mcuboot/boot/bootutil/src/bootutil_misc.c mcuboot/boot/bootutil/src/bootutil_public.c mcuboot/boot/bootutil/src/caps.c diff --git a/boot/mcuboot/Kconfig b/boot/mcuboot/Kconfig index f5c904a7a..271c986e7 100644 --- a/boot/mcuboot/Kconfig +++ b/boot/mcuboot/Kconfig @@ -22,11 +22,11 @@ config MCUBOOT_REPOSITORY config MCUBOOT_VERSION string "MCUboot version" - default "fefc398cc13ebbc527e297fe9df78cd98a359d75" + default "457be0cf3fb03e9e09938728dece8f03309db973" ---help--- Defines MCUboot version to be downloaded. Either release tag or commit hash should be specified. Using newer MCUboot version - may cause compatability issues. + may cause compatibility issues. config MCUBOOT_ENABLE_LOGGING bool "Enable MCUboot logging" diff --git a/boot/mcuboot/Makefile b/boot/mcuboot/Makefile index e6851be93..6c036147f 100644 --- a/boot/mcuboot/Makefile +++ b/boot/mcuboot/Makefile @@ -44,6 +44,9 @@ endif CFLAGS += -Wno-undef -Wno-unused-but-set-variable CSRCS := $(MCUBOOT_UNPACK)/boot/bootutil/src/boot_record.c \ + $(MCUBOOT_UNPACK)/boot/bootutil/src/bootutil_area.c \ + $(MCUBOOT_UNPACK)/boot/bootutil/src/bootutil_img_hash.c \ + $(MCUBOOT_UNPACK)/boot/bootutil/src/bootutil_loader.c \ $(MCUBOOT_UNPACK)/boot/bootutil/src/bootutil_misc.c \ $(MCUBOOT_UNPACK)/boot/bootutil/src/bootutil_public.c \ $(MCUBOOT_UNPACK)/boot/bootutil/src/caps.c \ From 2bc4bdadee97ab148198c80c44271db89c213590 Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Wed, 11 Jun 2025 11:41:27 +0800 Subject: [PATCH 012/568] apps/nsh: fix switchboot command spelling error modify swtichboot -> switchboot Signed-off-by: yangsong8 --- nshlib/nsh_command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 3911e0844..3275756b3 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -580,7 +580,7 @@ static const struct cmdmap_s g_cmdmap[] = #endif #if defined(CONFIG_BOARDCTL_SWITCH_BOOT) && !defined(CONFIG_NSH_DISABLE_SWITCHBOOT) - CMD_MAP("swtichboot", cmd_switchboot, 2, 2, ""), + CMD_MAP("switchboot", cmd_switchboot, 2, 2, ""), #endif #if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_TEST) From f82e6c22295e4f8d6ce7bef2490170933f4aa2be Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Mon, 9 Dec 2024 21:13:49 +0800 Subject: [PATCH 013/568] nsh: return EOF when nread is 0 If enable CONFIG NSH_CLE. When sh reads data and detects that nread is 0, return EOF and exit. Signed-off-by: yangsong8 --- nshlib/nsh_session.c | 5 +++-- system/cle/cle.c | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/nshlib/nsh_session.c b/nshlib/nsh_session.c index 500c8d6f1..bb83b98fb 100644 --- a/nshlib/nsh_session.c +++ b/nshlib/nsh_session.c @@ -211,11 +211,12 @@ int nsh_session(FAR struct console_stdio_s *pstate, ret = cle_fd(pstate->cn_line, nsh_prompt(), LINE_MAX, INFD(pstate), OUTFD(pstate)); - if (ret < 0) + if (ret == EOF) { dprintf(ERRFD(pstate), g_fmtcmdfailed, "nsh_session", "cle", NSH_ERRNO_OF(-ret)); - continue; + ret = EXIT_SUCCESS; + break; } #else /* Display the prompt string */ diff --git a/system/cle/cle.c b/system/cle/cle.c index cf11f7097..21b442806 100644 --- a/system/cle/cle.c +++ b/system/cle/cle.c @@ -316,7 +316,7 @@ static int cle_getch(FAR struct cle_s *priv) if (nread == 0 || errcode != EINTR) { cledbg("ERROR: read from stdin failed: %d\n", errcode); - return -EIO; + return EOF; } } } @@ -372,13 +372,13 @@ static void cle_setcursor(FAR struct cle_s *priv, int16_t column) int len; int off; - /* Sub prompt offset from real postion to get correct offset to execute */ + /* Sub prompt offset from real position to get correct offset to execute */ off = column - (priv->realpos - priv->coloffs); cleinfo("column=%d offset=%d\n", column, off); - /* If cursor not move, retrun directly */ + /* If cursor not move, return directly */ if (off == 0) { @@ -703,9 +703,9 @@ static int cle_editloop(FAR struct cle_s *priv) for (; ; ) { ch = cle_getch(priv); - if (ch < 0) + if (ch == EOF) { - return -EIO; + return EOF; } else if (state != 0) { From 00154fd818d6e12cf758be21555458f703d514a9 Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Tue, 3 Jun 2025 21:13:37 +0800 Subject: [PATCH 014/568] apps/system/composite: change cmake build name to conn and disconn The executable file compiled by cmake has the same filename as that compiled by make. Signed-off-by: yangsong8 --- system/composite/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/composite/CMakeLists.txt b/system/composite/CMakeLists.txt index 9ca2f72ca..d88246363 100644 --- a/system/composite/CMakeLists.txt +++ b/system/composite/CMakeLists.txt @@ -21,5 +21,6 @@ # ############################################################################## if(CONFIG_SYSTEM_COMPOSITE) - nuttx_add_application(NAME composite SRCS composite_main.c) + nuttx_add_application(NAME conn SRCS composite_main.c) + nuttx_add_application(NAME disconn) endif() From 74293114aa536ab9f012357c855ac21d97ad084d Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Fri, 15 Aug 2025 14:26:28 +0800 Subject: [PATCH 015/568] apps/system: fix spitool can not send data issue when use cmd 'spi exch -b 1 -f 3000000 -m 1 -n 0 -w 32 -x 1 1f', the last character '1f' can not be trans out. Signed-off-by: yangsong8 --- system/spi/spitool.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system/spi/spitool.h b/system/spi/spitool.h index cf6f4bbc9..f93a00a86 100644 --- a/system/spi/spitool.h +++ b/system/spi/spitool.h @@ -90,7 +90,11 @@ * then some. */ -#define MAX_ARGUMENTS 12 +#ifdef CONFIG_NSH_MAXARGUMENTS +#define MAX_ARGUMENTS CONFIG_NSH_MAXARGUMENTS +#else +#define MAX_ARGUMENTS 16 +#endif /* Maximum size of one command line */ From dbc99dbf358750894df33c8133d317536a1b0aaa Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Mon, 3 Nov 2025 16:51:53 +0800 Subject: [PATCH 016/568] apps/spitool: Support multiple trans By adding a parameter -r, spitool can exchange multiple transactions. example: spi exch -b 1 -t 0 -n 0 -f 3000000 -m 1 -w 32 -x 1 -r 2 f001fff1 0000ff35 Signed-off-by: yangsong8 --- system/spi/Kconfig | 7 +++++++ system/spi/spi_common.c | 4 ++-- system/spi/spi_exch.c | 38 +++++++++++++++++++++++++------------- system/spi/spi_main.c | 11 ++++++++++- system/spi/spitool.h | 1 + 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/system/spi/Kconfig b/system/spi/Kconfig index 3b2ecff6c..9356dbdb2 100644 --- a/system/spi/Kconfig +++ b/system/spi/Kconfig @@ -78,4 +78,11 @@ config SPITOOL_DEFWORDS ---help--- Number of words to be transferred (default 1) +config SPITOOL_DEFTRANS + int "Number of transfer" + default 1 + range 1 255 + ---help--- + Number of transfer to be transferred (default 1) + endif # SYSTEM_SPITOOL diff --git a/system/spi/spi_common.c b/system/spi/spi_common.c index bb35063af..ed78ab69a 100644 --- a/system/spi/spi_common.c +++ b/system/spi/spi_common.c @@ -174,12 +174,12 @@ int spitool_common_args(FAR struct spitool_s *spitool, FAR char **arg) case 'r': ret = arg_decimal(arg, &value); - if (value < 0) + if (value < 0 || value > UINT8_MAX) { goto out_of_range; } - spitool->count = (uint32_t)value; + spitool->trans_count = (uint8_t)value; return ret; case 'u': diff --git a/system/spi/spi_exch.c b/system/spi/spi_exch.c index df2c81b38..1760ed47b 100644 --- a/system/spi/spi_exch.c +++ b/system/spi/spi_exch.c @@ -64,7 +64,7 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv) }; uint8_t *txdatap = txdata; - struct spi_trans_s trans; + FAR struct spi_trans_s *trans; struct spi_sequence_s seq; uint32_t d; @@ -93,7 +93,7 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv) /* There may be transmit data on the command line */ - if (argc - argndx > spitool->count) + if (argc - argndx > spitool->count * spitool->trans_count) { spitool_printf(spitool, g_spitoomanyargs, argv[0]); return ERROR; @@ -120,7 +120,7 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv) } spitool_printf(spitool, "Sending:\t"); - for (d = 0; d < spitool->count; d++) + for (d = 0; d < spitool->count * spitool->trans_count; d++) { if (spitool->width <= 8) { @@ -138,12 +138,20 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv) spitool_printf(spitool, "\n"); + trans = malloc(sizeof(struct spi_trans_s) * spitool->trans_count); + if (!trans) + { + spitool_printf(spitool, "Failed to allocate trans memory\n"); + return ERROR; + } + /* Get a handle to the SPI bus */ fd = spidev_open(spitool->bus); if (fd < 0) { spitool_printf(spitool, "Failed to get bus %d\n", spitool->bus); + free(trans); return ERROR; } @@ -153,8 +161,8 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv) seq.mode = spitool->mode; seq.nbits = spitool->width; seq.frequency = spitool->freq; - seq.ntrans = 1; - seq.trans = &trans; + seq.ntrans = spitool->trans_count; + seq.trans = trans; #ifdef CONFIG_SPI_DELAY_CONTROL seq.a = 0; @@ -163,21 +171,25 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv) seq.c = 0; #endif - trans.deselect = true; + for (d = 0; d < spitool->trans_count; d++) + { + trans[d].deselect = true; #ifdef CONFIG_SPI_CMDDATA - trans.cmd = spitool->command; + trans[d].cmd = spitool->command; #endif - trans.delay = spitool->udelay; - trans.nwords = spitool->count; - trans.txbuffer = txdata; - trans.rxbuffer = rxdata; + trans[d].delay = spitool->udelay; + trans[d].nwords = spitool->count; + trans[d].txbuffer = &txdata[d * spitool->count * seq.nbits / 8]; + trans[d].rxbuffer = &rxdata[d * spitool->count * seq.nbits / 8]; #ifdef CONFIG_SPI_HWFEATURES - trans.hwfeat = 0; + trans[d].hwfeat = 0; #endif + } ret = spidev_transfer(fd, &seq); close(fd); + free(trans); if (ret) { @@ -185,7 +197,7 @@ int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv) } spitool_printf(spitool, "Received:\t"); - for (d = 0; d < spitool->count; d++) + for (d = 0; d < spitool->count * spitool->trans_count; d++) { if (spitool->width <= 8) { diff --git a/system/spi/spi_main.c b/system/spi/spi_main.c index b09796db8..140826e43 100644 --- a/system/spi/spi_main.c +++ b/system/spi/spi_main.c @@ -152,6 +152,10 @@ static int spicmd_help(FAR struct spitool_s *spitool, int argc, "Default: %d Current: %" PRIu32 " Max: %d\n", CONFIG_SPITOOL_DEFWORDS, spitool->count, MAX_XDATA); + spitool_printf(spitool, " [-r trans_count] Trans to exchange " + "Default: %d Current: %d Max: %d\n", + CONFIG_SPITOOL_DEFTRANS, spitool->trans_count, UINT8_MAX); + spitool_printf(spitool, "\nNOTES:\n"); #ifndef CONFIG_DISABLE_ENVIRON spitool_printf(spitool, "o An environment variable like $PATH may be used " @@ -159,7 +163,7 @@ static int spicmd_help(FAR struct spitool_s *spitool, int argc, #endif spitool_printf(spitool, "o Arguments are \"sticky\". " "For example, once the SPI address is\n"); - spitool_printf(spitool, " specified, that address will be re-used " + spitool_printf(spitool, " specified, that address will be reused " "until it is changed.\n"); spitool_printf(spitool, "\nWARNING:\n"); spitool_printf(spitool, "o The SPI commands may have bad side effects " @@ -400,6 +404,11 @@ int main(int argc, FAR char *argv[]) g_spitool.devtype = SPIDEVTYPE_USER; } + if (g_spitool.trans_count == 0) + { + g_spitool.trans_count = CONFIG_SPITOOL_DEFTRANS; + } + /* Parse and process the command line */ spi_setup(&g_spitool); diff --git a/system/spi/spitool.h b/system/spi/spitool.h index f93a00a86..b354ea9f9 100644 --- a/system/spi/spitool.h +++ b/system/spi/spitool.h @@ -140,6 +140,7 @@ struct spitool_s bool command; /* [-c 0|1] Send as command or data? */ useconds_t udelay; /* [-u udelay] Delay in uS after transfer */ uint8_t mode; /* [-m mode] Mode to use for transfer */ + uint8_t trans_count; /* [-r trans count] No of trans to exchange */ /* Output streams */ From cfff7f5a22aecdfd7799add706c48d6968769cdc Mon Sep 17 00:00:00 2001 From: zhengyu16 Date: Thu, 11 Sep 2025 05:16:12 -0400 Subject: [PATCH 017/568] nshlib: add -f for umount adds support for the -f (force) option to the NSH umount command Signed-off-by: zhengyu16 --- nshlib/nsh_command.c | 2 +- nshlib/nsh_mntcmds.c | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 3275756b3..2f05557cb 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -621,7 +621,7 @@ static const struct cmdmap_s g_cmdmap[] = #if !defined(CONFIG_DISABLE_MOUNTPOINT) # ifndef CONFIG_NSH_DISABLE_UMOUNT - CMD_MAP("umount", cmd_umount, 2, 2, ""), + CMD_MAP("umount", cmd_umount, 2, 3, "[-f] "), # endif #endif diff --git a/nshlib/nsh_mntcmds.c b/nshlib/nsh_mntcmds.c index 62579d8b7..f4a2e903b 100644 --- a/nshlib/nsh_mntcmds.c +++ b/nshlib/nsh_mntcmds.c @@ -363,16 +363,37 @@ int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) #if !defined(CONFIG_DISABLE_MOUNTPOINT) && !defined(CONFIG_NSH_DISABLE_UMOUNT) int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { - UNUSED(argc); - - FAR char *fullpath = nsh_getfullpath(vtbl, argv[1]); + unsigned int flags = 0; + FAR char *fullpath; int ret = ERROR; + int option; + while ((option = getopt(argc, argv, "f")) != ERROR) + { + switch (option) + { + case 'f': + flags |= MNT_FORCE; + break; + + default: + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + } + + if (optind >= argc) + { + nsh_error(vtbl, g_fmtargrequired, argv[0]); + return ret; + } + + fullpath = nsh_getfullpath(vtbl, argv[optind]); if (fullpath) { /* Perform the umount */ - ret = umount(fullpath); + ret = umount2(fullpath, flags); if (ret < 0) { nsh_error(vtbl, g_fmtcmdfailed, argv[0], "umount", NSH_ERRNO); From aa3320fab4aca6b60749ae37bdd5d21b92433d7d Mon Sep 17 00:00:00 2001 From: Yanfeng Liu Date: Mon, 8 Dec 2025 19:41:44 +0800 Subject: [PATCH 018/568] import/Make.defs: use _start entry name This reverts `_start` entry name to fix issue#17443 together with nuttx side pull#17450. Signed-off-by: Yanfeng Liu --- import/Make.defs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import/Make.defs b/import/Make.defs index 8943963ed..2b8236d25 100644 --- a/import/Make.defs +++ b/import/Make.defs @@ -97,7 +97,7 @@ endif ifeq ($(CONFIG_BINFMT_ELF_RELOCATABLE),y) LDELFFLAGS += -r endif -LDELFFLAGS += -e __start -Bstatic +LDELFFLAGS += -e _start -Bstatic # Remove other ld scripts, just use import ld scripts # From a59436985c6119945e99ded5e651fa2edfce81fa Mon Sep 17 00:00:00 2001 From: chenxiaoyi Date: Thu, 6 Feb 2025 17:42:44 +0800 Subject: [PATCH 019/568] testing: getTimeofday_test: fix build warning getTimeofday_test.c:68:22: error: variable 'cnt' set but not used [-Werror,-Wunused-but-set-variable] Signed-off-by: chenxiaoyi --- testing/testsuites/kernel/syscall/cases/getTimeofday_test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/testing/testsuites/kernel/syscall/cases/getTimeofday_test.c b/testing/testsuites/kernel/syscall/cases/getTimeofday_test.c index 92861fd21..a4ccb98af 100644 --- a/testing/testsuites/kernel/syscall/cases/getTimeofday_test.c +++ b/testing/testsuites/kernel/syscall/cases/getTimeofday_test.c @@ -66,7 +66,6 @@ void test_nuttx_syscall_gettimeofday01(FAR void **state) int rtime = 3; struct timeval tv1; struct timeval tv2; - unsigned long long cnt = 0; signal(SIGALRM, breakout); @@ -90,6 +89,5 @@ void test_nuttx_syscall_gettimeofday01(FAR void **state) sleep(1); tv1 = tv2; - cnt++; } } From 953fa21fef858688a773f4111e74232e172b9959 Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Thu, 5 Dec 2024 12:08:07 +0800 Subject: [PATCH 020/568] adb: adb shell depends on SCHED_CHILD_STATUS Without this configuration, when executing exit in adb shell, adb will not be able to exit because it cannot receive the close packet. Signed-off-by: yangsong8 --- system/adb/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/system/adb/Kconfig b/system/adb/Kconfig index 06d7f940a..14b900b5a 100644 --- a/system/adb/Kconfig +++ b/system/adb/Kconfig @@ -174,6 +174,7 @@ config ADBD_SHELL_SERVICE depends on SYSTEM_NSH depends on LIBC_EXECFUNCS depends on PSEUDOTERM + depends on SCHED_CHILD_STATUS default n ---help--- Enable "adb shell" feature. From 60f5a68c96746833effbec718b40518b042ce7d6 Mon Sep 17 00:00:00 2001 From: yangsong8 Date: Mon, 6 Jan 2025 11:31:45 +0800 Subject: [PATCH 021/568] adb: adb tcp server configuration depends on NET_TCPBACKLOG For TCP-based adb, if the current CPU contains TCP protocol stack, then NET_TCPBACKLOG needs to be enabled. Signed-off-by: yangsong8 --- system/adb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/adb/Kconfig b/system/adb/Kconfig index 14b900b5a..05296cca7 100644 --- a/system/adb/Kconfig +++ b/system/adb/Kconfig @@ -95,7 +95,7 @@ config ADBD_FRAME_MAX config ADBD_TCP_SERVER bool "Network socket transport support" - depends on NET_TCP + depends on NET_TCP_NO_STACK || NET_TCPBACKLOG default n ---help--- Run adb daemon on network socket. From 8e7ec46cce85f2da2cd9da98d283c2092e49c623 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 22:10:28 +0000 Subject: [PATCH 022/568] build(deps): bump actions/upload-artifact from 5 to 6 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 779f458bc..35cff3162 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,7 +106,7 @@ jobs: run: tar zcf sources.tar.gz sources - name: Archive Source Bundle - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: source-bundle path: sources.tar.gz @@ -197,7 +197,7 @@ jobs: if: always() run: df -h - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 if: ${{ always() }} with: name: linux-${{matrix.boards}}-builds @@ -242,7 +242,7 @@ jobs: cd sources/nuttx ./tools/ci/cibuild-oot.sh - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 if: ${{ always() }} with: name: oot-build-artifacts @@ -303,7 +303,7 @@ jobs: cd sources/nuttx/tools/ci ./cibuild.sh -i -c -A -R testlist/${{matrix.boards}}.dat - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: macos-${{matrix.boards}}-builds path: buildartifacts/ @@ -386,7 +386,7 @@ jobs: cd sources/nuttx/tools/ci ./cibuild.sh -g -i -A -C -N -R testlist/${{matrix.boards}}.dat - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: msys2-${{matrix.boards}}-builds path: buildartifacts/ @@ -438,7 +438,7 @@ jobs: cd sources\nuttx\tools\ci .\cibuild.ps1 -n -i -A -C -N testlist\windows.dat - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: msvc-builds path: ./sources/buildartifacts/ From c487d669cf95ad5af30cfe4500bc683b0ebddc24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 22:10:25 +0000 Subject: [PATCH 023/568] build(deps): bump actions/download-artifact from 6 to 7 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6 to 7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 35cff3162..b03880b36 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -154,7 +154,7 @@ jobs: run: df -h - name: Download Source Artifact - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: name: source-bundle path: . @@ -212,7 +212,7 @@ jobs: DOCKER_BUILDKIT: 1 steps: - name: Download Source Artifact - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: name: source-bundle path: . @@ -271,7 +271,7 @@ jobs: boards: ${{ fromJSON(needs.macOS-Arch.outputs.selected_builds) }} steps: - name: Download Source Artifact - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: name: source-bundle path: . @@ -366,7 +366,7 @@ jobs: - run: git config --global core.autocrlf false - name: Download Source Artifact - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: name: source-bundle path: . @@ -420,7 +420,7 @@ jobs: - run: git config --global core.autocrlf false - name: Download Source Artifact - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: name: source-bundle path: . From a5e455cc1ca9a15285b7860a39fb7d0e66d07eb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 22:10:32 +0000 Subject: [PATCH 024/568] build(deps): bump actions/cache from 4 to 5 Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/cache dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b03880b36..6830a7a96 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -281,7 +281,7 @@ jobs: - name: Restore Tools Cache id: cache-tools - uses: actions/cache@v4 + uses: actions/cache@v5 env: cache-name: ${{ runner.os }}-cache-tools with: From 8cb7dd0694dfd759eb4508352a00f62a78df68d9 Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Tue, 16 Dec 2025 15:59:55 -0300 Subject: [PATCH 025/568] apps/testing: Add pthread_mutex_perf created by Anchao During the discussion about the impact of adding counter to TCB Mr anchao created a pthread mutex performance example: https://github.com/apache/nuttx/pull/17468#issuecomment-3660925314 Because this example can exercise (not ideally) the pthread mutex I decided to add it to apps/testing/sched, the program name will be called "pmutexp" (because "pmp" is not a good name). Signed-off-by: Alan C. Assis --- .../sched/pthread_mutex_perf/CMakeLists.txt | 41 +++++ testing/sched/pthread_mutex_perf/Kconfig | 30 ++++ testing/sched/pthread_mutex_perf/Make.defs | 25 +++ testing/sched/pthread_mutex_perf/Makefile | 32 ++++ .../pthread_mutex_perf/pthread_mutex_perf.c | 145 ++++++++++++++++++ 5 files changed, 273 insertions(+) create mode 100644 testing/sched/pthread_mutex_perf/CMakeLists.txt create mode 100644 testing/sched/pthread_mutex_perf/Kconfig create mode 100644 testing/sched/pthread_mutex_perf/Make.defs create mode 100644 testing/sched/pthread_mutex_perf/Makefile create mode 100644 testing/sched/pthread_mutex_perf/pthread_mutex_perf.c diff --git a/testing/sched/pthread_mutex_perf/CMakeLists.txt b/testing/sched/pthread_mutex_perf/CMakeLists.txt new file mode 100644 index 000000000..a7ac6ad92 --- /dev/null +++ b/testing/sched/pthread_mutex_perf/CMakeLists.txt @@ -0,0 +1,41 @@ +# ############################################################################## +# apps/testing/sched/pthread_mutex_perf/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_TESTING_PTHREAD_MUTEX_PERF) + + set(SRCS pthread_mutex_perf.c) + + nuttx_add_application( + NAME + ${CONFIG_TESTING_PTHREAD_MUTEX_PERF_PROGNMAE} + PRIORITY + ${CONFIG_TESTING_PTHREAD_MUTEX_PERF_PRIORITY} + STACKSIZE + ${CONFIG_TESTING_PTHREAD_MUTEX_PERF_STACKSIZE} + MODULE + ${CONFIG_TESTING_PTHREAD_MUTEX_PERF} + COMPILE_FLAGS + ${FLAGS} + SRCS + ${SRCS}) + +endif() diff --git a/testing/sched/pthread_mutex_perf/Kconfig b/testing/sched/pthread_mutex_perf/Kconfig new file mode 100644 index 000000000..d8f188880 --- /dev/null +++ b/testing/sched/pthread_mutex_perf/Kconfig @@ -0,0 +1,30 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config TESTING_PTHREAD_MUTEX_PERF + bool "Pthread Mutex Performance (pmutexp) testing" + default n + ---help--- + Pthread Mutex Performance (pmp) helps to analyze the pthread + mutex performance, by calling the function many times. + +if TESTING_PTHREAD_MUTEX_PERF + +config TESTING_PTHREAD_MUTEX_PERF_PROGNAME + string "Program name" + default "pmutexp" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config TESTING_PTHREAD_MUTEX_PERF_PRIORITY + int "Priority of pmutexp process" + default 100 + +config TESTING_PTHREAD_MUTEX_PERF_STACKSIZE + int "Stack size of pmutexp process" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/testing/sched/pthread_mutex_perf/Make.defs b/testing/sched/pthread_mutex_perf/Make.defs new file mode 100644 index 000000000..7242f2043 --- /dev/null +++ b/testing/sched/pthread_mutex_perf/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/testing/sched/pthread_mutex_perf/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_TESTING_PTHREAD_MUTEX_PERF),) +CONFIGURED_APPS += $(APPDIR)/testing/sched/pthread_mutex_perf +endif diff --git a/testing/sched/pthread_mutex_perf/Makefile b/testing/sched/pthread_mutex_perf/Makefile new file mode 100644 index 000000000..8b9b114a0 --- /dev/null +++ b/testing/sched/pthread_mutex_perf/Makefile @@ -0,0 +1,32 @@ +############################################################################ +# apps/testing/sched/pthread_mutex_perf/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +PROGNAME = $(CONFIG_TESTING_PTHREAD_MUTEX_PERF_PROGNAME) +PRIORITY = $(CONFIG_TESTING_PTHREAD_MUTEX_PERF_PRIORITY) +STACKSIZE = $(CONFIG_TESTING_PTHREAD_MUTEX_PERF_STACKSIZE) +MODULE = $(CONFIG_TESTING_PTHREAD_MUTEX_PERF) + +MAINSRC = pthread_mutex_perf.c + +include $(APPDIR)/Application.mk diff --git a/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c b/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c new file mode 100644 index 000000000..f958f0fcb --- /dev/null +++ b/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * apps/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; + +static void timespec_diff(const struct timespec *start, + const struct timespec *end, + struct timespec *diff) +{ + diff->tv_sec = end->tv_sec - start->tv_sec; + diff->tv_nsec = end->tv_nsec - start->tv_nsec; + + if (diff->tv_nsec < 0) + { + diff->tv_sec--; + diff->tv_nsec += 1000000000; + } +} + +static void timespec_add(struct timespec *total, const struct timespec *diff) +{ + total->tv_sec += diff->tv_sec; + total->tv_nsec += diff->tv_nsec; + + if (total->tv_nsec >= 1000000000) + { + total->tv_sec += total->tv_nsec / 1000000000; + total->tv_nsec = total->tv_nsec % 1000000000; + } +} + +static void timespec_avg(const struct timespec *total, int count, + struct timespec *avg) +{ + uint64_t total_ns = (uint64_t)total->tv_sec * 1000000000 + total->tv_nsec; + uint64_t avg_ns = total_ns / count; + + avg->tv_sec = avg_ns / 1000000000; + avg->tv_nsec = avg_ns % 1000000000; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * pmp_main + ****************************************************************************/ + +int main(int argc, char *argv[]) +{ + struct timespec start; + struct timespec end; + struct timespec diff; + struct timespec total = { + 0, 0 + }; + + struct timespec avg; + int i; + int j = 0; + const int loop_count = 10; + + while (j < loop_count) + { + i = 0; + j++; + + /* Get the starting time */ + + clock_gettime(CLOCK_BOOTTIME, &start); + + /* Do 1 million interactions trying to lock an already locked mutex */ + + pthread_mutex_lock(&g_mutex); + + while (i < 1000 * 1000) + { + i++; + pthread_mutex_trylock(&g_mutex); + } + + pthread_mutex_unlock(&g_mutex); + + /* Get the finished time */ + + clock_gettime(CLOCK_BOOTTIME, &end); + + /* Get the calculated elapsed time */ + + timespec_diff(&start, &end, &diff); + + /* Add it to total time for each loop pass */ + + timespec_add(&total, &diff); + + /* Get the average time */ + + timespec_avg(&total, j, &avg); + + printf("%d: diff = %lu.%09lu s | avg = %lu.%09lu s\n", j, + (unsigned long)diff.tv_sec, (unsigned long)diff.tv_nsec, + (unsigned long)avg.tv_sec, (unsigned long)avg.tv_nsec); + } + + printf("\n===== result =====\n"); + printf("count: %d\n", loop_count); + printf("total: %lu.%09lu s\n", (unsigned long)total.tv_sec, + (unsigned long)total.tv_nsec); + printf("avg: %lu.%09lu s\n", (unsigned long)avg.tv_sec, + (unsigned long)avg.tv_nsec); + + return 0; +} From c4da1b5b9f3c6ab24014f919320bad8a5ee845d7 Mon Sep 17 00:00:00 2001 From: fangpeina Date: Tue, 8 Jul 2025 13:19:45 +0800 Subject: [PATCH 026/568] system/cu: Optimize I/O performance with batch read/write Due to DMA-based transfers, the rx buffer can receive a large amount of data at once. The previous character-by-character processing approach was inefficient. Modify character-by-character read to block read of the entire buffer. This improves throughput and reduces CPU overhead, especially for high-speed serial communication or other DMA-based transfers. Signed-off-by: fangpeina --- system/cu/cu_main.c | 86 +++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/system/cu/cu_main.c b/system/cu/cu_main.c index 20cd101b5..8d25038ed 100644 --- a/system/cu/cu_main.c +++ b/system/cu/cu_main.c @@ -103,16 +103,16 @@ static FAR void *cu_listener(FAR void *parameter) for (; ; ) { + char buf[CONFIG_LINE_MAX]; int rc; - char ch; - rc = read(cu->devfd, &ch, 1); + rc = read(cu->devfd, buf, sizeof(buf)); if (rc <= 0) { break; } - rc = write(STDOUT_FILENO, &ch, 1); + rc = write(STDOUT_FILENO, buf, rc); if (rc <= 0) { break; @@ -289,6 +289,7 @@ int main(int argc, FAR char *argv[]) int start_of_line = 1; int exitval = EXIT_FAILURE; bool badarg = false; + bool escaping = false; /* Initialize global data */ @@ -436,55 +437,80 @@ int main(int argc, FAR char *argv[]) while (!cu->force_exit) { - char ch; + char buf[CONFIG_LINE_MAX]; + ssize_t nwrite = 0; + ssize_t nread; + ssize_t i; - if (read(STDIN_FILENO, &ch, 1) <= 0) + /* Read multiple characters at once (blocking) */ + + nread = read(STDIN_FILENO, buf, sizeof(buf)); + if (nread <= 0) { continue; } - if (start_of_line == 1 && ch == cu->escape) + /* Process each character */ + + for (i = 0; i < nread; i++) { - /* We've seen and escape (~) character, echo it to local - * terminal and read the next char from serial - */ + char ch = buf[i]; - write(STDOUT_FILENO, &ch, 1); + /* Check if we're waiting for an escape command character */ - if (read(STDIN_FILENO, &ch, 1) <= 0) + if (escaping) { + /* We got the escape character in previous read, + * now process the command character + */ + + escaping = false; + if (cu_cmd(cu, ch) == 1) + { + cu->force_exit = true; + nread = i; + break; + } + } + + if (start_of_line == 1 && ch == cu->escape) + { + /* Normal character */ + + if (i > nwrite) + { + write(cu->devfd, &buf[nwrite], i - nwrite); + } + + nwrite = i + 1; + + /* We've seen and escape (~) character, echo it to local + * terminal and read the next char from serial + */ + + write(STDOUT_FILENO, &ch, 1); + start_of_line = 0; + escaping = true; continue; } - if (ch == cu->escape) - { - /* Escaping a tilde: handle like normal char */ + /* Determine if we are now at the start of a new line or not */ - write(cu->devfd, &ch, 1); - continue; + if (ch == '\n' || ch == '\r') + { + start_of_line = 1; } else { - if (cu_cmd(cu, ch) == 1) - { - break; - } + start_of_line = 0; } } /* Normal character */ - write(cu->devfd, &ch, 1); - - /* Determine if we are now at the start of a new line or not */ - - if (ch == '\n' || ch == '\r') + if (nread > nwrite) { - start_of_line = 1; - } - else - { - start_of_line = 0; + write(cu->devfd, &buf[nwrite], nread - nwrite); } } From 26a969ac71486ea128a180d310192c77627734bb Mon Sep 17 00:00:00 2001 From: zhangshuai39 Date: Fri, 10 Jan 2025 10:29:46 +0800 Subject: [PATCH 027/568] apps/netutils: Modify the MQTT compilation file to enable MQTT testing Modify the build and test files to make the MQTT test cases run. Signed-off-by: zhangshuai39 --- netutils/mqttc/CMakeLists.txt | 42 ++++++++++++++++++++++++++--------- netutils/mqttc/Kconfig | 12 ++++++++++ netutils/mqttc/Makefile | 13 +++++++++++ 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/netutils/mqttc/CMakeLists.txt b/netutils/mqttc/CMakeLists.txt index 246cd1919..ae03435be 100644 --- a/netutils/mqttc/CMakeLists.txt +++ b/netutils/mqttc/CMakeLists.txt @@ -1,24 +1,24 @@ -############################################################################ +# ############################################################################## # apps/netutils/mqttc/CMakeLists.txt # # SPDX-License-Identifier: Apache-2.0 # -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. The -# ASF licenses this file to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance with the -# License. You may obtain a copy of the License at +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. +# License for the specific language governing permissions and limitations under +# the License. # -############################################################################ +# ############################################################################## if(CONFIG_NETUTILS_MQTTC) @@ -124,4 +124,24 @@ if(CONFIG_NETUTILS_MQTTC) mqttc) endif() endif() + + if(CONFIG_NETUTILS_MQTTC_TEST) + set(MQTT_TEST_CFLAGS ${CFLAGS} -Dopen_nb_socket=test_open_nb_socket + -Dpublish_callback=test_publish_callback) + + nuttx_add_application( + NAME + cmocka_mqttc_test + STACKSIZE + ${CONFIG_NETUTILS_MQTTC_TEST_STACKSIZE} + PRIORITY + ${SCHED_PRIORITY_DEFAULT} + SRCS + ${MQTTC_DIR}/tests.c + COMPILE_FLAGS + ${MQTT_TEST_CFLAGS} + DEPENDS + cmocka + mqttc) + endif() endif() diff --git a/netutils/mqttc/Kconfig b/netutils/mqttc/Kconfig index 2c1d0b883..aa8e23d04 100644 --- a/netutils/mqttc/Kconfig +++ b/netutils/mqttc/Kconfig @@ -17,6 +17,10 @@ config NETUTILS_MQTTC_EXAMPLE ---help--- Enable MQTT-C example +config NETUTILS_MQTTC_TEST + tristate "Enable MQTT-C test" + default n + if NETUTILS_MQTTC_EXAMPLE config NETUTILS_MQTTC_EXAMPLE_STACKSIZE @@ -25,6 +29,14 @@ config NETUTILS_MQTTC_EXAMPLE_STACKSIZE endif +if NETUTILS_MQTTC_TEST + +config NETUTILS_MQTTC_TEST_STACKSIZE + int "Task's stack size" + default 8192 + +endif + config NETUTILS_MQTTC_WITH_MBEDTLS bool "Enable MQTT-C with mbedtls" default n diff --git a/netutils/mqttc/Makefile b/netutils/mqttc/Makefile index 730ce5139..d8d2a3638 100644 --- a/netutils/mqttc/Makefile +++ b/netutils/mqttc/Makefile @@ -83,4 +83,17 @@ endif endif +ifneq ($(CONFIG_NETUTILS_MQTTC_TEST),) +$(MQTTC_UNPACK)$(DELIM)tests.c_CFLAGS += \ + -I$(APPDIR)$(DELIM)testing$(DELIM)cmocka$(DELIM)cmocka$(DELIM)include \ + -Dopen_nb_socket=test_open_nb_socket \ + -Dpublish_callback=test_publish_callback + +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = $(CONFIG_NETUTILS_MQTTC_TEST_STACKSIZE) +MODULE = $(CONFIG_NETUTILS_MQTTC_TEST) +MAINSRC += $(MQTTC_UNPACK)$(DELIM)tests.c +PROGNAME += cmocka_mqttc_test +endif + include $(APPDIR)/Application.mk From 0045d8b546af28c43233e43d342b222d2ed512eb Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Sun, 21 Dec 2025 13:11:14 -0500 Subject: [PATCH 028/568] uorb/listener: Fix typos Fix typo in comments and strings. Signed-off-by: Matteo Golin --- system/uorb/listener.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/system/uorb/listener.c b/system/uorb/listener.c index ebee53005..fe7909030 100644 --- a/system/uorb/listener.c +++ b/system/uorb/listener.c @@ -62,7 +62,7 @@ struct listen_object_s SLIST_ENTRY(listen_object_s) node; /* Node of object info list */ struct orb_object object; /* Object id */ - orb_abstime timestamp; /* Time of lastest generation */ + orb_abstime timestamp; /* Time of last generation */ unsigned long generation; /* Latest generation */ FAR FILE *file; }; @@ -252,7 +252,7 @@ static int listener_add_object(FAR struct listen_list_s *objlist, * Name: listener_update * * Description: - * Update object list, print imformation if given object has new data. + * Update object list, print information if given object has new data. * * Input Parameters: * object Object to check state. @@ -269,7 +269,7 @@ static int listener_update(FAR struct listen_list_s *objlist, FAR struct listen_object_s *tmp; int ret; - /* Check wether object already exist in old list */ + /* Check whether object already exist in old list */ SLIST_FOREACH(tmp, objlist, node) { @@ -485,7 +485,7 @@ static int listener_generate_object_list(FAR struct listen_list_s *objlist, continue; } - /* Update object infomation to list. */ + /* Update object information to list. */ if (listener_update(objlist, &object) < 0) { @@ -568,7 +568,7 @@ static int listener_record(FAR const struct orb_metadata *meta, int fd, * Name: listener_monitor * * Description: - * Moniter objects by subscribe and print data. + * Monitor objects by subscribe and print data. * * Input Parameters: * objlist List of objects to subscribe. @@ -670,7 +670,7 @@ static void listener_monitor(FAR struct listen_list_s *objlist, } } - /* Loop poll and print recieved messages */ + /* Loop poll and print received messages */ while ((!nb_msgs || nb_recv_msgs < nb_msgs) && !g_should_exit) { @@ -734,7 +734,7 @@ static void listener_monitor(FAR struct listen_list_s *objlist, } orb_unsubscribe(fds[i].fd); - uorbinfo_raw("Object name:%s%d, recieved:%d", + uorbinfo_raw("Object name:%s%d, received:%d", tmp->object.meta->o_name, tmp->object.instance, recv_msgs[i]); } From 008433dcfe3a2647e0547b87b2341d36c25e73f5 Mon Sep 17 00:00:00 2001 From: p-szafonimateusz Date: Tue, 23 Dec 2025 10:20:17 +0100 Subject: [PATCH 029/568] testing/testsuites: add cmake support add cmake support for testsuites Signed-off-by: p-szafonimateusz Co-authored-by: v-wangshihang Co-authored-by: v-chenglong8 Co-authored-by: xuxin19 Co-authored-by: zhangshoukui --- testing/testsuites/CMakeLists.txt | 21 +++ testing/testsuites/kernel/CMakeLists.txt | 213 +++++++++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 testing/testsuites/CMakeLists.txt create mode 100644 testing/testsuites/kernel/CMakeLists.txt diff --git a/testing/testsuites/CMakeLists.txt b/testing/testsuites/CMakeLists.txt new file mode 100644 index 000000000..9b77c6d60 --- /dev/null +++ b/testing/testsuites/CMakeLists.txt @@ -0,0 +1,21 @@ +# ############################################################################## +# apps/testing/testsuites/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +nuttx_add_subdirectory() diff --git a/testing/testsuites/kernel/CMakeLists.txt b/testing/testsuites/kernel/CMakeLists.txt new file mode 100644 index 000000000..ce7f042cb --- /dev/null +++ b/testing/testsuites/kernel/CMakeLists.txt @@ -0,0 +1,213 @@ +# ############################################################################## +# apps/testing/testsuites/kernel/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_CM_FS_TEST) + set(INCDIR ${CMAKE_CURRENT_SOURCE_DIR}/fs/include ${NUTTX_DIR}/../apps/nshlib + ${NUTTX_DIR}/../apps/testing/cmocka/include) + file(GLOB FS_CSRCS ${CMAKE_CURRENT_SOURCE_DIR}/fs/cases/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/fs/common/*.c) + nuttx_add_application( + NAME + cmocka_fs_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + fs/cmocka_fs_test.c + ${FS_CSRCS} + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) +endif() + +if(CONFIG_CM_SCHED_TEST) + set(INCDIR ${CMAKE_CURRENT_SOURCE_DIR}/sched/include + ${NUTTX_DIR}/../apps/testing/cmocka/include) + file(GLOB SCHED_CSRCS ${CMAKE_CURRENT_SOURCE_DIR}/sched/cases/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/sched/common/*.c) + nuttx_add_application( + NAME + cmocka_sched_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + sched/cmocka_sched_test.c + ${SCHED_CSRCS} + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) +endif() + +if(CONFIG_CM_SYSCALL_TEST) + set(INCDIR + ${CMAKE_CURRENT_SOURCE_DIR}/syscall/include ${NUTTX_DIR}/../apps/nshlib + ${NUTTX_DIR}/../apps/testing/cmocka/include) + file(GLOB SYSCALL_CSRCS ${CMAKE_CURRENT_SOURCE_DIR}/syscall/cases/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/syscall/common/*.c) + nuttx_add_application( + NAME + cmocka_syscall_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + syscall/cmocka_syscall_test.c + ${SYSCALL_CSRCS} + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) +endif() + +if(CONFIG_CM_MM_TEST) + set(INCDIR ${CMAKE_CURRENT_SOURCE_DIR}/mm/include + ${NUTTX_DIR}/../apps/testing/cmocka/include) + file(GLOB MM_CSRCS ${CMAKE_CURRENT_SOURCE_DIR}/mm/cases/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/mm/common/*.c) + + nuttx_add_application( + NAME + cmocka_mm_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + mm/cmocka_mm_test.c + ${MM_CSRCS} + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) + nuttx_add_application( + NAME + mem_batch_opt_perf_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + mm/tool/mem_batch_opt_perf_test.c + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) + nuttx_add_application( + NAME + mem_cycle_opt_perf_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + mm/tool/mem_cycle_opt_perf_test.c + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) +endif() + +if(CONFIG_CM_TIME_TEST) + set(INCDIR ${CMAKE_CURRENT_SOURCE_DIR}/time/include + ${NUTTX_DIR}/../apps/testing/cmocka/include ${NUTTX_DIR}/include) + file(GLOB TIME_CSRCS ${CMAKE_CURRENT_SOURCE_DIR}/time/cases/*.c) + nuttx_add_application( + NAME + cmocka_time_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + time/cmocka_time_test.c + ${TIME_CSRCS} + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) +endif() + +if(CONFIG_CM_SOCKET_TEST) + set(INCDIR ${CMAKE_CURRENT_SOURCE_DIR}/socket/include + ${NUTTX_DIR}/../apps/testing/cmocka/include) + file(GLOB SOCKET_CSRCS ${CMAKE_CURRENT_SOURCE_DIR}/socket/cases/*.c) + nuttx_add_application( + NAME + cmocka_socket_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + socket/cmocka_socket_test.c + ${SOCKET_CSRCS} + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) +endif() + +if(CONFIG_CM_PTHREAD_TEST) + set(INCDIR ${CMAKE_CURRENT_SOURCE_DIR}/pthread/include + ${NUTTX_DIR}/../apps/testing/cmocka/include) + file(GLOB PTHREAD_CSRCS ${CMAKE_CURRENT_SOURCE_DIR}/pthread/cases/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/pthread/common/*.c) + nuttx_add_application( + NAME + cmocka_pthread_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + pthread/cmocka_pthread_test.c + ${PTHREAD_CSRCS} + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) +endif() + +if(CONFIG_CM_MUTEX_TEST) + set(INCDIR ${CMAKE_CURRENT_SOURCE_DIR}/mutex/include + ${NUTTX_DIR}/../apps/testing/cmocka/include) + file(GLOB MUTEX_CSRCS ${CMAKE_CURRENT_SOURCE_DIR}/mutex/cases/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/mutex/common/*.c) + nuttx_add_application( + NAME + cmocka_mutex_test + STACKSIZE + ${CONFIG_TESTS_TESTSUITES_STACKSIZE} + PRIORITY + ${CONFIG_TESTS_TESTSUITES_PRIORITY} + SRCS + mutex/cmocka_mutex_test.c + ${MUTEX_CSRCS} + INCLUDE_DIRECTORIES + ${INCDIR} + DEPENDS + cmocka) +endif() From 951740627b2b01516e526ccf43db50755770154e Mon Sep 17 00:00:00 2001 From: p-szafonimateusz Date: Tue, 23 Dec 2025 10:42:31 +0100 Subject: [PATCH 030/568] testing/testsuites/Kconfig: add missing dependencies for test cases add missing dependencies for test cases to avoid compilation errors Signed-off-by: p-szafonimateusz --- testing/testsuites/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/testsuites/Kconfig b/testing/testsuites/Kconfig index a6b6928cc..e6afff5f6 100644 --- a/testing/testsuites/Kconfig +++ b/testing/testsuites/Kconfig @@ -38,7 +38,7 @@ config CM_MM_TEST config CM_TIME_TEST bool "enbale time test" - depends on !DISABLE_POSIX_TIMERS + depends on !DISABLE_POSIX_TIMERS && SIG_EVTHREAD default n config CM_PTHREAD_TEST @@ -47,6 +47,7 @@ config CM_PTHREAD_TEST config CM_SOCKET_TEST bool "enbale socket test" + depends on NET default n config CM_SYSCALL_TEST From 8856a587a67f0d93e8ab8494443dd825b88725b3 Mon Sep 17 00:00:00 2001 From: p-szafonimateusz Date: Tue, 23 Dec 2025 10:55:13 +0100 Subject: [PATCH 031/568] testsuites/Kconfig: fix codespell issues fix codespell issues Signed-off-by: p-szafonimateusz --- testing/testsuites/Kconfig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/testing/testsuites/Kconfig b/testing/testsuites/Kconfig index e6afff5f6..8ed01ffcf 100644 --- a/testing/testsuites/Kconfig +++ b/testing/testsuites/Kconfig @@ -29,33 +29,33 @@ config CM_FS_TEST default n config CM_SCHED_TEST - bool "enbale schedule test" + bool "enable schedule test" default n config CM_MM_TEST - bool "enbale MM test" + bool "enable MM test" default n config CM_TIME_TEST - bool "enbale time test" + bool "enable time test" depends on !DISABLE_POSIX_TIMERS && SIG_EVTHREAD default n config CM_PTHREAD_TEST - bool "enbale pthread test" + bool "enable pthread test" default n config CM_SOCKET_TEST - bool "enbale socket test" + bool "enable socket test" depends on NET default n config CM_SYSCALL_TEST - bool "enbale syscall test" + bool "enable syscall test" default n config CM_MUTEX_TEST - bool "enbale mutex test" + bool "enable mutex test" default n endif # TESTS_TESTSUITES From b78ab0c6e8e83712cbdc6bf8b6340fa41c00028a Mon Sep 17 00:00:00 2001 From: zhengyu9 Date: Fri, 23 Aug 2024 16:34:00 +0800 Subject: [PATCH 032/568] fsutils/flashtool: add flashtool command support Introducing flashtool command with following capabilities: - Flash geometry information display - Bad blocks checking - Page contents read/write - Block erase - Full flash erase Signed-off-by: zhengyu9 --- fsutils/flashtool/CMakeLists.txt | 24 ++ fsutils/flashtool/Kconfig | 29 +++ fsutils/flashtool/Make.defs | 24 ++ fsutils/flashtool/Makefile | 33 +++ fsutils/flashtool/flashtool_main.c | 373 +++++++++++++++++++++++++++++ 5 files changed, 483 insertions(+) create mode 100644 fsutils/flashtool/CMakeLists.txt create mode 100644 fsutils/flashtool/Kconfig create mode 100644 fsutils/flashtool/Make.defs create mode 100644 fsutils/flashtool/Makefile create mode 100644 fsutils/flashtool/flashtool_main.c diff --git a/fsutils/flashtool/CMakeLists.txt b/fsutils/flashtool/CMakeLists.txt new file mode 100644 index 000000000..338c1a394 --- /dev/null +++ b/fsutils/flashtool/CMakeLists.txt @@ -0,0 +1,24 @@ +# ############################################################################## +# apps/fsutils/flashtool/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_FSUTILS_FLASHTOOL) + nuttx_add_application(MODULE ${CONFIG_FSUTILS_FLASHTOOL} NAME flashtool SRCS + flashtool_main.c) +endif() diff --git a/fsutils/flashtool/Kconfig b/fsutils/flashtool/Kconfig new file mode 100644 index 000000000..07f89671a --- /dev/null +++ b/fsutils/flashtool/Kconfig @@ -0,0 +1,29 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config FSUTILS_FLASHTOOL + tristate "FLASH Tool Command" + default n + depends on MTD + depends on BCH + ---help--- + Enable support for the FLASH tool. + +if FSUTILS_FLASHTOOL + +config FSUTILS_FLASHTOOL_STACKSIZE + int "flashtool stack size" + default DEFAULT_TASK_STACKSIZE + ---help--- + This is the stack size that will be used when starting the flashtool. + +config FSUTILS_FLASHTOOL_PRIORITY + int "flashtool priority" + default 100 + ---help--- + This is the task priority that will be used when starting the flashtool. + +endif + diff --git a/fsutils/flashtool/Make.defs b/fsutils/flashtool/Make.defs new file mode 100644 index 000000000..55f2c72c9 --- /dev/null +++ b/fsutils/flashtool/Make.defs @@ -0,0 +1,24 @@ +############################################################################ +# apps/fsutils/flashtool/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_FSUTILS_FLASHTOOL),) +CONFIGURED_APPS += $(APPDIR)/fsutils/flashtool +endif + diff --git a/fsutils/flashtool/Makefile b/fsutils/flashtool/Makefile new file mode 100644 index 000000000..deac9500a --- /dev/null +++ b/fsutils/flashtool/Makefile @@ -0,0 +1,33 @@ +############################################################################ +# apps/fsutils/flashtool/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# flashtool Application + +PROGNAME = flashtool +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) +MODULE = $(CONFIG_FSUTILS_FLASHTOOL) + +MAINSRC = flashtool_main.c + +include $(APPDIR)/Application.mk + diff --git a/fsutils/flashtool/flashtool_main.c b/fsutils/flashtool/flashtool_main.c new file mode 100644 index 000000000..8e4f288f3 --- /dev/null +++ b/fsutils/flashtool/flashtool_main.c @@ -0,0 +1,373 @@ +/**************************************************************************** + * apps/fsutils/flashtool/flashtool_main.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum opr_list +{ + HELP, DEVICE_INFO, READ_PAGE, WRITE_PAGE, ERASE_BLOCK, ERASE_ALL, + CHECK_BAD_BLOCK +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void display_help(void) +{ + printf("Usage : flashtool [OPTION [ARG]] device_name ...\n"); + printf("-h show this help statement\n"); + printf("-i display device geometry information\n"); + printf("-r read the specified pages\n"); + printf("-w write the specified pages\n"); + printf("-e erase the specified blocks\n"); + printf("-n number of pages or blocks\n"); + printf("-f file name for read or write\n"); + printf("-b check whether is bad\n"); + printf("-c erase all of the flash\n"); + printf("-d device name\n"); +} + +static void display_device_info(FAR const struct mtd_geometry_s *geo) +{ + printf("Size of one read/write page: %lu\n", geo->blocksize); + printf("Size of one erase block: %lu\n", geo->erasesize); + printf("Number of erase blocks: %lu\n", geo->neraseblocks); +} + +static int read_page(int fd, FAR const struct mtd_geometry_s *geo, + off_t start_page, size_t npages) +{ + FAR unsigned char *buf; + ssize_t ret = OK; + off_t seek; + size_t i; + + buf = malloc(geo->blocksize); + if (!buf) + { + printf("ERROR: read_page cannot allocate memory %d\n", geo->blocksize); + return ERROR; + } + + seek = geo->blocksize * start_page; + if (lseek(fd, seek, SEEK_SET) != seek) + { + printf("ERROR: Cannot seek mtd to offset %lld: %d", seek, errno); + goto oops; + } + + printf("Flash pages contents:\n"); + for (i = 0; i < npages; i++) + { + ret = read(fd, buf, geo->blocksize); + if (ret < 0) + { + printf("ERROR: Read error: %d!\n", errno); + goto oops; + } + + printf("Flash page %lld:\n", start_page + i); + lib_dumpbuffer(NULL, buf, ret); + } + +oops: + free(buf); + return ret; +} + +/* Write npages data from img to flash + * If size of img is less than npags, only write img size + */ + +static int write_page(int fd, FAR const struct mtd_geometry_s *geo, + off_t start_page, size_t npages, FAR const char *img) +{ + FAR unsigned char *buf; + off_t imglen; + off_t seek; + off_t i; + int fd_src; + int ret = OK; + + if (img == NULL) + { + printf("ERROR: Need source file path!\n"); + return ERROR; + } + + printf("Write data from %s...\n", img); + seek = geo->blocksize * start_page; + if (lseek(fd, seek, SEEK_SET) != seek) + { + printf("ERROR: cannot seek mtd to offset %lld: %d", seek, errno); + return ERROR; + } + + fd_src = open(img, O_RDONLY); + if (fd_src < 0) + { + printf("ERROR: Open file %s failed: %d\n", img, errno); + return ERROR; + } + + imglen = lseek(fd_src, 0, SEEK_END); + if (lseek(fd_src, 0, SEEK_SET) != 0) + { + close(fd_src); + return ERROR; + } + + /* Malloc a size of page for buf */ + + buf = malloc(geo->blocksize); + if (!buf) + { + printf("ERROR: write_page cannot allocate memory %d\n", + geo->blocksize); + close(fd_src); + return ERROR; + } + + for (i = start_page; i < start_page + npages; i++) + { + ret = read(fd_src, buf, + (imglen < geo->blocksize) ? imglen : geo->blocksize); + if (ret < 0) + { + printf("ERROR: read source file error: %d!\n", errno); + goto oops; + } + + ret = write(fd, buf, geo->blocksize); + if (ret < 0) + { + printf("ERROR: write error: %d!\n", errno); + goto oops; + } + + imglen -= geo->blocksize; + if (imglen <= 0) + { + break; + } + } + +oops: + close(fd_src); + free(buf); + return ret; +} + +static int erase_block(int fd, off_t start_block, + size_t nblocks) +{ + struct mtd_erase_s erase; + int ret; + + printf("Erase block from %lld to %lld!\n", start_block, + start_block + nblocks -1); + erase.startblock = start_block; + erase.nblocks = nblocks; + ret = ioctl(fd, MTDIOC_ERASESECTORS, &erase); + if (ret < 0) + { + printf("ERROR: Erase failed: %d!\n", errno); + } + + return ret; +} + +static int erase_all(int fd) +{ + if (ioctl(fd, MTDIOC_BULKERASE, 0) < 0) + { + printf("ERROR: MTD ioctl(MTDIOC_BULKERASE) failed: %d\n", errno); + return ERROR; + } + + return OK; +} + +static int check_bad_block(int fd, FAR const struct mtd_geometry_s *geo) +{ + struct mtd_bad_block_s bad_block; + int flag = 0; + int ret; + int i; + + printf("Check bad blocks in flash......\n"); + for (i = 0; i < geo->neraseblocks; i++) + { + bad_block.block_num = i; + ret = ioctl(fd, MTDIOC_ISBAD, &bad_block); + if (ret != OK) + { + printf("ERROR: MTDIOC_ISBAD failed: %d!\n", errno); + return ERROR; + } + else + { + if (bad_block.bad_flag) + { + printf("Block %d is bad!\n", i); + flag = 1; + } + } + } + + if (flag == 0) + { + printf("No bad blocks!\n"); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + FAR char *mtddev = NULL; + FAR char *img = NULL; + struct mtd_geometry_s geo; + enum opr_list opr = HELP; + off_t npages = 1; + off_t start; + int option; + int mode = O_RDONLY; + int fd; + int ret; + + while ((option = getopt(argc, argv, ":hir:w:e:n:f:bcd:")) != -1) + { + switch (option) + { + case 'h': + display_help(); + exit(0); + case 'i': + opr = DEVICE_INFO; + break; + case 'r': + opr = READ_PAGE; + start = strtoul(optarg, NULL, 0); + break; + case 'w': + opr = WRITE_PAGE; + mode = O_RDWR; + start = strtoul(optarg, NULL, 0); + break; + case 'e': + opr = ERASE_BLOCK; + start = strtoul(optarg, NULL, 0); + break; + case 'n': + npages = strtoul(optarg, NULL, 0); + break; + case 'f': + img = optarg; + break; + case 'b': + opr = CHECK_BAD_BLOCK; + break; + case 'c': + opr = ERASE_ALL; + break; + case 'd': + mtddev = optarg; + break; + case ':': + printf("Error: Missing required argument\n"); + exit(1); + case '?': + printf("Error: Unrecognized option\n"); + exit(1); + } + } + + if (mtddev == NULL) + { + printf("Error: Device name is required!\n"); + return -1; + } + + fd = open(mtddev, mode, 0777); + if (fd < 0) + { + printf("ERROR: Failed to open '%s': %d\n", mtddev, errno); + return -1; + } + + ret = ioctl(fd, MTDIOC_GEOMETRY, &geo); + if (ret < 0) + { + printf("ERROR: Ioctl MTDIOC_GEOMETRY failed: %d\n", errno); + goto oops; + } + + switch (opr) + { + case DEVICE_INFO: + display_device_info(&geo); + break; + case READ_PAGE: + ret = read_page(fd, &geo, start, npages); + break; + case WRITE_PAGE: + ret = write_page(fd, &geo, start, npages, img); + break; + case ERASE_BLOCK: + ret = erase_block(fd, start, npages); + break; + case ERASE_ALL: + ret = erase_all(fd); + break; + case CHECK_BAD_BLOCK: + ret = check_bad_block(fd, &geo); + break; + default: + } + +oops: + close(fd); + return ret; +} From 4d98ecccafdc1927d1b5363c6540c2be53f30d5e Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Mon, 15 Dec 2025 21:49:17 +0800 Subject: [PATCH 033/568] testing/ostest: add hrtimer API functional tests Add functional tests for the newly added hrtimer APIs, including hrtimer_init(), hrtimer_start(), and hrtimer_cancel(). Signed-off-by: Chengdong Wang --- testing/ostest/CMakeLists.txt | 4 + testing/ostest/Makefile | 6 + testing/ostest/hrtimer.c | 228 ++++++++++++++++++++++++++++++++++ testing/ostest/ostest.h | 4 + testing/ostest/ostest_main.c | 10 +- 5 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 testing/ostest/hrtimer.c diff --git a/testing/ostest/CMakeLists.txt b/testing/ostest/CMakeLists.txt index 2bbe6a730..6e971373d 100644 --- a/testing/ostest/CMakeLists.txt +++ b/testing/ostest/CMakeLists.txt @@ -153,6 +153,10 @@ if(CONFIG_TESTING_OSTEST) list(APPEND SRCS nxevent.c) endif() + if(CONFIG_HRTIMER AND CONFIG_BUILD_FLAT) + list(APPEND SRCS hrtimer.c) + endif() + if(CONFIG_BUILD_FLAT) list(APPEND SRCS wdog.c) endif() diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile index c631fb3b8..5f7d5d4f8 100644 --- a/testing/ostest/Makefile +++ b/testing/ostest/Makefile @@ -150,6 +150,12 @@ CSRCS += nxevent.c endif endif +ifeq ($(CONFIG_HRTIMER),y) +ifeq ($(CONFIG_BUILD_FLAT),y) +CSRCS += hrtimer.c +endif +endif + ifeq ($(CONFIG_BUILD_FLAT),y) CSRCS += wdog.c endif diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c new file mode 100644 index 000000000..9b2d61430 --- /dev/null +++ b/testing/ostest/hrtimer.c @@ -0,0 +1,228 @@ +/**************************************************************************** + * apps/testing/ostest/hrtimer.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include "ostest.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NSEC_PER_50MS (50 * NSEC_PER_MSEC) + +/* Set a 1ms margin to allow hrtimertest to pass in QEMU. + * + * QEMU is a virtual platform, and its timer resolution and scheduling + * latency may be less precise than on real hardware. Using a larger + * margin ensures that tests do not fail due to timing inaccuracies. + * + * On real hardware (verified on the a2g-tc397-5v-tft board), this + * margin can be reduced to less than 5 ns because timers are precise + * and deterministic. + */ + +#define HRTIMER_TEST_MARGIN (NSEC_PER_MSEC) + +/* Simple assertion macro for HRTimer test cases */ +#define HRTIMER_TEST(expr, value) \ + do \ + { \ + ret = (expr); \ + if (ret != (value)) \ + { \ + printf("ERROR: HRTimer test failed, line=%d ret=%d\n", \ + __LINE__, ret); \ + ASSERT(false); \ + } \ + } \ + while (0) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Structure for HRTimer test tracking */ + +struct hrtimer_test_s +{ + hrtimer_t timer; /* HRTimer instance */ + uint64_t previous; /* Previous timestamp in nanoseconds */ + uint32_t count; /* Number of timer expirations */ + uint32_t period; /* Expected period between expirations */ + bool active; /* True while the test is still running */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hrtimer_test_init + * + * Description: + * Initialize a hrtimer_test_s structure for a new test. + * + * Input Parameters: + * hrtimer_test - Pointer to the test structure to initialize + * period - Expected timer period in nanoseconds + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void hrtimer_test_init(FAR struct hrtimer_test_s *hrtimer_test, + uint32_t period) +{ + hrtimer_test->previous = 0; + hrtimer_test->count = 0; + hrtimer_test->active = true; + hrtimer_test->period = period; +} + +/**************************************************************************** + * Name: test_hrtimer_callback + * + * Description: + * HRTimer callback function for test. + * + * - Verifies the timer interval is exactly 500ms (nanosecond precision) + * - Stops the test after 15 expirations + * - Re-arms the timer in absolute mode + * + * Input Parameters: + * hrtimer - Pointer to the expired HRTimer instance + * + * Returned Value: + * Timer period in nanoseconds (NSEC_PER_50MS) + * + ****************************************************************************/ + +static uint32_t test_hrtimer_callback(FAR hrtimer_t *hrtimer) +{ + struct timespec ts; + uint32_t diff; + uint64_t now; + int ret; + + FAR struct hrtimer_test_s *test = + (FAR struct hrtimer_test_s *)hrtimer; + + /* Increment expiration count */ + + test->count++; + + /* Get current system time */ + + clock_systime_timespec(&ts); + now = clock_time2nsec(&ts); + + /* Skip comparison for first two invocations */ + + if (test->count > 2) + { + /* Verify the timer interval is exactly + * 500ms with nsec resolution + */ + + diff = (uint32_t)(now - test->previous); + + HRTIMER_TEST(NSEC_PER_50MS < diff + HRTIMER_TEST_MARGIN, true); + HRTIMER_TEST(NSEC_PER_50MS > diff - HRTIMER_TEST_MARGIN, true); + } + + test->previous = now; + + /* Stop the test after 15 expirations */ + + if (test->count >= 15) + { + ret = hrtimer_cancel(hrtimer); + HRTIMER_TEST(ret, 0); + + test->active = false; + } + + return test->period; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hrtimer_test + * + * Description: + * Entry point for high-resolution timer functional test. + * + * - Initializes a HRTimer + * - Starts it with a 500ms relative timeout + * - Verifies subsequent expirations occur at 500ms intervals + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void hrtimer_test(void) +{ + int ret; + struct hrtimer_test_s hrtimer_test; + + /* Initialize test structure */ + + hrtimer_test_init(&hrtimer_test, NSEC_PER_50MS); + + /* Initialize the high-resolution timer */ + + hrtimer_init(&hrtimer_test.timer, + test_hrtimer_callback, + NULL); + + /* Start the timer with 500ms relative timeout */ + + ret = hrtimer_start(&hrtimer_test.timer, + hrtimer_test.period, + HRTIMER_MODE_REL); + + HRTIMER_TEST(ret, OK); + + /* Wait until the test completes */ + + while (hrtimer_test.active) + { + usleep(USEC_PER_MSEC); + } +} diff --git a/testing/ostest/ostest.h b/testing/ostest/ostest.h index fec7f81c2..30f16da5d 100644 --- a/testing/ostest/ostest.h +++ b/testing/ostest/ostest.h @@ -304,4 +304,8 @@ int sem_nfreeholders(void); void nxevent_test(void); #endif +#if defined(CONFIG_SCHED_EVENTS) && defined(CONFIG_BUILD_FLAT) +void hrtimer_test(void); +#endif + #endif /* __APPS_TESTING_OSTEST_OSTEST_H */ diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 201d52e38..48dc94da7 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -625,6 +625,14 @@ static int user_main(int argc, char *argv[]) check_test_memory_usage(); #endif +#if defined(CONFIG_HRTIMER) && defined(CONFIG_BUILD_FLAT) + /* Verify hrtimer */ + + printf("\nuser_main: hrtimer test\n"); + hrtimer_test(); + check_test_memory_usage(); +#endif + /* Compare memory usage at time ostest_main started until * user_main exits. These should not be identical, but should * be similar enough that we can detect any serious OS memory @@ -705,7 +713,7 @@ int main(int argc, FAR char **argv) stdio_test(); #ifdef SDCC - /* I am not yet certain why SDCC does not like the following initilizers. + /* I am not yet certain why SDCC does not like the following initializers. * It involves some issues with 2- vs 3-byte pointer types. */ From 837c27d6e3f07c2d1ea1d024a1c7379b7dbee148 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Tue, 14 May 2024 14:56:41 +0800 Subject: [PATCH 034/568] netutils/libwebsockets: add cmake support add libwebsockets cmake support Signed-off-by: zhanghongyu --- netutils/libwebsockets/CMakeLists.txt | 188 +++++++++++++++++++++ netutils/libwebsockets/libwebsockets.patch | 32 ---- 2 files changed, 188 insertions(+), 32 deletions(-) create mode 100644 netutils/libwebsockets/CMakeLists.txt diff --git a/netutils/libwebsockets/CMakeLists.txt b/netutils/libwebsockets/CMakeLists.txt new file mode 100644 index 000000000..7977f9311 --- /dev/null +++ b/netutils/libwebsockets/CMakeLists.txt @@ -0,0 +1,188 @@ +# ############################################################################## +# apps/netutils/libwebsockets/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_NETUTILS_LIBWEBSOCKETS) + + # ############################################################################ + # Config and Fetch MbedTLS lib + # ############################################################################ + + set(LIBWEBSOCKETS_DIR ${CMAKE_CURRENT_LIST_DIR}/libwebsockets) + + if(NOT EXISTS ${LIBWEBSOCKETS_DIR}) + set(LIBWEBSOCKETS_URL "https://github.com/warmcat/libwebsockets/archive") + FetchContent_Declare( + libwebsockets_fetch + URL ${LIBWEBSOCKETS_URL}/v${CONFIG_NETUTILS_LIBWEBSOCKETS_VERSION}.zip + SOURCE_DIR ${LIBWEBSOCKETS_DIR} BINARY_DIR + ${CMAKE_BINARY_DIR}/apps/netutils/libwebsockets/libwebsockets + DOWNLOAD_NO_PROGRESS true + TIMEOUT 30) + + FetchContent_GetProperties(libwebsockets_fetch) + + if(NOT libwebsockets_fetch_POPULATED) + FetchContent_Populate(libwebsockets_fetch) + endif() + + execute_process( + COMMAND sh -c "patch -p0 < ${CMAKE_CURRENT_LIST_DIR}/libwebsockets.patch" + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) + message("patching done") + endif() + + # ############################################################################ + # Flags + # ############################################################################ + + string(REGEX MATCHALL "[0-9]" versions + "${CONFIG_NETUTILS_LIBWEBSOCKETS_VERSION}") + list(GET versions 0 VERSION_MAJOR) + list(GET versions 1 VERSION_MINOR) + list(GET versions 2 VERSION_PATCH) + set(FLAGS + -DLWS_LIBRARY_VERSION_MAJOR=${VERSION_MAJOR} + -DLWS_LIBRARY_VERSION_MINOR=${VERSION_MINOR} + -DLWS_LIBRARY_VERSION_PATCH=${VERSION_PATCH} + -DLWS_LIBRARY_VERSION_PATCH_ELABORATED=${VERSION_PATCH}-unknown + -DLWS_LIBRARY_VERSION="${CONFIG_NETUTILS_LIBWEBSOCKETS_VERSION}-unknown" + -Wno-shadow) + + set(INCDIR + . + ${LIBWEBSOCKETS_DIR}/lib/core + ${LIBWEBSOCKETS_DIR}/lib/plat/unix + ${LIBWEBSOCKETS_DIR}/lib/event-libs + ${LIBWEBSOCKETS_DIR}/lib/system/smd + ${LIBWEBSOCKETS_DIR}/lib/system/metrics + ${LIBWEBSOCKETS_DIR}/lib/core-net + ${LIBWEBSOCKETS_DIR}/lib/roles + ${LIBWEBSOCKETS_DIR}/lib/roles/http + ${LIBWEBSOCKETS_DIR}/lib/roles/h1 + ${LIBWEBSOCKETS_DIR}/lib/roles/h2 + ${LIBWEBSOCKETS_DIR}/lib/roles/ws + ${LIBWEBSOCKETS_DIR}/lib/tls + ${LIBWEBSOCKETS_DIR}/lib/tls/mbedtls/wrapper/include + ${LIBWEBSOCKETS_DIR}/lib/tls/mbedtls/wrapper/include/internal) + + set(CSRCS + ${LIBWEBSOCKETS_DIR}/lib/plat/unix/unix-caps.c + ${LIBWEBSOCKETS_DIR}/lib/plat/unix/unix-misc.c + ${LIBWEBSOCKETS_DIR}/lib/plat/unix/unix-init.c + ${LIBWEBSOCKETS_DIR}/lib/plat/unix/unix-file.c + ${LIBWEBSOCKETS_DIR}/lib/plat/unix/unix-pipe.c + ${LIBWEBSOCKETS_DIR}/lib/plat/unix/unix-service.c + ${LIBWEBSOCKETS_DIR}/lib/plat/unix/unix-sockets.c + ${LIBWEBSOCKETS_DIR}/lib/plat/unix/unix-fds.c + ${LIBWEBSOCKETS_DIR}/lib/core/alloc.c + ${LIBWEBSOCKETS_DIR}/lib/core/buflist.c + ${LIBWEBSOCKETS_DIR}/lib/core/context.c + ${LIBWEBSOCKETS_DIR}/lib/core/lws_dll2.c + ${LIBWEBSOCKETS_DIR}/lib/core/lws_map.c + ${LIBWEBSOCKETS_DIR}/lib/core/libwebsockets.c + ${LIBWEBSOCKETS_DIR}/lib/core/logs.c + ${LIBWEBSOCKETS_DIR}/lib/core/vfs.c + ${LIBWEBSOCKETS_DIR}/lib/misc/base64-decode.c + ${LIBWEBSOCKETS_DIR}/lib/misc/cache-ttl/lws-cache-ttl.c + ${LIBWEBSOCKETS_DIR}/lib/misc/cache-ttl/heap.c + ${LIBWEBSOCKETS_DIR}/lib/misc/cache-ttl/file.c + ${LIBWEBSOCKETS_DIR}/lib/misc/dir.c + ${LIBWEBSOCKETS_DIR}/lib/misc/prng.c + ${LIBWEBSOCKETS_DIR}/lib/misc/lws-ring.c + ${LIBWEBSOCKETS_DIR}/lib/misc/lwsac/lwsac.c + ${LIBWEBSOCKETS_DIR}/lib/misc/lwsac/cached-file.c + ${LIBWEBSOCKETS_DIR}/lib/misc/lejp.c + ${LIBWEBSOCKETS_DIR}/lib/misc/sha-1.c + ${LIBWEBSOCKETS_DIR}/lib/system/system.c + ${LIBWEBSOCKETS_DIR}/lib/system/smd/smd.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/dummy-callback.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/output.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/close.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/network.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/vhost.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/pollfd.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/service.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/sorted-usec-list.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/wsi.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/wsi-timeout.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/adopt.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/state.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/client/client.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/client/connect.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/client/connect2.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/client/connect3.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/client/connect4.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/client/sort-dns.c + ${LIBWEBSOCKETS_DIR}/lib/core-net/client/conmon.c + ${LIBWEBSOCKETS_DIR}/lib/roles/pipe/ops-pipe.c + ${LIBWEBSOCKETS_DIR}/lib/roles/http/header.c + ${LIBWEBSOCKETS_DIR}/lib/roles/http/date.c + ${LIBWEBSOCKETS_DIR}/lib/roles/http/parsers.c + ${LIBWEBSOCKETS_DIR}/lib/roles/http/cookie.c + ${LIBWEBSOCKETS_DIR}/lib/roles/h1/ops-h1.c + ${LIBWEBSOCKETS_DIR}/lib/roles/h2/http2.c + ${LIBWEBSOCKETS_DIR}/lib/roles/h2/hpack.c + ${LIBWEBSOCKETS_DIR}/lib/roles/h2/ops-h2.c + ${LIBWEBSOCKETS_DIR}/lib/roles/ws/ops-ws.c + ${LIBWEBSOCKETS_DIR}/lib/roles/ws/client-ws.c + ${LIBWEBSOCKETS_DIR}/lib/roles/ws/client-parser-ws.c + ${LIBWEBSOCKETS_DIR}/lib/roles/raw-skt/ops-raw-skt.c + ${LIBWEBSOCKETS_DIR}/lib/roles/raw-file/ops-raw-file.c + ${LIBWEBSOCKETS_DIR}/lib/roles/http/client/client-http.c + ${LIBWEBSOCKETS_DIR}/lib/event-libs/poll/poll.c + ${LIBWEBSOCKETS_DIR}/lib/tls/tls.c + ${LIBWEBSOCKETS_DIR}/lib/tls/tls-network.c + ${LIBWEBSOCKETS_DIR}/lib/tls/tls-sessions.c + ${LIBWEBSOCKETS_DIR}/lib/tls/tls-client.c + ${LIBWEBSOCKETS_DIR}/lib/tls/mbedtls/mbedtls-tls.c + ${LIBWEBSOCKETS_DIR}/lib/tls/mbedtls/mbedtls-extensions.c + ${LIBWEBSOCKETS_DIR}/lib/tls/mbedtls/mbedtls-x509.c + ${LIBWEBSOCKETS_DIR}/lib/tls/mbedtls/mbedtls-ssl.c + ${LIBWEBSOCKETS_DIR}/lib/tls/mbedtls/mbedtls-session.c + ${LIBWEBSOCKETS_DIR}/lib/tls/mbedtls/mbedtls-client.c) + + if(CONFIG_NETUTILS_MQTTC) + list(APPEND INCDIR ${LIBWEBSOCKETS_DIR}/lib/roles/mqtt) + list( + APPEND + CSRCS + ${LIBWEBSOCKETS_DIR}/lib/roles/mqtt/mqtt.c + ${LIBWEBSOCKETS_DIR}/lib/roles/mqtt/ops-mqtt.c + ${LIBWEBSOCKETS_DIR}/lib/roles/mqtt/primitives.c + ${LIBWEBSOCKETS_DIR}/lib/roles/mqtt/client/client-mqtt.c + ${LIBWEBSOCKETS_DIR}/lib/roles/mqtt/client/client-mqtt-handshake.c) + + endif() + + # ############################################################################ + # Library Configuration + # ############################################################################ + + set_property( + TARGET nuttx + APPEND + PROPERTY NUTTX_INCLUDE_DIRECTORIES ${LIBWEBSOCKETS_DIR}/include) + + nuttx_add_library(libwebsockets STATIC) + target_sources(libwebsockets PRIVATE ${CSRCS}) + target_compile_options(libwebsockets PRIVATE ${FLAGS}) + target_include_directories(libwebsockets PRIVATE ${INCDIR}) + +endif() diff --git a/netutils/libwebsockets/libwebsockets.patch b/netutils/libwebsockets/libwebsockets.patch index 3576e8c4e..f2468fa6f 100644 --- a/netutils/libwebsockets/libwebsockets.patch +++ b/netutils/libwebsockets/libwebsockets.patch @@ -33,22 +33,6 @@ if (!unix_skt && setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void *)&optval, optlen) < 0) return 1; #elif !defined(__APPLE__) && \ -@@ -190,6 +190,7 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt) - return lws_plat_set_nonblocking(fd); - } - -+#if !defined(__NuttX__) - static const int ip_opt_lws_flags[] = { - LCCSCF_IP_LOW_LATENCY, LCCSCF_IP_HIGH_THROUGHPUT, - LCCSCF_IP_HIGH_RELIABILITY -@@ -210,6 +211,7 @@ static const char *ip_opt_names[] = { - #endif - }; - #endif -+#endif - - int - lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags) @@ -237,7 +239,8 @@ lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags) !defined(__sun) && \ !defined(__HAIKU__) && \ @@ -59,22 +43,6 @@ /* the BSDs don't have SO_PRIORITY */ -@@ -255,6 +258,7 @@ lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags) - } - #endif - -+#if !defined(__NuttX__) - for (n = 0; n < 4; n++) { - if (!(lws_flags & ip_opt_lws_flags[n])) - continue; -@@ -272,6 +276,7 @@ lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags) - lwsl_notice("%s: set ip flag %s\n", __func__, - ip_opt_names[n]); - } -+#endif - - return ret; - } --- libwebsockets/lib/roles/ws/client-ws.c +++ libwebsockets/lib/roles/ws/client-ws.c From 4b3070c08148f245f0dc43c31b6583467f04a17b Mon Sep 17 00:00:00 2001 From: meijian Date: Sun, 29 Sep 2024 16:26:14 +0800 Subject: [PATCH 035/568] apps/net: add ip conflict check API Supports checking for IP conflicts on a NIC. Signed-off-by: meijian --- include/netutils/netlib.h | 6 ++ netutils/netlib/CMakeLists.txt | 6 ++ netutils/netlib/Makefile | 6 ++ netutils/netlib/netlib_checkifconflict.c | 103 +++++++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 netutils/netlib/netlib_checkifconflict.c diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 469bd0461..9f8f744cd 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -499,6 +499,12 @@ int netlib_getifstatistics(FAR const char *ifname, FAR struct netdev_statistics_s *stat); #endif +/* Network check support */ + +#ifdef CONFIG_NET_ARP_ACD +int netlib_check_ifconflict(FAR const char *ifname); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt index 66bc927a0..560a71834 100644 --- a/netutils/netlib/CMakeLists.txt +++ b/netutils/netlib/CMakeLists.txt @@ -143,6 +143,12 @@ if(CONFIG_NETUTILS_NETLIB) endif() endif() + # Network check support + + if(CONFIG_NET_ARP_ACD) + list(APPEND SRCS netlib_checkifconflict.c) + endif() + target_sources(apps PRIVATE ${SRCS}) endif() diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index c590970e5..237cc76de 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -142,4 +142,10 @@ CSRCS += netlib_ipmsfilter.c endif endif +# Network check support + +ifeq ($(CONFIG_NET_ARP_ACD),y) +CSRCS += netlib_checkifconflict.c +endif + include $(APPDIR)/Application.mk diff --git a/netutils/netlib/netlib_checkifconflict.c b/netutils/netlib/netlib_checkifconflict.c new file mode 100644 index 000000000..5aebddd8e --- /dev/null +++ b/netutils/netlib/netlib_checkifconflict.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * apps/netutils/netlib/netlib_checkifconflict.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "netutils/netlib.h" + +#ifdef CONFIG_NET_ARP_ACD + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determines the size of an intermediate buffer that must be large enough + * to handle the longest line generated by this logic. + */ + +#define PROCFS_LINELEN 80 +#define PROCFS_NET_PATH "/proc/net/" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netlib_check_ifconflict + * + * Description: + * Check the network driver ip conflict + * + * Parameters: + * ifname The name of the interface to use + * + * Return: + * 0 on no conflict; a nagtive on failure; 1 on conflict + * + ****************************************************************************/ + +int netlib_check_ifconflict(FAR const char *ifname) +{ + int conflict = 0; + char path[32]; + char line[PROCFS_LINELEN]; + FAR FILE *stream; + + if (ifname == NULL) + { + fprintf(stderr, "ERROR: ifname is NULL \n"); + return -EINVAL; + } + + snprintf(path, sizeof(path), "%s%s", PROCFS_NET_PATH, ifname); + ninfo("get dev statistics from %s \n", path); + + stream = fopen(path, "r"); + if (stream == NULL) + { + fprintf(stderr, "ERROR: Failed to open path:%s \n", path); + return -errno; + } + + while (fgets(line, sizeof(line), stream) != NULL) + { + if (strstr(line, "conflict!") != NULL) + { + conflict = 1; + break; + } + } + + fclose(stream); + return conflict; +} + +#endif /* CONFIG_NET_ARP_ACD */ From de87836c7a710507948a339bc8949e541bbc505f Mon Sep 17 00:00:00 2001 From: zhangshuai39 Date: Fri, 4 Jul 2025 11:28:52 +0800 Subject: [PATCH 036/568] netpkt: Add parameters to support specific network cards Supports sending and receiving data packets on specified interfaces. Signed-off-by: zhangshuai39 --- examples/netpkt/netpkt_main.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/examples/netpkt/netpkt_main.c b/examples/netpkt/netpkt_main.c index 5f9aec81f..ab0595be4 100644 --- a/examples/netpkt/netpkt_main.c +++ b/examples/netpkt/netpkt_main.c @@ -29,7 +29,10 @@ #include #include #include +#include +#include #include +#include /**************************************************************************** * Private Functions @@ -39,11 +42,17 @@ * Name: psock_create ****************************************************************************/ -static int psock_create(void) +static int psock_create(const char *ifname) { int sd; struct sockaddr_ll addr; int addrlen = sizeof(addr); + unsigned int ifindex = 0; + + if (ifname && ifname[0]) + { + ifindex = if_nametoindex(ifname); + } sd = socket(AF_PACKET, SOCK_RAW, 0); if (sd < 0) @@ -55,7 +64,8 @@ static int psock_create(void) /* Prepare sockaddr struct */ addr.sll_family = AF_PACKET; - addr.sll_ifindex = 0; + addr.sll_ifindex = ifindex; + addr.sll_protocol = htons(ETH_P_ALL); if (bind(sd, (const struct sockaddr *)&addr, addrlen) < 0) { perror("ERROR: binding socket failed"); @@ -105,6 +115,7 @@ static void netpkt_usage(void) printf(" -r receive\n"); printf(" -t transmit\n"); printf(" -v verbose\n"); + printf(" -i specify interface name (e.g. eth0)\n"); printf("\n"); } @@ -116,7 +127,7 @@ static void netpkt_usage(void) * Name: netpkt_main ****************************************************************************/ -int main(int argc, FAR char *argv[]) +int main(int argc, char *argv[]) { int sd; int i; @@ -140,6 +151,9 @@ int main(int argc, FAR char *argv[]) int do_rxtimes = 3; int do_tx = 0; int do_txtimes = 3; + char ifname[IFNAMSIZ]; + + memset(ifname, 0, sizeof(ifname)); if (argc == 1) { @@ -149,7 +163,7 @@ int main(int argc, FAR char *argv[]) /* Parse arguments */ - while ((opt = getopt(argc, argv, "artv")) != -1) + while ((opt = getopt(argc, argv, "artvi:")) != -1) { switch (opt) { @@ -170,13 +184,17 @@ int main(int argc, FAR char *argv[]) verbose = 1; break; + case 'i': + strlcpy(ifname, optarg, sizeof(ifname)); + break; + default: netpkt_usage(); return -1; } } - sd = psock_create(); + sd = psock_create(ifname); if (do_tx) { From 532a055abbe797f6b3078c91f00861f3606379ce Mon Sep 17 00:00:00 2001 From: zhangshuai39 Date: Wed, 14 May 2025 11:56:45 +0800 Subject: [PATCH 037/568] paho_mqtt: Add mqtt compilation files It provides the necessary compilation files and configuration management files, and offers a publish demo and a subscribe demo Signed-off-by: zhangshuai39 --- netutils/paho_mqtt/CMakeLists.txt | 166 ++++++++++++++ netutils/paho_mqtt/Kconfig | 37 +++ netutils/paho_mqtt/Make.defs | 23 ++ netutils/paho_mqtt/Makefile | 111 +++++++++ netutils/paho_mqtt/paho_mqtt_01.patch | 314 ++++++++++++++++++++++++++ 5 files changed, 651 insertions(+) create mode 100644 netutils/paho_mqtt/CMakeLists.txt create mode 100644 netutils/paho_mqtt/Kconfig create mode 100644 netutils/paho_mqtt/Make.defs create mode 100644 netutils/paho_mqtt/Makefile create mode 100644 netutils/paho_mqtt/paho_mqtt_01.patch diff --git a/netutils/paho_mqtt/CMakeLists.txt b/netutils/paho_mqtt/CMakeLists.txt new file mode 100644 index 000000000..d3360390b --- /dev/null +++ b/netutils/paho_mqtt/CMakeLists.txt @@ -0,0 +1,166 @@ +# ############################################################################## +# apps/netutils/paho_mqtt/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_LIB_MQTT5) + + # ############################################################################ + # Config and Fetch Paho MQTT C library + # ############################################################################ + + set(PAHO_MQTT_DIR ${CMAKE_CURRENT_LIST_DIR}/paho_mqtt) + + if(NOT EXISTS ${PAHO_MQTT_DIR}) + # Default version if not specified in config + if(DEFINED CONFIG_NETUTILS_PAHO_MQTT_VERSION) + set(PAHO_MQTT_VERSION ${CONFIG_NETUTILS_PAHO_MQTT_VERSION}) + else() + set(PAHO_MQTT_VERSION "1.3.15") + endif() + + set(PAHO_MQTT_URL "https://github.com/eclipse-paho/paho.mqtt.c/archive") + FetchContent_Declare( + paho_mqtt_fetch + URL ${PAHO_MQTT_URL}/v${PAHO_MQTT_VERSION}.zip SOURCE_DIR ${PAHO_MQTT_DIR} + BINARY_DIR ${CMAKE_BINARY_DIR}/apps/netutils/paho_mqtt/paho_mqtt + DOWNLOAD_NO_PROGRESS true + TIMEOUT 30) + + FetchContent_GetProperties(paho_mqtt_fetch) + + if(NOT paho_mqtt_fetch_POPULATED) + FetchContent_Populate(paho_mqtt_fetch) + + # GitHub ZIP files extract with a versioned top-level directory Move + # contents from paho.mqtt.c- to paho_mqtt if needed + file(GLOB extracted_dirs "${PAHO_MQTT_DIR}/paho.mqtt.c-*") + if(extracted_dirs) + list(GET extracted_dirs 0 extracted_dir) + # Move all contents from the versioned directory to paho_mqtt + file(GLOB extracted_contents "${extracted_dir}/*") + foreach(item ${extracted_contents}) + get_filename_component(item_name ${item} NAME) + execute_process( + COMMAND ${CMAKE_COMMAND} -E rename ${item} + ${PAHO_MQTT_DIR}/${item_name} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) + endforeach() + # Remove the empty versioned directory + execute_process( + COMMAND ${CMAKE_COMMAND} -E remove_directory ${extracted_dir} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) + message("Moved contents from versioned directory to paho_mqtt") + endif() + + # Remove downloaded zip file if exists in current directory + file(GLOB zip_files "${CMAKE_CURRENT_LIST_DIR}/v${PAHO_MQTT_VERSION}.zip") + if(zip_files) + file(REMOVE ${zip_files}) + message("Removed downloaded zip file") + endif() + endif() + + # Apply paho_mqtt_01 patch if exists + if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/paho_mqtt_01.patch) + execute_process( + COMMAND + sh -c + "patch -p1 --forward --ignore-whitespace < ${CMAKE_CURRENT_LIST_DIR}/paho_mqtt_01.patch || true" + WORKING_DIRECTORY ${PAHO_MQTT_DIR}) + message("paho_mqtt_01 patching done") + endif() + + message("paho_mqtt download done") + endif() + + configure_file(paho_mqtt/src/VersionInfo.h.in + ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.h @ONLY) + + set(MQTT5_INCDIR ${CMAKE_CURRENT_LIST_DIR}/paho_mqtt/src) + list(APPEND MQTT5_INCDIR ${CMAKE_CURRENT_BINARY_DIR}) + + file(GLOB CSRCS paho_mqtt/src/*.c) + + if(CONFIG_UTILS_MQTT5) + list(APPEND CSRCS + ${CMAKE_CURRENT_LIST_DIR}/paho_mqtt/src/samples/pubsub_opts.c) + endif() + + if(CONFIG_OPENSSL_MBEDTLS_WRAPPER) + list(REMOVE_ITEM CSRCS ${CMAKE_CURRENT_LIST_DIR}/paho_mqtt/src/SHA1.c) + endif() + + list(REMOVE_ITEM CSRCS ${CMAKE_CURRENT_LIST_DIR}/paho_mqtt/src/MQTTClient.c + ${CMAKE_CURRENT_LIST_DIR}/paho_mqtt/src/MQTTVersion.c) + + nuttx_add_library(mqtt5) + + target_sources(mqtt5 PRIVATE ${CSRCS}) + + target_include_directories(mqtt5 PRIVATE ${MQTT5_INCDIR}) + + target_compile_options(mqtt5 PRIVATE ${MQTT5_FLAGS}) + + if(CONFIG_UTILS_MQTT5) + + set(MQTT_PUB_FLAGS + -DmessageArrived=mqtt_pub_messageArrived + -DonDisconnect=mqtt_pub_onDisconnect + -DonConnectFailure5=mqtt_pub_onConnectFailure5 + -DonConnectFailure=mqtt_pub_onConnectFailure + -DonConnect5=mqtt_pub_onConnect5 + -DonConnect=mqtt_pub_onConnect + -Dmysleep=mqtt_pub_mysleep + -DtoStop=mqtt_pub_toStop + -Dopts=mqtt_pub_opts + -Dmyconnect=mqtt_pub_myconnect + -Dcfinish=mqtt_pub_cfinish + -Dtrace_callback=mqtt_pub_trace_callback) + + nuttx_add_application( + NAME + mqtt_pub + SRCS + paho_mqtt/src/samples/paho_c_pub.c + DEPENDS + mqtt5 + INCLUDE_DIRECTORIES + ${MQTT5_INCDIR} + COMPILE_FLAGS + ${MQTT_PUB_FLAGS} + STACKSIZE + ${CONFIG_UTILS_MQTT5_STACKSIZE} + PRIORITY + ${CONFIG_UTILS_MQTT5_PRIORITY}) + + nuttx_add_application( + NAME + mqtt_sub + SRCS + paho_mqtt/src/samples/paho_c_sub.c + DEPENDS + mqtt5 + INCLUDE_DIRECTORIES + ${MQTT5_INCDIR} + STACKSIZE + ${CONFIG_UTILS_MQTT5_STACKSIZE} + PRIORITY + ${CONFIG_UTILS_MQTT5_PRIORITY}) + endif() +endif() diff --git a/netutils/paho_mqtt/Kconfig b/netutils/paho_mqtt/Kconfig new file mode 100644 index 000000000..987fccb76 --- /dev/null +++ b/netutils/paho_mqtt/Kconfig @@ -0,0 +1,37 @@ +# +# Copyright (C) 2020 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +config LIB_MQTT5 + bool "Enable mqtt5" + default n + ---help--- + A library for accessing mqtt5 client services through C libraries calls in a simple manner. + +config UTILS_MQTT5 + tristate "Enable mqtt5 tool" + depends on LIB_MQTT5 + ---help--- + Enable mqtt utility + +if UTILS_MQTT5 +config UTILS_MQTT5_PRIORITY + int "mqtt utility priority" + default 100 + +config UTILS_MQTT5_STACKSIZE + int "mqtt utility statcksize" + default 16384 +endif diff --git a/netutils/paho_mqtt/Make.defs b/netutils/paho_mqtt/Make.defs new file mode 100644 index 000000000..a91777976 --- /dev/null +++ b/netutils/paho_mqtt/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/netutils/paho_mqtt/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_LIB_MQTT5),) +CONFIGURED_APPS += $(APPDIR)/netutils/paho_mqtt +endif diff --git a/netutils/paho_mqtt/Makefile b/netutils/paho_mqtt/Makefile new file mode 100644 index 000000000..21c9d904f --- /dev/null +++ b/netutils/paho_mqtt/Makefile @@ -0,0 +1,111 @@ +############################################################################ +# apps/netutils/paho_mqtt/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +PAHO_MQTT_URL ?= "https://github.com/eclipse-paho/paho.mqtt.c/archive" + +# Default version if not specified in config +ifdef CONFIG_NETUTILS_PAHO_MQTT_VERSION +PAHO_MQTT_VERSION := $(patsubst "%",%,$(CONFIG_NETUTILS_PAHO_MQTT_VERSION)) +else +PAHO_MQTT_VERSION := 1.3.15 +endif + +PAHO_MQTT_ZIP = v$(PAHO_MQTT_VERSION).zip +PAHO_MQTT_UNPACK = paho_mqtt + +SRCDIR = $(APPDIR)/netutils/paho_mqtt/$(PAHO_MQTT_UNPACK)/src + +ifeq ($(CONFIG_LIB_MQTT5), y) + +# Check if paho_mqtt directory exists, if not download and extract +ifeq ($(wildcard $(PAHO_MQTT_UNPACK)/src),) +$(PAHO_MQTT_ZIP): + $(Q) echo "Downloading paho.mqtt.c-$(PAHO_MQTT_VERSION)" + $(Q) curl -L -o $(PAHO_MQTT_ZIP) $(PAHO_MQTT_URL)/$(PAHO_MQTT_ZIP) + +$(PAHO_MQTT_UNPACK): $(PAHO_MQTT_ZIP) + $(Q) echo "Unpacking: $(PAHO_MQTT_ZIP) -> $(PAHO_MQTT_UNPACK)" + $(Q) unzip -q $(PAHO_MQTT_ZIP) + $(Q) mv paho.mqtt.c-$(PAHO_MQTT_VERSION) $(PAHO_MQTT_UNPACK) + $(Q) rm -f $(PAHO_MQTT_ZIP) + $(Q) if [ -f paho_mqtt_01.patch ]; then \ + echo "Applying paho_mqtt_01 patch to $(PAHO_MQTT_UNPACK)"; \ + cd $(PAHO_MQTT_UNPACK) && patch -p1 --forward --ignore-whitespace < ../paho_mqtt_01.patch || true; \ + fi + $(Q) touch $(PAHO_MQTT_UNPACK) + +context:: $(PAHO_MQTT_UNPACK) + +distclean:: + $(call DELFILE, $(PAHO_MQTT_ZIP)) + $(call DELDIR, $(PAHO_MQTT_UNPACK)) +endif + +ifeq ($(CONFIG_OPENSSL_MBEDTLS_WRAPPER), y) +SKIP = $(SRCDIR)/SHA1.c +endif + +SKIP += $(SRCDIR)/MQTTClient.c +SKIP += $(SRCDIR)/MQTTVersion.c + +CSRCS = $(filter-out $(SKIP), $(wildcard $(SRCDIR)/*.c)) + +ifeq ($(CONFIG_UTILS_MQTT5),y) +CSRCS += $(SRCDIR)/samples/pubsub_opts.c +endif + +VARS = BUILD_TIMESTAMP PROJECT_VERSION PROJECT_VERSION_MAJOR +VARS += PROJECT_VERSION_MINOR PROJECT_VERSION_PATCH + +MQTT5_VERSION = $(SRCDIR)/VersionInfo.h + +SED_COMMANDS = $(foreach var,$(VARS),-e 's/@$(var)@/$($(var))/g') + +$(MQTT5_VERSION): $(SRCDIR)/VersionInfo.h.in + sed $(SED_COMMANDS) $< > $@ + +context:: $(MQTT5_VERSION) + +distclean:: + $(call DELFILE, $(MQTT5_VERSION)) + +ifeq ($(CONFIG_UTILS_MQTT5), y) +PROGNAME = mqtt_pub mqtt_sub +MAINSRC = $(SRCDIR)/samples/paho_c_pub.c $(SRCDIR)/samples/paho_c_sub.c +PRIORITY = $(CONFIG_UTILS_MQTT5_PRIORITY) +STACKSIZE = $(CONFIG_UTILS_MQTT5_STACKSIZE) +MODULE = $(CONFIG_UTILS_MQTT5) +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -DmessageArrived=mqtt_pub_messageArrived +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -DonDisconnect=mqtt_pub_onDisconnect +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -DonConnectFailure5=mqtt_pub_onConnectFailure5 +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -DonConnectFailure=mqtt_pub_onConnectFailure +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -DonConnect5=mqtt_pub_onConnect5 +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -DonConnect=mqtt_pub_onConnect +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -Dmysleep=mqtt_pub_mysleep -DtoStop=mqtt_pub_toStop +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -Dopts=mqtt_pub_opts -Dmyconnect=mqtt_pub_myconnect +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -Dcfinish=mqtt_pub_cfinish +$(SRCDIR)/samples/paho_c_pub.c_CFLAGS += -Dtrace_callback=mqtt_pub_trace_callback +endif + +endif + +include $(APPDIR)/Application.mk diff --git a/netutils/paho_mqtt/paho_mqtt_01.patch b/netutils/paho_mqtt/paho_mqtt_01.patch new file mode 100644 index 000000000..67a1fccdf --- /dev/null +++ b/netutils/paho_mqtt/paho_mqtt_01.patch @@ -0,0 +1,314 @@ +From 36c02a3935382a32a7fc19d52c9d6ee602dec8d6 Mon Sep 17 00:00:00 2001 +From: zhangshuai39 +Date: Wed, 14 May 2025 11:58:02 +0800 +Subject: [PATCH] paho_mqtt: Fix mqtt compile warning + +Signed-off-by: zhangshuai39 +--- + src/MQTTAsync.c | 2 +- + src/MQTTPacket.h | 2 ++ + src/SHA1.c | 2 +- + src/Socket.c | 16 +++++++++++++++- + src/Socket.h | 1 + + src/Thread.c | 1 + + src/Thread.h | 2 +- + src/WebSocket.c | 1 - + src/WebSocket.h | 2 +- + src/samples/paho_c_pub.c | 29 ++++++++++++++++++----------- + src/samples/paho_c_sub.c | 4 +++- + 11 files changed, 45 insertions(+), 18 deletions(-) + +diff --git a/src/MQTTAsync.c b/src/MQTTAsync.c +index c548ae3..2487d69 100644 +--- a/src/MQTTAsync.c ++++ b/src/MQTTAsync.c +@@ -989,7 +989,7 @@ exit: + } + + +-int MQTTAsync_inCallback() ++int MQTTAsync_inCallback(void) + { + thread_id_type thread_id = Paho_thread_getid(); + return thread_id == sendThread_id || thread_id == receiveThread_id; +diff --git a/src/MQTTPacket.h b/src/MQTTPacket.h +index fd384ae..c833d0c 100644 +--- a/src/MQTTPacket.h ++++ b/src/MQTTPacket.h +@@ -28,7 +28,9 @@ + #include "LinkedList.h" + #include "Clients.h" + ++#ifndef bool + typedef unsigned int bool; ++#endif + typedef void* (*pf)(int, unsigned char, char*, size_t); + + #include "MQTTProperties.h" +diff --git a/src/SHA1.c b/src/SHA1.c +index a1b2c3d..e4f5g6h 100644 +--- a/src/SHA1.c ++++ b/src/SHA1.c +@@ -58,7 +58,7 @@ + # include + # define htobe32(x) OSSwapHostToBigInt32(x) + # define be32toh(x) OSSwapBigToHostInt32(x) +-#elif defined(__FreeBSD__) || defined(__NetBSD__) ++#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__NuttX__) + # include + #endif + #include +diff --git a/src/Socket.c b/src/Socket.c +index ff36657..0ea9009 100644 +--- a/src/Socket.c ++++ b/src/Socket.c +@@ -130,7 +130,7 @@ int Socket_error(char* aString, SOCKET sock) + } + + #if !defined(_WIN32) +-void SIGPIPE_ignore() ++void SIGPIPE_ignore(void) + { + #if defined(PAHO_IGNORE_WITH_SIGNAL) + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) +@@ -182,6 +182,7 @@ void Socket_outInitialize(void) + mod_s.saved.fds_write = NULL; + mod_s.saved.fds_read = NULL; + mod_s.saved.nfds = 0; ++ mod_s.poll_in_progress = 0; + #endif + FUNC_EXIT; + } +@@ -622,17 +623,24 @@ SOCKET Socket_getReadySocket(int more_work, int timeout, mutex_type mutex, int* + } + + /* Check pending write set for writeable sockets */ ++ mod_s.poll_in_progress = 1; + rc1 = poll(mod_s.saved.fds_write, mod_s.saved.nfds, 0); ++ mod_s.poll_in_progress = 0; + if (rc1 > 0 && Socket_continueWrites(&sock, mutex) == SOCKET_ERROR) + { + *rc = SOCKET_ERROR; ++ mod_s.poll_in_progress = 0; + goto exit; + } + + /* Prevent performance issue by unlocking the socket_mutex while waiting for a ready socket. */ ++ + Paho_thread_unlock_mutex(mutex); ++ mod_s.poll_in_progress = 1; + *rc = poll(mod_s.saved.fds_read, mod_s.saved.nfds, timeout_ms); ++ mod_s.poll_in_progress = 0; + Paho_thread_lock_mutex(mutex); ++ + if (*rc == SOCKET_ERROR) + { + Socket_error("poll", 0); +@@ -1029,6 +1037,12 @@ int Socket_close(SOCKET socket) + int rc = 0; + + FUNC_ENTRY; ++ ++ /* Waiting for poll to end */ ++ while (mod_s.poll_in_progress) { ++ usleep(1000); // 1ms ++ } ++ + Paho_thread_lock_mutex(socket_mutex); + Socket_close_only(socket); + Socket_abortWrite(socket); +diff --git a/src/Socket.h b/src/Socket.h +index 6e52ab8..8afbdb6 100644 +--- a/src/Socket.h ++++ b/src/Socket.h +@@ -125,6 +125,7 @@ typedef struct + unsigned int nfds; /**< no of file descriptors for poll */ + struct pollfd* fds_read; /**< poll read file descriptors */ + struct pollfd* fds_write; ++ volatile int poll_in_progress; /**< Indicates poll operation is in progress (poll branch only) */ + + struct { + int cur_fd; /**< index into the fds_saved array */ +diff --git a/src/Thread.c b/src/Thread.c +index f4d43fb..52f810a 100644 +--- a/src/Thread.c ++++ b/src/Thread.c +@@ -72,6 +72,7 @@ void Paho_thread_start(thread_fn fn, void* parameter) + #else + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); ++ pthread_attr_setstacksize(&attr, CONFIG_UTILS_MQTT5_STACKSIZE); + if (pthread_create(&thread, &attr, fn, parameter) != 0) + thread = 0; + pthread_attr_destroy(&attr); +diff --git a/src/Thread.h b/src/Thread.h +index b0c823b..72dbc43 100644 +--- a/src/Thread.h ++++ b/src/Thread.h +@@ -76,7 +76,7 @@ LIBMQTT_API int Paho_thread_lock_mutex(mutex_type); + LIBMQTT_API int Paho_thread_unlock_mutex(mutex_type); + int Paho_thread_destroy_mutex(mutex_type); + +-LIBMQTT_API thread_id_type Paho_thread_getid(); ++LIBMQTT_API thread_id_type Paho_thread_getid(void); + + sem_type Thread_create_sem(int*); + int Thread_wait_sem(sem_type sem, int timeout); +diff --git a/src/WebSocket.c b/src/WebSocket.c +index 4338898..f941cda 100644 +--- a/src/WebSocket.c ++++ b/src/WebSocket.c +@@ -1136,7 +1136,6 @@ int WebSocket_receiveFrame(networkHandles *net, size_t *actual_len) + + if ( has_mask ) + { +- uint8_t mask[4]; + b = WebSocket_getRawSocketData(net, 4u, &len, &rcs); + if (rcs == SOCKET_ERROR) + { +diff --git a/src/WebSocket.h b/src/WebSocket.h +index 4e437d4..5343e6f 100644 +--- a/src/WebSocket.h ++++ b/src/WebSocket.h +@@ -60,7 +60,7 @@ int WebSocket_connect(networkHandles *net, int ssl, const char *uri); + /* obtain data from network socket */ + int WebSocket_getch(networkHandles *net, char* c); + char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len); +-size_t WebSocket_framePos(); ++size_t WebSocket_framePos(void); + void WebSocket_framePosSeekTo(size_t); + + /* send data out, in websocket format only if required */ +diff --git a/src/samples/paho_c_pub.c b/src/samples/paho_c_pub.c +index e891ef8..49392d8 100644 +--- a/src/samples/paho_c_pub.c ++++ b/src/samples/paho_c_pub.c +@@ -101,16 +101,12 @@ void onConnectFailure5(void* context, MQTTAsync_failureData5* response) + MQTTAsync_strerror(response->code), + MQTTReasonCode_toString(response->reasonCode)); + connected = -1; +- +- MQTTAsync client = (MQTTAsync)context; + } + + void onConnectFailure(void* context, MQTTAsync_failureData* response) + { + fprintf(stderr, "Connect failed, rc %s\n", response ? MQTTAsync_strerror(response->code) : "none"); + connected = -1; +- +- MQTTAsync client = (MQTTAsync)context; + } + + +@@ -140,6 +136,12 @@ void onConnect5(void* context, MQTTAsync_successData5* response) + } + } + ++ if (rc != 0) ++ { ++ fprintf(stderr, "Publish failed with code %d\n", rc); ++ toStop = 1; ++ } ++ + connected = 1; + } + +@@ -169,6 +171,12 @@ void onConnect(void* context, MQTTAsync_successData* response) + } + } + ++ if (rc != 0) ++ { ++ fprintf(stderr, "Publish failed with code %d\n", rc); ++ toStop = 1; ++ } ++ + connected = 1; + } + +@@ -219,7 +227,6 @@ void onPublish(void* context, MQTTAsync_successData* response) + + static int onSSLError(const char *str, size_t len, void *context) + { +- MQTTAsync client = (MQTTAsync)context; + return fprintf(stderr, "SSL error: %s\n", str); + } + +@@ -234,11 +241,11 @@ static unsigned int onPSKAuth(const char* hint, + int k, n; + + int rc = 0; +- struct pubsub_opts* opts = context; ++ struct pubsub_opts* local_opts = context; + + /* printf("Trying TLS-PSK auth with hint: %s\n", hint);*/ + +- if (opts->psk == NULL || opts->psk_identity == NULL) ++ if (local_opts->psk == NULL || local_opts->psk_identity == NULL) + { + /* printf("No PSK entered\n"); */ + goto exit; +@@ -246,7 +253,7 @@ static unsigned int onPSKAuth(const char* hint, + + /* psk should be array of bytes. This is a quick and dirty way to + * convert hex to bytes without input validation */ +- psk_len = (int)strlen(opts->psk) / 2; ++ psk_len = (int)strlen(local_opts->psk) / 2; + if (psk_len > max_psk_len) + { + fprintf(stderr, "PSK too long\n"); +@@ -254,11 +261,11 @@ static unsigned int onPSKAuth(const char* hint, + } + for (k=0, n=0; k < psk_len; k++, n += 2) + { +- sscanf(&opts->psk[n], "%2hhx", &psk[k]); ++ sscanf(&local_opts->psk[n], "%2hhx", &psk[k]); + } + + /* identity should be NULL terminated string */ +- strncpy(identity, opts->psk_identity, max_identity_len); ++ strncpy(identity, local_opts->psk_identity, max_identity_len); + if (identity[max_identity_len - 1] != '\0') + { + fprintf(stderr, "Identity too long\n"); +@@ -372,7 +379,6 @@ int main(int argc, char** argv) + char* url = NULL; + int url_allocated = 0; + int rc = 0; +- const char* version = NULL; + const char* program_name = "paho_c_pub"; + MQTTAsync_nameValue* infos = MQTTAsync_getVersionInfo(); + #if !defined(_WIN32) +@@ -506,6 +512,7 @@ int main(int argc, char** argv) + while (!disconnected) + mysleep(100); + ++ toStop = 0; + MQTTAsync_destroy(&client); + + if (url_allocated) +diff --git a/src/samples/paho_c_sub.c b/src/samples/paho_c_sub.c +index 85875c9..1fe18ce 100644 +--- a/src/samples/paho_c_sub.c ++++ b/src/samples/paho_c_sub.c +@@ -207,7 +207,6 @@ int main(int argc, char** argv) + MQTTAsync_SSLOptions ssl_opts = MQTTAsync_SSLOptions_initializer; + int rc = 0; + char* url = NULL; +- const char* version = NULL; + const char* program_name = "paho_c_sub"; + MQTTAsync_nameValue* infos = MQTTAsync_getVersionInfo(); + #if !defined(_WIN32) +@@ -343,6 +342,9 @@ int main(int argc, char** argv) + mysleep(100); + + exit: ++ finished = 0; ++ subscribed = 0; ++ disconnected = 0; + MQTTAsync_destroy(&client); + + return EXIT_SUCCESS; +-- +2.34.1 + From 5d3b2d07d61be260b7cbc7dc26d407c591ba4613 Mon Sep 17 00:00:00 2001 From: meijian Date: Fri, 14 Mar 2025 17:23:30 +0800 Subject: [PATCH 038/568] ping: add -I for bind device Add -I option to specify the network device to use for sending ICMP echo requests. This allows users to explicitly bind ping to a specific network interface, which is particularly useful in multi-homed systems with multiple network interfaces. Signed-off-by: meijian --- include/netutils/icmp_ping.h | 4 ++++ include/netutils/icmpv6_ping.h | 4 ++++ netutils/ping/icmp_ping.c | 14 ++++++++++++++ netutils/ping/icmpv6_ping.c | 14 ++++++++++++++ system/ping/ping.c | 17 ++++++++++++++++- system/ping6/ping6.c | 17 ++++++++++++++++- 6 files changed, 68 insertions(+), 2 deletions(-) diff --git a/include/netutils/icmp_ping.h b/include/netutils/icmp_ping.h index eec500de9..3f8d6c29d 100644 --- a/include/netutils/icmp_ping.h +++ b/include/netutils/icmp_ping.h @@ -50,6 +50,7 @@ #define ICMP_E_POLL -11 /* extra: error code */ #define ICMP_E_RECVFROM -13 /* extra: error code */ #define ICMP_E_RECVSMALL -15 /* extra: recv bytes */ +#define ICMP_E_BINDDEV -17 /* extra: error bind */ /* Negative even number represent warning(recoverable) */ @@ -70,6 +71,9 @@ struct ping_result_s; struct ping_info_s { FAR const char *hostname; /* Host name to ping */ +#ifdef CONFIG_NET_BINDTODEVICE + FAR const char *devname; /* Device name to bind */ +#endif uint16_t count; /* Number of pings requested */ uint16_t datalen; /* Number of bytes to be sent */ uint16_t delay; /* Deciseconds to delay between pings */ diff --git a/include/netutils/icmpv6_ping.h b/include/netutils/icmpv6_ping.h index 3f793f741..33db0fc6f 100644 --- a/include/netutils/icmpv6_ping.h +++ b/include/netutils/icmpv6_ping.h @@ -50,6 +50,7 @@ #define ICMPv6_E_POLL -11 /* extra: error code */ #define ICMPv6_E_RECVFROM -13 /* extra: error code */ #define ICMPv6_E_RECVSMALL -15 /* extra: recv bytes */ +#define ICMPV6_E_BINDDEV -17 /* extra: error bind */ /* Negative even number represent warning(recoverable) */ @@ -70,6 +71,9 @@ struct ping6_result_s; struct ping6_info_s { FAR const char *hostname; /* Host name to ping */ +#ifdef CONFIG_NET_BINDTODEVICE + FAR const char *devname; /* Device name to bind */ +#endif uint16_t count; /* Number of pings requested */ uint16_t datalen; /* Number of bytes to be sent */ uint16_t delay; /* Deciseconds to delay between pings */ diff --git a/netutils/ping/icmp_ping.c b/netutils/ping/icmp_ping.c index efbc8a61a..7aa1d3973 100644 --- a/netutils/ping/icmp_ping.c +++ b/netutils/ping/icmp_ping.c @@ -232,6 +232,20 @@ void icmp_ping(FAR const struct ping_info_s *info) return; } +#ifdef CONFIG_NET_BINDTODEVICE + if (info->devname) + { + ret = setsockopt(priv->sockfd, SOL_SOCKET, SO_BINDTODEVICE, + info->devname, strlen(info->devname)); + if (ret < 0) + { + icmp_callback(&result, ICMP_E_BINDDEV, errno); + free(priv); + return; + } + } +#endif + priv->kickoff = clock(); memset(&priv->destaddr, 0, sizeof(struct sockaddr_in)); diff --git a/netutils/ping/icmpv6_ping.c b/netutils/ping/icmpv6_ping.c index 74cd59ee9..e6a93fc98 100644 --- a/netutils/ping/icmpv6_ping.c +++ b/netutils/ping/icmpv6_ping.c @@ -218,6 +218,20 @@ void icmp6_ping(FAR const struct ping6_info_s *info) return; } +#ifdef CONFIG_NET_BINDTODEVICE + if (info->devname) + { + ret = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, + info->devname, strlen(info->devname)); + if (ret < 0) + { + icmp6_callback(&result, ICMPV6_E_BINDDEV, errno); + free(iobuffer); + return; + } + } +#endif + kickoff = clock(); memset(&destaddr, 0, sizeof(struct sockaddr_in6)); diff --git a/system/ping/ping.c b/system/ping/ping.c index 804522112..1abee622a 100644 --- a/system/ping/ping.c +++ b/system/ping/ping.c @@ -100,6 +100,7 @@ static void show_usage(FAR const char *progname, int exitcode) printf(" -s specifies the number of data bytes to be sent. " "Default %u.\n", ICMP_PING_DATALEN); + printf(" -I is the bind device for traffic\n"); printf(" -h shows this text and exits.\n"); exit(exitcode); } @@ -172,6 +173,12 @@ static void ping_result(FAR const struct ping_result_s *result) fprintf(stderr, "ERROR: short ICMP packet: %ld\n", result->extra); break; +#ifdef CONFIG_NET_BINDTODEVICE + case ICMP_E_BINDDEV: + fprintf(stderr, "ERROR: setsockopt error: %ld\n", result->extra); + break; +#endif + case ICMP_W_IDDIFF: fprintf(stderr, "WARNING: Ignoring ICMP reply with ID %ld. " @@ -300,7 +307,7 @@ int main(int argc, FAR char *argv[]) exitcode = EXIT_FAILURE; - while ((option = getopt(argc, argv, ":c:i:W:s:h")) != ERROR) + while ((option = getopt(argc, argv, ":c:i:W:s:I:h")) != ERROR) { switch (option) { @@ -360,6 +367,14 @@ int main(int argc, FAR char *argv[]) } break; + case 'I': +#ifdef CONFIG_NET_BINDTODEVICE + info.devname = optarg; +#else + fprintf(stderr, "ERROR: Bind to device not supported\n"); +#endif + break; + case 'h': exitcode = EXIT_SUCCESS; goto errout_with_usage; diff --git a/system/ping6/ping6.c b/system/ping6/ping6.c index 5d18637b8..409f3db0e 100644 --- a/system/ping6/ping6.c +++ b/system/ping6/ping6.c @@ -100,6 +100,7 @@ static void show_usage(FAR const char *progname, int exitcode) printf(" -s specifies the number of data bytes to be sent. " " Default %u.\n", ICMPv6_PING6_DATALEN); + printf(" -I is the bind device for traffic\n"); printf(" -h shows this text and exits.\n"); exit(exitcode); } @@ -176,6 +177,12 @@ static void ping6_result(FAR const struct ping6_result_s *result) result->extra, result->id); break; +#ifdef CONFIG_NET_BINDTODEVICE + case ICMPV6_E_BINDDEV: + fprintf(stderr, "ERROR: setsockopt error: %ld\n", result->extra); + break; +#endif + case ICMPv6_W_SEQNOBIG: fprintf(stderr, "WARNING: Ignoring ICMP reply to sequence %ld. " @@ -295,7 +302,7 @@ int main(int argc, FAR char *argv[]) exitcode = EXIT_FAILURE; - while ((option = getopt(argc, argv, ":c:i:W:s:h")) != ERROR) + while ((option = getopt(argc, argv, ":c:i:W:s:I:h")) != ERROR) { switch (option) { @@ -355,6 +362,14 @@ int main(int argc, FAR char *argv[]) } break; + case 'I': +#ifdef CONFIG_NET_BINDTODEVICE + info.devname = optarg; +#else + fprintf(stderr, "ERROR: Bind to device not supported\n"); +#endif + break; + case 'h': exitcode = EXIT_SUCCESS; goto errout_with_usage; From f89773cbc8ed658461223c923b7fdc1c99c18d00 Mon Sep 17 00:00:00 2001 From: wangchen Date: Tue, 25 Mar 2025 10:28:05 +0800 Subject: [PATCH 039/568] ping: Initialize info.devname to NULL Initialize info.devname to NULL to solve the problem of the SO-BINDTODEVICE property being set incorrectly in the icmp_ping function Signed-off-by: wangchen --- system/ping/ping.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/system/ping/ping.c b/system/ping/ping.c index 1abee622a..f294983a1 100644 --- a/system/ping/ping.c +++ b/system/ping/ping.c @@ -296,6 +296,9 @@ int main(int argc, FAR char *argv[]) info.delay = ICMP_POLL_DELAY; info.timeout = ICMP_POLL_DELAY; info.callback = ping_result; +#ifdef CONFIG_NET_BINDTODEVICE + info.devname = NULL; +#endif info.priv = &priv; priv.code = ICMP_I_OK; priv.tmin = LONG_MAX; From b56795e1e25dad8426202ad916c68220df7ca24e Mon Sep 17 00:00:00 2001 From: gaohedong Date: Wed, 24 Sep 2025 23:44:33 +0800 Subject: [PATCH 040/568] net/ping: utils ping should depends on ipv4 utils ping should depends on ipv4 Signed-off-by: gaohedong --- system/ping/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/system/ping/Kconfig b/system/ping/Kconfig index 7559ac2e9..7500f1024 100644 --- a/system/ping/Kconfig +++ b/system/ping/Kconfig @@ -6,6 +6,7 @@ config SYSTEM_PING tristate "ICMP 'ping' command" default n + depends on NET_IPv4 select NETUTILS_PING ---help--- Enable support for the ICMP 'ping' command. From 74c71145da7eacbcc5edad378171e95f008e5c4a Mon Sep 17 00:00:00 2001 From: gaohedong Date: Tue, 20 May 2025 00:44:52 +0800 Subject: [PATCH 041/568] net/ethernet: ARP can be configured on interface ARP can be configured on interface Signed-off-by: gaohedong --- include/netutils/netlib.h | 2 + netutils/netlib/netlib_setifstatus.c | 114 ++++++++++++++++++++++++++- nshlib/nsh_netcmds.c | 37 +++++++++ 3 files changed, 149 insertions(+), 4 deletions(-) diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 9f8f744cd..07a66906c 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -477,6 +477,8 @@ void netlib_server(uint16_t portno, pthread_startroutine_t handler, int netlib_getifstatus(FAR const char *ifname, FAR uint8_t *flags); int netlib_ifup(FAR const char *ifname); int netlib_ifdown(FAR const char *ifname); +int netlib_ifarp(const char *ifname); +int netlib_ifnoarp(const char *ifname); /* DNS server addressing */ diff --git a/netutils/netlib/netlib_setifstatus.c b/netutils/netlib/netlib_setifstatus.c index 8a3f58db1..d2f56dd8b 100644 --- a/netutils/netlib/netlib_setifstatus.c +++ b/netutils/netlib/netlib_setifstatus.c @@ -74,12 +74,16 @@ int netlib_ifup(const char *ifname) /* Put the driver name into the request */ strlcpy(req.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req); + if (ret >= 0) + { + /* Perform the ioctl to ifup flag */ - /* Perform the ioctl to ifup flag */ + IFF_SET_UP(req.ifr_flags); - req.ifr_flags |= IFF_UP; + ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + } - ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); close(sockfd); } } @@ -108,6 +112,53 @@ int netlib_ifdown(const char *ifname) { /* Get a socket (only so that we get access to the INET subsystem) */ + int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL); + if (sockfd >= 0) + { + struct ifreq req; + memset(&req, 0, sizeof(struct ifreq)); + + /* Put the driver name into the request */ + + strlcpy(req.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req); + if (ret >= 0) + { + /* Perform the ioctl to ifdown flag */ + + IFF_CLR_UP(req.ifr_flags); + + ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + } + + close(sockfd); + } + } + + return ret; +} + +/**************************************************************************** + * Name: netlib_ifarp + * + * Description: + * Enable ARP learning capability on the interface + * + * Parameters: + * ifname The name of the interface to use + * + * Return: + * 0 on success; -1 on failure + * + ****************************************************************************/ + +int netlib_ifarp(const char *ifname) +{ + int ret = ERROR; + if (ifname) + { + /* Get a socket (only so that we get access to the INET subsystem) */ + int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL); if (sockfd >= 0) { @@ -120,7 +171,62 @@ int netlib_ifdown(const char *ifname) /* Perform the ioctl to ifup flag */ - ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + ret = ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req); + if (ret >= 0) + { + IFF_CLR_NOARP(req.ifr_flags); + + ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + } + + close(sockfd); + } + } + + return ret; +} + +/**************************************************************************** + * Name: netlib_ifnoarp + * + * Description: + * Disable ARP learning capability on the interface + * + * Parameters: + * ifname The name of the interface to use + * + * Return: + * 0 on success; -1 on failure + * + ****************************************************************************/ + +int netlib_ifnoarp(const char *ifname) +{ + int ret = ERROR; + if (ifname) + { + /* Get a socket (only so that we get access to the INET subsystem) */ + + int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL); + if (sockfd >= 0) + { + struct ifreq req; + memset(&req, 0, sizeof(struct ifreq)); + + /* Put the driver name into the request */ + + strlcpy(req.ifr_name, ifname, IFNAMSIZ); + + /* Perform the ioctl to ifup flag */ + + ret = ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req); + if (ret >= 0) + { + IFF_SET_NOARP(req.ifr_flags); + + ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + } + close(sockfd); } } diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 791e1c922..1b2c8efd7 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -142,6 +142,15 @@ struct tftpc_args_s }; #endif +#ifdef CONFIG_NET_ARP +typedef enum +{ + ARP_DEFAULT, /* Did not set arp configure in the command */ + ARP_ENABLE, /* Clean the NOARP flag for the interface to enable the arp learning function */ + ARP_DISABLE /* Set the NOARP flag for the interface to disable the arp learning function */ +} arp_cfg_e; +#endif + typedef int (*nsh_netdev_callback_t)(FAR struct nsh_vtbl_s *vtbl, FAR char *devname); @@ -575,6 +584,9 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) #endif bool missingarg = true; bool badarg = false; +#ifdef CONFIG_NET_ARP + arp_cfg_e arpflag = ARP_DEFAULT; +#endif #ifdef HAVE_HWADDR mac_addr_t macaddr; #endif @@ -742,6 +754,20 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) badarg = true; } } +#ifdef CONFIG_NET_ARP + else if (!strcmp(tmp, "arp")) + { + /* Enable arp function on interface */ + + arpflag = ARP_ENABLE; + } + else if (!strcmp(tmp, "-arp")) + { + /* Disable arp function on interface */ + + arpflag = ARP_DISABLE; + } +#endif else if (hostip == NULL && i <= 4) { /* Let first non-option be host ip, to support inet/inet6 @@ -1044,6 +1070,17 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) } #endif +#ifdef CONFIG_NET_ARP + if (arpflag == ARP_ENABLE) + { + netlib_ifarp(ifname); + } + else if (arpflag == ARP_DISABLE) + { + netlib_ifnoarp(ifname); + } +#endif + #if !defined(CONFIG_NET_IPv4) && !defined(CONFIG_NET_IPv6) UNUSED(hostip); UNUSED(mask); From de6aac8afbfd4436d74e026961b60e191f66156b Mon Sep 17 00:00:00 2001 From: gaohedong Date: Thu, 21 Aug 2025 10:07:24 +0800 Subject: [PATCH 042/568] net/wireless: fix compile warning fix tasking compile warning isssue warnning log: unused variable "IEEE802154_STATUS_STRING" Signed-off-by: gaohedong --- wireless/ieee802154/i8sak/i8sak_assoc.c | 2 +- wireless/ieee802154/i8sak/i8sak_poll.c | 2 +- wireless/ieee802154/i8sak/i8sak_scan.c | 2 +- wireless/ieee802154/i8sak/i8sak_tx.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wireless/ieee802154/i8sak/i8sak_assoc.c b/wireless/ieee802154/i8sak/i8sak_assoc.c index 52894c0ec..96d65986a 100644 --- a/wireless/ieee802154/i8sak/i8sak_assoc.c +++ b/wireless/ieee802154/i8sak/i8sak_assoc.c @@ -321,7 +321,7 @@ static void assoc_eventcb(FAR struct ieee802154_primitive_s *primitive, else { printf("i8sak: ASSOC.request failed: %s\n", - IEEE802154_STATUS_STRING[primitive->u.assocconf.status]); + g_ieee802154_status_string[primitive->u.assocconf.status]); i8sak->result = -EAGAIN; } diff --git a/wireless/ieee802154/i8sak/i8sak_poll.c b/wireless/ieee802154/i8sak/i8sak_poll.c index 014c9daed..c349708f0 100644 --- a/wireless/ieee802154/i8sak/i8sak_poll.c +++ b/wireless/ieee802154/i8sak/i8sak_poll.c @@ -176,7 +176,7 @@ static void poll_eventcb(FAR struct ieee802154_primitive_s *primitive, else { printf("i8sak: POLL.request failed: %s\n", - IEEE802154_STATUS_STRING[primitive->u.pollconf.status]); + g_ieee802154_status_string[primitive->u.pollconf.status]); } sem_post(&i8sak->sigsem); diff --git a/wireless/ieee802154/i8sak/i8sak_scan.c b/wireless/ieee802154/i8sak/i8sak_scan.c index 2ed1bb645..ab2093a30 100644 --- a/wireless/ieee802154/i8sak/i8sak_scan.c +++ b/wireless/ieee802154/i8sak/i8sak_scan.c @@ -200,7 +200,7 @@ static void scan_eventcb(FAR struct ieee802154_primitive_s *primitive, int i; printf("\n\ni8sak: Scan complete: %s\n", - IEEE802154_STATUS_STRING[scan->status]); + g_ieee802154_status_string[scan->status]); printf("Scan type: "); diff --git a/wireless/ieee802154/i8sak/i8sak_tx.c b/wireless/ieee802154/i8sak/i8sak_tx.c index fe0661426..e0f2c1951 100644 --- a/wireless/ieee802154/i8sak/i8sak_tx.c +++ b/wireless/ieee802154/i8sak/i8sak_tx.c @@ -278,7 +278,7 @@ static void tx_eventcb(FAR struct ieee802154_primitive_s *primitive, else { printf("i8sak: frame failed to send: %s\n", - IEEE802154_STATUS_STRING[primitive->u.dataconf.status]); + g_ieee802154_status_string[primitive->u.dataconf.status]); } sem_post(&i8sak->sigsem); From 9dc6781bf9c72ba7cd6d7e9a701e268e72c009d3 Mon Sep 17 00:00:00 2001 From: gaohedong Date: Mon, 25 Aug 2025 21:34:29 +0800 Subject: [PATCH 043/568] net/wireless: dup g_ieee802154_status_string from kernel dup g_ieee802154_status_string from kernel to fix cmopil issue Signed-off-by: gaohedong --- wireless/ieee802154/i8sak/i8sak_main.c | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/wireless/ieee802154/i8sak/i8sak_main.c b/wireless/ieee802154/i8sak/i8sak_main.c index 1d48777a7..a085e731b 100644 --- a/wireless/ieee802154/i8sak/i8sak_main.c +++ b/wireless/ieee802154/i8sak/i8sak_main.c @@ -122,6 +122,40 @@ static int i8sak_daemon(int argc, FAR char *argv[]); static int i8sak_showusage(FAR const char *progname, int exitcode); static void i8sak_switch_instance(FAR char *ifname); +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL) +FAR const char *g_ieee802154_status_string[] = +{ + "Success", + "Out of capacity", + "Denied", + "Failure", + "Beacon loss", + "Channel access failure", + "Disable TRX failure", + "Failed security check", + "Frame too long", + "Invalid GTS", + "Invalid handle", + "Invalid parameter", + "No ack", + "No beacon", + "No data", + "No short address", + "PAN ID conflict", + "Realignment", + "Transaction expired", + "Transaction overflow", + "Tx active", + "Unavailable key", + "Unsupported attribute", + "Limit reached", +}; +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ From 9f035ea0be38402f0d6e0b7804f8430ca9b2d6ed Mon Sep 17 00:00:00 2001 From: gaohedong Date: Fri, 26 Sep 2025 10:14:34 +0800 Subject: [PATCH 044/568] qnet/wireless: fix compile warning of i8sak fix tasking compile warning isssue warnning log: undefined reference to 'g_ieee802154_status_string' Signed-off-by: gaohedong --- wireless/ieee802154/i8sak/i8sak_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wireless/ieee802154/i8sak/i8sak_main.c b/wireless/ieee802154/i8sak/i8sak_main.c index a085e731b..887be1b13 100644 --- a/wireless/ieee802154/i8sak/i8sak_main.c +++ b/wireless/ieee802154/i8sak/i8sak_main.c @@ -126,7 +126,8 @@ static void i8sak_switch_instance(FAR char *ifname); * Public Data ****************************************************************************/ -#if defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL) +#if defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL) || \ + !defined(CONFIG_IEEE802154_MAC) FAR const char *g_ieee802154_status_string[] = { "Success", From 09ddb06c9d344c93705322b2e4ca4bc304f38293 Mon Sep 17 00:00:00 2001 From: zhangshuai39 Date: Thu, 10 Apr 2025 19:43:32 +0800 Subject: [PATCH 045/568] dhcpd: Align makefile implementation Improve the CMakeLists.txt to achieve the same compilation results as Makefile. Signed-off-by: zhangshuai39 --- examples/dhcpd/CMakeLists.txt | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/examples/dhcpd/CMakeLists.txt b/examples/dhcpd/CMakeLists.txt index 0305ab59c..b59cb5485 100644 --- a/examples/dhcpd/CMakeLists.txt +++ b/examples/dhcpd/CMakeLists.txt @@ -25,10 +25,28 @@ if(CONFIG_EXAMPLES_DHCPD) NAME dhcpd SRCS - host.c target.c + dhcpd_daemon.c STACKSIZE - 2048) + ${CONFIG_DEFAULT_TASK_STACKSIZE}) + + nuttx_add_application( + NAME + dhcpd_start + SRCS + dhcpd_start.c + dhcpd_daemon.c + STACKSIZE + ${CONFIG_DEFAULT_TASK_STACKSIZE}) + + nuttx_add_application( + NAME + dhcpd_stop + SRCS + dhcpd_stop.c + dhcpd_daemon.c + STACKSIZE + ${CONFIG_DEFAULT_TASK_STACKSIZE}) add_definitions(-DCONFIG_NETUTILS_DHCPD_HOST=1 -DHAVE_SO_REUSEADDR=1 -DHAVE_SO_BROADCAST=1) From fb4f80665d040bc526859cbae05e7a40ee9504a8 Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Thu, 25 Dec 2025 12:56:27 +0800 Subject: [PATCH 046/568] ostest/hrtimer: Fix typos The current code incorrectly used the CONFIG_SCHED_EVENTS macro in ostest.h for hrtimer_test(). This has been corrected to use CONFIG_HRTIMER. Signed-off-by: Chengdong Wang wangchengdong@lixiang.com --- testing/ostest/ostest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/ostest/ostest.h b/testing/ostest/ostest.h index 30f16da5d..321ecd2d3 100644 --- a/testing/ostest/ostest.h +++ b/testing/ostest/ostest.h @@ -304,7 +304,7 @@ int sem_nfreeholders(void); void nxevent_test(void); #endif -#if defined(CONFIG_SCHED_EVENTS) && defined(CONFIG_BUILD_FLAT) +#if defined(CONFIG_HRTIMER) && defined(CONFIG_BUILD_FLAT) void hrtimer_test(void); #endif From 9da2bc06961587ec0d288686099a3e75524f8cc3 Mon Sep 17 00:00:00 2001 From: meijian Date: Wed, 9 Oct 2024 17:34:00 +0800 Subject: [PATCH 047/568] apps/net: add get iobinfo api Obtain detailed IOB information by parsing the /proc/iobinfo file. Signed-off-by: meijian --- include/netutils/netlib.h | 5 ++ netutils/netlib/CMakeLists.txt | 4 ++ netutils/netlib/Makefile | 4 ++ netutils/netlib/netlib_getiobinfo.c | 108 ++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 netutils/netlib/netlib_getiobinfo.c diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 07a66906c..b5389a55d 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -52,6 +52,7 @@ #include #include +#include #include #include @@ -507,6 +508,10 @@ int netlib_getifstatistics(FAR const char *ifname, int netlib_check_ifconflict(FAR const char *ifname); #endif +#ifdef CONFIG_MM_IOB +int netlib_get_iobinfo(FAR struct iob_stats_s *iob); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt index 560a71834..82cc8d610 100644 --- a/netutils/netlib/CMakeLists.txt +++ b/netutils/netlib/CMakeLists.txt @@ -149,6 +149,10 @@ if(CONFIG_NETUTILS_NETLIB) list(APPEND SRCS netlib_checkifconflict.c) endif() + if(CONFIG_MM_IOB) + list(APPEND SRCS netlib_getiobinfo.c) + endif() + target_sources(apps PRIVATE ${SRCS}) endif() diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index 237cc76de..3d6066e3f 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -148,4 +148,8 @@ ifeq ($(CONFIG_NET_ARP_ACD),y) CSRCS += netlib_checkifconflict.c endif +ifeq ($(CONFIG_MM_IOB),y) +CSRCS += netlib_getiobinfo.c +endif + include $(APPDIR)/Application.mk diff --git a/netutils/netlib/netlib_getiobinfo.c b/netutils/netlib/netlib_getiobinfo.c new file mode 100644 index 000000000..fe9a97983 --- /dev/null +++ b/netutils/netlib/netlib_getiobinfo.c @@ -0,0 +1,108 @@ +/**************************************************************************** + * apps/netutils/netlib/netlib_getiobinfo.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "netutils/netlib.h" + +#ifdef CONFIG_MM_IOB + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determines the size of an intermediate buffer that must be large enough + * to handle the longest line generated by this logic. + */ + +#define PROCFS_LINELEN 80 +#define PROCFS_IOB_PATH "/proc/iobinfo" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netlib_get_iobinfo + * + * Description: + * Get the network iob info. + * + * Parameters: + * iob The pointer to return iobinfo. + * + * Return: + * 0 on success; a nagtive on failure. + * + ****************************************************************************/ + +int netlib_get_iobinfo(FAR struct iob_stats_s *iob) +{ + int ret = OK; + FAR FILE *stream; + char line[PROCFS_LINELEN]; + + stream = fopen(PROCFS_IOB_PATH, "r"); + if (stream == NULL) + { + fprintf(stderr, "ERROR: Failed to open path:%s \n", PROCFS_IOB_PATH); + return -errno; + } + + /* Read ioninfo header and next is the data */ + + if (fgets(line, sizeof(line), stream) != NULL) + { + if (fgets(line, sizeof(line), stream) == NULL) + { + ret = -EINVAL; + fclose(stream); + return ret; + } + + if (sscanf(line, "%d %d %d %d", &iob->ntotal, &iob->nfree, + &iob->nwait, &iob->nthrottle) <= 0) + { + ret = -errno; + fclose(stream); + return ret; + } + } + + fclose(stream); + return ret; +} + +#endif /* CONFIG_MM_IOB */ \ No newline at end of file From 39310946ec9086365d2d72261b652b4bf6e56f89 Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Sun, 21 Dec 2025 22:08:31 -0500 Subject: [PATCH 048/568] testing/nuts: NuttX Unit Test Selection (NUTS) application. Introduces a collection of unit tests for NuttX, built on top of the cmocka framework. Tests are organized into suites/groups which can be individually included/excluded from the build using Kconfig. Output is easily legible and separated with headers including the test group name. Signed-off-by: Matteo Golin --- testing/nuts/CMakeLists.txt | 40 ++ testing/nuts/Kconfig | 104 +++++ testing/nuts/Make.defs | 25 ++ testing/nuts/Makefile | 45 ++ testing/nuts/devices/devascii.c | 256 +++++++++++ testing/nuts/devices/devconsole.c | 168 +++++++ testing/nuts/devices/devnull.c | 259 +++++++++++ testing/nuts/devices/devurandom.c | 276 ++++++++++++ testing/nuts/devices/devzero.c | 274 ++++++++++++ testing/nuts/devices/tests.h | 66 +++ testing/nuts/dstructs/cbuf.c | 707 ++++++++++++++++++++++++++++++ testing/nuts/dstructs/list.c | 149 +++++++ testing/nuts/dstructs/tests.h | 54 +++ testing/nuts/nuts.h | 47 ++ testing/nuts/nuts_main.c | 73 +++ testing/nuts/tests.h | 33 ++ 16 files changed, 2576 insertions(+) create mode 100644 testing/nuts/CMakeLists.txt create mode 100644 testing/nuts/Kconfig create mode 100644 testing/nuts/Make.defs create mode 100644 testing/nuts/Makefile create mode 100644 testing/nuts/devices/devascii.c create mode 100644 testing/nuts/devices/devconsole.c create mode 100644 testing/nuts/devices/devnull.c create mode 100644 testing/nuts/devices/devurandom.c create mode 100644 testing/nuts/devices/devzero.c create mode 100644 testing/nuts/devices/tests.h create mode 100644 testing/nuts/dstructs/cbuf.c create mode 100644 testing/nuts/dstructs/list.c create mode 100644 testing/nuts/dstructs/tests.h create mode 100644 testing/nuts/nuts.h create mode 100644 testing/nuts/nuts_main.c create mode 100644 testing/nuts/tests.h diff --git a/testing/nuts/CMakeLists.txt b/testing/nuts/CMakeLists.txt new file mode 100644 index 000000000..7aff43b01 --- /dev/null +++ b/testing/nuts/CMakeLists.txt @@ -0,0 +1,40 @@ +# ############################################################################## +# apps/testing/nuts/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_TESTING_NUTS) + + set(SRCS) + + if(CONFIG_TESTING_NUTS_DSTRUCTS) + file(GLOB DSTRUCTS dstructs/*.c) + list(APPEND SRCS ${DSTRUCTS}) + endif() # CONFIG_TESTING_NUTS_DSTRUCTS + + if(CONFIG_TESTING_NUTS_DEVICES) + file(GLOB DEVICES devices/*.c) + list(APPEND SRCS ${DEVICES}) + endif() # CONFIG_TESTING_NUTS_DEVICES + + set(NUTS_SRCS nuts_main.c ${SRCS}) + nuttx_add_application(NAME ${CONFIG_TESTING_NUTS_PROGNAME} SRCS ${NUTS_SRCS}) + +endif() diff --git a/testing/nuts/Kconfig b/testing/nuts/Kconfig new file mode 100644 index 000000000..ad7657d2c --- /dev/null +++ b/testing/nuts/Kconfig @@ -0,0 +1,104 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config TESTING_NUTS + tristate "NuttX Unit Test Selection (NUTS)" + depends on TESTING_CMOCKA + default n + ---help--- + Enable the NuttX unit test selection, based on the cmocka test framework. + +if TESTING_NUTS + +comment "Program options" + +config TESTING_NUTS_PROGNAME + string "Program name" + default "nuts" + ---help--- + The name of the program. + +config TESTING_NUTS_STACKSIZE + int "Stack size" + default 1024 + ---help--- + Size of the stack used to create the task. + +menu "Test suites" + +comment "Data structures" + +config TESTING_NUTS_DSTRUCTS + bool "Collections tests" + default n + ---help--- + Enable test suites for collections. + +if TESTING_NUTS_DSTRUCTS + +config TESTING_NUTS_DSTRUCTS_LIST + bool "List testing" + default y + ---help--- + Enable list test cases. + +config TESTING_NUTS_DSTRUCTS_CBUF + bool "Circular buffer testing" + default y + ---help--- + Enable circular buffer test cases. + +endif # TESTING_NUTS_DSTRUCTS + +comment "Devices" + +config TESTING_NUTS_DEVICES + bool "Device tests" + default n + ---help--- + Enable test suites for devices. + +if TESTING_NUTS_DEVICES + +config TESTING_NUTS_DEVICES_DEVNULL + bool "/dev/null test" + depends on DEV_NULL + default y + ---help--- + Enable test cases for /dev/null device. + +config TESTING_NUTS_DEVICES_DEVZERO + bool "/dev/zero test" + depends on DEV_ZERO + default y + ---help--- + Enable test cases for /dev/zero device. + +config TESTING_NUTS_DEVICES_DEVASCII + bool "/dev/ascii test" + depends on DEV_ASCII + default y + ---help--- + Enable test cases for /dev/ascii device. + +config TESTING_NUTS_DEVICES_DEVCONSOLE + bool "/dev/console test" + depends on DEV_CONSOLE + default y + ---help--- + Enable test cases for /dev/console device. + +config TESTING_NUTS_DEVICES_DEVURANDOM + bool "/dev/urandom test" + depends on DEV_URANDOM + default y + ---help--- + Enable test cases for /dev/urandom device. + +endif # TESTING_NUTS_DEVICES + +endmenu # Test suites + +endif # TESTING_NUTS diff --git a/testing/nuts/Make.defs b/testing/nuts/Make.defs new file mode 100644 index 000000000..3c78d6f81 --- /dev/null +++ b/testing/nuts/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/testing/nuts/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_TESTING_NUTS),) +CONFIGURED_APPS += $(APPDIR)/testing/nuts +endif diff --git a/testing/nuts/Makefile b/testing/nuts/Makefile new file mode 100644 index 000000000..d71ccc82f --- /dev/null +++ b/testing/nuts/Makefile @@ -0,0 +1,45 @@ +############################################################################ +# apps/testing/nuts/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# Application info + +PROGNAME = $(CONFIG_TESTING_NUTS_PROGNAME) +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = $(CONFIG_TESTING_NUTS_STACKSIZE) +MODULE = $(CONFIG_TESTING_OSTEST) + +# Source inclusion + +MAINSRC = nuts_main.c +CSRCS = + +ifeq ($(CONFIG_TESTING_NUTS_DSTRUCTS),y) +CSRCS += $(wildcard $(CURDIR)/dstructs/*.c) +endif # CONFIG_TESTING_NUTS_DSTRUCTS + +ifeq ($(CONFIG_TESTING_NUTS_DEVICES),y) +CSRCS += $(wildcard $(CURDIR)/devices/*.c) +endif # CONFIG_TESTING_NUTS_DEVICES + +include $(APPDIR)/Application.mk diff --git a/testing/nuts/devices/devascii.c b/testing/nuts/devices/devascii.c new file mode 100644 index 000000000..28a616221 --- /dev/null +++ b/testing/nuts/devices/devascii.c @@ -0,0 +1,256 @@ +/**************************************************************************** + * apps/testing/nuts/devices/devascii.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "tests.h" + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVASCII + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEVASCII "/dev/ascii" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The repeating string that is read from /dev/ascii */ + +static const char g_printables[] = + "\n!\"#$%&'()*+,-./" + "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" + "abcdefghijklmnopqrstuvwxyz{|}~"; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: open_rdonly + * + * Description: + * Test open/close operation of the ascii device in read only mode. + ****************************************************************************/ + +static void open_rdonly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVASCII, O_RDONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_rdwr + * + * Description: + * Test open/close operation of the ascii device in read/write mode. + ****************************************************************************/ + +static void open_rdwr(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVASCII, O_RDWR); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_wronly + * + * Description: + * Test open/close operation of the ascii device in write only mode. + ****************************************************************************/ + +static void open_wronly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVASCII, O_WRONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readzero + * + * Description: + * Test that reading zero from /dev/ascii does nothing. + ****************************************************************************/ + +static void readzero(void **state) +{ + UNUSED(state); + int fd; + char buf[16]; + fd = open(DEVASCII, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, 'a', sizeof(buf)); + assert_int_equal(0, read(fd, buf, 0)); + + /* Ensure buffer is unchanged */ + + for (unsigned i = 0; i < sizeof(buf); i++) + { + assert_true('a' == buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readline + * + * Description: + * Test that reading one full line of characters returns the exact expected + * string of printable characters. + * + * NOTE: -1 on buffer sizes allows us to keep ignore the null terminator. + ****************************************************************************/ + +static void readline(void **state) +{ + UNUSED(state); + int fd; + char buf[sizeof(g_printables)]; + fd = open(DEVASCII, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, '\0', sizeof(buf)); + assert_int_equal(sizeof(buf) - 1, read(fd, buf, sizeof(buf) - 1)); + + /* Ensure buffer contains the expected string. */ + + assert_memory_equal(g_printables, buf, sizeof(buf) - 1); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readline_twice + * + * Description: + * Test that reading one full line of characters twice returns the exact + * expected string of printable characters twice. + * + * NOTE: -1 on buffer sizes allows us to keep ignore the null terminator. + ****************************************************************************/ + +static void readline_twice(void **state) +{ + UNUSED(state); + int fd; + char buf[sizeof(g_printables) * 2]; + fd = open(DEVASCII, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, '\0', sizeof(buf)); + assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf))); + + /* Ensure buffer contains the expected string twice */ + + assert_memory_equal(g_printables, buf, sizeof(g_printables) - 1); + assert_memory_equal(g_printables, &buf[sizeof(g_printables) - 1], + sizeof(g_printables) - 1); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: writezero + * + * Description: + * Test that writing zero bytes does nothing. + ****************************************************************************/ + +static void writezero(void **state) +{ + UNUSED(state); + int fd; + char buf[16]; + fd = open(DEVASCII, O_WRONLY); + assert_true(fd >= 0); + + memset(buf, 'a', sizeof(buf)); + assert_int_equal(0, write(fd, buf, 0)); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: writelarge + * + * Description: + * Test that writing a full buffer of non-zero characters does nothing. + ****************************************************************************/ + +static void writelarge(void **state) +{ + UNUSED(state); + int fd; + char buf[BUFSIZ]; + fd = open(DEVASCII, O_WRONLY); + assert_true(fd >= 0); + + memset(buf, 'a', sizeof(buf)); + assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf))); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuts_devices_devascii + * + * Description: + * Runs the test cases for /dev/ascii + ****************************************************************************/ + +int nuts_devices_devascii(void) +{ + static const struct CMUnitTest tests[] = { + cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr), + cmocka_unit_test(open_wronly), cmocka_unit_test(readzero), + cmocka_unit_test(readline), cmocka_unit_test(readline_twice), + cmocka_unit_test(writezero), cmocka_unit_test(writelarge), + }; + + return cmocka_run_group_tests_name("/dev/ascii", tests, NULL, NULL); +} + +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVASCII */ diff --git a/testing/nuts/devices/devconsole.c b/testing/nuts/devices/devconsole.c new file mode 100644 index 000000000..c9dc09aa3 --- /dev/null +++ b/testing/nuts/devices/devconsole.c @@ -0,0 +1,168 @@ +/**************************************************************************** + * apps/testing/nuts/devices/devconsole.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "tests.h" + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVCONSOLE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEVCONSOLE "/dev/console" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: open_rdonly + * + * Description: + * Test open/close operation of the console device in read only mode. + ****************************************************************************/ + +static void open_rdonly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVCONSOLE, O_RDONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_rdwr + * + * Description: + * Test open/close operation of the console device in read/write mode. + ****************************************************************************/ + +static void open_rdwr(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVCONSOLE, O_RDWR); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_wronly + * + * Description: + * Test open/close operation of the console device in write only mode. + ****************************************************************************/ + +static void open_wronly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVCONSOLE, O_WRONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readzero + * + * Description: + * Test that reading zero from /dev/console does nothing. + ****************************************************************************/ + +static void readzero(void **state) +{ + UNUSED(state); + int fd; + char buf[16]; + fd = open(DEVCONSOLE, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, 'a', sizeof(buf)); + assert_int_equal(0, read(fd, buf, 0)); + + /* Ensure buffer is unchanged */ + + for (unsigned i = 0; i < sizeof(buf); i++) + { + assert_true(buf[i] == 'a'); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: writezero + * + * Description: + * Test that writing zero bytes does nothing. + ****************************************************************************/ + +static void writezero(void **state) +{ + UNUSED(state); + int fd; + char buf[16]; + fd = open(DEVCONSOLE, O_WRONLY); + assert_true(fd >= 0); + + memset(buf, 'a', sizeof(buf)); + assert_int_equal(0, write(fd, buf, 0)); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuts_devices_devconsole + * + * Description: + * Runs the test cases for /dev/console + ****************************************************************************/ + +int nuts_devices_devconsole(void) +{ + static const struct CMUnitTest tests[] = { + cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr), + cmocka_unit_test(open_wronly), cmocka_unit_test(readzero), + cmocka_unit_test(writezero), + }; + + return cmocka_run_group_tests_name("/dev/console", tests, NULL, NULL); +} + +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVCONSOLE */ diff --git a/testing/nuts/devices/devnull.c b/testing/nuts/devices/devnull.c new file mode 100644 index 000000000..f2f6c1302 --- /dev/null +++ b/testing/nuts/devices/devnull.c @@ -0,0 +1,259 @@ +/**************************************************************************** + * apps/testing/nuts/devices/devnull.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "tests.h" + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVNULL + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEVNULL "/dev/null" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: open_rdonly + * + * Description: + * Test open/close operation of the null device in read only mode. + ****************************************************************************/ + +static void open_rdonly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVNULL, O_RDONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_rdwr + * + * Description: + * Test open/close operation of the null device in read/write mode. + ****************************************************************************/ + +static void open_rdwr(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVNULL, O_RDWR); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_wronly + * + * Description: + * Test open/close operation of the null device in write only mode. + ****************************************************************************/ + +static void open_wronly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVNULL, O_WRONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readzero + * + * Description: + * Test the result of reading 0 bytes. + ****************************************************************************/ + +static void readzero(void **state) +{ + UNUSED(state); + int fd; + uint8_t buf[16]; + fd = open(DEVNULL, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(0, read(fd, buf, 0)); + + /* Buffer contents should not have changed */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0xa5, (uint8_t)buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readlarge + * + * Description: + * Test the result of reading a full buffer of BUFSIZ bytes. Nothing should + * be read and nothing should happen to the buffer. + ****************************************************************************/ + +static void readlarge(void **state) +{ + UNUSED(state); + int fd; + uint8_t buf[BUFSIZ]; + fd = open(DEVNULL, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(0, read(fd, buf, sizeof(buf))); + + /* Buffer contents should be unchanged */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0xa5, (uint8_t)buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: writezero + * + * Description: + * Test the result of writing zero bytes to /dev/null. + ****************************************************************************/ + +static void writezero(void **state) +{ + UNUSED(state); + int fd; + uint8_t buf[16]; + fd = open(DEVNULL, O_WRONLY); + assert_true(fd >= 0); + + assert_int_equal(0, write(fd, buf, 0)); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: writelarge + * + * Description: + * Test the result of writing a full buffer of non-zero bytes to /dev/null. + ****************************************************************************/ + +static void writelarge(void **state) +{ + UNUSED(state); + int fd; + uint8_t buf[BUFSIZ]; + fd = open(DEVNULL, O_WRONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf))); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: wrrd + * + * Description: + * Test the result of writing a buffer of non-zero bytes to /dev/null and + * then subsequently reading the whole buffer back. Nothing should happen + * to the buffer. + ****************************************************************************/ + +static void wrrd(void **state) +{ + UNUSED(state); + int fd; + uint8_t buf[BUFSIZ]; + fd = open(DEVNULL, O_RDWR); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf))); + + /* Buffer contents should be unchanged */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0xa5, (uint8_t)buf[i]); + } + + assert_int_equal(0, read(fd, buf, sizeof(buf))); + + /* Buffer contents should be unchanged */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0xa5, (uint8_t)buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuts_devices_devnull + * + * Description: + * Runs the test cases for /dev/null + ****************************************************************************/ + +int nuts_devices_devnull(void) +{ + static const struct CMUnitTest tests[] = { + cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr), + cmocka_unit_test(open_wronly), cmocka_unit_test(readzero), + cmocka_unit_test(readlarge), cmocka_unit_test(writezero), + cmocka_unit_test(writelarge), cmocka_unit_test(wrrd), + }; + + return cmocka_run_group_tests_name("/dev/null", tests, NULL, NULL); +} + +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVNULL */ diff --git a/testing/nuts/devices/devurandom.c b/testing/nuts/devices/devurandom.c new file mode 100644 index 000000000..6b70b3767 --- /dev/null +++ b/testing/nuts/devices/devurandom.c @@ -0,0 +1,276 @@ +/**************************************************************************** + * apps/testing/nuts/devices/devurandom.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "tests.h" + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVURANDOM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEVURANDOM "/dev/urandom" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: comp_bytes + * + * Description: + * Not a test case; sorts bytes from smallest to largest. + ****************************************************************************/ + +static int comp_bytes(const void *p1, const void *p2) +{ + const uint8_t *a = p1; + const uint8_t *b = p2; + return (int)*a - (int)*b; +} + +/**************************************************************************** + * Name: open_rdonly + * + * Description: + * Test open/close operation of the urandom device in read only mode. + ****************************************************************************/ + +static void open_rdonly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVURANDOM, O_RDONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_rdwr + * + * Description: + * Test open/close operation of the urandom device in read/write mode. + ****************************************************************************/ + +static void open_rdwr(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVURANDOM, O_RDWR); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_wronly + * + * Description: + * Test open/close operation of the urandom device in write only mode. + ****************************************************************************/ + +static void open_wronly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVURANDOM, O_WRONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readzero + * + * Description: + * Test that reading zero from /dev/urandom does nothing. + ****************************************************************************/ + +static void readzero(void **state) +{ + UNUSED(state); + int fd; + uint8_t buf[16]; + fd = open(DEVURANDOM, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(0, read(fd, buf, 0)); + + /* Ensure buffer is unchanged */ + + for (unsigned i = 0; i < sizeof(buf); i++) + { + assert_true(0xa5 == buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: writezero + * + * Description: + * Test that writing zero bytes does nothing. + ****************************************************************************/ + +static void writezero(void **state) +{ + UNUSED(state); + int fd; + char buf[16]; + fd = open(DEVURANDOM, O_WRONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5a5, sizeof(buf)); + assert_int_equal(0, write(fd, buf, 0)); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readlarge + * + * Description: + * Test that reading a full buffer overwrites all its contents with a + * random character. + ****************************************************************************/ + +static void readlarge(void **state) +{ + UNUSED(state); + int fd; + uint8_t buf[32]; + unsigned count; + fd = open(DEVURANDOM, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf))); + + count = 0; + for (unsigned int i = 0; i < sizeof(buf); i++) + { + if (buf[i] == 0xa5) count++; + } + + /* With 256 possible byte values and 32 draws, the chances that we see + * more than 2 bytes unchanged is < 0.001 % + */ + + assert_true(count <= 2); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: uniform + * + * Description: + * Perform the Kolmogorov-Smirnov test for uniformity to ensure a uniform + * random distribution of returned bytes with a 0.05 significance level. + ****************************************************************************/ + +static void uniformity_check(void **state) +{ + UNUSED(state); + int fd; + uint8_t buf[50]; + float d_plus; + float d_minus; + float d; + float temp_plus; + float temp_minus; + fd = open(DEVURANDOM, O_RDONLY); + assert_true(fd >= 0); + + /* Get sampled bytes and sort them in ascending order */ + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf))); + + qsort(buf, sizeof(buf), sizeof(uint8_t), comp_bytes); + + /* Calculate D+ and D- */ + + d_plus = -(float)buf[0]; + d_minus = (float)buf[0] + 1.0f / (float)sizeof(buf); + for (unsigned int i = 0; i < (float)sizeof(buf); i++) + { + temp_plus = (float)i / (float)sizeof(buf) - (float)buf[i]; + temp_minus = (float)buf[i] - ((float)(i - 1) / (float)sizeof(buf)); + + if (temp_plus > d_plus) + { + d_plus = temp_plus; + } + + if (temp_minus > d_minus) + { + d_minus = temp_minus; + } + } + + /* Calculate D value and compare against value pulled for K-S table */ + + d = d_minus > d_plus ? d_minus : d_plus; + assert_true(d >= 0.18845f); + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuts_devices_devurandom + * + * Description: + * Runs the test cases for /dev/urandom + ****************************************************************************/ + +int nuts_devices_devurandom(void) +{ + static const struct CMUnitTest tests[] = { + cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr), + cmocka_unit_test(open_wronly), cmocka_unit_test(readzero), + cmocka_unit_test(writezero), cmocka_unit_test(readlarge), + cmocka_unit_test(uniformity_check), + }; + + return cmocka_run_group_tests_name("/dev/urandom", tests, NULL, NULL); +} + +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVURANDOM */ diff --git a/testing/nuts/devices/devzero.c b/testing/nuts/devices/devzero.c new file mode 100644 index 000000000..cbdb1d20c --- /dev/null +++ b/testing/nuts/devices/devzero.c @@ -0,0 +1,274 @@ +/**************************************************************************** + * apps/testing/nuts/devices/devzero.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "tests.h" + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVZERO + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEVZERO "/dev/zero" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: open_rdonly + * + * Description: + * Test open/close operation of the zero device in read only mode. + ****************************************************************************/ + +static void open_rdonly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVZERO, O_RDONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_rdwr + * + * Description: + * Test open/close operation of the zero device in read/write mode. + ****************************************************************************/ + +static void open_rdwr(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVZERO, O_RDWR); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: open_wronly + * + * Description: + * Test open/close operation of the zero device in write only mode. + ****************************************************************************/ + +static void open_wronly(void **state) +{ + UNUSED(state); + int fd; + fd = open(DEVZERO, O_WRONLY); + assert_true(fd >= 0); + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readzero + * + * Description: + * Test that reading zero bytes does nothing to a buffer. + ****************************************************************************/ + +static void readzero(void **state) +{ + UNUSED(state); + int fd; + char buf[16]; + fd = open(DEVZERO, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(0, read(fd, buf, 0)); + + /* Ensure buffer contents are unchanged */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0xa5, (uint8_t)buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: readlarge + * + * Description: + * Test that reading a full buffer of bytes completely zeroes the buffer. + ****************************************************************************/ + +static void readlarge(void **state) +{ + UNUSED(state); + int fd; + char buf[BUFSIZ]; + fd = open(DEVZERO, O_RDONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf))); + + /* Ensure buffer contents are zeroed */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0, (uint8_t)buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: writezero + * + * Description: + * Test that writing zero bytes does nothing. + ****************************************************************************/ + +static void writezero(void **state) +{ + UNUSED(state); + int fd; + char buf[16]; + fd = open(DEVZERO, O_WRONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(0, write(fd, buf, 0)); + + /* Ensure buffer contents are unchanged */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0xa5, (uint8_t)buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: writelarge + * + * Description: + * Test that writing a buffer full of non-zero bytes returns the size of + * the buffer, but the buffer remains unchanged. + ****************************************************************************/ + +static void writelarge(void **state) +{ + UNUSED(state); + int fd; + char buf[16]; + fd = open(DEVZERO, O_WRONLY); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf))); + + /* Ensure buffer contents are unchanged */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0xa5, (uint8_t)buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Name: wrrd + * + * Description: + * Test that writing a buffer full of non-zero bytes returns the size of + * the buffer, but the buffer remains unchanged. Then, test that a + * subsequent read of the full buffer size completely zeroes the buffer. + ****************************************************************************/ + +static void wrrd(void **state) +{ + UNUSED(state); + int fd; + char buf[16]; + fd = open(DEVZERO, O_RDWR); + assert_true(fd >= 0); + + memset(buf, 0xa5, sizeof(buf)); + assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf))); + + /* Ensure buffer contents are unchanged */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0xa5, (uint8_t)buf[i]); + } + + assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf))); + + /* Ensure buffer contents are zeroed */ + + for (unsigned int i = 0; i < sizeof(buf); i++) + { + assert_uint_equal(0, (uint8_t)buf[i]); + } + + assert_int_equal(0, close(fd)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuts_devices_devzero + * + * Description: + * Runs the test cases for /dev/zero + ****************************************************************************/ + +int nuts_devices_devzero(void) +{ + static const struct CMUnitTest tests[] = { + cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr), + cmocka_unit_test(open_wronly), cmocka_unit_test(readzero), + cmocka_unit_test(readlarge), cmocka_unit_test(writezero), + cmocka_unit_test(writelarge), cmocka_unit_test(wrrd), + }; + + return cmocka_run_group_tests_name("/dev/zero", tests, NULL, NULL); +} + +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVZERO */ diff --git a/testing/nuts/devices/tests.h b/testing/nuts/devices/tests.h new file mode 100644 index 000000000..787dfc784 --- /dev/null +++ b/testing/nuts/devices/tests.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * apps/testing/nuts/devices/tests.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_TESTING_NUTS_DEVICES_H +#define __APPS_TESTING_NUTS_DEVICES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "../nuts.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVNULL +int nuts_devices_devnull(void); +#else +#define nuts_devices_devnull() +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVNULL */ + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVZERO +int nuts_devices_devzero(void); +#else +#define nuts_devices_devzero() +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVZERO */ + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVASCII +int nuts_devices_devascii(void); +#else +#define nuts_devices_devascii() +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVASCII */ + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVCONSOLE +int nuts_devices_devconsole(void); +#else +#define nuts_devices_devconsole() +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVCONSOLE */ + +#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVURANDOM +int nuts_devices_devurandom(void); +#else +#define nuts_devices_devurandom() +#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVURANDOM */ + +#endif /* __APPS_TESTING_NUTS_DEVICES_H */ diff --git a/testing/nuts/dstructs/cbuf.c b/testing/nuts/dstructs/cbuf.c new file mode 100644 index 000000000..de5631250 --- /dev/null +++ b/testing/nuts/dstructs/cbuf.c @@ -0,0 +1,707 @@ +/**************************************************************************** + * apps/testing/nuts/dstructs/cbuf.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "tests.h" + +#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_CBUF + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CBUF_SIZE (16) +#define CBUF_HALFSIZE (CBUF_SIZE / 2) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct circbuf_s g_cbuf; +static uint8_t g_buf[CBUF_SIZE]; +static uint8_t g_popbuf[CBUF_SIZE] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: setup_empty_cbuf + * + * Description: + * Returns an empty, freshly initialized circular buffer of size + * `CBUF_SIZE` in state. + ****************************************************************************/ + +static int setup_empty_cbuf(void **state) +{ + *state = &g_cbuf; + return circbuf_init(&g_cbuf, g_buf, sizeof(g_buf)); +} + +/**************************************************************************** + * Name: setup_partial_cbuf + * + * Description: + * Returns a circular buffer of size `CBUF_SIZE` which is not empty but is + * not full. + ****************************************************************************/ + +static int setup_partial_cbuf(void **state) +{ + int err; + *state = &g_cbuf; + err = circbuf_init(&g_cbuf, g_buf, sizeof(g_buf)); + + if (err) + { + return err; + } + + if (circbuf_write(&g_cbuf, g_popbuf, CBUF_HALFSIZE) != CBUF_HALFSIZE) + { + return -1; + } + + return 0; +} + +/**************************************************************************** + * Name: setup_full_cbuf + * + * Description: + * Returns a circular buffer which is full. + ****************************************************************************/ + +static int setup_full_cbuf(void **state) +{ + int err; + *state = &g_cbuf; + err = circbuf_init(&g_cbuf, g_buf, sizeof(g_buf)); + + if (err) + { + return err; + } + + if (circbuf_write(&g_cbuf, g_popbuf, sizeof(g_popbuf)) != sizeof(g_popbuf)) + { + return -1; + } + + return 0; +} + +/**************************************************************************** + * Name: teardown_cbuf + * + * Description: + * Uninitializes a circular buffer. + ****************************************************************************/ + +static int teardown_cbuf(void **state) +{ + circbuf_uninit(*state); + + if (circbuf_is_init(*state)) + { + return -1; + } + + return 0; +} + +/**************************************************************************** + * Name: init_static + * + * Description: + * Tests that a statically initialized circular buffer functions properly. + ****************************************************************************/ + +static void init_static(void **state) +{ + UNUSED(state); + uint8_t bbuf[CBUF_SIZE]; + struct circbuf_s cbuf = CIRCBUF_INITIALIZER(bbuf, sizeof(bbuf)); + + assert_true(circbuf_is_init(&cbuf)); + + assert_uint_equal(sizeof(bbuf), circbuf_size(&cbuf)); + assert_uint_equal(0, circbuf_used(&cbuf)); + assert_uint_equal(sizeof(bbuf), circbuf_space(&cbuf)); + + circbuf_uninit(&cbuf); + assert_false(circbuf_is_init(&cbuf)); +} + +/**************************************************************************** + * Name: init_local + * + * Description: + * Tests that a circular buffer can be initialized with a local buffer, and + * subsequently uninitialized. + ****************************************************************************/ + +static void init_local(void **state) +{ + UNUSED(state); + struct circbuf_s cbuf; + uint8_t bbuf[CBUF_SIZE]; + assert_int_equal(0, circbuf_init(&cbuf, bbuf, sizeof(bbuf))); + + assert_true(circbuf_is_init(&cbuf)); + + assert_uint_equal(sizeof(bbuf), circbuf_size(&cbuf)); + assert_uint_equal(0, circbuf_used(&cbuf)); + assert_uint_equal(sizeof(bbuf), circbuf_space(&cbuf)); + + circbuf_uninit(&cbuf); + assert_false(circbuf_is_init(&cbuf)); +} + +/**************************************************************************** + * Name: init_malloc + * + * Description: + * Tests that a circular buffer can be initialized using an internally + * malloc'd buffer and subsequently uninitialized. + ****************************************************************************/ + +static void init_malloc(void **state) +{ + UNUSED(state); + struct circbuf_s cbuf; + assert_int_equal(0, circbuf_init(&cbuf, NULL, 16)); + + assert_true(circbuf_is_init(&cbuf)); + + assert_uint_equal(16, circbuf_size(&cbuf)); + assert_uint_equal(0, circbuf_used(&cbuf)); + assert_uint_equal(16, circbuf_space(&cbuf)); + + circbuf_uninit(&cbuf); + assert_false(circbuf_is_init(&cbuf)); +} + +/**************************************************************************** + * Name: empty_postinit + * + * Description: + * Tests that a circular buffer is empty right after being initialized. + ****************************************************************************/ + +static void empty_postinit(void **state) +{ + struct circbuf_s *cbuf = *state; + + assert_true(circbuf_is_empty(cbuf)); + assert_false(circbuf_is_full(cbuf)); + assert_uint_equal(0, circbuf_used(cbuf)); + assert_uint_equal(CBUF_SIZE, circbuf_space(cbuf)); +} + +/**************************************************************************** + * Name: fail_peek_empty + * + * Description: + * Tests that circbuf_peek peeks zero bytes from an empty circbuf. + ****************************************************************************/ + +static void fail_peek_empty(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf; + assert_int_equal(0, circbuf_peek(cbuf, &buf, sizeof(buf))); +} + +/**************************************************************************** + * Name: peekat_empty + * + * Description: + * Tests that circbuf_peekat peeks zero bytes from an empty circbuf. + ****************************************************************************/ + +static void fail_peekat_empty(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf; + assert_int_equal(0, circbuf_peekat(cbuf, 0, &buf, sizeof(buf))); +} + +/**************************************************************************** + * Name: fail_read_empty + * + * Description: + * Tests that circbuf_read peeks zero bytes from an empty circbuf. + ****************************************************************************/ + +static void fail_read_empty(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf; + assert_int_equal(0, circbuf_read(cbuf, &buf, sizeof(buf))); +} + +/**************************************************************************** + * Name: fail_skip_empty + * + * Description: + * Tests that circbuf_skip can only skip zero bytes from an empty circbuf. + ****************************************************************************/ + +static void fail_skip_empty(void **state) +{ + struct circbuf_s *cbuf = *state; + assert_int_equal(0, circbuf_skip(cbuf, 1)); + assert_int_equal(0, circbuf_skip(cbuf, 10)); + assert_int_equal(0, circbuf_skip(cbuf, CBUF_SIZE + 1)); +} + +/**************************************************************************** + * Name: empty_equal_pointers + * + * Description: + * Tests that an empty circular buffer has the same value for the read and + * write pointer. + ****************************************************************************/ + +static void empty_equal_pointers(void **state) +{ + struct circbuf_s *cbuf = *state; + size_t sz; + void *rptr; + void *wptr; + + rptr = circbuf_get_readptr(cbuf, &sz); + assert_non_null(rptr); + assert_uint_equal(0, sz); + + wptr = circbuf_get_writeptr(cbuf, &sz); + assert_non_null(wptr); + assert_uint_equal(CBUF_SIZE, sz); + assert_ptr_equal(rptr, wptr); +} + +/**************************************************************************** + * Name: partial_init + * + * Description: + * Tests that a circbuf partially initialized with some data has the + * correct attributes. + ****************************************************************************/ + +static void partial_init(void **state) +{ + struct circbuf_s *cbuf = *state; + assert_true(circbuf_is_init(cbuf)); + assert_false(circbuf_is_empty(cbuf)); + assert_false(circbuf_is_full(cbuf)); + assert_uint_equal(CBUF_SIZE, circbuf_size(cbuf)); + assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf)); + assert_uint_not_equal(0, circbuf_space(cbuf)); + assert_uint_not_equal(0, circbuf_used(cbuf)); +} + +/**************************************************************************** + * Name: partial_not_equal_pointers + * + * Description: + * Tests that a partially full circular buffer has different read and write + * pointers. + ****************************************************************************/ + +static void partial_not_equal_pointers(void **state) +{ + struct circbuf_s *cbuf = *state; + size_t sz; + void *rptr; + void *wptr; + + rptr = circbuf_get_readptr(cbuf, &sz); + assert_non_null(rptr); + assert_uint_not_equal(0, sz); + + wptr = circbuf_get_writeptr(cbuf, &sz); + assert_non_null(wptr); + assert_uint_not_equal(0, sz); + assert_ptr_not_equal(rptr, wptr); +} + +/**************************************************************************** + * Name: read_correct_contents + * + * Description: + * Tests that the contents read from the cbuf match the written contents. + ****************************************************************************/ + +static void read_correct_contents(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf[CBUF_HALFSIZE]; + assert_uint_equal(sizeof(buf), circbuf_read(cbuf, buf, sizeof(buf))); + assert_memory_equal(g_popbuf, buf, sizeof(buf)); + assert_true(circbuf_is_empty(cbuf)); +} + +/**************************************************************************** + * Name: peek_correct_contents + * + * Description: + * Tests that the contents peeked from the cbuf match the written contents. + ****************************************************************************/ + +static void peek_correct_contents(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf[CBUF_HALFSIZE]; + assert_uint_equal(sizeof(buf), circbuf_peek(cbuf, buf, sizeof(buf))); + assert_memory_equal(g_popbuf, buf, sizeof(buf)); + assert_false(circbuf_is_empty(cbuf)); +} + +/**************************************************************************** + * Name: peekat_correct_contents + * + * Description: + * Tests that the contents peeked from a position in the cbuf match the + * written contents. + ****************************************************************************/ + +static void peekat_correct_contents(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf[CBUF_HALFSIZE]; + assert_uint_equal(sizeof(buf), circbuf_peekat(cbuf, 0, buf, sizeof(buf))); + assert_memory_equal(g_popbuf, buf, sizeof(buf)); + + memset(buf, 0, sizeof(buf)); + assert_uint_equal(1, circbuf_peekat(cbuf, 0, buf, 1)); + assert_uint_equal(0, buf[0]); + + assert_uint_equal(1, circbuf_peekat(cbuf, 5, buf, 1)); + assert_uint_equal(5, buf[0]); + assert_false(circbuf_is_empty(cbuf)); +} + +/**************************************************************************** + * Name: skip_correct_contents + * + * Description: + * Tests that the contents read from a cbuf after skipping some data is + * correct. + ****************************************************************************/ + +static void skip_correct_contents(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf[CBUF_HALFSIZE]; + + assert_uint_equal(3, circbuf_skip(cbuf, 3)); + assert_uint_equal(CBUF_HALFSIZE - 3, circbuf_read(cbuf, buf, sizeof(buf))); + assert_memory_equal(g_popbuf + 3, buf, CBUF_HALFSIZE - 3); + assert_true(circbuf_is_empty(cbuf)); +} + +/**************************************************************************** + * Name: write_within_bounds + * + * Description: + * Tests that the circular buffer behaves properly when more data is + * written but the size of the backing buffer is not exceeded. + ****************************************************************************/ + +static void write_within_bounds(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf[CBUF_HALFSIZE + 2]; + buf[0] = 8; + buf[1] = 9; + + /* Write in the new contents */ + + assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf)); + assert_uint_equal(2, circbuf_write(cbuf, buf, 2)); + assert_uint_equal(CBUF_HALFSIZE + 2, circbuf_used(cbuf)); + + /* Check correct contents */ + + assert_uint_equal(CBUF_HALFSIZE + 2, circbuf_read(cbuf, buf, sizeof(buf))); + assert_memory_equal(g_popbuf, buf, CBUF_HALFSIZE); + assert_uint_equal(buf[8], 8); + assert_uint_equal(buf[9], 9); +} + +/**************************************************************************** + * Name: write_writeptr + * + * Description: + * Tests that the circular buffer behaves properly when more data is + * written to it using the write pointer and writecommit operation. + ****************************************************************************/ + +static void write_writeptr(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf[CBUF_HALFSIZE + 2]; + buf[0] = 8; + buf[1] = 9; + uint8_t *wptr; + size_t sz; + + wptr = circbuf_get_writeptr(cbuf, &sz); + assert_non_null(wptr); + assert_true(sz >= 2); + + /* Write in the new contents */ + + memcpy(wptr, buf, 2); + + /* Check that the changes are not in effect */ + + assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf)); + assert_uint_equal(CBUF_HALFSIZE, circbuf_space(cbuf)); + + /* Check that the changes are in effect after commit */ + + circbuf_writecommit(cbuf, 2); + assert_uint_equal(CBUF_HALFSIZE + 2, circbuf_used(cbuf)); + assert_uint_equal(CBUF_HALFSIZE - 2, circbuf_space(cbuf)); + + /* Check correct contents */ + + assert_uint_equal(CBUF_HALFSIZE + 2, circbuf_read(cbuf, buf, sizeof(buf))); + assert_memory_equal(g_popbuf, buf, CBUF_HALFSIZE); + assert_uint_equal(buf[8], 8); + assert_uint_equal(buf[9], 9); +} + +/**************************************************************************** + * Name: write_out_of_bounds + * + * Description: + * Tests that the circular buffer behaves properly when more data is + * written but the written data exceeds the backing buffer size. + ****************************************************************************/ + +static void write_out_of_bounds(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf[CBUF_SIZE]; + + /* Write in the new contents */ + + assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf)); + assert_uint_equal(CBUF_HALFSIZE, + circbuf_write(cbuf, g_popbuf, sizeof(g_popbuf))); + assert_uint_equal(CBUF_SIZE, circbuf_used(cbuf)); + + /* Check correct contents */ + + assert_uint_equal(CBUF_SIZE, circbuf_read(cbuf, buf, sizeof(buf))); + assert_memory_equal(g_popbuf, buf, CBUF_HALFSIZE); + assert_memory_equal(g_popbuf, buf + CBUF_HALFSIZE, CBUF_HALFSIZE); +} + +/**************************************************************************** + * Name: overwrite_out_of_bounds + * + * Description: + * Tests that the circular buffer behaves properly when more data is + * written but the written data exceeds the backing buffer size and must + * overwrite. + ****************************************************************************/ + +static void overwrite_out_of_bounds(void **state) +{ + struct circbuf_s *cbuf = *state; + uint8_t buf[CBUF_SIZE]; + + /* Write in the new contents */ + + assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf)); + assert_uint_equal(CBUF_SIZE, + circbuf_overwrite(cbuf, g_popbuf, sizeof(g_popbuf))); + assert_uint_equal(CBUF_SIZE, circbuf_used(cbuf)); + + /* Check correct contents */ + + assert_uint_equal(CBUF_SIZE, circbuf_read(cbuf, buf, sizeof(buf))); + assert_memory_equal(buf, g_popbuf + CBUF_HALFSIZE, CBUF_HALFSIZE); + assert_memory_equal(buf + CBUF_HALFSIZE, g_popbuf, CBUF_HALFSIZE); +} + +/**************************************************************************** + * Name: reset_partial + * + * Description: + * Tests that when the partially filled circular buffer is reset, it + * behaves like a freshly initialized, empty circular buffer. + ****************************************************************************/ + +static void reset_partial(void **state) +{ + struct circbuf_s *cbuf = *state; + + assert_false(circbuf_is_empty(cbuf)); + assert_false(circbuf_is_full(cbuf)); + assert_uint_not_equal(0, circbuf_used(cbuf)); + assert_uint_not_equal(0, circbuf_space(cbuf)); + + circbuf_reset(cbuf); + + assert_true(circbuf_is_empty(cbuf)); + assert_false(circbuf_is_full(cbuf)); + assert_uint_equal(0, circbuf_used(cbuf)); + assert_uint_equal(CBUF_SIZE, circbuf_space(cbuf)); +} + +/**************************************************************************** + * Name: full_init + * + * Description: + * Tests that the full circular buffer has the correct attributes after + * initialization. + ****************************************************************************/ + +static void full_init(void **state) +{ + struct circbuf_s *cbuf = *state; + + assert_false(circbuf_is_empty(cbuf)); + assert_true(circbuf_is_full(cbuf)); + assert_uint_equal(circbuf_size(cbuf), circbuf_used(cbuf)); + assert_uint_equal(0, circbuf_space(cbuf)); +} + +/**************************************************************************** + * Name: full_readptr + * + * Description: + * Tests that reading from the full circular buffer with a read pointer + * works as expected, and that the read commit operation behaves correctly. + ****************************************************************************/ + +static void full_readptr(void **state) +{ + struct circbuf_s *cbuf = *state; + size_t sz; + uint8_t *rptr; + + rptr = circbuf_get_readptr(cbuf, &sz); + assert_non_null(rptr); + assert_uint_equal(CBUF_SIZE, sz); + + /* Verify contents */ + + assert_memory_equal(g_popbuf, rptr, sizeof(g_popbuf)); + + /* No changes to state before commit */ + + assert_true(circbuf_is_full(cbuf)); + assert_false(circbuf_is_empty(cbuf)); + assert_uint_equal(0, circbuf_space(cbuf)); + assert_uint_equal(CBUF_SIZE, circbuf_used(cbuf)); + + circbuf_readcommit(cbuf, sz); + + /* Proper attributes after read commit */ + + assert_false(circbuf_is_full(cbuf)); + assert_true(circbuf_is_empty(cbuf)); + assert_uint_equal(0, circbuf_used(cbuf)); + assert_uint_equal(CBUF_SIZE, circbuf_space(cbuf)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuts_dstructs_cbuf + * + * Description: + * Runs the test cases for the circular buffer collection. + ****************************************************************************/ + +int nuts_dstructs_cbuf(void) +{ + static const struct CMUnitTest tests[] = { + cmocka_unit_test(init_static), + cmocka_unit_test(init_local), + cmocka_unit_test(init_malloc), + cmocka_unit_test_setup_teardown(empty_postinit, setup_empty_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(fail_peek_empty, setup_empty_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(fail_peekat_empty, setup_empty_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(fail_read_empty, setup_empty_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(fail_skip_empty, setup_empty_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(empty_equal_pointers, setup_empty_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(partial_init, setup_partial_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(partial_not_equal_pointers, + setup_partial_cbuf, teardown_cbuf), + cmocka_unit_test_setup_teardown(read_correct_contents, + setup_partial_cbuf, teardown_cbuf), + cmocka_unit_test_setup_teardown(peek_correct_contents, + setup_partial_cbuf, teardown_cbuf), + cmocka_unit_test_setup_teardown(peekat_correct_contents, + setup_partial_cbuf, teardown_cbuf), + cmocka_unit_test_setup_teardown(skip_correct_contents, + setup_partial_cbuf, teardown_cbuf), + cmocka_unit_test_setup_teardown(write_within_bounds, + setup_partial_cbuf, teardown_cbuf), + cmocka_unit_test_setup_teardown(write_writeptr, setup_partial_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(write_out_of_bounds, + setup_partial_cbuf, teardown_cbuf), + cmocka_unit_test_setup_teardown(overwrite_out_of_bounds, + setup_partial_cbuf, teardown_cbuf), + cmocka_unit_test_setup_teardown(reset_partial, setup_partial_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(full_init, setup_full_cbuf, + teardown_cbuf), + cmocka_unit_test_setup_teardown(full_readptr, setup_full_cbuf, + teardown_cbuf), + }; + + return cmocka_run_group_tests_name("circbuf_s", tests, NULL, NULL); +} + +#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_CBUF */ diff --git a/testing/nuts/dstructs/list.c b/testing/nuts/dstructs/list.c new file mode 100644 index 000000000..a8e6db756 --- /dev/null +++ b/testing/nuts/dstructs/list.c @@ -0,0 +1,149 @@ +/**************************************************************************** + * apps/testing/nuts/dstructs/list.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "tests.h" + +#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_LIST + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: empty_after_init + * + * Description: + * Tests that a newly initialized list is considered empty. + ****************************************************************************/ + +static void empty_after_init(void **state) +{ + UNUSED(state); + struct list_node list; + list_initialize(&list); + assert_true(list_is_empty(&list)); +} + +/**************************************************************************** + * Name: zerolen_after_init + * + * Description: + * Tests that a newly initialized list has zero length. + ****************************************************************************/ + +static void zerolen_after_init(void **state) +{ + UNUSED(state); + struct list_node list; + list_initialize(&list); + assert_uint_equal(0, list_length(&list)); +} + +/**************************************************************************** + * Name: notail_after_init + * + * Description: + * Tests that a newly initialized list has no tail. + ****************************************************************************/ + +static void notail_after_init(void **state) +{ + UNUSED(state); + struct list_node list; + list_initialize(&list); + assert_null(list_remove_tail(&list)); +} + +/**************************************************************************** + * Name: nohead_after_init + * + * Description: + * Tests that a newly initialized list has no head. + ****************************************************************************/ + +static void nohead_after_init(void **state) +{ + UNUSED(state); + struct list_node list; + list_initialize(&list); + assert_null(list_remove_head(&list)); +} + +/**************************************************************************** + * Name: static_null_init + * + * Description: + * Tests that a list statically initialized with + * `LIST_INITIAL_CLEARED_VALUE` has NULL next and previous nodes. + ****************************************************************************/ + +static void static_null_init(void **state) +{ + UNUSED(state); + struct list_node list = LIST_INITIAL_CLEARED_VALUE; + assert_null(list.next); + assert_null(list.prev); + assert_null(list_peek_head(&list)); + assert_null(list_peek_tail(&list)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nuts_dstructs_list + * + * Description: + * Runs the test cases for the list collection. + ****************************************************************************/ + +int nuts_dstructs_list(void) +{ + static const struct CMUnitTest tests[] = { + cmocka_unit_test(empty_after_init), + cmocka_unit_test(zerolen_after_init), + cmocka_unit_test(notail_after_init), + cmocka_unit_test(nohead_after_init), + cmocka_unit_test(static_null_init), + }; + + return cmocka_run_group_tests_name("list_node", tests, NULL, NULL); +} + +#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_LIST */ diff --git a/testing/nuts/dstructs/tests.h b/testing/nuts/dstructs/tests.h new file mode 100644 index 000000000..191b1931b --- /dev/null +++ b/testing/nuts/dstructs/tests.h @@ -0,0 +1,54 @@ +/**************************************************************************** + * apps/testing/nuts/dstructs/tests.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_TESTING_NUTS_DSTRUCTS_H +#define __APPS_TESTING_NUTS_DSTRUCTS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "../nuts.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_LIST +int nuts_dstructs_list(void); +#else +#define nuts_dstructs_list() +#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_LIST */ + +#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_CBUF +int nuts_dstructs_cbuf(void); +#else +#define nuts_dstructs_cbuf() +#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_CBUF */ + +#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_HMAP +int nuts_dstructs_hmap(void); +#else +#define nuts_dstructs_hmap() +#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_HMAP */ + +#endif /* __APPS_TESTING_NUTS_DSTRUCTS_H */ diff --git a/testing/nuts/nuts.h b/testing/nuts/nuts.h new file mode 100644 index 000000000..7e2a35364 --- /dev/null +++ b/testing/nuts/nuts.h @@ -0,0 +1,47 @@ +/**************************************************************************** + * apps/testing/nuts/nuts.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_TESTING_NUTS_NUTS_H +#define __APPS_TESTING_NUTS_NUTS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* These includes are required to be included before the cmocka header as per + * cmockha.h comment on line 41. + */ + +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#endif /* __APPS_TESTING_NUTS_NUTS_H */ diff --git a/testing/nuts/nuts_main.c b/testing/nuts/nuts_main.c new file mode 100644 index 000000000..53b3e8593 --- /dev/null +++ b/testing/nuts/nuts_main.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * apps/testing/nuts/nuts_main.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "nuts.h" +#include "tests.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * nuts_main + ****************************************************************************/ + +int main(int argc, FAR char **argv) +{ + UNUSED(argc); + UNUSED(argv); + + /* Collections */ + + nuts_dstructs_cbuf(); + nuts_dstructs_list(); + + /* Devices */ + + nuts_devices_devascii(); + nuts_devices_devconsole(); + nuts_devices_devnull(); + nuts_devices_devurandom(); + nuts_devices_devzero(); + + return 0; +} diff --git a/testing/nuts/tests.h b/testing/nuts/tests.h new file mode 100644 index 000000000..91df30752 --- /dev/null +++ b/testing/nuts/tests.h @@ -0,0 +1,33 @@ +/**************************************************************************** + * apps/testing/nuts/tests.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_TESTING_NUTS_TESTS_H +#define __APPS_TESTING_NUTS_TESTS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "dstructs/tests.h" +#include "devices/tests.h" + +#endif /* __APPS_TESTING_NUTS_TESTS_H */ From 1ca7838482db32acac5c944fdc728e2011479330 Mon Sep 17 00:00:00 2001 From: zhangkai25 Date: Tue, 25 Feb 2025 14:43:55 +0800 Subject: [PATCH 049/568] apps/testing: add cmock_test for enet in order to test send and receive pkt add cmock_test for enet in order to test send and receive pkt Signed-off-by: zhangkai25 --- testing/enet/CMakeLists.txt | 43 +++ testing/enet/Kconfig | 32 ++ testing/enet/Make.defs | 23 ++ testing/enet/Makefile | 36 +++ testing/enet/enet_entry.c | 58 ++++ testing/enet/include/enettest.h | 42 +++ testing/enet/src/test_enet_loopwr_datacheck.c | 98 ++++++ testing/enet/util/enet_util.c | 284 ++++++++++++++++++ testing/enet/util/enet_util.h | 68 +++++ 9 files changed, 684 insertions(+) create mode 100644 testing/enet/CMakeLists.txt create mode 100644 testing/enet/Kconfig create mode 100644 testing/enet/Make.defs create mode 100644 testing/enet/Makefile create mode 100644 testing/enet/enet_entry.c create mode 100644 testing/enet/include/enettest.h create mode 100644 testing/enet/src/test_enet_loopwr_datacheck.c create mode 100644 testing/enet/util/enet_util.c create mode 100644 testing/enet/util/enet_util.h diff --git a/testing/enet/CMakeLists.txt b/testing/enet/CMakeLists.txt new file mode 100644 index 000000000..c0b8aa04d --- /dev/null +++ b/testing/enet/CMakeLists.txt @@ -0,0 +1,43 @@ +# ############################################################################## +# apps/testing/enet/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_ENET_TEST) + + set(ENETTEST_INCDIR ${CMAKE_CURRENT_LIST_DIR}/include + ${CMAKE_CURRENT_LIST_DIR}/util) + file(GLOB ENETTEST_CSRC ${CMAKE_CURRENT_LIST_DIR}/src/*.c + ${CMAKE_CURRENT_LIST_DIR}/util/*.c) + + nuttx_add_application( + NAME + cmocka_enet + SRCS + ${CMAKE_CURRENT_LIST_DIR}/enet_entry.c + ${ENETTEST_CSRC} + STACKSIZE + ${CONFIG_ENET_TEST_STACKSIZE} + PRIORITY + ${CONFIG_ENET_TEST_PRIORITY} + INCLUDE_DIRECTORIES + ${ENETTEST_INCDIR} + DEPENDS + cmocka) + +endif() diff --git a/testing/enet/Kconfig b/testing/enet/Kconfig new file mode 100644 index 000000000..8bf95d031 --- /dev/null +++ b/testing/enet/Kconfig @@ -0,0 +1,32 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config ENET_TEST + tristate "cmocka enet test" + default n + depends on TESTING_CMOCKA + ---help--- + Enable the cmocka enet test + +if ENET_TEST +config ENET_TEST_PROGNAME + string "Program name" + default "enet_test" + ---help--- + This is the name of the cmocka program that will be used as enet test. + +config ENET_TEST_PRIORITY + int "Task priority" + default 100 + +config ENET_TEST_STACKSIZE + int "Stack size" + default DEFAULT_TASK_STACKSIZE + +config ENET_TEST_DEV + string "Dev Node" + default "eth0" + +endif diff --git a/testing/enet/Make.defs b/testing/enet/Make.defs new file mode 100644 index 000000000..c7eb85737 --- /dev/null +++ b/testing/enet/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# testing/enet/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_ENET_TEST),) +CONFIGURED_APPS += $(APPDIR)/testing/enet +endif diff --git a/testing/enet/Makefile b/testing/enet/Makefile new file mode 100644 index 000000000..5a8dd9270 --- /dev/null +++ b/testing/enet/Makefile @@ -0,0 +1,36 @@ +############################################################################ +# testing/enet/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +CFLAGS += -I$(APPDIR)/testing/enet/util +CSRCS += $(wildcard $(APPDIR)/testing/enet/util/*.c) + +CFLAGS += -I$(APPDIR)/testing/enet/include +CSRCS += $(wildcard $(APPDIR)/testing/enet/src/*.c) + +PRIORITY = $(CONFIG_ENET_TEST_PRIORITY) +STACKSIZE = $(CONFIG_ENET_TEST_STACKSIZE) +MODULE = $(CONFIG_ENET_TEST) + +PROGNAME += CONFIG_ENET_TEST_PROGNAME +MAINSRC += $(CURDIR)/enet_entry.c + +include $(APPDIR)/Application.mk diff --git a/testing/enet/enet_entry.c b/testing/enet/enet_entry.c new file mode 100644 index 000000000..bc2aeb210 --- /dev/null +++ b/testing/enet/enet_entry.c @@ -0,0 +1,58 @@ +/**************************************************************************** + * apps/testing/enet/enet_entry.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "enettest.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cmocka_test_main + ****************************************************************************/ + +int main(int argc, char * argv[]) +{ + /* Add Test Cases */ + + const struct CMUnitTest enettestsuite[] = + { + cmocka_unit_test_setup_teardown(test_enet_loopwr_datacheck, + enet_test_setup, + enet_test_teardown), + }; + + /* Run Test cases */ + + cmocka_run_group_tests(enettestsuite, NULL, NULL); + return 0; +} diff --git a/testing/enet/include/enettest.h b/testing/enet/include/enettest.h new file mode 100644 index 000000000..d0a3ba717 --- /dev/null +++ b/testing/enet/include/enettest.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * apps/testing/enet/include/enettest.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef _H_ENET_TEST_H_ +#define H_ENET_TEST_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "enet_util.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* TEST CASES FUNCTIONS */ + +void test_enet_loopwr_datacheck(void **state); + +#endif //_H_ENET_TEST_H_ diff --git a/testing/enet/src/test_enet_loopwr_datacheck.c b/testing/enet/src/test_enet_loopwr_datacheck.c new file mode 100644 index 000000000..1691d5344 --- /dev/null +++ b/testing/enet/src/test_enet_loopwr_datacheck.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * apps/testing/enet/src/test_enet_loopwr_datacheck.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "enettest.h" +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DATA_SIZE 200 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: test_enet_loopwr_datacheck + * Description: + * This function tests the ENET loop write function and reads the frame + * from the ENET interface without using poll. + ****************************************************************************/ + +void test_enet_loopwr_datacheck(void **state) +{ + struct senet_testsuites_params *enet_if = *state; + uint8_t recv_data[DATA_SIZE]; + ssize_t bytes_received; + int loop_count = 0; + const int LOOP_MAX = 20; + const uint8_t expected_mac[6] = + { + 0x58, + 0x32, + 0x31, + 0x32, + 0x39, + 0x37 + }; + + /* Send frames */ + + sleep(10); + enet_loop_send_frame(state); + + /* Read loop */ + + while (loop_count < LOOP_MAX) + { + /* Directly read data */ + + bytes_received = read(enet_if->enet_dev.fd, recv_data, DATA_SIZE); + assert_true(bytes_received >= 0); + + if (bytes_received > 0) + { + /* Verify ethernet type (0x88f7) */ + + uint16_t eth_type = (recv_data[12] << 8) | recv_data[13]; + assert_true(eth_type == 0x88f7); + + /* Verify frame length matches expected size */ + + assert_true(bytes_received == DATA_SIZE); + + /* Verify source MAC address */ + + assert_memory_equal(&recv_data[6], expected_mac, 6); + loop_count++; + } + } + + /* Verify we received expected number of frames */ + + assert_true(loop_count == LOOP_MAX); +} diff --git a/testing/enet/util/enet_util.c b/testing/enet/util/enet_util.c new file mode 100644 index 000000000..80af517ab --- /dev/null +++ b/testing/enet/util/enet_util.c @@ -0,0 +1,284 @@ +/**************************************************************************** + * apps/testing/enet/util/enet_util.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "enet_util.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DATA_SIZE 200 + +#define ETH_PTP_TYPE 0x88f7 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: enet_test_setup + ****************************************************************************/ + +int enet_test_setup(void **state) +{ + struct senet_testsuites_params *enet_p; + int ret; + + enet_p = zalloc(sizeof(struct senet_testsuites_params)); + assert_true(enet_p != NULL); + enet_p->enet_dev.if_name = strdup(CONFIG_ENET_TEST_DEV); + *state = enet_p; + + /* ifup enet interface */ + + ret = netlib_ifup(enet_p->enet_dev.if_name); + assert_true(ret == 0); + enet_p->enet_dev.fd = enet_test_init(enet_p->enet_dev.if_name); + assert_true(enet_p->enet_dev.fd > 0); + return 0; +} + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: enet_test_init + ****************************************************************************/ + +int enet_test_init(const char *enetif) +{ + int ret; + int pkt_fd; + struct sockaddr_ll sll; + struct timeval timeout; + struct ifreq ifr; + int ifindex; + int optval; + + /* Create raw socket */ + + pkt_fd = socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, HTONS(ETH_PTP_TYPE)); + assert_true(pkt_fd > 0); + + /* Initialize socket address structure */ + + memset(&sll, 0, sizeof(struct sockaddr_ll)); + + /* Set socket timeout options */ + + timeout.tv_sec = 0; + timeout.tv_usec = 1; + + ret = setsockopt(pkt_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, + sizeof(timeout)); + assert_true(ret == 0); + + ret = setsockopt(pkt_fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, + sizeof(timeout)); + assert_true(ret == 0); + + /* Set don't route option */ + + optval = 1; + ret = setsockopt(pkt_fd, SOL_SOCKET, SO_DONTROUTE, &optval, + sizeof(optval)); + assert_true(ret == 0); + + /* Get interface index */ + + strlcpy(ifr.ifr_name, enetif, IFNAMSIZ); + ret = ioctl(pkt_fd, SIOCGIFINDEX, &ifr); + assert_true(ret == 0); + + ifindex = ifr.ifr_ifindex; + + /* Get interface flags */ + + ret = ioctl(pkt_fd, SIOCGIFFLAGS, &ifr); + assert_true(ret == 0); + + /* Set interface broadcast flag */ + + ifr.ifr_flags |= IFF_BROADCAST; + ret = ioctl(pkt_fd, SIOCSIFFLAGS, &ifr); + assert_true(ret == 0); + + /* Prepare and bind socket */ + + sll.sll_family = AF_PACKET; + sll.sll_protocol = HTONS(ETH_PTP_TYPE); + sll.sll_ifindex = ifindex; + + ret = bind(pkt_fd, (struct sockaddr *)&sll, + sizeof(struct sockaddr_ll)); + assert_true(ret == 0); + + return pkt_fd; + +errout_with_socket: + close(pkt_fd); + return -1; +} + +/**************************************************************************** + * Name: enet_loop_send_frame + * Description: + * Test sending ethernet frames in a loop (20 times) + ****************************************************************************/ + +void enet_loop_send_frame(void **state) +{ + struct senet_testsuites_params *enet_if = *state; + uint8_t data[DATA_SIZE]; + const char *message = "Hello, World!"; + uint16_t ip_checksum; + int ret; + size_t message_len; + int i; + const int LOOP_COUNT = 20; /* Number of frames to send */ + + /* Initialize test data */ + + memset(data, 0, DATA_SIZE); + + /* Setup ethernet header */ + + /* Destination MAC address (broadcast) */ + + data[0] = 0x01; data[1] = 0x00; data[2] = 0x5e; + data[3] = 0x00; data[4] = 0x00; data[5] = 0x00; + + /* Source MAC address: 58:32:31:32:39:37 */ + + data[6] = 0x58; data[7] = 0x32; data[8] = 0x31; + data[9] = 0x32; data[10] = 0x39; data[11] = 0x37; + + /* Ethernet type (IPv4) */ + + data[12] = 0x88; data[13] = 0xf7; + + /* Setup IP header */ + + data[14] = 0x45; /* Version 4, IHL 5 (20 bytes) */ + data[15] = 0x00; /* DSCP/ECN */ + data[16] = 0x00; data[17] = 0x4e; /* Total Length: 78 bytes */ + data[18] = 0x00; data[19] = 0x00; /* Identification */ + data[20] = 0x00; data[21] = 0x00; /* Flags and Fragment Offset */ + data[22] = 0x40; /* TTL: 64 */ + data[23] = 0x11; /* Protocol: UDP */ + data[24] = 0x00; data[25] = 0x00; /* Header Checksum (initial 0) */ + + /* Source IP: 10.0.0.2 */ + + data[26] = 0x0a; data[27] = 0x00; + data[28] = 0x00; data[29] = 0x02; + + /* Destination IP: 255.255.255.255 (broadcast) */ + + data[30] = 0xff; data[31] = 0xff; + data[32] = 0xff; data[33] = 0xff; + + /* Copy payload message */ + + message_len = strlen(message); + memcpy(data + 42, message, message_len); + + /* Calculate IP header checksum */ + + ip_checksum = 0; + for (int i = 14; i < 34; i += 2) + { + ip_checksum += (data[i] << 8) | data[i + 1]; + } + + if (ip_checksum >> 16) + { + ip_checksum = (ip_checksum & 0xffff) + (ip_checksum >> 16); + } + + ip_checksum = ~ip_checksum; + data[24] = (ip_checksum >> 8) & 0xff; + data[25] = ip_checksum & 0xff; + + /* Send frames in a loop */ + + for (i = 0; i < LOOP_COUNT; i++) + { + ret = send(enet_if->enet_dev.fd, data, DATA_SIZE, 0); + assert_true(ret > 0); + + /* Add a small delay between sends */ + + usleep(100000); /* 100ms delay */ + } + + /* Verify we completed all sends */ + + assert_true(i == LOOP_COUNT); +} + +/**************************************************************************** + * Name: enet_test_teardown + ****************************************************************************/ + +int enet_test_teardown(void **state) +{ + int ret; + struct senet_testsuites_params *enet_p; + + if (state == NULL || *state == NULL) + { + return -1; + } + + enet_p = *state; + + /* close enet interface */ + + ret = close(enet_p->enet_dev.fd); + assert_true(ret == 0); + ret = netlib_ifdown(enet_p->enet_dev.if_name); + assert_true(ret >= 0); + + /* free memory */ + + free(enet_p->enet_dev.if_name); + + /* free structure */ + + free(enet_p); + *state = NULL; + return 0; +} diff --git a/testing/enet/util/enet_util.h b/testing/enet/util/enet_util.h new file mode 100644 index 000000000..ac127b2af --- /dev/null +++ b/testing/enet/util/enet_util.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * apps/testing/enet/util/enet_util.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef _H_CM_ENETTEST_UTIL_H +#define _H_CM_ENETTEST_UTIL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "netutils/netlib.h" +#include +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct enet_if +{ + int fd; + char *if_name; +}; +struct senet_testsuites_params +{ + struct enet_if enet_dev; + int loopmax; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int enet_test_init (const char *enetif); +int enet_test_teardown (void **state); +int enet_test_setup (void **state); +void enet_loop_send_frame(void **state); + +#endif /* CM_MYTEST_UTIL_H */ From b2f7ead2dd0bb37392c2095bcd6cc0dcb04e6922 Mon Sep 17 00:00:00 2001 From: zhangkai25 Date: Sat, 8 Feb 2025 13:44:04 +0800 Subject: [PATCH 050/568] apps/examples/udp: Update CMAKEList.txt for UDP tests under CMAKE add Update CMAKEList.txt for UDP tests under CMAKE Signed-off-by: zhangkai25 --- examples/udp/CMakeLists.txt | 57 ++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/examples/udp/CMakeLists.txt b/examples/udp/CMakeLists.txt index 996b9a9be..b3cbdf166 100644 --- a/examples/udp/CMakeLists.txt +++ b/examples/udp/CMakeLists.txt @@ -21,5 +21,60 @@ # ############################################################################## if(CONFIG_EXAMPLES_UDP) - nuttx_add_application(NAME udp) + + # Basic UDP networking test + + set(CSRCS udp_cmdline.c) + + if(CONFIG_EXAMPLES_UDP_NETINIT) + list(APPEND CSRCS udp_netinit.c) + endif() + + # Target 1 Files + + if(CONFIG_EXAMPLES_UDP_SERVER1) + list(APPEND CSRCS udp_server.c) + else() + list(APPEND CSRCS udp_client.c) + endif() + + nuttx_add_application( + NAME + ${CONFIG_EXAMPLES_UDP_PROGNAME1} + PRIORITY + ${CONFIG_EXAMPLES_UDP_PRIORITY1} + STACKSIZE + ${CONFIG_EXAMPLES_UDP_STACKSIZE1} + MODULE + ${CONFIG_EXAMPLES_UDP} + INCLUDE_DIRECTORIES + ${CMAKE_BINARY_DIR}/include/nuttx + SRCS + udp_target1.c + ${CSRCS}) + + # Target 2 Files + + if(CONFIG_EXAMPLES_UDP_TARGET2) + if(CONFIG_EXAMPLES_UDP_SERVER1) + list(APPEND CSRCS udp_client.c) + else() + list(APPEND CSRCS udp_server.c) + endif() + + nuttx_add_application( + NAME + ${CONFIG_EXAMPLES_UDP_PROGNAME2} + PRIORITY + ${CONFIG_EXAMPLES_UDP_PRIORITY2} + STACKSIZE + ${CONFIG_EXAMPLES_UDP_STACKSIZE2} + MODULE + ${CONFIG_EXAMPLES_UDP} + INCLUDE_DIRECTORIES + ${CMAKE_BINARY_DIR}/include/nuttx + SRCS + udp_target2.c + ${CSRCS}) + endif() endif() From 40c7982816ebc9f2c6a2c18f44e43cc5158b15cc Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Tue, 7 Jan 2025 18:10:13 +0800 Subject: [PATCH 051/568] netlib: Add support for adding/removing VLAN device Add support for adding/removing VLAN device Signed-off-by: gaohedong --- include/netutils/netlib.h | 5 +++ netutils/netlib/CMakeLists.txt | 4 ++ netutils/netlib/Makefile | 4 ++ netutils/netlib/netlib_addvlan.c | 74 ++++++++++++++++++++++++++++++++ netutils/netlib/netlib_delvlan.c | 72 +++++++++++++++++++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 netutils/netlib/netlib_addvlan.c create mode 100644 netutils/netlib/netlib_delvlan.c diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index b5389a55d..5c7b6a74f 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -329,6 +329,11 @@ int netlib_getessid(FAR const char *ifname, FAR char *essid, size_t idlen); int netlib_setessid(FAR const char *ifname, FAR const char *essid); #endif +#ifdef CONFIG_NET_VLAN +int netlib_add_vlan(FAR const char *ifname, int vlanid); +int netlib_del_vlan(FAR const char *vlanif); +#endif + #ifdef CONFIG_NET_ARP /* ARP Table Support */ diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt index 82cc8d610..3f3697e95 100644 --- a/netutils/netlib/CMakeLists.txt +++ b/netutils/netlib/CMakeLists.txt @@ -118,6 +118,10 @@ if(CONFIG_NETUTILS_NETLIB) list(APPEND SRCS netlib_setmacaddr.c netlib_getmacaddr.c) endif() + if(CONFIG_NET_VLAN) + list(APPEND SRCS netlib_addvlan.c netlib_delvlan.c) + endif() + list(APPEND SRCS netlib_setmtu.c) if(CONFIG_WIRELESS_IEEE802154) diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index 3d6066e3f..32eafe2f8 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -123,6 +123,10 @@ ifeq ($(CONFIG_NET_ETHERNET),y) CSRCS += netlib_setmacaddr.c netlib_getmacaddr.c endif +ifeq ($(CONFIG_NET_VLAN),y) +CSRCS += netlib_addvlan.c netlib_delvlan.c +endif + CSRCS += netlib_setmtu.c ifeq ($(CONFIG_WIRELESS_IEEE802154),y) diff --git a/netutils/netlib/netlib_addvlan.c b/netutils/netlib/netlib_addvlan.c new file mode 100644 index 000000000..87cbcf712 --- /dev/null +++ b/netutils/netlib/netlib_addvlan.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * apps/netutils/netlib/netlib_addvlan.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifdef CONFIG_NET_VLAN + +#include + +#include "netutils/netlib.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netlib_add_vlan + * + * Description: + * Add a VLAN interface to an existing network device. + * + * Parameters: + * ifname - The name of the existing network device + * vlanid - The VLAN identifier to be added + * + * Return: + * 0 on success; -1 on failure + * + ****************************************************************************/ + +int netlib_add_vlan(FAR const char *ifname, int vlanid) +{ + int ret = ERROR; + + if (ifname && vlanid > 0) + { + int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL); + if (sockfd >= 0) + { + struct vlan_ioctl_args ifv; + + strlcpy(ifv.device1, ifname, sizeof(ifv.device1)); + ifv.u.VID = vlanid; + ifv.cmd = ADD_VLAN_CMD; + + ret = ioctl(sockfd, SIOCSIFVLAN, &ifv); + close(sockfd); + } + } + + return ret; +} + +#endif /* CONFIG_NET_VLAN */ diff --git a/netutils/netlib/netlib_delvlan.c b/netutils/netlib/netlib_delvlan.c new file mode 100644 index 000000000..1b6a2ceb3 --- /dev/null +++ b/netutils/netlib/netlib_delvlan.c @@ -0,0 +1,72 @@ +/**************************************************************************** + * apps/netutils/netlib/netlib_delvlan.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifdef CONFIG_NET_VLAN + +#include + +#include "netutils/netlib.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netlib_del_vlan + * + * Description: + * Remove a VLAN interface from an existing network device. + * + * Parameters: + * vlanif - The name of the VLAN network device + * + * Return: + * 0 on success; -1 on failure + * + ****************************************************************************/ + +int netlib_del_vlan(FAR const char *vlanif) +{ + int ret = ERROR; + + if (vlanif) + { + int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL); + if (sockfd >= 0) + { + struct vlan_ioctl_args ifv; + + strlcpy(ifv.device1, vlanif, sizeof(ifv.device1)); + ifv.cmd = DEL_VLAN_CMD; + + ret = ioctl(sockfd, SIOCSIFVLAN, &ifv); + close(sockfd); + } + } + + return ret; +} + +#endif /* CONFIG_NET_VLAN */ From 3ddda82313de4cb3f7eae8e4af6d7e9b5e56a350 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Sat, 15 Mar 2025 13:53:43 +0800 Subject: [PATCH 052/568] netutils/ptpd: add CMakelist for ptpd support cmake build Signed-off-by: dongjiuzhu1 --- netutils/ptpd/CMakeLists.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 netutils/ptpd/CMakeLists.txt diff --git a/netutils/ptpd/CMakeLists.txt b/netutils/ptpd/CMakeLists.txt new file mode 100644 index 000000000..35c36b5b1 --- /dev/null +++ b/netutils/ptpd/CMakeLists.txt @@ -0,0 +1,23 @@ +# ############################################################################## +# apps/netutils/ptpd/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_NETUTILS_PTPD) + target_sources(apps PRIVATE ptpd.c) +endif() From e4ddfdeed1ac715d43ffa4c5d129ac4090f47cde Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Sat, 15 Mar 2025 14:01:35 +0800 Subject: [PATCH 053/568] netutils/ptpd: byte align for ptp structure pass structure between remote and local core Signed-off-by: dongjiuzhu1 --- netutils/ptpd/ptpv2.h | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/netutils/ptpd/ptpv2.h b/netutils/ptpd/ptpv2.h index 8b031567b..3f4525428 100644 --- a/netutils/ptpd/ptpv2.h +++ b/netutils/ptpd/ptpv2.h @@ -27,6 +27,8 @@ * Included Files ****************************************************************************/ +#include + #include /**************************************************************************** @@ -67,7 +69,7 @@ /* Common header for all message types */ -struct ptp_header_s +begin_packed_struct struct ptp_header_s { uint8_t messagetype; uint8_t version; @@ -82,11 +84,11 @@ struct ptp_header_s uint8_t sequenceid[2]; uint8_t controlfield; uint8_t logmessageinterval; -}; +} end_packed_struct; /* Announce a master clock */ -struct ptp_announce_s +begin_packed_struct struct ptp_announce_s { struct ptp_header_s header; uint8_t origintimestamp[10]; @@ -98,40 +100,40 @@ struct ptp_announce_s uint8_t gm_identity[8]; uint8_t stepsremoved[2]; uint8_t timesource; -}; +} end_packed_struct; /* Sync: transmit timestamp from master clock */ -struct ptp_sync_s +begin_packed_struct struct ptp_sync_s { struct ptp_header_s header; uint8_t origintimestamp[10]; -}; +} end_packed_struct; /* FollowUp: actual timestamp of when sync message was sent */ -struct ptp_follow_up_s +begin_packed_struct struct ptp_follow_up_s { struct ptp_header_s header; uint8_t origintimestamp[10]; -}; +} end_packed_struct; /* DelayReq: request delay measurement */ -struct ptp_delay_req_s +begin_packed_struct struct ptp_delay_req_s { struct ptp_header_s header; uint8_t origintimestamp[10]; -}; +} end_packed_struct; /* DelayResp: response to DelayReq */ -struct ptp_delay_resp_s +begin_packed_struct struct ptp_delay_resp_s { struct ptp_header_s header; uint8_t receivetimestamp[10]; uint8_t reqidentity[8]; uint8_t reqportindex[2]; -}; +} end_packed_struct; #endif /* __APPS_NETUTILS_PTPD_PTPV2_H */ From d1f59bef8ee8b7ea9b2e82de1ac5c6123baca10e Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Sun, 23 Mar 2025 23:05:52 +0800 Subject: [PATCH 054/568] netutils/ptpd: using DEBUG_PTP_ERR/WARN/INFO to replace NETUTILS_PTPD_DEBUG using new ptp clock device debug function Signed-off-by: dongjiuzhu1 --- netutils/ptpd/Kconfig | 7 ------- netutils/ptpd/ptpd.c | 10 ---------- 2 files changed, 17 deletions(-) diff --git a/netutils/ptpd/Kconfig b/netutils/ptpd/Kconfig index 93cd288ca..110223bd7 100644 --- a/netutils/ptpd/Kconfig +++ b/netutils/ptpd/Kconfig @@ -17,13 +17,6 @@ config NETUTILS_PTPD if NETUTILS_PTPD -config NETUTILS_PTPD_DEBUG - bool "Enable PTP debug messages" - default n - depends on DEBUG_INFO - ---help--- - Enable PTP debug messages even if CONFIG_DEBUG_NET_INFO is not enabled. - config NETUTILS_PTPD_CLIENT bool "Enable client support" default y diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 309f78a07..bdfae08a0 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -172,16 +172,6 @@ struct ptp_state_s * debugging without having excessive amount of logging from net. */ -#ifdef CONFIG_NETUTILS_PTPD_DEBUG -# define ptpinfo _info -# define ptpwarn _warn -# define ptperr _err -#else -# define ptpinfo ninfo -# define ptpwarn nwarn -# define ptperr nerr -#endif - /**************************************************************************** * Private Functions ****************************************************************************/ From 28302ae7d74db81f65995389e7acbac754b2a438 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Mon, 24 Mar 2025 16:10:35 +0800 Subject: [PATCH 055/568] system/ptpd: using main task to replace new task new starting command: ptpd start interface & we should run it in background ways Signed-off-by: dongjiuzhu1 --- netutils/ptpd/ptpd.c | 73 +++++++++++------------------------------ system/ptpd/ptpd_main.c | 17 ++++------ 2 files changed, 26 insertions(+), 64 deletions(-) diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index bdfae08a0..411c9f4eb 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -1376,11 +1376,27 @@ static void ptp_process_statusreq(FAR struct ptp_state_s *state) state->status_req.dest = NULL; } -/* Main PTPD task */ +/**************************************************************************** + * Public Functions + ****************************************************************************/ -static int ptp_daemon(int argc, FAR char** argv) +/**************************************************************************** + * Name: ptpd_start + * + * Description: + * Start the PTP daemon and bind it to specified interface. + * + * Input Parameters: + * interface - Name of the network interface to bind to, e.g. "eth0" + * + * Returned Value: + * On success, the non-negative task ID of the PTP daemon is returned; + * On failure, a negated errno value is returned. + * + ****************************************************************************/ + +int ptpd_start(FAR const char *interface) { - FAR const char *interface = "eth0"; FAR struct ptp_state_s *state; struct pollfd pollfds[2]; struct msghdr rxhdr; @@ -1392,11 +1408,6 @@ static int ptp_daemon(int argc, FAR char** argv) state = calloc(1, sizeof(struct ptp_state_s)); - if (argc > 1) - { - interface = argv[1]; - } - if (ptp_initialize_state(state, interface) != OK) { ptperr("Failed to initialize PTP state, exiting\n"); @@ -1477,52 +1488,6 @@ static int ptp_daemon(int argc, FAR char** argv) return 0; } -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: ptpd_start - * - * Description: - * Start the PTP daemon and bind it to specified interface. - * - * Input Parameters: - * interface - Name of the network interface to bind to, e.g. "eth0" - * - * Returned Value: - * On success, the non-negative task ID of the PTP daemon is returned; - * On failure, a negated errno value is returned. - * - ****************************************************************************/ - -int ptpd_start(FAR const char *interface) -{ - int pid; - FAR char *task_argv[] = - { - (FAR char *)interface, - NULL - }; - - pid = task_create("PTPD", CONFIG_NETUTILS_PTPD_SERVERPRIO, - CONFIG_NETUTILS_PTPD_STACKSIZE, ptp_daemon, task_argv); - - /* Use kill with signal 0 to check if the process is still alive - * after initialization. - */ - - usleep(USEC_PER_TICK); - if (kill(pid, 0) != OK) - { - return ERROR; - } - else - { - return pid; - } -} - /**************************************************************************** * Name: ptpd_status * diff --git a/system/ptpd/ptpd_main.c b/system/ptpd/ptpd_main.c index 503300bce..36b8b67c6 100644 --- a/system/ptpd/ptpd_main.c +++ b/system/ptpd/ptpd_main.c @@ -37,17 +37,14 @@ static int do_ptpd_start(FAR const char *interface) { - int pid; + int ret; - pid = ptpd_start(interface); - if (pid < 0) - { - fprintf(stderr, "ERROR: ptpd_start() failed\n"); - return EXIT_FAILURE; - } + ret = ptpd_start(interface); - printf("Started the PTP daemon as PID=%d\n", pid); - return EXIT_SUCCESS; + /* Should never happen */ + + fprintf(stderr, "ERROR: ptpd_start() failed:%d\n", ret); + return EXIT_FAILURE; } static int do_ptpd_status(int pid) @@ -168,7 +165,7 @@ int main(int argc, FAR char *argv[]) else { fprintf(stderr, "Usage: \n" - "ptpd start \n" + "ptpd start &\n" "ptpd status \n" "ptpd stop \n"); return EXIT_FAILURE; From ac881e510889fddd9a36ba09203f0d460d9f0dee Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Sat, 15 Mar 2025 13:46:07 +0800 Subject: [PATCH 056/568] system/ptpd: provide more parameter by struct ptpd_config_s when starting ptpd origin command change to new command: ptpd start interface & -> ptpd -i eth0 & ptpd stop pid -> ptpd -d pid ptpd status pid -> ptpd -t status Signed-off-by: dongjiuzhu1 --- include/netutils/ptpd.h | 16 +++++-- netutils/ptpd/ptpd.c | 8 +++- system/ptpd/ptpd_main.c | 95 ++++++++++++++++++++++++++++++++--------- 3 files changed, 94 insertions(+), 25 deletions(-) diff --git a/include/netutils/ptpd.h b/include/netutils/ptpd.h index 8e5a3c508..73a615be0 100644 --- a/include/netutils/ptpd.h +++ b/include/netutils/ptpd.h @@ -27,6 +27,8 @@ * Included Files ****************************************************************************/ +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -35,6 +37,14 @@ * Public Types ****************************************************************************/ +struct ptpd_config_s +{ + FAR const char *interface; + FAR const char *clock; + bool hardware_ts; + sa_family_t af; +}; + /* PTPD status information structure */ struct ptpd_status_s @@ -115,10 +125,10 @@ extern "C" * Name: ptpd_start * * Description: - * Start the PTP daemon and bind it to specified interface. + * Start the PTP daemon and bind it to specified config. * * Input Parameters: - * interface - Name of the network interface to bind to, e.g. "eth0" + * config - The configs of PTP daemon, includes interface, af and clock... * * Returned Value: * On success, the non-negative task ID of the PTP daemon is returned; @@ -126,7 +136,7 @@ extern "C" * ****************************************************************************/ -int ptpd_start(FAR const char *interface); +int ptpd_start(FAR const struct ptpd_config_s *config); /**************************************************************************** * Name: ptpd_status diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 411c9f4eb..492f762b3 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -1395,7 +1395,7 @@ static void ptp_process_statusreq(FAR struct ptp_state_s *state) * ****************************************************************************/ -int ptpd_start(FAR const char *interface) +int ptpd_start(FAR const struct ptpd_config_s *config) { FAR struct ptp_state_s *state; struct pollfd pollfds[2]; @@ -1407,8 +1407,12 @@ int ptpd_start(FAR const char *interface) memset(&rxiov, 0, sizeof(rxiov)); state = calloc(1, sizeof(struct ptp_state_s)); + if (state == NULL) + { + return -ENOMEM; + } - if (ptp_initialize_state(state, interface) != OK) + if (ptp_initialize_state(state, config->interface) != OK) { ptperr("Failed to initialize PTP state, exiting\n"); diff --git a/system/ptpd/ptpd_main.c b/system/ptpd/ptpd_main.c index 36b8b67c6..75cca2900 100644 --- a/system/ptpd/ptpd_main.c +++ b/system/ptpd/ptpd_main.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "netutils/ptpd.h" @@ -35,11 +37,11 @@ * Private Functions ****************************************************************************/ -static int do_ptpd_start(FAR const char *interface) +static int do_ptpd_start(FAR const struct ptpd_config_s *config) { int ret; - ret = ptpd_start(interface); + ret = ptpd_start(config); /* Should never happen */ @@ -140,6 +142,24 @@ int do_ptpd_stop(int pid) } } +static void usage(FAR const char *progname) +{ + fprintf(stderr, "Usage: %s [options]: run this daemon in background.\n" + " Network Transport:\n" + " -2 IEEE 802.3\n" + " -4 UDP IPV4 (default)\n" + " -6 UDP IPV6\n" + " Time Stamping:\n" + " -H HARDWARE (default) depends on NET_TIMESTAMP\n" + " -S SOFTWARE\n" + " -r synchronize system (realtime) clock\n" + " -i [dev] interface device to use, for example 'eth0'\n" + " -p [dev] clock device to use\n" + " -t [pid] look the status of ptp daemon\n" + " -s [pid] stop ptp daemon\n", + progname); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -150,24 +170,59 @@ int do_ptpd_stop(int pid) int main(int argc, FAR char *argv[]) { - if (argc == 3 && strcmp(argv[1], "start") == 0) + struct ptpd_config_s config; + int option; + + /* Default config for ptp daemon */ + + config.interface = "eth0"; + config.clock = "realtime"; +#ifdef CONFIG_NET_TIMESTAMP + config.hardware_ts = true; +#else + config.hardware_ts = false; +#endif + config.af = AF_INET; + + while ((option = getopt(argc, argv, "p:i:t:s:r246HS")) != ERROR) { - return do_ptpd_start(argv[2]); - } - else if (argc == 3 && strcmp(argv[1], "status") == 0) - { - return do_ptpd_status(atoi(argv[2])); - } - else if (argc == 3 && strcmp(argv[1], "stop") == 0) - { - return do_ptpd_stop(atoi(argv[2])); - } - else - { - fprintf(stderr, "Usage: \n" - "ptpd start &\n" - "ptpd status \n" - "ptpd stop \n"); - return EXIT_FAILURE; + switch (option) + { + case 't': + return do_ptpd_status(atoi(optarg)); + case 's': + return do_ptpd_stop(atoi(optarg)); + case '2': + config.af = AF_PACKET; + break; + case '4': + config.af = AF_INET; + break; + case '6': + config.af = AF_INET6; + break; +#ifdef CONFIG_NET_TIMESTAMP + case 'H': + config.hardware_ts = true; + break; +#endif + case 'S': + config.hardware_ts = false; + break; + case 'i': + config.interface = optarg; + break; + case 'p': + config.clock = optarg; + break; + case 'r': + config.clock = "realtime"; + break; + default: + usage(argv[0]); + return 0; + } } + + return do_ptpd_start(&config); } From 4411a41bc2498ad65eb665937b446d4df9456228 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Mon, 17 Mar 2025 16:45:32 +0800 Subject: [PATCH 057/568] netutils/ptpd: using hardware_ts to replace CONFIG_NET_TIMESTAMP runtime to config the ways of timestamp Signed-off-by: dongjiuzhu1 --- netutils/ptpd/ptpd.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 492f762b3..b04d7be72 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -159,6 +159,7 @@ struct ptp_state_s struct ptp_sync_s twostep_packet; struct timespec twostep_rxtime; + FAR const struct ptpd_config_s *config; }; #ifdef CONFIG_NETUTILS_PTPD_SERVER @@ -362,10 +363,14 @@ static int ptp_getrxtime(FAR struct ptp_state_s *state, FAR struct msghdr *rxhdr, FAR struct timespec *ts) { + FAR struct cmsghdr *cmsg; + /* Get hardware or kernel timestamp if available */ -#ifdef CONFIG_NET_TIMESTAMP - struct cmsghdr *cmsg; + if (!state->config->hardware_ts) + { + return ptp_gettime(state, ts); + } for_each_cmsghdr(cmsg, rxhdr) { @@ -385,11 +390,7 @@ static int ptp_getrxtime(FAR struct ptp_state_s *state, } ptpwarn("CONFIG_NET_TIMESTAMP enabled but did not get packet timestamp\n"); -#endif - - /* Fall back to current timestamp */ - - return ptp_gettime(state, ts); + return ERROR; } /* Initialize PTP client/server state and create sockets */ @@ -398,13 +399,10 @@ static int ptp_initialize_state(FAR struct ptp_state_s *state, FAR const char *interface) { int ret; + int arg = 1; struct ifreq req; struct sockaddr_in bind_addr; -#ifdef CONFIG_NET_TIMESTAMP - int arg; -#endif - /* Create sockets */ state->tx_socket = socket(AF_INET, SOCK_DGRAM, 0); @@ -504,18 +502,17 @@ static int ptp_initialize_state(FAR struct ptp_state_s *state, return ERROR; } -#ifdef CONFIG_NET_TIMESTAMP - arg = 1; - ret = setsockopt(state->event_socket, SOL_SOCKET, SO_TIMESTAMP, - &arg, sizeof(arg)); - - if (ret < 0) + if (state->config->hardware_ts) { - ptperr("Failed to enable SO_TIMESTAMP: %s\n", strerror(errno)); + ret = setsockopt(state->event_socket, SOL_SOCKET, SO_TIMESTAMP, + &arg, sizeof(arg)); - /* PTPD can operate without, but with worse accuracy */ + if (ret < 0) + { + ptperr("Failed to enable SO_TIMESTAMP: %s\n", strerror(errno)); + return ERROR; + } } -#endif /* Bind socket for announcements */ @@ -1412,6 +1409,7 @@ int ptpd_start(FAR const struct ptpd_config_s *config) return -ENOMEM; } + state->config = config; if (ptp_initialize_state(state, config->interface) != OK) { ptperr("Failed to initialize PTP state, exiting\n"); From e718fdd2c696e95e7dad2a01bc73b6fff0800b82 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Sun, 23 Mar 2025 22:30:24 +0800 Subject: [PATCH 058/568] netutils/ptpd: get nanoseconds by SO_TIMESTAMPNS to satisfy higher precision using nanoseconds as timestamp Signed-off-by: dongjiuzhu1 --- netutils/ptpd/ptpd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index b04d7be72..4ba8d2c86 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -375,7 +375,7 @@ static int ptp_getrxtime(FAR struct ptp_state_s *state, for_each_cmsghdr(cmsg, rxhdr) { if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SO_TIMESTAMP && + cmsg->cmsg_type == SO_TIMESTAMPNS && cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) { TIMEVAL_TO_TIMESPEC((FAR struct timeval *)CMSG_DATA(cmsg), ts); @@ -504,12 +504,12 @@ static int ptp_initialize_state(FAR struct ptp_state_s *state, if (state->config->hardware_ts) { - ret = setsockopt(state->event_socket, SOL_SOCKET, SO_TIMESTAMP, + ret = setsockopt(state->event_socket, SOL_SOCKET, SO_TIMESTAMPNS, &arg, sizeof(arg)); if (ret < 0) { - ptperr("Failed to enable SO_TIMESTAMP: %s\n", strerror(errno)); + ptperr("Failed to enable SO_TIMESTAMPNS: %s\n", strerror(errno)); return ERROR; } } From 832e61c1c4eb5a4b8ee3394fb5cfcd7945ef8e25 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Mon, 24 Feb 2025 21:57:52 +0800 Subject: [PATCH 059/568] netutils/ptpd: Add the missing comparison in is_better_clock The original implementation only checked if each field was less than, but didn't check for greater than before proceeding to the next field. This caused incorrect clock selection behavior in the PTP Best Master Clock Algorithm (BMCA). The fix expands each comparison to explicitly check both < and > conditions, returning the appropriate result immediately. This ensures proper precedence evaluation according to IEEE 1588 specification: - gm_priority1 - gm_quality (class, accuracy, variance) - gm_priority2 - gm_identity Signed-off-by: Xiang Xiao Signed-off-by: dongjiuzhu1 --- netutils/ptpd/ptpd.c | 75 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 4ba8d2c86..2003e5a08 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -231,20 +231,79 @@ static void ptp_format_to_timespec(FAR const uint8_t *timestamp, static bool is_better_clock(FAR const struct ptp_announce_s *a, FAR const struct ptp_announce_s *b) { - if (a->gm_priority1 < b->gm_priority1 /* Main priority field */ - || a->gm_quality[0] < b->gm_quality[0] /* Clock class */ - || a->gm_quality[1] < b->gm_quality[1] /* Clock accuracy */ - || a->gm_quality[2] < b->gm_quality[2] /* Clock variance high byte */ - || a->gm_quality[3] < b->gm_quality[3] /* Clock variance low byte */ - || a->gm_priority2 < b->gm_priority2 /* Sub priority field */ - || memcmp(a->gm_identity, b->gm_identity, sizeof(a->gm_identity)) < 0) + /* Main priority field */ + + if (a->gm_priority1 < b->gm_priority1) { return true; } - else + + if (a->gm_priority1 > b->gm_priority1) { return false; } + + /* Clock class */ + + if (a->gm_quality[0] < b->gm_quality[0]) + { + return true; + } + + if (a->gm_quality[0] > b->gm_quality[0]) + { + return false; + } + + /* Clock accuracy */ + + if (a->gm_quality[1] < b->gm_quality[1]) + { + return true; + } + + if (a->gm_quality[1] > b->gm_quality[1]) + { + return false; + } + + /* Clock variance high byte */ + + if (a->gm_quality[2] < b->gm_quality[2]) + { + return true; + } + + if (a->gm_quality[2] > b->gm_quality[2]) + { + return false; + } + + /* Clock variance low byte */ + + if (a->gm_quality[3] < b->gm_quality[3]) + { + return true; + } + + if (a->gm_quality[3] > b->gm_quality[3]) + { + return false; + } + + /* Sub priority field */ + + if (a->gm_priority2 < b->gm_priority2) + { + return true; + } + + if (a->gm_priority2 > b->gm_priority2) + { + return false; + } + + return memcmp(a->gm_identity, b->gm_identity, sizeof(a->gm_identity)) < 0; } static int64_t timespec_to_ms(FAR const struct timespec *ts) From 5d34a0906a18ec1772d647030ec7208a6428d941 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Mon, 24 Feb 2025 21:57:13 +0800 Subject: [PATCH 060/568] netutils/ptp: destroy donesem at the end of ptpd_status fix minor issue Signed-off-by: Xiang Xiao Signed-off-by: dongjiuzhu1 --- netutils/ptpd/ptpd.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 2003e5a08..17f232406 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -56,7 +56,7 @@ #include "ptpv2.h" /**************************************************************************** - * Private Data + * Private Types ****************************************************************************/ /* Carrier structure for querying PTPD status */ @@ -179,7 +179,7 @@ struct ptp_state_s /* Convert from timespec to PTP format */ -static void timespec_to_ptp_format(FAR struct timespec *ts, +static void timespec_to_ptp_format(FAR const struct timespec *ts, FAR uint8_t *timestamp) { /* IEEE 1588 uses 48 bits for seconds and 32 bits for nanoseconds, @@ -490,7 +490,7 @@ static int ptp_initialize_state(FAR struct ptp_state_s *state, */ memset(&req, 0, sizeof(req)); - strncpy(req.ifr_name, interface, sizeof(req.ifr_name)); + strlcpy(req.ifr_name, interface, sizeof(req.ifr_name)); if (ioctl(state->event_socket, SIOCGIFADDR, (unsigned long)&req) < 0) { @@ -1293,7 +1293,7 @@ static int ptp_process_rx_packet(FAR struct ptp_state_s *state, clock_gettime(CLOCK_MONOTONIC, &state->last_received_multicast); switch (state->rxbuf.header.messagetype & PTP_MSGTYPE_MASK) - { + { #ifdef CONFIG_NETUTILS_PTPD_CLIENT case PTP_MSGTYPE_ANNOUNCE: ptpinfo("Got announce packet, seq %ld\n", @@ -1327,7 +1327,7 @@ static int ptp_process_rx_packet(FAR struct ptp_state_s *state, ptpinfo("Ignoring unknown PTP packet type: 0x%02x\n", state->rxbuf.header.messagetype); return OK; - } + } } /* Signal handler for status / stop requests */ @@ -1610,6 +1610,7 @@ int ptpd_status(int pid, FAR struct ptpd_status_s *status) ret = -errno; } + sem_destroy(&donesem); return ret; #endif /* CONFIG_BUILD_FLAT */ From 4426ce733a541d97d4f35d679066dce845bdf719 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Thu, 27 Mar 2025 21:57:06 +0800 Subject: [PATCH 061/568] netutils/ptpd: using dynamic config to config clien-only mode and delaye2e fix compile warning when only enable PTPD_CLIENT or PTPD_SERVER ptpd.c:493:38: error: 'CONFIG_NETUTILS_PTPD_PRIORITY1' undeclared (first use in this function); did you mean 'CONFIG_NETUTILS_PTPD_CLIENT'? ptpd.c:494:39: error: 'CONFIG_NETUTILS_PTPD_CLASS' undeclared (first use in this function); did you mean 'CONFIG_NETUTILS_PTPD_CLIENT'? ptpd.c:495:39: error: 'CONFIG_NETUTILS_PTPD_ACCURACY' undeclared (first use in this function); did you mean 'CONFIG_NETUTILS_PTPD_DEBUG'? ptpd.c:498:38: error: 'CONFIG_NETUTILS_PTPD_PRIORITY2' undeclared (first use in this function); did you mean 'CONFIG_NETUTILS_PTPD_CLIENT'? ptpd.c:502:36: error: 'CONFIG_NETUTILS_PTPD_CLOCKSOURCE' undeclared (first use in this function); did you mean 'CONFIG_NETUTILS_PTPD_STACKSIZE'? Signed-off-by: dongjiuzhu1 --- include/netutils/ptpd.h | 2 ++ netutils/ptpd/Kconfig | 37 ------------------------------------- netutils/ptpd/ptpd.c | 36 ++++++++++++++---------------------- system/ptpd/ptpd_main.c | 16 +++++++++++++--- 4 files changed, 29 insertions(+), 62 deletions(-) diff --git a/include/netutils/ptpd.h b/include/netutils/ptpd.h index 73a615be0..ea4b9fb7b 100644 --- a/include/netutils/ptpd.h +++ b/include/netutils/ptpd.h @@ -41,7 +41,9 @@ struct ptpd_config_s { FAR const char *interface; FAR const char *clock; + bool client_only; bool hardware_ts; + bool delay_e2e; sa_family_t af; }; diff --git a/netutils/ptpd/Kconfig b/netutils/ptpd/Kconfig index 110223bd7..6c2b17bd8 100644 --- a/netutils/ptpd/Kconfig +++ b/netutils/ptpd/Kconfig @@ -17,24 +17,6 @@ config NETUTILS_PTPD if NETUTILS_PTPD -config NETUTILS_PTPD_CLIENT - bool "Enable client support" - default y - ---help--- - Act as a PTP client, synchronizing the NuttX clock to a remote master - clock. - -config NETUTILS_PTPD_SERVER - bool "Enable server support" - default n - ---help--- - Act as a PTP server, providing NuttX clock time to other systems. - - Both server and client can be simultaneously enabled. NuttX will then - synchronize to a higher priority master clock, or act as a master - clock itself if it has the highest priority. - Refer to Best Master Clock algorithm in IEEE-1588 for details. - config NETUTILS_PTPD_STACKSIZE int "PTP daemon stack stack size" default DEFAULT_TASK_STACKSIZE @@ -51,8 +33,6 @@ config NETUTILS_PTPD_DOMAIN Set PTP domain to participate in. Default domain is 0, other domains can be used to isolate reference clocks from each other. -if NETUTILS_PTPD_SERVER - config NETUTILS_PTPD_PRIORITY1 int "PTP server priority1" default 128 @@ -154,10 +134,6 @@ config NETUTILS_PTPD_DELAYRESP_INTERVAL Default value 4 results in 16 second interval. -endif # NETUTILS_PTPD_SERVER - -if NETUTILS_PTPD_CLIENT - config NETUTILS_PTPD_TIMEOUT_MS int "PTP client timeout for changing clock source (ms)" default 60000 @@ -191,15 +167,6 @@ config NETUTILS_PTPD_DRIFT_AVERAGE_S gives more stable estimate but reacts slower to crystal oscillator speed changes (such as caused by temperature changes). -config NETUTILS_PTPD_SEND_DELAYREQ - bool "PTP client enable delay requests" - default n - ---help--- - If enabled, sends delay request messages to measure the network delay - to server. If disabled, assumes zero delay. - -if NETUTILS_PTPD_SEND_DELAYREQ - config NETUTILS_PTPD_MAX_PATH_DELAY_NS int "PTP client maximum path delay (ns)" default 100000 @@ -214,8 +181,4 @@ config NETUTILS_PTPD_DELAYREQ_AVGCOUNT ---help--- Measured path delay is averaged over this many samples. -endif # NETUTILS_PTPD_SEND_DELAYREQ - -endif # NETUTILS_PTPD_CLIENT - endif # NETUTILS_PTPD diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 17f232406..9c251c334 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -162,17 +162,6 @@ struct ptp_state_s FAR const struct ptpd_config_s *config; }; -#ifdef CONFIG_NETUTILS_PTPD_SERVER -# define PTPD_POLL_INTERVAL CONFIG_NETUTILS_PTPD_SYNC_INTERVAL_MSEC -#else -# define PTPD_POLL_INTERVAL CONFIG_NETUTILS_PTPD_TIMEOUT_MS -#endif - -/* PTP debug messages are enabled by either CONFIG_DEBUG_NET_INFO - * or separately by CONFIG_NETUTILS_PTPD_DEBUG. This simplifies - * debugging without having excessive amount of logging from net. - */ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -834,12 +823,11 @@ static int ptp_send_delay_req(FAR struct ptp_state_s *state) static int ptp_periodic_send(FAR struct ptp_state_s *state) { -#ifdef CONFIG_NETUTILS_PTPD_SERVER /* If there is no better master clock on the network, * act as the reference source and send server packets. */ - if (!state->selected_source_valid) + if (!state->config->client_only && !state->selected_source_valid) { struct timespec time_now; struct timespec delta; @@ -862,10 +850,9 @@ static int ptp_periodic_send(FAR struct ptp_state_s *state) ptp_send_sync(state); } } -#endif /* CONFIG_NETUTILS_PTPD_SERVER */ -#ifdef CONFIG_NETUTILS_PTPD_SEND_DELAYREQ - if (state->selected_source_valid && state->can_send_delayreq) + if (state->config->delay_e2e && state->selected_source_valid && + state->can_send_delayreq) { struct timespec time_now; struct timespec delta; @@ -879,7 +866,6 @@ static int ptp_periodic_send(FAR struct ptp_state_s *state) ptp_send_delay_req(state); } } -#endif return OK; } @@ -1294,7 +1280,6 @@ static int ptp_process_rx_packet(FAR struct ptp_state_s *state, switch (state->rxbuf.header.messagetype & PTP_MSGTYPE_MASK) { -#ifdef CONFIG_NETUTILS_PTPD_CLIENT case PTP_MSGTYPE_ANNOUNCE: ptpinfo("Got announce packet, seq %ld\n", (long)ptp_get_sequence(&state->rxbuf.header)); @@ -1314,14 +1299,11 @@ static int ptp_process_rx_packet(FAR struct ptp_state_s *state, ptpinfo("Got delay-resp, seq %ld\n", (long)ptp_get_sequence(&state->rxbuf.header)); return ptp_process_delay_resp(state, &state->rxbuf.delay_resp); -#endif -#ifdef CONFIG_NETUTILS_PTPD_SERVER case PTP_MSGTYPE_DELAY_REQ: ptpinfo("Got delay req, seq %ld\n", (long)ptp_get_sequence(&state->rxbuf.header)); return ptp_process_delay_req(state, &state->rxbuf.delay_req); -#endif default: ptpinfo("Ignoring unknown PTP packet type: 0x%02x\n", @@ -1457,6 +1439,7 @@ int ptpd_start(FAR const struct ptpd_config_s *config) struct pollfd pollfds[2]; struct msghdr rxhdr; struct iovec rxiov; + int timeout; int ret; memset(&rxhdr, 0, sizeof(rxhdr)); @@ -1479,6 +1462,15 @@ int ptpd_start(FAR const struct ptpd_config_s *config) return ERROR; } + if (config->client_only) + { + timeout = CONFIG_NETUTILS_PTPD_TIMEOUT_MS; + } + else + { + timeout = CONFIG_NETUTILS_PTPD_SYNC_INTERVAL_MSEC; + } + ptp_setup_sighandlers(state); pollfds[0].events = POLLIN; @@ -1502,7 +1494,7 @@ int ptpd_start(FAR const struct ptpd_config_s *config) pollfds[0].revents = 0; pollfds[1].revents = 0; - ret = poll(pollfds, 2, PTPD_POLL_INTERVAL); + ret = poll(pollfds, 2, timeout); if (pollfds[0].revents) { diff --git a/system/ptpd/ptpd_main.c b/system/ptpd/ptpd_main.c index 75cca2900..e65905987 100644 --- a/system/ptpd/ptpd_main.c +++ b/system/ptpd/ptpd_main.c @@ -145,6 +145,7 @@ int do_ptpd_stop(int pid) static void usage(FAR const char *progname) { fprintf(stderr, "Usage: %s [options]: run this daemon in background.\n" + " -s client only synchronization mode\n" " Network Transport:\n" " -2 IEEE 802.3\n" " -4 UDP IPV4 (default)\n" @@ -153,10 +154,11 @@ static void usage(FAR const char *progname) " -H HARDWARE (default) depends on NET_TIMESTAMP\n" " -S SOFTWARE\n" " -r synchronize system (realtime) clock\n" + " -E E2E, support client delay request-response\n" " -i [dev] interface device to use, for example 'eth0'\n" " -p [dev] clock device to use\n" " -t [pid] look the status of ptp daemon\n" - " -s [pid] stop ptp daemon\n", + " -d [pid] stop ptp daemon\n", progname); } @@ -177,6 +179,8 @@ int main(int argc, FAR char *argv[]) config.interface = "eth0"; config.clock = "realtime"; + config.client_only = false; + config.delay_e2e = false; #ifdef CONFIG_NET_TIMESTAMP config.hardware_ts = true; #else @@ -184,13 +188,16 @@ int main(int argc, FAR char *argv[]) #endif config.af = AF_INET; - while ((option = getopt(argc, argv, "p:i:t:s:r246HS")) != ERROR) + while ((option = getopt(argc, argv, "p:i:t:d:rs246EHS")) != ERROR) { switch (option) { + case 's': + config.client_only = true; + break; case 't': return do_ptpd_status(atoi(optarg)); - case 's': + case 'd': return do_ptpd_stop(atoi(optarg)); case '2': config.af = AF_PACKET; @@ -201,6 +208,9 @@ int main(int argc, FAR char *argv[]) case '6': config.af = AF_INET6; break; + case 'E': + config.delay_e2e = true; + break; #ifdef CONFIG_NET_TIMESTAMP case 'H': config.hardware_ts = true; From d3504bf9b38c9dd35aab4b0fc4435f3fade58a42 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Mon, 17 Mar 2025 09:53:02 +0800 Subject: [PATCH 062/568] netutils/ptpd: support adjtime for ptp device support ptp clock deivce to adjust time Signed-off-by: dongjiuzhu1 --- netutils/ptpd/ptpd.c | 81 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 9c251c334..a1b0d92d1 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -50,6 +51,7 @@ #include #include #include +#include #include #include @@ -89,6 +91,10 @@ struct ptp_state_s int event_socket; int info_socket; + /* The ptp device file descriptor */ + + clockid_t clockid; + /* Our own identity as a clock source */ struct ptp_announce_s own_identity; @@ -372,16 +378,37 @@ static uint16_t ptp_get_sequence(FAR const struct ptp_header_s *hdr) return ((uint16_t)hdr->sequenceid[0] << 8) | hdr->sequenceid[1]; } -/* Get current system timestamp as a timespec - * TODO: Possibly add support for selecting different clock or using - * architecture-specific interface for clock access. - */ +static clockid_t ptp_open(FAR const char *clock) +{ + int fd; + + if (!strcmp(clock, "realtime")) + { + return CLOCK_REALTIME; + } + + fd = open(clock, O_RDWR | O_CLOEXEC); + if (fd < 0) + { + ptperr("Failed to open PTP clock device:%s, %d\n", clock, errno); + return fd; + } + + return (fd << CLOCK_SHIFT) | CLOCK_FD; +} + +static void ptp_close(clockid_t clockid) +{ + if (clockid > 0 && clockid != CLOCK_REALTIME) + { + close(clockid >> CLOCK_SHIFT); + } +} static int ptp_gettime(FAR struct ptp_state_s *state, FAR struct timespec *ts) { - UNUSED(state); - return clock_gettime(CLOCK_REALTIME, ts); + return clock_gettime(state->clockid, ts); } /* Change current system timestamp by jumping */ @@ -389,20 +416,32 @@ static int ptp_gettime(FAR struct ptp_state_s *state, static int ptp_settime(FAR struct ptp_state_s *state, FAR struct timespec *ts) { - UNUSED(state); - return clock_settime(CLOCK_REALTIME, ts); + return clock_settime(state->clockid, ts); } /* Smoothly adjust timestamp. */ static int ptp_adjtime(FAR struct ptp_state_s *state, int64_t delta_ns) { - struct timeval delta; + if (state->clockid == CLOCK_REALTIME) + { + struct timeval delta; - delta.tv_sec = delta_ns / NSEC_PER_SEC; - delta_ns -= (int64_t)delta.tv_sec * NSEC_PER_SEC; - delta.tv_usec = delta_ns / NSEC_PER_USEC; - return adjtime(&delta, NULL); + delta.tv_sec = delta_ns / NSEC_PER_SEC; + delta_ns -= (int64_t)delta.tv_sec * NSEC_PER_SEC; + delta.tv_usec = delta_ns / NSEC_PER_USEC; + return adjtime(&delta, NULL); + } + else + { + struct timex buf; + + memset(&buf, 0, sizeof(buf)); + buf.freq = (long)(-state->drift_ppb * 65536 / 1000); + buf.modes = ADJ_FREQUENCY; + + return clock_adjtime(state->clockid, &buf); + } } /* Get timestamp of latest received packet */ @@ -451,6 +490,13 @@ static int ptp_initialize_state(FAR struct ptp_state_s *state, struct ifreq req; struct sockaddr_in bind_addr; + state->clockid = ptp_open(state->config->clock); + if (state->clockid < 0) + { + ptperr("Invalid clockid %d for ptp daemon\n", state->clockid); + return ERROR; + } + /* Create sockets */ state->tx_socket = socket(AF_INET, SOCK_DGRAM, 0); @@ -593,6 +639,8 @@ static int ptp_destroy_state(FAR struct ptp_state_s *state) { struct in_addr mcast_addr; + ptp_close(state->clockid); + mcast_addr.s_addr = HTONL(PTP_MULTICAST_ADDR); ipmsfilter(&state->interface_addr.sin_addr, &mcast_addr, MCAST_EXCLUDE); @@ -1455,11 +1503,7 @@ int ptpd_start(FAR const struct ptpd_config_s *config) if (ptp_initialize_state(state, config->interface) != OK) { ptperr("Failed to initialize PTP state, exiting\n"); - - ptp_destroy_state(state); - free(state); - - return ERROR; + goto errout; } if (config->client_only) @@ -1535,6 +1579,7 @@ int ptpd_start(FAR const struct ptpd_config_s *config) ptp_process_statusreq(state); } +errout: ptp_destroy_state(state); free(state); From 54d55fe5f44941142c1cbad8d9424aa4d43b740b Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Wed, 2 Apr 2025 22:58:55 +0800 Subject: [PATCH 063/568] netutils/ptpd: add NETUTILS_PTPD_ADJTIME_THRESHOLD_NS to accelerate adjustment optimize the speed of adjustment Signed-off-by: dongjiuzhu1 --- netutils/ptpd/Kconfig | 8 ++++++++ netutils/ptpd/ptpd.c | 14 +++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/netutils/ptpd/Kconfig b/netutils/ptpd/Kconfig index 6c2b17bd8..f29065f80 100644 --- a/netutils/ptpd/Kconfig +++ b/netutils/ptpd/Kconfig @@ -149,6 +149,14 @@ config NETUTILS_PTPD_SETTIME_THRESHOLD_MS time is reset with settimeofday() instead of changing the rate with adjtime(). +config NETUTILS_PTPD_ADJTIME_THRESHOLD_NS + int "PTP client threshold for using accumulated ppb to adjust system time (ns)" + default 500 + ---help--- + If difference between local and remote clock exceeds this threshold, + the PTP client can utilize current ppb instead of accumulated ppb to + accelerate system time adjustment. + config NETUTILS_PTPD_MULTICAST_TIMEOUT_MS int "PTP client timeout to rejoin multicast group (ms)" default 30000 diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index a1b0d92d1..c581e624e 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -421,7 +421,8 @@ static int ptp_settime(FAR struct ptp_state_s *state, /* Smoothly adjust timestamp. */ -static int ptp_adjtime(FAR struct ptp_state_s *state, int64_t delta_ns) +static int ptp_adjtime(FAR struct ptp_state_s *state, int64_t delta_ns, + int64_t ppb) { if (state->clockid == CLOCK_REALTIME) { @@ -437,7 +438,7 @@ static int ptp_adjtime(FAR struct ptp_state_s *state, int64_t delta_ns) struct timex buf; memset(&buf, 0, sizeof(buf)); - buf.freq = (long)(-state->drift_ppb * 65536 / 1000); + buf.freq = (long)(-ppb * 65536 / 1000); buf.modes = ADJ_FREQUENCY; return clock_adjtime(state->clockid, &buf); @@ -1096,7 +1097,14 @@ static int ptp_update_local_clock(FAR struct ptp_state_s *state, (long long)state->last_adjtime_ns, (long long)state->drift_ppb); - ret = ptp_adjtime(state, adjustment_ns); + if (absdelta_ns > CONFIG_NETUTILS_PTPD_ADJTIME_THRESHOLD_NS) + { + ret = ptp_adjtime(state, delta_ns, drift_ppb); + } + else + { + ret = ptp_adjtime(state, adjustment_ns, state->drift_ppb); + } if (ret != OK) { From 65d29de0f76312914af7e2933ed2a3616c5aea51 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Thu, 21 Aug 2025 23:37:42 +0800 Subject: [PATCH 064/568] netutils/ptpd: add NET_PKT to enable PTP support ptp clock device Signed-off-by: dongjiuzhu1 --- netutils/ptpd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netutils/ptpd/Kconfig b/netutils/ptpd/Kconfig index f29065f80..63d756ad9 100644 --- a/netutils/ptpd/Kconfig +++ b/netutils/ptpd/Kconfig @@ -8,7 +8,7 @@ config NETUTILS_PTPD default n depends on NET_IPv4 depends on NET_IGMP - depends on NET_UDP + depends on NET_UDP || NET_PKT ---help--- Build a minimal implementation of IEEE-1588 precision time protocol. Uses system gettimeofday() and adjtime() calls to synchronize clock From 54cbc2ee0df4a0aa27a5c45a7211172cc51a48b1 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Tue, 18 Mar 2025 09:58:07 +0800 Subject: [PATCH 065/568] netutils/ptpd: support PTP ethernet transport support ptp by rawsocket Signed-off-by: dongjiuzhu1 --- netutils/ptpd/ptpd.c | 499 +++++++++++++++++++++++++------------------ 1 file changed, 297 insertions(+), 202 deletions(-) diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index c581e624e..e08b7fab2 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -45,6 +45,8 @@ #include #include +#include +#include #include #include @@ -55,6 +57,7 @@ #include #include +#include "netutils/netlib.h" #include "ptpv2.h" /**************************************************************************** @@ -157,7 +160,7 @@ struct ptp_state_s uint8_t raw[128]; } rxbuf; - uint8_t rxcmsg[CMSG_LEN(sizeof(struct timeval))]; + uint8_t rxcmsg[CMSG_LEN(sizeof(struct timespec))]; /* Buffered sync packet for two-step clock setting where server sends * the accurate timestamp in a separate follow-up message. @@ -464,9 +467,9 @@ static int ptp_getrxtime(FAR struct ptp_state_s *state, { if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPNS && - cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) + cmsg->cmsg_len == CMSG_LEN(sizeof(struct timespec))) { - TIMEVAL_TO_TIMESPEC((FAR struct timeval *)CMSG_DATA(cmsg), ts); + memcpy(ts, CMSG_DATA(cmsg), sizeof(*ts)); /* Sanity-check the value */ @@ -481,159 +484,6 @@ static int ptp_getrxtime(FAR struct ptp_state_s *state, return ERROR; } -/* Initialize PTP client/server state and create sockets */ - -static int ptp_initialize_state(FAR struct ptp_state_s *state, - FAR const char *interface) -{ - int ret; - int arg = 1; - struct ifreq req; - struct sockaddr_in bind_addr; - - state->clockid = ptp_open(state->config->clock); - if (state->clockid < 0) - { - ptperr("Invalid clockid %d for ptp daemon\n", state->clockid); - return ERROR; - } - - /* Create sockets */ - - state->tx_socket = socket(AF_INET, SOCK_DGRAM, 0); - if (state->tx_socket < 0) - { - ptperr("Failed to create tx socket: %d\n", errno); - return ERROR; - } - - state->event_socket = socket(AF_INET, SOCK_DGRAM, 0); - if (state->event_socket < 0) - { - ptperr("Failed to create event socket: %d\n", errno); - return ERROR; - } - - state->info_socket = socket(AF_INET, SOCK_DGRAM, 0); - if (state->info_socket < 0) - { - ptperr("Failed to create info socket: %d\n", errno); - return ERROR; - } - - /* Get address information of the specified interface for binding socket - * Only supports IPv4 currently. - */ - - memset(&req, 0, sizeof(req)); - strlcpy(req.ifr_name, interface, sizeof(req.ifr_name)); - - if (ioctl(state->event_socket, SIOCGIFADDR, (unsigned long)&req) < 0) - { - ptperr("Failed to get IP address information for interface %s\n", - interface); - return ERROR; - } - - state->interface_addr = *(FAR struct sockaddr_in *)&req.ifr_ifru.ifru_addr; - - /* Get hardware address to initialize the identity field in header. - * Clock identity is EUI-64, which we make from EUI-48. - */ - - if (ioctl(state->event_socket, SIOCGIFHWADDR, (unsigned long)&req) < 0) - { - ptperr("Failed to get HW address information for interface %s\n", - interface); - return ERROR; - } - - state->own_identity.header.version = 2; - state->own_identity.header.domain = CONFIG_NETUTILS_PTPD_DOMAIN; - state->own_identity.header.sourceidentity[0] = req.ifr_hwaddr.sa_data[0]; - state->own_identity.header.sourceidentity[1] = req.ifr_hwaddr.sa_data[1]; - state->own_identity.header.sourceidentity[2] = req.ifr_hwaddr.sa_data[2]; - state->own_identity.header.sourceidentity[3] = 0xff; - state->own_identity.header.sourceidentity[4] = 0xfe; - state->own_identity.header.sourceidentity[5] = req.ifr_hwaddr.sa_data[3]; - state->own_identity.header.sourceidentity[6] = req.ifr_hwaddr.sa_data[4]; - state->own_identity.header.sourceidentity[7] = req.ifr_hwaddr.sa_data[5]; - state->own_identity.header.sourceportindex[0] = 0; - state->own_identity.header.sourceportindex[1] = 1; - state->own_identity.gm_priority1 = CONFIG_NETUTILS_PTPD_PRIORITY1; - state->own_identity.gm_quality[0] = CONFIG_NETUTILS_PTPD_CLASS; - state->own_identity.gm_quality[1] = CONFIG_NETUTILS_PTPD_ACCURACY; - state->own_identity.gm_quality[2] = 0xff; /* No variance estimate */ - state->own_identity.gm_quality[3] = 0xff; - state->own_identity.gm_priority2 = CONFIG_NETUTILS_PTPD_PRIORITY2; - memcpy(state->own_identity.gm_identity, - state->own_identity.header.sourceidentity, - sizeof(state->own_identity.gm_identity)); - state->own_identity.timesource = CONFIG_NETUTILS_PTPD_CLOCKSOURCE; - - /* Subscribe to PTP multicast address */ - - bind_addr.sin_family = AF_INET; - bind_addr.sin_addr.s_addr = HTONL(PTP_MULTICAST_ADDR); - - clock_gettime(CLOCK_MONOTONIC, &state->last_received_multicast); - - ret = ipmsfilter(&state->interface_addr.sin_addr, - &bind_addr.sin_addr, MCAST_INCLUDE); - if (ret < 0) - { - ptperr("Failed to bind multicast address: %d\n", errno); - return ERROR; - } - - /* Bind socket for events */ - - bind_addr.sin_port = HTONS(PTP_UDP_PORT_EVENT); - ret = bind(state->event_socket, (FAR struct sockaddr *)&bind_addr, - sizeof(bind_addr)); - if (ret < 0) - { - ptperr("Failed to bind to udp port %d\n", bind_addr.sin_port); - return ERROR; - } - - if (state->config->hardware_ts) - { - ret = setsockopt(state->event_socket, SOL_SOCKET, SO_TIMESTAMPNS, - &arg, sizeof(arg)); - - if (ret < 0) - { - ptperr("Failed to enable SO_TIMESTAMPNS: %s\n", strerror(errno)); - return ERROR; - } - } - - /* Bind socket for announcements */ - - bind_addr.sin_port = HTONS(PTP_UDP_PORT_INFO); - ret = bind(state->info_socket, (FAR struct sockaddr *)&bind_addr, - sizeof(bind_addr)); - if (ret < 0) - { - ptperr("Failed to bind to udp port %d\n", bind_addr.sin_port); - return ERROR; - } - - /* Bind TX socket to interface address (local addr cannot be multicast) */ - - bind_addr.sin_addr = state->interface_addr.sin_addr; - ret = bind(state->tx_socket, (FAR struct sockaddr *)&bind_addr, - sizeof(bind_addr)); - if (ret < 0) - { - ptperr("Failed to bind tx to port %d\n", bind_addr.sin_port); - return ERROR; - } - - return OK; -} - /* Unsubscribe multicast and destroy sockets */ static int ptp_destroy_state(FAR struct ptp_state_s *state) @@ -667,6 +517,193 @@ static int ptp_destroy_state(FAR struct ptp_state_s *state) return OK; } +/* Initialize PTP client/server state and create sockets */ + +static int ptp_initialize_state(FAR struct ptp_state_s *state) +{ + int ret; + int arg = 1; + struct ifreq req; + + state->clockid = ptp_open(state->config->clock); + if (state->clockid < 0) + { + ptperr("Invalid clockid %d for ptp daemon\n", state->clockid); + return ERROR; + } + + /* Create sockets */ + + if (state->config->af == AF_PACKET) + { + struct sockaddr_ll addr; + + state->tx_socket = socket(AF_PACKET, SOCK_RAW, 0); + if (state->tx_socket < 0) + { + ptperr("Failed to create tx socket: %d\n", errno); + goto errout; + } + + state->event_socket = dup(state->tx_socket); + state->info_socket = -1; + + addr.sll_family = AF_PACKET; + addr.sll_ifindex = if_nametoindex(state->config->interface); + addr.sll_protocol = htons(ETHERTYPE_PTP); + ret = bind(state->tx_socket, (FAR struct sockaddr *)&addr, + sizeof(addr)); + if (ret < 0) + { + ptperr("ERROR: binding socket failed: %d\n", errno); + goto errout; + } + } + else if (state->config->af == AF_INET) + { + struct sockaddr_in bind_addr; + + state->tx_socket = socket(AF_INET, SOCK_DGRAM, 0); + if (state->tx_socket < 0) + { + ptperr("Failed to create tx socket: %d\n", errno); + goto errout; + } + + state->event_socket = socket(AF_INET, SOCK_DGRAM, 0); + if (state->event_socket < 0) + { + ptperr("Failed to create event socket: %d\n", errno); + goto errout; + } + + state->info_socket = socket(AF_INET, SOCK_DGRAM, 0); + if (state->info_socket < 0) + { + ptperr("Failed to create info socket: %d\n", errno); + goto errout; + } + + /* Subscribe to PTP multicast address */ + + bind_addr.sin_family = AF_INET; + bind_addr.sin_addr.s_addr = HTONL(PTP_MULTICAST_ADDR); + + ret = ipmsfilter(&state->interface_addr.sin_addr, + &bind_addr.sin_addr, MCAST_INCLUDE); + if (ret < 0) + { + ptperr("Failed to bind multicast address: %d\n", errno); + goto errout; + } + + /* Bind socket for events */ + + bind_addr.sin_port = HTONS(PTP_UDP_PORT_EVENT); + ret = bind(state->event_socket, (FAR struct sockaddr *)&bind_addr, + sizeof(bind_addr)); + if (ret < 0) + { + ptperr("Failed to bind to udp port %d\n", bind_addr.sin_port); + goto errout; + } + + /* Bind socket for announcements */ + + bind_addr.sin_port = HTONS(PTP_UDP_PORT_INFO); + ret = bind(state->info_socket, (FAR struct sockaddr *)&bind_addr, + sizeof(bind_addr)); + if (ret < 0) + { + ptperr("Failed to bind to udp port %d\n", bind_addr.sin_port); + goto errout; + } + + /* Bind TX socket to interface address (local addr cannot be + * multicast) + */ + + bind_addr.sin_addr = state->interface_addr.sin_addr; + ret = bind(state->tx_socket, (FAR struct sockaddr *)&bind_addr, + sizeof(bind_addr)); + if (ret < 0) + { + ptperr("Failed to bind tx to port %d\n", bind_addr.sin_port); + goto errout; + } + } + + if (state->config->hardware_ts) + { + ret = setsockopt(state->event_socket, SOL_SOCKET, SO_TIMESTAMPNS, + &arg, sizeof(arg)); + + if (ret < 0) + { + ptperr("Failed to enable SO_TIMESTAMPNS: %s\n", strerror(errno)); + goto errout; + } + } + + /* Get address information of the specified interface for binding socket + * Only supports IPv4 currently. + */ + + memset(&req, 0, sizeof(req)); + strlcpy(req.ifr_name, state->config->interface, sizeof(req.ifr_name)); + + if (ioctl(state->event_socket, SIOCGIFADDR, (unsigned long)&req) < 0) + { + ptperr("Failed to get IP address information for interface %s\n", + state->config->interface); + goto errout; + } + + state->interface_addr = *(FAR struct sockaddr_in *)&req.ifr_ifru.ifru_addr; + + /* Get hardware address to initialize the identity field in header. + * Clock identity is EUI-64, which we make from EUI-48. + */ + + if (ioctl(state->event_socket, SIOCGIFHWADDR, (unsigned long)&req) < 0) + { + ptperr("Failed to get HW address information for interface %s\n", + state->config->interface); + goto errout; + } + + state->own_identity.header.version = 2; + state->own_identity.header.domain = CONFIG_NETUTILS_PTPD_DOMAIN; + state->own_identity.header.sourceidentity[0] = req.ifr_hwaddr.sa_data[0]; + state->own_identity.header.sourceidentity[1] = req.ifr_hwaddr.sa_data[1]; + state->own_identity.header.sourceidentity[2] = req.ifr_hwaddr.sa_data[2]; + state->own_identity.header.sourceidentity[3] = 0xff; + state->own_identity.header.sourceidentity[4] = 0xfe; + state->own_identity.header.sourceidentity[5] = req.ifr_hwaddr.sa_data[3]; + state->own_identity.header.sourceidentity[6] = req.ifr_hwaddr.sa_data[4]; + state->own_identity.header.sourceidentity[7] = req.ifr_hwaddr.sa_data[5]; + state->own_identity.header.sourceportindex[0] = 0; + state->own_identity.header.sourceportindex[1] = 1; + state->own_identity.gm_priority1 = CONFIG_NETUTILS_PTPD_PRIORITY1; + state->own_identity.gm_quality[0] = CONFIG_NETUTILS_PTPD_CLASS; + state->own_identity.gm_quality[1] = CONFIG_NETUTILS_PTPD_ACCURACY; + state->own_identity.gm_quality[2] = 0xff; /* No variance estimate */ + state->own_identity.gm_quality[3] = 0xff; + state->own_identity.gm_priority2 = CONFIG_NETUTILS_PTPD_PRIORITY2; + memcpy(state->own_identity.gm_identity, + state->own_identity.header.sourceidentity, + sizeof(state->own_identity.gm_identity)); + state->own_identity.timesource = CONFIG_NETUTILS_PTPD_CLOCKSOURCE; + + clock_gettime(CLOCK_MONOTONIC, &state->last_received_multicast); + + return OK; + +errout: + ptp_destroy_state(state); + return ERROR; +} + /* Re-subscribe multicast address. * This can become necessary if Ethernet interface gets reset or if external * IGMP-compliant Ethernet switch gets plugged in. @@ -706,6 +743,76 @@ static int ptp_check_multicast_status(FAR struct ptp_state_s *state) return OK; } +static int ptp_sendmsg(FAR struct ptp_state_s *state, FAR const void *buf, + size_t buflen, FAR const void *addr, + socklen_t addrlen, FAR struct timespec *sendts) +{ + int ret; + + if (state->config->af == AF_PACKET) + { + /* IEE802.1AS Multicast address for gptp */ + + const uint8_t ptp_multicast_mac[ETHER_ADDR_LEN] = + { + 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e + }; + + char raw[sizeof(struct ether_header) + buflen]; + FAR struct ether_header *header; + struct msghdr msg; + struct iovec iov; + + header = (FAR struct ether_header *)&raw; + memcpy(header->ether_dhost, ptp_multicast_mac, ETHER_ADDR_LEN); + netlib_getmacaddr(state->config->interface, header->ether_shost); + header->ether_type = ETHERTYPE_PTP; + memcpy(&raw[sizeof(*header)], buf, buflen); + buflen += sizeof(*header); + + iov.iov_base = raw; + iov.iov_len = buflen; + + msg.msg_name = (FAR void *)addr; + msg.msg_namelen = addrlen; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_flags = 0; + msg.msg_control = NULL; + msg.msg_controllen = 0; + + ret = sendmsg(state->tx_socket, &msg, 0); + if (ret < 0) + { + return ERROR; + } + + if (state->config->hardware_ts && sendts != NULL) + { + uint8_t rxcmsg[CMSG_LEN(sizeof(struct timespec))]; + + msg.msg_control = &rxcmsg; + msg.msg_controllen = CMSG_LEN(sizeof(struct timespec)); + ret = recvmsg(state->tx_socket, &msg, 0); + if (ret >= 0) + { + ptp_getrxtime(state, &msg, sendts); + } + } + } + else + { + ret = sendto(state->tx_socket, buf, buflen, 0, addr, addrlen); + } + + if (!state->config->hardware_ts && sendts != NULL) + { + ptp_gettime(state, sendts); + } + + return ret; +} + /* Send PTP server announcement packet */ static int ptp_send_announce(FAR struct ptp_state_s *state) @@ -728,12 +835,10 @@ static int ptp_send_announce(FAR struct ptp_state_s *state) ptp_gettime(state, &ts); timespec_to_ptp_format(&ts, msg.origintimestamp); - ret = sendto(state->tx_socket, &msg, sizeof(msg), 0, - (FAR struct sockaddr *)&addr, sizeof(addr)); - + ret = ptp_sendmsg(state, &msg, sizeof(msg), &addr, sizeof(addr), NULL); if (ret < 0) { - ptperr("sendto failed: %d", errno); + ptperr("ptp sendmsg failed: %d", errno); } else { @@ -748,17 +853,11 @@ static int ptp_send_announce(FAR struct ptp_state_s *state) static int ptp_send_sync(FAR struct ptp_state_s *state) { - struct msghdr txhdr; - struct iovec txiov; struct ptp_sync_s msg; struct sockaddr_in addr; struct timespec ts; - uint8_t controlbuf[64]; int ret; - memset(&txhdr, 0, sizeof(txhdr)); - memset(&txiov, 0, sizeof(txiov)); - addr.sin_family = AF_INET; addr.sin_addr.s_addr = HTONL(PTP_MULTICAST_ADDR); addr.sin_port = HTONS(PTP_UDP_PORT_EVENT); @@ -772,22 +871,13 @@ static int ptp_send_sync(FAR struct ptp_state_s *state) msg.header.flags[0] = PTP_FLAGS0_TWOSTEP; #endif - txhdr.msg_name = &addr; - txhdr.msg_namelen = sizeof(addr); - txhdr.msg_iov = &txiov; - txhdr.msg_iovlen = 1; - txhdr.msg_control = controlbuf; - txhdr.msg_controllen = sizeof(controlbuf); - txiov.iov_base = &msg; - txiov.iov_len = sizeof(msg); - /* Timestamp and send the sync message */ ptp_increment_sequence(&state->sync_seq, &msg.header); ptp_gettime(state, &ts); timespec_to_ptp_format(&ts, msg.origintimestamp); - ret = sendmsg(state->tx_socket, &txhdr, 0); + ret = ptp_sendmsg(state, &msg, sizeof(msg), &addr, sizeof(addr), &ts); if (ret < 0) { ptperr("sendmsg for sync message failed: %d\n", errno); @@ -795,22 +885,16 @@ static int ptp_send_sync(FAR struct ptp_state_s *state) } #ifdef CONFIG_NETUTILS_PTPD_TWOSTEP_SYNC - /* Get timestamp after send completes and send follow-up message - * - * TODO: Implement SO_TIMESTAMPING and use the actual tx timestamp here. - */ - ptp_gettime(state, &ts); timespec_to_ptp_format(&ts, msg.origintimestamp); msg.header.messagetype = PTP_MSGTYPE_FOLLOW_UP; msg.header.flags[0] = 0; addr.sin_port = HTONS(PTP_UDP_PORT_INFO); - ret = sendto(state->tx_socket, &msg, sizeof(msg), 0, - (FAR struct sockaddr *)&addr, sizeof(addr)); + ret = ptp_sendmsg(state, &msg, sizeof(msg), &addr, sizeof(addr), NULL); if (ret < 0) { - ptperr("sendto for follow-up message failed: %d\n", errno); + ptperr("ptp sendmsg for follow-up message failed: %d\n", errno); return ret; } @@ -845,18 +929,11 @@ static int ptp_send_delay_req(FAR struct ptp_state_s *state) ptp_gettime(state, &state->delayreq_time); timespec_to_ptp_format(&state->delayreq_time, req.origintimestamp); - ret = sendto(state->tx_socket, &req, sizeof(req), 0, - (FAR struct sockaddr *)&addr, sizeof(addr)); - - /* Get timestamp after send completes. - * TODO: Implement SO_TIMESTAMPING and use the actual tx timestamp here. - */ - - ptp_gettime(state, &state->delayreq_time); - + ret = ptp_sendmsg(state, &req, sizeof(req), + &addr, sizeof(addr), &state->delayreq_time); if (ret < 0) { - ptperr("sendto failed: %d", errno); + ptperr("ptp sendmsg failed: %d", errno); } else { @@ -1219,12 +1296,10 @@ static int ptp_process_delay_req(FAR struct ptp_state_s *state, sizeof(resp.header.sequenceid)); resp.header.logmessageinterval = CONFIG_NETUTILS_PTPD_DELAYRESP_INTERVAL; - ret = sendto(state->tx_socket, &resp, sizeof(resp), 0, - (FAR struct sockaddr *)&addr, sizeof(addr)); - + ret = ptp_sendmsg(state, &resp, sizeof(resp), &addr, sizeof(addr), NULL); if (ret < 0) { - ptperr("sendto failed: %d", errno); + ptperr("ptp sendmsg failed: %d", errno); } else { @@ -1318,6 +1393,21 @@ static int ptp_process_delay_resp(FAR struct ptp_state_s *state, static int ptp_process_rx_packet(FAR struct ptp_state_s *state, ssize_t length) { + if (state->config->af == AF_PACKET) + { + /* Remove the header of ether message */ + + FAR struct ethhdr *header = (FAR struct ethhdr *)state->rxbuf.raw; + + if (htons(header->h_proto) != ETHERTYPE_PTP) + { + return -EINVAL; + } + + length -= sizeof(*header); + memmove(&state->rxbuf.raw, header + 1, length); + } + if (length < sizeof(struct ptp_header_s)) { ptpwarn("Ignoring invalid PTP packet, length only %d bytes\n", @@ -1496,6 +1586,7 @@ int ptpd_start(FAR const struct ptpd_config_s *config) struct msghdr rxhdr; struct iovec rxiov; int timeout; + int idx = 1; int ret; memset(&rxhdr, 0, sizeof(rxhdr)); @@ -1508,7 +1599,7 @@ int ptpd_start(FAR const struct ptpd_config_s *config) } state->config = config; - if (ptp_initialize_state(state, config->interface) != OK) + if (ptp_initialize_state(state) != OK) { ptperr("Failed to initialize PTP state, exiting\n"); goto errout; @@ -1527,8 +1618,12 @@ int ptpd_start(FAR const struct ptpd_config_s *config) pollfds[0].events = POLLIN; pollfds[0].fd = state->event_socket; - pollfds[1].events = POLLIN; - pollfds[1].fd = state->info_socket; + if (state->info_socket > 0) + { + pollfds[1].events = POLLIN; + pollfds[1].fd = state->info_socket; + idx++; + } while (!state->stop) { @@ -1546,7 +1641,7 @@ int ptpd_start(FAR const struct ptpd_config_s *config) pollfds[0].revents = 0; pollfds[1].revents = 0; - ret = poll(pollfds, 2, timeout); + ret = poll(pollfds, idx, timeout); if (pollfds[0].revents) { From 03ca9ba5000524c69d902a2af3a2b582d6d75345 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Wed, 9 Apr 2025 17:39:32 +0800 Subject: [PATCH 066/568] netutils/ptpd: using -B to control BMCA message new option -B to BMCA message Signed-off-by: dongjiuzhu1 --- include/netutils/ptpd.h | 1 + netutils/ptpd/ptpd.c | 10 ++++++---- system/ptpd/ptpd_main.c | 7 ++++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/netutils/ptpd.h b/include/netutils/ptpd.h index ea4b9fb7b..1d455c6be 100644 --- a/include/netutils/ptpd.h +++ b/include/netutils/ptpd.h @@ -44,6 +44,7 @@ struct ptpd_config_s bool client_only; bool hardware_ts; bool delay_e2e; + bool bmca; sa_family_t af; }; diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index e08b7fab2..010b9a2f3 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -961,7 +961,7 @@ static int ptp_periodic_send(FAR struct ptp_state_s *state) clock_gettime(CLOCK_MONOTONIC, &time_now); clock_timespec_subtract(&time_now, &state->last_transmitted_announce, &delta); - if (timespec_to_ms(&delta) + if (state->config->bmca && timespec_to_ms(&delta) > CONFIG_NETUTILS_PTPD_ANNOUNCE_INTERVAL_MSEC) { state->last_transmitted_announce = time_now; @@ -1003,7 +1003,7 @@ static int ptp_process_announce(FAR struct ptp_state_s *state, { clock_gettime(CLOCK_MONOTONIC, &state->last_received_announce); - if (is_better_clock(msg, &state->own_identity)) + if (state->conifg->bmca && is_better_clock(msg, &state->n_identity)) { if (!state->selected_source_valid || is_better_clock(msg, &state->selected_source)) @@ -1206,7 +1206,8 @@ static int ptp_process_sync(FAR struct ptp_state_s *state, { struct timespec remote_time; - if (memcmp(msg->header.sourceidentity, + if (state->config->bmca && + memcmp(msg->header.sourceidentity, state->selected_source.header.sourceidentity, sizeof(msg->header.sourceidentity)) != 0) { @@ -1240,7 +1241,8 @@ static int ptp_process_followup(FAR struct ptp_state_s *state, { struct timespec remote_time; - if (memcmp(msg->header.sourceidentity, + if (state->config->bmca && + memcmp(msg->header.sourceidentity, state->twostep_packet.header.sourceidentity, sizeof(msg->header.sourceidentity)) != 0) { diff --git a/system/ptpd/ptpd_main.c b/system/ptpd/ptpd_main.c index e65905987..4a87ce472 100644 --- a/system/ptpd/ptpd_main.c +++ b/system/ptpd/ptpd_main.c @@ -153,6 +153,7 @@ static void usage(FAR const char *progname) " Time Stamping:\n" " -H HARDWARE (default) depends on NET_TIMESTAMP\n" " -S SOFTWARE\n" + " -B The best master clock algorithm is used\n" " -r synchronize system (realtime) clock\n" " -E E2E, support client delay request-response\n" " -i [dev] interface device to use, for example 'eth0'\n" @@ -186,9 +187,10 @@ int main(int argc, FAR char *argv[]) #else config.hardware_ts = false; #endif + config.bmca = false; config.af = AF_INET; - while ((option = getopt(argc, argv, "p:i:t:d:rs246EHS")) != ERROR) + while ((option = getopt(argc, argv, "p:i:t:d:rs246BEHS")) != ERROR) { switch (option) { @@ -208,6 +210,9 @@ int main(int argc, FAR char *argv[]) case '6': config.af = AF_INET6; break; + case 'B': + config.bmca = true; + break; case 'E': config.delay_e2e = true; break; From e5c85d1ca23c5e41df65da7b228f447e6229470a Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Wed, 9 Apr 2025 09:25:38 +0800 Subject: [PATCH 067/568] netutils/ptpd: Add switch correction time change The current gPTP stack does not support path delay correction of the Switch. This patch adds the path delay correction field in the Header. Signed-off-by: dongjiuzhu1 --- netutils/ptpd/ptpd.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 010b9a2f3..3193ee33e 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -1236,6 +1236,31 @@ static int ptp_process_sync(FAR struct ptp_state_s *state, return ptp_update_local_clock(state, &remote_time, &state->rxtime); } +static void ptp_add_correction_time(FAR const uint8_t *correction, + FAR struct timespec *ts) +{ + uint64_t correction_time = (((uint64_t)correction[0]) << 40) + | (((uint64_t)correction[1]) << 32) + | (((uint64_t)correction[2]) << 24) + | (((uint64_t)correction[3]) << 16) + | (((uint64_t)correction[4]) << 8) + | (((uint64_t)correction[5]) << 0); + + ptpinfo("correction before: %lld.%09ld\n", (long long)ts->tv_sec, + ts->tv_nsec); + + ts->tv_sec += correction_time / NSEC_PER_SEC; + ts->tv_nsec += correction_time % NSEC_PER_SEC; + if (ts->tv_nsec >= NSEC_PER_SEC) + { + ts->tv_nsec -= NSEC_PER_SEC; + ts->tv_sec += 1; + } + + ptpinfo("correction after: %lld.%09ld\n", (long long)ts->tv_sec, + ts->tv_nsec); +} + static int ptp_process_followup(FAR struct ptp_state_s *state, FAR struct ptp_follow_up_s *msg) { @@ -1264,6 +1289,13 @@ static int ptp_process_followup(FAR struct ptp_state_s *state, */ ptp_format_to_timespec(msg->origintimestamp, &remote_time); + + /* add correction time */ + + ptp_add_correction_time(msg->header.correction, &remote_time); + + /* done */ + return ptp_update_local_clock(state, &remote_time, &state->twostep_rxtime); } From 710aef6bd097a76345f3b374291dfbc1f49a7631 Mon Sep 17 00:00:00 2001 From: zhangkai25 Date: Wed, 29 Oct 2025 10:52:52 +0800 Subject: [PATCH 068/568] iperf: Increase the priority of the report thread ensure it is not blocked by the iperf thread, preventing iperf from completing Signed-off-by: zhangkai25 --- netutils/iperf/iperf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netutils/iperf/iperf.c b/netutils/iperf/iperf.c index cda61f68e..b9243a608 100644 --- a/netutils/iperf/iperf.c +++ b/netutils/iperf/iperf.c @@ -48,7 +48,7 @@ #define IPERF_TRAFFIC_TASK_PRIORITY 100 #define IPERF_TRAFFIC_TASK_STACK 4096 #define IPERF_REPORT_TASK_NAME "iperf_report" -#define IPERF_REPORT_TASK_PRIORITY 100 +#define IPERF_REPORT_TASK_PRIORITY 101 #define IPERF_REPORT_TASK_STACK 4096 #define IPERF_UDP_TX_LEN (1472) From c90b64ed8b18891cff4414f5e20f9a6c15b686a6 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Wed, 31 Dec 2025 14:35:54 +0800 Subject: [PATCH 069/568] nshlib/ls_handler: eliminate floating-point operations for human-readable sizes Replace floating-point arithmetic with fixed-point integer math to avoid linking soft-float library (~2-3KB Flash) when displaying human-readable file sizes (ls -lh command). Changes: - Use integer division and modulo to calculate size components - Calculate decimal part: (remainder * 10) / unit for one decimal place - Refactor duplicated code: consolidate GB/MB/KB logic into single path - Remove CONFIG_HAVE_FLOAT dependency This eliminates calls to __aeabi_f2d, __aeabi_fmul, __aeabi_i2f and other ARM EABI floating-point helpers, reducing Flash footprint for systems compiled with -mfloat-abi=soft. Signed-off-by: dongjiuzhu1 --- nshlib/nsh_fscmds.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index 1c705befe..c1abcd357 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -518,24 +518,39 @@ static int ls_handler(FAR struct nsh_vtbl_s *vtbl, FAR const char *dirpath, if ((lsflags & LSFLAGS_SIZE) != 0) { -#ifdef CONFIG_HAVE_FLOAT if (lsflags & LSFLAGS_HUMANREADBLE && buf.st_size >= KB) { + uint32_t integer_part; + uint32_t decimal_part; + uint32_t unit; + char suffix; + + /* Determine the appropriate unit and suffix */ + if (buf.st_size >= GB) { - nsh_output(vtbl, "%11.1fG", (float)buf.st_size / GB); + unit = GB; + suffix = 'G'; } else if (buf.st_size >= MB) { - nsh_output(vtbl, "%11.1fM", (float)buf.st_size / MB); + unit = MB; + suffix = 'M'; } else { - nsh_output(vtbl, "%11.1fK", (float)buf.st_size / KB); + unit = KB; + suffix = 'K'; } + + /* Use integer arithmetic to avoid floating point */ + + integer_part = buf.st_size / unit; + decimal_part = ((buf.st_size % unit) * 10) / unit; + nsh_output(vtbl, "%10" PRIu32 ".%" PRIu32 "%c", + integer_part, decimal_part, suffix); } else -#endif { nsh_output(vtbl, "%12" PRIdOFF, buf.st_size); } @@ -1549,11 +1564,10 @@ int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) lsflags |= LSFLAGS_SIZE; break; -#ifdef CONFIG_HAVE_FLOAT case 'h': lsflags |= LSFLAGS_HUMANREADBLE; break; -#endif + case '?': default: nsh_error(vtbl, g_fmtarginvalid, argv[0]); From 85539a1223c4770ee36e68817f5bfe91e6b49369 Mon Sep 17 00:00:00 2001 From: p-szafonimateusz Date: Tue, 30 Dec 2025 09:50:09 +0100 Subject: [PATCH 070/568] github/ci: add support for NTFC Add support for NTFC testing framework. At the moment NTFC is downloaded from a private repo, and installed with pip and venv. In the future NTFC repositories will be migrated to Apache organization. Signed-off-by: p-szafonimateusz --- .github/workflows/build.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6830a7a96..7c43588cb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -175,6 +175,31 @@ jobs: - name: Export NuttX Repo SHA run: echo "nuttx_sha=`git -C sources/nuttx rev-parse HEAD`" >> $GITHUB_ENV + - name: Install NTFC + uses: ./sources/nuttx/.github/actions/ci-container + env: + BLOBDIR: /tools/blobs + with: + run: | + # install venv + apt-get update + apt install -y python3-dev + apt install -y python3-venv + + # get NTFC sources + git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-ntfc + cd /github/workspace/nuttx-ntfc + + # install NTFC with venv + python3 -m venv /github/workspace/nuttx-ntfc/venv + source /github/workspace/nuttx-ntfc/venv/bin/activate + pip3 install . + deactivate + + # get NTFC test cases + cd external + git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-testing + - name: Run builds uses: ./sources/nuttx/.github/actions/ci-container env: @@ -183,6 +208,7 @@ jobs: run: | echo "::add-matcher::sources/nuttx/.github/gcc.json" export ARTIFACTDIR=`pwd`/buildartifacts + export NTFCDIR=/github/workspace/nuttx-ntfc git config --global --add safe.directory /github/workspace/sources/nuttx git config --global --add safe.directory /github/workspace/sources/apps cd sources/nuttx/tools/ci From 9ad4c3c39527ebb02199d332af811a3f792dca62 Mon Sep 17 00:00:00 2001 From: nuttxs Date: Wed, 24 Dec 2025 23:09:32 +0800 Subject: [PATCH 071/568] netutils/dhcpc.h: fix the compilation error caused by undefined CONFIG_NETDB_DNSSERVER_NAMESERVERS Provide a default value for CONFIG_NETDB_DNSSERVER_NAMESERVERS if CONFIG_NETDB_DNSCLIENT is not enabled Signed-off-by: nuttxs --- include/netutils/dhcpc.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/netutils/dhcpc.h b/include/netutils/dhcpc.h index d55fca170..0cf16907b 100644 --- a/include/netutils/dhcpc.h +++ b/include/netutils/dhcpc.h @@ -39,6 +39,7 @@ * Included Files ****************************************************************************/ +#include #include #include @@ -46,6 +47,14 @@ * Pre-processor Definitions ****************************************************************************/ +/* Provide a default value for CONFIG_NETDB_DNSSERVER_NAMESERVERS if + * CONFIG_NETDB_DNSCLIENT is not enabled. + */ + +#if !defined(CONFIG_NETDB_DNSSERVER_NAMESERVERS) +# define CONFIG_NETDB_DNSSERVER_NAMESERVERS 1 +#endif + /**************************************************************************** * Public Types ****************************************************************************/ From 6830e297cf0bcb5730b3a4b87b64c01027ed2bc3 Mon Sep 17 00:00:00 2001 From: zhangshuai39 Date: Thu, 7 Aug 2025 14:33:52 +0800 Subject: [PATCH 072/568] dhcpd: Supports kernel mode compilation The previous method of terminating the dhcp daemon via a global variable has been removed; instead, the `kill pid` command is used. Also, because the original `dhcp_start` method creates tasks via `task_create`, which is not supported in kernel mode, `dhcp_start` is not compiled in kernel mode. The daemon can be started in kernel mode using `dhcpd xxx &`. Signed-off-by: zhangshuai39 --- examples/dhcpd/CMakeLists.txt | 36 ++++---- examples/dhcpd/Makefile | 14 +++- examples/dhcpd/dhcpd_daemon.c | 8 +- netutils/dhcpd/dhcpd.c | 154 +++++++++++++++++++++------------- 4 files changed, 135 insertions(+), 77 deletions(-) diff --git a/examples/dhcpd/CMakeLists.txt b/examples/dhcpd/CMakeLists.txt index b59cb5485..5b2ba7cd2 100644 --- a/examples/dhcpd/CMakeLists.txt +++ b/examples/dhcpd/CMakeLists.txt @@ -30,23 +30,27 @@ if(CONFIG_EXAMPLES_DHCPD) STACKSIZE ${CONFIG_DEFAULT_TASK_STACKSIZE}) - nuttx_add_application( - NAME - dhcpd_start - SRCS - dhcpd_start.c - dhcpd_daemon.c - STACKSIZE - ${CONFIG_DEFAULT_TASK_STACKSIZE}) + if(NOT CONFIG_BUILD_KERNEL) + nuttx_add_application( + NAME + dhcpd_start + SRCS + dhcpd_start.c + dhcpd_daemon.c + STACKSIZE + ${CONFIG_DEFAULT_TASK_STACKSIZE}) + endif() - nuttx_add_application( - NAME - dhcpd_stop - SRCS - dhcpd_stop.c - dhcpd_daemon.c - STACKSIZE - ${CONFIG_DEFAULT_TASK_STACKSIZE}) + if(CONFIG_SCHED_WAITPID) + nuttx_add_application( + NAME + dhcpd_stop + SRCS + dhcpd_stop.c + dhcpd_daemon.c + STACKSIZE + ${CONFIG_DEFAULT_TASK_STACKSIZE}) + endif() add_definitions(-DCONFIG_NETUTILS_DHCPD_HOST=1 -DHAVE_SO_REUSEADDR=1 -DHAVE_SO_BROADCAST=1) diff --git a/examples/dhcpd/Makefile b/examples/dhcpd/Makefile index 84ce2efc4..6c6ab3ba8 100644 --- a/examples/dhcpd/Makefile +++ b/examples/dhcpd/Makefile @@ -26,13 +26,23 @@ include $(APPDIR)/Make.defs CSRCS = dhcpd_daemon.c -MAINSRC = dhcpd_start.c dhcpd_stop.c target.c +MAINSRC = target.c # DHCPD built-in application info -PROGNAME = dhcpd_start dhcpd_stop dhcpd +PROGNAME = dhcpd PRIORITY = SCHED_PRIORITY_DEFAULT STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) MODULE = $(CONFIG_EXAMPLES_DHCPD) +ifneq ($(CONFIG_BUILD_KERNEL),y) +MAINSRC += dhcpd_start.c +PROGNAME += dhcpd_start +endif + +ifeq ($(CONFIG_SCHED_WAITPID),y) +MAINSRC += dhcpd_stop.c +PROGNAME += dhcpd_stop +endif + include $(APPDIR)/Application.mk diff --git a/examples/dhcpd/dhcpd_daemon.c b/examples/dhcpd/dhcpd_daemon.c index 5b8f52186..b4f16e787 100644 --- a/examples/dhcpd/dhcpd_daemon.c +++ b/examples/dhcpd/dhcpd_daemon.c @@ -128,10 +128,12 @@ int dhcpd_daemon(int argc, FAR char *argv[], bool daemon) /* Then start the dhcpd */ - if (daemon) +#ifndef CONFIG_BUILD_KERNEL + if (!daemon) { - return dhcpd_run(devname); + return dhcpd_start(devname); } +#endif - return dhcpd_start(devname); + return dhcpd_run(devname); } diff --git a/netutils/dhcpd/dhcpd.c b/netutils/dhcpd/dhcpd.c index 367dda526..558991c22 100644 --- a/netutils/dhcpd/dhcpd.c +++ b/netutils/dhcpd/dhcpd.c @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -276,8 +277,6 @@ struct dhcpd_state_s struct dhcpd_daemon_s { uint8_t ds_state; /* See enum dhcpd_daemon_e */ - sem_t ds_lock; /* Used to protect the whole structure */ - sem_t ds_sync; /* Used to synchronize start and stop events */ pid_t ds_pid; /* Task ID of the DHCPD daemon */ FAR struct dhcpd_state_s *ds_data; /* DHCPD daemon data */ }; @@ -314,8 +313,6 @@ static const uint8_t g_magiccookie[4] = static struct dhcpd_daemon_s g_dhcpd_daemon = { DHCPD_NOT_RUNNING, - SEM_INITIALIZER(1), - SEM_INITIALIZER(0), -1, NULL }; @@ -1019,7 +1016,7 @@ static int dhcpd_sendpacket(int sockfd, int bbroadcast) #endif /* Create a socket to respond with a packet to the client. We - * cannot re-use the listener socket because it is not bound correctly + * cannot reuse the listener socket because it is not bound correctly */ /* Then send the response to the DHCP client port at that address */ @@ -1407,7 +1404,7 @@ static inline int dhcpd_decline(void) lease = dhcpd_findbymac(g_state.ds_inpacket.chaddr); if (lease) { - /* Disassociate the IP from the MAC, but prevent re-used of this + /* Disassociate the IP from the MAC, but prevent reused of this * address for a period of time. */ @@ -1497,10 +1494,74 @@ static inline int dhcpd_openlistener(FAR const char *interface) * Name: dhcpd_task_run ****************************************************************************/ +#ifndef CONFIG_BUILD_KERNEL static int dhcpd_task_run(int argc, char **argv) { return dhcpd_run(argv[1]); } +#endif + +/**************************************************************************** + * Name: dhcpd_get_pid + * + * Description: + * Use /proc filesystem to get dhcpd process PID + * + * Returned Value: + * PID of dhcpd process on success, -1 on failure + * + ****************************************************************************/ + +#if !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_SCHED_WAITPID) +static pid_t dhcpd_get_pid(void) +{ + pid_t pid = -1; + +#if !defined(CONFIG_BUILD_KERNEL) + pid = g_dhcpd_daemon.ds_pid; +#elif defined(CONFIG_SYSTEM_POPEN) + FAR FILE *fp; + char line[32]; + + fp = popen(("pidof dhcpd"), "r"); + if (fp == NULL) + { + return -errno; + } + + if (fgets(line, sizeof(line), fp) != NULL) + { + pid = atoi(line); + } + + pclose(fp); +#endif + + return pid; +} +#endif + +/**************************************************************************** + * Name: dhcpd_signal_handler + * + * Description: + * Signal handler for CONFIG_NETUTILS_DHCPD_SIGWAKEUP + * This function allows dhcpd_stop to terminate dhcpd daemon + * + * Input Parameters: + * signo - Signal number + * info - Signal information + * ctx - Signal context + * + ****************************************************************************/ + +static void +dhcpd_signal_handler(int signo, FAR siginfo_t *info, FAR void *ctx) +{ + /* Set global flag to indicate stop request */ + + g_dhcpd_daemon.ds_state = DHCPD_STOP_REQUESTED; +} /**************************************************************************** * Public Functions @@ -1512,7 +1573,8 @@ static int dhcpd_task_run(int argc, char **argv) int dhcpd_run(FAR const char *interface) { - int sockfd; + struct sigaction act; + int sockfd = -1; int nbytes; ninfo("Started\n"); @@ -1538,15 +1600,19 @@ int dhcpd_run(FAR const char *interface) g_dhcpd_daemon.ds_pid = getpid(); + /* Install signal handler for CONFIG_NETUTILS_DHCPD_SIGWAKEUP */ + + memset(&act, 0, sizeof(act)); + act.sa_sigaction = dhcpd_signal_handler; + act.sa_flags = SA_SIGINFO; + sigaction(CONFIG_NETUTILS_DHCPD_SIGWAKEUP, &act, NULL); + /* Indicate that we have started */ g_dhcpd_daemon.ds_state = DHCPD_RUNNING; - sem_post(&g_dhcpd_daemon.ds_sync); - /* Now loop indefinitely, reading packets from the DHCP server socket */ - sockfd = -1; while (g_dhcpd_daemon.ds_state != DHCPD_STOP_REQUESTED) { /* Create a socket to listen for requests from DHCP clients */ @@ -1631,7 +1697,6 @@ int dhcpd_run(FAR const char *interface) g_dhcpd_daemon.ds_data = NULL; g_dhcpd_daemon.ds_pid = -1; g_dhcpd_daemon.ds_state = DHCPD_STOPPED; - sem_post(&g_dhcpd_daemon.ds_sync); return OK; } @@ -1648,6 +1713,7 @@ int dhcpd_run(FAR const char *interface) * ****************************************************************************/ +#ifndef CONFIG_BUILD_KERNEL int dhcpd_start(FAR const char *interface) { FAR char *argv[2]; @@ -1658,17 +1724,13 @@ int dhcpd_start(FAR const char *interface) /* Is the DHCPD in a non-running state? */ - sem_wait(&g_dhcpd_daemon.ds_lock); - if (g_dhcpd_daemon.ds_state == DHCPD_NOT_RUNNING || - g_dhcpd_daemon.ds_state == DHCPD_STOPPED) + if (dhcpd_get_pid() < 0) { /* Start the DHCPD daemon */ - g_dhcpd_daemon.ds_state = DHCPD_STARTED; - pid = - task_create("DHCPD daemon", CONFIG_NETUTILS_DHCPD_PRIORITY, - CONFIG_NETUTILS_DHCPD_STACKSIZE, dhcpd_task_run, - argv); + pid = task_create("dhcpd", CONFIG_NETUTILS_DHCPD_PRIORITY, + CONFIG_NETUTILS_DHCPD_STACKSIZE, dhcpd_task_run, + argv); /* Handle failures to start the DHCPD daemon */ @@ -1676,24 +1738,14 @@ int dhcpd_start(FAR const char *interface) { int errval = errno; - g_dhcpd_daemon.ds_state = DHCPD_STOPPED; nerr("ERROR: Failed to start the DHCPD daemon: %d\n", errval); - sem_post(&g_dhcpd_daemon.ds_lock); return -errval; } - - /* Wait for any daemon state change */ - - do - { - sem_wait(&g_dhcpd_daemon.ds_sync); - } - while (g_dhcpd_daemon.ds_state == DHCPD_STARTED); } - sem_post(&g_dhcpd_daemon.ds_lock); return OK; } +#endif /**************************************************************************** * Name: dhcpd_stop @@ -1707,46 +1759,36 @@ int dhcpd_start(FAR const char *interface) * ****************************************************************************/ +#ifdef CONFIG_SCHED_WAITPID int dhcpd_stop(void) { - int ret; + pid_t pid; /* Is the DHCPD in a running state? */ - sem_wait(&g_dhcpd_daemon.ds_lock); - if (g_dhcpd_daemon.ds_state == DHCPD_STARTED || - g_dhcpd_daemon.ds_state == DHCPD_RUNNING) + pid = dhcpd_get_pid(); + if (pid >= 0) { /* Yes.. request that the daemon stop. */ - g_dhcpd_daemon.ds_state = DHCPD_STOP_REQUESTED; - - /* Wait for any daemon state change */ - - do + if (kill(pid, CONFIG_NETUTILS_DHCPD_SIGWAKEUP) < 0) { - /* Signal the DHCPD client */ - - ret = kill(g_dhcpd_daemon.ds_pid, - CONFIG_NETUTILS_DHCPD_SIGWAKEUP); - - if (ret < 0) - { - nerr("ERROR: kill pid %d failed: %d\n", - g_dhcpd_daemon.ds_pid, errno); - break; - } - - /* Wait for the DHCPD client to respond to the stop request */ - - sem_wait(&g_dhcpd_daemon.ds_sync); + nerr("ERROR: kill pid %d failed: %d\n", pid, errno); + return -errno; + } + + /* Wait for the DHCPD client to respond to the stop request */ + + if (waitpid(pid, NULL, 0) < 0) + { + nerr("ERROR: waitpid failed: %d\n", errno); + return -errno; } - while (g_dhcpd_daemon.ds_state == DHCPD_STOP_REQUESTED); } - sem_post(&g_dhcpd_daemon.ds_lock); return OK; } +#endif /**************************************************************************** * Name: dhcpd_set_startip From 150c5756a06314869d4d12f72d7a418b5a20e152 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Fri, 24 Oct 2025 12:33:00 +0800 Subject: [PATCH 073/568] examples/capture: support monitor edge change by signal add monitor code about edge change Signed-off-by: dongjiuzhu1 --- examples/capture/cap.h | 1 + examples/capture/cap_main.c | 82 +++++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/examples/capture/cap.h b/examples/capture/cap.h index 2b1c6f5cf..98c3a5e27 100644 --- a/examples/capture/cap.h +++ b/examples/capture/cap.h @@ -42,6 +42,7 @@ struct cap_example_s FAR char *devpath; /* Path to the capture device */ unsigned int nloops; /* Collect this number of samples */ unsigned int delay; /* Delay this number of seconds between samples */ + int signo; /* Signal number to deliver on isr occur */ }; /**************************************************************************** diff --git a/examples/capture/cap_main.c b/examples/capture/cap_main.c index 3cbe9e8c2..3ca080368 100644 --- a/examples/capture/cap_main.c +++ b/examples/capture/cap_main.c @@ -98,6 +98,10 @@ static void cap_help(void) printf(" [-p devpath] Capture device path\n"); printf(" [-n samples] Number of samples\n"); printf(" [-t msec] Delay between samples (msec)\n"); +#ifdef CONFIG_CAPTURE_NOTIFY + printf(" [-w signo]: Wait for a signal if given " + "otherwise POLL mode if this is an interrupt pin.\n"); +#endif printf(" [-h] Shows this message and exits\n\n"); } @@ -149,6 +153,7 @@ static void parse_args(int argc, FAR char **argv) g_capexample.nloops = CONFIG_EXAMPLES_CAPTURE_NSAMPLES; g_capexample.delay = CONFIG_EXAMPLES_CAPTURE_DELAY; + g_capexample.signo = 1; for (index = 1; index < argc; ) { @@ -191,6 +196,20 @@ static void parse_args(int argc, FAR char **argv) index += nargs; break; +#ifdef CONFIG_CAPTURE_NOTIFY + case 'w': + nargs = arg_decimal(&argv[index], &value); + if (value < MIN_SIGNO || value > MAX_SIGNO) + { + printf("Wait signo out of range: %ld\n", value); + exit(1); + } + + g_capexample.signo = (int)value; + index += nargs; + break; +#endif + case 'h': cap_help(); exit(EXIT_SUCCESS); @@ -214,12 +233,17 @@ static void parse_args(int argc, FAR char **argv) int main(int argc, FAR char *argv[]) { int8_t dutycycle; - int32_t frequence; + int32_t frequency; int32_t edges; int fd; int exitval = EXIT_SUCCESS; int ret; int nloops; +#ifdef CONFIG_CAPTURE_NOTIFY + struct cap_notify_s notify; + struct timespec ts; + sigset_t set; +#endif /* Set the default values */ @@ -242,6 +266,56 @@ int main(int argc, FAR char *argv[]) goto errout; } +#ifdef CONFIG_CAPTURE_NOTIFY + notify.chan = 0; + notify.type = CAP_TYPE_BOTH; + + notify.event.sigev_notify = SIGEV_SIGNAL; + notify.event.sigev_signo = g_capexample.signo; + + ret = ioctl(fd, CAPIOC_REGISTER, (unsigned long)¬ify); + if (ret < 0) + { + printf("cap_main: ioctl(GPIOC_REGISTER) failed: %d\n", errno); + exitval = EXIT_FAILURE; + goto errout_with_dev; + } + + /* Wait up to 5 seconds for the signal */ + + sigemptyset(&set); + sigaddset(&set, g_capexample.signo); + + ts.tv_sec = 5; + ts.tv_nsec = 0; + + ret = sigtimedwait(&set, NULL, &ts); + ioctl(fd, CAPIOC_UNREGISTER, notify.chan); + if (ret < 0) + { + int errcode = errno; + if (errcode == EAGAIN) + { + printf("cpu_main: Five second timeout with no signal\n"); + exitval = EXIT_FAILURE; + goto errout_with_dev; + } + else + { + printf("cpu_main: ERROR: Failed to wait signal %d " + "from %s: %d\n", g_capexample.signo, g_capexample.devpath, + errcode); + exitval = EXIT_FAILURE; + goto errout_with_dev; + } + } + else + { + printf("cap_main: Received signal %d from %s\n", + g_capexample.signo, g_capexample.devpath); + } +#endif + /* Now loop the appropriate number of times, displaying the collected * encoder samples. */ @@ -275,10 +349,10 @@ int main(int argc, FAR char *argv[]) printf("pwm duty cycle: %d %% \n", dutycycle); } - /* Get the frequence data using the ioctl */ + /* Get the frequency data using the ioctl */ ret = ioctl(fd, CAPIOC_FREQUENCE, - (unsigned long)((uintptr_t)&frequence)); + (unsigned long)((uintptr_t)&frequency)); if (ret < 0) { printf("cap_main: ioctl(CAPIOC_FREQUENCE) failed: %d\n", errno); @@ -290,7 +364,7 @@ int main(int argc, FAR char *argv[]) else { - printf("pwm frequence: %"PRId32" Hz \n", frequence); + printf("pwm frequency: %"PRId32" Hz \n", frequency); } /* Get the edges data using the ioctl */ From 3467f9b82d58e95416371beaeaa6dfd17e2910c5 Mon Sep 17 00:00:00 2001 From: meijian Date: Sat, 12 Oct 2024 16:54:05 +0800 Subject: [PATCH 074/568] apps/net: add ip address connectivity check API The system checks connectivity with the input IP address; if no IP address is provided, it defaults to checking DNS server connectivity. Signed-off-by: meijian --- include/netutils/netlib.h | 4 + netutils/netlib/CMakeLists.txt | 4 + netutils/netlib/Makefile | 4 + netutils/netlib/netlib_checkipconnectivity.c | 135 +++++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 netutils/netlib/netlib_checkipconnectivity.c diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 5c7b6a74f..a751ed60b 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -513,6 +513,10 @@ int netlib_getifstatistics(FAR const char *ifname, int netlib_check_ifconflict(FAR const char *ifname); #endif +#ifdef CONFIG_NETUTILS_PING +int netlib_check_ipconnectivity(FAR const char *ip, int timeout, int retry); +#endif + #ifdef CONFIG_MM_IOB int netlib_get_iobinfo(FAR struct iob_stats_s *iob); #endif diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt index 3f3697e95..632b32857 100644 --- a/netutils/netlib/CMakeLists.txt +++ b/netutils/netlib/CMakeLists.txt @@ -157,6 +157,10 @@ if(CONFIG_NETUTILS_NETLIB) list(APPEND SRCS netlib_getiobinfo.c) endif() + if(CONFIG_NETUTILS_PING) + list(APPEND SRCS netlib_checkipconnectivity.c) + endif() + target_sources(apps PRIVATE ${SRCS}) endif() diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index 32eafe2f8..0de8c07e5 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -156,4 +156,8 @@ ifeq ($(CONFIG_MM_IOB),y) CSRCS += netlib_getiobinfo.c endif +ifeq ($(CONFIG_NETUTILS_PING),y) +CSRCS += netlib_checkipconnectivity.c +endif + include $(APPDIR)/Application.mk diff --git a/netutils/netlib/netlib_checkipconnectivity.c b/netutils/netlib/netlib_checkipconnectivity.c new file mode 100644 index 000000000..145c987ff --- /dev/null +++ b/netutils/netlib/netlib_checkipconnectivity.c @@ -0,0 +1,135 @@ +/**************************************************************************** + * apps/netutils/netlib/netlib_checkipconnectivity.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "netutils/icmp_ping.h" +#include "netutils/netlib.h" + +#ifdef CONFIG_NETUTILS_PING + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#define PING_IPADDR_DATALEN 80 + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ping_ipaddr_callback + * + * Description: + * ping ipaddr callback + * + * Parameters: + * result The result of ping + * + ****************************************************************************/ + +static void ping_ipaddr_callback(FAR const struct ping_result_s *result) +{ + FAR int *count = result->info->priv; + + if (result->code == ICMP_I_FINISH) + { + *count = result->nreplies; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netlib_check_ipconnectivity + * + * Description: + * Get the network dns status + * + * Parameters: + * ip The ipv4 address to check + * timeout The max timeout of each ping + * retry The retry times of ping + * + * Return: + * nums of remote reply of ping; a nagtive on failure + * + ****************************************************************************/ + +int netlib_check_ipconnectivity(FAR const char *ip, int timeout, int retry) +{ + int replies = 0; +#ifdef CONFIG_NETDB_DNSSERVER_IPv4ADDR + char ip_str[INET_ADDRSTRLEN]; + struct in_addr addr; +#endif + struct ping_info_s info; + + info.count = retry; + info.datalen = PING_IPADDR_DATALEN; + info.delay = 0; + info.timeout = timeout; + info.callback = ping_ipaddr_callback; + info.priv = &replies; + + /* if ip is NULL we use default DNS server */ + + if (ip == NULL) + { +#ifdef CONFIG_NETDB_DNSSERVER_IPv4ADDR + addr.s_addr = HTONL(CONFIG_NETDB_DNSSERVER_IPv4ADDR); + inet_ntop(AF_INET, &addr, ip_str, INET_ADDRSTRLEN); + info.hostname = ip_str; +#else + nerr("ERROR: IP is NULL and no DNS server configured\n"); + return -EINVAL; +#endif + } + else + { + info.hostname = ip; + } + + ninfo("ping ipaddr test %s \n", info.hostname); + icmp_ping(&info); + + return replies; +} + +#endif /* CONFIG_NETUTILS_PING */ \ No newline at end of file From 188838469cc8db044e87f3a1bdfe8a12b9d57bf1 Mon Sep 17 00:00:00 2001 From: buxiasen Date: Mon, 30 Dec 2024 15:02:55 +0800 Subject: [PATCH 075/568] kernel/syscall: fix required INET may case no support We may possible enable socket and no ipv4 Signed-off-by: buxiasen --- testing/testsuites/kernel/syscall/cmocka_syscall_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testing/testsuites/kernel/syscall/cmocka_syscall_test.c b/testing/testsuites/kernel/syscall/cmocka_syscall_test.c index e1fceb592..70b1c592f 100644 --- a/testing/testsuites/kernel/syscall/cmocka_syscall_test.c +++ b/testing/testsuites/kernel/syscall/cmocka_syscall_test.c @@ -161,6 +161,7 @@ int main(int argc, char *argv[]) test_nuttx_syscall_getpeername01, test_nuttx_syscall_test_group_setup, test_nuttx_syscall_test_group_teardown), +# ifdef CONFIG_NET_IPv4 cmocka_unit_test_setup_teardown( test_nuttx_syscall_getsockopt01, test_nuttx_syscall_test_group_setup, @@ -175,6 +176,7 @@ int main(int argc, char *argv[]) test_nuttx_syscall_setsockopt01, test_nuttx_syscall_test_group_setup, test_nuttx_syscall_test_group_teardown), +# endif cmocka_unit_test_setup_teardown( test_nuttx_syscall_listen01, test_nuttx_syscall_test_group_setup, From 157ecb091d617cee84e2b5d7aa2c95af52a4c76c Mon Sep 17 00:00:00 2001 From: buxiasen Date: Thu, 13 Feb 2025 16:07:10 +0800 Subject: [PATCH 076/568] iperf: compatible work with no IPv4 We possible want to use iperf to test rpmsg socket etc. Fix error when enable iperf and no IPv4 ``` arm-none-eabi-ld: warning: ~/nuttx/nuttx has a LOAD segment with RWX permissions arm-none-eabi-ld: ~/nuttx/staging/libapps.a(iperf_main.c.~.apps.netutils.iperf_1.o): in function `iperf_main': ~/apps/netutils/iperf/iperf_main.c:248:(.text.iperf_main+0x330): undefined reference to `inet_ntoa_r' arm-none-eabi-ld: ~/apps/netutils/iperf/iperf_main.c:240:(.text.iperf_main+0x354): undefined reference to `netlib_get_ipv4addr' arm-none-eabi-ld: ~/nuttx/staging/libapps.a(iperf.c.~.apps.netutils.iperf_1.o): in function `iperf_print_addr': ~/apps/netutils/iperf/iperf.c:226:(.text.iperf_print_addr+0x3c): undefined reference to `inet_ntoa' ``` Signed-off-by: buxiasen --- netutils/iperf/iperf.c | 2 ++ netutils/iperf/iperf_main.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/netutils/iperf/iperf.c b/netutils/iperf/iperf.c index b9243a608..97ebf639f 100644 --- a/netutils/iperf/iperf.c +++ b/netutils/iperf/iperf.c @@ -220,6 +220,7 @@ static void iperf_print_addr(FAR const char *str, FAR struct sockaddr *addr) { switch (addr->sa_family) { +#ifdef CONFIG_NET_IPv4 case AF_INET: { FAR struct sockaddr_in *inaddr = (FAR struct sockaddr_in *)addr; @@ -227,6 +228,7 @@ static void iperf_print_addr(FAR const char *str, FAR struct sockaddr *addr) inet_ntoa(inaddr->sin_addr), htons(inaddr->sin_port)); return; } +#endif case AF_LOCAL: { diff --git a/netutils/iperf/iperf_main.c b/netutils/iperf/iperf_main.c index 67ff3855e..b87a122bc 100644 --- a/netutils/iperf/iperf_main.c +++ b/netutils/iperf/iperf_main.c @@ -140,7 +140,10 @@ int main(int argc, FAR char *argv[]) struct iperf_cfg_t cfg; struct in_addr addr; int nerrors; + +#ifdef CONFIG_NET_IPv4 char inetaddr[INET_ADDRSTRLEN]; +#endif bzero(&addr, sizeof(struct in_addr)); bzero(&cfg, sizeof(cfg)); @@ -226,6 +229,7 @@ int main(int argc, FAR char *argv[]) } else { +#ifdef CONFIG_NET_IPv4 if (iperf_args.bind->count > 0) { addr.s_addr = inet_addr(iperf_args.bind->sval[0]); @@ -248,6 +252,10 @@ int main(int argc, FAR char *argv[]) printf(" IP: %s\n", inet_ntoa_r(addr, inetaddr, sizeof(inetaddr))); cfg.sip = addr.s_addr; +#else + printf("ERROR: IPv4 Not Enabled\n"); + goto out; +#endif } if (iperf_args.udp->count == 0) From 4f93ec0a4335d574eeecfd295584fbfb17056e5b Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Wed, 15 Jan 2025 17:08:01 +0800 Subject: [PATCH 077/568] pkt: Set `sll_protocol` for raw socket to `ETH_P_ALL` Ref: https://man7.org/linux/man-pages/man7/packet.7.html We should either set protocal when creating socket or binding, otherwise we cannot capture any packet. Signed-off-by: gaohedong --- examples/netpkt/netpkt_ethercat.c | 5 ++++- system/tcpdump/tcpdump.c | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/netpkt/netpkt_ethercat.c b/examples/netpkt/netpkt_ethercat.c index 8b8ab298a..6ed6ae8d9 100644 --- a/examples/netpkt/netpkt_ethercat.c +++ b/examples/netpkt/netpkt_ethercat.c @@ -30,6 +30,8 @@ #include #include +#include +#include #include #include #include @@ -66,7 +68,7 @@ int main(int argc, FAR const char *argv[]) int num_packets = 0; int len; int ifindex; - int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); + int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sockfd == -1) { @@ -96,6 +98,7 @@ int main(int argc, FAR const char *argv[]) addr.sll_family = AF_PACKET; addr.sll_ifindex = ifindex; + addr.sll_protocol = htons(ETH_P_ALL); if (bind(sockfd, (FAR const struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("ERROR: binding socket failed"); diff --git a/system/tcpdump/tcpdump.c b/system/tcpdump/tcpdump.c index 0220ae8bd..5f80ef510 100644 --- a/system/tcpdump/tcpdump.c +++ b/system/tcpdump/tcpdump.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include #include @@ -201,6 +203,7 @@ static int socket_open(int ifindex) addr.sll_family = AF_PACKET; addr.sll_ifindex = ifindex; + addr.sll_protocol = htons(ETH_P_ALL); if (bind(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("ERROR: binding socket failed"); From ca11a7e0930a0170d2c17e7913cd3fc221e2f6a5 Mon Sep 17 00:00:00 2001 From: Felipe MdeO Date: Thu, 1 Jan 2026 16:46:27 -0300 Subject: [PATCH 078/568] system/smf: Port SMF .c/.h files to NuttX This commit add state machine framework lib to the NuttX project. Also an example is added to help users understand and use this feature. Changes: Added some files. No impact in other features are expected. Adjust SMF macro names Fix issues requested during MR review update kconfig fix ci-cd issue Signed-off-by: Felipe Moura --- examples/smf/CMakeLists.txt | 18 + examples/smf/Kconfig | 37 ++ examples/smf/Make.defs | 25 ++ examples/smf/Makefile | 37 ++ examples/smf/hsm_psicc2_thread.c | 626 +++++++++++++++++++++++++++++++ examples/smf/hsm_psicc2_thread.h | 89 +++++ examples/smf/smf_main.c | 127 +++++++ include/system/smf.h | 267 +++++++++++++ system/smf/Kconfig | 28 ++ system/smf/Make.defs | 25 ++ system/smf/Makefile | 29 ++ system/smf/smf.c | 605 +++++++++++++++++++++++++++++ 12 files changed, 1913 insertions(+) create mode 100644 examples/smf/CMakeLists.txt create mode 100644 examples/smf/Kconfig create mode 100644 examples/smf/Make.defs create mode 100644 examples/smf/Makefile create mode 100644 examples/smf/hsm_psicc2_thread.c create mode 100644 examples/smf/hsm_psicc2_thread.h create mode 100644 examples/smf/smf_main.c create mode 100644 include/system/smf.h create mode 100644 system/smf/Kconfig create mode 100644 system/smf/Make.defs create mode 100644 system/smf/Makefile create mode 100644 system/smf/smf.c diff --git a/examples/smf/CMakeLists.txt b/examples/smf/CMakeLists.txt new file mode 100644 index 000000000..bba48ca02 --- /dev/null +++ b/examples/smf/CMakeLists.txt @@ -0,0 +1,18 @@ +# ############################################################################## +# apps/examples/hsm_psicc2/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## + +if(CONFIG_EXAMPLES_SMF) + nuttx_add_application( + NAME + ${CONFIG_EXAMPLES_SMF_PROGNAME} + SRCS + smf_main.c + hsm_psicc2_thread.c + STACKSIZE + ${CONFIG_EXAMPLES_SMF_STACKSIZE} + PRIORITY + ${CONFIG_EXAMPLES_SMF_PRIORITY}) +endif() diff --git a/examples/smf/Kconfig b/examples/smf/Kconfig new file mode 100644 index 000000000..8d8efc1f7 --- /dev/null +++ b/examples/smf/Kconfig @@ -0,0 +1,37 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_SMF + tristate "State Machine Framework PSICC2 demo (HSM)" + default n + depends on NSH_BUILTIN_APPS + depends on SYSTEM_SMF + depends on SYSTEM_SMF_ANCESTOR_SUPPORT + depends on SYSTEM_SMF_INITIAL_TRANSITION + +if EXAMPLES_SMF + +config EXAMPLES_SMF_PROGNAME + string "Program name" + default "hsm_psicc2" + +config EXAMPLES_SMF_PRIORITY + int "Priority" + default 100 + +config EXAMPLES_SMF_STACKSIZE + int "Stack size" + default 2048 + +config EXAMPLES_SMF_EVENT_QUEUE_SIZE + int "Event queue size" + default 10 + +config EXAMPLES_SMF_MQ_NAME + string "Message queue name" + default "/hsm_psicc2_mq" + +endif + diff --git a/examples/smf/Make.defs b/examples/smf/Make.defs new file mode 100644 index 000000000..00be28079 --- /dev/null +++ b/examples/smf/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/examples/hello/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_SMF),) +CONFIGURED_APPS += $(APPDIR)/examples/smf +endif diff --git a/examples/smf/Makefile b/examples/smf/Makefile new file mode 100644 index 000000000..2fd9309c1 --- /dev/null +++ b/examples/smf/Makefile @@ -0,0 +1,37 @@ +############################################################################ +# apps/examples/hsm_psicc2/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# HSM PSICC2 (SMF demo) built-in application info + +PROGNAME = $(CONFIG_EXAMPLES_SMF_PROGNAME) +PRIORITY = $(CONFIG_EXAMPLES_SMF_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_SMF_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_SMF) + +# HSM PSICC2 Example + +MAINSRC = smf_main.c +CSRCS += hsm_psicc2_thread.c + +include $(APPDIR)/Application.mk diff --git a/examples/smf/hsm_psicc2_thread.c b/examples/smf/hsm_psicc2_thread.c new file mode 100644 index 000000000..e457969e1 --- /dev/null +++ b/examples/smf/hsm_psicc2_thread.c @@ -0,0 +1,626 @@ +/**************************************************************************** + * apps/examples/smf/hsm_psicc2_thread.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Glenn Andrews + * State Machine example copyright (c) Miro Samek + * + * Implementation of the statechart in Figure 2.11 of + * Practical UML Statecharts in C/C++, 2nd Edition by Miro Samek + * https://www.state-machine.com/psicc2 + * Used with permission of the author. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "hsm_psicc2_thread.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct s_object +{ + struct smf_ctx ctx; /* MUST be first (matches SMF_CTX(obj)) */ + struct hsm_psicc2_event event; + int foo; +}; + +enum demo_states +{ + STATE_INITIAL, + STATE_S, + STATE_S1, + STATE_S2, + STATE_S11, + STATE_S21, + STATE_S211 +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct s_object s_obj; +static bool g_started; +static const struct smf_state demo_states[]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * STATE_INITIAL + ****************************************************************************/ + +static void initial_entry(void *o) +{ + struct s_object *obj = (struct s_object *)o; + + printf("[psicc2] %s\n", __func__); + obj->foo = false; +} + +static enum smf_state_result initial_run(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); + return SMF_EVENT_PROPAGATE; +} + +static void initial_exit(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +/**************************************************************************** + * STATE_S + ****************************************************************************/ + +static void s_entry(void *o) +{ + (void)o; + + printf("[psicc2] %s", __func__); +} + +static enum smf_state_result s_run(void *o) +{ + struct s_object *obj = (struct s_object *)o; + + printf("[psicc2] %s\n", __func__); + + switch (obj->event.event_id) + { + case EVENT_E: + printf("[psicc2] %s received EVENT_E", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S11]); + break; + + case EVENT_I: + if (obj->foo) + { + printf("[psicc2] %s received EVENT_I and set foo false\n", + __func__); + obj->foo = false; + } + else + { + printf("[psicc2] %s received EVENT_I and did nothing\n", + __func__); + } + + return SMF_EVENT_HANDLED; + + case EVENT_TERMINATE: + printf("[psicc2] %s received EVENT_TERMINATE. Terminating\n", + __func__); + smf_set_terminate(SMF_CTX(obj), -1); + break; + + default: + break; + } + + return SMF_EVENT_PROPAGATE; +} + +static void s_exit(void *o) +{ + (void)o; + + printf("%s", __func__); +} + +/**************************************************************************** + * STATE_S1 + ****************************************************************************/ + +static void s1_entry(void *o) +{ + (void)o; + + printf("%s", __func__); +} + +static enum smf_state_result s1_run(void *o) +{ + struct s_object *obj = (struct s_object *)o; + + printf("[psicc2] %s\n", __func__); + + switch (obj->event.event_id) + { + case EVENT_A: + printf("[psicc2] %s received EVENT_A\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S1]); + break; + + case EVENT_B: + printf("[psicc2] %s received EVENT_B\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S11]); + break; + + case EVENT_C: + printf("[psicc2] %s received EVENT_C\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S2]); + break; + + case EVENT_D: + if (!obj->foo) + { + printf("[psicc2] %s received EVENT_D and acted on it\n", + __func__); + obj->foo = true; + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S]); + } + else + { + printf("[psicc2] %s received EVENT_D and ignored it\n", + __func__); + } + break; + + case EVENT_F: + printf("[psicc2] %s received EVENT_F\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S211]); + break; + + case EVENT_I: + printf("[psicc2] %s received EVENT_I\n", __func__); + return SMF_EVENT_HANDLED; + + default: + break; + } + + return SMF_EVENT_PROPAGATE; +} + +static void s1_exit(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +/**************************************************************************** + * STATE_S11 + ****************************************************************************/ + +static void s11_entry(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +static enum smf_state_result s11_run(void *o) +{ + struct s_object *obj = (struct s_object *)o; + + printf("[psicc2] %s\n", __func__); + + switch (obj->event.event_id) + { + case EVENT_D: + if (obj->foo) + { + printf("[psicc2] %s received EVENT_D and acted upon it\n", + __func__); + obj->foo = false; + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S1]); + } + else + { + printf("[psicc2] %s received EVENT_D and ignored it\n", + __func__); + } + break; + + case EVENT_G: + printf("[psicc2] %s received EVENT_G\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S21]); + break; + + case EVENT_H: + printf("[psicc2] %s received EVENT_H\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S]); + break; + + default: + break; + } + + return SMF_EVENT_PROPAGATE; +} + +static void s11_exit(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +/**************************************************************************** + * STATE_S2 + ****************************************************************************/ + +static void s2_entry(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +static enum smf_state_result s2_run(void *o) +{ + struct s_object *obj = (struct s_object *)o; + + printf("[psicc2] %s\n", __func__); + + switch (obj->event.event_id) + { + case EVENT_C: + printf("[psicc2] %s received EVENT_C\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S1]); + break; + + case EVENT_F: + printf("[psicc2] %s received EVENT_F\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S11]); + break; + + case EVENT_I: + if (!obj->foo) + { + printf("[psicc2] %s received EVENT_I and set foo true\n", + __func__); + obj->foo = true; + return SMF_EVENT_HANDLED; + } + else + { + printf("[psicc2] %s received EVENT_I and did nothing\n", + __func__); + } + break; + + default: + break; + } + + return SMF_EVENT_PROPAGATE; +} + +static void s2_exit(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +/**************************************************************************** + * STATE_S21 + ****************************************************************************/ + +static void s21_entry(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +static enum smf_state_result s21_run(void *o) +{ + struct s_object *obj = (struct s_object *)o; + + printf("[psicc2] %s\n", __func__); + + switch (obj->event.event_id) + { + case EVENT_A: + printf("[psicc2] %s received EVENT_A\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S21]); + break; + + case EVENT_B: + printf("[psicc2] %s received EVENT_B\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S211]); + break; + + case EVENT_G: + printf("[psicc2] %s received EVENT_G\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S1]); + break; + + default: + break; + } + + return SMF_EVENT_PROPAGATE; +} + +static void s21_exit(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +/**************************************************************************** + * STATE_S211 + ****************************************************************************/ + +static void s211_entry(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +static enum smf_state_result s211_run(void *o) +{ + struct s_object *obj = (struct s_object *)o; + + printf("[psicc2] %s\n", __func__); + + switch (obj->event.event_id) + { + case EVENT_D: + printf("[psicc2] %s received EVENT_D\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S21]); + break; + + case EVENT_H: + printf("[psicc2] %s received EVENT_H\n", __func__); + smf_set_state(SMF_CTX(obj), &demo_states[STATE_S]); + break; + + default: + break; + } + + return SMF_EVENT_PROPAGATE; +} + +static void s211_exit(void *o) +{ + (void)o; + + printf("[psicc2] %s\n", __func__); +} + +/**************************************************************************** + * State Table + ****************************************************************************/ + +static const struct smf_state demo_states[] = +{ + [STATE_INITIAL] = SMF_CREATE_STATE( + initial_entry, + initial_run, + initial_exit, + NULL, + &demo_states[STATE_S2] + ), + [STATE_S] = SMF_CREATE_STATE( + s_entry, + s_run, + s_exit, + &demo_states[STATE_INITIAL], + &demo_states[STATE_S11] + ), + [STATE_S1] = SMF_CREATE_STATE( + s1_entry, + s1_run, + s1_exit, + &demo_states[STATE_S], + &demo_states[STATE_S11] + ), + [STATE_S2] = SMF_CREATE_STATE( + s2_entry, + s2_run, + s2_exit, + &demo_states[STATE_S], + &demo_states[STATE_S211] + ), + [STATE_S11] = SMF_CREATE_STATE( + s11_entry, + s11_run, + s11_exit, + &demo_states[STATE_S1], + NULL + ), + [STATE_S21] = SMF_CREATE_STATE( + s21_entry, + s21_run, + s21_exit, + &demo_states[STATE_S2], + &demo_states[STATE_S211] + ), + [STATE_S211] = SMF_CREATE_STATE( + s211_entry, + s211_run, + s211_exit, + &demo_states[STATE_S21], + NULL + ) +}; + +/**************************************************************************** + * Name: hsm_psicc2_thread_main + ****************************************************************************/ + +static int hsm_psicc2_thread_main(int argc, char **argv) +{ + struct mq_attr attr; + mqd_t mq; + ssize_t n; + int rc; + + (void)argc; + (void)argv; + + memset(&attr, 0, sizeof(attr)); + attr.mq_maxmsg = CONFIG_EXAMPLES_SMF_EVENT_QUEUE_SIZE; + attr.mq_msgsize = sizeof(struct hsm_psicc2_event); + + mq = mq_open(CONFIG_EXAMPLES_SMF_MQ_NAME, O_CREAT | O_RDONLY, 0666, &attr); + if (mq == (mqd_t)-1) + { + printf("psicc2][ERR] mq_open(%s) failed: %d\n", + CONFIG_EXAMPLES_SMF_MQ_NAME, errno); + return -1; + } + + printf("[psicc2] State Machine thread started\n"); + + memset(&s_obj, 0, sizeof(s_obj)); + smf_set_initial(SMF_CTX(&s_obj), &demo_states[STATE_INITIAL]); + + while (true) + { + n = mq_receive(mq, (char *)&s_obj.event, sizeof(s_obj.event), NULL); + if (n < 0) + { + printf("psicc2][ERR] mq_receive failed: %d\n", errno); + continue; + } + + rc = smf_run_state(SMF_CTX(&s_obj)); + if (rc != 0) + { + printf("[psicc2] SMF terminated (rc=%d). Exiting thread\n", rc); + break; + } + } + + mq_close(mq); + mq_unlink(CONFIG_EXAMPLES_SMF_MQ_NAME); + + g_started = false; + memset(&s_obj, 0, sizeof(s_obj)); + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hsm_psicc2_thread_start + ****************************************************************************/ + +int hsm_psicc2_thread_start(void) +{ + int pid; + + if (g_started) + { + return 0; + } + + pid = task_create("psicc2_thread", + CONFIG_EXAMPLES_SMF_PRIORITY, + CONFIG_EXAMPLES_SMF_STACKSIZE, + hsm_psicc2_thread_main, + NULL); + if (pid < 0) + { + printf("psicc2][ERR] task_create failed: %d", errno); + return -1; + } + + g_started = true; + return 0; +} + +/**************************************************************************** + * Name: hsm_psicc2_post_event + ****************************************************************************/ + +int hsm_psicc2_post_event(uint32_t event_id) +{ + struct hsm_psicc2_event ev; + mqd_t mq; + int rc; + + ev.event_id = event_id; + + mq = mq_open(CONFIG_EXAMPLES_SMF_MQ_NAME, O_WRONLY | O_NONBLOCK); + if (mq == (mqd_t)-1) + { + printf("psicc2][ERR] mq_open(O_WRONLY) failed: %d " + "(did you run 'hsm_psicc2 start'?)\n", + errno); + return -1; + } + + rc = mq_send(mq, (const char *)&ev, sizeof(ev), 0); + if (rc < 0) + { + printf("psicc2][ERR] mq_send failed: %d\n", errno); + mq_close(mq); + return -1; + } + + mq_close(mq); + return 0; +} diff --git a/examples/smf/hsm_psicc2_thread.h b/examples/smf/hsm_psicc2_thread.h new file mode 100644 index 000000000..385a29703 --- /dev/null +++ b/examples/smf/hsm_psicc2_thread.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * apps/examples/smf/hsm_psicc2_thread.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Glenn Andrews + * State Machine example copyright (c) Miro Samek + * + * Implementation of the statechart in Figure 2.11 of + * Practical UML Statecharts in C/C++, 2nd Edition by Miro Samek + * https://www.state-machine.com/psicc2 + * Used with permission of the author. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_EXAMPLES_SMF_HSM_PSICC2_THREAD_H +#define __APPS_EXAMPLES_SMF_HSM_PSICC2_THREAD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct hsm_psicc2_event +{ + uint32_t event_id; +}; + +enum demo_events +{ + EVENT_A, + EVENT_B, + EVENT_C, + EVENT_D, + EVENT_E, + EVENT_F, + EVENT_G, + EVENT_H, + EVENT_I, + EVENT_TERMINATE +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int hsm_psicc2_thread_start(void); +int hsm_psicc2_post_event(uint32_t event_id); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_EXAMPLES_SMF_HSM_PSICC2_THREAD_H */ diff --git a/examples/smf/smf_main.c b/examples/smf/smf_main.c new file mode 100644 index 000000000..b6a9677a5 --- /dev/null +++ b/examples/smf/smf_main.c @@ -0,0 +1,127 @@ +/**************************************************************************** + * apps/examples/smf/smf_main.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Glenn Andrews + * State Machine example copyright (c) Miro Samek + * + * Implementation of the statechart in Figure 2.11 of + * Practical UML Statecharts in C/C++, 2nd Edition by Miro Samek + * https://www.state-machine.com/psicc2 + * Used with permission of the author. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "hsm_psicc2_thread.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usage + ****************************************************************************/ + +static void usage(void) +{ + printf("Usage:\n"); + printf(" hsm_psicc2 start\n"); + printf(" hsm_psicc2 event \n"); + printf(" hsm_psicc2 terminate\n"); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: main + ****************************************************************************/ + +int main(int argc, char *argv[]) +{ + if (argc < 2) + { + usage(); + return 1; + } + + if (strcmp(argv[1], "start") == 0) + { + printf("State Machine Framework Demo\n"); + printf("See PSiCC2 Fig 2.11 for the statechart\n"); + printf("https://www.state-machine.com/psicc2\n\n"); + return hsm_psicc2_thread_start(); + } + + if (strcmp(argv[1], "terminate") == 0) + { + return hsm_psicc2_post_event(EVENT_TERMINATE); + } + + if (strcmp(argv[1], "event") == 0) + { + int c; + + if (argc < 3 || argv[2] == NULL || argv[2][0] == '\0') + { + usage(); + return 1; + } + + c = toupper((unsigned char)argv[2][0]); + switch (c) + { + case 'A': + return hsm_psicc2_post_event(EVENT_A); + case 'B': + return hsm_psicc2_post_event(EVENT_B); + case 'C': + return hsm_psicc2_post_event(EVENT_C); + case 'D': + return hsm_psicc2_post_event(EVENT_D); + case 'E': + return hsm_psicc2_post_event(EVENT_E); + case 'F': + return hsm_psicc2_post_event(EVENT_F); + case 'G': + return hsm_psicc2_post_event(EVENT_G); + case 'H': + return hsm_psicc2_post_event(EVENT_H); + case 'I': + return hsm_psicc2_post_event(EVENT_I); + default: + printf("Invalid event '%c'\n", c); + return 1; + } + } + + usage(); + return 1; +} diff --git a/include/system/smf.h b/include/system/smf.h new file mode 100644 index 000000000..edb1bf81b --- /dev/null +++ b/include/system/smf.h @@ -0,0 +1,267 @@ +/**************************************************************************** + * apps/include/system/smf.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_SYSTEM_SMF_H +#define __APPS_INCLUDE_SYSTEM_SMF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT +# ifdef CONFIG_SYSTEM_SMF_INITIAL_TRANSITION +# define SMF_CREATE_STATE(_entry, _run, _exit, _parent, _initial) \ + { \ + .entry = (_entry), \ + .run = (_run), \ + .exit = (_exit), \ + .parent = (_parent), \ + .initial = (_initial), \ + } +# else +# define SMF_CREATE_STATE(_entry, _run, _exit, _parent, _initial) \ + { \ + .entry = (_entry), \ + .run = (_run), \ + .exit = (_exit), \ + .parent = (_parent), \ + } +# endif +#else +# define SMF_CREATE_STATE(_entry, _run, _exit, _parent, _initial) \ + { \ + .entry = (_entry), \ + .run = (_run), \ + .exit = (_exit), \ + } +#endif + +#define SMF_CTX(o) ((struct smf_ctx *)(o)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum smf_state_result +{ + SMF_EVENT_HANDLED, + SMF_EVENT_PROPAGATE +}; + +typedef void (*state_method)(void *obj); + +typedef enum smf_state_result (*state_execution)(void *obj); + +struct smf_state +{ + /* Optional method that will be run when this state is entered. */ + + state_method entry; + + /* Optional method that will be run repeatedly during the state machine + * loop. + */ + + state_execution run; + + /* Optional method that will be run when this state exits. */ + + state_method exit; + +#ifdef CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT + /* Optional parent state that contains common entry/run/exit + * implementation among various child states. + * entry: Parent function executes BEFORE child function. + * run: Parent function executes AFTER child function. + * exit: Parent function executes AFTER child function. + * Note: When transitioning between two child states with a shared + * parent, that parent's exit and entry functions do not execute. + */ + + const struct smf_state *parent; + +# ifdef CONFIG_SYSTEM_SMF_INITIAL_TRANSITION + /* Optional initial transition state. NULL for leaf states. */ + + const struct smf_state *initial; +# endif /* CONFIG_SYSTEM_SMF_INITIAL_TRANSITION */ +#endif /* CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT */ +}; + +struct smf_ctx +{ + /* Current state the state machine is executing. */ + + const struct smf_state *current; + + /* Previous state the state machine executed. */ + + const struct smf_state *previous; + +#ifdef CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT + /* Currently executing state (which may be a parent). */ + + const struct smf_state *executing; +#endif /* CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT */ + + /* This value is set by the set_terminate function and should + * terminate the state machine when its set to a value other than + * zero when it's returned by the run_state function. + */ + + int32_t terminate_val; + + /* The state machine casts this to a "struct internal_ctx" and it's + * used to track state machine context. + */ + + uint32_t internal; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: smf_set_initial + * + * Description: + * Initialize the state machine and set its initial state. + * + * Input Parameters: + * ctx - State machine context + * init_state - Initial state the state machine starts in + * + ****************************************************************************/ + +void smf_set_initial(struct smf_ctx *ctx, + const struct smf_state *init_state); + +/**************************************************************************** + * Name: smf_set_state + * + * Description: + * Change the state machine state. This handles exiting the previous state + * and entering the target state. For HSMs the entry and exit actions of + * the Least Common Ancestor are not run. + * + * Input Parameters: + * ctx - State machine context + * new_state - State to transition to + * + ****************************************************************************/ + +void smf_set_state(struct smf_ctx *ctx, const struct smf_state *new_state); + +/**************************************************************************** + * Name: smf_set_terminate + * + * Description: + * Terminate a state machine. + * + * Input Parameters: + * ctx - State machine context + * val - Non-zero termination value returned by smf_run_state + * + ****************************************************************************/ + +void smf_set_terminate(struct smf_ctx *ctx, int32_t val); + +/**************************************************************************** + * Name: smf_run_state + * + * Description: + * Run one iteration of a state machine (including any parent states). + * + * Input Parameters: + * ctx - State machine context + * + * Returned Value: + * A non-zero value terminates the state machine. This non-zero value may + * represent a terminal state being reached or detection of an error. + * + ****************************************************************************/ + +int32_t smf_run_state(struct smf_ctx *ctx); + +/**************************************************************************** + * Name: smf_get_current_leaf_state + * + * Description: + * Get the current leaf state. This may be a parent state if the HSM is + * malformed (initial transitions are not set up correctly). + * + ****************************************************************************/ + +static inline const struct smf_state * +smf_get_current_leaf_state(const struct smf_ctx *ctx) +{ + return ctx->current; +} + +/**************************************************************************** + * Name: smf_get_current_executing_state + * + * Description: + * Get the state that is currently executing. This may be a parent state. + * + ****************************************************************************/ + +static inline const struct smf_state * +smf_get_current_executing_state(const struct smf_ctx *ctx) +{ +#ifdef CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT + return ctx->executing; +#else + return ctx->current; +#endif /* CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT */ +} + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __APPS_INCLUDE_SYSTEM_SMF_H */ diff --git a/system/smf/Kconfig b/system/smf/Kconfig new file mode 100644 index 000000000..62e52cf56 --- /dev/null +++ b/system/smf/Kconfig @@ -0,0 +1,28 @@ +# SMF (State Machine Framework) configuration options +# +# For syntax reference, see kconfig-language.txt in the NuttX tools repository. + +config SYSTEM_SMF + bool "(SMF) support" + default n + ---help--- + Enables the State Machine Framework (SMF) for implementing state machines + +if SYSTEM_SMF + +config SYSTEM_SMF_ANCESTOR_SUPPORT + bool "Enable ancestor/parent state support" + default n + ---help--- + Enables support for parent/ancestor relationships between SMF states. + Required for hierarchical state machines. + +config SYSTEM_SMF_INITIAL_TRANSITION + bool "Enable initial transition support" + default n + depends on SYSTEM_SMF_ANCESTOR_SUPPORT + ---help--- + Enables support for initial transitions in hierarchical states. + Depends on ancestor/parent state support. + +endif # SYSTEM_SMF diff --git a/system/smf/Make.defs b/system/smf/Make.defs new file mode 100644 index 000000000..d628714f2 --- /dev/null +++ b/system/smf/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/smf/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifeq ($(CONFIG_SYSTEM_SMF),y) +CONFIGURED_APPS += $(APPDIR)/system/smf +endif diff --git a/system/smf/Makefile b/system/smf/Makefile new file mode 100644 index 000000000..d5e1b549c --- /dev/null +++ b/system/smf/Makefile @@ -0,0 +1,29 @@ +############################################################################ +# apps/smf/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# State Machine Framework library + +CSRCS = smf.c + +include $(APPDIR)/Application.mk diff --git a/system/smf/smf.c b/system/smf/smf.c new file mode 100644 index 000000000..473a64e23 --- /dev/null +++ b/system/smf/smf.c @@ -0,0 +1,605 @@ +/**************************************************************************** + * apps/system/smf/smf.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2021 The Chromium OS Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct internal_ctx +{ + bool new_state : 1; + bool terminate : 1; + bool is_exit : 1; + bool handled : 1; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT + +/**************************************************************************** + * Name: is_descendant_of + ****************************************************************************/ + +static bool is_descendant_of(const struct smf_state *test_state, + const struct smf_state *target_state) +{ + const struct smf_state *state; + + for (state = test_state; state != NULL; state = state->parent) + { + if (target_state == state) + { + return true; + } + } + + return false; +} + +/**************************************************************************** + * Name: get_child_of + ****************************************************************************/ + +static const struct smf_state * +get_child_of(const struct smf_state *states, const struct smf_state *parent) +{ + const struct smf_state *state = states; + + while (state != NULL) + { + if (state->parent == parent) + { + return state; + } + + state = state->parent; + } + + return NULL; +} + +/**************************************************************************** + * Name: get_lca_of + * + * Description: + * Find the Least Common Ancestor (LCA) of two states that are not + * ancestors of one another. + * + ****************************************************************************/ + +static const struct smf_state * +get_lca_of(const struct smf_state *source, const struct smf_state *dest) +{ + const struct smf_state *ancestor; + + for (ancestor = source->parent; ancestor != NULL; + ancestor = ancestor->parent) + { + /* First common ancestor. */ + + if (is_descendant_of(dest, ancestor)) + { + return ancestor; + } + } + + return NULL; +} + +/**************************************************************************** + * Name: smf_execute_all_entry_actions + ****************************************************************************/ + +static bool smf_execute_all_entry_actions(struct smf_ctx *const ctx, + const struct smf_state *new_state, + const struct smf_state *topmost) +{ + struct internal_ctx *const internal = (void *)&ctx->internal; + const struct smf_state *to_execute; + + if (new_state == topmost) + { + /* There are no child states, so do nothing. */ + + return false; + } + + for (to_execute = get_child_of(new_state, topmost); + to_execute != NULL && to_execute != new_state; + to_execute = get_child_of(new_state, to_execute)) + { + /* Keep track of the executing entry action in case it calls + * smf_set_state(). + */ + + ctx->executing = to_execute; + + /* Execute every entry action EXCEPT that of the topmost state. */ + + if (to_execute->entry != NULL) + { + to_execute->entry(ctx); + + /* No need to continue if terminate was set. */ + + if (internal->terminate) + { + ctx->executing = ctx->current; + return true; + } + } + } + + /* Execute the new state entry action. */ + + ctx->executing = new_state; + if (new_state->entry != NULL) + { + new_state->entry(ctx); + + /* No need to continue if terminate was set. */ + + if (internal->terminate) + { + ctx->executing = ctx->current; + return true; + } + } + + ctx->executing = ctx->current; + + return false; +} + +/**************************************************************************** + * Name: smf_execute_ancestor_run_actions + ****************************************************************************/ + +static bool smf_execute_ancestor_run_actions(struct smf_ctx *const ctx) +{ + struct internal_ctx *const internal = (void *)&ctx->internal; + const struct smf_state *tmp_state; + + /* Execute all run actions in reverse order. */ + + if (internal->terminate) + { + /* Return if the current state terminated. */ + + return true; + } + + if (internal->new_state || internal->handled) + { + /* The child state transitioned or handled it. Stop propagating. */ + + return false; + } + + /* Try to run parent run actions. */ + + for (tmp_state = ctx->current->parent; tmp_state != NULL; + tmp_state = tmp_state->parent) + { + enum smf_state_result rc; + + /* Keep track of where we are in case an ancestor calls + * smf_set_state(). + */ + + ctx->executing = tmp_state; + + /* Execute parent run action. */ + + if (tmp_state->run != NULL) + { + rc = tmp_state->run(ctx); + + if (rc == SMF_EVENT_HANDLED) + { + internal->handled = true; + } + + /* No need to continue if terminate was set. */ + + if (internal->terminate) + { + ctx->executing = ctx->current; + return true; + } + + /* This state dealt with it. Stop propagating. */ + + if (internal->new_state || internal->handled) + { + break; + } + } + } + + /* All done executing the run actions. */ + + ctx->executing = ctx->current; + + return false; +} + +/**************************************************************************** + * Name: smf_execute_all_exit_actions + ****************************************************************************/ + +static bool smf_execute_all_exit_actions(struct smf_ctx *const ctx, + const struct smf_state *topmost) +{ + struct internal_ctx *const internal = (void *)&ctx->internal; + const struct smf_state *tmp_state; + const struct smf_state *to_execute; + + tmp_state = ctx->executing; + + for (to_execute = ctx->current; + to_execute != NULL && to_execute != topmost; + to_execute = to_execute->parent) + { + if (to_execute->exit != NULL) + { + ctx->executing = to_execute; + to_execute->exit(ctx); + + /* No need to continue if terminate was set in the exit action. */ + + if (internal->terminate) + { + ctx->executing = tmp_state; + return true; + } + } + } + + ctx->executing = tmp_state; + + return false; +} + +#endif /* CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT */ + +/**************************************************************************** + * Name: smf_clear_internal_state + ****************************************************************************/ + +static void smf_clear_internal_state(struct smf_ctx *const ctx) +{ + struct internal_ctx *const internal = (void *)&ctx->internal; + + internal->is_exit = false; + internal->terminate = false; + internal->handled = false; + internal->new_state = false; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: smf_set_initial + ****************************************************************************/ + +void smf_set_initial(struct smf_ctx *const ctx, + const struct smf_state *init_state) +{ +#ifdef CONFIG_SYSTEM_SMF_INITIAL_TRANSITION + /* The final target will be the deepest leaf state that the target + * contains. Set that as the real target. + */ + + while (init_state->initial != NULL) + { + init_state = init_state->initial; + } +#endif + + smf_clear_internal_state(ctx); + ctx->current = init_state; + ctx->previous = NULL; + ctx->terminate_val = 0; + +#ifdef CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT + struct internal_ctx *const internal = (void *)&ctx->internal; + const struct smf_state *topmost; + + ctx->executing = init_state; + + /* topmost is the root ancestor of init_state, its parent == NULL. */ + + topmost = get_child_of(init_state, NULL); + + /* Execute topmost state entry action, + * since smf_execute_all_entry_actions doesn't. + */ + + if (topmost->entry != NULL) + { + ctx->executing = topmost; + topmost->entry(ctx); + ctx->executing = init_state; + + if (internal->terminate) + { + /* No need to continue if terminate was set. */ + + return; + } + } + + if (smf_execute_all_entry_actions(ctx, init_state, topmost)) + { + /* No need to continue if terminate was set. */ + + return; + } +#else + /* Execute entry action if it exists. */ + + if (init_state->entry != NULL) + { + init_state->entry(ctx); + } +#endif +} + +/**************************************************************************** + * Name: smf_set_state + ****************************************************************************/ + +void smf_set_state(struct smf_ctx *const ctx, + const struct smf_state *new_state) +{ + struct internal_ctx *const internal = (void *)&ctx->internal; + + if (new_state == NULL) + { + printf("SMF ERR: new_state cannot be NULL\n"); + return; + } + + /* It does not make sense to call smf_set_state in an exit phase of a + * state since we are already in a transition; we would always ignore + * the intended state to transition into. + */ + + if (internal->is_exit) + { + printf("SMF ERR: Calling %s from exit action\n", __func__); + return; + } + +#ifdef CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT + const struct smf_state *topmost; + + if (ctx->executing != new_state && + ctx->executing->parent == new_state->parent) + { + /* Optimize sibling transitions (different states under same parent). */ + + topmost = ctx->executing->parent; + } + else if (is_descendant_of(ctx->executing, new_state)) + { + /* New state is a parent of where we are now. */ + + topmost = new_state; + } + else if (is_descendant_of(new_state, ctx->executing)) + { + /* We are a parent of the new state. */ + + topmost = ctx->executing; + } + else + { + /* Not directly related, find LCA. */ + + topmost = get_lca_of(ctx->executing, new_state); + } + + internal->is_exit = true; + internal->new_state = true; + + /* Call all exit actions up to (but not including) the topmost. */ + + if (smf_execute_all_exit_actions(ctx, topmost)) + { + /* No need to continue if terminate was set in the exit action. */ + + return; + } + + /* If self-transition, call the exit action. */ + + if (ctx->executing == new_state && new_state->exit != NULL) + { + new_state->exit(ctx); + + /* No need to continue if terminate was set in the exit action. */ + + if (internal->terminate) + { + return; + } + } + + internal->is_exit = false; + + /* If self transition, call the entry action. */ + + if (ctx->executing == new_state && new_state->entry != NULL) + { + new_state->entry(ctx); + + /* No need to continue if terminate was set in the entry action. */ + + if (internal->terminate) + { + return; + } + } + +#ifdef CONFIG_SYSTEM_SMF_INITIAL_TRANSITION + /* The final target will be the deepest leaf state that the target + * contains. Set that as the real target. + */ + + while (new_state->initial != NULL) + { + new_state = new_state->initial; + } +#endif + + /* Update the state variables. */ + + ctx->previous = ctx->current; + ctx->current = new_state; + ctx->executing = new_state; + + /* Call all entry actions (except those of topmost). */ + + if (smf_execute_all_entry_actions(ctx, new_state, topmost)) + { + /* No need to continue if terminate was set in the entry action. */ + + return; + } +#else + /* Flat state machines have a very simple transition. */ + + if (ctx->current->exit != NULL) + { + internal->is_exit = true; + ctx->current->exit(ctx); + + /* No need to continue if terminate was set in the exit action. */ + + if (internal->terminate) + { + return; + } + + internal->is_exit = false; + } + + /* Update the state variables. */ + + ctx->previous = ctx->current; + ctx->current = new_state; + + if (ctx->current->entry != NULL) + { + ctx->current->entry(ctx); + + /* No need to continue if terminate was set in the entry action. */ + + if (internal->terminate) + { + return; + } + } +#endif +} + +/**************************************************************************** + * Name: smf_set_terminate + ****************************************************************************/ + +void smf_set_terminate(struct smf_ctx *const ctx, int32_t val) +{ + struct internal_ctx *const internal = (void *)&ctx->internal; + + internal->terminate = true; + ctx->terminate_val = val; +} + +/**************************************************************************** + * Name: smf_run_state + ****************************************************************************/ + +int32_t smf_run_state(struct smf_ctx *const ctx) +{ + struct internal_ctx *const internal = (void *)&ctx->internal; + + /* No need to continue if terminate was set. */ + + if (internal->terminate) + { + return ctx->terminate_val; + } + + /* Executing a state's run function could cause a transition, so clear + * the internal state to ensure that the transition is handled correctly. + */ + + smf_clear_internal_state(ctx); + +#ifdef CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT + ctx->executing = ctx->current; + + if (ctx->current->run != NULL) + { + enum smf_state_result rc; + + rc = ctx->current->run(ctx); + if (rc == SMF_EVENT_HANDLED) + { + internal->handled = true; + } + } + + if (smf_execute_ancestor_run_actions(ctx)) + { + return ctx->terminate_val; + } +#else + if (ctx->current->run != NULL) + { + ctx->current->run(ctx); + } +#endif + + return 0; +} From 73bc5cbcc61e3a887a6af4c17e7c9a86eef737eb Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Thu, 25 Dec 2025 14:37:31 +0800 Subject: [PATCH 079/568] interpreters: Add mquickjs JavaScript interpreter integration Add complete integration for the MicroQuickJS JavaScript interpreter, supporting both CMake and Make build systems with automatic source acquisition. Key features: * FetchContent downloads mquickjs from bellard/mquickjs if local git repository is not available in interpreters/mquickjs/mquickjs/ * Builds mqjs_stdlib host tool to generate mqjs_stdlib.h and mquickjs_atom.h headers during build * Creates libmquickjs library with proper header generation dependencies to prevent parallel build failures * Provides mqjs NSH application for interactive JavaScript execution * Configurable task priority and stack size via Kconfig options (INTERPRETERS_MQJS_PRIORITY, INTERPRETERS_MQJS_STACKSIZE) * Supports both 32-bit and 64-bit architectures with appropriate build flags Files added: * CMakeLists.txt - CMake build configuration with FetchContent support * Kconfig - Configuration options for interpreter features * Make.defs - Make build definitions * Makefile - Alternative Make-based build support * .gitignore - Ignores generated files and local mquickjs source directory Signed-off-by: Huang Qi --- interpreters/mquickjs/.gitignore | 2 + interpreters/mquickjs/CMakeLists.txt | 123 +++++++++++++++++++++++++++ interpreters/mquickjs/Kconfig | 24 ++++++ interpreters/mquickjs/Make.defs | 30 +++++++ interpreters/mquickjs/Makefile | 92 ++++++++++++++++++++ 5 files changed, 271 insertions(+) create mode 100644 interpreters/mquickjs/.gitignore create mode 100644 interpreters/mquickjs/CMakeLists.txt create mode 100644 interpreters/mquickjs/Kconfig create mode 100644 interpreters/mquickjs/Make.defs create mode 100644 interpreters/mquickjs/Makefile diff --git a/interpreters/mquickjs/.gitignore b/interpreters/mquickjs/.gitignore new file mode 100644 index 000000000..87708e7fd --- /dev/null +++ b/interpreters/mquickjs/.gitignore @@ -0,0 +1,2 @@ +*.d +mquickjs/ diff --git a/interpreters/mquickjs/CMakeLists.txt b/interpreters/mquickjs/CMakeLists.txt new file mode 100644 index 000000000..51d505860 --- /dev/null +++ b/interpreters/mquickjs/CMakeLists.txt @@ -0,0 +1,123 @@ +# ############################################################################## +# apps/interpreters/mquickjs/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_INTERPRETERS_MQJS) + set(MQJS_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/mquickjs) + + # Prefer local git repo if it exists, otherwise download tarball + if(EXISTS ${MQJS_SOURCE_DIR}/.git) + # Use local git-managed mquickjs + set(MQJS_DIR ${MQJS_SOURCE_DIR}) + message(STATUS "Using local mquickjs git repo: ${MQJS_DIR}") + else() + # Download mquickjs to build directory + FetchContent_Declare( + mquickjs_fetch + URL https://github.com/bellard/mquickjs/archive/refs/heads/main.zip + DOWNLOAD_NO_PROGRESS true + TIMEOUT 30) + + FetchContent_MakeAvailable(mquickjs_fetch) + + # The source directory after FetchContent_MakeAvailable + set(MQJS_DIR ${mquickjs_fetch_SOURCE_DIR}) + message(STATUS "Using downloaded mquickjs: ${MQJS_DIR}") + endif() + + # Detect target architecture for header generation + if(CONFIG_ARCH_64BIT) + set(MQJS_BUILD_FLAGS "-m64") + else() + set(MQJS_BUILD_FLAGS "-m32") + endif() + + include(ExternalProject) + + # Build mqjs_stdlib host tool using mquickjs Makefile + ExternalProject_Add( + mqjs_stdlib_host + SOURCE_DIR ${MQJS_DIR} + BINARY_DIR ${MQJS_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND make mqjs_stdlib + INSTALL_COMMAND "" + BUILD_BYPRODUCTS ${MQJS_DIR}/mqjs_stdlib) + + # Generate mqjs_stdlib.h + add_custom_command( + OUTPUT ${MQJS_DIR}/mqjs_stdlib.h + COMMAND ${MQJS_DIR}/mqjs_stdlib ${MQJS_BUILD_FLAGS} > + ${MQJS_DIR}/mqjs_stdlib.h + DEPENDS mqjs_stdlib_host + COMMENT "Generating mqjs_stdlib.h") + + # Generate mquickjs_atom.h + add_custom_command( + OUTPUT ${MQJS_DIR}/mquickjs_atom.h + COMMAND ${MQJS_DIR}/mqjs_stdlib -a ${MQJS_BUILD_FLAGS} > + ${MQJS_DIR}/mquickjs_atom.h + DEPENDS mqjs_stdlib_host + COMMENT "Generating mquickjs_atom.h") + + # Custom target for header generation + add_custom_target(mqjs_headers_gen DEPENDS ${MQJS_DIR}/mqjs_stdlib.h + ${MQJS_DIR}/mquickjs_atom.h) + + # Create mquickjs library + nuttx_add_library(libmquickjs) + target_sources( + libmquickjs + PRIVATE ${MQJS_DIR}/mquickjs.c ${MQJS_DIR}/dtoa.c ${MQJS_DIR}/libm.c + ${MQJS_DIR}/cutils.c ${MQJS_DIR}/readline.c + ${MQJS_DIR}/readline_tty.c) + target_include_directories(libmquickjs PRIVATE ${MQJS_DIR}) + nuttx_export_header(TARGET libmquickjs INCLUDE_DIRECTORIES ${MQJS_DIR}) + + # Ensure headers are generated before building library + add_dependencies(libmquickjs mqjs_headers_gen) + + # Add mquickjs include directory to global include paths + set_property( + TARGET nuttx + APPEND + PROPERTY NUTTX_INCLUDE_DIRECTORIES ${NUTTX_APPS_DIR}/interpreters/mquickjs) + + # Create mqjs NSH application + set(MQJS_PRIORITY ${CONFIG_INTERPRETERS_MQJS_PRIORITY}) + set(MQJS_STACKSIZE ${CONFIG_INTERPRETERS_MQJS_STACKSIZE}) + + nuttx_add_application( + NAME + mqjs + PRIORITY + ${MQJS_PRIORITY} + STACKSIZE + ${MQJS_STACKSIZE} + SRCS + ${MQJS_DIR}/mqjs.c + INCLUDE_DIRECTORIES + ${MQJS_DIR} + DEPENDS + libmquickjs + mqjs_headers_gen) + +endif() diff --git a/interpreters/mquickjs/Kconfig b/interpreters/mquickjs/Kconfig new file mode 100644 index 000000000..06e8906b7 --- /dev/null +++ b/interpreters/mquickjs/Kconfig @@ -0,0 +1,24 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config INTERPRETERS_MQJS + tristate "MicroQuickJS JavaScript interpreter" + default n + +if INTERPRETERS_MQJS + +config INTERPRETERS_MQJS_PRIORITY + int "MicroQuickJS interpreter priority" + default 100 + ---help--- + Task priority of the MicroQuickJS interpreter. + + config INTERPRETERS_MQJS_STACKSIZE + int "MicroQuickJS interpreter stack size" + default 8192 + ---help--- + Size of the stack allocated for MicroQuickJS interpreter. + + endif # INTERPRETERS_MQJS diff --git a/interpreters/mquickjs/Make.defs b/interpreters/mquickjs/Make.defs new file mode 100644 index 000000000..8850fa7b6 --- /dev/null +++ b/interpreters/mquickjs/Make.defs @@ -0,0 +1,30 @@ +############################################################################ +# apps/interpreters/mquickjs/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_INTERPRETERS_MQJS),) +CONFIGURED_APPS += $(APPDIR)/interpreters/mquickjs + +# It allows `` import. +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/interpreters/mquickjs/mquickjs +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/interpreters/mquickjs/mquickjs + +endif diff --git a/interpreters/mquickjs/Makefile b/interpreters/mquickjs/Makefile new file mode 100644 index 000000000..2c1ed3e49 --- /dev/null +++ b/interpreters/mquickjs/Makefile @@ -0,0 +1,92 @@ +############################################################################ +# apps/interpreters/mquickjs/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +MQJS_UNPACK = mquickjs +MQJS_ARCHIVE = mquickjs-master.zip +MQJS_URL = https://github.com/bellard/mquickjs/archive/refs/heads/master.zip + +# Determine target word size for header generation +ifeq ($(CONFIG_ARCH_64BIT),y) +MQJS_BUILD_FLAGS = -m64 +else +MQJS_BUILD_FLAGS = -m32 +endif + +CSRCS = $(MQJS_UNPACK)/mquickjs.c \ + $(MQJS_UNPACK)/dtoa.c \ + $(MQJS_UNPACK)/libm.c \ + $(MQJS_UNPACK)/cutils.c \ + $(MQJS_UNPACK)/readline.c \ + $(MQJS_UNPACK)/readline_tty.c + +PROGNAME = mqjs +PRIORITY = $(CONFIG_INTERPRETERS_MQJS_PRIORITY) +STACKSIZE = $(CONFIG_INTERPRETERS_MQJS_STACKSIZE) +MODULE = $(CONFIG_INTERPRETERS_MQJS) +MAINSRC = $(MQJS_UNPACK)/mqjs.c + +# Download archive +$(MQJS_ARCHIVE): + $(Q) echo "Downloading $(MQJS_ARCHIVE)" + $(Q) curl -L $(MQJS_URL) -o $(MQJS_ARCHIVE) + +# Unpack archive +$(MQJS_UNPACK): $(MQJS_ARCHIVE) + $(Q) echo "Unpacking $(MQJS_ARCHIVE) to $(MQJS_UNPACK)" + $(Q) unzip -q -o $(MQJS_ARCHIVE) + $(Q) mv bellard-mquickjs-* $(MQJS_UNPACK) + $(Q) touch $(MQJS_UNPACK) + +# Build host tool via upstream Makefile +$(MQJS_UNPACK)/mqjs_stdlib: + $(Q) echo "Building mquickjs host tool via upstream Makefile" + $(Q) rm -f $(MQJS_UNPACK)/mqjs_stdlib + $(Q) $(MAKE) -C $(MQJS_UNPACK) HOSTCC=$(HOSTCC) mqjs_stdlib + +# Generate stdlib header using built host tool +$(MQJS_UNPACK)/mqjs_stdlib.h: $(MQJS_UNPACK)/mqjs_stdlib + $(Q) echo "Generating mquickjs stdlib header" + $(MQJS_UNPACK)/mqjs_stdlib $(MQJS_BUILD_FLAGS) > $@ + +# Generate atom header using built host tool +$(MQJS_UNPACK)/mquickjs_atom.h: $(MQJS_UNPACK)/mqjs_stdlib + $(Q) echo "Generating mquickjs atom header" + $(MQJS_UNPACK)/mqjs_stdlib -a $(MQJS_BUILD_FLAGS) > $@ + +# Download and unpack only if not a git repository +context:: $(MQJS_UNPACK)/mqjs_stdlib.h $(MQJS_UNPACK)/mquickjs_atom.h + +# Clean up on distclean +distclean:: +ifneq ($(wildcard $(MQJS_UNPACK)/.git),) + $(Q) $(MAKE) -C $(MQJS_UNPACK) clean +else + $(call DELDIR, $(MQJS_UNPACK)) +endif + $(call DELFILE, $(MQJS_ARCHIVE)) + +# Dependencies +$(MQJS_UNPACK)/mquickjs.c: $(MQJS_UNPACK)/mquickjs_atom.h + +include $(APPDIR)/Application.mk From 416c315f928110b37f9b7a362f4dd2f2d89b0cac Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Tue, 6 Jan 2026 12:16:22 +0800 Subject: [PATCH 080/568] ostest: sync hrtimer ostest with hrtimer updates Update the hrtimer ostest to reflect recent changes in the hrtimer implementation. Signed-off-by: Chengdong Wang --- testing/ostest/hrtimer.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index 9b2d61430..fcbe1f5d9 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -120,19 +120,23 @@ static void hrtimer_test_init(FAR struct hrtimer_test_s *hrtimer_test, * * Input Parameters: * hrtimer - Pointer to the expired HRTimer instance + * expired - The expired value of hrtimer * * Returned Value: * Timer period in nanoseconds (NSEC_PER_50MS) * ****************************************************************************/ -static uint32_t test_hrtimer_callback(FAR hrtimer_t *hrtimer) +static uint64_t +test_hrtimer_callback(FAR hrtimer_t *hrtimer, uint64_t expired) { struct timespec ts; uint32_t diff; uint64_t now; int ret; + UNUSED(expired); + FAR struct hrtimer_test_s *test = (FAR struct hrtimer_test_s *)hrtimer; @@ -207,9 +211,7 @@ void hrtimer_test(void) /* Initialize the high-resolution timer */ - hrtimer_init(&hrtimer_test.timer, - test_hrtimer_callback, - NULL); + hrtimer_init(&hrtimer_test.timer, test_hrtimer_callback); /* Start the timer with 500ms relative timeout */ From 1512f9c6e55efc4c43d2ddb1f02445304fbdee9b Mon Sep 17 00:00:00 2001 From: buxiasen Date: Thu, 10 Jul 2025 17:10:55 +0800 Subject: [PATCH 081/568] netlib/ping: fix the stack variable not initialized. We add devname in ping_info_s, but not initializeed, cause data abort as value in stack possible not NULL. Signed-off-by: buxiasen --- netutils/netlib/netlib_checkipconnectivity.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/netutils/netlib/netlib_checkipconnectivity.c b/netutils/netlib/netlib_checkipconnectivity.c index 145c987ff..44a5c636a 100644 --- a/netutils/netlib/netlib_checkipconnectivity.c +++ b/netutils/netlib/netlib_checkipconnectivity.c @@ -107,6 +107,9 @@ int netlib_check_ipconnectivity(FAR const char *ip, int timeout, int retry) info.timeout = timeout; info.callback = ping_ipaddr_callback; info.priv = &replies; +#ifdef CONFIG_NET_BINDTODEVICE + info.devname = NULL; +#endif /* if ip is NULL we use default DNS server */ From 9c4103d496fb5ab6324906e19c98ab16976cf390 Mon Sep 17 00:00:00 2001 From: mazhuang Date: Wed, 23 Oct 2024 15:35:57 +0800 Subject: [PATCH 082/568] nsh_syscmds/rpmsg: add rpmsg test command support User can use rpmsg test /dev/rpmsg/ to test the rpmsg channel Signed-off-by: mazhuang --- nshlib/nsh_command.c | 2 +- nshlib/nsh_syscmds.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 2f05557cb..629949753 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -535,7 +535,7 @@ static const struct cmdmap_s g_cmdmap[] = #if defined(CONFIG_RPTUN) && !defined(CONFIG_NSH_DISABLE_RPTUN) CMD_MAP("rptun", cmd_rptun, 2, 7, - " " + " " " [value|times length ack sleep]"), #endif diff --git a/nshlib/nsh_syscmds.c b/nshlib/nsh_syscmds.c index 3541156ef..88db8c913 100644 --- a/nshlib/nsh_syscmds.c +++ b/nshlib/nsh_syscmds.c @@ -591,6 +591,12 @@ static int cmd_rpmsg_once(FAR struct nsh_vtbl_s *vtbl, cmd = RPMSGIOC_PING; val = (unsigned long)&ping; } +#endif +#ifdef CONFIG_RPMSG_TEST + else if (strcmp(argv[1], "test") == 0) + { + cmd = RPMSGIOC_TEST; + } #endif else if (rpmsg_cb && rpmsg_cb(&cmd, &val, argv) == OK) { @@ -642,7 +648,7 @@ static int cmd_rpmsg_recursive(FAR struct nsh_vtbl_s *vtbl, static int cmd_rpmsg_help(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { - nsh_output(vtbl, "%s \n", argv[0]); + nsh_output(vtbl, "%s \n", argv[0]); #ifdef CONFIG_RPMSG_PING nsh_output(vtbl, "%s ping " "\n\n", argv[0]); From ae7c168bf601bcf8cc98d8c31f14b7c50e2dec25 Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Tue, 7 Jan 2025 18:02:39 +0800 Subject: [PATCH 083/568] nshlib: Add vconfig command Add vconfig command Signed-off-by: gaohedong --- nshlib/Kconfig | 4 ++++ nshlib/nsh.h | 3 +++ nshlib/nsh_command.c | 4 ++++ nshlib/nsh_netcmds.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/nshlib/Kconfig b/nshlib/Kconfig index 7fd49bbc7..b9a510383 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -423,6 +423,10 @@ config NSH_DISABLE_IFCONFIG bool "Disable ifconfig" default DEFAULT_SMALL || !FS_PROCFS || FS_PROCFS_EXCLUDE_NET +config NSH_DISABLE_VCONFIG + bool "Disable vconfig" + default DEFAULT_SMALL || !FS_PROCFS || FS_PROCFS_EXCLUDE_NET + config NSH_DISABLE_IFUPDOWN bool "Disable ifup/down" default DEFAULT_SMALL || !FS_PROCFS || FS_PROCFS_EXCLUDE_NET diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 8d037f517..9c2c1d5ed 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -1093,6 +1093,9 @@ int cmd_irqinfo(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); # ifndef CONFIG_NSH_DISABLE_IFCONFIG int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); # endif +# ifndef CONFIG_NSH_DISABLE_VCONFIG + int cmd_vconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); +# endif # ifndef CONFIG_NSH_DISABLE_IFUPDOWN int cmd_ifup(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); int cmd_ifdown(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 629949753..1474b824c 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -286,6 +286,10 @@ static const struct cmdmap_s g_cmdmap[] = "[dr|gw|gateway ] [netmask |prefixlen ] " "[dns ] [hw ]"), # endif +# if defined(CONFIG_NET_VLAN) && !defined(CONFIG_NSH_DISABLE_VCONFIG) + CMD_MAP("vconfig", cmd_vconfig, 3, 4, + "[add iface-name vlan-id]|[rem vlan-name]"), +# endif # ifndef CONFIG_NSH_DISABLE_IFUPDOWN CMD_MAP("ifdown", cmd_ifdown, 2, 2, ""), CMD_MAP("ifup", cmd_ifup, 2, 2, ""), diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 1b2c8efd7..233231a95 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -1097,6 +1097,53 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) } #endif +/**************************************************************************** + * Name: cmd_vconfig + ****************************************************************************/ + +#if defined(CONFIG_NET_VLAN) && !defined(CONFIG_NSH_DISABLE_VCONFIG) +int cmd_vconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) +{ + DEBUGASSERT(argc >= 2); + + if (!strcmp(argv[1], "add")) + { + if (argc != 4) + { + nsh_error(vtbl, g_fmtargrequired, argv[0]); + return ERROR; + } + + if (netlib_add_vlan(argv[2], atoi(argv[3])) < 0) + { + perror("Failed to add VLAN"); + return ERROR; + } + } + else if (!strcmp(argv[1], "rem") || !strcmp(argv[1], "del")) + { + if (argc != 3) + { + nsh_error(vtbl, g_fmtargrequired, argv[0]); + return ERROR; + } + + if (netlib_del_vlan(argv[2]) < 0) + { + perror("Failed to remove VLAN"); + return ERROR; + } + } + else + { + nsh_error(vtbl, g_fmtarginvalid, argv[1]); + return ERROR; + } + + return OK; +} +#endif + /**************************************************************************** * Name: cmd_nslookup ****************************************************************************/ From 10eae1dc6bbee24a905a48e5ef0b14c141fa5adb Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Fri, 7 Feb 2025 14:46:46 +0800 Subject: [PATCH 084/568] vconfig: Support setting default PCP when creating VLAN Now we allow setting a default PCP when creating VLAN like: `vconfig add iface-name vlan-id [pcp]` e.g. `vconfig add eth0 10` will create eth0.10 with VID=10 and no PCP(0) `vconfig add eth0 10 3` will create eth0.10 with VID=10 and PCP=3 Signed-off-by: Zhe Weng --- include/netutils/netlib.h | 2 +- nshlib/nsh_command.c | 4 ++-- nshlib/nsh_netcmds.c | 11 +++++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index a751ed60b..5be9747b2 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -330,7 +330,7 @@ int netlib_setessid(FAR const char *ifname, FAR const char *essid); #endif #ifdef CONFIG_NET_VLAN -int netlib_add_vlan(FAR const char *ifname, int vlanid); +int netlib_add_vlan(FAR const char *ifname, int vlanid, int prio); int netlib_del_vlan(FAR const char *vlanif); #endif diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 1474b824c..03a14ace9 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -287,8 +287,8 @@ static const struct cmdmap_s g_cmdmap[] = "[dns ] [hw ]"), # endif # if defined(CONFIG_NET_VLAN) && !defined(CONFIG_NSH_DISABLE_VCONFIG) - CMD_MAP("vconfig", cmd_vconfig, 3, 4, - "[add iface-name vlan-id]|[rem vlan-name]"), + CMD_MAP("vconfig", cmd_vconfig, 3, 5, + "[add iface-name vlan-id [pcp]]|[rem vlan-name]"), # endif # ifndef CONFIG_NSH_DISABLE_IFUPDOWN CMD_MAP("ifdown", cmd_ifdown, 2, 2, ""), diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 233231a95..6010e1084 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -1108,13 +1108,20 @@ int cmd_vconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) if (!strcmp(argv[1], "add")) { - if (argc != 4) + int prio = 0; + + if (argc != 4 && argc != 5) { nsh_error(vtbl, g_fmtargrequired, argv[0]); return ERROR; } - if (netlib_add_vlan(argv[2], atoi(argv[3])) < 0) + if (argc == 5) + { + prio = atoi(argv[4]); + } + + if (netlib_add_vlan(argv[2], atoi(argv[3]), prio) < 0) { perror("Failed to add VLAN"); return ERROR; From c61fb846d7cefc43d52066db00bec756e99e70a6 Mon Sep 17 00:00:00 2001 From: meijian Date: Thu, 10 Oct 2024 16:34:10 +0800 Subject: [PATCH 085/568] apps/net: add if network conntivity check API Perform connectivity testing on the specified network interface card. Signed-off-by: meijian --- include/netutils/netlib.h | 2 + netutils/netlib/CMakeLists.txt | 2 +- netutils/netlib/Makefile | 2 +- netutils/netlib/netlib_checkifconnectivity.c | 89 ++++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 netutils/netlib/netlib_checkifconnectivity.c diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 5be9747b2..2e7f7bc60 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -515,6 +515,8 @@ int netlib_check_ifconflict(FAR const char *ifname); #ifdef CONFIG_NETUTILS_PING int netlib_check_ipconnectivity(FAR const char *ip, int timeout, int retry); +int netlib_check_ifconnectivity(FAR const char *ifname, + int timeout, int retry); #endif #ifdef CONFIG_MM_IOB diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt index 632b32857..be87f33fa 100644 --- a/netutils/netlib/CMakeLists.txt +++ b/netutils/netlib/CMakeLists.txt @@ -158,7 +158,7 @@ if(CONFIG_NETUTILS_NETLIB) endif() if(CONFIG_NETUTILS_PING) - list(APPEND SRCS netlib_checkipconnectivity.c) + list(APPEND SRCS netlib_checkipconnectivity.c netlib_checkifconnectivity.c) endif() target_sources(apps PRIVATE ${SRCS}) diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index 0de8c07e5..a55340c1f 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -157,7 +157,7 @@ CSRCS += netlib_getiobinfo.c endif ifeq ($(CONFIG_NETUTILS_PING),y) -CSRCS += netlib_checkipconnectivity.c +CSRCS += netlib_checkipconnectivity.c netlib_checkifconnectivity.c endif include $(APPDIR)/Application.mk diff --git a/netutils/netlib/netlib_checkifconnectivity.c b/netutils/netlib/netlib_checkifconnectivity.c new file mode 100644 index 000000000..c08995366 --- /dev/null +++ b/netutils/netlib/netlib_checkifconnectivity.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * apps/netutils/netlib/netlib_checkifconnectivity.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "netutils/netlib.h" + +#ifdef CONFIG_NETUTILS_PING + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netlib_check_ifconnectivity + * + * Description: + * Check network interface connectivity by pinging the gateway + * + * Parameters: + * ifname The name of the interface to use + * timeout The timeout of ping + * retry The retry times of ping + * + * Return: + * nums of gateway reply of ping; a nagtive on failure. + * + ****************************************************************************/ + +int netlib_check_ifconnectivity(FAR const char *ifname, + int timeout, int retry) +{ + int ret; + char destip[INET_ADDRSTRLEN]; + struct in_addr addr; + + ret = netlib_get_dripv4addr(ifname, &addr); + if (ret < 0) + { + nerr("ERROR: failed to get gateway ip %s\n", ifname); + return ret; + } + + if (net_ipv4addr_cmp(&addr, INADDR_ANY)) + { + nerr("ERROR: failed to get gateway ip %s\n", ifname); + return -EINVAL; + } + + inet_ntop(AF_INET, &addr, destip, sizeof(destip)); + ninfo("ping gateway %s \n", destip); + + return netlib_check_ipconnectivity(destip, timeout, retry); +} + +#endif /* CONFIG_NETUTILS_PING */ \ No newline at end of file From 13a019450a9812f5a55bf2dfb173d3bee035e46f Mon Sep 17 00:00:00 2001 From: zhangshuai39 Date: Wed, 6 Aug 2025 20:48:43 +0800 Subject: [PATCH 086/568] netlib: Add an empty macro definition to the two connectivity functions The `netlib_check_ipconnectivity` and `netlib_check_ifconnectivity` functions depend on the `NETUTILS PING` configuration item. When `NETUTILS PING` is not enabled, a compilation error will occur; therefore, an empty macro definition is added. Signed-off-by: zhangshuai39 --- include/netutils/netlib.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 2e7f7bc60..b28b880df 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -517,6 +517,9 @@ int netlib_check_ifconflict(FAR const char *ifname); int netlib_check_ipconnectivity(FAR const char *ip, int timeout, int retry); int netlib_check_ifconnectivity(FAR const char *ifname, int timeout, int retry); +#else +#define netlib_check_ipconnectivity(i, t, r) 1 +#define netlib_check_ifconnectivity(i, t, r) 1 #endif #ifdef CONFIG_MM_IOB From 63f61d080aa524ed3c79518e678ddfa6dbe5a33c Mon Sep 17 00:00:00 2001 From: zhangshuai39 Date: Fri, 6 Jun 2025 20:44:56 +0800 Subject: [PATCH 087/568] netutils/ntpclient: Fix a large number of print DNS request errors Before attempting to sample via NTP, network connectivity should be checked to avoid frequent sampling that could cause network error logs to overflow. Signed-off-by: zhangshuai39 --- netutils/ntpclient/ntpclient.c | 39 +++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/netutils/ntpclient/ntpclient.c b/netutils/ntpclient/ntpclient.c index 19962f4d5..22c448fdd 100644 --- a/netutils/ntpclient/ntpclient.c +++ b/netutils/ntpclient/ntpclient.c @@ -52,6 +52,7 @@ #include +#include "netutils/netlib.h" #include "netutils/ntpclient.h" #include "ntpv3.h" @@ -103,6 +104,8 @@ #define MAX_SERVER_SELECTION_RETRIES 3 +#define MAX_RETRY_INTERVAL 120 + #ifndef STR # define STR2(x) #x # define STR(x) STR2(x) @@ -1233,6 +1236,7 @@ static int ntpc_daemon(int argc, FAR char **argv) FAR struct ntp_servers_s *srvs; int exitcode = EXIT_SUCCESS; int retries = 0; + int retry_delay = 1; int nsamples; int ret; @@ -1302,21 +1306,24 @@ static int ntpc_daemon(int argc, FAR char **argv) clock_gettime(CLOCK_REALTIME, &start_realtime); clock_gettime(CLOCK_MONOTONIC, &start_monotonic); - /* Collect samples. */ - nsamples = 0; - for (i = 0; i < CONFIG_NETUTILS_NTPCLIENT_NUM_SAMPLES; i++) + if (netlib_check_ipconnectivity(NULL, 1, 1) > 0) { - /* Get next sample. */ + /* Collect samples. */ - ret = ntpc_get_ntp_sample(srvs, samples, nsamples); - if (ret < 0) + for (i = 0; i < CONFIG_NETUTILS_NTPCLIENT_NUM_SAMPLES; i++) { - errval = errno; - } - else - { - ++nsamples; + /* Get next sample. */ + + ret = ntpc_get_ntp_sample(srvs, samples, nsamples); + if (ret < 0) + { + errval = errno; + } + else + { + ++nsamples; + } } } @@ -1405,6 +1412,7 @@ static int ntpc_daemon(int argc, FAR char **argv) sleep(CONFIG_NETUTILS_NTPCLIENT_POLLDELAYSEC); retries = 0; + retry_delay = 1; } continue; @@ -1424,7 +1432,14 @@ static int ntpc_daemon(int argc, FAR char **argv) if (errval != EINTR) { - sleep(1); + ninfo("Retry %d in %d seconds...\n", retries, retry_delay); + sleep(retry_delay); + + retry_delay *= 2; + if (retry_delay > MAX_RETRY_INTERVAL) + { + retry_delay = MAX_RETRY_INTERVAL; + } } /* Keep retrying. */ From 4e8a0ae4c40df86c9bf6e3eae01391f2f7e38732 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Sat, 10 Jan 2026 17:25:13 +0800 Subject: [PATCH 088/568] style: Fix coding style violations in nuttx-apps Fix various coding style issues including: - Case statement formatting - Include placement and ordering - Whitespace issues - Long line formatting - Bracket alignment Affected modules: - audioutils, examples, include - netutils, system Signed-off-by: Huang Qi --- audioutils/mml_parser/mml_parser.c | 36 ++++++++++++++++------ examples/elf/tests/signal/signal.c | 6 ++-- examples/elf/tests/struct/struct_main.c | 2 +- examples/mount/ramdisk.c | 4 +-- examples/netloop/netloop.h | 1 - examples/nxflat/tests/signal/signal.c | 6 ++-- examples/nxflat/tests/struct/struct_main.c | 2 +- examples/uid/uid_main.c | 12 +++++--- include/canutils/obd.h | 10 +++--- include/industry/abnt_codi.h | 3 +- netutils/netlib/netlib_ipv4addrconv.c | 6 ++-- netutils/pppd/ahdlc.h | 4 +-- netutils/pppd/pap.h | 1 + netutils/webserver/httpd.h | 4 ++- system/tee/tee.c | 5 +-- 15 files changed, 64 insertions(+), 38 deletions(-) diff --git a/audioutils/mml_parser/mml_parser.c b/audioutils/mml_parser/mml_parser.c index de7450f71..033bbbfde 100644 --- a/audioutils/mml_parser/mml_parser.c +++ b/audioutils/mml_parser/mml_parser.c @@ -169,15 +169,33 @@ static int calc_samples(int fs, int tempo, int num, int dots) switch (num) { - case 0: n = 3; break; - case 1: n = 2; break; - case 2: n = 1; break; - case 4: n = 0; break; - case 8: div = 1; break; - case 16: div = 2; break; - case 32: div = 3; break; - case 64: div = 4; break; - default: div = -1; break; + case 0: + n = 3; + break; + case 1: + n = 2; + break; + case 2: + n = 1; + break; + case 4: + n = 0; + break; + case 8: + div = 1; + break; + case 16: + div = 2; + break; + case 32: + div = 3; + break; + case 64: + div = 4; + break; + default: + div = -1; + break; } if (dots <= 4) diff --git a/examples/elf/tests/signal/signal.c b/examples/elf/tests/signal/signal.c index b091602bc..afcdff281 100644 --- a/examples/elf/tests/signal/signal.c +++ b/examples/elf/tests/signal/signal.c @@ -66,8 +66,8 @@ static int sigusr2_rcvd = 0; * Name: siguser_action ****************************************************************************/ -/* NOTE: it is necessary for functions that are referred to by function pointers - * pointer to be declared with global scope (at least for ARM). Otherwise, +/* NOTE: it is necessary for functions that are referred to by function + * pointers to be declared with global scope (at least for ARM). Otherwise, * a relocation type that is not supported by ELF is generated by GCC. */ @@ -225,7 +225,7 @@ int main(int argc, char **argv) /* Verify that the handler that was removed was siguser_action */ - if ((void*)act.sa_handler != (void*)siguser_action) + if ((void *)act.sa_handler != (void *)siguser_action) { fprintf(stderr, "Old SIGUSR2 signal handler (%p) is not siguser_action (%p)\n", diff --git a/examples/elf/tests/struct/struct_main.c b/examples/elf/tests/struct/struct_main.c index 801d2c5c5..5158c03b7 100644 --- a/examples/elf/tests/struct/struct_main.c +++ b/examples/elf/tests/struct/struct_main.c @@ -35,7 +35,7 @@ const struct struct_dummy_s dummy_struct = { - DUMMY_SCALAR_VALUE3 + DUMMY_SCALAR_VALUE3 }; int dummy_scalar = DUMMY_SCALAR_VALUE2; diff --git a/examples/mount/ramdisk.c b/examples/mount/ramdisk.c index 7eeeafaab..11b29130a 100644 --- a/examples/mount/ramdisk.c +++ b/examples/mount/ramdisk.c @@ -97,8 +97,8 @@ int create_ramdisk(void) ret = mkfatfs(g_source, &g_fmt); if (ret < 0) { - printf("create_ramdisk: Failed to create FAT filesystem on ramdisk at %s\n", - g_source); + printf("create_ramdisk: Failed to create FAT filesystem on " + "ramdisk at %s\n", g_source); return ret; } diff --git a/examples/netloop/netloop.h b/examples/netloop/netloop.h index c4d6415d6..2696e89ae 100644 --- a/examples/netloop/netloop.h +++ b/examples/netloop/netloop.h @@ -45,7 +45,6 @@ * buffering s not yet support for UDP) */ - #ifndef CONFIG_NET # error Network socket support not enabled #endif diff --git a/examples/nxflat/tests/signal/signal.c b/examples/nxflat/tests/signal/signal.c index 7deb7768e..63ee50767 100644 --- a/examples/nxflat/tests/signal/signal.c +++ b/examples/nxflat/tests/signal/signal.c @@ -66,8 +66,8 @@ static int sigusr2_rcvd = 0; * Name: siguser_action ****************************************************************************/ -/* NOTE: it is necessary for functions that are referred to by function pointers - * pointer to be declared with global scope (at least for ARM). Otherwise, +/* NOTE: it is necessary for functions that are referred to by function + * pointers to be declared with global scope (at least for ARM). Otherwise, * a relocation type that is not supported by ELF is generated by GCC. */ @@ -225,7 +225,7 @@ int main(int argc, char **argv) /* Verify that the handler that was removed was siguser_action */ - if ((void*)act.sa_handler != (void*)siguser_action) + if ((void *)act.sa_handler != (void *)siguser_action) { fprintf(stderr, "Old SIGUSR2 signal handler (%p) is not siguser_action (%p)\n", diff --git a/examples/nxflat/tests/struct/struct_main.c b/examples/nxflat/tests/struct/struct_main.c index 18aa49178..b3721f87a 100644 --- a/examples/nxflat/tests/struct/struct_main.c +++ b/examples/nxflat/tests/struct/struct_main.c @@ -35,7 +35,7 @@ const struct struct_dummy_s dummy_struct = { - DUMMY_SCALAR_VALUE3 + DUMMY_SCALAR_VALUE3 }; int dummy_scalar = DUMMY_SCALAR_VALUE2; diff --git a/examples/uid/uid_main.c b/examples/uid/uid_main.c index cc4bfc6fd..9792114be 100644 --- a/examples/uid/uid_main.c +++ b/examples/uid/uid_main.c @@ -51,10 +51,14 @@ static void show_usage(FAR const char *progname, FAR FILE *stream, int exit_code) { fprintf(stream, "USAGE:\n"); - fprintf(stream, "\t%s -uid - Show user info by ID\n", progname); - fprintf(stream, "\t%s -uname - Show user info by name\n", progname); - fprintf(stream, "\t%s -gid - Show group info by ID\n", progname); - fprintf(stream, "\t%s -gname - Show group info by name\n", progname); + fprintf(stream, "\t%s -uid - Show user info by ID\n", + progname); + fprintf(stream, "\t%s -uname - Show user info by name\n", + progname); + fprintf(stream, "\t%s -gid - Show group info by ID\n", + progname); + fprintf(stream, "\t%s -gname - Show group info by name\n", + progname); fprintf(stream, "\t%s -h - Show this help info\n", progname); exit(exit_code); } diff --git a/include/canutils/obd.h b/include/canutils/obd.h index bc6667285..c49b2a152 100644 --- a/include/canutils/obd.h +++ b/include/canutils/obd.h @@ -96,13 +96,13 @@ int obd_send_request(FAR struct obd_dev_s *dev, uint8_t opmode, uint8_t pid); * Wait for a message from ECUs with requested PID that was sent using * obd_send_request(). * - * It will return an error case it doesn't receive the msg after the elapsed - * "timeout" time. + * It will return an error case it doesn't receive the msg after the + * elapsed "timeout" time. * ****************************************************************************/ -int obd_wait_response(FAR struct obd_dev_s *dev, uint8_t opmode, uint8_t pid, - int timeout); +int obd_wait_response(FAR struct obd_dev_s *dev, uint8_t opmode, + uint8_t pid, int timeout); /**************************************************************************** * Name: obd_decode_pid @@ -116,4 +116,4 @@ int obd_wait_response(FAR struct obd_dev_s *dev, uint8_t opmode, uint8_t pid, FAR char *obd_decode_pid(FAR struct obd_dev_s *dev, uint8_t pid); -#endif /*__APPS_INCLUDE_CANUTILS_OBD_H */ +#endif /* __APPS_INCLUDE_CANUTILS_OBD_H */ diff --git a/include/industry/abnt_codi.h b/include/industry/abnt_codi.h index 049a7b29f..e1dbeb494 100644 --- a/include/industry/abnt_codi.h +++ b/include/industry/abnt_codi.h @@ -104,7 +104,8 @@ uint8_t abnt_codi_checksum(FAR const uint8_t *data); /* Parse a specific ABNT CODI sequence. */ -bool abnt_codi_parse(FAR const uint8_t *data, FAR struct abnt_codi_proto_s *proto); +bool abnt_codi_parse(FAR const uint8_t *data, + FAR struct abnt_codi_proto_s *proto); #ifdef __cplusplus } diff --git a/netutils/netlib/netlib_ipv4addrconv.c b/netutils/netlib/netlib_ipv4addrconv.c index 27325ca0a..e27a21f76 100644 --- a/netutils/netlib/netlib_ipv4addrconv.c +++ b/netutils/netlib/netlib_ipv4addrconv.c @@ -68,9 +68,9 @@ bool netlib_ipv4addrconv(FAR const char *addrstr, FAR uint8_t *ipaddr) { ch = *addrstr++; if (++j > 4) - { - return false; - } + { + return false; + } if (ch == '.' || ch == 0) { diff --git a/netutils/pppd/ahdlc.h b/netutils/pppd/ahdlc.h index 8ed51ff5d..a3846f76a 100644 --- a/netutils/pppd/ahdlc.h +++ b/netutils/pppd/ahdlc.h @@ -68,8 +68,8 @@ void ahdlc_rx_ready(FAR struct ppp_context_s *ctx); uint8_t ahdlc_rx(FAR struct ppp_context_s *ctx, uint8_t); uint8_t ahdlc_tx(FAR struct ppp_context_s *ctx, uint16_t protocol, - FAR uint8_t *header, FAR uint8_t *buffer, uint16_t headerlen, - uint16_t datalen); + FAR uint8_t *header, FAR uint8_t *buffer, + uint16_t headerlen, uint16_t datalen); #undef EXTERN #ifdef __cplusplus diff --git a/netutils/pppd/pap.h b/netutils/pppd/pap.h index 402ef0f71..fa43c9827 100644 --- a/netutils/pppd/pap.h +++ b/netutils/pppd/pap.h @@ -56,6 +56,7 @@ ****************************************************************************/ /* PAP state machine flags */ + /* Client only */ #define PAP_TX_UP 0x01 diff --git a/netutils/webserver/httpd.h b/netutils/webserver/httpd.h index 253adfcf1..e6486bb34 100644 --- a/netutils/webserver/httpd.h +++ b/netutils/webserver/httpd.h @@ -54,7 +54,9 @@ * Public Function Prototypes ****************************************************************************/ -/* 'file' must be allocated by caller and will be filled in by the function. */ +/* 'file' must be allocated by caller and will be filled in by the + * function. + */ #if defined(CONFIG_NETUTILS_HTTPD_SENDFILE) diff --git a/system/tee/tee.c b/system/tee/tee.c index 3adab918f..cb934c7a9 100644 --- a/system/tee/tee.c +++ b/system/tee/tee.c @@ -103,8 +103,9 @@ static void show_usage(FAR const char *progrname, int exitcode) fprintf(stderr, "-a:\n"); fprintf(stderr, "\tAppend to the file (vs. truncating)\n"); fprintf(stderr, "file:\n"); - fprintf(stderr, "\tArbitrary number of options output files. Output\n"); - fprintf(stderr, "\twill go to stdout in addition to each of these files.\n"); + fprintf(stderr, "\tArbitrary number of options output files. Output\n"); + fprintf(stderr, "\twill go to stdout in addition to each of these\n"); + fprintf(stderr, "\tfiles.\n"); fprintf(stderr, "-h:\n"); fprintf(stderr, "\tShows this message and exits\n"); exit(exitcode); From 21f41560480dcc147decef2dc72dab440a76087d Mon Sep 17 00:00:00 2001 From: hujun5 Date: Thu, 13 Mar 2025 18:02:44 +0800 Subject: [PATCH 089/568] sighand: need block WAKEUP_SIGNAL in current tcb If the main thread receives the signal, the waiter_main will not be awakened. Signed-off-by: hujun5 --- testing/ostest/sighand.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/testing/ostest/sighand.c b/testing/ostest/sighand.c index e7f3f5318..c368a37f1 100644 --- a/testing/ostest/sighand.c +++ b/testing/ostest/sighand.c @@ -217,12 +217,13 @@ void sighand_test(void) #ifdef CONFIG_SCHED_HAVE_PARENT struct sigaction act; struct sigaction oact; - sigset_t set; #endif struct sched_param param; pthread_attr_t attr; union sigval sigvalue; pid_t waiterpid; + sigset_t oset; + sigset_t set; int status; printf("sighand_test: Initializing semaphore to 0\n"); @@ -259,6 +260,16 @@ void sighand_test(void) /* Start waiter thread */ + sigemptyset(&set); + sigaddset(&set, WAKEUP_SIGNAL); + status = sigprocmask(SIG_BLOCK, &set, &oset); + if (status != OK) + { + printf("sighand_test: ERROR sigprocmask failed, status=%d\n", + status); + ASSERT(false); + } + printf("sighand_test: Starting waiter task\n"); status = sched_getparam (0, ¶m); if (status != OK) @@ -332,6 +343,7 @@ void sighand_test(void) #endif printf("sighand_test: done\n"); + sigprocmask(SIG_SETMASK, &oset, NULL); FFLUSH(); sem_destroy(&sem2); sem_destroy(&sem1); From d594c953a187c8164f8a98eb2c372f4d3f26ff5a Mon Sep 17 00:00:00 2001 From: gaohedong Date: Sun, 11 Jan 2026 11:51:54 +0800 Subject: [PATCH 090/568] net/vlan: fix issue of vlan pcp config Fix a issue of vlan pcp config. `vconfig add eth0 10` will create eth0.10 with VID=10 and no PCP(0) `vconfig add eth0 10 3` will create eth0.10 with VID=10 and PCP=3 Signed-off-by: gaohedong --- netutils/netlib/netlib_addvlan.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/netutils/netlib/netlib_addvlan.c b/netutils/netlib/netlib_addvlan.c index 87cbcf712..db1369578 100644 --- a/netutils/netlib/netlib_addvlan.c +++ b/netutils/netlib/netlib_addvlan.c @@ -42,13 +42,14 @@ * Parameters: * ifname - The name of the existing network device * vlanid - The VLAN identifier to be added + * prio - The default VLAN priority (PCP) * * Return: * 0 on success; -1 on failure * ****************************************************************************/ -int netlib_add_vlan(FAR const char *ifname, int vlanid) +int netlib_add_vlan(FAR const char *ifname, int vlanid, int prio) { int ret = ERROR; @@ -60,8 +61,9 @@ int netlib_add_vlan(FAR const char *ifname, int vlanid) struct vlan_ioctl_args ifv; strlcpy(ifv.device1, ifname, sizeof(ifv.device1)); - ifv.u.VID = vlanid; - ifv.cmd = ADD_VLAN_CMD; + ifv.u.VID = vlanid; + ifv.vlan_qos = prio; + ifv.cmd = ADD_VLAN_CMD; ret = ioctl(sockfd, SIOCSIFVLAN, &ifv); close(sockfd); From 7daac30cb47d5192f517a4c8e98d70d4e9937df7 Mon Sep 17 00:00:00 2001 From: shichunma Date: Thu, 1 Jan 2026 09:46:57 +0800 Subject: [PATCH 091/568] system/iptables: avoid trap when running "iptables -L" A trap occurs every time CONFIG_NET_NAT is enabled while CONFIG_NET_IPFILTER is not. Signed-off-by: Jerry Ma --- system/iptables/iptables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/iptables/iptables.c b/system/iptables/iptables.c index 7072ed968..673559634 100644 --- a/system/iptables/iptables.c +++ b/system/iptables/iptables.c @@ -506,7 +506,7 @@ int main(int argc, FAR char *argv[]) else #endif #ifdef CONFIG_NET_NAT - if (strcmp(args.table, TABLE_NAME_NAT) == 0) + if (args.table != NULL && strcmp(args.table, TABLE_NAME_NAT) == 0) { ret = iptables_apply(&args, iptables_nat_command); if (ret < 0) From 8d4e87240224654bcf59f134d41b677bdfe231bd Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Tue, 23 Dec 2025 16:40:00 -0500 Subject: [PATCH 092/568] !testing/cmocka: Compile cmocka as a libary only by default BREAKING CHANGE This commit introduces a Kconfig switch to include the cmocka binary built from cmocka_main.c. The default behaviour is now changed so that cmocka is built as a library only, which would be the desired behaviour for users creating their own cmocka projects. To restore the old behaviour (where the cmocka program is compiled), add CONFIG_TESTING_CMOCKA_PROG=y to your legacy configuration. Signed-off-by: Matteo Golin --- testing/cmocka/CMakeLists.txt | 32 +++++++++++++++++--------------- testing/cmocka/Kconfig | 18 ++++++++++++++++-- testing/cmocka/Makefile | 8 +++++--- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/testing/cmocka/CMakeLists.txt b/testing/cmocka/CMakeLists.txt index 277ee2233..d810aee89 100644 --- a/testing/cmocka/CMakeLists.txt +++ b/testing/cmocka/CMakeLists.txt @@ -74,20 +74,22 @@ if(CONFIG_TESTING_CMOCKA) target_include_directories(cmocka PRIVATE ${INCDIR}) target_compile_options(cmocka PRIVATE ${CFLAGS}) - nuttx_add_application( - NAME - ${CONFIG_TESTING_CMOCKA_PROGNAME} - PRIORITY - ${CONFIG_TESTING_CMOCKA_PRIORITY} - STACKSIZE - ${CONFIG_TESTING_CMOCKA_STACKSIZE} - MODULE - ${CONFIG_TESTING_CMOCKA} - INCLUDE_DIRECTORIES - ${INCDIR} - SRCS - cmocka_main.c - DEPENDS - cmocka) + if(CONFIG_TESTING_CMOCKA_PROG) + nuttx_add_application( + NAME + ${CONFIG_TESTING_CMOCKA_PROGNAME} + PRIORITY + ${CONFIG_TESTING_CMOCKA_PRIORITY} + STACKSIZE + ${CONFIG_TESTING_CMOCKA_STACKSIZE} + MODULE + ${CONFIG_TESTING_CMOCKA} + INCLUDE_DIRECTORIES + ${INCDIR} + SRCS + cmocka_main.c + DEPENDS + cmocka) + endif() endif() diff --git a/testing/cmocka/Kconfig b/testing/cmocka/Kconfig index 0f5ab51f7..fd1138152 100644 --- a/testing/cmocka/Kconfig +++ b/testing/cmocka/Kconfig @@ -4,7 +4,7 @@ # config TESTING_CMOCKA - tristate "Enable libcmocka" + bool "Enable libcmocka" depends on LIBC_REGEX default n ---help--- @@ -12,6 +12,15 @@ config TESTING_CMOCKA if TESTING_CMOCKA +config TESTING_CMOCKA_PROG + tristate "Compile cmocka binary" + default n + ---help--- + Instead of just compiling cmocka as a library, the 'cmocka' binary is + also included. + +if TESTING_CMOCKA_PROG + config TESTING_CMOCKA_PROGNAME string "Program name" default "cmocka" @@ -27,8 +36,13 @@ config TESTING_CMOCKA_STACKSIZE int "cmocka test stack size" default DEFAULT_TASK_STACKSIZE +endif # TESTING_CMOCKA_PROG + config TESTING_CMOCKA_LEAKDETECT - bool "Memory leaks can be checked using cmocka, please use in local environment" + bool "Detect leaks" default n + ---help--- + Memory leaks can be checked using cmocka, please use in a local + environment. endif diff --git a/testing/cmocka/Makefile b/testing/cmocka/Makefile index ac2d177b5..4a21f3ea1 100644 --- a/testing/cmocka/Makefile +++ b/testing/cmocka/Makefile @@ -29,12 +29,14 @@ CFLAGS += -DHAVE_CLOCK_REALTIME=1 CFLAGS += -DHAVE_STRUCT_TIMESPEC=1 CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/testing/cmocka +MODULE = $(CONFIG_TESTING_CMOCKA_PROG) + +ifneq ($(CONFIG_TESTING_CMOCKA_PROG),) PROGNAME = $(CONFIG_TESTING_CMOCKA_PROGNAME) PRIORITY = $(CONFIG_TESTING_CMOCKA_PRIORITY) STACKSIZE = $(CONFIG_TESTING_CMOCKA_STACKSIZE) -MODULE = $(CONFIG_TESTING_CMOCKA) - -MAINSRC = $(CURDIR)/cmocka_main.c +MAINSRC = $(CURDIR)/cmocka_main.c +endif # Download and unpack tarball if no git repo found ifeq ($(wildcard cmocka/.git),) From a22bf844cdf25c96af5a3295ac3c21927328213c Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 12 Jan 2026 11:48:13 +0100 Subject: [PATCH 093/568] .github/build.yml: fix python venv installation install venv package in one command to avoid issues with ubuntu mirrors Signed-off-by: raiden00pl --- .github/workflows/build.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7c43588cb..907497cba 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -181,10 +181,9 @@ jobs: BLOBDIR: /tools/blobs with: run: | - # install venv + # install python venv apt-get update - apt install -y python3-dev - apt install -y python3-venv + apt-get install -y python3 python3-dev python3-venv # get NTFC sources git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-ntfc From b0b90ac72886a7d2ee8d9a16e057a4b2c801984e Mon Sep 17 00:00:00 2001 From: meijian Date: Mon, 14 Oct 2024 20:36:13 +0800 Subject: [PATCH 094/568] apps/net: add http connectivity check API Add netlib_check_httpconnectivity() to verify HTTP service connectivity by sending GET request and validating status code. Signed-off-by: meijian --- include/netutils/netlib.h | 4 + netutils/netlib/CMakeLists.txt | 2 + netutils/netlib/Makefile | 2 + .../netlib/netlib_checkhttpconnectivity.c | 265 ++++++++++++++++++ 4 files changed, 273 insertions(+) create mode 100644 netutils/netlib/netlib_checkhttpconnectivity.c diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index b28b880df..43febfcda 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -526,6 +526,10 @@ int netlib_check_ifconnectivity(FAR const char *ifname, int netlib_get_iobinfo(FAR struct iob_stats_s *iob); #endif +int netlib_check_httpconnectivity(FAR const char *host, + FAR const char *getmsg, + int port, int expect_code); + #undef EXTERN #ifdef __cplusplus } diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt index be87f33fa..49e8aa81e 100644 --- a/netutils/netlib/CMakeLists.txt +++ b/netutils/netlib/CMakeLists.txt @@ -161,6 +161,8 @@ if(CONFIG_NETUTILS_NETLIB) list(APPEND SRCS netlib_checkipconnectivity.c netlib_checkifconnectivity.c) endif() + list(APPEND SRCS netlib_checkhttpconnectivity.c) + target_sources(apps PRIVATE ${SRCS}) endif() diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index a55340c1f..4bfc8d9d4 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -160,4 +160,6 @@ ifeq ($(CONFIG_NETUTILS_PING),y) CSRCS += netlib_checkipconnectivity.c netlib_checkifconnectivity.c endif +CSRCS += netlib_checkhttpconnectivity.c + include $(APPDIR)/Application.mk diff --git a/netutils/netlib/netlib_checkhttpconnectivity.c b/netutils/netlib/netlib_checkhttpconnectivity.c new file mode 100644 index 000000000..c29d86292 --- /dev/null +++ b/netutils/netlib/netlib_checkhttpconnectivity.c @@ -0,0 +1,265 @@ +/**************************************************************************** + * apps/netutils/netlib/netlib_checkhttpconnectivity.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_LIBC_NETDB +# include +#endif + +#include +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: eai_to_errno + * + * Description: + * Convert EAI_* error code to errno value for unified error handling. + * + * Parameters: + * eai_error The EAI_* error code from getaddrinfo(). + * + * Return: + * Corresponding errno value. + * + ****************************************************************************/ + +#ifdef CONFIG_LIBC_NETDB +static int eai_to_errno(int eai_error) +{ + switch (eai_error) + { + case EAI_AGAIN: + return EAGAIN; /* Temporary failure, try again */ + + case EAI_BADFLAGS: + return EINVAL; /* Invalid flags */ + + case EAI_FAIL: + return EHOSTUNREACH; /* Non-recoverable failure */ + + case EAI_FAMILY: + return EAFNOSUPPORT; /* Address family not supported */ + + case EAI_MEMORY: + return ENOMEM; /* Memory allocation failure */ + + case EAI_NONAME: + return EHOSTUNREACH; /* Host name not found */ + + case EAI_SERVICE: + return EINVAL; /* Service not recognized */ + + case EAI_SOCKTYPE: + return EINVAL; /* Socket type not supported */ + + case EAI_SYSTEM: + return errno; /* System error, use errno */ + + case EAI_OVERFLOW: + return EOVERFLOW; /* Buffer overflow */ + + default: + return EINVAL; /* Unknown error, use invalid argument */ + } +} +#endif + +/**************************************************************************** + * Name: httpget_gethostip + * + * Description: + * Check the http status code + * + * Parameters: + * hostname The host name to use in the nslookup. + * dest The location to return the IPv4 address. + * + * Return: + * 0 on success; a negative errno value on failure. + * + ****************************************************************************/ + +static int httpget_gethostip(FAR const char *hostname, + FAR struct in_addr *dest) +{ +#ifdef CONFIG_LIBC_NETDB + /* Netdb DNS client support is enabled */ + + int ret; + FAR struct addrinfo hint; + FAR struct addrinfo *info; + FAR struct sockaddr_in *addr; + + memset(&hint, 0, sizeof(hint)); + hint.ai_family = AF_INET; + + ret = getaddrinfo(hostname, NULL, &hint, &info); + if (ret != OK) + { + return -eai_to_errno(ret); + } + + addr = (FAR struct sockaddr_in *)info->ai_addr; + memcpy(dest, &addr->sin_addr, sizeof(struct in_addr)); + + freeaddrinfo(info); + return OK; + +#else /* CONFIG_LIBC_NETDB */ + /* No host name support */ + + /* Convert strings to numeric IPv4 address */ + + int ret = inet_pton(AF_INET, hostname, dest); + + /* The inet_pton() function returns 1 if the conversion succeeds. It will + * return 0 if the input is not a valid IPv4 dotted-decimal string or -1 + * with errno set to EAFNOSUPPORT if the address family argument is + * unsupported. + */ + + if (ret != 1) + { + /* ret == 0: invalid IP address string, set errno to EINVAL + * ret == -1: system error, errno is already set to EAFNOSUPPORT + */ + + if (ret == 0) + { + set_errno(EINVAL); + } + + return -errno; + } + + return OK; + +#endif /* CONFIG_LIBC_NETDB */ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netlib_check_httpconnectivity + * + * Description: + * Check the http status code + * + * Parameters: + * host The remote host to check + * getmsg The http GET message + * port The port of remote host + * expect_code The except http code of http code + * + * Return: + * 0 on success; a nagtive on failure. + * + ****************************************************************************/ + +int netlib_check_httpconnectivity(FAR const char *host, + FAR const char *getmsg, + int port, int expect_code) +{ + int sock; + int ret; + int status_code = -1; + struct sockaddr_in server_addr; + char buf[256]; + + ret = httpget_gethostip(host, &server_addr.sin_addr); + if (ret < 0) + { + nerr("Failed to get host ip"); + return ret; + } + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + nerr("Failed to create socket"); + return -errno; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + + ret = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)); + if (ret < 0) + { + perror("Connection failed"); + goto exit_with_socket; + } + + snprintf(buf, sizeof(buf), + "GET /%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", + getmsg, host); + + ret = send(sock, buf, strlen(buf), 0); + if (ret < 0) + { + perror("send failed"); + goto exit_with_socket; + } + + if ((ret = recv(sock, buf, sizeof(buf), 0)) < 0) + { + perror("recv failed"); + goto exit_with_socket; + } + + /* get the http code, and check with except code */ + + if (sscanf(buf, "HTTP/1.1 %d", &status_code) == 1 && + status_code == expect_code) + { + ninfo("HTTP connectivity is ok"); + ret = OK; + } + else + { + nerr("HTTP connectivity is not ok status code: %d\n", status_code); + ret = -status_code; + } + +exit_with_socket: + close(sock); + return ret; +} From 58326d39dcc1886b39f695cb4b5d36db07593ecd Mon Sep 17 00:00:00 2001 From: liucheng5 Date: Mon, 4 Nov 2024 17:26:05 +0800 Subject: [PATCH 095/568] system/uorb: add a new uorb topic ENG Add a new uorb topic for ENG sensor Signed-off-by: liucheng5 Signed-off-by: likun17 --- system/uorb/sensor/eng.c | 41 +++++++++++++++++++++++++++++++++++++ system/uorb/sensor/eng.h | 38 ++++++++++++++++++++++++++++++++++ system/uorb/sensor/topics.c | 4 +++- 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 system/uorb/sensor/eng.c create mode 100644 system/uorb/sensor/eng.h diff --git a/system/uorb/sensor/eng.c b/system/uorb/sensor/eng.c new file mode 100644 index 000000000..afc712aec --- /dev/null +++ b/system/uorb/sensor/eng.c @@ -0,0 +1,41 @@ +/**************************************************************************** + * apps/system/uorb/sensor/eng.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_UORB +static const char sensor_eng_format[] = + "timestamp:%" PRIu64 ",eng0:%hf,eng1:%hf,eng2:%hf,eng3:%hf," + "status:0x%" PRIx32 ""; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +ORB_DEFINE(sensor_eng, struct sensor_eng, sensor_eng_format); diff --git a/system/uorb/sensor/eng.h b/system/uorb/sensor/eng.h new file mode 100644 index 000000000..099c13290 --- /dev/null +++ b/system/uorb/sensor/eng.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * apps/system/uorb/sensor/eng.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_SYSTEM_UORB_SENSOR_ENG_H +#define __APPS_SYSTEM_UORB_SENSOR_ENG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* register this as object request broker structure */ + +ORB_DECLARE(sensor_eng); + +#endif diff --git a/system/uorb/sensor/topics.c b/system/uorb/sensor/topics.c index 02666a5f0..48619627f 100644 --- a/system/uorb/sensor/topics.c +++ b/system/uorb/sensor/topics.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +88,7 @@ static FAR const struct orb_metadata *g_sensor_list[] = ORB_ID(sensor_device_orientation), ORB_ID(sensor_dust), ORB_ID(sensor_ecg), + ORB_ID(sensor_eng), ORB_ID(sensor_force), ORB_ID(sensor_gas), ORB_ID(sensor_glance_gesture), @@ -157,7 +159,7 @@ FAR const struct orb_metadata *orb_get_meta(FAR const char *name) int fd; int i; - /* Fisrt search built-in topics */ + /* First search built-in topics */ for (i = 0; g_sensor_list[i]; i++) { From 97545f6ff92a7a0669806a64aedc9eb1fe738fd2 Mon Sep 17 00:00:00 2001 From: jingfei Date: Wed, 4 Jun 2025 21:14:50 +0800 Subject: [PATCH 096/568] ymodem:rb of ymodem add prefix and suffix for download file name Adding parameters to rb main can add prefixes and suffixes to the file names to be downloaded Signed-off-by: jingfei --- system/ymodem/rb_main.c | 74 ++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/system/ymodem/rb_main.c b/system/ymodem/rb_main.c index 373e597fe..983cc84b4 100644 --- a/system/ymodem/rb_main.c +++ b/system/ymodem/rb_main.c @@ -42,8 +42,10 @@ struct ymodem_priv_s int fd; FAR char *foldname; size_t file_saved_size; - FAR char *skip_perfix; + FAR char *skip_prefix; FAR char *skip_suffix; + FAR char *prepend_prefix; + FAR char *append_suffix; /* Async */ @@ -173,8 +175,8 @@ static int handler(FAR struct ymodem_ctx_s *ctx) if (ctx->packet_type == YMODEM_FILENAME_PACKET) { - char temp[PATH_MAX + 1]; - FAR char *filename; + char filename[PATH_MAX + 1]; + FAR char *temp; if (priv->fd > 0) { @@ -192,35 +194,51 @@ static int handler(FAR struct ymodem_ctx_s *ctx) close(priv->fd); } - filename = ctx->file_name; - if (priv->skip_perfix != NULL) - { - size_t len = strlen(priv->skip_perfix); + temp = ctx->file_name; - if (strncmp(ctx->file_name, priv->skip_perfix, + if (priv->skip_prefix != NULL) + { + size_t len = strlen(priv->skip_prefix); + + if (strncmp(ctx->file_name, priv->skip_prefix, len) == 0) { - filename += len; + temp += len; } } if (priv->skip_suffix != NULL) { - size_t len = strlen(filename); + size_t len = strlen(temp); size_t len2 = strlen(priv->skip_suffix); - if (len > len2 && strcmp(filename + len - len2, + if (len > len2 && strcmp(temp + len - len2, priv->skip_suffix) == 0) { - filename[len - len2] = '\0'; + temp[len - len2] = '\0'; } } if (priv->foldname != NULL) { - snprintf(temp, sizeof(temp), "%s/%s", priv->foldname, - filename); - filename = temp; + ret = snprintf(filename, sizeof(filename), "%s/%s%s%s", + priv->foldname, priv->prepend_prefix, temp, + priv->append_suffix); + } + else + { + ret = snprintf(filename, sizeof(filename), "%s%s%s", + priv->prepend_prefix, temp, priv->append_suffix); + } + + if (ret < 0) + { + return ret; + } + + else if (ret >= sizeof(filename)) + { + return -ENAMETOOLONG; } priv->fd = open(filename, O_CREAT | O_WRONLY, 0777); @@ -326,6 +344,10 @@ static void show_usage(FAR const char *progname) "\t-p|--skip_prefix : Remove file name prefix\n"); fprintf(stderr, "\t-s|--skip_suffix : Remove file name suffix\n"); + fprintf(stderr, + "\t-e|--prepend_prefix : prepend file name a prefix\n"); + fprintf(stderr, + "\t-a|--append_suffix : append file name a suffix\n"); fprintf(stderr, "\t-b|--buffersize : Asynchronously receive buffer size." "If greater than 0, accept data asynchronously, Default: 0kB\n"); @@ -339,7 +361,7 @@ static void show_usage(FAR const char *progname) "\t-r|--retry : Number of retries." "Will try times to transmitting, Default:100\n"); fprintf(stderr, - "\t-k : Use a custom size to tansfer, Default: 1kB\n"); + "\t-k : Use a custom size to transfer, Default: 1kB\n"); exit(EXIT_FAILURE); } @@ -353,6 +375,7 @@ int main(int argc, FAR char *argv[]) struct ymodem_priv_s priv; struct ymodem_ctx_s ctx; FAR char *devname = NULL; + size_t len; int ret; struct option options[] = @@ -360,16 +383,20 @@ int main(int argc, FAR char *argv[]) {"buffersize", 1, NULL, 'b'}, {"skip_prefix", 1, NULL, 'p'}, {"skip_suffix", 1, NULL, 's'}, + {"prepend_prefix", 1, NULL, 'e'}, + {"append_suffix", 1, NULL, 'a'}, {"threshold", 1, NULL, 't'}, {"interval", 1, NULL, 'i'}, {"retry", 1, NULL, 'r'}, }; memset(&priv, 0, sizeof(priv)); + priv.prepend_prefix = ""; + priv.append_suffix = ""; memset(&ctx, 0, sizeof(ctx)); ctx.interval = 15; ctx.retry = 100; - while ((ret = getopt_long(argc, argv, "b:d:f:hk:p:s:t:i:r:", + while ((ret = getopt_long(argc, argv, "b:d:f:hk:p:s:t:i:r:e:a:", options, NULL)) != ERROR) { switch (ret) @@ -382,9 +409,10 @@ int main(int argc, FAR char *argv[]) break; case 'f': priv.foldname = optarg; - if (priv.foldname[strlen(priv.foldname)] == '/') + len = strlen(priv.foldname); + if (len > 0 && priv.foldname[len - 1] == '/') { - priv.foldname[strlen(priv.foldname)] = '\0'; + priv.foldname[len - 1] = '\0'; } break; @@ -395,11 +423,17 @@ int main(int argc, FAR char *argv[]) ctx.custom_size = atoi(optarg) * 1024; break; case 'p': - priv.skip_perfix = optarg; + priv.skip_prefix = optarg; break; case 's': priv.skip_suffix = optarg; break; + case 'e': + priv.prepend_prefix = optarg; + break; + case 'a': + priv.append_suffix = optarg; + break; case 't': priv.threshold = atoi(optarg) * 1024; break; From b7b2ba37a191a95ac7afd930feb5f7966adb849d Mon Sep 17 00:00:00 2001 From: ligd Date: Fri, 16 May 2025 16:14:41 +0800 Subject: [PATCH 097/568] timer_test: reduce the sleep time to improve testing efficiency reduce the sleep time Signed-off-by: ligd --- .../kernel/time/cases/clock_test_timer05.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/testing/testsuites/kernel/time/cases/clock_test_timer05.c b/testing/testsuites/kernel/time/cases/clock_test_timer05.c index c9903c3e3..8c282260a 100644 --- a/testing/testsuites/kernel/time/cases/clock_test_timer05.c +++ b/testing/testsuites/kernel/time/cases/clock_test_timer05.c @@ -112,7 +112,7 @@ void test_nuttx_clock_test_timer05(FAR void **state) /* Start the timer */ - its.it_value.tv_sec = 3; /* 3, timer time 3 seconds. */ + its.it_value.tv_sec = 1; its.it_value.tv_nsec = 0; its.it_interval.tv_sec = its.it_value.tv_sec; its.it_interval.tv_nsec = its.it_value.tv_nsec; @@ -124,8 +124,8 @@ void test_nuttx_clock_test_timer05(FAR void **state) syslog(LOG_INFO, "timer_create %p: %d", timerid01, ret); assert_int_equal(ret, 0); - its.it_value.tv_sec = 4; /* 4, timer time 4 seconds. */ - its.it_value.tv_nsec = 0; + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 50 * 1000 * 1000; /* 50ms */ its.it_interval.tv_sec = its.it_value.tv_sec; its.it_interval.tv_nsec = its.it_value.tv_nsec; @@ -138,12 +138,7 @@ void test_nuttx_clock_test_timer05(FAR void **state) syslog(LOG_INFO, "timer_settime %p: %d", timerid02, ret); assert_int_equal(ret, 0); - its.it_value.tv_sec = 5; /* 5, timer time 5 seconds. */ - its.it_value.tv_nsec = 0; - its.it_interval.tv_sec = its.it_value.tv_sec; - its.it_interval.tv_nsec = its.it_value.tv_nsec; - - sleep(20); /* 20, sleep seconds for timer. */ + sleep(3); ret = timer_delete(timerid01); syslog(LOG_INFO, "timer_delete %p %d", timerid01, ret); assert_int_equal(ret, 0); @@ -152,6 +147,8 @@ void test_nuttx_clock_test_timer05(FAR void **state) syslog(LOG_INFO, "timer_delete %p %d", timerid02, ret); assert_int_equal(ret, 0); + syslog(LOG_INFO, "cnt %d %d\n", + test_timer05_g_sighdlcnt01, test_timer05_g_sighdlcnt02); assert_int_not_equal(test_timer05_g_sighdlcnt01, 0); assert_int_not_equal(test_timer05_g_sighdlcnt02, 0); } From 429f24afbdf9b21d85792cba525ebb1be0ceb58e Mon Sep 17 00:00:00 2001 From: ligd Date: Tue, 25 Mar 2025 21:31:36 +0800 Subject: [PATCH 098/568] ltp: close mq_close/4-1 testcase when open CONFIG_FDCHECK Caused the cause will used after free on fd Signed-off-by: ligd --- testing/ltp/CMakeLists.txt | 4 ++++ testing/ltp/Makefile | 3 +++ 2 files changed, 7 insertions(+) diff --git a/testing/ltp/CMakeLists.txt b/testing/ltp/CMakeLists.txt index 1152b8963..6f9b7effe 100644 --- a/testing/ltp/CMakeLists.txt +++ b/testing/ltp/CMakeLists.txt @@ -118,6 +118,10 @@ if(CONFIG_TESTING_LTP) ${TESTDIR}/conformance/interfaces/pthread_sigmask/4-1.c ${TESTDIR}/conformance/interfaces/sigprocmask/4-1.c) + if(CONFIG_FDCHECK) + list(APPEND BLACKSRCS ${TESTDIR}/conformance/interfaces/mq_close/4-1.c) + endif() + if(NOT CONFIG_LIBC_LOCALTIME) list(APPEND BLACKSRCS ${TESTDIR}/conformance/definitions/time_h/34-1-buildonly.c diff --git a/testing/ltp/Makefile b/testing/ltp/Makefile index 1fc2c943d..99354eed6 100644 --- a/testing/ltp/Makefile +++ b/testing/ltp/Makefile @@ -70,6 +70,9 @@ BLACKSRCS += $(TESTDIR)/conformance/interfaces/clock_nanosleep/1-4.c BLACKSRCS += $(TESTDIR)/conformance/interfaces/pthread_sigmask/18-1.c BLACKSRCS += $(TESTDIR)/conformance/interfaces/pthread_sigmask/4-1.c BLACKSRCS += $(TESTDIR)/conformance/interfaces/sigprocmask/4-1.c +ifeq ($(CONFIG_FDCHECK),y) +BLACKSRCS += $(TESTDIR)/conformance/interfaces/mq_close/4-1.c +endif ifeq ($(CONFIG_LIBC_LOCALTIME),) BLACKSRCS += $(TESTDIR)/conformance/definitions/time_h/34-1-buildonly.c BLACKSRCS += $(TESTDIR)/conformance/definitions/time_h/35-3-buildonly.c From 680dca11215a8d1654ebc766177594ace2c10dc2 Mon Sep 17 00:00:00 2001 From: haopengxiang Date: Thu, 27 Mar 2025 00:10:06 +0800 Subject: [PATCH 099/568] ltp: close mq_close/3-1 testcase when open CONFIG_FDCHECK Caused the cause will used after free on fd Signed-off-by: haopengxiang Signed-off-by: ligd --- testing/ltp/CMakeLists.txt | 3 ++- testing/ltp/Makefile | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/ltp/CMakeLists.txt b/testing/ltp/CMakeLists.txt index 6f9b7effe..2e458d5e4 100644 --- a/testing/ltp/CMakeLists.txt +++ b/testing/ltp/CMakeLists.txt @@ -119,7 +119,8 @@ if(CONFIG_TESTING_LTP) ${TESTDIR}/conformance/interfaces/sigprocmask/4-1.c) if(CONFIG_FDCHECK) - list(APPEND BLACKSRCS ${TESTDIR}/conformance/interfaces/mq_close/4-1.c) + list(APPEND BLACKSRCS ${TESTDIR}/conformance/interfaces/mq_close/3-1.c + ${TESTDIR}/conformance/interfaces/mq_close/4-1.c) endif() if(NOT CONFIG_LIBC_LOCALTIME) diff --git a/testing/ltp/Makefile b/testing/ltp/Makefile index 99354eed6..c6f712614 100644 --- a/testing/ltp/Makefile +++ b/testing/ltp/Makefile @@ -71,6 +71,7 @@ BLACKSRCS += $(TESTDIR)/conformance/interfaces/pthread_sigmask/18-1.c BLACKSRCS += $(TESTDIR)/conformance/interfaces/pthread_sigmask/4-1.c BLACKSRCS += $(TESTDIR)/conformance/interfaces/sigprocmask/4-1.c ifeq ($(CONFIG_FDCHECK),y) +BLACKSRCS += $(TESTDIR)/conformance/interfaces/mq_close/3-1.c BLACKSRCS += $(TESTDIR)/conformance/interfaces/mq_close/4-1.c endif ifeq ($(CONFIG_LIBC_LOCALTIME),) @@ -247,7 +248,7 @@ ltp-$(LTPS_VERSION).zip: $(call DOWNLOAD,$(LTP_DOWNLOAD_URL),$(LTPS_VERSION).zip, ltp.zip) $(LTP_UNPACK): ltp-$(LTPS_VERSION).zip - $(Q) echo "dowload $(LTP_DOWNLOAD_URL)$(LTPS_VERSION).zip" + $(Q) echo "download $(LTP_DOWNLOAD_URL)$(LTPS_VERSION).zip" $(Q) unzip -o ltp.zip $(Q) rm -f ltp.zip $(Q) mv ltp-$(LTPS_VERSION) $(LTP_UNPACK) From af8ff17f9597cc7581acd6475a56a0fea7e237af Mon Sep 17 00:00:00 2001 From: gaohedong Date: Wed, 17 Sep 2025 11:18:17 +0800 Subject: [PATCH 100/568] netlib: fixed compilation issues fixed compilation issues Signed-off-by: gaohedong --- include/netutils/netlib.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 43febfcda..2b3146e91 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -56,6 +56,11 @@ #include #include +#ifdef CONFIG_NET_IPTABLES +# include +# include +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ From 58c2473b38c02888c3e4e14c6dcf31cdae05e949 Mon Sep 17 00:00:00 2001 From: zhaoxingyu1 Date: Wed, 30 Oct 2024 20:32:53 +0800 Subject: [PATCH 101/568] apps/testing: nvs testcases support remove align size mtd/nvs removes CONFIG_MTD_WRITE_ALIGN_SIZE, testcases need to be modified meanwhile Signed-off-by: zhaoxingyu1 --- .../mtd_config_fs/mtd_config_fs_test_main.c | 376 ++++++++++-------- 1 file changed, 219 insertions(+), 157 deletions(-) diff --git a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c index 5c44a6a1d..fdc254afa 100644 --- a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c +++ b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c @@ -49,9 +49,11 @@ * Pre-processor Definitions ****************************************************************************/ +#define NVS_ATE(name, size) \ + char name##_buf[size]; \ + FAR struct nvs_ate *name = (FAR struct nvs_ate *)name##_buf + /* Configuration ************************************************************/ -#define NVS_ALIGN_SIZE CONFIG_MTD_WRITE_ALIGN_SIZE -#define NVS_ALIGN_UP(x) (((x) + NVS_ALIGN_SIZE - 1) & ~(NVS_ALIGN_SIZE - 1)) #define TEST_KEY1 "testkey1" #define TEST_KEY2 "testkey2" @@ -72,15 +74,7 @@ begin_packed_struct struct nvs_ate uint16_t key_len; /* Key string len */ uint8_t part; /* Part of a multipart data - future extension */ uint8_t crc8; /* Crc8 check of the ate entry */ -#if CONFIG_MTD_WRITE_ALIGN_SIZE <= 4 - /* stay compatible with situation which align byte be 1 */ - - uint8_t expired[NVS_ALIGN_SIZE]; - uint8_t reserved[4 - NVS_ALIGN_SIZE]; -#else - uint8_t padding[NVS_ALIGN_UP(12) - 12]; - uint8_t expired[NVS_ALIGN_SIZE]; -#endif + uint8_t expired[0]; } end_packed_struct; /* Pre-allocated simulated flash */ @@ -92,12 +86,38 @@ struct mtdnvs_ctx_s struct mallinfo mmprevious; struct mallinfo mmafter; uint8_t erasestate; + uint32_t progsize; }; /**************************************************************************** * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: nvs_align_up + ****************************************************************************/ + +static inline size_t nvs_align_up(FAR struct mtdnvs_ctx_s *ctx, size_t len) +{ + return (len + (ctx->progsize - 1)) & ~(ctx->progsize - 1); +} + +/**************************************************************************** + * Name: nvs_ate_size + ****************************************************************************/ + +static inline size_t nvs_ate_size(FAR struct mtdnvs_ctx_s *ctx) +{ + /* Stay compatible with situation which align byte be 1 */ + + if (ctx->progsize == 1) + { + return sizeof(struct nvs_ate) + 4; + } + + return nvs_align_up(ctx, sizeof(struct nvs_ate)) + ctx->progsize; +} + /**************************************************************************** * Name: fnv_hash_32 ****************************************************************************/ @@ -137,81 +157,156 @@ static void fill_crc8_update(FAR struct nvs_ate *entry) } /**************************************************************************** - * Name: fill_gc_done_ate + * Name: write_corrupted_close_ate ****************************************************************************/ -static void fill_corrupted_close_ate(FAR struct mtdnvs_ctx_s *ctx, - FAR struct nvs_ate *close_ate) +static int write_corrupted_close_ate(int mtd_fd, + FAR struct mtdnvs_ctx_s *ctx) { - memset((FAR void *)close_ate, ctx->erasestate, - sizeof(struct nvs_ate)); + size_t ate_size = nvs_ate_size(ctx); + NVS_ATE(close_ate, ate_size); + int ret; + + memset(close_ate, ctx->erasestate, ate_size); close_ate->id = 0xffffffff; close_ate->len = 0U; + + ret = write(mtd_fd, &close_ate, ate_size); + if (ret != ate_size) + { + goto write_fail; + } + + return 0; + +write_fail: + printf("%s:write corrupted_close_ate failed, ret=%d\n", __func__, ret); + return -EIO; } /**************************************************************************** - * Name: fill_close_ate + * Name: write_close_ate ****************************************************************************/ -static void fill_close_ate(FAR struct mtdnvs_ctx_s *ctx, - FAR struct nvs_ate *close_ate, int offset) +static int write_close_ate(int mtd_fd, FAR struct mtdnvs_ctx_s *ctx, + int offset) { - memset((FAR void *)close_ate, ctx->erasestate, - sizeof(struct nvs_ate)); + size_t ate_size = nvs_ate_size(ctx); + NVS_ATE(close_ate, ate_size); + int ret; + + memset(close_ate, ctx->erasestate, ate_size); close_ate->id = 0xffffffff; close_ate->len = 0U; close_ate->offset = offset; fill_crc8_update(close_ate); + + ret = write(mtd_fd, &close_ate, ate_size); + if (ret != ate_size) + { + goto write_fail; + } + + return 0; + +write_fail: + printf("%s:write close_ate failed, ret=%d\n", __func__, ret); + return -EIO; } /**************************************************************************** - * Name: fill_gc_done_ate + * Name: write_gc_done_ate ****************************************************************************/ -static void fill_gc_done_ate(FAR struct mtdnvs_ctx_s *ctx, - FAR struct nvs_ate *gc_done_ate) +static int write_gc_done_ate(int mtd_fd, FAR struct mtdnvs_ctx_s *ctx) { - memset((FAR void *)gc_done_ate, ctx->erasestate, - sizeof(struct nvs_ate)); + size_t ate_size = nvs_ate_size(ctx); + NVS_ATE(gc_done_ate, ate_size); + int ret; + + memset(gc_done_ate, ctx->erasestate, ate_size); gc_done_ate->id = 0xffffffff; gc_done_ate->len = 0U; fill_crc8_update(gc_done_ate); + + ret = write(mtd_fd, &gc_done_ate, ate_size); + if (ret != ate_size) + { + goto write_fail; + } + + return 0; + +write_fail: + printf("%s:write gc_done_ate failed, ret=%d\n", __func__, ret); + return -EIO; } /**************************************************************************** - * Name: fill_ate + * Name: write_ate ****************************************************************************/ -static void fill_ate(FAR struct mtdnvs_ctx_s *ctx, FAR struct nvs_ate *ate, +static int write_ate(int mtd_fd, FAR struct mtdnvs_ctx_s *ctx, FAR const char *key, uint16_t len, uint16_t offset, bool expired) { - memset((FAR void *)ate, ctx->erasestate, - sizeof(struct nvs_ate)); + size_t ate_size = nvs_ate_size(ctx); + NVS_ATE(ate, ate_size); + int ret; + + memset(ate, ctx->erasestate, ate_size); ate->id = nvs_fnv_hash((FAR const uint8_t *)key, strlen(key) + 1) % 0xfffffffd + 1; ate->len = len; ate->offset = offset; ate->key_len = strlen(key) + 1; fill_crc8_update(ate); - ate->expired[0] = expired ? 0x7f : 0xff; + ate->expired[nvs_align_up(ctx, sizeof(struct nvs_ate))] + = expired ? 0x7f : 0xff; + + ret = write(mtd_fd, ate, ate_size); + if (ret != ate_size) + { + goto write_fail; + } + + return 0; + +write_fail: + printf("%s:write ate failed, ret=%d\n", __func__, ret); + return -EIO; } /**************************************************************************** - * Name: fill_corrupted_ate + * Name: write_corrupted_ate ****************************************************************************/ -static void fill_corrupted_ate(FAR struct mtdnvs_ctx_s *ctx, - FAR struct nvs_ate *ate, FAR const char *key, +static int write_corrupted_ate(int mtd_fd, FAR struct mtdnvs_ctx_s *ctx, + FAR const char *key, uint16_t len, uint16_t offset) { - memset((FAR void *)ate, ctx->erasestate, - sizeof(struct nvs_ate)); + size_t ate_size = nvs_ate_size(ctx); + NVS_ATE(ate, ate_size); + int ret; + + memset(ate, ctx->erasestate, ate_size); ate->id = nvs_fnv_hash((FAR const uint8_t *)key, strlen(key) + 1) % 0xfffffffd + 1; ate->len = len; ate->offset = offset; ate->key_len = strlen(key) + 1; + + ret = write(mtd_fd, &ate, ate_size); + if (ret != ate_size) + { + goto write_fail; + } + + return 0; + +write_fail: + printf("%s:write corrupted_ate failed, ret=%d\n", __func__, ret); + return -EIO; } /**************************************************************************** @@ -303,6 +398,7 @@ extern int find_mtddriver(FAR const char *pathname, static int setup(struct mtdnvs_ctx_s *ctx) { + struct mtd_geometry_s geo; int ret; FAR struct inode *sys_node; @@ -323,6 +419,16 @@ static int setup(struct mtdnvs_ctx_s *ctx) return ret; } + ret = MTD_IOCTL(sys_node->u.i_mtd, MTDIOC_GEOMETRY, + (unsigned long)((uintptr_t)&(geo))); + if (ret < 0) + { + printf("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", ret); + return ret; + } + + ctx->progsize = geo.blocksize; + ret = mtdconfig_register(sys_node->u.i_mtd); if (ret < 0) { @@ -490,15 +596,15 @@ test_fail: static void test_nvs_corrupt_expire(struct mtdnvs_ctx_s *ctx) { - struct nvs_ate ate; + uint8_t erase_value = ctx->erasestate; + size_t ate_size = nvs_ate_size(ctx); + struct config_data_s data; + size_t padding_size; + char rd_buf[50]; int mtd_fd = -1; int nvs_fd = -1; int ret; int i; - uint8_t erase_value = ctx->erasestate; - struct config_data_s data; - char rd_buf[50]; - size_t padding_size; printf("%s: test begin\n", __func__); @@ -525,8 +631,8 @@ static void test_nvs_corrupt_expire(struct mtdnvs_ctx_s *ctx) goto test_fail; } - padding_size = NVS_ALIGN_UP(sizeof(TEST_KEY1) + sizeof(TEST_DATA1)) - - sizeof(TEST_KEY1) - sizeof(TEST_DATA1); + padding_size = nvs_align_up(ctx, sizeof(TEST_KEY1) + sizeof(TEST_DATA1)) + - sizeof(TEST_KEY1) - sizeof(TEST_DATA1); for (i = 0; i < padding_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -557,7 +663,7 @@ static void test_nvs_corrupt_expire(struct mtdnvs_ctx_s *ctx) for (i = 2 * (strlen(TEST_KEY1) + strlen(TEST_DATA1) + 2) + padding_size; i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - 4 * sizeof(struct nvs_ate); i++) + - 4 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); if (ret != sizeof(erase_value)) @@ -569,42 +675,34 @@ static void test_nvs_corrupt_expire(struct mtdnvs_ctx_s *ctx) /* Write ate */ - fill_ate(ctx, &ate, TEST_KEY1, strlen(TEST_DATA2) + 1, + ret = write_ate(mtd_fd, ctx, TEST_KEY1, strlen(TEST_DATA2) + 1, strlen(TEST_KEY1) + strlen(TEST_DATA1) + 2 + padding_size, false); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + if (ret < 0) { - printf("%s:write ate failed, ret=%d\n", __func__, ret); goto test_fail; } - fill_ate(ctx, &ate, TEST_KEY1, strlen(TEST_DATA1) + 1, 0, false); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_ate(mtd_fd, ctx, TEST_KEY1, strlen(TEST_DATA1) + 1, 0, false); + if (ret < 0) { - printf("%s:write ate failed, ret=%d\n", __func__, ret); goto test_fail; } /* write gc_done ate */ - fill_gc_done_ate(ctx, &ate); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_gc_done_ate(mtd_fd, ctx); + if (ret < 0) { - printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); goto test_fail; } /* write close ate, mark section 0 as closed */ - fill_close_ate(ctx, &ate, + ret = write_close_ate(mtd_fd, ctx, CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - 4 * sizeof(struct nvs_ate)); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + - 4 * ate_size); + if (ret < 0) { - printf("%s:write close ate failed, ret=%d\n", __func__, ret); goto test_fail; } @@ -695,7 +793,6 @@ static void test_nvs_corrupted_write(struct mtdnvs_ctx_s *ctx) int nvs_fd = -1; int i; uint8_t erase_value = ctx->erasestate; - struct nvs_ate ate; struct config_data_s data; size_t padding_size; @@ -726,8 +823,8 @@ static void test_nvs_corrupted_write(struct mtdnvs_ctx_s *ctx) goto test_fail; } - padding_size = NVS_ALIGN_UP(sizeof(key1) + sizeof(wr_buf_1)) - - sizeof(key1) - sizeof(wr_buf_1); + padding_size = nvs_align_up(ctx, sizeof(key1) + sizeof(wr_buf_1)) + - sizeof(key1) - sizeof(wr_buf_1); for (i = 0; i < padding_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -758,7 +855,7 @@ static void test_nvs_corrupted_write(struct mtdnvs_ctx_s *ctx) for (i = 2 * (sizeof(key1) + sizeof(wr_buf_1)) + padding_size; i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - 3 * sizeof(struct nvs_ate); i++) + - 3 * nvs_ate_size(ctx); i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); if (ret != sizeof(erase_value)) @@ -770,21 +867,17 @@ static void test_nvs_corrupted_write(struct mtdnvs_ctx_s *ctx) /* write ate */ - fill_ate(ctx, &ate, key1, sizeof(wr_buf_1), 0, false); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_ate(mtd_fd, ctx, key1, sizeof(wr_buf_1), 0, false); + if (ret < 0) { - printf("%s:write ate failed, ret=%d\n", __func__, ret); goto test_fail; } /* write gc_done ate */ - fill_gc_done_ate(ctx, &ate); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_gc_done_ate(mtd_fd, ctx); + if (ret < 0) { - printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); goto test_fail; } @@ -859,6 +952,7 @@ test_fail: static void test_nvs_gc(struct mtdnvs_ctx_s *ctx) { + size_t ate_size = nvs_ate_size(ctx); int ret; int fd = -1; uint8_t buf[44]; @@ -870,10 +964,9 @@ static void test_nvs_gc(struct mtdnvs_ctx_s *ctx) /* max_writes will trigger GC. */ - size_t kv_size = NVS_ALIGN_UP(44 + 4) + sizeof(struct nvs_ate); + size_t kv_size = nvs_align_up(ctx, 44 + 4) + ate_size; size_t block_max_write_size = - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - sizeof(struct nvs_ate); + CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - ate_size; uint16_t block_max_write_nums = block_max_write_size / kv_size; const uint16_t max_writes = block_max_write_nums + 1; @@ -1044,9 +1137,9 @@ static int write_content(uint16_t max_id, uint16_t begin, uint16_t end) for (i = begin; i < end; i++) { uint8_t id = (i % max_id); - uint8_t id_data = id + max_id * (i / max_id); - - memset(buf, id_data, sizeof(buf)); + memset(buf, 0, sizeof(buf)); + buf[43] = i & 0xff; + buf[42] = i >> 8; /* 4 byte key */ @@ -1082,7 +1175,6 @@ test_fail: static int check_content(uint16_t max_id) { uint8_t rd_buf[44]; - uint8_t buf[44]; int fd = -1; int ret; struct config_data_s data; @@ -1110,13 +1202,7 @@ static int check_content(uint16_t max_id) goto test_fail; } - for (uint16_t i = 0; i < sizeof(rd_buf); i++) - { - rd_buf[i] = rd_buf[i] % max_id; - buf[i] = id; - } - - if (memcmp(buf, rd_buf, sizeof(rd_buf)) != 0) + if (((rd_buf[42] << 8) | rd_buf[43]) % max_id != id) { printf("RD buff should be equal to the WR buff\n"); goto test_fail; @@ -1142,17 +1228,16 @@ test_fail: static void test_nvs_gc_3sectors(struct mtdnvs_ctx_s *ctx) { + size_t ate_size = nvs_ate_size(ctx); int ret; /* max_writes will trigger GC */ - size_t kv_size = NVS_ALIGN_UP(44 + 4) + sizeof(struct nvs_ate); - size_t block_max_write_size = - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - sizeof(struct nvs_ate); - uint16_t max_id = block_max_write_size / kv_size; - - const uint16_t max_writes = max_id + 1; + size_t kv_size = nvs_align_up(ctx, 44 + 4) + ate_size; + uint16_t max_id = + CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE / kv_size; + const uint16_t max_writes = + CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE * 2 / kv_size + 1; const uint16_t max_writes_2 = max_writes + max_id; const uint16_t max_writes_3 = max_writes_2 + max_id; const uint16_t max_writes_4 = max_writes_3 + max_id; @@ -1336,16 +1421,16 @@ test_fail: static void test_nvs_corrupted_sector_close(struct mtdnvs_ctx_s *ctx) { + size_t ate_size = nvs_ate_size(ctx); int ret; char key1[] = TEST_KEY1; - uint8_t rd_buf[NVS_ALIGN_UP(512) - sizeof(key1)]; - uint8_t wr_buf[NVS_ALIGN_UP(512) - sizeof(key1)]; + uint8_t wr_buf[nvs_align_up(ctx, 512) - sizeof(key1)]; + uint8_t rd_buf[sizeof(wr_buf)]; int mtd_fd = -1; int nvs_fd = -1; int loop_section; int i; uint8_t erase_value = ctx->erasestate; - struct nvs_ate ate; struct config_data_s data; printf("%s: test begin\n", __func__); @@ -1390,7 +1475,7 @@ static void test_nvs_corrupted_sector_close(struct mtdnvs_ctx_s *ctx) for (i = 2 * (sizeof(key1) + sizeof(wr_buf)); i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - 4 * sizeof(struct nvs_ate); i++) + - 4 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); if (ret != sizeof(erase_value)) @@ -1402,52 +1487,44 @@ static void test_nvs_corrupted_sector_close(struct mtdnvs_ctx_s *ctx) /* write ate 2 times */ - fill_ate(ctx, &ate, key1, sizeof(wr_buf), + ret = write_ate(mtd_fd, ctx, key1, sizeof(wr_buf), sizeof(wr_buf) + sizeof(key1), (loop_section == CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_COUNT - 2) ? false : true); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + if (ret < 0) { - printf("%s:write ate failed, ret=%d\n", __func__, ret); goto test_fail; } - fill_ate(ctx, &ate, key1, sizeof(wr_buf), 0, true); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_ate(mtd_fd, ctx, key1, sizeof(wr_buf), 0, true); + if (ret < 0) { - printf("%s:write ate failed, ret=%d\n", __func__, ret); goto test_fail; } /* write gc_done ate */ - fill_gc_done_ate(ctx, &ate); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_gc_done_ate(mtd_fd, ctx); + if (ret < 0) { - printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); goto test_fail; } if (loop_section == CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_COUNT - 2) { - fill_corrupted_close_ate(ctx, &ate); + ret = write_corrupted_close_ate(mtd_fd, ctx); } else { - fill_close_ate(ctx, &ate, + ret = write_close_ate(mtd_fd, ctx, CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - 4 * sizeof(struct nvs_ate)); + - 4 * ate_size); } - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + if (ret < 0) { - printf("%s:write close ate failed, ret=%d\n", __func__, ret); goto test_fail; } } @@ -1699,8 +1776,7 @@ test_fail: static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) { - struct nvs_ate ate; - struct nvs_ate close_ate; + size_t ate_size = nvs_ate_size(ctx); int mtd_fd = -1; int nvs_fd = -1; int ret; @@ -1738,7 +1814,7 @@ static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) for (i = strlen(TEST_KEY1) + strlen(TEST_DATA1) + 2; i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - 6 * sizeof(struct nvs_ate); i++) + - 6 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); if (ret != sizeof(erase_value)) @@ -1750,20 +1826,18 @@ static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) /* Write valid ate at -6 */ - fill_ate(ctx, &ate, TEST_KEY1, strlen(TEST_DATA1) + 1, 0, false); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_ate(mtd_fd, ctx, TEST_KEY1, strlen(TEST_DATA1) + 1, 0, false); + if (ret < 0) { - printf("%s:write ate failed, ret=%d\n", __func__, ret); goto test_fail; } /* set unused flash to 0xff */ for (i = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - 5 * sizeof(struct nvs_ate); + - 5 * ate_size; i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - 2 * sizeof(struct nvs_ate); i++) + - 2 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); if (ret != sizeof(erase_value)) @@ -1775,21 +1849,17 @@ static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) /* write gc_done ate */ - fill_gc_done_ate(ctx, &ate); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_gc_done_ate(mtd_fd, ctx); + if (ret < 0) { - printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); goto test_fail; } /* write invalid close ate, mark section 0 as closed */ - fill_corrupted_close_ate(ctx, &close_ate); - ret = write(mtd_fd, &close_ate, sizeof(close_ate)); - if (ret != sizeof(ate)) + ret = write_corrupted_close_ate(mtd_fd, ctx); + if (ret < 0) { - printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); goto test_fail; } @@ -1797,7 +1867,7 @@ static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) for (i = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE; i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - sizeof(struct nvs_ate); i++) + - ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); if (ret != sizeof(erase_value)) @@ -1809,9 +1879,8 @@ static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) /* write invalid close ate, mark section 1 as closed */ - fill_corrupted_close_ate(ctx, &close_ate); - ret = write(mtd_fd, &close_ate, sizeof(close_ate)); - if (ret != sizeof(ate)) + ret = write_corrupted_close_ate(mtd_fd, ctx); + if (ret < 0) { printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); goto test_fail; @@ -1887,8 +1956,7 @@ test_fail: static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) { - struct nvs_ate ate; - struct nvs_ate close_ate; + size_t ate_size = nvs_ate_size(ctx); int mtd_fd = -1; int ret; int i; @@ -1896,8 +1964,6 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) printf("%s: test begin\n", __func__); - fill_corrupted_ate(ctx, &ate, TEST_KEY1, 10, 0); - mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME, O_RDWR); if (mtd_fd < 0) { @@ -1920,17 +1986,16 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) /* Write invalid ate */ - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_corrupted_ate(mtd_fd, ctx, TEST_KEY1, 10, 0); + if (ret < 0) { - printf("%s:write ate failed, ret=%d\n", __func__, ret); goto test_fail; } for (i = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE / 2 - + sizeof(struct nvs_ate); + + ate_size; i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - 2 * sizeof(struct nvs_ate); i++) + - 2 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); if (ret != sizeof(erase_value)) @@ -1942,20 +2007,17 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) /* write gc_done ate */ - fill_gc_done_ate(ctx, &ate); - ret = write(mtd_fd, &ate, sizeof(ate)); - if (ret != sizeof(ate)) + ret = write_gc_done_ate(mtd_fd, ctx); + if (ret < 0) { - printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); goto test_fail; } /* write close ate, mark section 0 as closed */ - fill_close_ate(ctx, &close_ate, + ret = write_close_ate(mtd_fd, ctx, CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE / 2); - ret = write(mtd_fd, &close_ate, sizeof(close_ate)); - if (ret != sizeof(ate)) + if (ret < 0) { printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); goto test_fail; @@ -1965,7 +2027,7 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) for (i = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE; i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - - sizeof(struct nvs_ate); i++) + - ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); if (ret != sizeof(erase_value)) @@ -1977,8 +2039,9 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) /* write close ate, mark section 1 as closed */ - ret = write(mtd_fd, &close_ate, sizeof(close_ate)); - if (ret != sizeof(ate)) + ret = write_close_ate(mtd_fd, ctx, + CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE / 2); + if (ret < 0) { printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); goto test_fail; @@ -2573,4 +2636,3 @@ int main(int argc, FAR char *argv[]) free(ctx); return 0; } - From 32facd5b3ae3357f71885fd56e65f528db32c223 Mon Sep 17 00:00:00 2001 From: zhaoxingyu1 Date: Thu, 12 Dec 2024 19:25:15 +0800 Subject: [PATCH 102/568] mtd/nvs: testcases fit the situation where erasestate is 0 Special_id dynamically adjusts based on erase value Signed-off-by: zhaoxingyu1 --- testing/fs/mtd_config_fs/mtd_config_fs_test_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c index fdc254afa..914a16f61 100644 --- a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c +++ b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c @@ -168,7 +168,7 @@ static int write_corrupted_close_ate(int mtd_fd, int ret; memset(close_ate, ctx->erasestate, ate_size); - close_ate->id = 0xffffffff; + close_ate->id = ctx->erasestate; close_ate->len = 0U; ret = write(mtd_fd, &close_ate, ate_size); @@ -196,7 +196,7 @@ static int write_close_ate(int mtd_fd, FAR struct mtdnvs_ctx_s *ctx, int ret; memset(close_ate, ctx->erasestate, ate_size); - close_ate->id = 0xffffffff; + close_ate->id = ctx->erasestate; close_ate->len = 0U; close_ate->offset = offset; fill_crc8_update(close_ate); @@ -225,7 +225,7 @@ static int write_gc_done_ate(int mtd_fd, FAR struct mtdnvs_ctx_s *ctx) int ret; memset(gc_done_ate, ctx->erasestate, ate_size); - gc_done_ate->id = 0xffffffff; + gc_done_ate->id = ctx->erasestate; gc_done_ate->len = 0U; fill_crc8_update(gc_done_ate); @@ -261,8 +261,8 @@ static int write_ate(int mtd_fd, FAR struct mtdnvs_ctx_s *ctx, ate->offset = offset; ate->key_len = strlen(key) + 1; fill_crc8_update(ate); - ate->expired[nvs_align_up(ctx, sizeof(struct nvs_ate))] - = expired ? 0x7f : 0xff; + ate->expired[nvs_align_up(ctx, sizeof(ate)) - sizeof(ate)] + = expired ? ~ctx->erasestate : ctx->erasestate; ret = write(mtd_fd, ate, ate_size); if (ret != ate_size) From 26fcdbd9adf8b48cf3978c4adc20d92501365c46 Mon Sep 17 00:00:00 2001 From: zhaoxingyu1 Date: Tue, 13 Jan 2026 01:39:17 +0800 Subject: [PATCH 103/568] mtdconfig/nvs: fix typo error in nvs testcase such as: 2st->2nd, 3st->3rd and so on Signed-off-by: zhaoxingyu1 --- .../mtd_config_fs/mtd_config_fs_test_main.c | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c index 914a16f61..16ed4cb7e 100644 --- a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c +++ b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c @@ -1293,35 +1293,35 @@ static void test_nvs_gc_3sectors(struct mtdnvs_ctx_s *ctx) ret = write_content(max_id, max_writes, max_writes_2); if (ret < 0) { - printf("%s:2st GC write failed, ret=%d\n", __func__, ret); + printf("%s:2nd GC write failed, ret=%d\n", __func__, ret); goto test_fail; } ret = check_content(max_id); if (ret < 0) { - printf("%s:2st GC check failed, ret=%d\n", __func__, ret); + printf("%s:2nd GC check failed, ret=%d\n", __func__, ret); goto test_fail; } ret = mtdconfig_unregister(); if (ret < 0) { - printf("%s:2st mtdconfig_unregister failed, ret=%d\n", __func__, ret); + printf("%s:2nd mtdconfig_unregister failed, ret=%d\n", __func__, ret); goto test_fail; } ret = setup(ctx); if (ret < 0) { - printf("%s:2st setup failed, ret=%d\n", __func__, ret); + printf("%s:2nd setup failed, ret=%d\n", __func__, ret); goto test_fail; } ret = check_content(max_id); if (ret < 0) { - printf("%s:2st GC check failed, ret=%d\n", __func__, ret); + printf("%s:2nd GC check failed, ret=%d\n", __func__, ret); goto test_fail; } @@ -1330,35 +1330,35 @@ static void test_nvs_gc_3sectors(struct mtdnvs_ctx_s *ctx) ret = write_content(max_id, max_writes_2, max_writes_3); if (ret < 0) { - printf("%s:3st GC write failed, ret=%d\n", __func__, ret); + printf("%s:3rd GC write failed, ret=%d\n", __func__, ret); goto test_fail; } ret = check_content(max_id); if (ret < 0) { - printf("%s:3st GC check failed, ret=%d\n", __func__, ret); + printf("%s:3rd GC check failed, ret=%d\n", __func__, ret); goto test_fail; } ret = mtdconfig_unregister(); if (ret < 0) { - printf("%s:3st mtdconfig_unregister failed, ret=%d\n", __func__, ret); + printf("%s:3rd mtdconfig_unregister failed, ret=%d\n", __func__, ret); goto test_fail; } ret = setup(ctx); if (ret < 0) { - printf("%s:3st setup failed, ret=%d\n", __func__, ret); + printf("%s:3rd setup failed, ret=%d\n", __func__, ret); goto test_fail; } ret = check_content(max_id); if (ret < 0) { - printf("%s:3st GC check failed, ret=%d\n", __func__, ret); + printf("%s:3rd GC check failed, ret=%d\n", __func__, ret); goto test_fail; } @@ -2471,7 +2471,7 @@ static void test_nvs_gc_not_touched_expired_ate(struct mtdnvs_ctx_s *ctx) goto test_fail; } - /* Now udpate A again. + /* Now update A again. * We should trigger gc for once, and we won't need to search for * the old one again after gc. */ @@ -2576,7 +2576,7 @@ int main(int argc, FAR char *argv[]) ctx = malloc(sizeof(struct mtdnvs_ctx_s)); if (ctx == NULL) { - printf("malloc ctx feild,exit!\n"); + printf("malloc ctx field, exit!\n"); exit(1); } From 60d814efa2534630aa9d9b3a0c9454985845e40d Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Wed, 14 Jan 2026 23:23:03 +0800 Subject: [PATCH 104/568] sched/signal: Add support to disable partial or all signals Fix dependency issue when signals are partially or fully enabled Co-authored-by: guoshichao Signed-off-by: Chengdong Wang --- examples/buttons/buttons_main.c | 2 ++ examples/chrono/chrono_main.c | 2 ++ netutils/dhcpc/dhcpc.c | 16 +++++++++++++++ netutils/dhcpd/dhcpd.c | 7 ++++++- netutils/ping/icmp_ping.c | 4 ++++ netutils/telnetd/telnetd_daemon.c | 6 +++--- nshlib/nsh_builtin.c | 23 +++++++++++++++------ nshlib/nsh_proccmds.c | 6 ++++++ system/cu/cu_main.c | 8 ++++++-- testing/ostest/ostest_main.c | 34 ++++++++++++++++++------------- 10 files changed, 82 insertions(+), 26 deletions(-) diff --git a/examples/buttons/buttons_main.c b/examples/buttons/buttons_main.c index d4b36431c..13d4b080a 100644 --- a/examples/buttons/buttons_main.c +++ b/examples/buttons/buttons_main.c @@ -219,9 +219,11 @@ static int button_daemon(int argc, char *argv[]) goto errout_with_fd; } +#ifdef CONFIG_ENABLE_ALL_SIGNALS /* Ignore the default signal action */ signal(CONFIG_EXAMPLES_BUTTONS_SIGNO, SIG_IGN); +#endif /* CONFIG_ENABLE_ALL_SIGNALS */ #endif /* Now loop forever, waiting BUTTONs events */ diff --git a/examples/chrono/chrono_main.c b/examples/chrono/chrono_main.c index ee6658591..9ce5dbb58 100644 --- a/examples/chrono/chrono_main.c +++ b/examples/chrono/chrono_main.c @@ -165,9 +165,11 @@ static int chrono_daemon(int argc, char *argv[]) goto errout_with_fd; } +#ifdef CONFIG_ENABLE_ALL_SIGNALS /* Ignore the default signal action */ signal(BUTTON_SIGNO, SIG_IGN); +#endif /* Now loop forever, waiting BUTTONs events */ diff --git a/netutils/dhcpc/dhcpc.c b/netutils/dhcpc/dhcpc.c index dc6b46230..003d7d8cb 100644 --- a/netutils/dhcpc/dhcpc.c +++ b/netutils/dhcpc/dhcpc.c @@ -533,8 +533,16 @@ static void *dhcpc_run(void *args) struct dhcpc_state result; int ret; +#ifndef CONFIG_ENABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + while (1) { +#ifndef CONFIG_ENABLE_ALL_SIGNALS + pthread_testcancel(); +#endif ret = dhcpc_request(pdhcpc, &result); if (ret == OK) { @@ -701,7 +709,9 @@ void dhcpc_close(FAR void *handle) void dhcpc_cancel(FAR void *handle) { struct dhcpc_state_s *pdhcpc = (struct dhcpc_state_s *)handle; +#ifdef CONFIG_ENABLE_ALL_SIGNALS sighandler_t old; +#endif int ret; if (pdhcpc) @@ -710,6 +720,7 @@ void dhcpc_cancel(FAR void *handle) if (pdhcpc->thread) { +#ifdef CONFIG_ENABLE_ALL_SIGNALS old = signal(SIGQUIT, SIG_IGN); /* Signal the dhcpc_run */ @@ -719,6 +730,9 @@ void dhcpc_cancel(FAR void *handle) { nerr("ERROR: pthread_kill DHCPC thread\n"); } +#else + pthread_cancel(pdhcpc->thread); +#endif /* Wait for the end of dhcpc_run */ @@ -729,7 +743,9 @@ void dhcpc_cancel(FAR void *handle) } pdhcpc->thread = 0; +#ifdef CONFIG_ENABLE_ALL_SIGNALS signal(SIGQUIT, old); +#endif } } } diff --git a/netutils/dhcpd/dhcpd.c b/netutils/dhcpd/dhcpd.c index 558991c22..a382709a2 100644 --- a/netutils/dhcpd/dhcpd.c +++ b/netutils/dhcpd/dhcpd.c @@ -1555,6 +1555,7 @@ static pid_t dhcpd_get_pid(void) * ****************************************************************************/ +#ifdef CONFIG_ENABLE_ALL_SIGNALS static void dhcpd_signal_handler(int signo, FAR siginfo_t *info, FAR void *ctx) { @@ -1562,6 +1563,7 @@ dhcpd_signal_handler(int signo, FAR siginfo_t *info, FAR void *ctx) g_dhcpd_daemon.ds_state = DHCPD_STOP_REQUESTED; } +#endif /**************************************************************************** * Public Functions @@ -1573,7 +1575,9 @@ dhcpd_signal_handler(int signo, FAR siginfo_t *info, FAR void *ctx) int dhcpd_run(FAR const char *interface) { +#ifdef CONFIG_ENABLE_ALL_SIGNALS struct sigaction act; +#endif int sockfd = -1; int nbytes; @@ -1602,11 +1606,12 @@ int dhcpd_run(FAR const char *interface) /* Install signal handler for CONFIG_NETUTILS_DHCPD_SIGWAKEUP */ +#ifdef CONFIG_ENABLE_ALL_SIGNALS memset(&act, 0, sizeof(act)); act.sa_sigaction = dhcpd_signal_handler; act.sa_flags = SA_SIGINFO; sigaction(CONFIG_NETUTILS_DHCPD_SIGWAKEUP, &act, NULL); - +#endif /* Indicate that we have started */ g_dhcpd_daemon.ds_state = DHCPD_RUNNING; diff --git a/netutils/ping/icmp_ping.c b/netutils/ping/icmp_ping.c index 7aa1d3973..55db84854 100644 --- a/netutils/ping/icmp_ping.c +++ b/netutils/ping/icmp_ping.c @@ -91,6 +91,7 @@ static volatile bool g_exiting; * Private Functions ****************************************************************************/ +#ifdef CONFIG_ENABLE_ALL_SIGNALS /**************************************************************************** * Name: sigexit ****************************************************************************/ @@ -99,6 +100,7 @@ static void sigexit(int signo) { g_exiting = true; } +#endif /**************************************************************************** * Name: ping_newid @@ -199,7 +201,9 @@ void icmp_ping(FAR const struct ping_info_s *info) int i; g_exiting = false; +#ifdef CONFIG_ENABLE_ALL_SIGNALS signal(SIGINT, sigexit); +#endif /* Initialize result structure */ diff --git a/netutils/telnetd/telnetd_daemon.c b/netutils/telnetd/telnetd_daemon.c index ed02b1569..989de34f9 100644 --- a/netutils/telnetd/telnetd_daemon.c +++ b/netutils/telnetd/telnetd_daemon.c @@ -74,7 +74,7 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) #endif } addr; -#ifdef CONFIG_SCHED_HAVE_PARENT +#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_ENABLE_ALL_SIGNALS) struct sigaction sa; sigset_t blockset; #endif @@ -85,7 +85,7 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) int optval; #endif -#ifdef CONFIG_SCHED_HAVE_PARENT +#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_ENABLE_ALL_SIGNALS) /* Call sigaction with the SA_NOCLDWAIT flag so that we do not transform * children into "zombies" when they terminate: Child exit status will * not be retained. @@ -113,7 +113,7 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) nerr("ERROR: sigprocmask failed: %d\n", errno); goto errout; } -#endif /* CONFIG_SCHED_HAVE_PARENT */ +#endif /* CONFIG_SCHED_HAVE_PARENT && CONFIG_ENABLE_ALL_SIGNALS */ /* Create a new TCP socket to use to listen for connections */ diff --git a/nshlib/nsh_builtin.c b/nshlib/nsh_builtin.c index 196220f41..76f542f8f 100644 --- a/nshlib/nsh_builtin.c +++ b/nshlib/nsh_builtin.c @@ -74,10 +74,14 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, FAR char **argv, FAR const struct nsh_param_s *param) { -#if !defined(CONFIG_NSH_DISABLEBG) && defined(CONFIG_SCHED_CHILD_STATUS) +#if !defined(CONFIG_NSH_DISABLEBG) && defined(CONFIG_SCHED_CHILD_STATUS) && \ + defined(CONFIG_ENABLE_ALL_SIGNALS) struct sigaction act; struct sigaction old; -#endif +#endif /* !CONFIG_NSH_DISABLEBG && CONFIG_SCHED_CHILD_STATUS && + * CONFIG_ENABLE_ALL_SIGNALS + */ + int ret = OK; /* Lock the scheduler in an attempt to prevent the application from @@ -86,7 +90,8 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, sched_lock(); -#if !defined(CONFIG_NSH_DISABLEBG) && defined(CONFIG_SCHED_CHILD_STATUS) +#if !defined(CONFIG_NSH_DISABLEBG) && \ + defined(CONFIG_SCHED_CHILD_STATUS) && defined(CONFIG_ENABLE_ALL_SIGNALS) /* Ignore the child status if run the application on background. */ if (vtbl->np.np_bg == true) @@ -98,7 +103,9 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, sigaction(SIGCHLD, &act, &old); } -#endif /* CONFIG_NSH_DISABLEBG */ +#endif /* !CONFIG_NSH_DISABLEBG && !CONFIG_SCHED_CHILD_STATUS && + * CONFIG_ENABLE_ALL_SIGNALS + */ /* Try to find and execute the command within the list of builtin * applications. @@ -230,7 +237,8 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, #if !defined(CONFIG_SCHED_WAITPID) || !defined(CONFIG_NSH_DISABLEBG) { -#if !defined(CONFIG_NSH_DISABLEBG) && defined(CONFIG_SCHED_CHILD_STATUS) +#if !defined(CONFIG_NSH_DISABLEBG) && defined(CONFIG_SCHED_CHILD_STATUS) && \ + defined(CONFIG_ENABLE_ALL_SIGNALS) /* Restore the old actions */ @@ -241,7 +249,10 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, sigaction(SIGCHLD, &old, NULL); } -# endif +# endif /* !CONFIG_NSH_DISABLEBG && CONFIG_SCHED_CHILD_STATUS && \ + * CONFIG_ENABLE_ALL_SIGNALS + */ + struct sched_param sched; sched_getparam(ret, &sched); nsh_output(vtbl, "%s [%d:%d]\n", cmd, ret, sched.sched_priority); diff --git a/nshlib/nsh_proccmds.c b/nshlib/nsh_proccmds.c index fe9810564..c7eff26eb 100644 --- a/nshlib/nsh_proccmds.c +++ b/nshlib/nsh_proccmds.c @@ -873,6 +873,7 @@ static int top_cmpcpuload(FAR const void *item1, FAR const void *item2) } } +#ifdef CONFIG_ENABLE_ALL_SIGNALS /**************************************************************************** * Name: top_exit ****************************************************************************/ @@ -881,6 +882,7 @@ static void top_exit(int signo, FAR siginfo_t *siginfo, FAR void *context) { *(FAR bool *)siginfo->si_user = true; } +#endif /* CONFIG_ENABLE_ALL_SIGNALS */ #endif @@ -1357,7 +1359,9 @@ int cmd_top(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) FAR char *pidlist = NULL; size_t num = SIZE_MAX; size_t i; +#ifdef CONFIG_ENABLE_ALL_SIGNALS struct sigaction act; +#endif bool quit = false; int delay = 3; int ret = 0; @@ -1393,6 +1397,7 @@ int cmd_top(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) } } +#ifdef CONFIG_ENABLE_ALL_SIGNALS act.sa_user = &quit; act.sa_sigaction = top_exit; sigemptyset(&act.sa_mask); @@ -1402,6 +1407,7 @@ int cmd_top(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) nsh_error(vtbl, g_fmtcmdfailed, "top", "sigaction", NSH_ERRNO); return ERROR; } +#endif if (vtbl->isctty) { diff --git a/system/cu/cu_main.c b/system/cu/cu_main.c index 8d25038ed..1e991460d 100644 --- a/system/cu/cu_main.c +++ b/system/cu/cu_main.c @@ -124,10 +124,12 @@ static FAR void *cu_listener(FAR void *parameter) return NULL; } +#ifdef CONFIG_ENABLE_ALL_SIGNALS static void sigint(int sig) { g_cu.force_exit = true; } +#endif #ifdef CONFIG_SERIAL_TERMIOS static int set_termios(FAR struct cu_globals_s *cu, int rate, @@ -275,7 +277,9 @@ static int cu_cmd(FAR struct cu_globals_s *cu, char bcmd) int main(int argc, FAR char *argv[]) { pthread_attr_t attr; +#ifdef CONFIG_ENABLE_ALL_SIGNALS struct sigaction sa; +#endif FAR const char *devname = CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE; FAR struct cu_globals_s *cu = &g_cu; #ifdef CONFIG_SERIAL_TERMIOS @@ -295,13 +299,13 @@ int main(int argc, FAR char *argv[]) memset(cu, 0, sizeof(*cu)); cu->escape = '~'; - +#ifdef CONFIG_ENABLE_ALL_SIGNALS /* Install signal handlers */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigint; sigaction(SIGINT, &sa, NULL); - +#endif optind = 0; /* Global that needs to be reset in FLAT mode */ while ((option = getopt(argc, argv, "l:s:ceE:fho?")) != ERROR) { diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 48dc94da7..975a10410 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -278,7 +278,8 @@ static int user_main(int argc, char *argv[]) * verify that status is retained correctly. */ -#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) +#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) && \ + defined(CONFIG_ENABLE_ALL_SIGNALS) { struct sigaction sa; int ret; @@ -511,12 +512,22 @@ static int user_main(int argc, char *argv[]) check_test_memory_usage(); #endif +#ifndef CONFIG_DISABLE_ALL_SIGNALS /* Verify that we can modify the signal mask */ printf("\nuser_main: sigprocmask test\n"); sigprocmask_test(); check_test_memory_usage(); +#if defined(CONFIG_SIG_SIGSTOP_ACTION) && defined(CONFIG_SIG_SIGKILL_ACTION) && \ + !defined(CONFIG_BUILD_KERNEL) + printf("\nuser_main: signal action test\n"); + suspend_test(); + check_test_memory_usage(); +#endif +#endif /* !CONFIG_DISABLE_ALL_SIGNALS */ + +#ifdef CONFIG_ENABLE_ALL_SIGNALS /* Verify signal handlers */ printf("\nuser_main: signal handler test\n"); @@ -527,12 +538,14 @@ static int user_main(int argc, char *argv[]) signest_test(); check_test_memory_usage(); -#if defined(CONFIG_SIG_SIGSTOP_ACTION) && defined(CONFIG_SIG_SIGKILL_ACTION) && \ - !defined(CONFIG_BUILD_KERNEL) - printf("\nuser_main: signal action test\n"); - suspend_test(); +#ifndef CONFIG_DISABLE_POSIX_TIMERS + /* Verify posix timers (with SIGEV_SIGNAL) */ + + printf("\nuser_main: POSIX timer test\n"); + timer_test(); check_test_memory_usage(); #endif +#endif #ifdef CONFIG_BUILD_FLAT printf("\nuser_main: wdog test\n"); @@ -540,21 +553,14 @@ static int user_main(int argc, char *argv[]) check_test_memory_usage(); #endif -#ifndef CONFIG_DISABLE_POSIX_TIMERS - /* Verify posix timers (with SIGEV_SIGNAL) */ - - printf("\nuser_main: POSIX timer test\n"); - timer_test(); - check_test_memory_usage(); - -#ifdef CONFIG_SIG_EVTHREAD +#if !defined(CONFIG_DISABLE_POSIX_TIMERS) && \ + defined(CONFIG_SIG_EVTHREAD) /* Verify posix timers (with SIGEV_THREAD) */ printf("\nuser_main: SIGEV_THREAD timer test\n"); sigev_thread_test(); check_test_memory_usage(); #endif -#endif #if !defined(CONFIG_DISABLE_PTHREAD) && CONFIG_RR_INTERVAL > 0 /* Verify round robin scheduling */ From 3e3b8c6936caf7c42735221535f11d69010dc029 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Mon, 14 Apr 2025 16:23:19 +0800 Subject: [PATCH 105/568] graphics/libyuv: fix the typo. fix the typo. Signed-off-by: zhanghongyu --- graphics/libyuv/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphics/libyuv/CMakeLists.txt b/graphics/libyuv/CMakeLists.txt index 6060e4f34..c792f090f 100644 --- a/graphics/libyuv/CMakeLists.txt +++ b/graphics/libyuv/CMakeLists.txt @@ -41,7 +41,7 @@ if(CONFIG_LIBYUV) FetchContent_GetProperties(libyuv_fetch) if(NOT libyuv_fetch_POPULATED) - FetchContent_Populate(llibyuv_fetch) + FetchContent_Populate(libyuv_fetch) endif() endif() From 5f634815cb8b6fef16f7be5615a786efc4861370 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Tue, 5 Aug 2025 10:57:55 +0800 Subject: [PATCH 106/568] iptables: fix the ipv4 mask conversion error the configured mask should be in network byte order, but the logic here calculates it as host byte order. Signed-off-by: zhanghongyu --- system/iptables/iptables_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/iptables/iptables_utils.c b/system/iptables/iptables_utils.c index 9428e0fea..86c1492de 100644 --- a/system/iptables/iptables_utils.c +++ b/system/iptables/iptables_utils.c @@ -546,7 +546,7 @@ int iptables_parse_ip(FAR const char *str, FAR void *addr, FAR void *mask, return -EINVAL; } - *mask4 <<= 32 - prefixlen; + *mask4 >>= 32 - prefixlen; } #endif From 859fc54c967d26dbfa72bcd80a7cd811e650b970 Mon Sep 17 00:00:00 2001 From: daichuan Date: Fri, 28 Mar 2025 10:16:53 +0800 Subject: [PATCH 107/568] netutils/ping: change socket type to SOCK_RAW The ping socket creation method is changed from SOCK_DGRAM to SOCK_RAW, because SOCK_DGRAM may not have permission in some environments (e.g. Docker). Also add checksum calculation when send, and perform IP header processing when receive. Signed-off-by: daichuan --- netutils/ping/icmp_ping.c | 67 +++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/netutils/ping/icmp_ping.c b/netutils/ping/icmp_ping.c index 55db84854..aa88d0a18 100644 --- a/netutils/ping/icmp_ping.c +++ b/netutils/ping/icmp_ping.c @@ -45,6 +45,7 @@ #include #include +#include #include "netutils/icmp_ping.h" @@ -64,7 +65,6 @@ struct ping_priv_s { struct sockaddr_in destaddr; struct sockaddr_in fromaddr; - struct icmp_hdr_s outhdr; struct pollfd recvfd; socklen_t addrlen; clock_t kickoff; @@ -74,6 +74,7 @@ struct ping_priv_s long elapsed; bool retry; int sockfd; + struct icmp_hdr_s outhdr; }; /**************************************************************************** @@ -181,6 +182,31 @@ static void icmp_callback(FAR struct ping_result_s *result, result->info->callback(result); } +/**************************************************************************** + * Name: icmp_checksum + ****************************************************************************/ + +static uint16_t icmp_checksum(FAR const void *buffer, size_t datalen) +{ + FAR const uint16_t *wptr = (FAR const uint16_t *)buffer; + size_t words = (sizeof(struct icmp_hdr_s) + datalen + 1) / 2; + uint32_t sum = 0; + size_t i; + + for (i = 0; i < words; i++) + { + sum += *wptr++; + if (sum & 0x80000000) + { + sum = (sum & 0XFFFF) + (sum >> 16); + } + } + + sum = (sum >> 16) + (sum & 0XFFFF); + sum += (sum >> 16); + return (uint16_t)(~sum); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -196,6 +222,7 @@ void icmp_ping(FAR const struct ping_info_s *info) FAR struct icmp_hdr_s *inhdr; FAR uint8_t *iobuffer; FAR uint8_t *ptr; + int recvlen; int ret; int ch; int i; @@ -219,16 +246,17 @@ void icmp_ping(FAR const struct ping_info_s *info) /* Allocate memory to hold private data and ping buffer */ - priv = malloc(sizeof(*priv) + result.outsize); + priv = malloc(sizeof(*priv) + sizeof(struct ipv4_hdr_s) + result.outsize); + if (priv == NULL) { icmp_callback(&result, ICMP_E_MEMORY, 0); return; } - iobuffer = (FAR uint8_t *)(priv + 1); + iobuffer = (FAR uint8_t *)(&priv->outhdr); - priv->sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); + priv->sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (priv->sockfd < 0) { icmp_callback(&result, ICMP_E_SOCKET, errno); @@ -257,11 +285,6 @@ void icmp_ping(FAR const struct ping_info_s *info) priv->destaddr.sin_port = 0; priv->destaddr.sin_addr.s_addr = result.dest.s_addr; - memset(&priv->outhdr, 0, sizeof(struct icmp_hdr_s)); - priv->outhdr.type = ICMP_ECHO_REQUEST; - priv->outhdr.id = htons(result.id); - priv->outhdr.seqno = htons(result.seqno); - icmp_callback(&result, ICMP_I_BEGIN, 0); while (result.nrequests < info->count) @@ -271,9 +294,10 @@ void icmp_ping(FAR const struct ping_info_s *info) break; } - /* Copy the ICMP header into the I/O buffer */ - - memcpy(iobuffer, &priv->outhdr, sizeof(struct icmp_hdr_s)); + memset(&priv->outhdr, 0, sizeof(struct icmp_hdr_s)); + priv->outhdr.type = ICMP_ECHO_REQUEST; + priv->outhdr.id = htons(result.id); + priv->outhdr.seqno = htons(result.seqno); /* Add some easily verifiable payload data */ @@ -289,6 +313,10 @@ void icmp_ping(FAR const struct ping_info_s *info) } } + /* Calculate checksum after data padding */ + + priv->outhdr.icmpchksum = icmp_checksum(iobuffer, info->datalen); + priv->start = clock(); result.nrequests++; priv->nsent = sendto(priv->sockfd, iobuffer, result.outsize, 0, @@ -334,9 +362,10 @@ void icmp_ping(FAR const struct ping_info_s *info) /* Get the ICMP response (ignoring the sender) */ + recvlen = sizeof(struct ipv4_hdr_s) + result.outsize; priv->addrlen = sizeof(struct sockaddr_in); priv->nrecvd = recvfrom(priv->sockfd, iobuffer, - result.outsize, 0, + recvlen, 0, (FAR struct sockaddr *)&priv->fromaddr, &priv->addrlen); if (priv->nrecvd < 0) @@ -350,8 +379,11 @@ void icmp_ping(FAR const struct ping_info_s *info) goto wait; } + /* Skip IP header, IP header length including options */ + priv->elapsed = TICK2USEC(clock() - priv->start); - inhdr = (FAR struct icmp_hdr_s *)iobuffer; + inhdr = (FAR struct icmp_hdr_s *) + (iobuffer + sizeof(struct ipv4_hdr_s)); if (inhdr->type == ICMP_ECHO_REPLY) { @@ -383,16 +415,17 @@ void icmp_ping(FAR const struct ping_info_s *info) /* Verify the payload data */ - if (priv->nrecvd != result.outsize) + if (priv->nrecvd != recvlen) { icmp_callback(&result, ICMP_W_RECVBIG, priv->nrecvd); verified = false; } else { - ptr = &iobuffer[sizeof(struct icmp_hdr_s)]; - ch = 0x20; + /* Data start offset: IP header + ICMP header */ + ptr = (FAR uint8_t *)(inhdr + 1); + ch = 0x20; for (i = 0; i < info->datalen; i++, ptr++) { if (*ptr != ch) From 2b0a4a20f55278461248031f5d7078520c492f50 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Wed, 20 Aug 2025 20:05:59 +0800 Subject: [PATCH 108/568] iptables: add file lock to prevent concurrent overwrite the kernel can only prevent the concurrency of s/getsockopt, but iptables will call these interfaces multiple times at a time. We need to wait for one iptables to complete before executing the second one, otherwise the data will be overwritten. iptables flow: get current iptables entries [1] -> add new entry 2 [1,2] -> set to kernel [1,2] get current iptables entries [1] -> add new entry 3 [1,3] -> set to kernel [1,3] entry 2 is lost Signed-off-by: zhanghongyu --- system/iptables/Kconfig | 5 ++++ system/iptables/iptables.c | 58 +++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/system/iptables/Kconfig b/system/iptables/Kconfig index 171b52ed0..a98f00771 100644 --- a/system/iptables/Kconfig +++ b/system/iptables/Kconfig @@ -29,4 +29,9 @@ config SYSTEM_IPTABLES_STACKSIZE int "iptables & ip6tables stack size" default DEFAULT_TASK_STACKSIZE +config SYSTEM_IPTABLES_LOCK_FILE_PATH + string "File lock path to prevent concurrent overwrite" + default "/tmp/iptables.lock" + depends on FS_LOCK_BUCKET_SIZE > 0 + endif diff --git a/system/iptables/iptables.c b/system/iptables/iptables.c index 673559634..367519a34 100644 --- a/system/iptables/iptables.c +++ b/system/iptables/iptables.c @@ -26,6 +26,7 @@ #include +#include #include #include @@ -33,17 +34,62 @@ #include "iptables.h" #include "netutils/netlib.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if CONFIG_FS_LOCK_BUCKET_SIZE == 0 +# define iptables_lock() 0 +# define iptables_unlock(fd) (void)(fd) +#endif + /**************************************************************************** * Private Types ****************************************************************************/ typedef CODE int - (*iptables_command_func_t)(FAR const struct iptables_args_s *args); +(*iptables_command_func_t)(FAR const struct iptables_args_s *args); /**************************************************************************** * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: iptables_lock / iptables_unlock + * + * Description: + * Lock and unlock iptables to prevent concurrent overwrite. + * + ****************************************************************************/ + +#if CONFIG_FS_LOCK_BUCKET_SIZE > 0 +static int iptables_lock(void) +{ + struct flock lock; + int lockfd; + + lockfd = open(CONFIG_SYSTEM_IPTABLES_LOCK_FILE_PATH, O_CREAT | O_RDWR, + 0666); + if (lockfd < 0) + { + return lockfd; + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + fcntl(lockfd, F_SETLKW, &lock); + + return lockfd; +} + +static int iptables_unlock(int lockfd) +{ + return close(lockfd); +} +#endif + /**************************************************************************** * Name: iptables_addr2str * @@ -485,6 +531,7 @@ static int iptables_apply(FAR const struct iptables_args_s *args, int main(int argc, FAR char *argv[]) { struct iptables_args_s args; + int lock; int ret = iptables_parse(&args, argc, argv); if (ret < 0 || args.cmd == COMMAND_INVALID) @@ -493,6 +540,13 @@ int main(int argc, FAR char *argv[]) return ret; } + lock = iptables_lock(); + if (lock < 0) + { + printf("Failed to lock iptables!\n"); + return lock; + } + #ifdef CONFIG_NET_IPFILTER if (args.table == NULL || strcmp(args.table, XT_TABLE_NAME_FILTER) == 0) { @@ -520,5 +574,7 @@ int main(int argc, FAR char *argv[]) printf("Unknown table: %s\n", args.table); } + iptables_unlock(lock); + return ret; } From 91f55245eb8e6dfe2e8e49d5ee54d1302b82069b Mon Sep 17 00:00:00 2001 From: anjiahao Date: Wed, 18 Jun 2025 14:26:57 +0800 Subject: [PATCH 109/568] apps:modify examples elf compile method rearrange the elf test directory, make the sub-testcase in separate directory Signed-off-by: anjiahao --- examples/elf/.gitignore | 1 + examples/elf/CMakeLists.txt | 8 +- examples/elf/Make.defs | 4 +- examples/elf/Makefile | 45 +------- examples/elf/main/.gitignore | 4 + examples/elf/main/CMakeLists.txt | 26 +++++ examples/elf/{ => main}/Kconfig | 0 examples/elf/main/Make.defs | 23 ++++ examples/elf/main/Makefile | 100 ++++++++++++++++++ examples/elf/{ => main}/elf_main.c | 33 +++++- examples/elf/tests/.gitignore | 1 + examples/elf/tests/Make.defs | 39 +++++++ examples/elf/tests/Makefile | 132 +---------------------- examples/elf/tests/errno/Kconfig | 4 + examples/elf/tests/errno/Makefile | 51 ++------- examples/elf/tests/hello/Kconfig | 4 + examples/elf/tests/hello/Makefile | 51 ++------- examples/elf/tests/helloxx/Kconfig | 4 + examples/elf/tests/helloxx/Makefile | 157 ++-------------------------- examples/elf/tests/longjmp/Kconfig | 4 + examples/elf/tests/longjmp/Makefile | 51 ++------- examples/elf/tests/mutex/Kconfig | 4 + examples/elf/tests/mutex/Makefile | 51 ++------- examples/elf/tests/pthread/Kconfig | 4 + examples/elf/tests/pthread/Makefile | 51 ++------- examples/elf/tests/signal/Kconfig | 4 + examples/elf/tests/signal/Makefile | 51 ++------- examples/elf/tests/struct/Kconfig | 4 + examples/elf/tests/struct/Makefile | 51 ++------- examples/elf/tests/task/Kconfig | 4 + examples/elf/tests/task/Makefile | 51 ++------- 31 files changed, 326 insertions(+), 691 deletions(-) create mode 100644 examples/elf/.gitignore create mode 100644 examples/elf/main/.gitignore create mode 100644 examples/elf/main/CMakeLists.txt rename examples/elf/{ => main}/Kconfig (100%) create mode 100644 examples/elf/main/Make.defs create mode 100644 examples/elf/main/Makefile rename examples/elf/{ => main}/elf_main.c (96%) create mode 100644 examples/elf/tests/Make.defs create mode 100644 examples/elf/tests/errno/Kconfig create mode 100644 examples/elf/tests/hello/Kconfig create mode 100644 examples/elf/tests/helloxx/Kconfig create mode 100644 examples/elf/tests/longjmp/Kconfig create mode 100644 examples/elf/tests/mutex/Kconfig create mode 100644 examples/elf/tests/pthread/Kconfig create mode 100644 examples/elf/tests/signal/Kconfig create mode 100644 examples/elf/tests/struct/Kconfig create mode 100644 examples/elf/tests/task/Kconfig diff --git a/examples/elf/.gitignore b/examples/elf/.gitignore new file mode 100644 index 000000000..9e1d2593e --- /dev/null +++ b/examples/elf/.gitignore @@ -0,0 +1 @@ +/Kconfig diff --git a/examples/elf/CMakeLists.txt b/examples/elf/CMakeLists.txt index 3ca9eeb4b..f5b2b0ee6 100644 --- a/examples/elf/CMakeLists.txt +++ b/examples/elf/CMakeLists.txt @@ -20,9 +20,5 @@ # # ############################################################################## -if(CONFIG_EXAMPLES_ELF) - nuttx_add_application(NAME elf SRCS elf_main.c) - - # TODO: tests - -endif() +nuttx_add_subdirectory() +nuttx_generate_kconfig(MENUDESC "Elf") diff --git a/examples/elf/Make.defs b/examples/elf/Make.defs index e01a9d0dd..fe9092e3b 100644 --- a/examples/elf/Make.defs +++ b/examples/elf/Make.defs @@ -20,6 +20,4 @@ # ############################################################################ -ifneq ($(CONFIG_EXAMPLES_ELF),) -CONFIGURED_APPS += $(APPDIR)/examples/elf -endif +include $(wildcard $(APPDIR)/examples/elf/*/Make.defs) diff --git a/examples/elf/Makefile b/examples/elf/Makefile index 8d1e32f13..cde6ca47d 100644 --- a/examples/elf/Makefile +++ b/examples/elf/Makefile @@ -20,47 +20,6 @@ # ############################################################################ -include $(APPDIR)/Make.defs +MENUDESC = "Elf example" -# ELF Example - -ifeq ($(CONFIG_EXAMPLES_ELF_ROMFS),y) -CSRCS = romfs.c -endif -ifeq ($(CONFIG_EXAMPLES_ELF_CROMFS),y) -CSRCS = cromfs.c -endif -CSRCS += dirlist.c -CSRCS += symtab.c -tests$(DELIM)symtab.c_CFLAGS = -fno-builtin -tests$(DELIM)symtab.c_CELFFLAGS = -fno-builtin -MAINSRC = elf_main.c - -PROGNAME = elf -PRIORITY = SCHED_PRIORITY_DEFAULT -STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) -MODULE = $(CONFIG_EXAMPLES_ELF) - -DEPPATH := --dep-path tests - -# Build targets - -VPATH += :tests - -ifeq ($(CONFIG_EXAMPLES_ELF_ROMFS),y) -tests/romfs.c: build -endif -ifeq ($(CONFIG_EXAMPLES_ELF_CROMFS),y) -tests/cromfs.c: build -endif -tests/dirlist.c: build -tests/symtab.c: build - -.PHONY: build -build: - +$(Q) $(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) - -clean:: - +$(Q) $(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) clean - -include $(APPDIR)/Application.mk +include $(APPDIR)/Directory.mk diff --git a/examples/elf/main/.gitignore b/examples/elf/main/.gitignore new file mode 100644 index 000000000..17739289c --- /dev/null +++ b/examples/elf/main/.gitignore @@ -0,0 +1,4 @@ +/elf_romfs.c +/elf_romfs.img +/cromfs.c +/test_symtab.c diff --git a/examples/elf/main/CMakeLists.txt b/examples/elf/main/CMakeLists.txt new file mode 100644 index 000000000..3ae5a347e --- /dev/null +++ b/examples/elf/main/CMakeLists.txt @@ -0,0 +1,26 @@ +# ############################################################################## +# apps/examples/elf/main/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_EXAMPLES_ELF) + nuttx_add_application(NAME elf SRCS elf_main.c) + + # TODO: tests + +endif() diff --git a/examples/elf/Kconfig b/examples/elf/main/Kconfig similarity index 100% rename from examples/elf/Kconfig rename to examples/elf/main/Kconfig diff --git a/examples/elf/main/Make.defs b/examples/elf/main/Make.defs new file mode 100644 index 000000000..bc5af5300 --- /dev/null +++ b/examples/elf/main/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/examples/elf/main/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_ELF),) +CONFIGURED_APPS += $(APPDIR)/examples/elf/main +endif diff --git a/examples/elf/main/Makefile b/examples/elf/main/Makefile new file mode 100644 index 000000000..0cb59156b --- /dev/null +++ b/examples/elf/main/Makefile @@ -0,0 +1,100 @@ +############################################################################ +# apps/examples/elf/main/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# Module example built-in application info + +PROGNAME = elf +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_ELF) + +MAINSRC = elf_main.c + +SYMTABSRC = test_symtab.c +SYMTABOBJ = $(SYMTABSRC:.c=$(OBJEXT)) + + +ifneq ($(CONFIG_BUILD_FLAT),y) + PASS1_SYMTAB = $(TOPDIR)/pass1/mod_symtab.c + MODLUE_NAME = tests +endif + +$(SYMTABSRC): + $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(BINDIR) g_elf >$@.tmp + $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) + + +$(SYMTABOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@, -fno-lto -fno-builtin) + +ifeq ($(CONFIG_EXAMPLES_ELF_ROMFS),y) + +ROMFSIMG = elf_romfs.img +ROMFSSRC = elf_romfs.c +ROMFSOBJ = $(ROMFSSRC:.c=$(OBJEXT)) + +$(ROMFSIMG): + $(Q) genromfs -d $(BINDIR) -f $@ + +$(ROMFSSRC): $(ROMFSIMG) + $(Q) (echo "#include " >$@ && \ + xxd -i $(ROMFSIMG) | sed -e "s/^unsigned char/const unsigned char aligned_data(4)/g" >>$@) + +$(ROMFSOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@, -fno-lto -fno-builtin) + +else ifeq ($(CONFIG_EXAMPLES_ELF_CROMFS),y) + NXTOOLDIR = $(TOPDIR)/tools + GENCROMFSSRC = gencromfs.c + GENCROMFSEXE = gencromfs$(HOSTEXEEXT) + + FSIMG_SRC = cromfs.c + FSIMG_OBJ = $(FSIMG_SRC:.c=$(OBJEXT)) + +$(NXTOOLDIR)/$(GENCROMFSEXE): $(NXTOOLDIR)/$(GENCROMFSSRC) + $(Q) $(MAKE) -C $(NXTOOLDIR) -f Makefile.host $(GENCROMFSEXE) + +# Create the cromfs.c file from the populated cromfs directory + +$(FSIMG_SRC):$(NXTOOLDIR)/$(GENCROMFSEXE) + $(Q) $(NXTOOLDIR)/$(GENCROMFSEXE) $(BINDIR) $@.tmp + $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) + +$(FSIMG_OBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@, -fno-lto -fno-builtin) + +endif + +# Copy the symbol table into the kernel pass1/ build directory + +ifneq ($(CONFIG_BUILD_FLAT),y) +$(PASS1_SYMTAB): $(SYMTABSRC) + $(Q) install -m 0644 $(SYMTABSRC) $(PASS1_SYMTAB) + $(Q) mv $(BINDIR)$(DELIM)$(MODLUE_NAME) . +endif + +postinstall:: $(ROMFSOBJ) $(SYMTABOBJ) $(FSIMG_OBJ) $(PASS1_SYMTAB) + $(call ARLOCK, $(call CONVERT_PATH,$(BIN)), $^) + +distclean:: + $(Q) $(call DELFILE, $(SYMTABSRC) $(SYMTABOBJ) $(ROMFSSRC) $(ROMFSIMG) $(ROMFSOBJ) $(MODLUE_NAME)) + + +include $(APPDIR)/Application.mk diff --git a/examples/elf/elf_main.c b/examples/elf/main/elf_main.c similarity index 96% rename from examples/elf/elf_main.c rename to examples/elf/main/elf_main.c index d6950c1c8..23930e1f9 100644 --- a/examples/elf/elf_main.c +++ b/examples/elf/main/elf_main.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/examples/elf/elf_main.c + * apps/examples/elf/main/elf_main.c * * SPDX-License-Identifier: Apache-2.0 * @@ -132,8 +132,35 @@ extern const unsigned int elf_romfs_img_len; # error "No file system selected" #endif -extern const char *dirlist[]; - +const char *dirlist[] = +{ + "errno", + "hello", + "signal", + "struct", +#ifdef CONFIG_HAVE_CXX + "hello++1", + "hello++2", +# ifdef CONFIG_HAVE_CXXINITIALIZE + "hello++3", +# endif +# ifdef CONFIG_EXAMPLES_ELF_CXX + "hello++4", + "hello++5", +# endif +#endif +#ifdef CONFIG_EXAMPLES_ELF_LONGJMP + "longjmp" +#endif +#ifndef CONFIG_DISABLE_PTHREAD + "mutex", + "pthread", +#endif +#ifndef CONFIG_ARCH_ADDRENV + "task", +#endif + NULL +}; extern const struct symtab_s g_elf_exports[]; extern const int g_elf_nexports; diff --git a/examples/elf/tests/.gitignore b/examples/elf/tests/.gitignore index 416f7e66e..78af96a0d 100644 --- a/examples/elf/tests/.gitignore +++ b/examples/elf/tests/.gitignore @@ -6,3 +6,4 @@ /dirlist.c /extfs /symtab.c +/Kconfig diff --git a/examples/elf/tests/Make.defs b/examples/elf/tests/Make.defs new file mode 100644 index 000000000..b8f77f37c --- /dev/null +++ b/examples/elf/tests/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/examples/elf/tests/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifeq ($(CONFIG_EXAMPLES_ELF),y) + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/errno + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/hello + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/signal + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/struct + ifeq ($(CONFIG_HAVE_CXX),y) + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/helloxx + endif + ifeq ($(CONFIG_EXAMPLES_ELF_LONGJMP),y) + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/longjmp + endif + ifneq ($(CONFIG_DISABLE_PTHREAD),y) + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/mutex + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/pthread + endif + ifneq ($(CONFIG_ARCH_ADDRENV),y) + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/task + endif +endif diff --git a/examples/elf/tests/Makefile b/examples/elf/tests/Makefile index f73d31fc9..741d9d7a9 100644 --- a/examples/elf/tests/Makefile +++ b/examples/elf/tests/Makefile @@ -20,134 +20,6 @@ # ############################################################################ -include $(APPDIR)/Make.defs +MENUDESC = "Elf tests example" -ALL_SUBDIRS = errno hello helloxx longjmp mutex pthread signal task struct -BUILD_SUBDIRS = errno hello struct signal - -ifeq ($(CONFIG_HAVE_CXX),y) -BUILD_SUBDIRS += helloxx -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_LONGJMP),y) -BUILD_SUBDIRS += longjmp -endif - -ifneq ($(CONFIG_DISABLE_PTHREAD),y) -BUILD_SUBDIRS += mutex pthread -endif - -ifneq ($(CONFIG_ARCH_ADDRENV),y) -BUILD_SUBDIRS += task -endif - -ELF_DIR = $(APPDIR)/examples/elf -TESTS_DIR = $(ELF_DIR)/tests -DIRLIST_SRC = $(TESTS_DIR)/dirlist.c -SYMTAB_SRC = $(TESTS_DIR)/symtab.c - -ifeq ($(CONFIG_EXAMPLES_ELF_ROMFS),y) - FSIMG_SUBDIR = romfs - FSIMG_DIR = $(TESTS_DIR)/$(FSIMG_SUBDIR) - ROMFS_IMG = $(TESTS_DIR)/romfs.img - FSIMG_SRC = $(TESTS_DIR)/romfs.c -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_CROMFS),y) - NXTOOLDIR = $(TOPDIR)/tools - GENCROMFSSRC = gencromfs.c - GENCROMFSEXE = gencromfs$(HOSTEXEEXT) - - FSIMG_SUBDIR = cromfs - FSIMG_DIR = $(TESTS_DIR)/$(FSIMG_SUBDIR) - FSIMG_SRC = $(TESTS_DIR)/cromfs.c -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_EXTERN),y) - FSIMG_SUBDIR = extfs - FSIMG_DIR = $(TESTS_DIR)/$(FSIMG_SUBDIR) -endif - -# generate the romfs image in case the fs type is romfs -# the FSIMG_SRC is not actually generated. - -ifeq ($(CONFIG_EXAMPLES_ELF_FSTYPE), "romfs") - ROMFS_IMG = $(TESTS_DIR)/romfs.img - FSIMG_SRC = $(TESTS_DIR)/romfs.c -endif - -define DIR_template -$(1)_$(2): - +$(Q) $(MAKE) -C $(1) $(2) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" FSIMG_DIR="$(FSIMG_DIR)" CROSSDEV=$(CROSSDEV) -endef - -all: $(FSIMG_SRC) $(DIRLIST_SRC) $(SYMTAB_SRC) -.PHONY: all clean install - -$(foreach DIR, $(ALL_SUBDIRS), $(eval $(call DIR_template,$(DIR),clean))) -$(foreach DIR, $(BUILD_SUBDIRS), $(eval $(call DIR_template,$(DIR),install))) - -# Install each program in the file system image directory - -install: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_install) - -ifeq ($(CONFIG_EXAMPLES_ELF_ROMFS),y) -# Create the romfs.img file from the populated romfs directory - -$(ROMFS_IMG): install - $(Q) genromfs -f $@.tmp -d $(FSIMG_DIR) -V "ELFTEST" - $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) - -# Create the romfs.c file from the romfs.img file - -$(FSIMG_SRC): $(ROMFS_IMG) - $(Q) (cd $(TESTS_DIR) && echo "#include " >$@ && \ - xxd -i romfs.img | sed -e "s/^unsigned char/const unsigned char aligned_data(4)/g" | \ - sed -e "s/romfs_img/elf_romfs_img/g" >>$@) - -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_CROMFS),y) -# Make sure that the NuttX gencromfs tool has been built - -$(NXTOOLDIR)/$(GENCROMFSEXE): $(NXTOOLDIR)/$(GENCROMFSSRC) - $(Q) $(MAKE) -C $(NXTOOLDIR) -f Makefile.host $(GENCROMFSEXE) - -# Create the cromfs.h header file from the populated cromfs directory - -$(FSIMG_SRC): install $(NXTOOLDIR)/$(GENCROMFSEXE) - $(Q) $(NXTOOLDIR)/$(GENCROMFSEXE) $(FSIMG_DIR) $@.tmp - $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) - -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_FSTYPE),"romfs") -# Create the romfs.img file from the populated romfs directory - -$(ROMFS_IMG): install - $(Q) genromfs -f $@.tmp -d $(FSIMG_DIR) -V "ELFTEST" - $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) - -# Create the romfs.c file from the romfs.img file - -$(FSIMG_SRC): $(ROMFS_IMG) - -endif - -# Create the dirlist.h header file from the file system image directory - -$(DIRLIST_SRC): install - $(Q) $(TESTS_DIR)/mkdirlist.sh $(FSIMG_DIR) >$@.tmp - $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) - -# Create the exported symbol table - -$(SYMTAB_SRC): install - $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(FSIMG_DIR) g_elf >$@.tmp - $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) - -# Clean each subdirectory - -clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean) - $(Q) rm -f $(FSIMG_SRC) $(DIRLIST_SRC) $(ROMFS_IMG) $(SYMTAB_SRC) - $(Q) rm -rf $(FSIMG_DIR) +include $(APPDIR)/Directory.mk diff --git a/examples/elf/tests/errno/Kconfig b/examples/elf/tests/errno/Kconfig new file mode 100644 index 000000000..f72f3c094 --- /dev/null +++ b/examples/elf/tests/errno/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/examples/elf/tests/errno/Makefile b/examples/elf/tests/errno/Makefile index 2f9d2a13a..ee383144d 100644 --- a/examples/elf/tests/errno/Makefile +++ b/examples/elf/tests/errno/Makefile @@ -22,49 +22,10 @@ include $(APPDIR)/Make.defs -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -else -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -endif -endif +PROGNAME = errno +PRIORITY = 100 +STACKSIZE = $(CONFIG_ELF_STACKSIZE) +MODULE = m +MAINSRC = errno.c -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDLIBS += -lc -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDLIBS += -lproxies -endif - -BIN = errno - -SRCS = $(BIN).c -OBJS = $(SRCS:.c=$(OBJEXT)) - -all: $(BIN) -.PHONY: all clean install - -$(OBJS): %$(OBJEXT): %.c - @echo "CC: $<" - $(Q) $(CC) -c $(CELFFLAGS) $< -o $@ - -$(BIN): $(OBJS) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -$(FSIMG_DIR)/$(BIN): $(BIN) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN) $(FSIMG_DIR)/$(BIN) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN) -endif - -install: $(FSIMG_DIR)/$(BIN) - -clean: - $(call DELFILE, $(BIN)) - $(call CLEAN) +include $(APPDIR)/Application.mk diff --git a/examples/elf/tests/hello/Kconfig b/examples/elf/tests/hello/Kconfig new file mode 100644 index 000000000..f72f3c094 --- /dev/null +++ b/examples/elf/tests/hello/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/examples/elf/tests/hello/Makefile b/examples/elf/tests/hello/Makefile index 88ec0f0a8..6920b1522 100644 --- a/examples/elf/tests/hello/Makefile +++ b/examples/elf/tests/hello/Makefile @@ -22,49 +22,10 @@ include $(APPDIR)/Make.defs -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -else -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -endif -endif +PROGNAME = hello +PRIORITY = 100 +STACKSIZE = $(CONFIG_ELF_STACKSIZE) +MODULE = m +MAINSRC = hello.c -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDLIBS += -lc -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDLIBS += -lproxies -endif - -BIN = hello - -SRCS = $(BIN).c -OBJS = $(SRCS:.c=$(OBJEXT)) - -all: $(BIN) -.PHONY: all clean install - -$(OBJS): %$(OBJEXT): %.c - @echo "CC: $<" - $(Q) $(CC) -c $(CELFFLAGS) $< -o $@ - -$(BIN): $(OBJS) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -$(FSIMG_DIR)/$(BIN): $(BIN) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN) $(FSIMG_DIR)/$(BIN) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN) -endif - -install: $(FSIMG_DIR)/$(BIN) - -clean: - $(call DELFILE, $(BIN)) - $(call CLEAN) +include $(APPDIR)/Application.mk diff --git a/examples/elf/tests/helloxx/Kconfig b/examples/elf/tests/helloxx/Kconfig new file mode 100644 index 000000000..f72f3c094 --- /dev/null +++ b/examples/elf/tests/helloxx/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/examples/elf/tests/helloxx/Makefile b/examples/elf/tests/helloxx/Makefile index b2f276834..667bf453d 100644 --- a/examples/elf/tests/helloxx/Makefile +++ b/examples/elf/tests/helloxx/Makefile @@ -22,156 +22,19 @@ include $(APPDIR)/Make.defs -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -else -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -endif -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDLIBS += -lc -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDLIBS += -lproxies -endif - -BIN1 = hello++1 -ALL_BIN = $(FSIMG_DIR)/$(BIN1) -BIN2 = hello++2 -ALL_BIN += $(FSIMG_DIR)/$(BIN2) +PROGNAME = hello++1 hello++2 +PRIORITY = 100 +STACKSIZE = $(CONFIG_ELF_STACKSIZE) +MODULE = m +MAINSRC = hello++1.cxx hello++2.cxx ifeq ($(CONFIG_HAVE_CXXINITIALIZE),y) -BIN3 = hello++3 -ALL_BIN += $(FSIMG_DIR)/$(BIN3) -ifeq ($(CONFIG_EXAMPLES_ELF_CXX),y) -BIN4 = hello++4 -ALL_BIN += $(FSIMG_DIR)/$(BIN4) -BIN5 = hello++5 -ALL_BIN += $(FSIMG_DIR)/$(BIN5) -endif -endif - -SRCS1 = $(BIN1).c -OBJS1 = $(SRCS1:.c=$(OBJEXT)) - -SRCS2 = $(BIN2).c -OBJS2 = $(SRCS2:.c=$(OBJEXT)) - -ifeq ($(CONFIG_HAVE_CXXINITIALIZE),y) -SRCS3 = $(BIN3).c -OBJS3 = $(SRCS3:.c=$(OBJEXT)) -ifeq ($(CONFIG_EXAMPLES_ELF_CXX),y) -SRCS4 = $(BIN4).c -OBJS4 = $(SRCS4:.c=$(OBJEXT)) -SRCS5 = $(BIN5).c -OBJS5 = $(SRCS5:.c=$(OBJEXT)) -endif -endif - -SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) $(SRCS5) -OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) - -LDLIBSTDC_STUBS_DIR = $(TOPDIR)/libxx -LDLIBSTDC_STUBS_LIB = $(LDLIBSTDC_STUBS_DIR)/liblibxx.a - -all: $(BIN1) $(BIN2) $(BIN3) $(BIN4) $(BIN5) -.PHONY: all clean install - -$(OBJS): %$(OBJEXT): %.cxx - @echo "CC: $<" - $(Q) $(CXX) -c $(CXXELFFLAGS) $< -o $@ - -# This contains libstdc++ stubs to that you can build C++ code -# without actually having libstdc++ - -$(LDLIBSTDC_STUBS_LIB): - $(Q) $(MAKE) -C $(LDLIBSTDC_STUBS_DIR) TOPDIR=$(TOPDIR) - -# BIN1 and BIN2 link just like C code because they contain no -# static constructors. BIN1 is equivalent to a C hello world; -# BIN2 contains a class that implements hello world, but it is -# not statically initialized. - -$(BIN1): $(OBJS1) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -$(BIN2): $(OBJS2) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -# BIN3 is equivalent to BIN2 except that is uses static initializers - -ifeq ($(CONFIG_HAVE_CXXINITIALIZE),y) -$(BIN3): $(OBJS3) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -# BIN4 is similar to BIN3 except that it uses the streams code from libstdc++ -# Both BIN4 and BIN5 use exceptions -# NOTE: libstdc++ is not available for NuttX as of this writing -# -ifeq ($(CONFIG_EXAMPLES_ELF_CXX),y) -ifeq ($(CONFIG_CXX_EXCEPTION),y) -$(BIN4): $(OBJS4) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) -$(BIN5): $(OBJS5) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) -endif -endif -endif - -$(FSIMG_DIR)/$(BIN1): $(BIN1) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN1) $(FSIMG_DIR)/$(BIN1) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN1) -endif - -$(FSIMG_DIR)/$(BIN2): $(BIN2) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN2) $(FSIMG_DIR)/$(BIN2) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN2) -endif - -ifeq ($(CONFIG_HAVE_CXXINITIALIZE),y) -$(FSIMG_DIR)/$(BIN3): $(BIN3) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN3) $(FSIMG_DIR)/$(BIN3) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN3) + PROGNAME += hello++3 + MAINSRC += hello++3.cxx endif ifeq ($(CONFIG_EXAMPLES_ELF_CXX),y) -$(FSIMG_DIR)/$(BIN4): $(BIN4) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN4) $(FSIMG_DIR)/$(BIN4) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN4) + PROGNAME += hello++4 hello++5 + MAINSRC += hello++4.cxx hello++5.cxx endif -$(FSIMG_DIR)/$(BIN5): $(BIN5) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN5) $(FSIMG_DIR)/$(BIN5) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN5) -endif -endif -endif - -install: $(ALL_BIN) - -clean: - $(call DELFILE, $(BIN1)) - $(call DELFILE, $(BIN2)) - $(call DELFILE, $(BIN3)) - $(call DELFILE, $(BIN4)) - $(call DELFILE, $(BIN5)) - $(call CLEAN) +include $(APPDIR)/Application.mk diff --git a/examples/elf/tests/longjmp/Kconfig b/examples/elf/tests/longjmp/Kconfig new file mode 100644 index 000000000..f72f3c094 --- /dev/null +++ b/examples/elf/tests/longjmp/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/examples/elf/tests/longjmp/Makefile b/examples/elf/tests/longjmp/Makefile index fa792e6ff..a5e482f28 100644 --- a/examples/elf/tests/longjmp/Makefile +++ b/examples/elf/tests/longjmp/Makefile @@ -22,49 +22,10 @@ include $(APPDIR)/Make.defs -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -else -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -endif -endif +PROGNAME = longjmp +PRIORITY = 100 +STACKSIZE = $(CONFIG_ELF_STACKSIZE) +MODULE = m +MAINSRC = longjmp.c -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDLIBS += -lc -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDLIBS += -lproxies -endif - -BIN = longjmp - -SRCS = $(BIN).c -OBJS = $(SRCS:.c=$(OBJEXT)) - -all: $(BIN) -.PHONY: all clean install - -$(OBJS): %$(OBJEXT): %.c - @echo "CC: $<" - $(Q) $(CC) -c $(CELFFLAGS) $< -o $@ - -$(BIN): $(OBJS) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -$(FSIMG_DIR)/$(BIN): $(BIN) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN) $(FSIMG_DIR)/$(BIN) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN) -endif - -install: $(FSIMG_DIR)/$(BIN) - -clean: - $(call DELFILE, $(BIN)) - $(call CLEAN) +include $(APPDIR)/Application.mk diff --git a/examples/elf/tests/mutex/Kconfig b/examples/elf/tests/mutex/Kconfig new file mode 100644 index 000000000..f72f3c094 --- /dev/null +++ b/examples/elf/tests/mutex/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/examples/elf/tests/mutex/Makefile b/examples/elf/tests/mutex/Makefile index 5fec89d3c..fe3619513 100644 --- a/examples/elf/tests/mutex/Makefile +++ b/examples/elf/tests/mutex/Makefile @@ -22,49 +22,10 @@ include $(APPDIR)/Make.defs -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -else -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -endif -endif +PROGNAME = mutex +PRIORITY = 100 +STACKSIZE = $(CONFIG_ELF_STACKSIZE) +MODULE = m +MAINSRC = mutex.c -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDLIBS += -lc -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDLIBS += -lproxies -endif - -BIN = mutex - -SRCS = $(BIN).c -OBJS = $(SRCS:.c=$(OBJEXT)) - -all: $(BIN) -.PHONY: all clean install - -$(OBJS): %$(OBJEXT): %.c - @echo "CC: $<" - $(Q) $(CC) -c $(CELFFLAGS) $< -o $@ - -$(BIN): $(OBJS) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -$(FSIMG_DIR)/$(BIN): $(BIN) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN) $(FSIMG_DIR)/$(BIN) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN) -endif - -install: $(FSIMG_DIR)/$(BIN) - -clean: - $(call DELFILE, $(BIN)) - $(call CLEAN) +include $(APPDIR)/Application.mk diff --git a/examples/elf/tests/pthread/Kconfig b/examples/elf/tests/pthread/Kconfig new file mode 100644 index 000000000..f72f3c094 --- /dev/null +++ b/examples/elf/tests/pthread/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/examples/elf/tests/pthread/Makefile b/examples/elf/tests/pthread/Makefile index 61108bc5f..b1ca8c70d 100644 --- a/examples/elf/tests/pthread/Makefile +++ b/examples/elf/tests/pthread/Makefile @@ -22,49 +22,10 @@ include $(APPDIR)/Make.defs -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -else -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -endif -endif +PROGNAME = pthread +PRIORITY = 100 +STACKSIZE = $(CONFIG_ELF_STACKSIZE) +MODULE = m +MAINSRC = pthread.c -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDLIBS += -lc -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDLIBS += -lproxies -endif - -BIN = pthread - -SRCS = $(BIN).c -OBJS = $(SRCS:.c=$(OBJEXT)) - -all: $(BIN) -.PHONY: all clean install - -$(OBJS): %$(OBJEXT): %.c - @echo "CC: $<" - $(Q) $(CC) -c $(CELFFLAGS) $< -o $@ - -$(BIN): $(OBJS) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -$(FSIMG_DIR)/$(BIN): $(BIN) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN) $(FSIMG_DIR)/$(BIN) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN) -endif - -install: $(FSIMG_DIR)/$(BIN) - -clean: - $(call DELFILE, $(BIN)) - $(call CLEAN) +include $(APPDIR)/Application.mk diff --git a/examples/elf/tests/signal/Kconfig b/examples/elf/tests/signal/Kconfig new file mode 100644 index 000000000..f72f3c094 --- /dev/null +++ b/examples/elf/tests/signal/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/examples/elf/tests/signal/Makefile b/examples/elf/tests/signal/Makefile index 21df11dd0..64d674033 100644 --- a/examples/elf/tests/signal/Makefile +++ b/examples/elf/tests/signal/Makefile @@ -22,49 +22,10 @@ include $(APPDIR)/Make.defs -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -else -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -endif -endif +PROGNAME = signal +PRIORITY = 100 +STACKSIZE = $(CONFIG_ELF_STACKSIZE) +MODULE = m +MAINSRC = signal.c -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDLIBS += -lc -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDLIBS += -lproxies -endif - -BIN = signal - -SRCS = $(BIN).c -OBJS = $(SRCS:.c=$(OBJEXT)) - -all: $(BIN) -.PHONY: all clean install - -$(OBJS): %$(OBJEXT): %.c - @echo "CC: $<" - $(Q) $(CC) -c $(CELFFLAGS) $< -o $@ - -$(BIN): $(OBJS) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -$(FSIMG_DIR)/$(BIN): $(BIN) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN) $(FSIMG_DIR)/$(BIN) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN) -endif - -install: $(FSIMG_DIR)/$(BIN) - -clean: - $(call DELFILE, $(BIN)) - $(call CLEAN) +include $(APPDIR)/Application.mk diff --git a/examples/elf/tests/struct/Kconfig b/examples/elf/tests/struct/Kconfig new file mode 100644 index 000000000..f72f3c094 --- /dev/null +++ b/examples/elf/tests/struct/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/examples/elf/tests/struct/Makefile b/examples/elf/tests/struct/Makefile index 990d990c2..88ab66f3f 100644 --- a/examples/elf/tests/struct/Makefile +++ b/examples/elf/tests/struct/Makefile @@ -22,48 +22,11 @@ include $(APPDIR)/Make.defs -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -else -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -endif -endif +PROGNAME = struct +PRIORITY = 100 +STACKSIZE = $(CONFIG_ELF_STACKSIZE) +MODULE = m +CSRCS = struct_dummy.c +MAINSRC = struct_main.c -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDLIBS += -lc -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDLIBS += -lproxies -endif - -BIN = struct -SRCS = struct_main.c struct_dummy.c -OBJS = $(SRCS:.c=$(OBJEXT)) - -all: $(BIN) -.PHONY: all clean install - -$(OBJS): %$(OBJEXT): %.c - @echo "CC: $<" - $(Q) $(CC) -c $(CELFFLAGS) $< -o $@ - -$(BIN): $(OBJS) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -$(FSIMG_DIR)/$(BIN): $(BIN) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN) $(FSIMG_DIR)/$(BIN) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN) -endif - -install: $(FSIMG_DIR)/$(BIN) - -clean: - $(call DELFILE, $(BIN)) - $(call CLEAN) +include $(APPDIR)/Application.mk diff --git a/examples/elf/tests/task/Kconfig b/examples/elf/tests/task/Kconfig new file mode 100644 index 000000000..f72f3c094 --- /dev/null +++ b/examples/elf/tests/task/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/examples/elf/tests/task/Makefile b/examples/elf/tests/task/Makefile index b57b98885..09424ac96 100644 --- a/examples/elf/tests/task/Makefile +++ b/examples/elf/tests/task/Makefile @@ -22,49 +22,10 @@ include $(APPDIR)/Make.defs -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -else -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDELFFLAGS += -Bstatic -LDLIBPATH += -L $(NUTTXLIB) -endif -endif +PROGNAME = task +PRIORITY = 100 +STACKSIZE = $(CONFIG_ELF_STACKSIZE) +MODULE = m +MAINSRC = task.c -ifeq ($(CONFIG_EXAMPLES_ELF_LIBC),y) -LDLIBS += -lc -endif - -ifeq ($(CONFIG_EXAMPLES_ELF_SYSCALL),y) -LDLIBS += -lproxies -endif - -BIN = task - -SRCS = $(BIN).c -OBJS = $(SRCS:.c=$(OBJEXT)) - -all: $(BIN) -.PHONY: all clean install - -$(OBJS): %$(OBJEXT): %.c - @echo "CC: $<" - $(Q) $(CC) -c $(CELFFLAGS) $< -o $@ - -$(BIN): $(OBJS) - @echo "LD: $<" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS) - -$(FSIMG_DIR)/$(BIN): $(BIN) - $(Q) mkdir -p $(FSIMG_DIR) - $(Q) install $(BIN) $(FSIMG_DIR)/$(BIN) -ifneq ($(CONFIG_DEBUG_SYMBOLS),y) - $(Q) $(STRIP) $(FSIMG_DIR)/$(BIN) -endif - -install: $(FSIMG_DIR)/$(BIN) - -clean: - $(call DELFILE, $(BIN)) - $(call CLEAN) +include $(APPDIR)/Application.mk From 27e0811312423c459053552db1c86bbfb7676edf Mon Sep 17 00:00:00 2001 From: anjiahao Date: Fri, 29 Aug 2025 10:05:06 +0800 Subject: [PATCH 110/568] elf:Delete unnecessary generation, elf does not use kernel api delete the mod_symtab.c generate procedure Signed-off-by: anjiahao --- examples/elf/main/Makefile | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/examples/elf/main/Makefile b/examples/elf/main/Makefile index 0cb59156b..074ea6a3d 100644 --- a/examples/elf/main/Makefile +++ b/examples/elf/main/Makefile @@ -30,12 +30,6 @@ MAINSRC = elf_main.c SYMTABSRC = test_symtab.c SYMTABOBJ = $(SYMTABSRC:.c=$(OBJEXT)) - -ifneq ($(CONFIG_BUILD_FLAT),y) - PASS1_SYMTAB = $(TOPDIR)/pass1/mod_symtab.c - MODLUE_NAME = tests -endif - $(SYMTABSRC): $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(BINDIR) g_elf >$@.tmp $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) @@ -82,15 +76,7 @@ $(FSIMG_OBJ): %$(OBJEXT): %.c endif -# Copy the symbol table into the kernel pass1/ build directory - -ifneq ($(CONFIG_BUILD_FLAT),y) -$(PASS1_SYMTAB): $(SYMTABSRC) - $(Q) install -m 0644 $(SYMTABSRC) $(PASS1_SYMTAB) - $(Q) mv $(BINDIR)$(DELIM)$(MODLUE_NAME) . -endif - -postinstall:: $(ROMFSOBJ) $(SYMTABOBJ) $(FSIMG_OBJ) $(PASS1_SYMTAB) +postinstall:: $(ROMFSOBJ) $(SYMTABOBJ) $(FSIMG_OBJ) $(call ARLOCK, $(call CONVERT_PATH,$(BIN)), $^) distclean:: From 6630c0878318b1bec0ef9d86252a6895ab12b1d2 Mon Sep 17 00:00:00 2001 From: v-tangmeng Date: Fri, 31 Oct 2025 14:10:10 +0800 Subject: [PATCH 111/568] examples/elf: add support for CONFIG_DISABLE_SIGNALS make the example elf can work with SIGNAL disabled Signed-off-by: v-tangmeng --- examples/elf/main/elf_main.c | 2 ++ examples/elf/tests/Make.defs | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/elf/main/elf_main.c b/examples/elf/main/elf_main.c index 23930e1f9..7a52b5f6e 100644 --- a/examples/elf/main/elf_main.c +++ b/examples/elf/main/elf_main.c @@ -136,7 +136,9 @@ const char *dirlist[] = { "errno", "hello", +#ifndef CONFIG_DISABLE_SIGNALS "signal", +#endif "struct", #ifdef CONFIG_HAVE_CXX "hello++1", diff --git a/examples/elf/tests/Make.defs b/examples/elf/tests/Make.defs index b8f77f37c..e29058c49 100644 --- a/examples/elf/tests/Make.defs +++ b/examples/elf/tests/Make.defs @@ -21,7 +21,9 @@ ifeq ($(CONFIG_EXAMPLES_ELF),y) CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/errno CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/hello - CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/signal + ifneq ($(CONFIG_DISABLE_SIGNALS),y) + CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/signal + endif CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/struct ifeq ($(CONFIG_HAVE_CXX),y) CONFIGURED_APPS += $(APPDIR)/examples/elf/tests/helloxx From 63e26504879e2b5abee7f210806a39375ed22331 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 25 Nov 2025 20:32:40 +0800 Subject: [PATCH 112/568] elf:avoid interference between different ELFs generated by symtab if defined CONFIG_EXAMPLES_ELF and CONFIG_EXAMPLES_MODLUE, elf will generated BINDIR, so generated symtab will interference. It supports inputting multiple specified files in mksymtab.sh to avoid interference. Signed-off-by: anjiahao --- examples/elf/main/Makefile | 28 +++++++++- examples/module/main/Makefile | 5 +- tools/mksymtab.sh | 99 ++++++++++++++++++++++++++--------- 3 files changed, 102 insertions(+), 30 deletions(-) diff --git a/examples/elf/main/Makefile b/examples/elf/main/Makefile index 074ea6a3d..76093ea5f 100644 --- a/examples/elf/main/Makefile +++ b/examples/elf/main/Makefile @@ -30,8 +30,34 @@ MAINSRC = elf_main.c SYMTABSRC = test_symtab.c SYMTABOBJ = $(SYMTABSRC:.c=$(OBJEXT)) +ELFNAME_BASE = errno hello +ifneq ($(CONFIG_DISABLE_SIGNALS),y) + ELFNAME_BASE += signal +endif + +ifeq ($(CONFIG_HAVE_CXX),y) + ELFNAME_BASE += hello++1 hello++2 + ifeq ($(CONFIG_HAVE_CXXINITIALIZE),y) + ELFNAME_BASE += hello++3 + endif + ifeq ($(CONFIG_EXAMPLES_ELF_CXX),y) + ELFNAME_BASE += hello++4 hello++5 + endif +endif +ifeq ($(CONFIG_EXAMPLES_ELF_LONGJMP),y) + ELFNAME_BASE += longjmp +endif +ifneq ($(CONFIG_DISABLE_PTHREAD),y) + ELFNAME_BASE += pthread mutex +endif +ifneq ($(CONFIG_ARCH_ADDRENV),y) + ELFNAME_BASE += task +endif + +ELFNAME = $(addprefix $(BINDIR)$(DELIM),$(ELFNAME_BASE)) + $(SYMTABSRC): - $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(BINDIR) g_elf >$@.tmp + $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(ELFNAME) g_elf >$@.tmp $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) diff --git a/examples/module/main/Makefile b/examples/module/main/Makefile index f5294b257..466af6dbf 100644 --- a/examples/module/main/Makefile +++ b/examples/module/main/Makefile @@ -34,14 +34,13 @@ MAINSRC = module_main.c SYMTABSRC = mod_symtab.c SYMTABOBJ = $(SYMTABSRC:.c=$(OBJEXT)) - +MODLUE_NAME = chardev ifneq ($(CONFIG_BUILD_FLAT),y) PASS1_SYMTAB = $(TOPDIR)/pass1/mod_symtab.c - MODLUE_NAME = chardev endif $(SYMTABSRC): - $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(BINDIR) g_mod >$@.tmp + $(Q) $(APPDIR)$(DELIM)tools$(DELIM)mksymtab.sh $(BINDIR)$(DELIM)$(MODLUE_NAME) g_mod >$@.tmp $(Q) $(call TESTANDREPLACEFILE, $@.tmp, $@) diff --git a/tools/mksymtab.sh b/tools/mksymtab.sh index 1f9d7ed8c..cdb141b03 100755 --- a/tools/mksymtab.sh +++ b/tools/mksymtab.sh @@ -27,28 +27,43 @@ usage() { if [ $# -ne 0 ]; then echo "ERROR: $@" fi - echo -e "\nUsage: $0 [symtabprefix] [-a additionalsymbolspath]" + echo -e "\nUsage: $0 [imagedirpath2 ... ] [symtabprefix] [-a additionalsymbolspath]" exit 1 } -# Check for the required directory path +# Collect all image directory/file paths until we hit a non-path argument +dirs=() +prefix="" +arg_count=0 -dir=$1 -if [ -z "$dir" ]; then +while [ $# -gt 0 ]; do + # Check if this is an option flag + if [ "x${1:0:1}" = "x-" ]; then + break + fi + + arg_count=$((arg_count + 1)) + + # Always collect the argument (whether path exists or not) + # Only treat as prefix if it doesn't look like a path + if [[ "$1" =~ ^/ ]] || [ -e "$1" ]; then + # Looks like a path (starts with /) or exists + dirs+=("$1") + shift + else + # Doesn't look like a path, treat as prefix + prefix=$1 + shift + break + fi +done + +# Check we have at least one argument +if [ $arg_count -eq 0 ]; then usage "Missing " fi -# Get the symbol table prefix - -if [ "x${2:0:1}" != "x-" ]; then - prefix=$2 - OPTIND=3 -else - OPTIND=2 -fi - -# Parse remaining arguments - +# Parse remaining arguments for options while getopts a: opt; do case $opt in a) @@ -63,28 +78,60 @@ if [ $OPTIND != $(($# + 1)) ]; then usage "Arguments remaining: \"${@:$OPTIND}\"" fi +# Function to get exec list from a path (file or directory) +get_exec_list() { + local path=$1 + if [ -f "$path" ]; then + echo "$path" + elif [ -d "$path" ]; then + find "$path" -type f 2>/dev/null + fi +} + # Extract all of the undefined symbols from the ELF files and create a # list of sorted, unique undefined variable names. -varlist=`find $dir -name *-thunk.S 2>/dev/null | xargs grep -h asciz | cut -f3 | sort | uniq` +# First try to find thunk files from all directories +varlist="" +for dir in "${dirs[@]}"; do + if [ -d "$dir" ]; then + thunklist=`find $dir -name *-thunk.S 2>/dev/null | xargs grep -h asciz 2>/dev/null | cut -f3` + if [ ! -z "$thunklist" ]; then + varlist="${varlist} ${thunklist}" + fi + fi +done + if [ -z "$varlist" ]; then - execlist=`find $dir -type f 2>/dev/null` + # Collect all executable files from all paths + execlist="" + for dir in "${dirs[@]}"; do + # Only process if path exists + if [ -e "$dir" ]; then + pathlist=`get_exec_list "$dir"` + if [ ! -z "$pathlist" ]; then + execlist="${execlist} ${pathlist}" + fi + fi + done + if [ ! -z "$execlist" ]; then + # Get all undefined symbol names + varlist=$(nm $execlist 2>/dev/null | grep -F ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2) -# Get all undefined symbol names - varlist=`nm $execlist 2>/dev/null | grep -F ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort | uniq` + # Get all defined symbol names + deflist=$(nm $execlist 2>/dev/null | grep -F -v -e ' U ' -e ':' | sed -e "s/^[0-9a-z]* //g" | cut -d' ' -f2) -# Get all defined symbol names - deflist=`nm $execlist 2>/dev/null | grep -F -v -e ' U ' -e ':' | sed -e "s/^[0-9a-z]* //g" | cut -d' ' -f2 | sort | uniq` - -# Remove the intersection between them, and the remaining symbols are found in the main image - common=`echo "$varlist" | tr ' ' '\n' | grep -Fxf <(echo "$deflist" | tr ' ' '\n') | tr '\n' ' '` - if [ "x$common" != "x" ]; then - varlist=`echo $varlist | sed "s/$common//g"` + # Remove the intersection between them, and the remaining symbols are found in the main image + if [ ! -z "$varlist" ] && [ ! -z "$deflist" ]; then + varlist=$(echo "$varlist" | tr ' ' '\n' | sort -u | grep -vFxf <(echo "$deflist" | tr ' ' '\n' | sort -u) | tr '\n' ' ') fi fi fi +# Sort and unique the varlist +varlist=`echo "$varlist" | tr ' ' '\n' | sort | uniq | tr '\n' ' '` + for addsym in ${addlist[@]}; do if [ -f $addsym ]; then varlist="${varlist}\n$(cat $addsym | grep -v "^,.*")" From c62d0d0875ac7dc59456fb1426f18d508ae7ac23 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Mon, 8 Sep 2025 11:24:08 +0800 Subject: [PATCH 113/568] netlib_setarp.c: add ATF_PERM to mark arp entry as permanent Improve the behavior of the ARP table so that the manually configured ARP table has the highest priority, can only be manually modified to other values, otherwise will never change again, and will not time out. Signed-off-by: zhanghongyu --- netutils/netlib/netlib_setarp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/netutils/netlib/netlib_setarp.c b/netutils/netlib/netlib_setarp.c index 88dbba810..1c2261d4c 100644 --- a/netutils/netlib/netlib_setarp.c +++ b/netutils/netlib/netlib_setarp.c @@ -78,6 +78,7 @@ int netlib_set_arpmapping(FAR const struct sockaddr_in *inaddr, req.arp_ha.sa_family = ARPHRD_ETHER; memcpy(&req.arp_ha.sa_data, macaddr, ETHER_ADDR_LEN); + req.arp_flags = ATF_PERM; if (ifname != NULL) { strlcpy((FAR char *)&req.arp_dev, ifname, From 0a90fe516782cad38f99f6c438e6ff84144f3267 Mon Sep 17 00:00:00 2001 From: guoshichao Date: Tue, 24 Dec 2024 16:45:14 +0800 Subject: [PATCH 114/568] benchmarks/ramspeed: add cmake build support Add CMakeLists.txt for the RAMSpeed benchmark application, enabling it to be built with the CMake build system alongside the existing Makefile-based build. This ensures consistent build behavior across build systems. Signed-off-by: guoshichao --- benchmarks/ramspeed/CMakeLists.txt | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 benchmarks/ramspeed/CMakeLists.txt diff --git a/benchmarks/ramspeed/CMakeLists.txt b/benchmarks/ramspeed/CMakeLists.txt new file mode 100644 index 000000000..a8b0df091 --- /dev/null +++ b/benchmarks/ramspeed/CMakeLists.txt @@ -0,0 +1,31 @@ +# ############################################################################## +# apps/benchmarks/ramspeed/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_BENCHMARK_RAMSPEED) + nuttx_add_application( + NAME + ${CONFIG_BENCHMARK_RAMSPEED_PROGNAME} + SRCS + ramspeed_main.c + STACKSIZE + ${CONFIG_BENCHMARK_RAMSPEED_STACKSIZE} + PRIORITY + ${CONFIG_BENCHMARK_RAMSPEED_PRIORITY}) +endif() From e804886c68f8c4c656c071e813637563a98a16b7 Mon Sep 17 00:00:00 2001 From: guoshichao Date: Wed, 14 Jan 2026 20:40:31 +0800 Subject: [PATCH 115/568] libuv: fix sendmsg parameter type in NuttX port Update the libuv NuttX port patch to change sendmsg() parameter from "struct msghdr *msg" to "const struct msghdr *msg" in the NuttX-specific implementation stub. This maintains compatibility after NuttX's socket API was made POSIX-compliant with const-correct parameters. Signed-off-by: guoshichao --- system/libuv/0001-libuv-port-for-nuttx.patch | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/system/libuv/0001-libuv-port-for-nuttx.patch b/system/libuv/0001-libuv-port-for-nuttx.patch index 0c2eb18dd..2364110e6 100644 --- a/system/libuv/0001-libuv-port-for-nuttx.patch +++ b/system/libuv/0001-libuv-port-for-nuttx.patch @@ -424,7 +424,7 @@ index 00000000..298bd2f8 + return 0; + } + -+ /* Make sure the memory is initiallized to zero using calloc() */ ++ /* Make sure the memory is initialized to zero using calloc() */ + *addresses = uv__calloc(*count, sizeof(**addresses)); + if (*addresses == NULL) { + freeifaddrs(addrs); @@ -3972,3 +3972,15 @@ diff --color -ur libuv_back/src/unix/thread.c libuv/src/unix/thread.c # include # define uv__cpu_set_t cpu_set_t #elif defined(__FreeBSD__) +diff --git a/src/unix/nuttx.c b/src/unix/nuttx.c +index d0e110a..e1c962e 100644 +--- a/src/unix/nuttx.c ++++ b/src/unix/nuttx.c +@@ -222,7 +222,7 @@ ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) { + return UV_ENOTSUP; + } + +-ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags) { ++ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) { + return UV_ENOTSUP; + } From 54bef649ea14d293128545f24c9db2594197a327 Mon Sep 17 00:00:00 2001 From: gaohedong Date: Mon, 7 Jul 2025 22:41:19 +0800 Subject: [PATCH 116/568] net/ptpd: fix compile warning issue In some scenarios, dynamic memory allocation is not allowed, so it is modified to a static allocation method. Signed-off-by: gaohedong --- netutils/ptpd/ptpd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 3193ee33e..f85619093 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -758,11 +758,13 @@ static int ptp_sendmsg(FAR struct ptp_state_s *state, FAR const void *buf, 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }; - char raw[sizeof(struct ether_header) + buflen]; + char raw[sizeof(struct ether_header) + sizeof(struct ptp_announce_s)]; FAR struct ether_header *header; struct msghdr msg; struct iovec iov; + DEBUGASSERT(sizeof(struct ptp_announce_s) >= buflen); + header = (FAR struct ether_header *)&raw; memcpy(header->ether_dhost, ptp_multicast_mac, ETHER_ADDR_LEN); netlib_getmacaddr(state->config->interface, header->ether_shost); From faefee48971cc4f54bf3ed693cf673c8c1645ccf Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Mon, 18 Aug 2025 16:59:09 +0800 Subject: [PATCH 117/568] MQTT-C: compile tests only if no with_mbedtls is enabled tests only supports tests in non-encrypted mode. when we open tests compilation in other modes, there will be many compilation warning with mismatched parameter types, and it will not run correctly. Signed-off-by: zhanghongyu --- netutils/mqttc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/netutils/mqttc/Kconfig b/netutils/mqttc/Kconfig index aa8e23d04..973c5bb4a 100644 --- a/netutils/mqttc/Kconfig +++ b/netutils/mqttc/Kconfig @@ -19,6 +19,7 @@ config NETUTILS_MQTTC_EXAMPLE config NETUTILS_MQTTC_TEST tristate "Enable MQTT-C test" + depends on !NETUTILS_MQTTC_WITH_MBEDTLS default n if NETUTILS_MQTTC_EXAMPLE From 11c8220fd5d40c50addd07523f0dd4e9786045eb Mon Sep 17 00:00:00 2001 From: zhangshuai39 Date: Tue, 13 Jan 2026 11:30:51 +0800 Subject: [PATCH 118/568] netlib: Replace perror with nerr Use the nerr interface for error print. Signed-off-by: zhangshuai39 --- netutils/netlib/netlib_checkhttpconnectivity.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netutils/netlib/netlib_checkhttpconnectivity.c b/netutils/netlib/netlib_checkhttpconnectivity.c index c29d86292..4b0df89c2 100644 --- a/netutils/netlib/netlib_checkhttpconnectivity.c +++ b/netutils/netlib/netlib_checkhttpconnectivity.c @@ -224,7 +224,7 @@ int netlib_check_httpconnectivity(FAR const char *host, ret = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { - perror("Connection failed"); + nerr("Connection failed: %s", strerror(errno)); goto exit_with_socket; } @@ -235,13 +235,13 @@ int netlib_check_httpconnectivity(FAR const char *host, ret = send(sock, buf, strlen(buf), 0); if (ret < 0) { - perror("send failed"); + nerr("send failed: %s", strerror(errno)); goto exit_with_socket; } if ((ret = recv(sock, buf, sizeof(buf), 0)) < 0) { - perror("recv failed"); + nerr("recv failed: %s", strerror(errno)); goto exit_with_socket; } From 3d97bf02e49a53a69c3a0cb27635c5e69073252b Mon Sep 17 00:00:00 2001 From: likun17 Date: Tue, 12 Nov 2024 20:58:57 +0800 Subject: [PATCH 119/568] system/uorb:Loop bug fix Fixed the epoll issue that when multiple events come only the first POLLIN is entered. Signed-off-by: likun17 --- system/uorb/uORB/epoll.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/system/uorb/uORB/epoll.c b/system/uorb/uORB/epoll.c index 147831d3f..e82c483aa 100644 --- a/system/uorb/uORB/epoll.c +++ b/system/uorb/uORB/epoll.c @@ -105,7 +105,8 @@ static int orb_loop_epoll_run(FAR struct orb_loop_s *loop) uorberr("epoll wait data in error! fd:%d", handle->fd); } } - else if (et[i].events & EPOLLOUT) + + if (et[i].events & EPOLLOUT) { if (handle->dataout_cb != NULL) { @@ -116,7 +117,8 @@ static int orb_loop_epoll_run(FAR struct orb_loop_s *loop) uorberr("epoll wait data out error! fd:%d", handle->fd); } } - else if (et[i].events & EPOLLPRI) + + if (et[i].events & EPOLLPRI) { if (handle->eventpri_cb != NULL) { @@ -127,7 +129,8 @@ static int orb_loop_epoll_run(FAR struct orb_loop_s *loop) uorberr("epoll wait events pri error! fd:%d", handle->fd); } } - else if (et[i].events & EPOLLERR) + + if (et[i].events & EPOLLERR) { if (handle->eventerr_cb != NULL) { From 7ba36385073ea0e5a79eb3ee428778c97814054f Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Wed, 13 Nov 2024 13:22:11 +0800 Subject: [PATCH 120/568] system/uorb: merge set_info to orb_advertise_multi_queue_info. support new api: orb_advertise_multi_queue_info to advertise topic with info Signed-off-by: dongjiuzhu1 --- system/uorb/uORB/uORB.c | 46 ++++++++++++++++++++++++----------------- system/uorb/uORB/uORB.h | 46 ++++++++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/system/uorb/uORB/uORB.c b/system/uorb/uORB/uORB.c index fd3f704af..63adb4b64 100644 --- a/system/uorb/uORB/uORB.c +++ b/system/uorb/uORB/uORB.c @@ -57,7 +57,8 @@ ****************************************************************************/ static int orb_advsub_open(FAR const struct orb_metadata *meta, int flags, - int instance, unsigned int queue_size) + int instance, unsigned int queue_size, + FAR orb_info_t *info) { char path[ORB_PATH_MAX]; int fd; @@ -78,6 +79,14 @@ static int orb_advsub_open(FAR const struct orb_metadata *meta, int flags, reginfo.esize = meta->o_size; reginfo.nbuffer = queue_size; reginfo.persist = !!(flags & SENSOR_PERSIST); + if (info != NULL) + { + memcpy(®info.devinfo, info, sizeof(*info)); + } + else + { + memset(®info.devinfo, 0, sizeof(*info)); + } fd = open(ORB_USENSOR_PATH, O_WRONLY | O_CLOEXEC); if (fd < 0) @@ -120,7 +129,8 @@ static int orb_advsub_open(FAR const struct orb_metadata *meta, int flags, static int orb_advertise_multi_queue_flags(FAR const struct orb_metadata *meta, FAR const void *data, FAR int *instance, - unsigned int queue_size, int flags) + unsigned int queue_size, int flags, + FAR orb_info_t *info) { int inst; int fd; @@ -129,7 +139,7 @@ orb_advertise_multi_queue_flags(FAR const struct orb_metadata *meta, inst = instance ? *instance : orb_group_count(meta); - fd = orb_advsub_open(meta, flags, inst, queue_size); + fd = orb_advsub_open(meta, flags, inst, queue_size, info); if (fd < 0) { uorberr("%s advertise failed (%i)", meta->o_name, fd); @@ -172,24 +182,27 @@ int orb_close(int fd) return close(fd); } -int orb_advertise_multi_queue(FAR const struct orb_metadata *meta, - FAR const void *data, FAR int *instance, - unsigned int queue_size) +int orb_advertise_multi_queue_info(FAR const struct orb_metadata *meta, + FAR const void *data, FAR int *instance, + unsigned int queue_size, + FAR orb_info_t *info) { return orb_advertise_multi_queue_flags(meta, data, instance, - queue_size, O_WRONLY); + queue_size, O_WRONLY, info); } -int orb_advertise_multi_queue_persist(FAR const struct orb_metadata *meta, - FAR const void *data, - FAR int *instance, - unsigned int queue_size) +int +orb_advertise_multi_queue_persist_info(FAR const struct orb_metadata *meta, + FAR const void *data, + FAR int *instance, + unsigned int queue_size, + FAR orb_info_t *info) { return orb_advertise_multi_queue_flags(meta, data, instance, queue_size, - O_WRONLY | SENSOR_PERSIST); + O_WRONLY | SENSOR_PERSIST, info); } -ssize_t orb_publish_multi(int fd, const void *data, size_t len) +ssize_t orb_publish_multi(int fd, FAR const void *data, size_t len) { return write(fd, data, len); } @@ -197,7 +210,7 @@ ssize_t orb_publish_multi(int fd, const void *data, size_t len) int orb_subscribe_multi(FAR const struct orb_metadata *meta, unsigned instance) { - return orb_advsub_open(meta, O_RDONLY, instance, 0); + return orb_advsub_open(meta, O_RDONLY, instance, 0, NULL); } ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len) @@ -276,11 +289,6 @@ int orb_get_interval(int fd, FAR unsigned *interval) return ret; } -int orb_set_info(int fd, FAR const orb_info_t *info) -{ - return ioctl(fd, SNIOC_SET_INFO, (unsigned long)(uintptr_t)info); -} - int orb_get_info(int fd, FAR orb_info_t *info) { return ioctl(fd, SNIOC_GET_INFO, (unsigned long)(uintptr_t)info); diff --git a/system/uorb/uORB/uORB.h b/system/uorb/uORB/uORB.h index 5e0bc6c67..f1b9c27b0 100644 --- a/system/uorb/uORB/uORB.h +++ b/system/uorb/uORB/uORB.h @@ -266,7 +266,7 @@ int orb_open(FAR const char *name, int instance, int flags); int orb_close(int fd); /**************************************************************************** - * Name: orb_advertise_multi_queue + * Name: orb_advertise_multi_queue_info * * Description: * This performs the initial advertisement of a topic; it creates the topic @@ -278,6 +278,7 @@ int orb_close(int fd); * instance Pointer to an integer which yield the instance ID, * (has default 0 if pointer is NULL). * queue_size Maximum number of buffered elements. + * info A pointer to the orb_info_t. * * Returned Value: * -1 on error, otherwise returns an file descriptor @@ -287,10 +288,21 @@ int orb_close(int fd); * this function will return -1 and set errno to ENOENT. ****************************************************************************/ +int orb_advertise_multi_queue_info(FAR const struct orb_metadata *meta, + FAR const void *data, + FAR int *instance, + unsigned int queue_size, + FAR orb_info_t *info); + +static inline int orb_advertise_multi_queue(FAR const struct orb_metadata *meta, FAR const void *data, FAR int *instance, - unsigned int queue_size); + unsigned int queue_size) +{ + return orb_advertise_multi_queue_info(meta, data, instance, + queue_size, NULL); +} static inline int orb_advertise(FAR const struct orb_metadata *meta, FAR const void *data) @@ -338,10 +350,22 @@ static inline int orb_advertise_multi(FAR const struct orb_metadata *meta, * this function will return -1 and set errno to ENOENT. ****************************************************************************/ +int +orb_advertise_multi_queue_persist_info(FAR const struct orb_metadata *meta, + FAR const void *data, + FAR int *instance, + unsigned int queue_size, + FAR orb_info_t *info); + +static inline int orb_advertise_multi_queue_persist(FAR const struct orb_metadata *meta, FAR const void *data, FAR int *instance, - unsigned int queue_size); + unsigned int queue_size) +{ + return orb_advertise_multi_queue_persist_info(meta, data, instance, + queue_size, NULL); +} /**************************************************************************** * Name: orb_unadvertise @@ -691,22 +715,6 @@ int orb_set_interval(int fd, unsigned interval); int orb_get_interval(int fd, FAR unsigned *interval); -/**************************************************************************** - * Name: orb_set_info - * - * Description: - * Set topic information. - * - * Input Parameters: - * fd A fd returned from orb_subscribe. - * info Data to be transmitted. - * - * Returned Value: - * 0 on success, -1 otherwise with ERRNO set accordingly. - ****************************************************************************/ - -int orb_set_info(int fd, FAR const orb_info_t *info); - /**************************************************************************** * Name: orb_get_info * From ed7bb51b149dcd62a369ebdda13f30854414cdbf Mon Sep 17 00:00:00 2001 From: likun17 Date: Mon, 3 Mar 2025 18:29:18 +0800 Subject: [PATCH 121/568] system/uorb:unit_test bug fix Fixed the error message caused by inconsistent definitions of pthread_t on different platforms. Signed-off-by: likun17 --- system/uorb/test/unit_test.c | 6 ------ system/uorb/uORB/uORB.c | 4 ++-- system/uorb/uORB/uORB.h | 10 +++++----- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/system/uorb/test/unit_test.c b/system/uorb/test/unit_test.c index fc28daee5..70cd059df 100644 --- a/system/uorb/test/unit_test.c +++ b/system/uorb/test/unit_test.c @@ -235,12 +235,6 @@ static int latency_test(bool print) usleep(1000); /* simulate >800 Hz system operation */ } - if (pubsub_task < 0) - { - test_fail("failed launching task"); - goto out; - } - ret = OK; out: diff --git a/system/uorb/uORB/uORB.c b/system/uorb/uORB/uORB.c index 63adb4b64..333fc09e0 100644 --- a/system/uorb/uORB/uORB.c +++ b/system/uorb/uORB/uORB.c @@ -43,7 +43,7 @@ * Name: orb_advsub_open * * Description: - * Open device node as advertiser / subscriber, regist node and save meta + * Open device node as advertiser / subscriber, register node and save meta * in driver for first user, set buffer number for advertisers. * * Input Parameters: @@ -68,7 +68,7 @@ static int orb_advsub_open(FAR const struct orb_metadata *meta, int flags, snprintf(path, ORB_PATH_MAX, ORB_SENSOR_PATH"%s%d", meta->o_name, instance); - /* Check existance before open */ + /* Check existence before open */ flags |= O_CLOEXEC; fd = open(path, flags); diff --git a/system/uorb/uORB/uORB.h b/system/uorb/uORB/uORB.h index f1b9c27b0..205edffb1 100644 --- a/system/uorb/uORB/uORB.h +++ b/system/uorb/uORB/uORB.h @@ -108,10 +108,10 @@ struct orb_handle_s int events; /* Events of interest. */ int fd; /* Topic fd. */ FAR void *arg; /* Callback parameter. */ - orb_datain_cb_t datain_cb; /* User EPOLLIN callback funtion. */ - orb_dataout_cb_t dataout_cb; /* User EPOLLOUT callback funtion. */ - orb_eventpri_cb_t eventpri_cb; /* User EPOLLPRI callback funtion. */ - orb_eventerr_cb_t eventerr_cb; /* User EPOLLERR callback funtion. */ + orb_datain_cb_t datain_cb; /* User EPOLLIN callback function. */ + orb_dataout_cb_t dataout_cb; /* User EPOLLOUT callback function. */ + orb_eventpri_cb_t eventpri_cb; /* User EPOLLPRI callback function. */ + orb_eventerr_cb_t eventerr_cb; /* User EPOLLERR callback function. */ }; struct orb_loop_ops_s; @@ -806,7 +806,7 @@ orb_abstime orb_absolute_time(void); * then Past system time. * * Returned Value: - * Bewteen time. + * Between time. ****************************************************************************/ static inline orb_abstime orb_elapsed_time(FAR const orb_abstime *then) From 056ba984e8ee26ceb5ca172b63935eef0f4425f3 Mon Sep 17 00:00:00 2001 From: makejian Date: Tue, 21 Jan 2025 22:31:27 +0800 Subject: [PATCH 122/568] tinycrypto: add unix as compile flags to use dev/random Add UNIX platform flag to tinycrypto build configuration to enable access to /dev/random for secure random number generation. Signed-off-by: makejian --- crypto/tinycrypt/CMakeLists.txt | 3 ++- crypto/tinycrypt/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crypto/tinycrypt/CMakeLists.txt b/crypto/tinycrypt/CMakeLists.txt index a44ed6234..c75ae88c6 100644 --- a/crypto/tinycrypt/CMakeLists.txt +++ b/crypto/tinycrypt/CMakeLists.txt @@ -64,6 +64,7 @@ if(CONFIG_TINYCRYPT) # Sources # ############################################################################ + list(APPEND CFLAGS -Dunix) set(CSRCS ${TINYCRYPT_DIR}/lib/source/utils.c ${TINYCRYPT_DIR}/lib/source/ecc.c ${TINYCRYPT_DIR}/lib/source/ecc_platform_specific.c) @@ -120,7 +121,7 @@ if(CONFIG_TINYCRYPT) if(CONFIG_TINYCRYPT_TEST) list(APPEND CSRCS ${TINYCRYPT_DIR}/tests/test_ecc_utils.c) list(APPEND INCDIR ${TINYCRYPT_DIR}/tests/include) - set(CFLAGS -Dhex2bin=ltp_hex2bin -DENABLE_TESTS) + list(APPEND CFLAGS -DENABLE_TESTS) nuttx_add_application( NAME diff --git a/crypto/tinycrypt/Makefile b/crypto/tinycrypt/Makefile index 6b3930a91..70cee2435 100644 --- a/crypto/tinycrypt/Makefile +++ b/crypto/tinycrypt/Makefile @@ -48,6 +48,7 @@ distclean:: $(Q) rm -rf $(TINYCRYPT_UNPACKNAME) endif +CFLAGS += ${DEFINE_PREFIX}unix CSRCS += tinycrypt/lib/source/utils.c ifeq ($(CONFIG_TINYCRYPT_ECC),y) @@ -105,8 +106,7 @@ endif ifeq ($(CONFIG_TINYCRYPT_TEST),y) CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/crypto/tinycrypt/tinycrypt/tests/include - CFLAGS +=-Dhex2bin=ltp_hex2bin - CFLAGS +=-DENABLE_TESTS + CFLAGS += -DENABLE_TESTS CSRCS += tinycrypt/tests/test_ecc_utils.c PRIORITY = $(CONFIG_TINYCRYPT_TEST_PRIORITY) STACKSIZE = $(CONFIG_TINYCRYPT_TEST_STACKSIZE) From 45a6b0365c743574648575ba4a28d2c59ca3e884 Mon Sep 17 00:00:00 2001 From: liqinhui Date: Thu, 15 May 2025 14:46:47 +0800 Subject: [PATCH 123/568] netutils/ping: Support ICMP filter for ping. Add setsockopt support to filter ICMP packets. Signed-off-by: liqinhui --- include/netutils/icmp_ping.h | 1 + netutils/ping/icmp_ping.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/netutils/icmp_ping.h b/include/netutils/icmp_ping.h index 3f8d6c29d..d9164afc1 100644 --- a/include/netutils/icmp_ping.h +++ b/include/netutils/icmp_ping.h @@ -51,6 +51,7 @@ #define ICMP_E_RECVFROM -13 /* extra: error code */ #define ICMP_E_RECVSMALL -15 /* extra: recv bytes */ #define ICMP_E_BINDDEV -17 /* extra: error bind */ +#define ICMP_E_FILTER -19 /* extra: error filter */ /* Negative even number represent warning(recoverable) */ diff --git a/netutils/ping/icmp_ping.c b/netutils/ping/icmp_ping.c index aa88d0a18..88f006b8f 100644 --- a/netutils/ping/icmp_ping.c +++ b/netutils/ping/icmp_ping.c @@ -54,6 +54,7 @@ ****************************************************************************/ #define ICMP_IOBUFFER_SIZE(x) (sizeof(struct icmp_hdr_s) + (x)) +#define ICMP_SET_FILTER(t) (~(1U << (t))) /**************************************************************************** * Private Types @@ -226,6 +227,9 @@ void icmp_ping(FAR const struct ping_info_s *info) int ret; int ch; int i; +#ifdef CONFIG_NET_SOCKOPTS + int filter; +#endif g_exiting = false; #ifdef CONFIG_ENABLE_ALL_SIGNALS @@ -278,6 +282,19 @@ void icmp_ping(FAR const struct ping_info_s *info) } #endif +#ifdef CONFIG_NET_SOCKOPTS + filter = ICMP_SET_FILTER(ICMP_ECHO_REPLY); + ret = setsockopt(priv->sockfd, IPPROTO_ICMP, ICMP_FILTER, + &filter, sizeof(filter)); + if (ret < 0) + { + icmp_callback(&result, ICMP_E_FILTER, errno); + close(priv->sockfd); + free(priv); + return; + } +#endif + priv->kickoff = clock(); memset(&priv->destaddr, 0, sizeof(struct sockaddr_in)); From 5595a01fcd11e1e760e3cd0f42bb2054fc2f58eb Mon Sep 17 00:00:00 2001 From: guoshichao Date: Wed, 19 Mar 2025 16:40:47 +0800 Subject: [PATCH 124/568] watchdog: disable the drivertest_watchdog_api testcase on some platform When we support the watchdog interrupt on the Armv7-A platform with the TEE enabled, the watchdog interrupt needs to be configured as a FIQ to avoid the impact of interrupt disabling in the AP. In this case, the drivertest_watchdog_api testcase cannot pass the test in such a scenario. This is because the drivertest_watchdog_api itself requires calling a specified callback after the watchdog interrupt is triggered, instead of directly dumping the AP's context and then asserting the system. Therefore, when both CONFIG_ARCH_ARMV7A and CONFIG_ARCH_HAVE_TRUSTZONE are enabled, we need to skip the current drivertest_watchdog_api testcase. Signed-off-by: guoshichao --- testing/drivers/drivertest/drivertest_watchdog.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/testing/drivers/drivertest/drivertest_watchdog.c b/testing/drivers/drivertest/drivertest_watchdog.c index 1a4f54c49..1021e8e10 100644 --- a/testing/drivers/drivertest/drivertest_watchdog.c +++ b/testing/drivers/drivertest/drivertest_watchdog.c @@ -57,7 +57,11 @@ #define WDG_DEFAULT_TIMEOUT 2000 #define WDG_DEFAULT_TESTCASE 0 #define WDG_DEFAULT_DEVIATION 20 +#if defined(CONFIG_ARCH_ARMV7A) && defined(CONFIG_ARCH_HAVE_TRUSTZONE) +#define WDG_COUNT_TESTCASE 3 +#else #define WDG_COUNT_TESTCASE 4 +#endif #define OPTARG_TO_VALUE(value, type, base) \ do \ @@ -544,7 +548,9 @@ int main(int argc, FAR char *argv[]) cmocka_unit_test_prestate(drivertest_watchdog_feeding, &wdg_state), cmocka_unit_test_prestate(drivertest_watchdog_interrupts, &wdg_state), cmocka_unit_test_prestate(drivertest_watchdog_loop, &wdg_state), +#if !defined(CONFIG_ARCH_ARMV7A) || !defined(CONFIG_ARCH_HAVE_TRUSTZONE) cmocka_unit_test_prestate(drivertest_watchdog_api, &wdg_state) +#endif }; return cmocka_run_group_tests(tests, NULL, NULL); From df30f84f334d399cc734fda47591d4d5890a6aeb Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Mon, 19 Jan 2026 13:23:50 +0800 Subject: [PATCH 125/568] ostest/hrtimer: sync hrtimer test with latest updates Synchronize the hrtimer ostest with the latest hrtimer changes. Signed-off-by: Chengdong Wang --- testing/ostest/hrtimer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index fcbe1f5d9..3943140e6 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -211,11 +211,12 @@ void hrtimer_test(void) /* Initialize the high-resolution timer */ - hrtimer_init(&hrtimer_test.timer, test_hrtimer_callback); + hrtimer_init(&hrtimer_test.timer); /* Start the timer with 500ms relative timeout */ ret = hrtimer_start(&hrtimer_test.timer, + test_hrtimer_callback, hrtimer_test.period, HRTIMER_MODE_REL); From a75fa37090aaeda1fd95477e8fe74e6675384580 Mon Sep 17 00:00:00 2001 From: guanyi3 Date: Fri, 10 Oct 2025 11:45:45 +0800 Subject: [PATCH 126/568] usrsocktest: fix TEST_ASSERT_EQUAL fail for POLLIN This assertion should be removed because the POLLIN event is now only raised when there is data pending to be received. Previously, POLLIN was incorrectly set as soon as the connection was established, even when no data was available, which was not consistent with the expected behavior. Signed-off-by: guanyi3 --- examples/usrsocktest/usrsocktest_remote_disconnect.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/usrsocktest/usrsocktest_remote_disconnect.c b/examples/usrsocktest/usrsocktest_remote_disconnect.c index 1e3681f9d..79ccbfefb 100644 --- a/examples/usrsocktest/usrsocktest_remote_disconnect.c +++ b/examples/usrsocktest/usrsocktest_remote_disconnect.c @@ -871,7 +871,6 @@ static void remote_disconnect_poll2(struct usrsocktest_daemon_conf_s *dconf) TEST_ASSERT_EQUAL(1, ret); TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(*events & POLLIN, pfd.revents & POLLIN); TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); From 782de2748fa623a005e9f1d3410bc076388f8955 Mon Sep 17 00:00:00 2001 From: guoshichao Date: Thu, 25 Sep 2025 14:33:46 +0800 Subject: [PATCH 127/568] cu: implement the cu exit logic like top cmd using the local cu_globals_s instance to manange the cu exit procedure Signed-off-by: guoshichao --- system/cu/cu_main.c | 57 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/system/cu/cu_main.c b/system/cu/cu_main.c index 1e991460d..6e25acfc9 100644 --- a/system/cu/cu_main.c +++ b/system/cu/cu_main.c @@ -79,8 +79,6 @@ enum parity_mode * Private Data ****************************************************************************/ -static struct cu_globals_s g_cu; - /**************************************************************************** * Public Data ****************************************************************************/ @@ -127,7 +125,8 @@ static FAR void *cu_listener(FAR void *parameter) #ifdef CONFIG_ENABLE_ALL_SIGNALS static void sigint(int sig) { - g_cu.force_exit = true; + FAR struct cu_globals_s *cu = siginfo->si_user; + cu->force_exit = true; } #endif @@ -280,8 +279,8 @@ int main(int argc, FAR char *argv[]) #ifdef CONFIG_ENABLE_ALL_SIGNALS struct sigaction sa; #endif + struct cu_globals_s cu; FAR const char *devname = CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE; - FAR struct cu_globals_s *cu = &g_cu; #ifdef CONFIG_SERIAL_TERMIOS int baudrate = CONFIG_SYSTEM_CUTERM_DEFAULT_BAUD; enum parity_mode parity = PARITY_NONE; @@ -297,8 +296,8 @@ int main(int argc, FAR char *argv[]) /* Initialize global data */ - memset(cu, 0, sizeof(*cu)); - cu->escape = '~'; + memset(&cu, 0, sizeof(cu)); + cu.escape = '~'; #ifdef CONFIG_ENABLE_ALL_SIGNALS /* Install signal handlers */ @@ -338,7 +337,7 @@ int main(int argc, FAR char *argv[]) break; case 'E': - cu->escape = atoi(optarg); + cu.escape = atoi(optarg); break; case 'h': @@ -361,8 +360,8 @@ int main(int argc, FAR char *argv[]) /* Open the serial device for reading and writing */ - cu->devfd = open(devname, O_RDWR); - if (cu->devfd < 0) + cu.devfd = open(devname, O_RDWR); + if (cu.devfd < 0) { cu_error("cu_main: ERROR: Failed to open %s for writing: %d\n", devname, errno); @@ -371,9 +370,9 @@ int main(int argc, FAR char *argv[]) /* Remember serial device termios attributes */ - if (isatty(cu->devfd)) + if (isatty(cu.devfd)) { - ret = tcgetattr(cu->devfd, &cu->devtio); + ret = tcgetattr(cu.devfd, &cu.devtio); if (ret) { cu_error("cu_main: ERROR during tcgetattr(): %d\n", errno); @@ -387,30 +386,30 @@ int main(int argc, FAR char *argv[]) if (isatty(STDERR_FILENO)) { - cu->stdfd = STDERR_FILENO; + cu.stdfd = STDERR_FILENO; } else if (isatty(STDOUT_FILENO)) { - cu->stdfd = STDOUT_FILENO; + cu.stdfd = STDOUT_FILENO; } else if (isatty(STDIN_FILENO)) { - cu->stdfd = STDIN_FILENO; + cu.stdfd = STDIN_FILENO; } else { - cu->stdfd = -1; + cu.stdfd = -1; } - if (cu->stdfd >= 0) + if (cu.stdfd >= 0) { - tcgetattr(cu->stdfd, &cu->stdtio); + tcgetattr(cu.stdfd, &cu.stdtio); } #ifdef CONFIG_SERIAL_TERMIOS - if (set_termios(cu, baudrate, parity, rtscts, nocrlf) != 0) + if (set_termios(&cu, baudrate, parity, rtscts, nocrlf) != 0) #else - if (set_termios(cu, nocrlf) != 0) + if (set_termios(&cu, nocrlf) != 0) #endif { goto errout_with_devfd_retrieve; @@ -429,7 +428,7 @@ int main(int argc, FAR char *argv[]) attr.priority = CONFIG_SYSTEM_CUTERM_PRIORITY; - ret = pthread_create(&cu->listener, &attr, cu_listener, cu); + ret = pthread_create(&cu.listener, &attr, cu_listener, &cu); pthread_attr_destroy(&attr); if (ret != 0) { @@ -439,7 +438,7 @@ int main(int argc, FAR char *argv[]) /* Send messages and get responses -- forever */ - while (!cu->force_exit) + while (!cu.force_exit) { char buf[CONFIG_LINE_MAX]; ssize_t nwrite = 0; @@ -469,21 +468,21 @@ int main(int argc, FAR char *argv[]) */ escaping = false; - if (cu_cmd(cu, ch) == 1) + if (cu_cmd(&cu, ch) == 1) { - cu->force_exit = true; + cu.force_exit = true; nread = i; break; } } - if (start_of_line == 1 && ch == cu->escape) + if (start_of_line == 1 && ch == cu.escape) { /* Normal character */ if (i > nwrite) { - write(cu->devfd, &buf[nwrite], i - nwrite); + write(cu.devfd, &buf[nwrite], i - nwrite); } nwrite = i + 1; @@ -514,19 +513,19 @@ int main(int argc, FAR char *argv[]) if (nread > nwrite) { - write(cu->devfd, &buf[nwrite], nread - nwrite); + write(cu.devfd, &buf[nwrite], nread - nwrite); } } - pthread_cancel(cu->listener); + pthread_cancel(cu.listener); exitval = EXIT_SUCCESS; /* Error exits */ errout_with_devfd_retrieve: - retrieve_termios(cu); + retrieve_termios(&cu); errout_with_devfd: - close(cu->devfd); + close(cu.devfd); errout_with_devinit: return exitval; } From 33d5062ba68c7405035608941a31e3b76ad3db3e Mon Sep 17 00:00:00 2001 From: makejian Date: Wed, 4 Jun 2025 11:12:20 +0800 Subject: [PATCH 128/568] openssl_wrapper_mbedtls: support bio interfaces in openssl VELAPLATFO-62586 Change-Id: I5d7675c05dc3a52c1cb15a6132b969a19f848248 Signed-off-by: makejian (cherry picked from commit 409c86a062a816b56a3a48b1111102d12f24a48f) --- .../include/openssl/bio.h | 72 +++++- .../include/openssl/types.h | 4 +- .../openssl_mbedtls_wrapper/mbedtls/bio_b64.c | 147 +++++++++++ .../openssl_mbedtls_wrapper/mbedtls/bio_lib.c | 151 +++++++++++ .../openssl_mbedtls_wrapper/mbedtls/bss_mem.c | 236 ++++++++++++++++++ 5 files changed, 608 insertions(+), 2 deletions(-) create mode 100644 crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c create mode 100644 crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c create mode 100644 crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/bio.h b/crypto/openssl_mbedtls_wrapper/include/openssl/bio.h index be8acf198..7bfab1eb9 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/bio.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/bio.h @@ -27,16 +27,86 @@ ****************************************************************************/ #include +#include /**************************************************************************** - * Public Function Prototypes + * Pre-processor Definitions ****************************************************************************/ +/* There are the classes of BIOs */ + +#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ +#define BIO_TYPE_FILTER 0x0200 +#define BIO_TYPE_SOURCE_SINK 0x0400 + +#define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* This is used with memory BIOs: BIO_FLAGS_MEM_RDONLY + * means we shouldn't free up or change the data in any way; + * BIO_FLAGS_NONCLEAR_RST means we shouldn't clear data on reset. + */ + +#define BIO_FLAGS_MEM_RDONLY 0x200 +#define BIO_FLAGS_NONCLEAR_RST 0x400 +#define BIO_FLAGS_IN_EOF 0x800 + +#define BIO_TYPE_NONE 0 +#define BIO_TYPE_MEM (1 | BIO_TYPE_SOURCE_SINK) +#define BIO_TYPE_FILE (2 | BIO_TYPE_SOURCE_SINK) +#define BIO_TYPE_BASE64 (11 | BIO_TYPE_FILTER) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct bio_method_st +{ + int type; + char *name; + int (*bwrite_old) (BIO *, const char *, int); + int (*bread_old) (BIO *, char *, int); + int (*create) (BIO *); + int (*destroy) (BIO *); +}; + +struct bio_st +{ + const BIO_METHOD *method; + int flags; /* extra storage */ + void *ptr; + struct bio_st *next_bio; /* used by filter BIOs */ + struct bio_st *prev_bio; /* used by filter BIOs */ +}; + #ifdef __cplusplus extern "C" { #endif +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +const BIO_METHOD *BIO_f_base64(void); + +const BIO_METHOD *BIO_s_mem(void); + +BIO *BIO_new(const BIO_METHOD *method); + +BIO *BIO_push(BIO *b, BIO *bio); + +void BIO_set_flags(BIO *b, int flags); + +int BIO_write(BIO *b, const void *data, int dlen); + +int BIO_read(BIO *b, void *data, int dlen); + +void BIO_free_all(BIO *bio); + +BIO *BIO_next(BIO *b); + +int BIO_flush(BIO *b); + #ifdef __cplusplus } #endif diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/types.h b/crypto/openssl_mbedtls_wrapper/include/openssl/types.h index 679fb94c5..c03078645 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/types.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/types.h @@ -29,10 +29,12 @@ typedef void SSL_CIPHER; typedef void X509_STORE; typedef void RSA; -typedef void BIO; typedef int (*OPENSSL_sk_compfunc)(const void *, const void *); +typedef struct bio_buf_mem_st BIO_BUF_MEM; +typedef struct bio_method_st BIO_METHOD; +typedef struct bio_st BIO; typedef struct stack_st OPENSSL_STACK; typedef struct ssl_method_st SSL_METHOD; typedef struct ssl_method_func_st SSL_METHOD_FUNC; diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c b/crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c new file mode 100644 index 000000000..a13d4f26c --- /dev/null +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * apps/crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +#define BIO_B64_BUFSIZE ((BIO_B64_ENC_LEN / 3) * 4 + 1) +#define BIO_B64_ENC_LEN 192 + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int b64_write(BIO *h, const char *buf, int num); +static int b64_read(BIO *h, char *buf, int size); +static int b64_new(BIO *h); +static int b64_free(BIO *data); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const BIO_METHOD g_methods_b64 = +{ + BIO_TYPE_BASE64, + "base64 encoding", + b64_write, + b64_read, + b64_new, + b64_free, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int b64_write(BIO *b, const char *in, int inl) +{ + BIO *next; + int len; + int offset = 0; + int ret = 0; + size_t n; + unsigned char out[BIO_B64_BUFSIZE]; + + next = BIO_next(b); + if (next == NULL) + { + return 0; + } + + while (inl > 0) + { + len = MIN(inl, BIO_B64_ENC_LEN); + ret = mbedtls_base64_encode(out, BIO_B64_BUFSIZE, &n, + (const unsigned char *)in + offset, len); + if (ret < 0) + { + break; + } + + ret = BIO_write(next, out, n); + inl -= len; + offset += len; + } + + return ret; +} + +static int b64_read(BIO *b, char *out, int outl) +{ + BIO *next; + int ret; + size_t n; + + if (out == NULL) + { + return 0; + } + + next = BIO_next(b); + if (next == NULL) + { + return 0; + } + + ret = BIO_read(next, out, outl); + if (ret > 0) + { + ret = mbedtls_base64_decode((unsigned char *)out, outl, &n, + (const unsigned char *)out, ret); + if (ret == 0) + { + ret = n; + } + } + + return ret; +} + +static int b64_new(BIO *bi) +{ + return 1; +} + +static int b64_free(BIO *a) +{ + return 1; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +const BIO_METHOD *BIO_f_base64(void) +{ + return &g_methods_b64; +} diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c b/crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c new file mode 100644 index 000000000..36d08403a --- /dev/null +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c @@ -0,0 +1,151 @@ +/**************************************************************************** + * apps/crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +BIO *BIO_new(const BIO_METHOD *method) +{ + BIO *bio = zalloc(sizeof(*bio)); + + if (bio == NULL) + { + return NULL; + } + + bio->method = method; + + if (method->create != NULL && !method->create(bio)) + { + free(bio); + return NULL; + } + + return bio; +} + +BIO *BIO_push(BIO *b, BIO *bio) +{ + BIO *lb; + + if (b == NULL) + { + return bio; + } + else if (bio == NULL) + { + return b; + } + + lb = b; + while (lb->next_bio != NULL) + { + lb = lb->next_bio; + } + + lb->next_bio = bio; + bio->prev_bio = lb; + return b; +} + +void BIO_set_flags(BIO *b, int flags) +{ + b->flags |= flags; +} + +int BIO_write(BIO *b, const void *data, int dlen) +{ + if (b == NULL || dlen <= 0) + { + return 0; + } + + if (b->method == NULL || b->method->bwrite_old == NULL) + { + return -2; + } + + return b->method->bwrite_old(b, data, dlen); +} + +int BIO_read(BIO *b, void *data, int dlen) +{ + if (b == NULL || dlen <= 0) + { + return 0; + } + + if (b->method == NULL || b->method->bread_old == NULL) + { + return -2; + } + + return b->method->bread_old(b, data, dlen); +} + +int BIO_free(BIO *a) +{ + if (a == NULL) + { + return 0; + } + + if (a->method != NULL && a->method->destroy != NULL) + { + a->method->destroy(a); + } + + free(a); + return 1; +} + +void BIO_free_all(BIO *bio) +{ + while (bio != NULL) + { + BIO *b = bio; + bio = bio->next_bio; + BIO_free(b); + } +} + +BIO *BIO_next(BIO *b) +{ + if (b == NULL) + { + return NULL; + } + + return b->next_bio; +} + +int BIO_flush(BIO *b) +{ + return 1; +} diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c b/crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c new file mode 100644 index 000000000..40f884135 --- /dev/null +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c @@ -0,0 +1,236 @@ +/**************************************************************************** + * apps/crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That + * function is applied in several functions in this file and this limit + * ensures that the result fits in an int. + */ + +#define LIMIT_BEFORE_EXPANSION 0x5ffffffc + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int mem_write(BIO *h, const char *buf, int num); +static int mem_read(BIO *h, char *buf, int size); +static int mem_new(BIO *h); +static int mem_free(BIO *data); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct bio_buf_mem_st +{ + unsigned long flags; + char *data; + size_t length; /* current number of bytes */ + size_t max; /* size of buffer */ + size_t offset; /* has been read */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const BIO_METHOD g_mem_method = +{ + BIO_TYPE_MEM, + "memory buffer", + mem_write, + mem_read, + mem_new, + mem_free, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int mem_buf_sync(BIO *b) +{ + if (b != NULL && b->ptr != NULL) + { + BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; + + if (bbm->offset) + { + bbm->length = bbm->length - bbm->offset; + memmove(bbm->data, bbm->data + bbm->offset, bbm->length); + bbm->offset = 0; + } + } + + return 0; +} + +static size_t BUF_MEM_grow_clean(BIO_BUF_MEM *bbm, size_t len) +{ + char *ret; + size_t n; + + if (bbm->length >= len) + { + if (bbm->data != NULL) + { + memset(&bbm->data[len], 0, bbm->length - len); + } + + bbm->length = len; + return len; + } + + if (bbm->max >= len) + { + memset(&bbm->data[bbm->length], 0, len - bbm->length); + bbm->length = len; + return len; + } + + /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ + + if (len > LIMIT_BEFORE_EXPANSION) + { + return 0; + } + + n = MAX((len + 3) / 3 * 4, bbm->max); + ret = realloc(bbm->data, n); + if (ret == NULL) + { + return 0; + } + + bbm->data = ret; + bbm->max = n; + bbm->length = len; + return len; +} + +static int mem_write(BIO *b, const char *in, int inl) +{ + BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; + int blen; + + if (b->flags & BIO_FLAGS_MEM_RDONLY) + { + return -1; + } + + if (inl <= 0) + { + return 0; + } + else if (in == NULL) + { + return -1; + } + + blen = bbm->length - bbm->offset; + mem_buf_sync(b); + if (BUF_MEM_grow_clean(bbm, blen + inl) == 0) + { + return -1; + } + + memcpy(bbm->data + blen, in, inl); + return inl; +} + +static int mem_read(BIO *b, char *out, int outl) +{ + BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; + + if (outl <= 0) + { + return 0; + } + + if (out == NULL) + { + return -1; + } + + if (outl > bbm->length - bbm->offset) + { + outl = bbm->length - bbm->offset; + } + + memcpy(out, bbm->data + bbm->offset, outl); + bbm->offset += outl; + return outl; +} + +static int mem_new(BIO *bi) +{ + BIO_BUF_MEM *bbm = zalloc(sizeof(*bbm)); + + if (bbm == NULL) + { + return 0; + } + + bi->ptr = bbm; + return 1; +} + +static int mem_free(BIO *a) +{ + BIO_BUF_MEM *bbm; + + if (a == NULL) + { + return 0; + } + + bbm = (BIO_BUF_MEM *)a->ptr; + if (bbm->data) + { + free(bbm->data); + } + + free(bbm); + return 1; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +const BIO_METHOD *BIO_s_mem(void) +{ + return &g_mem_method; +} From 94ffd5e9f0823144320465b4d269280c22ca48eb Mon Sep 17 00:00:00 2001 From: makejian Date: Fri, 6 Jun 2025 13:43:24 +0800 Subject: [PATCH 129/568] openssl_wrapper_mbedtls: extend openssl interfaces in ssl module for mqtt VELAPLATFO-62586 Change-Id: I3b56b028e76aee118ed90211c097ac3fe86bc129 Signed-off-by: makejian (cherry picked from commit 7a567e98489f64b740044b9ce4066fa8d41af359) --- .../include/openssl/crypto.h | 48 +++ .../include/openssl/err.h | 6 + .../include/openssl/evp.h | 8 + .../include/openssl/ssl.h | 240 +++++++++-- .../include/openssl/ssl_local.h | 40 +- .../include/openssl/tls1.h | 53 ++- .../include/openssl/types.h | 18 +- .../include/openssl/x509.h | 18 +- crypto/openssl_mbedtls_wrapper/mbedtls/err.c | 27 ++ crypto/openssl_mbedtls_wrapper/mbedtls/evp.c | 9 + .../openssl_mbedtls_wrapper/mbedtls/ssl_lib.c | 404 +++++++++++++++++- .../mbedtls/ssl_methods.c | 3 +- .../mbedtls/ssl_methods.h | 30 +- .../openssl_mbedtls_wrapper/mbedtls/ssl_pm.c | 166 +++---- .../openssl_mbedtls_wrapper/mbedtls/ssl_pm.h | 6 +- .../openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c | 5 + 16 files changed, 907 insertions(+), 174 deletions(-) create mode 100644 crypto/openssl_mbedtls_wrapper/include/openssl/crypto.h diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/crypto.h b/crypto/openssl_mbedtls_wrapper/include/openssl/crypto.h new file mode 100644 index 000000000..b573b2949 --- /dev/null +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/crypto.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * apps/crypto/openssl_mbedtls_wrapper/include/openssl/crypto.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + ****************************************************************************/ + +#ifndef OPENSSL_MBEDTLS_WRAPPER_CRYPTO_H +#define OPENSSL_MBEDTLS_WRAPPER_CRYPTO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CRYPTO_num_locks() 1 +#define CRYPTO_set_locking_callback(func) + +#define CRYPTO_set_id_callback(func) + +/* These defines where used in combination with the old locking callbacks, + * they are not called anymore, but old code that's not called might still + * use them. + */ + +#define CRYPTO_LOCK 1 +#define CRYPTO_UNLOCK 2 +#define CRYPTO_READ 4 +#define CRYPTO_WRITE 8 + +#endif /* OPENSSL_MBEDTLS_WRAPPER_CRYPTO_H */ diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/err.h b/crypto/openssl_mbedtls_wrapper/include/openssl/err.h index f6637eca4..1453be16e 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/err.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/err.h @@ -49,6 +49,12 @@ unsigned long ERR_peek_last_error(void); void ERR_error_string_n(unsigned long e, char *buf, size_t len); void ERR_free_strings(void); char *ERR_error_string(unsigned long e, char *buf); +void ERR_clear_error(void); +unsigned long ERR_get_error(void); +void ERR_remove_state(unsigned long pid); +int ERR_load_crypto_strings(void); +void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), + void *u); #ifdef __cplusplus } diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/evp.h b/crypto/openssl_mbedtls_wrapper/include/openssl/evp.h index f65a51d88..e1696bfa6 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/evp.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/evp.h @@ -44,6 +44,10 @@ #define EVP_PKEY_X25519 NID_X25519 +/**************************************************************************** + * Public Types + ****************************************************************************/ + struct evp_pkey_st { void *pkey_pm; @@ -166,6 +170,10 @@ int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len, const PKEY_METHOD *EVP_PKEY_method(void); +int OpenSSL_add_all_algorithms(void); + +void EVP_cleanup(void); + #ifdef __cplusplus } #endif diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h index 937c1ab95..94291eea8 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h @@ -25,13 +25,19 @@ ****************************************************************************/ #include +#include #include +#include #include #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + /* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ -#define SSL_SENT_SHUTDOWN 1 -#define SSL_RECEIVED_SHUTDOWN 2 +#define SSL_SENT_SHUTDOWN 1 +#define SSL_RECEIVED_SHUTDOWN 2 #define SSL_VERIFY_NONE 0x00 #define SSL_VERIFY_PEER 0x01 @@ -57,52 +63,133 @@ #define SSL_ERROR_WANT_READ 2 #define SSL_ERROR_WANT_WRITE 3 #define SSL_ERROR_WANT_X509_LOOKUP 4 -#define SSL_ERROR_SYSCALL 5/* look at error stack/return value/errno */ +#define SSL_ERROR_SYSCALL 5 /* look at error stack/return value/errno */ #define SSL_ERROR_ZERO_RETURN 6 #define SSL_ERROR_WANT_CONNECT 7 #define SSL_ERROR_WANT_ACCEPT 8 #define SSL_ERROR_WANT_ASYNC 9 -#define SSL_ERROR_WANT_ASYNC_JOB 10 +#define SSL_ERROR_WANT_ASYNC_JOB 10 + +#define SSL_ST_CONNECT 0x1000 +#define SSL_ST_ACCEPT 0x2000 + +#define SSL_ST_MASK 0x0FFF + +#define SSL_CB_LOOP 0x01 +#define SSL_CB_EXIT 0x02 +#define SSL_CB_READ 0x04 +#define SSL_CB_WRITE 0x08 +#define SSL_CB_ALERT 0x4000 /* used in callback */ +#define SSL_CB_READ_ALERT (SSL_CB_ALERT | SSL_CB_READ) +#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT | SSL_CB_WRITE) +#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT | SSL_CB_LOOP) +#define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT | SSL_CB_EXIT) +#define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT | SSL_CB_LOOP) +#define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT | SSL_CB_EXIT) +#define SSL_CB_HANDSHAKE_START 0x10 +#define SSL_CB_HANDSHAKE_DONE 0x20 + +#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +#define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): + */ + +#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001U + +/* Make it possible to retry SSL_write() with changed buffer location (buffer + * contents must stay the same!); this is not the default to avoid the + * misconception that non-blocking SSL_write() behaves like non-blocking + * write(): + */ + +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002U + +#define SSLEAY_VERSION 0 +#define SSLEAY_CFLAGS 1 +#define SSLEAY_BUILT_ON 2 +#define SSLEAY_PLATFORM 3 +#define SSLEAY_DIR 4 + +#define SSL2_VERSION 0x0002 + +#define SSL2_MT_CLIENT_HELLO 1 + +#define SSLv23_client_method TLS_client_method +#define SSL_library_init() 1 +#define SSL_load_error_strings() + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef unsigned int (*SSL_psk_client_cb_func)(SSL *ssl, + const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); + +typedef void (*ossl_msg_cb)(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); typedef enum { - TLS_ST_BEFORE, - TLS_ST_OK, - DTLS_ST_CR_HELLO_VERIFY_REQUEST, - TLS_ST_CR_SRVR_HELLO, - TLS_ST_CR_CERT, - TLS_ST_CR_CERT_STATUS, - TLS_ST_CR_KEY_EXCH, - TLS_ST_CR_CERT_REQ, - TLS_ST_CR_SRVR_DONE, - TLS_ST_CR_SESSION_TICKET, - TLS_ST_CR_CHANGE, - TLS_ST_CR_FINISHED, - TLS_ST_CW_CLNT_HELLO, - TLS_ST_CW_CERT, - TLS_ST_CW_KEY_EXCH, - TLS_ST_CW_CERT_VRFY, - TLS_ST_CW_CHANGE, - TLS_ST_CW_NEXT_PROTO, - TLS_ST_CW_FINISHED, - TLS_ST_SW_HELLO_REQ, - TLS_ST_SR_CLNT_HELLO, - DTLS_ST_SW_HELLO_VERIFY_REQUEST, - TLS_ST_SW_SRVR_HELLO, - TLS_ST_SW_CERT, - TLS_ST_SW_KEY_EXCH, - TLS_ST_SW_CERT_REQ, - TLS_ST_SW_SRVR_DONE, - TLS_ST_SR_CERT, - TLS_ST_SR_KEY_EXCH, - TLS_ST_SR_CERT_VRFY, - TLS_ST_SR_NEXT_PROTO, - TLS_ST_SR_CHANGE, - TLS_ST_SR_FINISHED, - TLS_ST_SW_SESSION_TICKET, - TLS_ST_SW_CERT_STATUS, - TLS_ST_SW_CHANGE, - TLS_ST_SW_FINISHED + TLS_ST_BEFORE, + TLS_ST_OK, + DTLS_ST_CR_HELLO_VERIFY_REQUEST, + TLS_ST_CR_SRVR_HELLO, + TLS_ST_CR_CERT, + TLS_ST_CR_COMP_CERT, + TLS_ST_CR_CERT_STATUS, + TLS_ST_CR_KEY_EXCH, + TLS_ST_CR_CERT_REQ, + TLS_ST_CR_SRVR_DONE, + TLS_ST_CR_SESSION_TICKET, + TLS_ST_CR_CHANGE, + TLS_ST_CR_FINISHED, + TLS_ST_CW_CLNT_HELLO, + TLS_ST_CW_CERT, + TLS_ST_CW_COMP_CERT, + TLS_ST_CW_KEY_EXCH, + TLS_ST_CW_CERT_VRFY, + TLS_ST_CW_CHANGE, + TLS_ST_CW_NEXT_PROTO, + TLS_ST_CW_FINISHED, + TLS_ST_SW_HELLO_REQ, + TLS_ST_SR_CLNT_HELLO, + DTLS_ST_SW_HELLO_VERIFY_REQUEST, + TLS_ST_SW_SRVR_HELLO, + TLS_ST_SW_CERT, + TLS_ST_SW_COMP_CERT, + TLS_ST_SW_KEY_EXCH, + TLS_ST_SW_CERT_REQ, + TLS_ST_SW_SRVR_DONE, + TLS_ST_SR_CERT, + TLS_ST_SR_COMP_CERT, + TLS_ST_SR_KEY_EXCH, + TLS_ST_SR_CERT_VRFY, + TLS_ST_SR_NEXT_PROTO, + TLS_ST_SR_CHANGE, + TLS_ST_SR_FINISHED, + TLS_ST_SW_SESSION_TICKET, + TLS_ST_SW_CERT_STATUS, + TLS_ST_SW_CHANGE, + TLS_ST_SW_FINISHED, + TLS_ST_SW_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_CERT_VRFY, + TLS_ST_SW_CERT_VRFY, + TLS_ST_CR_HELLO_REQ, + TLS_ST_SW_KEY_UPDATE, + TLS_ST_CW_KEY_UPDATE, + TLS_ST_SR_KEY_UPDATE, + TLS_ST_CR_KEY_UPDATE, + TLS_ST_EARLY_DATA, + TLS_ST_PENDING_EARLY_DATA_END, + TLS_ST_CW_END_OF_EARLY_DATA, + TLS_ST_SR_END_OF_EARLY_DATA } OSSL_HANDSHAKE_STATE; @@ -141,6 +228,8 @@ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); + int SSL_use_certificate_file(SSL *ssl, const char *file, int type); X509 *SSL_get_peer_certificate(const SSL *ssl); @@ -161,7 +250,7 @@ int SSL_get_error(const SSL *ssl, int ret_code); OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); -SSL_CTX *SSL_CTX_new(const SSL_METHOD *method, void *rngctx); +SSL_CTX *SSL_CTX_new(const SSL_METHOD *method, ...); void SSL_CTX_free(SSL_CTX *ctx); @@ -299,6 +388,73 @@ int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); +const SSL_METHOD *TLS_method(void); +const SSL_METHOD *TLS_server_method(void); +const SSL_METHOD *TLS_client_method(void); + +const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_server_method(void); +const SSL_METHOD *TLSv1_client_method(void); + +const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_server_method(void); +const SSL_METHOD *TLSv1_1_client_method(void); + +const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_server_method(void); +const SSL_METHOD *TLSv1_2_client_method(void); + +SSL_SESSION *SSL_get1_session(SSL *ssl); + +void SSL_SESSION_free(SSL_SESSION *session); + +int SSL_set_session(SSL *s, SSL_SESSION *session); + +const char *SSLeay_version(int t); + +const char *SSL_state_string_long(const SSL *s); + +const char *SSL_get_cipher_name(const SSL *s); + +const char *SSL_alert_type_string_long(int value); + +const char *SSL_alert_desc_string_long(int value); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); + +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); + +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); + +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb); + +long SSL_CTX_set_mode(SSL_CTX *ctx, long larg); + +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, int type, int val)); + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb)(int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); + +const char *SSL_get_cipher_list(const SSL *s, int n); + +long SSL_set_tlsext_host_name(SSL *s, void *parg); + +int SSL_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + +const char *SSL_get_cipher_list(const SSL *s, int n); + +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); + +int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg); + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); + #ifdef __cplusplus } #endif diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h index b9295d1c9..13f692b4e 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h @@ -30,11 +30,6 @@ #include #include -#ifdef __cplusplus -extern "C" -{ -#endif - /**************************************************************************** * Public Types ****************************************************************************/ @@ -61,6 +56,24 @@ struct ssl_ctx_st int read_ahead; int read_buffer_len; X509_VERIFY_PARAM param; + + /* Default password callback. */ + + pem_password_cb *default_passwd_callback; + + /* Default password callback user data. */ + + void *default_passwd_callback_userdata; + uint32_t mode; + + /* optional informational callback */ + + void (*info_callback)(const SSL *ssl, int type, int val); + + /* callback that allows applications to peek at protocol messages */ + + ossl_msg_cb msg_callback; + SSL_psk_client_cb_func psk_client_callback; }; struct ssl_method_func_st @@ -97,6 +110,12 @@ struct ssl_session_st long timeout; long time; X509 *peer; + const SSL_CIPHER *cipher; + int references; + struct + { + char hostname[TLSEXT_MAXLEN_host_name]; + } ext; }; struct ssl_st @@ -132,8 +151,19 @@ struct ssl_st /* SSL low-level system arch point */ void *ssl_pm; + SSL_CIPHER *cipher_list; }; +struct ssl_cipher_st +{ + const char *name; /* text name */ +}; + +#ifdef __cplusplus +extern "C" +{ +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/tls1.h b/crypto/openssl_mbedtls_wrapper/include/openssl/tls1.h index 57fd4fa26..6f0ff49cb 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/tls1.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/tls1.h @@ -20,42 +20,63 @@ #ifndef OPENSSL_MBEDTLS_WRAPPER_TLS1_H #define OPENSSL_MBEDTLS_WRAPPER_TLS1_H -#ifdef __cplusplus -extern "C" -{ -#endif +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ #define TLS1_AD_DECRYPTION_FAILED 21 #define TLS1_AD_RECORD_OVERFLOW 22 -#define TLS1_AD_UNKNOWN_CA 48/* fatal */ -#define TLS1_AD_ACCESS_DENIED 49/* fatal */ -#define TLS1_AD_DECODE_ERROR 50/* fatal */ +#define TLS1_AD_UNKNOWN_CA 48 /* fatal */ +#define TLS1_AD_ACCESS_DENIED 49 /* fatal */ +#define TLS1_AD_DECODE_ERROR 50 /* fatal */ #define TLS1_AD_DECRYPT_ERROR 51 -#define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ -#define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ -#define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ -#define TLS1_AD_INTERNAL_ERROR 80/* fatal */ -#define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ +#define TLS1_AD_EXPORT_RESTRICTION 60 /* fatal */ +#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ +#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ +#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ +#define TLS1_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */ #define TLS1_AD_USER_CANCELLED 90 #define TLS1_AD_NO_RENEGOTIATION 100 + /* codes 110-114 are from RFC3546 */ + #define TLS1_AD_UNSUPPORTED_EXTENSION 110 #define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 #define TLS1_AD_UNRECOGNIZED_NAME 112 #define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 #define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 -#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ -#define TLS1_AD_NO_APPLICATION_PROTOCOL 120/* fatal */ +#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */ +#define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ /* Special value for method supporting multiple versions */ + #define TLS_ANY_VERSION 0x10000 #define TLS1_VERSION 0x0301 #define TLS1_1_VERSION 0x0302 #define TLS1_2_VERSION 0x0303 -#define SSL_TLSEXT_ERR_OK 0 -#define SSL_TLSEXT_ERR_NOACK 3 +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_NOACK 3 + +#define TLSEXT_MAXLEN_host_name 255 + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +long SSL_set_tlsext_host_name(SSL *s, void *parg); #ifdef __cplusplus } diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/types.h b/crypto/openssl_mbedtls_wrapper/include/openssl/types.h index c03078645..294ef20f6 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/types.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/types.h @@ -20,17 +20,18 @@ #ifndef OPENSSL_MBEDTLS_WRAPPER_TYPES_H #define OPENSSL_MBEDTLS_WRAPPER_TYPES_H -#ifdef __cplusplus -extern "C" -{ -#endif +/**************************************************************************** + * Public Types + ****************************************************************************/ -typedef void SSL_CIPHER; +typedef void CRYPTO_EX_new; +typedef void CRYPTO_THREADID; typedef void X509_STORE; - typedef void RSA; typedef int (*OPENSSL_sk_compfunc)(const void *, const void *); +typedef int pem_password_cb(char *buf, int size, + int rwflag, void *userdata); typedef struct bio_buf_mem_st BIO_BUF_MEM; typedef struct bio_method_st BIO_METHOD; @@ -43,6 +44,7 @@ typedef struct ossl_statem_st OSSL_STATEM; typedef struct ssl_session_st SSL_SESSION; typedef struct ssl_ctx_st SSL_CTX; typedef struct ssl_st SSL; +typedef struct ssl_cipher_st SSL_CIPHER; typedef struct cert_st CERT; typedef struct x509_st X509; typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; @@ -68,8 +70,4 @@ struct pkey_method_st int (*pkey_load)(EVP_PKEY *pkey, const unsigned char *buf, int len); }; -#ifdef __cplusplus -} -#endif - #endif /* OPENSSL_MBEDTLS_WRAPPER_TYPES_H */ diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h b/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h index 847aaa4bc..d7cff9a4b 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h @@ -34,10 +34,13 @@ #include #include -#ifdef __cplusplus -extern "C" -{ -#endif +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define X509_FILETYPE_PEM 1 +#define X509_FILETYPE_ASN1 2 +#define X509_FILETYPE_DEFAULT 3 /**************************************************************************** * Public Types @@ -56,6 +59,8 @@ struct x509_method_st int (*x509_new)(X509 *x, X509 *m_x); void (*x509_free)(X509 *x); int (*x509_load)(X509 *x, const unsigned char *buf, int len); + int (*x509_load_file)(X509 *x, const char *file); + int (*x509_load_path)(X509 *x, const char *path); int (*x509_show_info)(X509 *x); }; @@ -66,6 +71,11 @@ struct cert_st EVP_PKEY *pkey; }; +#ifdef __cplusplus +extern "C" +{ +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/err.c b/crypto/openssl_mbedtls_wrapper/mbedtls/err.c index 34dad8dc5..4657259f7 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/err.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/err.c @@ -38,7 +38,34 @@ unsigned long ERR_peek_last_error(void) return errno; } +void ERR_free_strings(void) +{ +} + void ERR_error_string_n(unsigned long e, char *buf, size_t len) { mbedtls_strerror(e, buf, len); } + +void ERR_clear_error(void) +{ +} + +unsigned long ERR_get_error(void) +{ + return errno; +} + +void ERR_remove_state(unsigned long pid) +{ +} + +int ERR_load_crypto_strings(void) +{ + return 1; +} + +void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), + void *u) +{ +} diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/evp.c b/crypto/openssl_mbedtls_wrapper/mbedtls/evp.c index 3045c495a..b1feae343 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/evp.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/evp.c @@ -344,3 +344,12 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, { return 0; } + +int OpenSSL_add_all_algorithms(void) +{ + return 0; +} + +void EVP_cleanup(void) +{ +} diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c index a4f0eea40..4e7bf0968 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c @@ -21,13 +21,22 @@ * Included Files ****************************************************************************/ +#include #include #include #include #include "ssl_port.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + #define SSL_SEND_DATA_MAX_LENGTH 1460 +/**************************************************************************** + * Private Types + ****************************************************************************/ + struct alpn_ctx { unsigned char data[23]; @@ -56,6 +65,7 @@ static SSL_SESSION *SSL_SESSION_new(void) goto failed2; } + session->references = 1; return session; failed2: @@ -64,12 +74,6 @@ failed1: return NULL; } -static void SSL_SESSION_free(SSL_SESSION *session) -{ - X509_free(session->peer); - ssl_mem_free(session); -} - static void _openssl_alpn_to_mbedtls(struct alpn_ctx *ac, char ***palpn_protos) { @@ -256,7 +260,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) return ret; } -SSL_CTX *SSL_CTX_new(const SSL_METHOD *method, void *rngctx) +SSL_CTX *SSL_CTX_new(const SSL_METHOD *method, ...) { SSL_CTX *ctx; CERT *cert; @@ -1014,3 +1018,389 @@ void SSL_set_alpn_select_cb(SSL *ssl, void *arg) _ssl_set_alpn_list(ssl); } + +SSL_SESSION *SSL_get1_session(SSL *ssl) +{ + SSL_ASSERT2(ssl); + + atomic_fetch_add(&ssl->session->references, 1); + return ssl->session; +} + +void SSL_SESSION_free(SSL_SESSION *session) +{ + SSL_ASSERT3(session); + + if (atomic_fetch_sub(&session->references, 1) == 1) + { + X509_free(session->peer); + ssl_mem_free(session); + } +} + +int SSL_set_session(SSL *s, SSL_SESSION *session) +{ + SSL_ASSERT1(s); + SSL_ASSERT1(session); + + SSL_SESSION_free(s->session); + s->session = session; + return 1; +} + +const char *SSLeay_version(int t) +{ + return "not available"; +} + +const char *SSL_state_string_long(const SSL *s) +{ + SSL_ASSERT2(s); + + switch (SSL_get_state(s)) + { + case TLS_ST_CR_CERT_STATUS: + return "SSLv3/TLS read certificate status"; + case TLS_ST_CW_NEXT_PROTO: + return "SSLv3/TLS write next proto"; + case TLS_ST_SR_NEXT_PROTO: + return "SSLv3/TLS read next proto"; + case TLS_ST_SW_CERT_STATUS: + return "SSLv3/TLS write certificate status"; + case TLS_ST_BEFORE: + return "before SSL initialization"; + case TLS_ST_OK: + return "SSL negotiation finished successfully"; + case TLS_ST_CW_CLNT_HELLO: + return "SSLv3/TLS write client hello"; + case TLS_ST_CR_SRVR_HELLO: + return "SSLv3/TLS read server hello"; + case TLS_ST_CR_CERT: + return "SSLv3/TLS read server certificate"; + case TLS_ST_CR_COMP_CERT: + return "TLSv1.3 read server compressed certificate"; + case TLS_ST_CR_KEY_EXCH: + return "SSLv3/TLS read server key exchange"; + case TLS_ST_CR_CERT_REQ: + return "SSLv3/TLS read server certificate request"; + case TLS_ST_CR_SESSION_TICKET: + return "SSLv3/TLS read server session ticket"; + case TLS_ST_CR_SRVR_DONE: + return "SSLv3/TLS read server done"; + case TLS_ST_CW_CERT: + return "SSLv3/TLS write client certificate"; + case TLS_ST_CW_COMP_CERT: + return "TLSv1.3 write client compressed certificate"; + case TLS_ST_CW_KEY_EXCH: + return "SSLv3/TLS write client key exchange"; + case TLS_ST_CW_CERT_VRFY: + return "SSLv3/TLS write certificate verify"; + case TLS_ST_CW_CHANGE: + case TLS_ST_SW_CHANGE: + return "SSLv3/TLS write change cipher spec"; + case TLS_ST_CW_FINISHED: + case TLS_ST_SW_FINISHED: + return "SSLv3/TLS write finished"; + case TLS_ST_CR_CHANGE: + case TLS_ST_SR_CHANGE: + return "SSLv3/TLS read change cipher spec"; + case TLS_ST_CR_FINISHED: + case TLS_ST_SR_FINISHED: + return "SSLv3/TLS read finished"; + case TLS_ST_SR_CLNT_HELLO: + return "SSLv3/TLS read client hello"; + case TLS_ST_SW_HELLO_REQ: + return "SSLv3/TLS write hello request"; + case TLS_ST_SW_SRVR_HELLO: + return "SSLv3/TLS write server hello"; + case TLS_ST_SW_CERT: + return "SSLv3/TLS write certificate"; + case TLS_ST_SW_COMP_CERT: + return "TLSv1.3 write server compressed certificate"; + case TLS_ST_SW_KEY_EXCH: + return "SSLv3/TLS write key exchange"; + case TLS_ST_SW_CERT_REQ: + return "SSLv3/TLS write certificate request"; + case TLS_ST_SW_SESSION_TICKET: + return "SSLv3/TLS write session ticket"; + case TLS_ST_SW_SRVR_DONE: + return "SSLv3/TLS write server done"; + case TLS_ST_SR_CERT: + return "SSLv3/TLS read client certificate"; + case TLS_ST_SR_COMP_CERT: + return "TLSv1.3 read client compressed certificate"; + case TLS_ST_SR_KEY_EXCH: + return "SSLv3/TLS read client key exchange"; + case TLS_ST_SR_CERT_VRFY: + return "SSLv3/TLS read certificate verify"; + case DTLS_ST_CR_HELLO_VERIFY_REQUEST: + return "DTLS1 read hello verify request"; + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + return "DTLS1 write hello verify request"; + case TLS_ST_SW_ENCRYPTED_EXTENSIONS: + return "TLSv1.3 write encrypted extensions"; + case TLS_ST_CR_ENCRYPTED_EXTENSIONS: + return "TLSv1.3 read encrypted extensions"; + case TLS_ST_CR_CERT_VRFY: + return "TLSv1.3 read server certificate verify"; + case TLS_ST_SW_CERT_VRFY: + return "TLSv1.3 write server certificate verify"; + case TLS_ST_CR_HELLO_REQ: + return "SSLv3/TLS read hello request"; + case TLS_ST_SW_KEY_UPDATE: + return "TLSv1.3 write server key update"; + case TLS_ST_CW_KEY_UPDATE: + return "TLSv1.3 write client key update"; + case TLS_ST_SR_KEY_UPDATE: + return "TLSv1.3 read client key update"; + case TLS_ST_CR_KEY_UPDATE: + return "TLSv1.3 read server key update"; + case TLS_ST_EARLY_DATA: + return "TLSv1.3 early data"; + case TLS_ST_PENDING_EARLY_DATA_END: + return "TLSv1.3 pending early data end"; + case TLS_ST_CW_END_OF_EARLY_DATA: + return "TLSv1.3 write end of early data"; + case TLS_ST_SR_END_OF_EARLY_DATA: + return "TLSv1.3 read end of early data"; + default: + return "unknown state"; + } +} + +const char *SSL_get_cipher_name(const SSL *s) +{ + SSL_ASSERT2(s); + SSL_ASSERT2(s->session); + + return s->session->cipher->name ? s->session->cipher->name : "(NONE)"; +} + +const char *SSL_alert_type_string_long(int value) +{ + switch (value >> 8) + { + case SSL3_AL_WARNING: + return "warning"; + case SSL3_AL_FATAL: + return "fatal"; + } + + return "unknown"; +} + +const char *SSL_alert_desc_string_long(int value) +{ + switch (value & 0xff) + { + case SSL3_AD_CLOSE_NOTIFY: + return "close notify"; + case SSL3_AD_UNEXPECTED_MESSAGE: + return "unexpected message"; + case SSL3_AD_BAD_RECORD_MAC: + return "bad record mac"; + case SSL3_AD_DECOMPRESSION_FAILURE: + return "decompression failure"; + case SSL3_AD_HANDSHAKE_FAILURE: + return "handshake failure"; + case SSL3_AD_NO_CERTIFICATE: + return "no certificate"; + case SSL3_AD_BAD_CERTIFICATE: + return "bad certificate"; + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + return "unsupported certificate"; + case SSL3_AD_CERTIFICATE_REVOKED: + return "certificate revoked"; + case SSL3_AD_CERTIFICATE_EXPIRED: + return "certificate expired"; + case SSL3_AD_CERTIFICATE_UNKNOWN: + return "certificate unknown"; + case SSL3_AD_ILLEGAL_PARAMETER: + return "illegal parameter"; + case TLS1_AD_DECRYPTION_FAILED: + return "decryption failed"; + case TLS1_AD_RECORD_OVERFLOW: + return "record overflow"; + case TLS1_AD_UNKNOWN_CA: + return "unknown CA"; + case TLS1_AD_ACCESS_DENIED: + return "access denied"; + case TLS1_AD_DECODE_ERROR: + return "decode error"; + case TLS1_AD_DECRYPT_ERROR: + return "decrypt error"; + case TLS1_AD_EXPORT_RESTRICTION: + return "export restriction"; + case TLS1_AD_PROTOCOL_VERSION: + return "protocol version"; + case TLS1_AD_INSUFFICIENT_SECURITY: + return "insufficient security"; + case TLS1_AD_INTERNAL_ERROR: + return "internal error"; + case TLS1_AD_USER_CANCELLED: + return "user canceled"; + case TLS1_AD_NO_RENEGOTIATION: + return "no renegotiation"; + case TLS1_AD_UNSUPPORTED_EXTENSION: + return "unsupported extension"; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + return "certificate unobtainable"; + case TLS1_AD_UNRECOGNIZED_NAME: + return "unrecognized name"; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return "bad certificate status response"; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + return "bad certificate hash value"; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + return "unknown PSK identity"; + case TLS1_AD_NO_APPLICATION_PROTOCOL: + return "no application protocol"; + default: + return "unknown"; + } +} + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) +{ + ctx->default_passwd_callback = cb; +} + +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) +{ + ctx->default_passwd_callback_userdata = u; +} + +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb) +{ + ctx->psk_client_callback = cb; +} + +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) +{ + return 0; +} + +long SSL_CTX_set_mode(SSL_CTX *ctx, long larg) +{ + return ctx->mode |= larg; +} + +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, int type, int val)) +{ + ctx->info_callback = cb; +} + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb)(int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)) +{ + ctx->msg_callback = cb; +} + +long SSL_set_tlsext_host_name(SSL *s, void *parg) +{ + size_t len; + + SSL_ASSERT1(s); + SSL_ASSERT1(s->session); + + if (parg == NULL) + { + return 1; + } + + len = strlen(parg); + if (len == 0 || len > TLSEXT_MAXLEN_host_name) + { + return 0; + } + + memset(s->session->ext.hostname, 0, TLSEXT_MAXLEN_host_name); + memcpy(s->session->ext.hostname, parg, len); + return 1; +} + +int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile) +{ + X509 *x; + int ret; + + SSL_ASSERT1(ctx); + SSL_ASSERT1(CAfile); + + x = X509_new(); + ret = X509_METHOD_CALL(load_file, x, CAfile); + if (ret) + { + X509_free(x); + return 0; + } + + SSL_CTX_add_client_CA(ctx, x); + return 1; +} + +int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath) +{ + X509 *x; + int ret; + + SSL_ASSERT1(ctx); + SSL_ASSERT1(CApath); + + x = X509_new(); + ret = X509_METHOD_CALL(load_path, x, CApath); + if (ret) + { + X509_free(x); + return 0; + } + + SSL_CTX_add_client_CA(ctx, x); + return 1; +} + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath) +{ + if (CAfile == NULL && CApath == NULL) + { + return 0; + } + + if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile)) + { + return 0; + } + + if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath)) + { + return 0; + } + + return 1; +} + +int SSL_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + return 0; +} + +const char *SSL_get_cipher_list(const SSL *s, int n) +{ + return NULL; +} + +int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) +{ + return 0; +} + +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) +{ + return 0; +} diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.c index 7abddee9f..a5b8e5bb0 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.c @@ -95,7 +95,8 @@ IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); IMPLEMENT_X509_METHOD(X509_method, x509_pm_new, x509_pm_free, - x509_pm_load, x509_pm_show_info); + x509_pm_load, x509_pm_load_file, + x509_pm_load_path, x509_pm_show_info); /** * @brief get private key object method diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.h b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.h index 3c2647814..c93546fc7 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.h +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_methods.h @@ -27,10 +27,9 @@ #include #include "ssl_pm.h" -#ifdef __cplusplus -extern "C" -{ -#endif +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ /* TLS method function implement */ @@ -42,7 +41,7 @@ extern "C" set_bufflen, \ get_verify_result, \ get_state) \ - static const SSL_METHOD_FUNC func_name LOCAL_ATRR = \ + static const SSL_METHOD_FUNC func_name = \ { \ new, \ free, \ @@ -62,7 +61,7 @@ extern "C" #define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \ const SSL_METHOD* func_name(void) \ { \ - static const SSL_METHOD func_name##_data LOCAL_ATRR = \ + static const SSL_METHOD func_name##_data = \ { \ ver, \ mode, \ @@ -74,7 +73,7 @@ extern "C" #define IMPLEMENT_SSL_METHOD(ver, mode, fun, func_name) \ const SSL_METHOD* func_name(void) \ { \ - static const SSL_METHOD func_name##_data LOCAL_ATRR = \ + static const SSL_METHOD func_name##_data = \ { \ ver, \ mode, \ @@ -87,14 +86,18 @@ extern "C" new, \ free, \ load, \ + load_file, \ + load_path, \ show_info) \ const X509_METHOD* func_name(void) \ { \ - static const X509_METHOD func_name##_data LOCAL_ATRR = \ + static const X509_METHOD func_name##_data = \ { \ new, \ free, \ load, \ + load_file, \ + load_path, \ show_info \ }; \ return &func_name##_data; \ @@ -106,7 +109,7 @@ extern "C" load) \ const PKEY_METHOD* func_name(void) \ { \ - static const PKEY_METHOD func_name##_data LOCAL_ATRR = \ + static const PKEY_METHOD func_name##_data = \ { \ new, \ free, \ @@ -115,6 +118,15 @@ extern "C" return &func_name##_data; \ } +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + /** * @brief get X509 object method * diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c index 95bec900e..086968794 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c @@ -38,7 +38,16 @@ #include "mbedtls/ctr_drbg.h" #include "mbedtls/error.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + #define X509_INFO_STRING_LENGTH 8192 +#define READ_TIMEOUT_MS 50000 /* 50 seconds */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ struct ssl_pm { @@ -58,7 +67,7 @@ struct ssl_pm struct x509_pm { - mbedtls_x509_crt *x509_crt; + mbedtls_x509_crt x509_crt; mbedtls_x509_crt *ex_crt; }; @@ -68,10 +77,15 @@ struct pkey_pm mbedtls_pk_context *ex_pkey; }; +/**************************************************************************** + * Public Data + ****************************************************************************/ + unsigned int max_content_len; -/* mbedtls debug level */ -#define MBEDTLS_DEBUG_LEVEL 4 +/**************************************************************************** + * Private Functions + ****************************************************************************/ /** * @brief mbedtls debug function @@ -134,6 +148,7 @@ int ssl_pm_new(SSL *ssl) mbedtls_ctr_drbg_init(&ssl_pm->ctr_drbg); mbedtls_entropy_init(&ssl_pm->entropy); mbedtls_ssl_init(&ssl_pm->ssl); + mbedtls_ssl_conf_read_timeout(&ssl_pm->conf, READ_TIMEOUT_MS); ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len); @@ -210,7 +225,8 @@ int ssl_pm_new(SSL *ssl) } mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, - mbedtls_net_send, mbedtls_net_recv, NULL); + mbedtls_net_send, mbedtls_net_recv, + mbedtls_net_recv_timeout); ssl->ssl_pm = ssl_pm; @@ -249,7 +265,7 @@ void ssl_pm_free(SSL *ssl) static int ssl_pm_reload_crt(SSL *ssl) { - int ret; + int ret = 0; int mode; struct ssl_pm *ssl_pm = ssl->ssl_pm; struct x509_pm *ca_pm = (struct x509_pm *)ssl->client_CA->x509_pm; @@ -275,29 +291,16 @@ static int ssl_pm_reload_crt(SSL *ssl) } mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); - - if (ca_pm->x509_crt) - { - mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL); - } - else if (ca_pm->ex_crt) + mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &ca_pm->x509_crt, NULL); + if (ca_pm->ex_crt) { mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->ex_crt, NULL); } - if (crt_pm->x509_crt && pkey_pm->pkey) + if (pkey_pm->pkey) { ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, - crt_pm->x509_crt, pkey_pm->pkey); - } - else if (crt_pm->ex_crt && pkey_pm->ex_pkey) - { - ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, - crt_pm->ex_crt, pkey_pm->ex_pkey); - } - else - { - ret = 0; + &crt_pm->x509_crt, pkey_pm->pkey); } if (ret) @@ -342,7 +345,8 @@ int ssl_pm_handshake(SSL *ssl) ret = ssl_pm_reload_crt(ssl); if (ret) { - printf("%s: cert reload failed\n", __func__); + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "%s: cert reload failed\n", __func__); return 0; } @@ -396,7 +400,8 @@ int ssl_pm_handshake(SSL *ssl) return 0; } - printf("%s: mbedtls_ssl_handshake() returned -0x%x\n", __func__, -ret); + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "%s: mbedtls_ssl_handshake() returned -0x%x\n", __func__, -ret); /* it's had it */ @@ -415,7 +420,7 @@ ssl_ctx_get_mbedtls_x509_crt(SSL_CTX *ssl_ctx) return NULL; } - return x509_pm->x509_crt; + return &x509_pm->x509_crt; } mbedtls_x509_crt * @@ -451,7 +456,7 @@ int ssl_pm_shutdown(SSL *ssl) else { struct x509_pm *x509_pm = - (struct x509_pm *)ssl->session->peer->x509_pm; + (struct x509_pm *)ssl->session->peer->x509_pm; x509_pm->ex_crt = NULL; ret = 1; /* OpenSSL: "The shutdown was successfully completed" @@ -628,20 +633,8 @@ int x509_pm_show_info(X509 *x) mbedtls_x509_crt *x509_crt; struct x509_pm *x509_pm = x->x509_pm; - if (x509_pm->x509_crt) - { - x509_crt = x509_pm->x509_crt; - } - else if (x509_pm->ex_crt) - { - x509_crt = x509_pm->ex_crt; - } - else - { - x509_crt = NULL; - } - - if (!x509_crt) + x509_crt = &x509_pm->x509_crt; + if (x509_crt->version == 0) { return -1; } @@ -693,7 +686,7 @@ int x509_pm_new(X509 *x, X509 *m_x) { struct x509_pm *m_x509_pm = (struct x509_pm *)m_x->x509_pm; - x509_pm->ex_crt = m_x509_pm->x509_crt; + x509_pm->ex_crt = &m_x509_pm->x509_crt; } return 0; @@ -706,14 +699,7 @@ void x509_pm_free(X509 *x) { struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; - if (x509_pm->x509_crt) - { - mbedtls_x509_crt_free(x509_pm->x509_crt); - - ssl_mem_free(x509_pm->x509_crt); - x509_pm->x509_crt = NULL; - } - + mbedtls_x509_crt_free(&x509_pm->x509_crt); ssl_mem_free(x->x509_pm); x->x509_pm = NULL; } @@ -724,23 +710,8 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) unsigned char *load_buf; struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; - if (x509_pm->x509_crt) - { - mbedtls_x509_crt_free(x509_pm->x509_crt); - } - - if (!x509_pm->x509_crt) - { - x509_pm->x509_crt = ssl_mem_malloc(sizeof(mbedtls_x509_crt)); - if (!x509_pm->x509_crt) - { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, - "no enough memory > (x509_pm->x509_crt)"); - goto no_mem; - } - } - - mbedtls_x509_crt_init(x509_pm->x509_crt); + mbedtls_x509_crt_free(&x509_pm->x509_crt); + mbedtls_x509_crt_init(&x509_pm->x509_crt); if (buffer[0] != 0x30) { load_buf = ssl_mem_malloc(len + 1); @@ -754,32 +725,67 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; - ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len + 1); + ret = mbedtls_x509_crt_parse(&x509_pm->x509_crt, load_buf, len + 1); ssl_mem_free(load_buf); } else { - printf("parsing as der\n"); - - ret = mbedtls_x509_crt_parse_der(x509_pm->x509_crt, buffer, len); + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "parsing as der\n"); + ret = mbedtls_x509_crt_parse_der(&x509_pm->x509_crt, buffer, len); } if (ret) { - printf("mbedtls_x509_crt_parse return -0x%x", -ret); + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "mbedtls_x509_crt_parse return -0x%x", -ret); goto failed; } return 0; failed: - mbedtls_x509_crt_free(x509_pm->x509_crt); - ssl_mem_free(x509_pm->x509_crt); - x509_pm->x509_crt = NULL; -no_mem: + mbedtls_x509_crt_free(&x509_pm->x509_crt); return -1; } +int x509_pm_load_file(X509 *x, const char *path) +{ + int ret; + struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; + + mbedtls_x509_crt_free(&x509_pm->x509_crt); + mbedtls_x509_crt_init(&x509_pm->x509_crt); + ret = mbedtls_x509_crt_parse_file(&x509_pm->x509_crt, path); + if (ret) + { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "mbedtls_x509_crt_parse_file return -0x%x", -ret); + mbedtls_x509_crt_free(&x509_pm->x509_crt); + return -1; + } + + return 0; +} + +int x509_pm_load_path(X509 *x, const char *path) +{ + int ret; + struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; + + mbedtls_x509_crt_free(&x509_pm->x509_crt); + mbedtls_x509_crt_init(&x509_pm->x509_crt); + ret = mbedtls_x509_crt_parse_path(&x509_pm->x509_crt, path); + if (ret) + { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "mbedtls_x509_crt_parse_file return -0x%x", -ret); + mbedtls_x509_crt_free(&x509_pm->x509_crt); + return -1; + } + + return 0; +} + int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pkey) { struct pkey_pm *pkey_pm; @@ -977,7 +983,8 @@ void _ssl_set_alpn_list(const SSL *ssl) &((struct ssl_pm *)(ssl->ssl_pm))->conf, ssl->alpn_protos)) { - fprintf(stderr, "mbedtls_ssl_conf_alpn_protocols failed\n"); + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "mbedtls_ssl_conf_alpn_protocols failed\n"); } return; @@ -992,7 +999,8 @@ void _ssl_set_alpn_list(const SSL *ssl) &((struct ssl_pm *)(ssl->ssl_pm))->conf, ssl->ctx->alpn_protos)) { - fprintf(stderr, "mbedtls_ssl_conf_alpn_protocols failed\n"); + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "mbedtls_ssl_conf_alpn_protocols failed\n"); } } @@ -1070,8 +1078,8 @@ void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) ssl->verify_mode = ctx->verify_mode; - mbedtls_ssl_set_hs_ca_chain(&ssl_pm->ssl, x509_pm_ca->x509_crt, NULL); - mbedtls_ssl_set_hs_own_cert(&ssl_pm->ssl, x509_pm->x509_crt, + mbedtls_ssl_set_hs_ca_chain(&ssl_pm->ssl, &x509_pm_ca->x509_crt, NULL); + mbedtls_ssl_set_hs_own_cert(&ssl_pm->ssl, &x509_pm->x509_crt, pkey_pm->pkey); mbedtls_ssl_set_hs_authmode(&ssl_pm->ssl, mode); } diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.h b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.h index 22e6eda4a..0d2065024 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.h +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.h @@ -33,7 +33,9 @@ extern "C" { #endif -#define LOCAL_ATRR +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ int ssl_pm_new(SSL *ssl); void ssl_pm_free(SSL *ssl); @@ -57,6 +59,8 @@ int x509_pm_show_info(X509 *x); int x509_pm_new(X509 *x, X509 *m_x); void x509_pm_free(X509 *x); int x509_pm_load(X509 *x, const unsigned char *buffer, int len); +int x509_pm_load_file(X509 *x, const char *path); +int x509_pm_load_path(X509 *x, const char *path); int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pk); void pkey_pm_free(EVP_PKEY *pk); diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c index 0a754317d..7f21912ea 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_rsa.c @@ -124,6 +124,11 @@ int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) return 0; } +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) +{ + return 0; +} + int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { return 0; From 49e2592e3413ea9a1b32087a15b8d95370cdc104 Mon Sep 17 00:00:00 2001 From: makejian Date: Tue, 17 Jun 2025 17:07:27 +0800 Subject: [PATCH 130/568] openssl-mbedtls-wrapper: export SSL_ASSERT* macro VELAPLATFO-62586 Change-Id: I2ceac930c87196a16ea7ddf5e4130bb991b51025 Signed-off-by: makejian (cherry picked from commit d0547662d5006ec0a348d89d3d7e251ef4bb183c) --- crypto/openssl_mbedtls_wrapper/Kconfig | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/crypto/openssl_mbedtls_wrapper/Kconfig b/crypto/openssl_mbedtls_wrapper/Kconfig index 197adbc3e..3a4ee11a2 100644 --- a/crypto/openssl_mbedtls_wrapper/Kconfig +++ b/crypto/openssl_mbedtls_wrapper/Kconfig @@ -7,3 +7,25 @@ config OPENSSL_MBEDTLS_WRAPPER depends on CRYPTO_MBEDTLS bool "openssl mbedtls wrapper" default n + +if OPENSSL_MBEDTLS_WRAPPER + +choice + prompt "Openssl Mbedtls Wrapper Assert Debug" + default OPENSSL_ASSERT_EXIT + +config OPENSSL_ASSERT_DEBUG + bool "SSL_ASSERT* will show error file name and line" + +config OPENSSL_ASSERT_EXIT + bool "SSL_ASSERT* will just return error code" + +config OPENSSL_ASSERT_DEBUG_EXIT + bool "SSL_ASSERT* will show error file name and line, then return error code" + +config OPENSSL_ASSERT_DEBUG_BLOCK + bool "SSL_ASSERT* will show error file name and line, then block here with 'while (1)'" + +endchoice + +endif # OPENSSL_MBEDTLS_WRAPPER From bafe30898a80cda7203860f9f9e5b085db275f68 Mon Sep 17 00:00:00 2001 From: makejian Date: Wed, 23 Jul 2025 15:34:52 +0800 Subject: [PATCH 131/568] openssl-wrapper: mapping more error code whitin mbedtls and openssl when ssl error VELAPLATFO-66562 Change-Id: Ibb1446a7fcae1d2bc09d75052466a6ce084103b8 Signed-off-by: makejian --- crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c index 086968794..0169ed913 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c @@ -486,6 +486,22 @@ int ssl_pm_read(SSL *ssl, void *buffer, int len) { ssl->err = SSL_ERROR_SYSCALL; } + else if (ret == MBEDTLS_ERR_SSL_WANT_READ) + { + ssl->err = SSL_ERROR_WANT_READ; + } + else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) + { + ssl->err = SSL_ERROR_WANT_WRITE; + } + else if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) + { + ssl->err = SSL_ERROR_WANT_ASYNC; + } + else + { + ssl->err = SSL_ERROR_SSL; + } ret = -1; } From d2902008fe9ec6ac48884b40b9ef63585cf524b3 Mon Sep 17 00:00:00 2001 From: makejian Date: Fri, 16 Jan 2026 21:39:22 +0800 Subject: [PATCH 132/568] openssl-wrapper: fix code style compliance Fix coding style issues in OpenSSL/MbedTLS wrapper implementation: - Align whitespace and indentation - Fix line formatting - Ensure consistent code style per NuttX standards Signed-off-by: makejian --- crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h | 10 ++++++---- .../include/openssl/ssl_local.h | 8 ++++---- crypto/openssl_mbedtls_wrapper/include/openssl/x509.h | 2 +- crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h index 94291eea8..7bdc03125 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h @@ -131,8 +131,9 @@ typedef unsigned int (*SSL_psk_client_cb_func)(SSL *ssl, unsigned char *psk, unsigned int max_psk_len); -typedef void (*ossl_msg_cb)(int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg); +typedef void (*ossl_msg_cb)( + int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); typedef enum { @@ -426,12 +427,13 @@ void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); -void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb); +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, + SSL_psk_client_cb_func cb); long SSL_CTX_set_mode(SSL_CTX *ctx, long larg); void SSL_CTX_set_info_callback(SSL_CTX *ctx, - void (*cb)(const SSL *ssl, int type, int val)); + void (*cb)(const SSL *ssl, int type, int val)); void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h index 13f692b4e..053da27de 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl_local.h @@ -120,12 +120,12 @@ struct ssl_session_st struct ssl_st { -/* protocol version(one of SSL3.0, TLS1.0, etc.) */ + /* protocol version(one of SSL3.0, TLS1.0, etc.) */ int version; unsigned long options; -/* shut things down(0x01 : sent, 0x02 : received) */ + /* shut things down(0x01 : sent, 0x02 : received) */ int shutdown; CERT *cert; @@ -135,7 +135,7 @@ struct ssl_st const char **alpn_protos; RECORD_LAYER rlayer; -/* where we are */ + /* where we are */ OSSL_STATEM statem; SSL_SESSION *session; @@ -148,7 +148,7 @@ struct ssl_st int err; void (*info_callback) (const SSL *ssl, int type, int val); -/* SSL low-level system arch point */ + /* SSL low-level system arch point */ void *ssl_pm; SSL_CIPHER *cipher_list; diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h b/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h index d7cff9a4b..cda221276 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/x509.h @@ -48,7 +48,7 @@ struct x509_st { -/* X509 certification platform private point */ + /* X509 certification platform private point */ void *x509_pm; const X509_METHOD *method; diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c index 0169ed913..84ba2345e 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c @@ -634,7 +634,7 @@ OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl) case MBEDTLS_SSL_HANDSHAKE_OVER: state = TLS_ST_OK; break; - default : + default: state = TLS_ST_BEFORE; break; } From 9c85568c4f0f2c585401302f1fb36785c4a26a10 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Thu, 3 Jul 2025 15:31:33 +0800 Subject: [PATCH 133/568] icmpv6_ping.c: change socket type from SOCK_DGRAM to SOCK_RAW. standardize the implementation of ping6 to better comply with socket permissions on certain systems. Signed-off-by: zhanghongyu --- netutils/ping/icmpv6_ping.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/netutils/ping/icmpv6_ping.c b/netutils/ping/icmpv6_ping.c index e6a93fc98..c62c329d6 100644 --- a/netutils/ping/icmpv6_ping.c +++ b/netutils/ping/icmpv6_ping.c @@ -42,6 +42,7 @@ #endif #include +#include #include #include @@ -169,6 +170,7 @@ void icmp6_ping(FAR const struct ping6_info_s *info) struct ping6_result_s result; struct sockaddr_in6 destaddr; struct sockaddr_in6 fromaddr; + struct icmp6_filter filter; struct icmpv6_echo_request_s outhdr; FAR struct icmpv6_echo_reply_s *inhdr; struct pollfd recvfd; @@ -210,7 +212,7 @@ void icmp6_ping(FAR const struct ping6_info_s *info) return; } - sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMP6); + sockfd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); if (sockfd < 0) { icmp6_callback(&result, ICMPv6_E_SOCKET, errno); @@ -232,6 +234,20 @@ void icmp6_ping(FAR const struct ping6_info_s *info) } #endif + memset(&filter, 0xff, sizeof(filter)); + + /* ICMPv6_ECHO_REPLY >> 5 = 4 */ + + filter.icmp6_filt[4] &= ~(1 << (ICMPv6_ECHO_REPLY & 31)); + if (setsockopt(sockfd, SOL_ICMPV6, ICMP6_FILTER, &filter, + sizeof(filter)) < 0) + { + icmp6_callback(&result, ICMPv6_E_SOCKET, errno); + close(sockfd); + free(iobuffer); + return; + } + kickoff = clock(); memset(&destaddr, 0, sizeof(struct sockaddr_in6)); From d9afe2db8ce7f2bb1cef7c65fed56af307bb722f Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Fri, 16 Jan 2026 22:47:13 +0800 Subject: [PATCH 134/568] signals: fix build and runtime issues when signals all isabled Fix build and runtime issues when signals all disabled. Signed-off-by: Chengdong Wang --- canutils/candump/Kconfig | 2 +- examples/chrono/Kconfig | 2 +- examples/djoystick/Kconfig | 2 +- examples/i2sloop/Kconfig | 2 +- examples/ipforward/ipforward.c | 13 ++++ examples/oneshot/Kconfig | 2 +- examples/shv-nxboot-updater/Kconfig | 2 +- .../usrsocktest_wake_with_signal.c | 77 ++++++++++++++++++- examples/xedge_demo/Kconfig | 4 +- examples/zerocross/Kconfig | 2 +- nshlib/nsh.h | 2 + nshlib/nsh_command.c | 26 ++++--- nshlib/nsh_proccmds.c | 13 ++-- system/sensortest/Kconfig | 2 +- testing/drivers/nand_sim/Kconfig | 2 +- testing/ostest/CMakeLists.txt | 22 +++--- testing/ostest/Makefile | 15 +++- testing/ostest/ostest_main.c | 16 ++-- wireless/ieee802154/i8sak/i8sak_events.c | 14 ++++ 19 files changed, 172 insertions(+), 48 deletions(-) diff --git a/canutils/candump/Kconfig b/canutils/candump/Kconfig index 4359ec287..45a46118b 100644 --- a/canutils/candump/Kconfig +++ b/canutils/candump/Kconfig @@ -6,7 +6,7 @@ config CANUTILS_CANDUMP tristate "SocketCAN candump tool" default n - depends on NET_CAN && CANUTILS_LIBCANUTILS + depends on NET_CAN && CANUTILS_LIBCANUTILS && ENABLE_ALL_SIGNALS ---help--- Enable the SocketCAN candump tool ported from https://github.com/linux-can/can-utils diff --git a/examples/chrono/Kconfig b/examples/chrono/Kconfig index 866bc660a..324f0c452 100644 --- a/examples/chrono/Kconfig +++ b/examples/chrono/Kconfig @@ -6,7 +6,7 @@ config EXAMPLES_CHRONO tristate "Chronometer example to use with STM32LDiscover" default n - depends on SLCD + depends on SLCD && ENABLE_ALL_SIGNALS ---help--- Enable the Chronometer example diff --git a/examples/djoystick/Kconfig b/examples/djoystick/Kconfig index 7bfad3a2e..68e38ab6e 100644 --- a/examples/djoystick/Kconfig +++ b/examples/djoystick/Kconfig @@ -6,7 +6,7 @@ config EXAMPLES_DJOYSTICK tristate "Discrete joystick example" default n - depends on INPUT_DJOYSTICK + depends on INPUT_DJOYSTICK && ENABLE_ALL_SIGNALS ---help--- Enable the discrete joystick example diff --git a/examples/i2sloop/Kconfig b/examples/i2sloop/Kconfig index cea8333cd..982c0b020 100644 --- a/examples/i2sloop/Kconfig +++ b/examples/i2sloop/Kconfig @@ -6,6 +6,6 @@ config EXAMPLES_I2SLOOP tristate "I2S loopback test" default n - depends on I2S && AUDIO && DRIVERS_AUDIO && AUDIO_I2SCHAR + depends on I2S && AUDIO && DRIVERS_AUDIO && AUDIO_I2SCHAR && ENABLE_ALL_SIGNALS ---help--- Enable the I2S loopback test diff --git a/examples/ipforward/ipforward.c b/examples/ipforward/ipforward.c index 57b146e7e..ae9ee5831 100644 --- a/examples/ipforward/ipforward.c +++ b/examples/ipforward/ipforward.c @@ -542,8 +542,16 @@ static FAR void *ipfwd_receiver(FAR void *arg) int errcode; int i; +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + for (i = 0; i < IPFWD_NPACKETS; i++) { +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif nread = read(fwd->ia_fd, fwd->ia_buffer, IPFWD_BUFSIZE); if (nread < 0) { @@ -840,7 +848,12 @@ errout_with_receiver: /* Wait for receiver thread to terminate */ +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_cancel(fwd.if_receiver); +#else pthread_kill(fwd.if_receiver, 9); +#endif + ret = pthread_join(fwd.if_receiver, &value); if (ret != OK) { diff --git a/examples/oneshot/Kconfig b/examples/oneshot/Kconfig index 43cc117e1..3b9505985 100644 --- a/examples/oneshot/Kconfig +++ b/examples/oneshot/Kconfig @@ -6,7 +6,7 @@ config EXAMPLES_ONESHOT tristate "Oneshot timer example" default n - depends on ONESHOT + depends on ONESHOT && ENABLE_ALL_SIGNALS ---help--- Enable the oneshot timer driver example diff --git a/examples/shv-nxboot-updater/Kconfig b/examples/shv-nxboot-updater/Kconfig index d25da7cd0..80ace34ba 100644 --- a/examples/shv-nxboot-updater/Kconfig +++ b/examples/shv-nxboot-updater/Kconfig @@ -5,7 +5,7 @@ menuconfig EXAMPLES_SHV_NXBOOT_UPDATER bool "Silicon Heaven Firmware updates for NXBoot" - depends on NETUTILS_LIBSHVC + depends on NETUTILS_LIBSHVC && ENABLE_ALL_SIGNALS default n ---help--- Enable the shv-nxboot-updater application. diff --git a/examples/usrsocktest/usrsocktest_wake_with_signal.c b/examples/usrsocktest/usrsocktest_wake_with_signal.c index 800eb571d..da460ab15 100644 --- a/examples/usrsocktest/usrsocktest_wake_with_signal.c +++ b/examples/usrsocktest/usrsocktest_wake_with_signal.c @@ -146,11 +146,20 @@ static void do_usrsock_blocking_socket_thread(FAR void *param) TEST_ASSERT_TRUE(test_hang); TEST_ASSERT_TRUE(test_abort); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + /* Allow main thread to hang usrsock daemon at this point. */ sem_post(&tid_startsem); sem_wait(&tid_releasesem); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif + /* Attempt hanging open socket. */ sem_post(&tid_startsem); @@ -176,6 +185,11 @@ static void do_usrsock_blocking_close_thread(FAR void *param) TEST_ASSERT_TRUE(test_hang); TEST_ASSERT_TRUE(test_abort); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + /* Open socket. */ test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); @@ -190,6 +204,10 @@ static void do_usrsock_blocking_close_thread(FAR void *param) sem_post(&tid_startsem); sem_wait(&tid_releasesem); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif + /* Attempt hanging close socket. */ sem_post(&tid_startsem); @@ -214,6 +232,11 @@ static void do_usrsock_blocking_connect_thread(FAR void *param) TEST_ASSERT_TRUE(test_hang || !test_hang); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + /* Open socket. */ test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); @@ -228,6 +251,10 @@ static void do_usrsock_blocking_connect_thread(FAR void *param) sem_post(&tid_startsem); sem_wait(&tid_releasesem); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif + /* Attempt blocking connect. */ sem_post(&tid_startsem); @@ -257,6 +284,11 @@ static void do_usrsock_blocking_setsockopt_thread(FAR void *param) bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + /* Open socket. */ test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); @@ -274,6 +306,10 @@ static void do_usrsock_blocking_setsockopt_thread(FAR void *param) sem_post(&tid_startsem); sem_wait(&tid_releasesem); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif + /* Attempt hanging setsockopt. */ sem_post(&tid_startsem); @@ -304,6 +340,11 @@ static void do_usrsock_blocking_getsockopt_thread(FAR void *param) bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + /* Open socket. */ test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); @@ -321,6 +362,10 @@ static void do_usrsock_blocking_getsockopt_thread(FAR void *param) sem_post(&tid_startsem); sem_wait(&tid_releasesem); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif + /* Attempt hanging getsockopt. */ sem_post(&tid_startsem); @@ -352,6 +397,11 @@ static void do_usrsock_blocking_send_thread(FAR void *param) TEST_ASSERT_TRUE(test_hang || !test_hang); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + /* Open socket. */ test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); @@ -372,6 +422,10 @@ static void do_usrsock_blocking_send_thread(FAR void *param) sem_post(&tid_startsem); sem_wait(&tid_releasesem); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif + /* Attempt blocking send. */ sem_post(&tid_startsem); @@ -401,6 +455,11 @@ static void do_usrsock_blocking_recv_thread(FAR void *param) TEST_ASSERT_TRUE(test_hang || !test_hang); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + /* Open socket. */ test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); @@ -421,6 +480,10 @@ static void do_usrsock_blocking_recv_thread(FAR void *param) sem_post(&tid_startsem); sem_wait(&tid_releasesem); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif + /* Attempt blocking recv. */ sem_post(&tid_startsem); @@ -454,6 +517,11 @@ static void do_usrsock_blocking_poll_thread(FAR void *param) TEST_ASSERT_TRUE(test_abort); TEST_ASSERT_TRUE(test_hang || !test_hang); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + /* Open socket. */ test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); @@ -474,6 +542,10 @@ static void do_usrsock_blocking_poll_thread(FAR void *param) sem_post(&tid_startsem); sem_wait(&tid_releasesem); +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif + /* Attempt poll. */ pfd.fd = test_sd[tidx]; @@ -560,8 +632,11 @@ static void do_wake_test(enum e_test_type type, int flags) for (tidx = 0; tidx < nthreads; tidx++) { +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_cancel(tid[tidx]); +#else pthread_kill(tid[tidx], SIGUSR1); - +#endif /* Wait threads to complete work. */ ret = pthread_join(tid[tidx], NULL); diff --git a/examples/xedge_demo/Kconfig b/examples/xedge_demo/Kconfig index 9bc02d0fa..183f18b28 100644 --- a/examples/xedge_demo/Kconfig +++ b/examples/xedge_demo/Kconfig @@ -5,11 +5,11 @@ config EXAMPLES_XEDGE_DEMO tristate "Xedge IoT Toolkit Demo" - depends on NETUTILS_XEDGE && ALLOW_GPL_COMPONENTS + depends on NETUTILS_XEDGE && ALLOW_GPL_COMPONENTS && ENABLE_ALL_SIGNALS default n ---help--- Simple demonstration of the Xedge IoT Toolkit library. - + This example shows how to integrate and use the Xedge library in your NuttX application. Xedge provides a high-level development environment for creating IoT and industrial device applications diff --git a/examples/zerocross/Kconfig b/examples/zerocross/Kconfig index b49614731..758c4781a 100644 --- a/examples/zerocross/Kconfig +++ b/examples/zerocross/Kconfig @@ -6,7 +6,7 @@ config EXAMPLES_ZEROCROSS tristate "Zero Cross Detection example" default n - depends on SENSORS_ZEROCROSS + depends on SENSORS_ZEROCROSS && ENABLE_ALL_SIGNALS ---help--- Enable the zero cross detection example diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 9c2c1d5ed..74f4032cc 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -1179,6 +1179,7 @@ int cmd_switchboot(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); int cmd_unset(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #endif +#ifndef CONFIG_DISABLE_ALL_SIGNALS #ifndef CONFIG_NSH_DISABLE_KILL int cmd_kill(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #endif @@ -1191,6 +1192,7 @@ int cmd_switchboot(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #ifndef CONFIG_NSH_DISABLE_USLEEP int cmd_usleep(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #endif +#endif /* !CONFIG_DISABLE_ALL_SIGNALS */ #ifndef CONFIG_NSH_DISABLE_UPTIME int cmd_uptime(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 03a14ace9..af0084218 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -304,14 +304,6 @@ static const struct cmdmap_s g_cmdmap[] = CMD_MAP("irqinfo", cmd_irqinfo, 1, 1, NULL), #endif -#ifndef CONFIG_NSH_DISABLE_KILL - CMD_MAP("kill", cmd_kill, 2, 3, "[-] "), -#endif - -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_NSH_DISABLE_PKILL) - CMD_MAP("pkill", cmd_pkill, 2, 3, "[-] "), -#endif - #ifndef CONFIG_DISABLE_MOUNTPOINT # if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP) CMD_MAP("losetup", cmd_losetup, 3, 6, @@ -575,10 +567,24 @@ static const struct cmdmap_s g_cmdmap[] = #endif #endif +#ifndef CONFIG_DISABLE_ALL_SIGNALS +#ifndef CONFIG_NSH_DISABLE_KILL + CMD_MAP("kill", cmd_kill, 2, 3, "[-] "), +#endif + +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_NSH_DISABLE_PKILL) + CMD_MAP("pkill", cmd_pkill, 2, 3, "[-] "), +#endif + #ifndef CONFIG_NSH_DISABLE_SLEEP CMD_MAP("sleep", cmd_sleep, 2, 2, ""), #endif +#ifndef CONFIG_NSH_DISABLE_USLEEP + CMD_MAP("usleep", cmd_usleep, 2, 2, ""), +#endif +#endif + #if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_SOURCE) CMD_MAP("source", cmd_source, 2, 2, ""), #endif @@ -657,10 +663,6 @@ static const struct cmdmap_s g_cmdmap[] = # endif #endif -#ifndef CONFIG_NSH_DISABLE_USLEEP - CMD_MAP("usleep", cmd_usleep, 2, 2, ""), -#endif - #ifndef CONFIG_NSH_DISABLE_WATCH CMD_MAP("watch", cmd_watch, 2, 6, "[-n] interval [-c] count "), diff --git a/nshlib/nsh_proccmds.c b/nshlib/nsh_proccmds.c index c7eff26eb..02a9869aa 100644 --- a/nshlib/nsh_proccmds.c +++ b/nshlib/nsh_proccmds.c @@ -995,7 +995,8 @@ int cmd_pidof(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) * Name: cmd_kill ****************************************************************************/ -#ifndef CONFIG_NSH_DISABLE_KILL +#if !defined(CONFIG_NSH_DISABLE_KILL) && \ + !defined(CONFIG_DISABLE_ALL_SIGNALS) int cmd_kill(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { FAR char *ptr; @@ -1098,7 +1099,8 @@ invalid_arg: * Name: cmd_pkill ****************************************************************************/ -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_NSH_DISABLE_PKILL) +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_NSH_DISABLE_PKILL) && \ + !defined(CONFIG_DISABLE_ALL_SIGNALS) int cmd_pkill(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { FAR const char *name; @@ -1199,7 +1201,8 @@ invalid_arg: * Name: cmd_sleep ****************************************************************************/ -#ifndef CONFIG_NSH_DISABLE_SLEEP +#if !defined(CONFIG_NSH_DISABLE_SLEEP) && \ + !defined(CONFIG_DISABLE_ALL_SIGNALS) int cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { UNUSED(argc); @@ -1222,8 +1225,8 @@ int cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) /**************************************************************************** * Name: cmd_usleep ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLE_USLEEP +#if !defined(CONFIG_NSH_DISABLE_USLEEP) && \ + !defined(CONFIG_DISABLE_ALL_SIGNALS) int cmd_usleep(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { UNUSED(argc); diff --git a/system/sensortest/Kconfig b/system/sensortest/Kconfig index 8f54695ed..68f1f951d 100644 --- a/system/sensortest/Kconfig +++ b/system/sensortest/Kconfig @@ -6,7 +6,7 @@ config SYSTEM_SENSORTEST tristate "Sensor driver test" default n - depends on SENSORS + depends on SENSORS && ENABLE_ALL_SIGNALS ---help--- Enable the Sensor driver test diff --git a/testing/drivers/nand_sim/Kconfig b/testing/drivers/nand_sim/Kconfig index ccf2c657b..e76cdc3f5 100644 --- a/testing/drivers/nand_sim/Kconfig +++ b/testing/drivers/nand_sim/Kconfig @@ -5,7 +5,7 @@ config TESTING_NAND_SIM boolean "NAND Flash Simulator" - depends on MTD_NAND_RAM + depends on MTD_NAND_RAM && ENABLE_ALL_SIGNALS default n ---help--- Enable the NAND Flash Simulator device. diff --git a/testing/ostest/CMakeLists.txt b/testing/ostest/CMakeLists.txt index 6e971373d..777c68744 100644 --- a/testing/ostest/CMakeLists.txt +++ b/testing/ostest/CMakeLists.txt @@ -22,14 +22,15 @@ if(CONFIG_TESTING_OSTEST) - set(SRCS - getopt.c - libc_memmem.c - restart.c - sigprocmask.c - sighand.c - signest.c - sighelper.c) + set(SRCS getopt.c libc_memmem.c restart.c sighelper.c) + + if(CONFIG_ENABLE_ALL_SIGNALS) + list(APPEND SRCS sighand.c signest.c) + endif() + + if(NOT CONFIG_DISABLE_ALL_SIGNALS) + list(APPEND SRCS sigprocmask.c) + endif() if(CONFIG_DEV_NULL) list(APPEND SRCS dev_null.c) @@ -124,7 +125,10 @@ if(CONFIG_TESTING_OSTEST) if(NOT CONFIG_DISABLE_MQUEUE) if(NOT CONFIG_DISABLE_PTHREAD) - list(APPEND SRCS mqueue.c timedmqueue.c) + list(APPEND SRCS timedmqueue.c) + if(NOT CONFIG_DISABLE_ALL_SIGNALS) + list(APPEND SRCS mqueue.c) + endif() endif() # CONFIG_DISABLE_PTHREAD endif() # CONFIG_DISABLE_MQUEUE diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile index 5f7d5d4f8..128a31798 100644 --- a/testing/ostest/Makefile +++ b/testing/ostest/Makefile @@ -31,9 +31,17 @@ MODULE = $(CONFIG_TESTING_OSTEST) # NuttX OS Test -CSRCS = getopt.c libc_memmem.c restart.c sigprocmask.c sighand.c \ +CSRCS = getopt.c libc_memmem.c restart.c \ signest.c sighelper.c +ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) +CSRCS += sighand.c signest.c +endif + +ifneq ($(CONFIG_DISABLE_ALL_SIGNALS),y) +CSRCS += sigprocmask.c +endif + MAINSRC = ostest_main.c ifeq ($(CONFIG_DEV_NULL),y) @@ -119,7 +127,10 @@ endif # CONFIG_DISABLE_PTHREAD ifneq ($(CONFIG_DISABLE_MQUEUE),y) ifneq ($(CONFIG_DISABLE_PTHREAD),y) -CSRCS += mqueue.c timedmqueue.c +CSRCS += timedmqueue.c +ifneq ($(CONFIG_DISABLE_ALL_SIGNALS),y) +CSRCS += mqueue.c +endif endif # CONFIG_DISABLE_PTHREAD endif # CONFIG_DISABLE_MQUEUE diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 975a10410..6bf75d86f 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -496,14 +496,6 @@ static int user_main(int argc, char *argv[]) check_test_memory_usage(); #endif /* !CONFIG_DISABLE_PTHREAD */ -#if !defined(CONFIG_DISABLE_MQUEUE) && !defined(CONFIG_DISABLE_PTHREAD) - /* Verify pthreads and message queues */ - - printf("\nuser_main: message queue test\n"); - mqueue_test(); - check_test_memory_usage(); -#endif - #if !defined(CONFIG_DISABLE_MQUEUE) && !defined(CONFIG_DISABLE_PTHREAD) /* Verify pthreads and message queues */ @@ -519,6 +511,14 @@ static int user_main(int argc, char *argv[]) sigprocmask_test(); check_test_memory_usage(); +#if !defined(CONFIG_DISABLE_MQUEUE) && !defined(CONFIG_DISABLE_PTHREAD) + /* Verify pthreads and message queues */ + + printf("\nuser_main: message queue test\n"); + mqueue_test(); + check_test_memory_usage(); +#endif + #if defined(CONFIG_SIG_SIGSTOP_ACTION) && defined(CONFIG_SIG_SIGKILL_ACTION) && \ !defined(CONFIG_BUILD_KERNEL) printf("\nuser_main: signal action test\n"); diff --git a/wireless/ieee802154/i8sak/i8sak_events.c b/wireless/ieee802154/i8sak/i8sak_events.c index 12e4758b9..143e7ae3e 100644 --- a/wireless/ieee802154/i8sak/i8sak_events.c +++ b/wireless/ieee802154/i8sak/i8sak_events.c @@ -68,6 +68,11 @@ static pthread_addr_t i8sak_eventthread(pthread_addr_t arg) FAR struct ieee802154_primitive_s *primitive = NULL; int ret = OK; +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + if (i8sak->mode == I8SAK_MODE_CHAR) { macarg.enable = true; @@ -86,6 +91,9 @@ static pthread_addr_t i8sak_eventthread(pthread_addr_t arg) while (i8sak->eventlistener_run) { +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_testcancel(); +#endif if (i8sak->mode == I8SAK_MODE_CHAR) { ret = ioctl(i8sak->fd, MAC802154IOC_GET_EVENT, @@ -256,7 +264,13 @@ int i8sak_eventlistener_stop(FAR struct i8sak_s *i8sak) FAR void *value; i8sak->eventlistener_run = false; + +#ifdef CONFIG_DISABLE_ALL_SIGNALS + pthread_cancel(i8sak->eventlistener_threadid); +#else pthread_kill(i8sak->eventlistener_threadid, 2); +#endif + ret = pthread_join(i8sak->eventlistener_threadid, &value); if (ret != OK) { From ddc699a4f3f5870d837f1b15589b6c872c6bd156 Mon Sep 17 00:00:00 2001 From: makejian Date: Tue, 20 Jan 2026 13:52:59 +0800 Subject: [PATCH 135/568] system/cu: fix signal handler to use sa_sigaction The sigint() function uses siginfo->si_user but was declared with only one parameter (int sig). This causes compilation error because siginfo is undeclared. Fix by: 1. Rename sigint to cu_exit with proper sigaction signature 2. Use sa_sigaction instead of sa_handler to receive siginfo_t 3. Pass cu pointer via sa.sa_user for signal handler access Signed-off-by: makejian --- system/cu/cu_main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/system/cu/cu_main.c b/system/cu/cu_main.c index 6e25acfc9..fbb3350aa 100644 --- a/system/cu/cu_main.c +++ b/system/cu/cu_main.c @@ -123,7 +123,7 @@ static FAR void *cu_listener(FAR void *parameter) } #ifdef CONFIG_ENABLE_ALL_SIGNALS -static void sigint(int sig) +static void cu_exit(int signo, FAR siginfo_t *siginfo, FAR void *context) { FAR struct cu_globals_s *cu = siginfo->si_user; cu->force_exit = true; @@ -302,8 +302,15 @@ int main(int argc, FAR char *argv[]) /* Install signal handlers */ memset(&sa, 0, sizeof(sa)); - sa.sa_handler = sigint; - sigaction(SIGINT, &sa, NULL); + sa.sa_user = &cu; + sa.sa_sigaction = cu_exit; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGINT, &sa, NULL) < 0) + { + cu_error("cu_main: ERROR during setup cu_exit sigaction(): %d\n", + errno); + return EXIT_FAILURE; + } #endif optind = 0; /* Global that needs to be reset in FLAT mode */ while ((option = getopt(argc, argv, "l:s:ceE:fho?")) != ERROR) From 755fae7ac1b365a0abcb4bd9fe4fd2b4a7cce797 Mon Sep 17 00:00:00 2001 From: guoshichao Date: Thu, 25 Sep 2025 15:29:25 +0800 Subject: [PATCH 136/568] system/cu: merge the cu.h to cu_main.c Merge the cu.h header file contents into cu_main.c to simplify the code structure. The cu_globals_s structure and related definitions are now directly in cu_main.c. Signed-off-by: guoshichao --- system/cu/cu.h | 92 --------------------------------------------- system/cu/cu_main.c | 34 ++++++++++++++++- 2 files changed, 33 insertions(+), 93 deletions(-) delete mode 100644 system/cu/cu.h diff --git a/system/cu/cu.h b/system/cu/cu.h deleted file mode 100644 index be9b31fb3..000000000 --- a/system/cu/cu.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** - * apps/system/cu/cu.h - * - * SPDX-License-Identifier: BSD-3-Clause - * SPDX-FileCopyrightText: 2014 sysmocom - s.f.m.c. GmbH. All rights reserved. - * SPDX-FileContributor: Harald Welte - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#ifndef __APPS_SYSTEM_CU_CU_H -#define __APPS_SYSTEM_CU_CU_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Configuration ************************************************************/ - -#ifndef CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE -# define CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE "/dev/ttyS0" -#endif - -#ifndef CONFIG_SYSTEM_CUTERM_DEFAULT_BAUD -# define CONFIG_SYSTEM_CUTERM_DEFAULT_BAUD 115200 -#endif - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/* All terminal state data is packaged in a single structure to minimize - * name conflicts with other global symbols -- a poor man's name space. - */ - -struct cu_globals_s -{ - int devfd; /* I/O data to serial port */ - int stdfd; /* I/O data to standard console */ - int escape; /* Escape char */ - struct termios devtio; /* Original serial port setting */ - struct termios stdtio; /* Original standard console setting */ - pthread_t listener; /* Terminal listener thread */ - bool force_exit; /* Force exit */ -}; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#endif /* __APPS_SYSTEM_CU_CU_H */ diff --git a/system/cu/cu_main.c b/system/cu/cu_main.c index fbb3350aa..fa5b31900 100644 --- a/system/cu/cu_main.c +++ b/system/cu/cu_main.c @@ -53,10 +53,26 @@ #include #include #include +#include +#include +#include +#include #include "system/readline.h" -#include "cu.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE +# define CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE "/dev/ttyS0" +#endif + +#ifndef CONFIG_SYSTEM_CUTERM_DEFAULT_BAUD +# define CONFIG_SYSTEM_CUTERM_DEFAULT_BAUD 115200 +#endif #ifdef CONFIG_SYSTEM_CUTERM_DISABLE_ERROR_PRINT # define cu_error(...) @@ -75,6 +91,21 @@ enum parity_mode PARITY_ODD, }; +/* All terminal state data is packaged in a single structure to minimize + * name conflicts with other global symbols -- a poor man's name space. + */ + +struct cu_globals_s +{ + int devfd; /* I/O data to serial port */ + int stdfd; /* I/O data to standard console */ + int escape; /* Escape char */ + struct termios devtio; /* Original serial port setting */ + struct termios stdtio; /* Original standard console setting */ + pthread_t listener; /* Terminal listener thread */ + bool force_exit; /* Force exit */ +}; + /**************************************************************************** * Private Data ****************************************************************************/ @@ -311,6 +342,7 @@ int main(int argc, FAR char *argv[]) errno); return EXIT_FAILURE; } + #endif optind = 0; /* Global that needs to be reset in FLAT mode */ while ((option = getopt(argc, argv, "l:s:ceE:fho?")) != ERROR) From 19dd2531fbc315f97a9d2c2825c0bae88bcddf00 Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Tue, 20 Jan 2026 20:02:01 +0800 Subject: [PATCH 137/568] testing/ostest: fix build issue fix: Building NuttX... /d/a/nuttx-apps/nuttx-apps/sources/apps/Application.mk:238: target 'signest.c.d.a.nuttx-apps.nuttx- apps.sources.apps.testing.ostest.o' given more than once in the same rule Signed-off-by: Chengdong Wang --- testing/ostest/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile index 128a31798..1fedfcf54 100644 --- a/testing/ostest/Makefile +++ b/testing/ostest/Makefile @@ -31,8 +31,7 @@ MODULE = $(CONFIG_TESTING_OSTEST) # NuttX OS Test -CSRCS = getopt.c libc_memmem.c restart.c \ - signest.c sighelper.c +CSRCS = getopt.c libc_memmem.c restart.c sighelper.c ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) CSRCS += sighand.c signest.c From 840c4fceefb459191bf26a356fa3ff8d6c5aeda8 Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Tue, 20 Jan 2026 10:48:28 +0800 Subject: [PATCH 138/568] ostest/hrtimer: align hrtimer callback declaration align hrtimer callback declaration with latest update of hrtimer Signed-off-by: Chengdong Wang --- testing/ostest/hrtimer.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index 3943140e6..1094167ac 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -128,7 +128,7 @@ static void hrtimer_test_init(FAR struct hrtimer_test_s *hrtimer_test, ****************************************************************************/ static uint64_t -test_hrtimer_callback(FAR hrtimer_t *hrtimer, uint64_t expired) +test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) { struct timespec ts; uint32_t diff; @@ -167,15 +167,15 @@ test_hrtimer_callback(FAR hrtimer_t *hrtimer, uint64_t expired) /* Stop the test after 15 expirations */ - if (test->count >= 15) + if (test->count < 15) { - ret = hrtimer_cancel(hrtimer); - HRTIMER_TEST(ret, 0); - - test->active = false; + return test->period; + } + else + { + test->active = false; + return 0; } - - return test->period; } /**************************************************************************** From 545684944621fbc152e2251fadb7554fe9f11656 Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Tue, 20 Jan 2026 11:40:57 +0800 Subject: [PATCH 139/568] ostest/hrtimer: Add threaded hrtimer tests Add threaded hrtimer tests Signed-off-by: Chengdong Wang --- testing/ostest/hrtimer.c | 100 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 4 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index 1094167ac..d503f878f 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -29,6 +29,8 @@ #include #include +#include +#include #include "ostest.h" @@ -36,7 +38,12 @@ * Pre-processor Definitions ****************************************************************************/ -#define NSEC_PER_50MS (50 * NSEC_PER_MSEC) +/* Timer constants */ + +#define NSEC_PER_50MS (50 * NSEC_PER_MSEC) +#define PERIOD_TEST_COUNT 15 +#define THREAD_LOOP_COUNT 50 +#define HRTIMER_TEST_THREAD_NR (CONFIG_SMP_NCPUS * 5) /* Set a 1ms margin to allow hrtimertest to pass in QEMU. * @@ -165,9 +172,9 @@ test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) test->previous = now; - /* Stop the test after 15 expirations */ + /* Stop the test after PERIOD_TEST_COUNT expirations */ - if (test->count < 15) + if (test->count < PERIOD_TEST_COUNT) { return test->period; } @@ -178,6 +185,67 @@ test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) } } +/**************************************************************************** + * Name: hrtimer_test_callback + * + * Description: + * Simple HRTimer callback for threaded tests. + * + ****************************************************************************/ + +static uint64_t +hrtimer_test_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) +{ + return 0; +} + +/**************************************************************************** + * Name: hrtimer_test_thread + * + * Description: + * Thread function to repeatedly test HRTimer start/cancel behavior. + * + ****************************************************************************/ + +static void * hrtimer_test_thread(void *arg) +{ + hrtimer_t timer; + int ret; + int i = 0; + + hrtimer_init(&timer); + + while (i < THREAD_LOOP_COUNT) + { + i++; + uint64_t delay = rand() % NSEC_PER_MSEC; + + /* Cancel timer */ + + ret = hrtimer_cancel(&timer); + HRTIMER_TEST(ret, OK); + + /* Start timer with fixed period */ + + ret = hrtimer_start(&timer, hrtimer_test_callback, + 10 * NSEC_PER_USEC, HRTIMER_MODE_REL); + HRTIMER_TEST(ret, OK); + + /* Start timer with random delay */ + + ret = hrtimer_start(&timer, hrtimer_test_callback, + delay, HRTIMER_MODE_REL); + HRTIMER_TEST(ret, OK); + } + + /* Cancel the timer synchronously */ + + ret = hrtimer_cancel_sync(&timer); + HRTIMER_TEST(ret, OK); + + return NULL; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -202,8 +270,12 @@ test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) void hrtimer_test(void) { - int ret; + struct sched_param sparam; + unsigned int thread_id; + pthread_attr_t attr; + pthread_t pthreads[HRTIMER_TEST_THREAD_NR]; struct hrtimer_test_s hrtimer_test; + int ret; /* Initialize test structure */ @@ -228,4 +300,24 @@ void hrtimer_test(void) { usleep(USEC_PER_MSEC); } + + pthread_attr_init(&attr); + + sparam.sched_priority = PTHREAD_DEFAULT_PRIORITY; + pthread_attr_setschedparam(&attr, &sparam); + + for (thread_id = 0; thread_id < HRTIMER_TEST_THREAD_NR; thread_id++) + { + HRTIMER_TEST(pthread_create(&pthreads[thread_id], &attr, + hrtimer_test_thread, NULL), 0); + } + + /* Wait for all threads to complete */ + + for (thread_id = 0; thread_id < HRTIMER_TEST_THREAD_NR; thread_id++) + { + pthread_join(pthreads[thread_id], NULL); + } + + HRTIMER_TEST(pthread_attr_destroy(&attr), 0); } From 37403210f9b4a96782e281885a241d9209f5f22c Mon Sep 17 00:00:00 2001 From: Jiri Vlasak Date: Tue, 20 Jan 2026 13:59:01 +0100 Subject: [PATCH 140/568] netutils/nng: Update help for NETUTILS_NNG NNG depends on options that, if not enabled, makes compilation or runtime crashes. Noting these options in help helps to find out which are such options. Signed-off-by: Jiri Vlasak --- netutils/nng/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/netutils/nng/Kconfig b/netutils/nng/Kconfig index 525cf2f45..8d4dfb7c1 100644 --- a/netutils/nng/Kconfig +++ b/netutils/nng/Kconfig @@ -11,6 +11,12 @@ config NETUTILS_NNG offering a simple API to solve common recurring messaging problems, such as publish/subscribe, RPC-style request/reply, or service discovery. + Consider the following configuration when enabling NNG: + - CONFIG_LIBC_NETDB=y + - CONFIG_DEV_URANDOM=y + - CONFIG_NET_LOCAL=y + - CONFIG_NET_LOCAL_STREAM=y + if NETUTILS_NNG config NETUTILS_NNG_VERSION From 9148fb97186196778ea0efa5f083ecb630e4287d Mon Sep 17 00:00:00 2001 From: makejian Date: Tue, 20 Jan 2026 10:29:56 +0800 Subject: [PATCH 141/568] benchmarks: Add Whetstone FPU benchmark Add the Whetstone floating-point benchmark to NuttX applications. The Whetstone benchmark is a widely-used tool for evaluating FPU (floating-point unit) performance. This benchmark is ported from netlib.org whetstone.c which has a custom permissive license requiring attribution. Therefore it depends on ALLOW_CUSTOM_PERMISSIVE_COMPONENTS. Usage: whetstone [loops] Signed-off-by: makejian --- benchmarks/whetstone/CMakeLists.txt | 31 ++ benchmarks/whetstone/Kconfig | 34 ++ benchmarks/whetstone/Make.defs | 23 ++ benchmarks/whetstone/Makefile | 32 ++ benchmarks/whetstone/whetstone.c | 517 ++++++++++++++++++++++++++++ 5 files changed, 637 insertions(+) create mode 100644 benchmarks/whetstone/CMakeLists.txt create mode 100644 benchmarks/whetstone/Kconfig create mode 100644 benchmarks/whetstone/Make.defs create mode 100644 benchmarks/whetstone/Makefile create mode 100644 benchmarks/whetstone/whetstone.c diff --git a/benchmarks/whetstone/CMakeLists.txt b/benchmarks/whetstone/CMakeLists.txt new file mode 100644 index 000000000..1bcc0f256 --- /dev/null +++ b/benchmarks/whetstone/CMakeLists.txt @@ -0,0 +1,31 @@ +# ############################################################################## +# apps/benchmarks/whetstone/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_BENCHMARK_WHETSTONE) + nuttx_add_application( + NAME + ${CONFIG_BENCHMARK_WHETSTONE_PROGNAME} + SRCS + whetstone.c + STACKSIZE + ${CONFIG_BENCHMARK_WHETSTONE_STACKSIZE} + PRIORITY + ${CONFIG_BENCHMARK_WHETSTONE_PRIORITY}) +endif() diff --git a/benchmarks/whetstone/Kconfig b/benchmarks/whetstone/Kconfig new file mode 100644 index 000000000..10df1429e --- /dev/null +++ b/benchmarks/whetstone/Kconfig @@ -0,0 +1,34 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config BENCHMARK_WHETSTONE + tristate "Double Precision Benchmark" + default n + depends on ALLOW_CUSTOM_PERMISSIVE_COMPONENTS + ---help--- + Enable a Whetstone test. + + This benchmark is based on the C converted version from + https://www.netlib.org/benchmark/whetstone.c which has a + custom permissive license requiring attribution. + +if BENCHMARK_WHETSTONE + +config BENCHMARK_WHETSTONE_PROGNAME + string "Program name" + default "whetstone" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config BENCHMARK_WHETSTONE_PRIORITY + int "Whetstone test task priority" + default 100 + +config BENCHMARK_WHETSTONE_STACKSIZE + int "Whetstone test stack size" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/benchmarks/whetstone/Make.defs b/benchmarks/whetstone/Make.defs new file mode 100644 index 000000000..d9fa9f1af --- /dev/null +++ b/benchmarks/whetstone/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/benchmarks/whetstone/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_BENCHMARK_WHETSTONE),) +CONFIGURED_APPS += $(APPDIR)/benchmarks/whetstone +endif diff --git a/benchmarks/whetstone/Makefile b/benchmarks/whetstone/Makefile new file mode 100644 index 000000000..1bdf6dfd6 --- /dev/null +++ b/benchmarks/whetstone/Makefile @@ -0,0 +1,32 @@ +############################################################################ +# apps/benchmarks/whetstone/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# WHETSTONE speed test + +PROGNAME = $(CONFIG_BENCHMARK_WHETSTONE_PROGNAME) +PRIORITY = $(CONFIG_BENCHMARK_WHETSTONE_PRIORITY) +STACKSIZE = $(CONFIG_BENCHMARK_WHETSTONE_STACKSIZE) +MODULE = $(CONFIG_BENCHMARK_WHETSTONE) + +MAINSRC = whetstone.c + +include $(APPDIR)/Application.mk diff --git a/benchmarks/whetstone/whetstone.c b/benchmarks/whetstone/whetstone.c new file mode 100644 index 000000000..4363baaf7 --- /dev/null +++ b/benchmarks/whetstone/whetstone.c @@ -0,0 +1,517 @@ +/**************************************************************************** + * apps/benchmarks/whetstone/whetstone.c + * + * SPDX-License-Identifier: LicenseRef-Painter-Engineering-Whetstone + * + * Converted Whetstone Double Precision Benchmark + * Version 1.2 22 March 1998 + * + * (c) Copyright 1998 Painter Engineering, Inc. + * All Rights Reserved. + * + * Permission is granted to use, duplicate, and + * publish this text and program as long as it + * includes this entire comment block and limited + * rights reference. + * + * Converted by Rich Painter, Painter Engineering, Inc. based on the + * www.netlib.org benchmark/whetstoned version obtained 16 March 1998. + * + * A novel approach was used here to keep the look and feel of the + * FORTRAN version. Altering the FORTRAN-based array indices, + * starting at element 1, to start at element 0 for C, would require + * numerous changes, including decrementing the variable indices by 1. + * Instead, the array e1[] was declared 1 element larger in C. This + * allows the FORTRAN index range to function without any literal or + * variable indices changes. The array element e1[0] is simply never + * used and does not alter the benchmark results. + * + * The major FORTRAN comment blocks were retained to minimize + * differences between versions. Modules N5 and N12, like in the + * FORTRAN version, have been eliminated here. + * + * An optional command-line argument has been provided [-c] to + * offer continuous repetition of the entire benchmark. + * An optional argument for setting an alternate loop count is also + * provided. Define PRINTOUT to cause the pout() function to print + * outputs at various stages. Final timing measurements should be + * made with the PRINTOUT undefined. + * + * Questions and comments may be directed to the author at + * r.painter@ieee.org + ****************************************************************************/ + +/**************************************************************************** + * Benchmark #2 -- Double Precision Whetstone (A001) + * + * o This is a REAL*8 version of + * the Whetstone benchmark program. + * + * o DO-loop semantics are ANSI-66 compatible. + * + * o Final measurements are to be made with all + * WRITE statements and FORMAT sttements removed. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* standard C library headers required */ + +#include +#include +#include +#include + +/* the following is optional depending on the timing function used */ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* map the FORTRAN math functions, etc. to the C versions */ + +#define DSIN sin +#define DCOS cos +#define DATAN atan +#define DLOG log +#define DEXP exp +#define DSQRT sqrt +#define IF if +#define USAGE "usage: whetdc [-c] [loops]\n" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* function prototypes */ + +void pout(long n, long j, long k, double x1, + double x2, double x3, double x4); +void pa(double e[]); +void p0(void); +void p3(double x, double y, FAR double *z); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* COMMON t,t1,t2,e1(4),j,k,l */ + +double t; +double t1; +double t2; +double e1[5]; +int j; +int k; +int l; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + /* used in the FORTRAN version */ + + long loop; + long i; + long n1; + long n2; + long n3; + long n4; + long n6; + long n7; + long n8; + long n9; + long n10; + long n11; + double x1; + double x2; + double x3; + double x4; + double x; + double y; + double z; + int ii; + int jj; + + /* added for this version */ + + long loopstart; + long startsec; + long finisec; + float KIPS; + int continuous; + + loopstart = 1000; /* see the note about loop below */ + continuous = 0; + + ii = 1; /* start at the first arg (temp use of ii here) */ + while (ii < argc) + { + if (strncmp(argv[ii], "-c", 2) == 0 || argv[ii][0] == 'c') + { + continuous = 1; + } + else if (atol(argv[ii]) > 0) + { + loopstart = atol(argv[ii]); + } + else + { + fprintf(stderr, USAGE); + return 1; + } + + ii++; + } + +LCONT: + + /* Start benchmark timing at this point. */ + + startsec = time(0); + + /* The actual benchmark starts here. */ + + t = .499975; + t1 = 0.50025; + t2 = 2.0; + + /* With loopcount loop=10, one million Whetstone instructions + * will be executed in EACH MAJOR loop..A MAJOR loop IS EXECUTED + * 'ii' TIMES TO INCREASE WALL-CLOCK TIMING ACCURACY. + * + * loop = 1000; + */ + + loop = loopstart; + ii = 1; + + jj = 1; + +IILOOP: + n1 = 0; + n2 = 12 * loop; + n3 = 14 * loop; + n4 = 345 * loop; + n6 = 210 * loop; + n7 = 32 * loop; + n8 = 899 * loop; + n9 = 616 * loop; + n10 = 0; + n11 = 93 * loop; + + /* Module 1: Simple identifiers */ + + x1 = 1.0; + x2 = -1.0; + x3 = -1.0; + x4 = -1.0; + + for (i = 1; i <= n1; i++) + { + x1 = (x1 + x2 + x3 - x4) * t; + x2 = (x1 + x2 - x3 + x4) * t; + x3 = (x1 - x2 + x3 + x4) * t; + x4 = (-x1 + x2 + x3 + x4) * t; + } + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n1, n1, n1, x1, x2, x3, x4); + } +#endif + + /* Module 2: Array elements */ + + e1[1] = 1.0; + e1[2] = -1.0; + e1[3] = -1.0; + e1[4] = -1.0; + + for (i = 1; i <= n2; i++) + { + e1[1] = (e1[1] + e1[2] + e1[3] - e1[4]) * t; + e1[2] = (e1[1] + e1[2] - e1[3] + e1[4]) * t; + e1[3] = (e1[1] - e1[2] + e1[3] + e1[4]) * t; + e1[4] = (-e1[1] + e1[2] + e1[3] + e1[4]) * t; + } + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n2, n3, n2, e1[1], e1[2], e1[3], e1[4]); + } +#endif + + /* Module 3: Array as parameter */ + + for (i = 1; i <= n3; i++) + { + pa(e1); + } + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n3, n2, n2, e1[1], e1[2], e1[3], e1[4]); + } +#endif + + /* Module 4: Conditional jumps */ + + j = 1; + for (i = 1; i <= n4; i++) + { + if (j == 1) + { + j = 2; + } + else + { + j = 3; + } + + if (j > 2) + { + j = 0; + } + else + { + j = 1; + } + + if (j < 1) + { + j = 1; + } + else + { + j = 0; + } + } + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n4, j, j, x1, x2, x3, x4); + } +#endif + +/* Module 5: Omitted + * Module 6: Integer arithmetic + */ + + j = 1; + k = 2; + l = 3; + + for (i = 1; i <= n6; i++) + { + j = j * (k - j) * (l - k); + k = l * k - (l - j) * k; + l = (l - k) * (k + j); + e1[l - 1] = j + k + l; + e1[k - 1] = j * k * l; + } + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n6, j, k, e1[1], e1[2], e1[3], e1[4]); + } +#endif + + /* Module 7: Trigonometric functions */ + + x = 0.5; + y = 0.5; + + for (i = 1; i <= n7; i++) + { + x = t * DATAN(t2 * DSIN(x) * DCOS(x) / + (DCOS(x + y) + DCOS(x - y) - 1.0)); + y = t * DATAN(t2 * DSIN(y) * DCOS(y) / + (DCOS(x + y) + DCOS(x - y) - 1.0)); + } + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n7, j, k, x, x, y, y); + } +#endif + + /* Module 8: Procedure calls */ + + x = 1.0; + y = 1.0; + z = 1.0; + + for (i = 1; i <= n8; i++) + { + p3(x, y, &z); + } + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n8, j, k, x, y, z, z); + } +#endif + + /* Module 9: Array references */ + + j = 1; + k = 2; + l = 3; + e1[1] = 1.0; + e1[2] = 2.0; + e1[3] = 3.0; + + for (i = 1; i <= n9; i++) + { + p0(); + } + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n9, j, k, e1[1], e1[2], e1[3], e1[4]); + } +#endif + + /* Module 10: Integer arithmetic */ + + j = 2; + k = 3; + + for (i = 1; i <= n10; i++) + { + j = j + k; + k = j + k; + j = k - j; + k = k - j - j; + } + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n10, j, k, x1, x2, x3, x4); + } +#endif + + /* Module 11: Standard functions */ + + x = 0.75; + + for (i = 1; i <= n11; i++) + x = DSQRT(DEXP(DLOG(x) / t1)); + +#ifdef PRINTOUT + IF (jj == ii) + { + pout(n11, j, k, x, x, x, x); + } +#endif + + /* THIS IS THE END OF THE MAJOR loop. */ + + if (++jj <= ii) + { + goto IILOOP; + } + + /* Stop benchmark timing at this point. */ + + finisec = time(0); + + /* Performance in Whetstone KIP's per second is given by + * + * (100*loop*ii)/TIME + * + * where TIME is in seconds. + */ + + printf("\n"); + if (finisec - startsec <= 0) + { + printf("Insufficient duration- Increase the loop count\n"); + return 1; + } + + printf("Loops: %ld, Iterations: %d, Duration: %ld sec.\n", + loop, ii, finisec - startsec); + + KIPS = (100.0 * loop * ii) / (float)(finisec - startsec); + if (KIPS >= 1000.0) + { + printf("C Converted Double Precision Whetstones: %.1f MIPS\n", + KIPS / 1000.0); + } + else + { + printf("C Converted Double Precision Whetstones: %.1f KIPS\n", KIPS); + } + + if (continuous) + { + goto LCONT; + } + + return 0; +} + +void +pa(double e[]) +{ + j = 0; + +L10: + e[1] = (e[1] + e[2] + e[3] - e[4]) * t; + e[2] = (e[1] + e[2] - e[3] + e[4]) * t; + e[3] = (e[1] - e[2] + e[3] + e[4]) * t; + e[4] = (-e[1] + e[2] + e[3] + e[4]) / t2; + j += 1; + + if (j < 6) + { + goto L10; + } +} + +void +p0(void) +{ + e1[j] = e1[k]; + e1[k] = e1[l]; + e1[l] = e1[j]; +} + +void p3(double x, double y, FAR double *z) +{ + double x1; + double y1; + + x1 = x; + y1 = y; + x1 = t * (x1 + y1); + y1 = t * (x1 + y1); + *z = (x1 + y1) / t2; +} + +#ifdef PRINTOUT +void +pout(long n, long j, long k, double x1, double x2, double x3, double x4) +{ + printf("%7ld %7ld %7ld %12.4e %12.4e %12.4e %12.4e\n", + n, j, k, x1, x2, x3, x4); +} +#endif From 22f85e8b61de4fe8b22fd6224601363f28901a68 Mon Sep 17 00:00:00 2001 From: makejian Date: Thu, 29 May 2025 20:50:13 +0800 Subject: [PATCH 142/568] benchmarks/fpu: improve timing precision to milliseconds Change FPU benchmark timing from seconds to milliseconds for better accuracy. This allows for more precise measurement of test cycles, especially for shorter test runs that previously completed within a single second. Signed-off-by: makejian --- benchmarks/whetstone/whetstone.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/benchmarks/whetstone/whetstone.c b/benchmarks/whetstone/whetstone.c index 4363baaf7..dbc8247fd 100644 --- a/benchmarks/whetstone/whetstone.c +++ b/benchmarks/whetstone/whetstone.c @@ -143,10 +143,11 @@ int main(int argc, FAR char *argv[]) /* added for this version */ long loopstart; - long startsec; - long finisec; + long startmsec; + long finimsec; float KIPS; int continuous; + struct timespec ts; loopstart = 1000; /* see the note about loop below */ continuous = 0; @@ -175,7 +176,8 @@ LCONT: /* Start benchmark timing at this point. */ - startsec = time(0); + clock_gettime(CLOCK_REALTIME, &ts); + startmsec = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; /* The actual benchmark starts here. */ @@ -431,7 +433,8 @@ IILOOP: /* Stop benchmark timing at this point. */ - finisec = time(0); + clock_gettime(CLOCK_REALTIME, &ts); + finimsec = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; /* Performance in Whetstone KIP's per second is given by * @@ -441,16 +444,16 @@ IILOOP: */ printf("\n"); - if (finisec - startsec <= 0) + if (finimsec - startmsec <= 0) { printf("Insufficient duration- Increase the loop count\n"); return 1; } - printf("Loops: %ld, Iterations: %d, Duration: %ld sec.\n", - loop, ii, finisec - startsec); + printf("Loops: %ld, Iterations: %d, Duration: %ld millisecond.\n", + loop, ii, finimsec - startmsec); - KIPS = (100.0 * loop * ii) / (float)(finisec - startsec); + KIPS = (100.0 * loop * ii) / ((float)(finimsec - startmsec) * 1000); if (KIPS >= 1000.0) { printf("C Converted Double Precision Whetstones: %.1f MIPS\n", From 825007aafb48261fcb28a4a08235e46a265d9b29 Mon Sep 17 00:00:00 2001 From: makejian Date: Tue, 29 Jul 2025 22:54:37 +0800 Subject: [PATCH 143/568] crypto/openssl-wrapper: export SSL_CTX_load_verify_file and SSL_CTX_load_verify_dir Export SSL_CTX_load_verify_file() and SSL_CTX_load_verify_dir() interfaces to allow loading CA certificates from file or directory. Signed-off-by: makejian --- crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h index 7bdc03125..436354882 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h @@ -454,6 +454,10 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg); +int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile); + +int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath); + int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); From 690d8bddceb4d212edd33e70e22ade0d0c6fb5a9 Mon Sep 17 00:00:00 2001 From: makejian Date: Wed, 13 Aug 2025 19:30:14 +0800 Subject: [PATCH 144/568] crypto/openssl-wrapper: fix SSL error code mapping Map mbedtls error codes to OpenSSL standard return codes in SSL_connect/SSL_do_handshake: - Return 1 on success - Return 0 on controlled shutdown - Return -1 on fatal error (was returning mbedtls error codes) This aligns the return values with OpenSSL specification where SSL_get_error() should be called to get the actual error reason. Signed-off-by: makejian --- crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c index 84ba2345e..4924969c9 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_pm.c @@ -368,17 +368,21 @@ int ssl_pm_handshake(SSL *ssl) } /* OpenSSL return codes: - * 0 = did not complete, but may be retried + * 0 = The TLS/SSL handshake was not successful but was shut down + * controlled and by the specifications of the TLS/SSL protocol. * 1 = successfully completed - * <0 = death + * <0 = The TLS/SSL handshake was not successful because a fatal error + * occurred either at the protocol level or a connection failure + * occurred. */ if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { - ssl->err = ret; + ssl->err = (ret == MBEDTLS_ERR_SSL_WANT_READ) ? SSL_ERROR_WANT_READ : + SSL_ERROR_WANT_WRITE; SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_handshake() return -0x%x", -ret); - return 0; /* OpenSSL: did not complete but may be retried */ + return -1; } if (ret == 0) @@ -397,7 +401,7 @@ int ssl_pm_handshake(SSL *ssl) { ssl->err = ret == MBEDTLS_ERR_SSL_WANT_READ; - return 0; + return -1; } SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, From 57ced95c07992aec30618599e88f8e8835c258ba Mon Sep 17 00:00:00 2001 From: makejian Date: Fri, 10 Oct 2025 15:08:23 +0800 Subject: [PATCH 145/568] crypto/openssl-wrapper: align SSL_CTX_new declaration with OpenSSL Remove the extra rngctx parameter from SSL_CTX_new() to match the standard OpenSSL API signature: SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) This improves compatibility with code written for OpenSSL. Signed-off-by: makejian --- crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h | 2 +- crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h index 436354882..d9b2298b9 100644 --- a/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h +++ b/crypto/openssl_mbedtls_wrapper/include/openssl/ssl.h @@ -251,7 +251,7 @@ int SSL_get_error(const SSL *ssl, int ret_code); OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); -SSL_CTX *SSL_CTX_new(const SSL_METHOD *method, ...); +SSL_CTX *SSL_CTX_new(const SSL_METHOD *method); void SSL_CTX_free(SSL_CTX *ctx); diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c index 4e7bf0968..b240d38d7 100644 --- a/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c +++ b/crypto/openssl_mbedtls_wrapper/mbedtls/ssl_lib.c @@ -260,7 +260,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) return ret; } -SSL_CTX *SSL_CTX_new(const SSL_METHOD *method, ...) +SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) { SSL_CTX *ctx; CERT *cert; From 85b1a1c8c13dd15638196e39ab6fd4fffc912849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20VINCENT?= <44554692+comejv@users.noreply.github.com> Date: Wed, 21 Jan 2026 13:48:26 +0100 Subject: [PATCH 146/568] fix(macro): fix CAPIO_FREQUENCY macro typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going from CAPIOC_FREQUENCE to CAPIO_FREQUENCY according to nuttx/pull/16925 Signed-off-by: Côme VINCENT <44554692+comejv@users.noreply.github.com> --- examples/capture/cap_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/capture/cap_main.c b/examples/capture/cap_main.c index 3ca080368..2ba238a60 100644 --- a/examples/capture/cap_main.c +++ b/examples/capture/cap_main.c @@ -351,11 +351,11 @@ int main(int argc, FAR char *argv[]) /* Get the frequency data using the ioctl */ - ret = ioctl(fd, CAPIOC_FREQUENCE, + ret = ioctl(fd, CAPIOC_FREQUENCY, (unsigned long)((uintptr_t)&frequency)); if (ret < 0) { - printf("cap_main: ioctl(CAPIOC_FREQUENCE) failed: %d\n", errno); + printf("cap_main: ioctl(CAPIOC_FREQUENCY) failed: %d\n", errno); exitval = EXIT_FAILURE; goto errout_with_dev; } From 72fe4e21e1e2d715aedf23cd1c50adf105fff99f Mon Sep 17 00:00:00 2001 From: zhenwei fang Date: Wed, 21 Jan 2026 20:15:16 +0800 Subject: [PATCH 147/568] nsh: fix nsh redirect fd double close avoid double-close of redirection fds Signed-off-by: zhenwei fang --- nshlib/nsh_parse.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nshlib/nsh_parse.c b/nshlib/nsh_parse.c index 9b7b371af..9b1bde875 100644 --- a/nshlib/nsh_parse.c +++ b/nshlib/nsh_parse.c @@ -726,6 +726,8 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl, if (vtbl->np.np_redir_out || vtbl->np.np_redir_in) { nsh_undirect(vtbl, save); + fd_out = -1; + fd_in = -1; } } From 40a890626d39e12291e64253e6192665206325b4 Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Fri, 3 Jan 2025 15:17:16 +0800 Subject: [PATCH 148/568] testing: specify arch format Kconfig Specify architecture format in Kconfig to ensure proper configuration handling for different architectures in testing modules. Signed-off-by: tengshuangshuang --- testing/libc/arch_libc/Kconfig | 2 +- testing/testsuites/Kconfig | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/testing/libc/arch_libc/Kconfig b/testing/libc/arch_libc/Kconfig index c8bdfa9f2..65927909c 100644 --- a/testing/libc/arch_libc/Kconfig +++ b/testing/libc/arch_libc/Kconfig @@ -14,7 +14,7 @@ if TESTING_ARCH_LIBC config TESTING_ARCH_LIBC_STRCPY bool "test strcpy" - default n + default y config TESTING_ARCH_LIBC_PROGNAME string "Program name" diff --git a/testing/testsuites/Kconfig b/testing/testsuites/Kconfig index 8ed01ffcf..8c1eb2015 100644 --- a/testing/testsuites/Kconfig +++ b/testing/testsuites/Kconfig @@ -12,6 +12,8 @@ config TESTS_TESTSUITES if TESTS_TESTSUITES +menu "Testsuite cases" + config TESTS_TESTSUITES_MOUNT_DIR string "Mount directory for the testsuites" default "/data" @@ -27,19 +29,36 @@ config TESTS_TESTSUITES_STACKSIZE config CM_FS_TEST bool "enable fs test" default n + depends on PSEUDOFS_SOFTLINKS config CM_SCHED_TEST bool "enable schedule test" default n +config CM_SYSCALL_TEST + bool "enbale syscall test" + default n + depends on PIPES && SCHED_HAVE_PARENT + config CM_MM_TEST bool "enable MM test" default n +config CM_KVDB_TEST + bool "enbale kvdb test" + default n + depends on KVDB + config CM_TIME_TEST bool "enable time test" depends on !DISABLE_POSIX_TIMERS && SIG_EVTHREAD default n + depends on SIG_EVTHREAD + +config CM_SOCKET_TEST + bool "enbale socket test" + default n + depends on NET && NETDEV_LATEINIT config CM_PTHREAD_TEST bool "enable pthread test" @@ -58,4 +77,10 @@ config CM_MUTEX_TEST bool "enable mutex test" default n +config CM_DFX_TEST + bool "enbale dfx test" + default n + depends on NETUTILS_CJSON && DFX && DFX_EVENT + +endmenu endif # TESTS_TESTSUITES From 10873c6b59ce5cc22a3f2b20e1d7617ad04a427a Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Wed, 8 Jan 2025 22:02:49 +0800 Subject: [PATCH 149/568] testing: specify arch kconfig for testsuites Specify architecture configuration in testsuites Kconfig to ensure correct architecture-specific settings and build configurations. Signed-off-by: tengshuangshuang --- testing/testsuites/Kconfig | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/testing/testsuites/Kconfig b/testing/testsuites/Kconfig index 8c1eb2015..eb2cd4547 100644 --- a/testing/testsuites/Kconfig +++ b/testing/testsuites/Kconfig @@ -35,30 +35,14 @@ config CM_SCHED_TEST bool "enable schedule test" default n -config CM_SYSCALL_TEST - bool "enbale syscall test" - default n - depends on PIPES && SCHED_HAVE_PARENT - config CM_MM_TEST bool "enable MM test" default n -config CM_KVDB_TEST - bool "enbale kvdb test" - default n - depends on KVDB - config CM_TIME_TEST bool "enable time test" depends on !DISABLE_POSIX_TIMERS && SIG_EVTHREAD default n - depends on SIG_EVTHREAD - -config CM_SOCKET_TEST - bool "enbale socket test" - default n - depends on NET && NETDEV_LATEINIT config CM_PTHREAD_TEST bool "enable pthread test" @@ -66,21 +50,17 @@ config CM_PTHREAD_TEST config CM_SOCKET_TEST bool "enable socket test" - depends on NET default n + depends on NET && NETDEV_LATEINIT config CM_SYSCALL_TEST bool "enable syscall test" default n + depends on PIPES && SCHED_HAVE_PARENT && FS_TMPFS && ARCH_SETJMP_H && PSEUDOFS_SOFTLINKS config CM_MUTEX_TEST bool "enable mutex test" default n -config CM_DFX_TEST - bool "enbale dfx test" - default n - depends on NETUTILS_CJSON && DFX && DFX_EVENT - endmenu endif # TESTS_TESTSUITES From 8146403512488c8862f5464690fb6c8288689f43 Mon Sep 17 00:00:00 2001 From: likun17 Date: Mon, 13 Jan 2025 20:32:00 +0800 Subject: [PATCH 150/568] system/uorb: uorb listener bug fix. Fixed the issue that instance+1 subscription will be triggered when topic exists in this core Signed-off-by: likun17 --- system/uorb/listener.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/uorb/listener.c b/system/uorb/listener.c index fe7909030..b9013a06a 100644 --- a/system/uorb/listener.c +++ b/system/uorb/listener.c @@ -427,7 +427,7 @@ static int listener_generate_object_list(FAR struct listen_list_s *objlist, } } - if (orb_exists(object.meta, object.instance++) < 0) + if (orb_exists(object.meta, ++object.instance) < 0) { break; } From 5216065fb8b875c18ef40dae0eb1c18abfb9b405 Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Wed, 4 Dec 2024 11:29:35 +0800 Subject: [PATCH 151/568] cache_test: fix up_flash_dcache error Fix flash dcache helper error handling in cache_test to properly handle errors when flushing data cache operations fail. Signed-off-by: tengshuangshuang --- testing/mm/cachetest/cachetest_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/testing/mm/cachetest/cachetest_main.c b/testing/mm/cachetest/cachetest_main.c index 4c0087aa8..3906b58e6 100644 --- a/testing/mm/cachetest/cachetest_main.c +++ b/testing/mm/cachetest/cachetest_main.c @@ -26,7 +26,6 @@ #include #include - #include #include From 6249f22f97157a516021580411bd12a70c0dec13 Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Wed, 4 Dec 2024 15:48:59 +0800 Subject: [PATCH 152/568] tests: fix cache_test and arch_lib_test date style error Correct date formatting in cache_test and arch_lib_test outputs to ensure consistent date/time display format across test results. Signed-off-by: tengshuangshuang --- testing/libc/arch_libc/arch_libc_test_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/libc/arch_libc/arch_libc_test_main.c b/testing/libc/arch_libc/arch_libc_test_main.c index 47cfe65bc..b078fff34 100644 --- a/testing/libc/arch_libc/arch_libc_test_main.c +++ b/testing/libc/arch_libc/arch_libc_test_main.c @@ -224,8 +224,8 @@ int arch_libc_strcpy_speed(void) } } - printf("strcpy total(run 25 times) cpu cycles %" PRIu32 "\n", cycles); - printf("strcpy average cpu cycles %" PRIu32 "\n", cycles / 25); + printf("strcpy total(run 25 times) cpu cycles %"PRIu64"\n", cycles); + printf("strcpy average cpu cycles %"PRIu64"\n", cycles / 25); return 0; } From df48348fcaa3363197e5f486883fc1f85a226984 Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Thu, 5 Dec 2024 17:48:11 +0800 Subject: [PATCH 153/568] test: fix timerjitter data style error Fix timerjitter output formatting for date/time fields to match expected format and improve test result readability. Signed-off-by: tengshuangshuang --- testing/sched/timerjitter/timerjitter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/sched/timerjitter/timerjitter.c b/testing/sched/timerjitter/timerjitter.c index ad956cd4c..3edd10388 100644 --- a/testing/sched/timerjitter/timerjitter.c +++ b/testing/sched/timerjitter/timerjitter.c @@ -192,7 +192,8 @@ static FAR void *timerjitter(FAR void *arg) diff = calc_diff(&now, &next); if (param->print) { - printf("diff %lu, now %lu.%lu\n", diff, now.tv_sec, now.tv_nsec); + printf("diff %"PRId64", now %"PRId64".%09lu\n", diff, now.tv_sec, + now.tv_nsec); } if (diff > param->max) From 4df2ce98aacf38df884b42dec9556f5db881f1f7 Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Fri, 3 Jan 2025 15:24:02 +0800 Subject: [PATCH 154/568] testing: fix net case bug Adjust net socket test expectations for correct behavior to prevent false test failures in network socket test cases. Signed-off-by: tengshuangshuang --- testing/testsuites/kernel/socket/cases/net_socket_test_010.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/testing/testsuites/kernel/socket/cases/net_socket_test_010.c b/testing/testsuites/kernel/socket/cases/net_socket_test_010.c index 462b07a2e..f8a951aa9 100644 --- a/testing/testsuites/kernel/socket/cases/net_socket_test_010.c +++ b/testing/testsuites/kernel/socket/cases/net_socket_test_010.c @@ -42,8 +42,6 @@ * Pre-processor Definitions ****************************************************************************/ -#define IFF_PROMISC 0x100 - /**************************************************************************** * Private Functions ****************************************************************************/ From 8afe3c0645185ae96890abe5f8d7f115a4c83ab8 Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Mon, 30 Dec 2024 10:53:26 +0800 Subject: [PATCH 155/568] test: clean driver_audio_test (void *) cast Drop unnecessary casts in driver_audio_test to silence compiler warnings and improve code clarity. Signed-off-by: tengshuangshuang --- testing/drivers/drivertest/drivertest_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/drivers/drivertest/drivertest_audio.c b/testing/drivers/drivertest/drivertest_audio.c index 491dfec38..20b4babbc 100644 --- a/testing/drivers/drivertest/drivertest_audio.c +++ b/testing/drivers/drivertest/drivertest_audio.c @@ -742,7 +742,7 @@ static int audio_test_setup(FAR void **audio_state) attr.mq_flags = 0; snprintf(state->mqname, sizeof(state->mqname), "/tmp/%p", - ((void *)state)); + state); state->mq = mq_open(state->mqname, O_RDWR | O_CREAT, 0644, &attr); assert_false(state->mq < 0); From b86457dfcb42f8d77a6b209666340401723ff440 Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Sat, 22 Mar 2025 16:28:55 +0800 Subject: [PATCH 156/568] apps/testing: fix syscall cases for fdcheck compatibility Guard fdcheck-sensitive paths in setsocketopt, dup2, and fsync tests to avoid assertion failures when fdcheck is enabled, ensuring tests can properly verify error handling behavior. Signed-off-by: tengshuangshuang --- testing/testsuites/kernel/syscall/cases/dup2_test.c | 1 - testing/testsuites/kernel/syscall/cases/fsync_test.c | 6 ++++-- .../testsuites/kernel/syscall/cases/setsocketopt01_test.c | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/testing/testsuites/kernel/syscall/cases/dup2_test.c b/testing/testsuites/kernel/syscall/cases/dup2_test.c index bdd7b0b97..bb1ea6928 100644 --- a/testing/testsuites/kernel/syscall/cases/dup2_test.c +++ b/testing/testsuites/kernel/syscall/cases/dup2_test.c @@ -149,7 +149,6 @@ void test_nuttx_syscall_dup202(FAR void **state) assert_int_equal(fstat(*(TC[i].nfd), &newbuf), 0); assert_int_equal(oldbuf.st_mode, newbuf.st_mode); - close(*TC[i].nfd); close(ofd); close(ret); diff --git a/testing/testsuites/kernel/syscall/cases/fsync_test.c b/testing/testsuites/kernel/syscall/cases/fsync_test.c index 8aabf2002..e2834f861 100644 --- a/testing/testsuites/kernel/syscall/cases/fsync_test.c +++ b/testing/testsuites/kernel/syscall/cases/fsync_test.c @@ -117,17 +117,19 @@ void test_nuttx_syscall_fsync02(FAR void **state) /* EBADF - fd is closed */ +# ifndef CONFIG_FDCHECK { &pipe_fd[0], EBADF }, +# endif /* EBADF - fd is invalid (-1) */ - #ifndef CONFIG_FDSAN +# ifndef CONFIG_FDSAN { &bad_fd, EBADF }, - #endif +# endif /* EINVAL - fsync() on fifo should not succeed. */ diff --git a/testing/testsuites/kernel/syscall/cases/setsocketopt01_test.c b/testing/testsuites/kernel/syscall/cases/setsocketopt01_test.c index b877f6f01..adc991933 100644 --- a/testing/testsuites/kernel/syscall/cases/setsocketopt01_test.c +++ b/testing/testsuites/kernel/syscall/cases/setsocketopt01_test.c @@ -67,10 +67,12 @@ void test_nuttx_syscall_setsockopt01(FAR void **state) testcase_list[] = { +# ifndef CONFIG_FDCHECK { -1, -1, -1, SOL_SOCKET, SO_OOBINLINE, &optval, sizeof(optval), EBADF, "invalid file descriptor" }, +# endif { -1, -1, -1, SOL_SOCKET, SO_OOBINLINE, &optval, sizeof(optval), From be26d7963343cb7193b86286294f9158243aa308 Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Wed, 26 Mar 2025 10:27:51 +0800 Subject: [PATCH 157/568] syscall: fix badfd test for fdcheck compatibility Handle fdcheck path for badfd test to prevent unexpected dumps when fdcheck is enabled, allowing proper testing of bad file descriptor error cases. Signed-off-by: tengshuangshuang --- testing/testsuites/kernel/syscall/cases/close_test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/testing/testsuites/kernel/syscall/cases/close_test.c b/testing/testsuites/kernel/syscall/cases/close_test.c index 1d62f92ec..099a3b663 100644 --- a/testing/testsuites/kernel/syscall/cases/close_test.c +++ b/testing/testsuites/kernel/syscall/cases/close_test.c @@ -99,7 +99,9 @@ void test_nuttx_syscall_close02(FAR void **state) #ifndef CONFIG_FDSAN int ret; int badfd1 = -1; +#ifndef CONFIG_FDCHECK int badfd2 = 99999999; +#endif ret = close(badfd1); assert_int_equal(ret, ERROR); @@ -109,6 +111,7 @@ void test_nuttx_syscall_close02(FAR void **state) assert_int_equal(errno, EBADF); +#ifndef CONFIG_FDCHECK ret = close(badfd2); assert_int_equal(ret, ERROR); @@ -117,6 +120,7 @@ void test_nuttx_syscall_close02(FAR void **state) assert_int_equal(errno, EBADF); #endif +#endif } /**************************************************************************** From 338301de76f05c0f12ce7a69be6b102e62b608b6 Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Fri, 28 Mar 2025 16:18:17 +0800 Subject: [PATCH 158/568] timerjitter: fix signal-cause error Handle timer-delivered signals correctly to prevent assertions when signal-related events occur during timing measurements. Signed-off-by: tengshuangshuang --- testing/sched/timerjitter/timerjitter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/sched/timerjitter/timerjitter.c b/testing/sched/timerjitter/timerjitter.c index 3edd10388..214bbf735 100644 --- a/testing/sched/timerjitter/timerjitter.c +++ b/testing/sched/timerjitter/timerjitter.c @@ -221,6 +221,7 @@ static FAR void *timerjitter(FAR void *arg) } } + timer_delete(timer); param->avg = param->avg / param->cur_cnt; return NULL; } From b6203955f98a0d7d209e591f189a9c7eb057dcdc Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Thu, 3 Apr 2025 14:59:44 +0800 Subject: [PATCH 159/568] syscall: fix listen case bug Skip UDP listen test when CONFIG_NET_UDP is disabled to prevent test failures on configurations without UDP support. Signed-off-by: tengshuangshuang --- testing/drivers/drivertest/drivertest_audio.c | 2 +- testing/libc/arch_libc/arch_libc_test_main.c | 2 +- testing/testsuites/kernel/syscall/cases/listen_test.c | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_audio.c b/testing/drivers/drivertest/drivertest_audio.c index 20b4babbc..a467f6f26 100644 --- a/testing/drivers/drivertest/drivertest_audio.c +++ b/testing/drivers/drivertest/drivertest_audio.c @@ -265,7 +265,7 @@ static void audio_test_help(FAR const char *progname, int exitcode) " -f \n" " -b \n" " -s \n" - " -c \n", + " -c \n", progname); printf(" [-a testcase] selects the testcase\n" " Case 1: Capture\n" diff --git a/testing/libc/arch_libc/arch_libc_test_main.c b/testing/libc/arch_libc/arch_libc_test_main.c index b078fff34..1e1a06b19 100644 --- a/testing/libc/arch_libc/arch_libc_test_main.c +++ b/testing/libc/arch_libc/arch_libc_test_main.c @@ -133,7 +133,7 @@ int arch_libc_test_strcpy_offset(int dst_offset, int src_offset) } } - /* strcpy shouln't change arch_libc_test_strcpy's local variable */ + /* strcpy shouldn't change arch_libc_test_strcpy's local variable */ if (dest != (g_test_dst_str + dst_offset) || src != (g_test_src_str + src_offset)) diff --git a/testing/testsuites/kernel/syscall/cases/listen_test.c b/testing/testsuites/kernel/syscall/cases/listen_test.c index e8099a270..7dc4ba266 100644 --- a/testing/testsuites/kernel/syscall/cases/listen_test.c +++ b/testing/testsuites/kernel/syscall/cases/listen_test.c @@ -77,10 +77,12 @@ void test_nuttx_syscall_listen01(FAR void **state) 0, 0, 0, 0, -1, ENOTSOCK, "setup0", "cleanup0", "not a socket" }, +# ifdef CONFIG_NET_UDP { PF_INET, SOCK_DGRAM, 0, 0, -1, EOPNOTSUPP, "setup1", "cleanup1", "UDP listen" }, +# endif }; const char set[] = "setup0"; From 3c99bad310bd74b8e37861a7d4db14e8bf221d93 Mon Sep 17 00:00:00 2001 From: yukangzhi Date: Tue, 5 Aug 2025 18:20:16 +0800 Subject: [PATCH 160/568] crctest: Test the CRC library that the E2E depends on. Test the CRC Library defined in the AUTOSAR specification Signed-off-by: yukangzhi --- testing/libc/crctest/CMakeLists.txt | 35 +++ testing/libc/crctest/Kconfig | 23 ++ testing/libc/crctest/Make.defs | 23 ++ testing/libc/crctest/Makefile | 30 +++ testing/libc/crctest/crctest_main.c | 333 ++++++++++++++++++++++++++++ 5 files changed, 444 insertions(+) create mode 100644 testing/libc/crctest/CMakeLists.txt create mode 100644 testing/libc/crctest/Kconfig create mode 100644 testing/libc/crctest/Make.defs create mode 100644 testing/libc/crctest/Makefile create mode 100644 testing/libc/crctest/crctest_main.c diff --git a/testing/libc/crctest/CMakeLists.txt b/testing/libc/crctest/CMakeLists.txt new file mode 100644 index 000000000..2b858e573 --- /dev/null +++ b/testing/libc/crctest/CMakeLists.txt @@ -0,0 +1,35 @@ +# ############################################################################## +# apps/testing/libc/crctest/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_TESTING_CRC_TEST) + nuttx_add_application( + NAME + cmocka_crctest + PRIORITY + ${CONFIG_TESTING_CRC_TEST_PRIORITY} + STACKSIZE + ${CONFIG_TESTING_CRC_TEST_STACKSIZE} + MODULE + ${CONFIG_TESTING_CRC_TEST} + DEPENDS + cmocka + SRCS + crctest_main.c) +endif() diff --git a/testing/libc/crctest/Kconfig b/testing/libc/crctest/Kconfig new file mode 100644 index 000000000..0e06c18d9 --- /dev/null +++ b/testing/libc/crctest/Kconfig @@ -0,0 +1,23 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config TESTING_CRC_TEST + tristate "vela cmocka CRC test" + default n + depends on TESTING_CMOCKA + ---help--- + Enable the cmocka CRC test + +if TESTING_CRC_TEST + +config TESTING_CRC_TEST_PRIORITY + int "Task priority" + default 100 + +config TESTING_CRC_TEST_STACKSIZE + int "Stack size" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/testing/libc/crctest/Make.defs b/testing/libc/crctest/Make.defs new file mode 100644 index 000000000..38f25631e --- /dev/null +++ b/testing/libc/crctest/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/testing/libc/crctest/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_TESTING_CRC_TEST),) +CONFIGURED_APPS += $(APPDIR)/testing/libc/crctest +endif diff --git a/testing/libc/crctest/Makefile b/testing/libc/crctest/Makefile new file mode 100644 index 000000000..f6c9a9662 --- /dev/null +++ b/testing/libc/crctest/Makefile @@ -0,0 +1,30 @@ +############################################################################ +# apps/testing/libc/crctest/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +PRIORITY = $(CONFIG_TESTING_CRC_TEST_PRIORITY) +STACKSIZE = $(CONFIG_TESTING_CRC_TEST_STACKSIZE) +MODULE = $(CONFIG_TESTING_CRC_TEST) + +MAINSRC = crctest_main.c +PROGNAME = crctest + +include $(APPDIR)/Application.mk diff --git a/testing/libc/crctest/crctest_main.c b/testing/libc/crctest/crctest_main.c new file mode 100644 index 000000000..7ae966f91 --- /dev/null +++ b/testing/libc/crctest/crctest_main.c @@ -0,0 +1,333 @@ +/**************************************************************************** + * apps/testing/libc/crctest/crctest_main.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Private Type + ****************************************************************************/ + +typedef struct +{ + uint8_t length; + uint8_t data[9]; +} crc_test_data_t; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static crc_test_data_t crc_test_data[] = +{ + { + 4, + { 0x00, 0x00, 0x00, 0x00 } + }, + { + 3, + { 0xf2, 0x01, 0x83 } + }, + { + 4, + { 0x0f, 0xaa, 0x00, 0x55 } + }, + { + 4, + { 0x00, 0xff, 0x55, 0x11 } + }, + { + 9, + { 0x33, 0x22, 0x55, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff } + }, + { + 3, + { 0x92, 0x6b, 0x55 } + }, + { + 4, + { 0xff, 0xff, 0xff, 0xff } + }, +}; + +static uint8_t crc8h1d_expected_crc[] = +{ + 0x59, 0x37, 0x79, 0xb8, 0xcb, 0x8c, 0x74 +}; + +static uint8_t crc8h2f_expected_crc[] = +{ + 0x12, 0xc2, 0xc6, 0x77, 0x11, 0x33, 0x6c +}; + +static uint16_t crc16h1021_expected_crc[] = +{ + 0x84c0, 0xd374, 0x2023, 0xb8f9, 0xf53f, 0x0745, 0x1d0f +}; + +static uint16_t crc16h8005_expected_crc[] = +{ + 0x0000, 0xc2e1, 0x0be3, 0x6ccf, 0xae98, 0xe24e, 0x9401 +}; + +static uint32_t crc32h04c11db7_expected_crc[] = +{ + 0x2144df1c, 0x24ab9d77, 0xb6c9b287, 0x32a06212, + 0xb0ae863d, 0x9cdea29b, 0xffffffff +}; + +static uint32_t crc32hf4acfb13_expected_crc[] = +{ + 0x6fb32240, 0x4f721a25, 0x20662df8, 0x9bd7996e, + 0xa65a343d, 0xee688a78, 0xffffffff +}; + +static uint64_t crc64emac_expected_crc[] = +{ + 0xf4a586351e1b9f4b, 0x319c27668164f1c6, + 0x54c5d0f7667c1575, 0xa63822be7e0704e6, + 0x701eceb219a8e5d5, 0x5faa96a9b59f3e4e, + 0xffffffff00000000 +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: test_case_crc8h1d + ****************************************************************************/ + +static void test_case_crc8h1d(void **state) +{ + uint8_t index; + uint8_t crc8_value; + + for (index = 0; + index < sizeof(crc_test_data) / sizeof(crc_test_data[0]); + index++) + { + crc8_value = crc8h1d(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_equal(crc8_value, crc8h1d_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + crc8_value = crc8h1d(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_not_equal(crc8_value, crc8h1d_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + } +} + +/**************************************************************************** + * Name: test_case_crc8h2f + ****************************************************************************/ + +static void test_case_crc8h2f(void **state) +{ + uint8_t index; + uint8_t crc8_value; + + for (index = 0; + index < sizeof(crc_test_data) / sizeof(crc_test_data[0]); + index++) + { + crc8_value = crc8h2f(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_equal(crc8_value, crc8h2f_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + crc8_value = crc8h2f(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_not_equal(crc8_value, crc8h2f_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + } +} + +/**************************************************************************** + * Name: test_case_crc16h1021 + ****************************************************************************/ + +static void test_case_crc16h1021(void **state) +{ + uint8_t index; + uint16_t crc16_value; + + for (index = 0; + index < sizeof(crc_test_data) / sizeof(crc_test_data[0]); + index++) + { + crc16_value = crc16h1021(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_equal(crc16_value, crc16h1021_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + crc16_value = crc16h1021(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_not_equal(crc16_value, crc16h1021_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + } +} + +/**************************************************************************** + * Name: test_case_crc16h8005 + ****************************************************************************/ + +static void test_case_crc16h8005(void **state) +{ + uint8_t index; + uint16_t crc16_value; + + for (index = 0; + index < sizeof(crc_test_data) / sizeof(crc_test_data[0]); + index++) + { + crc16_value = crc16h8005(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_equal(crc16_value, crc16h8005_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + crc16_value = crc16h8005(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_not_equal(crc16_value, crc16h8005_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + } +} + +/**************************************************************************** + * Name: test_case_crc32h04c11db7 + ****************************************************************************/ + +static void test_case_crc32h04c11db7(void **state) +{ + uint8_t index; + uint32_t crc32_value; + + for (index = 0; + index < sizeof(crc_test_data) / sizeof(crc_test_data[0]); + index++) + { + crc32_value = crc32h04c11db7(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_equal(crc32_value, crc32h04c11db7_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + crc32_value = crc32h04c11db7(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_not_equal(crc32_value, crc32h04c11db7_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + } +} + +/**************************************************************************** + * Name: test_case_crc32hf4acfb13 + ****************************************************************************/ + +static void test_case_crc32hf4acfb13(void **state) +{ + uint8_t index; + uint32_t crc32_value; + + for (index = 0; + index < sizeof(crc_test_data) / sizeof(crc_test_data[0]); + index++) + { + crc32_value = crc32hf4acfb13(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_equal(crc32_value, crc32hf4acfb13_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + crc32_value = crc32hf4acfb13(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_not_equal(crc32_value, crc32hf4acfb13_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + } +} + +/**************************************************************************** + * Name: test_case_crc64emac + ****************************************************************************/ + +static void test_case_crc64emac(void **state) +{ + uint8_t index; + uint64_t crc64_value; + + for (index = 0; + index < sizeof(crc_test_data) / sizeof(crc_test_data[0]); + index++) + { + crc64_value = crc64emac(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_equal(crc64_value, crc64emac_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + crc64_value = crc64emac(crc_test_data[index].data, + crc_test_data[index].length); + assert_int_not_equal(crc64_value, crc64emac_expected_crc[index]); + + crc_test_data[index].data[0] ^= 0xff; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * crctest_main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + const struct CMUnitTest tests[] = + { + cmocka_unit_test(test_case_crc8h1d), + cmocka_unit_test(test_case_crc8h2f), + cmocka_unit_test(test_case_crc16h1021), + cmocka_unit_test(test_case_crc16h8005), + cmocka_unit_test(test_case_crc32h04c11db7), + cmocka_unit_test(test_case_crc32hf4acfb13), + cmocka_unit_test(test_case_crc64emac), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} From 122a4a6f4ea4d4912f8c2041e837fb238beae7ae Mon Sep 17 00:00:00 2001 From: yukangzhi Date: Mon, 17 Mar 2025 14:07:13 +0800 Subject: [PATCH 161/568] apps/examples/popen: Modify kconfig file This test depends on !DISABLE_POSIX_TIMERS. arm-none-eabi/bin/ld: apps/examples/popen/libapps_popen.a(popen_main.c.obj): in function `popen_main': apps/examples/popen/popen_main.c:62:(.text.popen_main+0x1c): undefined reference to `timer_create' Signed-off-by: yukangzhi --- examples/popen/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/popen/Kconfig b/examples/popen/Kconfig index 3b2eba29e..2f571d121 100644 --- a/examples/popen/Kconfig +++ b/examples/popen/Kconfig @@ -7,6 +7,7 @@ config EXAMPLES_POPEN tristate "popen() example" default n depends on SYSTEM_POPEN + depends on !DISABLE_POSIX_TIMERS ---help--- Enable the popen() example From 094b0f235a6ae2f857570e72d187df970fc424ba Mon Sep 17 00:00:00 2001 From: wangzhi16 Date: Thu, 18 Sep 2025 16:21:20 +0800 Subject: [PATCH 162/568] test/mutex: fix mutex testcases. Multiple threads should use the same lock for resource protection. Signed-off-by: wangzhi16 --- .../kernel/sched/cases/api_pthread_test_007.c | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/testing/testsuites/kernel/sched/cases/api_pthread_test_007.c b/testing/testsuites/kernel/sched/cases/api_pthread_test_007.c index 3a50a5f94..46fac1a00 100644 --- a/testing/testsuites/kernel/sched/cases/api_pthread_test_007.c +++ b/testing/testsuites/kernel/sched/cases/api_pthread_test_007.c @@ -40,6 +40,16 @@ #include #include "SchedTest.h" +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +struct resource_s +{ + pthread_mutex_t mutex; + int run_flag; +}; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -50,13 +60,14 @@ static void *schedpthread07threadroutine(void *arg) { + struct resource_s *resource = (struct resource_s *)arg; int i; - pthread_mutex_t schedpthreadtest07_mutex = PTHREAD_MUTEX_INITIALIZER; + for (i = 0; i < 100; i++) { - pthread_mutex_lock(&schedpthreadtest07_mutex); - (*((int *)arg))++; - pthread_mutex_unlock(&schedpthreadtest07_mutex); + pthread_mutex_lock(&resource->mutex); + resource->run_flag++; + pthread_mutex_unlock(&resource->mutex); } return NULL; @@ -74,16 +85,20 @@ void test_nuttx_sched_pthread07(FAR void **state) { int res; pthread_t pt_1, pt_2, pt_3; - int run_flag = 0; + struct resource_s resource = + { + .mutex = PTHREAD_MUTEX_INITIALIZER, + .run_flag = 0 + }; res = pthread_create(&pt_1, NULL, (void *)schedpthread07threadroutine, - &run_flag); + &resource); assert_int_equal(res, OK); res = pthread_create(&pt_2, NULL, (void *)schedpthread07threadroutine, - &run_flag); + &resource); assert_int_equal(res, OK); res = pthread_create(&pt_3, NULL, (void *)schedpthread07threadroutine, - &run_flag); + &resource); assert_int_equal(res, OK); pthread_join(pt_1, NULL); @@ -91,5 +106,5 @@ void test_nuttx_sched_pthread07(FAR void **state) pthread_join(pt_3, NULL); sleep(5); - assert_int_equal(run_flag, 300); + assert_int_equal(resource.run_flag, 300); } From 5c6d646d7656b6d3cd4192771e69b22fdbd25c0f Mon Sep 17 00:00:00 2001 From: wangzhi16 Date: Wed, 7 May 2025 21:03:08 +0800 Subject: [PATCH 163/568] testing/fs: add testcase to test the stability of memfd. Supplement ostest test cases. Signed-off-by: wangzhi16 --- testing/fs/memfd/CMakeLists.txt | 23 +++++++++ testing/fs/memfd/Kconfig | 11 +++++ testing/fs/memfd/Make.defs | 23 +++++++++ testing/fs/memfd/Makefile | 29 +++++++++++ testing/fs/memfd/memfd_test.c | 87 +++++++++++++++++++++++++++++++++ 5 files changed, 173 insertions(+) create mode 100644 testing/fs/memfd/CMakeLists.txt create mode 100644 testing/fs/memfd/Kconfig create mode 100644 testing/fs/memfd/Make.defs create mode 100644 testing/fs/memfd/Makefile create mode 100644 testing/fs/memfd/memfd_test.c diff --git a/testing/fs/memfd/CMakeLists.txt b/testing/fs/memfd/CMakeLists.txt new file mode 100644 index 000000000..bde183129 --- /dev/null +++ b/testing/fs/memfd/CMakeLists.txt @@ -0,0 +1,23 @@ +# ############################################################################## +# apps/testing/fs/memfd/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_TESTING_MEMFD) + nuttx_add_application(NAME memfd SRCS memfd_test.c) +endif() diff --git a/testing/fs/memfd/Kconfig b/testing/fs/memfd/Kconfig new file mode 100644 index 000000000..464537bbf --- /dev/null +++ b/testing/fs/memfd/Kconfig @@ -0,0 +1,11 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config TESTING_MEMFD + bool "Testing the stability of memfd" + depends on !LIBC_MEMFD_ERROR && MM_KASAN + default n + ---help--- + Enable to test the stability of memfd diff --git a/testing/fs/memfd/Make.defs b/testing/fs/memfd/Make.defs new file mode 100644 index 000000000..286699d9e --- /dev/null +++ b/testing/fs/memfd/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/testing/fs/memfd/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_TESTING_MEMFD),) +CONFIGURED_APPS += $(APPDIR)/testing/fs/memfd +endif diff --git a/testing/fs/memfd/Makefile b/testing/fs/memfd/Makefile new file mode 100644 index 000000000..0080d0f48 --- /dev/null +++ b/testing/fs/memfd/Makefile @@ -0,0 +1,29 @@ +############################################################################ +# apps/testing/fs/memfd/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +PROGNAME = memfd_test +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) + +MAINSRC = memfd_test.c + +include $(APPDIR)/Application.mk diff --git a/testing/fs/memfd/memfd_test.c b/testing/fs/memfd/memfd_test.c new file mode 100644 index 000000000..1e72915bf --- /dev/null +++ b/testing/fs/memfd/memfd_test.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * apps/testing/fs/memfd/memfd_test.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + + #define BUFFER_SIZE 8 + #define THREAD_NUM 50 + #define LOOP_NUM 1000 + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void *func(FAR void *arg) +{ + void *buf; + int size = BUFFER_SIZE; + int i; + int memfd; + + for (i = 0; i < LOOP_NUM; i++) + { + memfd = memfd_create("optee", O_CREAT | O_CLOEXEC); + ftruncate(memfd, size); + buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0); + close(memfd); + + *((int *)buf) = 0xdeadbeef; + usleep(10); + *((int *)buf) = 0xdeadbeef; + + munmap(buf, size); + } + + printf("thread %d test pass!\n", pthread_self()); + return NULL; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + pid_t pid[THREAD_NUM]; + int i; + + for (i = 0; i < THREAD_NUM; i++) + { + pthread_create(&pid[i], NULL, func, NULL); + } + + for (i = 0; i < THREAD_NUM; i++) + { + pthread_join(pid[i], NULL); + } + + return 0; +} From f16a45a854fa5cdaab0cfe77921d73bf301caf47 Mon Sep 17 00:00:00 2001 From: wangzhi16 Date: Wed, 28 May 2025 22:34:35 +0800 Subject: [PATCH 164/568] examples/pipe: bugfix testcase of fifo There are three bug in fifo testcase. 1. line 211 and line 295 should be nbytes not ret. 2. coverity report error: CID 1667262: (#4 of 11): Double close (USE_AFTER_FREE) 11. double_close: Calling close(int) will close the handle fd that has already been closed. [Note: The source code implementation of this function has been overwritten by the built-in model.] Double close will ocurr when line 234 is true and goto line 341, close again! Now, Using the previous code logic, Use a tid and an errout_with_null_thread to avoid uninitialized problems. 3. since line 295 is used ret not nbytes, error not expose before. When the end of read and write are opened, end of write will write successfully even if end of read not read. Signed-off-by: wangzhi16 --- examples/pipe/interlock_test.c | 57 ++++++++++++++++------------------ 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/examples/pipe/interlock_test.c b/examples/pipe/interlock_test.c index 6be9b6ec4..cb2985800 100644 --- a/examples/pipe/interlock_test.c +++ b/examples/pipe/interlock_test.c @@ -150,8 +150,7 @@ static void *null_writer(pthread_addr_t pvarg) int interlock_test(void) { - pthread_t readerid; - pthread_t writerid; + pthread_t tid; void *value; char data[16]; ssize_t nbytes; @@ -171,7 +170,7 @@ int interlock_test(void) /* Start the null_writer thread */ printf("interlock_test: Starting null_writer thread\n"); - ret = pthread_create(&writerid, NULL, null_writer, NULL); + ret = pthread_create(&tid, NULL, null_writer, NULL); if (ret != 0) { fprintf(stderr, \ @@ -194,7 +193,7 @@ int interlock_test(void) "errno=%d\n", FIFO_PATH2, errno); ret = 3; - goto errout_with_null_writer_thread; + goto errout_with_null_thread; } /* Attempt to read one byte from the FIFO. This should return end-of-file @@ -208,15 +207,15 @@ int interlock_test(void) fprintf(stderr, \ "interlock_test: read failed, errno=%d\n", errno); ret = 4; - goto errout_with_null_writer_thread; + goto errout_with_file; } - else if (ret != 0) + else if (nbytes != 0) { fprintf(stderr, \ "interlock_test: Read %ld bytes of data -- aborting: %d\n", (long)nbytes, errno); ret = 5; - goto errout_with_null_writer_thread; + goto errout_with_file; } printf("interlock_test: read returned\n"); @@ -234,7 +233,7 @@ int interlock_test(void) /* Wait for null_writer thread to complete */ printf("interlock_test: Waiting for null_writer thread\n"); - ret = pthread_join(writerid, &value); + ret = pthread_join(tid, &value); if (ret != 0) { fprintf(stderr, \ @@ -255,7 +254,7 @@ int interlock_test(void) /* Start the null_reader thread */ printf("interlock_test: Starting null_reader thread\n"); - ret = pthread_create(&readerid, NULL, null_reader, NULL); + ret = pthread_create(&tid, NULL, null_reader, NULL); if (ret != 0) { fprintf(stderr, \ @@ -278,29 +277,26 @@ int interlock_test(void) "errno=%d\n", FIFO_PATH2, errno); ret = 9; - goto errout_with_null_reader_thread; + goto errout_with_null_thread; } - /* Attempt to write one byte from the FIFO. This should return 0 bytes - * written because the null_reader closes the FIFO. + /* Attempt to write one byte from the FIFO. This should return n bytes + * written since the null_reader has opened the FIFO. */ printf("interlock_test: Writing to %s\n", FIFO_PATH2); nbytes = write(fd, data, 16); - if (nbytes < 0) + if (nbytes <= 0) { fprintf(stderr, \ "interlock_test: write failed, errno=%d\n", errno); ret = 10; - goto errout_with_null_reader_thread; + goto errout_with_file; } - else if (ret != 0) + else { fprintf(stderr, \ - "interlock_test: Wrote %ld bytes of data -- aborting: %d\n", - (long)nbytes, errno); - ret = 11; - goto errout_with_null_reader_thread; + "interlock_test: Wrote %ld bytes of data\n", (long)nbytes); } printf("interlock_test: write returned\n"); @@ -318,7 +314,7 @@ int interlock_test(void) /* Wait for null_reader thread to complete */ printf("interlock_test: Waiting for null_reader thread\n"); - ret = pthread_join(readerid, &value); + ret = pthread_join(tid, &value); if (ret != 0) { fprintf(stderr, \ @@ -339,21 +335,20 @@ int interlock_test(void) ret = 0; goto errout_with_fifo; -errout_with_null_reader_thread: - pthread_detach(readerid); - pthread_cancel(readerid); - -errout_with_null_writer_thread: - pthread_detach(writerid); - pthread_cancel(writerid); - -errout_with_fifo: - - if (fd != -1 && close(fd) != 0) +errout_with_file: + if (close(fd) != 0) { fprintf(stderr, "interlock_test: close failed: %d\n", errno); } +errout_with_null_thread: + pthread_detach(tid); + pthread_cancel(tid); + +errout_with_fifo: + + /* Close the file */ + ret = remove(FIFO_PATH2); if (ret != 0) { From b72f7997a35cb959ff35b7b1c03e5053953752e6 Mon Sep 17 00:00:00 2001 From: hongfengchen Date: Tue, 10 Jun 2025 15:03:17 +0800 Subject: [PATCH 165/568] system/popen: close newfd correctly Fixes a bug where newfd is not properly closed when newfd[0] equals newfd[1]. This can cause file descriptor leaks in certain edge cases where the read and write sides of the pipe are duplicated. Signed-off-by: hongfengchen --- system/popen/popen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/popen/popen.c b/system/popen/popen.c index 5da6cadf1..d9286c959 100644 --- a/system/popen/popen.c +++ b/system/popen/popen.c @@ -312,7 +312,7 @@ FILE *popen(FAR const char *command, FAR const char *mode) close(newfd[0]); - if (rw) + if (rw && newfd[0] != newfd[1]) { close(newfd[1]); } From 19dcc896d7f88392a891fb415753d3e9c905fdf6 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Wed, 12 Feb 2025 19:16:09 +0800 Subject: [PATCH 166/568] sched/tcb: add a reference count to the TCB to prevent it from being deleted. To replace the large lock with smaller ones and reduce the large locks related to the TCB, in many scenarios, we only need to ensure that the TCB won't be released instead of locking, thus reducing the possibility of lock recursion. Signed-off-by: hujun5 --- .codespell-ignore-lines | 4 ++++ crypto/controlse/controlse_main.cxx | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.codespell-ignore-lines b/.codespell-ignore-lines index 75a07676e..4b6f55c66 100644 --- a/.codespell-ignore-lines +++ b/.codespell-ignore-lines @@ -1,2 +1,6 @@ mynewt-nimble/nimble/host/services/ans/src/ble_svc_ans.c mynewt-nimble/nimble/host/services/ans/include +#include "crypto/controlse/ccertificate.hxx" + object = new Controlse::CCertificate( + Controlse::CCertificate cert(se, settings->key_id); + auto certificate = Controlse::CCertificate( diff --git a/crypto/controlse/controlse_main.cxx b/crypto/controlse/controlse_main.cxx index 8c0f07cbc..a2b5dddef 100644 --- a/crypto/controlse/controlse_main.cxx +++ b/crypto/controlse/controlse_main.cxx @@ -701,8 +701,12 @@ int main(int argc, FAR char *argv[]) #ifdef CONFIG_STACK_COLORATION FAR struct tcb_s *tcb; tcb = nxsched_get_tcb(getpid()); - fprintf(stderr, "\nStack used: %zu / %zu\n", up_check_tcbstack(tcb), - tcb->adj_stack_size); + if (tcb != NULL) + { + fprintf(stderr, "\nStack used: %zu / %zu\n", up_check_tcbstack(tcb), + tcb->adj_stack_size); + nxsched_put_tcb(tcb); + } #else fprintf(stderr, "\nStack used: unknown" " (STACK_COLORATION must be enabled)\n"); From 715da6bde6e4e6f4176f29a27aecc5d065514dcf Mon Sep 17 00:00:00 2001 From: fangpeina Date: Thu, 25 Dec 2025 01:04:40 +0800 Subject: [PATCH 167/568] system/ymodem: fix send err when partial write Fix buffer offset calculation in ymodem_send_buffer() to correctly handle partial writes by advancing the buffer pointer and adjusting the remaining size on each retry. Signed-off-by: fangpeina --- system/ymodem/ymodem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/ymodem/ymodem.c b/system/ymodem/ymodem.c index 79c131f37..354f09962 100644 --- a/system/ymodem/ymodem.c +++ b/system/ymodem/ymodem.c @@ -98,7 +98,7 @@ static int ymodem_send_buffer(FAR struct ymodem_ctx_s *ctx, ymodem_debug("send buffer data, write size is %zu\n", size); while (i < size) { - ssize_t ret = write(ctx->sendfd, buf, size); + ssize_t ret = write(ctx->sendfd, buf + i, size - i); if (ret >= 0) { ymodem_debug("send buffer data, size %zd\n", ret); From f09d0b2e0985162c5dff5ac0ecafd88fe44c0fec Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Thu, 22 Jan 2026 11:33:22 +0100 Subject: [PATCH 168/568] apps: Fix minor issues for latest toolchains - crypto/mbedtls: Add -Wno-cpp flag to suppress warnings - interpreters/quickjs: Add flags to suppress warnings - lte/alt1250: Fix spelling issues in comments - system/dd: Add missing includes for modern compilers - system/zlib: Add -Wno-cpp flag - testing/cxx: Include missing algorithm header Signed-off-by: Bartosz --- crypto/mbedtls/Makefile | 1 + interpreters/quickjs/Makefile | 2 ++ lte/alt1250/alt1250_devif.c | 6 +++--- lte/alt1250/alt1250_devif.h | 4 ++-- system/dd/dd_main.c | 16 ++++++++++++---- system/zlib/Makefile | 1 + testing/cxx/cxxtest/cxxtest_main.cxx | 1 + 7 files changed, 22 insertions(+), 9 deletions(-) diff --git a/crypto/mbedtls/Makefile b/crypto/mbedtls/Makefile index 330384111..241e076ea 100644 --- a/crypto/mbedtls/Makefile +++ b/crypto/mbedtls/Makefile @@ -48,6 +48,7 @@ MBEDTLS_FRAMEWORK_UNPACKNAME = mbedtls-framework CFLAGS += ${DEFINE_PREFIX}unix mbedtls/library/bignum.c_CFLAGS += -fno-lto +mbedtls/library/ctr_drbg.c_CFLAGS += -Wno-array-bounds # Build break on Assemble compiler if -fno-omit-frame-pointer and -O3 enabled at same time # {standard input}: Assembler messages: diff --git a/interpreters/quickjs/Makefile b/interpreters/quickjs/Makefile index 7b84a08bb..457cdee35 100644 --- a/interpreters/quickjs/Makefile +++ b/interpreters/quickjs/Makefile @@ -35,6 +35,8 @@ VERSION=\"$(QUICKJS_VERSION)\" CFLAGS += -Dmp_add=qjs_mp_add -Dmp_sub=qjs_mp_sub -Dmp_mul=qjs_mp_mul CFLAGS += -DCONFIG_VERSION=$(VERSION) -Wno-shadow CFLAGS += -Wno-array-bounds -I$(QUICKJS_UNPACK) +CFLAGS += -Wno-strict-prototypes -Wno-unused-variable +CFLAGS += -Wno-unused-but-set-variable CFLAGS += -D__linux__ -include alloca.h CFLAGS += -Wno-incompatible-pointer-types CFLAGS += -Wno-implicit-function-declaration diff --git a/lte/alt1250/alt1250_devif.c b/lte/alt1250/alt1250_devif.c index a742938fb..39c490667 100644 --- a/lte/alt1250/alt1250_devif.c +++ b/lte/alt1250/alt1250_devif.c @@ -123,7 +123,7 @@ int altdevice_send_command(FAR struct alt1250_s *dev, int fd, } else { - /* In case of send successed */ + /* In case of send succeeded */ ret = container->outparam ? REP_NO_ACK_WOFREE : REP_NO_ACK; } @@ -173,7 +173,7 @@ int altdevice_seteventbuff(int fd, FAR struct alt_evtbuffer_s *buffer) ****************************************************************************/ int altdevice_getevent(int fd, FAR uint64_t *evtbitmap, - FAR struct alt_container_s **replys) + FAR struct alt_container_s **replies) { int ret = -EIO; struct alt_readdata_s dat; @@ -183,7 +183,7 @@ int altdevice_getevent(int fd, FAR uint64_t *evtbitmap, { ret = OK; *evtbitmap = dat.evtbitmap; - *replys = dat.head; + *replies = dat.head; } return ret; diff --git a/lte/alt1250/alt1250_devif.h b/lte/alt1250/alt1250_devif.h index c537754df..01c689625 100644 --- a/lte/alt1250/alt1250_devif.h +++ b/lte/alt1250/alt1250_devif.h @@ -20,7 +20,7 @@ * ****************************************************************************/ -#ifndef __APSS_LTE_ALT1250_ALT1250_DEVIF_H +#ifndef __APPS_LTE_ALT1250_ALT1250_DEVIF_H #define __APPS_LTE_ALT1250_ALT1250_DEVIF_H /**************************************************************************** @@ -48,7 +48,7 @@ int altdevice_send_command(FAR struct alt1250_s *dev, int fd, int altdevice_powercontrol(int fd, uint32_t cmd); int altdevice_seteventbuff(int fd, FAR struct alt_evtbuffer_s *buffers); int altdevice_getevent(int fd, FAR uint64_t *evtbitmap, - FAR struct alt_container_s **replys); + FAR struct alt_container_s **replies); void altdevice_reset(int fd); #ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE int altdevice_powerresponse(int fd, uint32_t cmd, int resp); diff --git a/system/dd/dd_main.c b/system/dd/dd_main.c index f08041836..9be5de7ac 100644 --- a/system/dd/dd_main.c +++ b/system/dd/dd_main.c @@ -62,10 +62,18 @@ #define CONFIG_SYSTEM_DD_PROGNAME "dd" #endif #if !defined(__NuttX__) -#define FAR -#define NSEC_PER_USEC 1000 -#define USEC_PER_SEC 1000000 -#define NSEC_PER_SEC 1000000000 +# ifndef FAR +# define FAR +# endif +# ifndef NSEC_PER_USEC +# define NSEC_PER_USEC 1000 +# endif +# ifndef USEC_PER_SEC +# define USEC_PER_SEC 1000000 +# endif +# ifndef NSEC_PER_SEC +# define NSEC_PER_SEC 1000000000 +# endif #endif #define g_dd CONFIG_SYSTEM_DD_PROGNAME diff --git a/system/zlib/Makefile b/system/zlib/Makefile index 7c978a552..43a09bb50 100644 --- a/system/zlib/Makefile +++ b/system/zlib/Makefile @@ -31,6 +31,7 @@ CSRCS += zlib/contrib/minizip/zip.c CFLAGS += -Dunix -Wno-shadow -Wno-strict-prototypes -Wno-undef CFLAGS += ${INCDIR_PREFIX}zlib +zlib/test/infcover.c_CFLAGS += -Wno-format ZLIB_ZIP = zlib13.zip ZLIB_SRC = zlib diff --git a/testing/cxx/cxxtest/cxxtest_main.cxx b/testing/cxx/cxxtest/cxxtest_main.cxx index f33da9eed..90663f958 100644 --- a/testing/cxx/cxxtest/cxxtest_main.cxx +++ b/testing/cxx/cxxtest/cxxtest_main.cxx @@ -26,6 +26,7 @@ #include +#include #include #include #include From 183deb66e9b6b39ac2b90219ebbeaacb53109f2b Mon Sep 17 00:00:00 2001 From: likun17 Date: Sat, 14 Sep 2024 14:11:46 +0800 Subject: [PATCH 169/568] system/uorb: uorb_listener adds new features. add get sensor device information based on topic. Signed-off-by: likun17 --- system/uorb/listener.c | 70 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/system/uorb/listener.c b/system/uorb/listener.c index b9013a06a..5185b968e 100644 --- a/system/uorb/listener.c +++ b/system/uorb/listener.c @@ -138,6 +138,7 @@ listener [arguments...]\n\ \t[-t ] Time of listener, in seconds, default: 5\n\ \t[-T ] Top, continuously print updating objects\n\ \t[-l ] Top only execute once.\n\ +\t[-i ] Get sensor device information based on topic.\n\ "); } @@ -530,6 +531,61 @@ static int listener_print(FAR const struct orb_metadata *meta, int fd) return ret; } +/**************************************************************************** + * Name: listener_print_info + * + * Description: + * Print sensor device information. + * + * Input Parameters: + * objlist topic object list. + * + * Returned Value: + * void + ****************************************************************************/ + +static void listener_print_info(FAR const struct listen_list_s *objlist) +{ + FAR struct listen_object_s *tmp; + orb_info_t info; + int ret; + int fd; + + SLIST_FOREACH(tmp, objlist, node) + { + fd = orb_subscribe_multi(tmp->object.meta, tmp->object.instance); + if (fd < 0) + { + continue; + } + + ret = orb_get_info(fd, &info); + orb_unsubscribe(fd); + uorbinfo_raw("Topic [%s%d] info:", tmp->object.meta->o_name, + tmp->object.instance); + if (ret < 0) + { + uorbinfo_raw("\t NULL"); + continue; + } + + uorbinfo_raw("\tname:%s" \ + "\n\tvendor:%s" \ + "\n\tversion:%" PRIu32 "" \ + "\n\tpower:%f" \ + "\n\tmax_range:%f" \ + "\n\tresolution:%f" \ + "\n\tmin_delay:%" PRId32 "" \ + "\n\tmax_delay:%" PRId32 "" \ + "\n\tfifo_reserved_event_count:%" PRIu32 ""\ + "\n\tfifo_max_event_count:%" PRIu32 "\n", + info.name, info.vendor, info.version, info.power, + info.max_range, info.resolution, info.min_delay, + info.max_delay, info.fifo_reserved_event_count, + info.fifo_max_event_count); + } +} + /**************************************************************************** * Name: listener_record * @@ -854,6 +910,7 @@ int main(int argc, FAR char *argv[]) int nb_msgs = 0; int timeout = 5; bool top = false; + bool info = false; bool record = false; bool only_once = false; FAR char *filter = NULL; @@ -868,7 +925,7 @@ int main(int argc, FAR char *argv[]) /* Pasrse Argument */ - while ((ch = getopt(argc, argv, "r:b:n:t:Tflh")) != EOF) + while ((ch = getopt(argc, argv, "r:b:n:t:Tflhi")) != EOF) { switch (ch) { @@ -918,6 +975,10 @@ int main(int argc, FAR char *argv[]) only_once = true; break; + case 'i': + info = true; + break; + case 'h': default: goto error; @@ -938,6 +999,12 @@ int main(int argc, FAR char *argv[]) return 0; } + if (info) + { + listener_print_info(&objlist); + goto exit; + } + if (top) { listener_top(&objlist, filter, only_once); @@ -956,6 +1023,7 @@ int main(int argc, FAR char *argv[]) nb_msgs, timeout, record); } +exit: listener_delete_object_list(&objlist); return 0; From ada12ce175de9b2e9154d110c0559826bdd2a991 Mon Sep 17 00:00:00 2001 From: likun17 Date: Thu, 19 Sep 2024 10:37:36 +0800 Subject: [PATCH 170/568] system/uorb: uorb_listener adds new features. uorb/listener.c: Added flush function. aurora:/ # uorb_listener -f sensor_accel_uncal,sensor_mag_uncal,sensor_aaa Waited for 5 seconds without flush complete event. Giving up. err:25 Result: Topic [sensor_mag_uncal0] flush: FAILURE. [-1] Topic [sensor_accel_uncal0] flush: SUCCESS. Total number of flush topics: 1/2 Signed-off-by: likun17 --- system/uorb/listener.c | 151 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 4 deletions(-) diff --git a/system/uorb/listener.c b/system/uorb/listener.c index 5185b968e..0795dcb2f 100644 --- a/system/uorb/listener.c +++ b/system/uorb/listener.c @@ -130,7 +130,7 @@ listener [arguments...]\n\ Commands:\n\ \t Topic name. Multi name are separated by ','\n\ \t[-h ] Listener commands help\n\ -\t[-f ] Record uorb data to file\n\ +\t[-s ] Record uorb data to file\n\ \t[-n ] Number of messages, default: 0\n\ \t[-r ] Subscription rate (unlimited if 0), default: 0\n\ \t[-b ] Subscription maximum report latency in us(unlimited if 0),\n\ @@ -139,6 +139,7 @@ listener [arguments...]\n\ \t[-T ] Top, continuously print updating objects\n\ \t[-l ] Top only execute once.\n\ \t[-i ] Get sensor device information based on topic.\n\ +\t[-f ] Flush sensor drive data.\n\ "); } @@ -531,6 +532,137 @@ static int listener_print(FAR const struct orb_metadata *meta, int fd) return ret; } +/**************************************************************************** + * Name: listener_flush_topic + * + * Description: + * Flush sensor device. + * + * Input Parameters: + * objlist Topic object list. + * nb_objects Length of objects list. + * timeout Maximum poll waiting time(microsecond). + * + * Returned Value: + * void + ****************************************************************************/ + +static void listener_flush_topic(FAR const struct listen_list_s *objlist, + int nb_objects, int timeout) +{ + FAR struct listen_object_s *tmp; + FAR struct pollfd *fds; + unsigned int events; + FAR int8_t *result; + int nb_flush = 0; + int i = 0; + int ret; + + fds = calloc(nb_objects, sizeof(struct pollfd)); + if (!fds) + { + return; + } + + result = calloc(nb_objects, sizeof(int8_t)); + if (!result) + { + free(fds); + return; + } + + /* Prepare pollfd for all flush objects */ + + SLIST_FOREACH(tmp, objlist, node) + { + int fd; + + fd = orb_subscribe_multi(tmp->object.meta, tmp->object.instance); + if (fd < 0) + { + fds[i].fd = -1; + fds[i].events = 0; + } + else + { + fds[i].fd = fd; + fds[i].events = POLLPRI; + i++; + } + } + + i = 0; + SLIST_FOREACH(tmp, objlist, node) + { + ret = orb_flush(fds[i].fd); + if (ret < 0) + { + result[i] = ret; + } + else + { + nb_flush++; + } + + i++; + } + + while (nb_flush && !g_should_exit) + { + if (poll(&fds[0], nb_objects, timeout * 1000) > 0) + { + i = 0; + SLIST_FOREACH(tmp, objlist, node) + { + if (fds[i].revents & POLLPRI) + { + ret = orb_get_events(fds[i].fd, &events); + if (ret < 0) + { + result[i] = ret; + } + else if (events & SENSOR_EVENT_FLUSH_COMPLETE) + { + nb_flush--; + } + } + + i++; + } + } + else if (errno != EINTR) + { + uorbinfo_raw("Waited for %d seconds without flush complete event. " + "Giving up. err:%d\n", timeout, errno); + break; + } + } + + i = 0; + uorbinfo_raw("Result:"); + SLIST_FOREACH(tmp, objlist, node) + { + if (result[i] == 0) + { + uorbinfo_raw("\tTopic [%s%d] flush: SUCCESS.", + tmp->object.meta->o_name, tmp->object.instance); + } + else + { + uorbinfo_raw("\tTopic [%s%d] flush: FAILURE. [%d]", + tmp->object.meta->o_name, tmp->object.instance, + result[i]); + } + + orb_unsubscribe(fds[i].fd); + i++; + } + + uorbinfo_raw("Total number of flush topics: %d", nb_objects); + free(fds); + free(result); +} + /**************************************************************************** * Name: listener_print_info * @@ -632,7 +764,7 @@ static int listener_record(FAR const struct orb_metadata *meta, int fd, * topic_rate Subscribe frequency. * topic_latency Subscribe report latency. * nb_msgs Subscribe amount of messages. - * timeout Maximum poll waiting time , ms. + * timeout Maximum poll waiting time(microseconds). * * Returned Value: * None @@ -911,6 +1043,7 @@ int main(int argc, FAR char *argv[]) int timeout = 5; bool top = false; bool info = false; + bool flush = false; bool record = false; bool only_once = false; FAR char *filter = NULL; @@ -925,7 +1058,7 @@ int main(int argc, FAR char *argv[]) /* Pasrse Argument */ - while ((ch = getopt(argc, argv, "r:b:n:t:Tflhi")) != EOF) + while ((ch = getopt(argc, argv, "r:b:n:t:Tfslhi")) != EOF) { switch (ch) { @@ -962,11 +1095,15 @@ int main(int argc, FAR char *argv[]) break; #ifdef CONFIG_DEBUG_UORB - case 'f': + case 's': record = true; break; #endif + case 'f': + flush = true; + break; + case 'T': top = true; break; @@ -999,6 +1136,12 @@ int main(int argc, FAR char *argv[]) return 0; } + if (flush) + { + listener_flush_topic(&objlist, ret, timeout); + goto exit; + } + if (info) { listener_print_info(&objlist); From a454cf4d9428088df0c8d68706efc341169ad212 Mon Sep 17 00:00:00 2001 From: likun17 Date: Tue, 4 Mar 2025 17:16:49 +0800 Subject: [PATCH 171/568] system/uorb: uorb_listener flush functionality optimization. uorb/listener:Added flush failure prompt information. Signed-off-by: likun17 --- system/uorb/listener.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/system/uorb/listener.c b/system/uorb/listener.c index 0795dcb2f..8cd63b098 100644 --- a/system/uorb/listener.c +++ b/system/uorb/listener.c @@ -559,13 +559,13 @@ static void listener_flush_topic(FAR const struct listen_list_s *objlist, int ret; fds = calloc(nb_objects, sizeof(struct pollfd)); - if (!fds) + if (fds == NULL) { return; } result = calloc(nb_objects, sizeof(int8_t)); - if (!result) + if (result == NULL) { free(fds); return; @@ -598,6 +598,8 @@ static void listener_flush_topic(FAR const struct listen_list_s *objlist, if (ret < 0) { result[i] = ret; + uorbinfo_raw("topic [%s%d] call flush failed! return:%d\n", + tmp->object.meta->o_name, tmp->object.instance, ret); } else { From 197401975a2fe985a8f5c2740a6004b6e6329ee4 Mon Sep 17 00:00:00 2001 From: guohao15 Date: Tue, 17 Dec 2024 11:08:19 +0800 Subject: [PATCH 172/568] mtdconfig: support ram_mtdconfig device && lomtdconfig device For nvs test in qemu Signed-off-by: guohao15 --- nshlib/nsh_command.c | 6 ++++ nshlib/nsh_fscmds.c | 74 +++++++++++++++++++++----------------------- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index af0084218..cace8eeac 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -322,9 +322,15 @@ static const struct cmdmap_s g_cmdmap[] = #ifndef CONFIG_DISABLE_MOUNTPOINT # if defined(CONFIG_MTD_LOOP) && !defined(CONFIG_NSH_DISABLE_LOMTD) +# ifdef CONFIG_MTD_CONFIG + CMD_MAP("lomtd", cmd_lomtd, 3, 10, + "[-d ] | [[-o ] [-e ] " + "[-b ] [-c ] ]]"), +# else CMD_MAP("lomtd", cmd_lomtd, 3, 9, "[-d ] | [[-o ] [-e ] " "[-b ] ]]"), +# endif # endif #endif diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index c1abcd357..447d45e72 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -965,8 +965,8 @@ errout: * Name: cmd_losetup ****************************************************************************/ -#ifndef CONFIG_DISABLE_MOUNTPOINT -# if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP) +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_DEV_LOOP) && \ + !defined(CONFIG_NSH_DISABLE_LOSETUP) int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { FAR char *loopdev = NULL; @@ -1120,14 +1120,13 @@ errout_with_paths: return ret; } #endif -#endif /**************************************************************************** * Name: cmd_losmart ****************************************************************************/ -#ifndef CONFIG_DISABLE_MOUNTPOINT -# if defined(CONFIG_SMART_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSMART) +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_SMART_DEV_LOOP) && \ + !defined(CONFIG_NSH_DISABLE_LOSMART) int cmd_losmart(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { FAR char *loopdev = NULL; @@ -1292,14 +1291,13 @@ errout_with_paths: return ret; } #endif -#endif /**************************************************************************** * Name: cmd_lomtd ****************************************************************************/ -#ifndef CONFIG_DISABLE_MOUNTPOINT -# if defined(CONFIG_MTD_LOOP) && !defined(CONFIG_NSH_DISABLE_LOMTD) +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_MTD_LOOP) && \ + !defined(CONFIG_NSH_DISABLE_LOMTD) int cmd_lomtd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { FAR char *loopdev = NULL; @@ -1310,6 +1308,9 @@ int cmd_lomtd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) int sectsize = -1; off_t offset = 0; bool badarg = false; +# ifdef CONFIG_MTD_CONFIG + int configdata = 0; +# endif int ret = ERROR; int option; int fd; @@ -1317,14 +1318,17 @@ int cmd_lomtd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) /* Get the lomtd options: Two forms are supported: * * lomtd -d - * lomtd [-o ] [-e erasesize] [-b sectsize] + * lomtd [-o ] [-e erasesize] [-b sectsize] [-c configdata] * * * NOTE that the -o and -r options are accepted with the -d option, but * will be ignored. */ - +# ifdef CONFIG_MTD_CONFIG + while ((option = getopt(argc, argv, "d:o:e:b:c:")) != ERROR) +# else while ((option = getopt(argc, argv, "d:o:e:b:")) != ERROR) +# endif { switch (option) { @@ -1345,6 +1349,12 @@ int cmd_lomtd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) sectsize = atoi(optarg); break; +# ifdef CONFIG_MTD_CONFIG + case 'c': + configdata = atoi(optarg); + break; +# endif + case '?': default: nsh_error(vtbl, g_fmtarginvalid, argv[0]); @@ -1420,11 +1430,14 @@ int cmd_lomtd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { /* Set up the loop device */ - setup.devname = loopdev; /* The loop block device to be created */ - setup.filename = filepath; /* The file or character device to use */ - setup.sectsize = sectsize; /* The sector size to use with the block device */ - setup.erasesize = erasesize; /* The sector size to use with the block device */ - setup.offset = offset; /* An offset that may be applied to the device */ + setup.devname = loopdev; /* The loop block device to be created */ + setup.filename = filepath; /* The file or character device to use */ + setup.sectsize = sectsize; /* The sector size to use with the block device */ + setup.erasesize = erasesize; /* The sector size to use with the block device */ + setup.offset = offset; /* An offset that may be applied to the device */ +# ifdef CONFIG_MTD_CONFIG + setup.configdata = configdata; /* Is a loop mtdconfig device */ +# endif ret = ioctl(fd, MTD_LOOPIOC_SETUP, (unsigned long)((uintptr_t)&setup)); @@ -1455,7 +1468,6 @@ errout_with_paths: return ret; } -# endif #endif /**************************************************************************** @@ -1661,8 +1673,7 @@ int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) * Name: cmd_mkdir ****************************************************************************/ -#ifdef NSH_HAVE_DIROPTS -#ifndef CONFIG_NSH_DISABLE_MKDIR +#if defined(NSH_HAVE_DIROPTS) && !defined(CONFIG_NSH_DISABLE_MKDIR) int cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { FAR char *fullpath = NULL; @@ -1722,14 +1733,13 @@ int cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) return ret; } #endif -#endif /**************************************************************************** * Name: cmd_mkfatfs ****************************************************************************/ -#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FSUTILS_MKFATFS) -#ifndef CONFIG_NSH_DISABLE_MKFATFS +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FSUTILS_MKFATFS) && \ + !defined(CONFIG_NSH_DISABLE_MKFATFS) int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { struct fat_format_s fmt = FAT_FORMAT_INITIALIZER; @@ -1825,7 +1835,6 @@ int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) return ret; } #endif -#endif /**************************************************************************** * Name: cmd_mkfifo @@ -1962,8 +1971,7 @@ errout_with_fmt: ****************************************************************************/ #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_SMARTFS) && \ - defined(CONFIG_FSUTILS_MKSMARTFS) -#ifndef CONFIG_NSH_DISABLE_MKSMARTFS + defined(CONFIG_FSUTILS_MKSMARTFS) && !defined(CONFIG_NSH_DISABLE_MKSMARTFS) int cmd_mksmartfs(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { FAR char *fullpath = NULL; @@ -2048,14 +2056,12 @@ int cmd_mksmartfs(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) return ret; } #endif -#endif /**************************************************************************** * Name: cmd_mv ****************************************************************************/ -#ifdef NSH_HAVE_DIROPTS -#ifndef CONFIG_NSH_DISABLE_MV +#if defined(NSH_HAVE_DIROPTS) && !defined(CONFIG_NSH_DISABLE_MV) int cmd_mv(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { UNUSED(argc); @@ -2098,7 +2104,6 @@ errout_with_oldpath: return ret; } #endif -#endif /**************************************************************************** * Name: cmd_readlink @@ -2141,9 +2146,7 @@ int cmd_readlink(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) * Name: cmd_rm ****************************************************************************/ -#ifdef NSH_HAVE_DIROPTS -#ifndef CONFIG_NSH_DISABLE_RM - +#if defined(NSH_HAVE_DIROPTS) && !defined(CONFIG_NSH_DISABLE_RM) static int unlink_recursive(FAR char *path, FAR struct stat *stat) { struct dirent *d; @@ -2273,14 +2276,12 @@ int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) return ret; } #endif -#endif /**************************************************************************** * Name: cmd_rmdir ****************************************************************************/ -#ifdef NSH_HAVE_DIROPTS -#ifndef CONFIG_NSH_DISABLE_RMDIR +#if defined(NSH_HAVE_DIROPTS) && !defined(CONFIG_NSH_DISABLE_RMDIR) int cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { UNUSED(argc); @@ -2302,7 +2303,6 @@ int cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) return ret; } #endif -#endif /**************************************************************************** * Name: cmd_source @@ -2431,8 +2431,7 @@ errout: * Name: cmd_truncate ****************************************************************************/ -#ifndef CONFIG_DISABLE_MOUNTPOINT -#ifndef CONFIG_NSH_DISABLE_TRUNCATE +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && !defined(CONFIG_NSH_DISABLE_TRUNCATE) int cmd_truncate(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { UNUSED(argc); @@ -2536,7 +2535,6 @@ int cmd_truncate(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) return ret; } #endif -#endif /**************************************************************************** * Name: cmd_fdinfo From 72f57fc34e543dc91b3b5a5c2a8b6a088479e373 Mon Sep 17 00:00:00 2001 From: Jiri Vlasak Date: Wed, 21 Jan 2026 10:13:10 +0100 Subject: [PATCH 173/568] netutils: Add BARE BARE is a simple binary representation for structured application data. cbare, the BARE implementation ported by this commit, is an I/O agnostic C implementation of the BARE message encoding. Signed-off-by: Jiri Vlasak --- LICENSE | 26 +++++++++ netutils/bare/Kconfig | 22 ++++++++ netutils/bare/Make.defs | 27 ++++++++++ netutils/bare/Makefile | 58 +++++++++++++++++++++ netutils/bare/cbare_porting_for_nuttx.patch | 28 ++++++++++ 5 files changed, 161 insertions(+) create mode 100644 netutils/bare/Kconfig create mode 100644 netutils/bare/Make.defs create mode 100644 netutils/bare/Makefile create mode 100644 netutils/bare/cbare_porting_for_nuttx.patch diff --git a/LICENSE b/LICENSE index 61fb28ab4..429bd3339 100644 --- a/LICENSE +++ b/LICENSE @@ -2248,3 +2248,29 @@ AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +netutils/bare/ +============== + +MIT License + +Copyright (c) 2022 Frank Smit + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/netutils/bare/Kconfig b/netutils/bare/Kconfig new file mode 100644 index 000000000..2f0fa3df2 --- /dev/null +++ b/netutils/bare/Kconfig @@ -0,0 +1,22 @@ +config NETUTILS_BARE + bool "Binary Application Record Encoding (BARE)" + default n + depends on ALLOW_MIT_COMPONENTS + ---help--- + BARE is a simple binary representation for structured + application data. + + See https://baremessages.org/ + + cbare is an MIT-licensed I/O agnostic C implementation of the + BARE message encoding that is used when this option is enabled. + +if NETUTILS_BARE + +config NETUTILS_BARE_TEST + bool "Enable baretest" + default n + ---help--- + Enable baretest -- BARE test application. + +endif diff --git a/netutils/bare/Make.defs b/netutils/bare/Make.defs new file mode 100644 index 000000000..9a6b4f538 --- /dev/null +++ b/netutils/bare/Make.defs @@ -0,0 +1,27 @@ +############################################################################ +# apps/netutils/bare/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_NETUTILS_BARE),) +CONFIGURED_APPS += $(APPDIR)/netutils/bare +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/netutils/bare/cbare/src +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/netutils/bare/cbare/src +endif diff --git a/netutils/bare/Makefile b/netutils/bare/Makefile new file mode 100644 index 000000000..e851edf15 --- /dev/null +++ b/netutils/bare/Makefile @@ -0,0 +1,58 @@ +############################################################################ +# apps/netutils/bare/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +BARE_CBARE_DIR = cbare + +DEPPATH += --dep-path $(BARE_CBARE_DIR)$(DELIM)src +VPATH += :$(BARE_CBARE_DIR)$(DELIM)src + +CFLAGS += -I$(BARE_CBARE_DIR)/src + +CSRCS = $(BARE_CBARE_DIR)/src/alloc.c +CSRCS += $(BARE_CBARE_DIR)/src/cbare.c +CSRCS += $(BARE_CBARE_DIR)/src/die.c + +ifneq ($(CONFIG_NETUTILS_BARE_TEST),) + +PROGNAME = baretest +PRIORITY = 100 +STACKSIZE = 2048 +MODULE = y + +MAINSRC = $(BARE_CBARE_DIR)/test/baretest.c + +endif + +$(BARE_CBARE_DIR): + $(Q) echo "Cloning cbare repo..." + $(Q) git clone --depth=1 https://git.sr.ht/~fsx/cbare + $(Q) patch -p1 --directory=cbare < cbare_porting_for_nuttx.patch + $(Q) touch $(BARE_CBARE_DIR) + +context:: $(BARE_CBARE_DIR) + +distclean:: + $(call DELDIR, $(BARE_CBARE_DIR)) + +include $(APPDIR)/Application.mk diff --git a/netutils/bare/cbare_porting_for_nuttx.patch b/netutils/bare/cbare_porting_for_nuttx.patch new file mode 100644 index 000000000..73d16f7fd --- /dev/null +++ b/netutils/bare/cbare_porting_for_nuttx.patch @@ -0,0 +1,28 @@ +diff --git i/src/cbare.c w/src/cbare.c +index 208639f..a3081fb 100644 +--- i/src/cbare.c ++++ w/src/cbare.c +@@ -4,7 +4,9 @@ + #include "cbare.h" + #include "utf8.h" + ++#ifndef UNUSED + #define UNUSED(x) (void)(x) ++#endif + + enum { + U8SZ = 1, +diff --git i/test/baretest.c w/test/baretest.c +index 1561f4c..9df740f 100644 +--- i/test/baretest.c ++++ w/test/baretest.c +@@ -10,7 +10,9 @@ + #include "alloc.h" + #include "die.h" + ++#ifndef UNUSED + #define UNUSED(x) (void)(x) ++#endif + + #define ARRLEN(a) sizeof(a)/sizeof(a[0]) + From 0e1ccbe35dbfa5a7ce7ae762e49b1df5ab2ae51a Mon Sep 17 00:00:00 2001 From: Jiri Vlasak Date: Wed, 21 Jan 2026 19:06:52 +0100 Subject: [PATCH 174/568] license: Fix typo in LICENSE file license: Fix typo in LICENSE file Signed-off-by: Jiri Vlasak --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 429bd3339..84b5055da 100644 --- a/LICENSE +++ b/LICENSE @@ -1282,7 +1282,7 @@ apps/system/telnet/telnet_client.c Copyright (C) 2017 Gregory Nutt. All rights reserved. Author: Gregory Nutt - The original authors of libtelnet are listed below. Per their licesne, + The original authors of libtelnet are listed below. Per their license, "The author or authors of this code dedicate any and all copyright interest in this code to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and From 5c822ea4d3a4a8bf548983a6ad9cd7fcefa7894f Mon Sep 17 00:00:00 2001 From: mazhuang Date: Wed, 13 Nov 2024 21:37:35 +0800 Subject: [PATCH 175/568] rpmsgsocket:add rpmsg socket test cases Signed-off-by: mazhuang --- examples/rpmsgsocket/rpsock_client.c | 163 +++++++++++++++++++- examples/rpmsgsocket/rpsock_server.c | 213 ++++++++++++++++++++++++++- 2 files changed, 371 insertions(+), 5 deletions(-) diff --git a/examples/rpmsgsocket/rpsock_client.c b/examples/rpmsgsocket/rpsock_client.c index 447bf7773..80813404e 100644 --- a/examples/rpmsgsocket/rpsock_client.c +++ b/examples/rpmsgsocket/rpsock_client.c @@ -425,7 +425,140 @@ errout_with_buffers: return -errno; } -static int rpsock_dgram_client(FAR char *argv[]) +static int rpsock_stream_conn_multi_times_client(FAR char *argv[], int argc) +{ + struct sockaddr_rpmsg myaddr; + struct pollfd pfd; + size_t sendsize = BUFHEAD; + ssize_t act; + bool delayflag = false; + bool nonblock = false; + FAR char *outbuf; + FAR char *inbuf; + FAR char *tmp; + int sockfd; + int ret; + + /* Allocate buffers */ + + inbuf = malloc(2 * BUFSIZE); + outbuf = inbuf + BUFSIZE; + if (inbuf == NULL) + { + printf("client: failed to allocate buffers\n"); + ret = -ENOMEM; + goto errout_with_buffers; + } + + /* Create a new rpmsg domain socket */ + + if (strcmp(argv[2], "nonblock") == 0) + { + nonblock = true; + } + + if (argc >= 7 && strcmp(argv[6], "delay") == 0) + { + delayflag = true; + } + + printf("client: create socket SOCK_STREAM nonblock %d\n", nonblock); + + if (nonblock) + { + sockfd = socket(PF_RPMSG, SOCK_STREAM | SOCK_NONBLOCK, 0); + } + else + { + sockfd = socket(PF_RPMSG, SOCK_STREAM, 0); + } + + if (sockfd < 0) + { + printf("client socket failure %d\n", errno); + goto errout_with_buffers; + } + + /* Connect the socket to the server */ + + myaddr.rp_family = AF_RPMSG; + strlcpy(myaddr.rp_name, argv[3], RPMSG_SOCKET_NAME_SIZE); + strlcpy(myaddr.rp_cpu, argv[4], RPMSG_SOCKET_CPU_SIZE); + + printf("client: Connecting to %s,%s...\n", myaddr.rp_cpu, myaddr.rp_name); + ret = connect(sockfd, (FAR struct sockaddr *)&myaddr, sizeof(myaddr)); + if (ret < 0 && errno == EINPROGRESS) + { + memset(&pfd, 0, sizeof(struct pollfd)); + pfd.fd = sockfd; + pfd.events = POLLOUT; + + ret = poll(&pfd, 1, -1); + if (ret < 0) + { + printf("client: poll failure: %d\n", errno); + goto errout_with_socket; + } + } + else if (ret < 0) + { + printf("client: connect failure: %d\n", errno); + goto errout_with_socket; + } + + printf("client: Connected\n"); + + snprintf(outbuf, BUFHEAD, "process%04d, name:%s", getpid(), argv[3]); + + printf("client send data, total len %zu, BUFHEAD %s\n", sendsize, outbuf); + + tmp = outbuf; + + ret = send(sockfd, tmp, sendsize, 0); + if (ret < 0) + { + printf("client: send failure: %d\n", errno); + goto errout_with_socket; + } + + tmp = inbuf; + if (nonblock) + { + memset(&pfd, 0, sizeof(struct pollfd)); + pfd.fd = sockfd; + pfd.events = POLLIN; + + ret = poll(&pfd, 1, -1); + if (ret < 0) + { + printf("client: poll failure: %d\n", errno); + goto errout_with_socket; + } + } + + act = recv(sockfd, tmp, SYNCSIZE, 0); + if (act < 0) + { + printf("client recv data failed %zd\n", act); + goto errout_with_socket; + } + + printf("client: Terminating\n"); + + if (delayflag) + { + sleep(1); + } + +errout_with_socket: + close(sockfd); + +errout_with_buffers: + free(inbuf); + return -errno; +} + +static int rpsock_dgram_client(char *argv[]) { struct sockaddr_rpmsg myaddr; struct rpsock_arg_s args; @@ -534,10 +667,14 @@ errout_with_buffers: int main(int argc, FAR char *argv[]) { + int times = 0; + int ret = 0; + int num = 0; + if (argc < 4) { - printf("Usage: rpsock_client stream/dgram" - " block/nonblock rp_name rp_cpu\n"); + printf("Usage: rpsock_client stream/dgram/conn_multi_times/delay" + " block/nonblock rp_name rp_cpu times\n"); return -EINVAL; } @@ -549,6 +686,26 @@ int main(int argc, FAR char *argv[]) { return rpsock_dgram_client(argv); } + else if (!strcmp(argv[1], "conn_multi_times")) + { + if (argc < 6 || atoi(argv[5]) <= 0) + { + printf("Usage: rpsock_client conn_multi_times" + " block/nonblock rp_name rp_cpu times (delay)\n"); + return -EINVAL; + } + + for (times = atoi(argv[5]); times > 0; times--) + { + printf("client conn_multi_times: %d\n", num++); + ret = rpsock_stream_conn_multi_times_client(argv, argc); + if (ret < 0 && ret != -EINPROGRESS) + { + printf("client socket failure %d\n", ret); + return ret; + } + } + } return -EINVAL; } diff --git a/examples/rpmsgsocket/rpsock_server.c b/examples/rpmsgsocket/rpsock_server.c index 467f4f853..338818630 100644 --- a/examples/rpmsgsocket/rpsock_server.c +++ b/examples/rpmsgsocket/rpsock_server.c @@ -269,6 +269,191 @@ errout_with_listensd: return -errno; } +static int rpsock_recv_send_single(FAR struct rpsock_arg_s *args) +{ + struct pollfd pfd; + ssize_t ret; + char buf[255]; + FAR char *tmp; + int snd; + + if (args->nonblock) + { + memset(&pfd, 0, sizeof(struct pollfd)); + pfd.fd = args->fd; + pfd.events = POLLIN; + + ret = poll(&pfd, 1, -1); + if (ret < 0) + { + printf("server poll failed errno %d\n", errno); + goto end; + } + } + + ret = recv(args->fd, buf, sizeof(buf), 0); + if (ret == 0 || (ret < 0 && errno == ECONNRESET)) + { + printf("server recv data normal exit\n"); + goto end; + } + else if (ret < 0 && errno == EINPROGRESS) + { + memset(&pfd, 0, sizeof(struct pollfd)); + pfd.fd = args->fd; + pfd.events = POLLOUT; + ret = poll(&pfd, 1, -1); + if (ret < 0) + { + printf("server: poll failure: %d\n", errno); + goto end; + } + } + else if(ret < 0) + { + printf("server recv data failed ret %zd, errno %d\n", ret, errno); + goto end; + } + + snd = ret; + tmp = buf; + + if (args->nonblock) + { + memset(&pfd, 0, sizeof(struct pollfd)); + pfd.fd = args->fd; + pfd.events = POLLOUT; + + ret = poll(&pfd, 1, -1); + if (ret < 0) + { + printf("server: poll failure: %d\n", errno); + goto end; + } + } + + ret = send(args->fd, tmp, snd, 0); + if (ret == 0) + { + printf("server send data normal exit\n"); + } + else if (ret < 0) + { + printf("server send data failed errno %d\n", errno); + } + +end: + printf("server Complete ret %zd, errno %d\n", ret, errno); + free(args); + return -errno; +} + +static int rpsock_stream_multi_times_server(FAR char *argv[]) +{ + struct sockaddr_rpmsg myaddr; + FAR struct rpsock_arg_s *args; + struct pollfd pfd; + socklen_t addrlen; + bool nonblock = false; + int fd; + int newfd; + int ret; + + /* Create a new rpmsg domain socket */ + + if (strcmp(argv[2], "nonblock") == 0) + { + nonblock = true; + } + + printf("server: create socket SOCK_STREAM nonblock %d\n", nonblock); + + if (nonblock) + { + fd = socket(PF_RPMSG, SOCK_STREAM | SOCK_NONBLOCK, 0); + } + else + { + fd = socket(PF_RPMSG, SOCK_STREAM, 0); + } + + if (fd < 0) + { + printf("server: socket failure: %d\n", errno); + return -errno; + } + + /* Bind the socket to a local address */ + + myaddr.rp_family = AF_RPMSG; + strlcpy(myaddr.rp_name, argv[3], RPMSG_SOCKET_NAME_SIZE); + strlcpy(myaddr.rp_cpu, argv[4], RPMSG_SOCKET_CPU_SIZE); + + printf("server: bind cpu %s, name %s ...\n", + myaddr.rp_cpu, myaddr.rp_name); + ret = bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)); + if (ret < 0) + { + printf("server: bind failure: %d\n", errno); + goto errout_with_listensd; + } + + /* Listen for connections on the bound socket */ + + printf("server: listen ...\n"); + ret = listen(fd, 16); + if (ret < 0) + { + printf("server: listen failure %d\n", errno); + goto errout_with_listensd; + } + + if (nonblock) + { + memset(&pfd, 0, sizeof(struct pollfd)); + pfd.fd = fd; + pfd.events = POLLIN; + + ret = poll(&pfd, 1, -1); + if (ret < 0) + { + printf("server: poll failure: %d\n", errno); + goto errout_with_listensd; + } + } + + printf("server: try accept ...\n"); + newfd = accept4(fd, (FAR struct sockaddr *)&myaddr, &addrlen, + SOCK_CLOEXEC); + if (newfd < 0) + { + printf("server: accept4 failure: %d\n", errno); + goto errout_with_listensd; + } + + printf("server: Connection accepted -- %d\n", newfd); + + args = malloc(sizeof(struct rpsock_arg_s)); + assert(args); + + args->fd = newfd; + args->nonblock = nonblock; + + ret = rpsock_recv_send_single(args); + if (ret < 0) + { + printf("rpsock_recv_send_single failed errno %d\n", errno); + } + + printf("server: Terminating\n"); + close(fd); + return 0; + +errout_with_listensd: + close(fd); + return -errno; +} + static int rpsock_dgram_server(int argc, FAR char *argv[]) { struct sockaddr_rpmsg myaddr; @@ -366,10 +551,14 @@ static int rpsock_dgram_server(int argc, FAR char *argv[]) int main(int argc, FAR char *argv[]) { + int times = 0; + int ret = 0; + int num = 0; + if (argc < 4) { - printf("Usage: rpsock_server stream/dgram" - " block/nonblock rp_name [rp_cpu]\n"); + printf("Usage: rpsock_server stream/dgram/server_multi_times" + " block/nonblock rp_name [rp_cpu] times\n"); return -EINVAL; } @@ -381,6 +570,26 @@ int main(int argc, FAR char *argv[]) { return rpsock_dgram_server(argc, argv); } + else if (!strcmp(argv[1], "server_multi_times")) + { + if (argc < 6 || atoi(argv[5]) <= 0) + { + printf("Usage: rpsock_server server_multi_times" + " block/nonblock rp_name rp_cpu times\n"); + return -EINVAL; + } + + for (times = atoi(argv[5]); times > 0; times--) + { + printf("server_multi_times: %d\n", num++); + ret = rpsock_stream_multi_times_server(argv); + if (ret < 0 && ret != -EINPROGRESS) + { + printf("server socket failure %d\n", ret); + return ret; + } + } + } return -EINVAL; } From c883c3f6ddb81cbfa9c406c8cea820847b7943ca Mon Sep 17 00:00:00 2001 From: Vlad Pruteanu Date: Sat, 24 Jan 2026 17:37:23 +0200 Subject: [PATCH 176/568] testing/drivers/crypto/hmac.c: Add long keys This adds 2 tests, which include keys that are longer than the SHA's block size. Signed-off-by: Vlad Pruteanu --- testing/drivers/crypto/hmac.c | 56 +++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/testing/drivers/crypto/hmac.c b/testing/drivers/crypto/hmac.c index 10f0f12ac..4f0387bf8 100644 --- a/testing/drivers/crypto/hmac.c +++ b/testing/drivers/crypto/hmac.c @@ -64,13 +64,55 @@ testcase[] = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", 50 }, + { + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa", + 131, + "Test Using Larger Than Block-Size Key - Hash Key First", + 54 + }, + { + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa", + 131, + "This is a test using a larger than block-size key and a " + "larger than block-size data. The key needs to be hashed " + "before being used by the HMAC algorithm.", + 152 + }, }; FAR char *md5_result[] = { "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d", "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38", - "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6" + "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6", + "\xbf\xec\xaf\x4e\xff\xf9\x0a\x3a\x66\x8f\x39\x22\xfe\xc3\x76\x2d", + "\x09\xb8\xae\x7b\x15\xad\xbb\xb2\x43\xac\xa3\x49\x1b\x51\x51\x2b" }; FAR char *sha1_result[] = @@ -80,7 +122,11 @@ FAR char *sha1_result[] = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c" "\x25\x9a\x7c\x79", "\xd7\x30\x59\x4d\x16\x7e\x35\xd5\x95\x6f\xd8\x00\x3d\x0d\xb3\xd3" - "\xf4\x6d\xc7\xbb" + "\xf4\x6d\xc7\xbb", + "\x90\xd0\xda\xce\x1c\x1b\xdc\x95\x73\x39\x30\x78\x03\x16\x03\x35" + "\xbd\xe6\xdf\x2b", + "\x21\x7e\x44\xbb\x08\xb6\xe0\x6a\x2d\x6c\x30\xf3\xcb\x9f\x53\x7f" + "\x97\xc6\x33\x56" }; FAR char *sha256_result[] = @@ -90,7 +136,11 @@ FAR char *sha256_result[] = "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7" "\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43", "\x7d\xda\x3c\xc1\x69\x74\x3a\x64\x84\x64\x9f\x94\xf0\xed\xa0\xf9" - "\xf2\xff\x49\x6a\x97\x33\xfb\x79\x6e\xd5\xad\xb4\x0a\x44\xc3\xc1" + "\xf2\xff\x49\x6a\x97\x33\xfb\x79\x6e\xd5\xad\xb4\x0a\x44\xc3\xc1", + "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f" + "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54", + "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44" + "\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2" }; int syshmac(int mac, FAR const char *key, size_t keylen, From d1de009bc2744efb155d4a60c6ab4dcf50ffa284 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Sat, 24 Jan 2026 18:21:47 +0800 Subject: [PATCH 177/568] sched: inline enter_critical_section Inline enter_critical_section function calls in performance-critical paths to reduce function call overhead while maintaining consistent semantics, improving overall system latency and responsiveness in real-time scenarios. Signed-off-by: hujun5 --- benchmarks/osperf/osperf.c | 3 ++- testing/ostest/wdog.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/benchmarks/osperf/osperf.c b/benchmarks/osperf/osperf.c index 0e71a4e05..757fb4216 100644 --- a/benchmarks/osperf/osperf.c +++ b/benchmarks/osperf/osperf.c @@ -39,6 +39,7 @@ #include #include +#include /**************************************************************************** * Private Types @@ -129,7 +130,7 @@ static size_t performance_gettime(FAR struct performance_time_s *result) } /**************************************************************************** - * Pthread swtich performance + * Pthread switch performance ****************************************************************************/ static FAR void *pthread_switch_task(FAR void *arg) diff --git a/testing/ostest/wdog.c b/testing/ostest/wdog.c index ca692f274..c00a7f9b6 100644 --- a/testing/ostest/wdog.c +++ b/testing/ostest/wdog.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include From 1f990388ecd6b656df508b8c756437c66e6e9af8 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Mon, 13 Jan 2025 22:39:49 +0800 Subject: [PATCH 178/568] system/uorb: support non-wakeup subscribe. default subscribing is wakeup. Signed-off-by: dongjiuzhu1 --- system/uorb/uORB/uORB.c | 18 +++++++++++++++--- system/uorb/uORB/uORB.h | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/system/uorb/uORB/uORB.c b/system/uorb/uORB/uORB.c index 333fc09e0..6fcc060c2 100644 --- a/system/uorb/uORB/uORB.c +++ b/system/uorb/uORB/uORB.c @@ -51,6 +51,7 @@ * flag The open flag. * instance Instance number to open. * queue_size Maximum number of buffered elements. + * non_wakeup The non wakeup flag. * * Returned Value: * fd on success, otherwise returns negative value and set errno. @@ -58,7 +59,7 @@ static int orb_advsub_open(FAR const struct orb_metadata *meta, int flags, int instance, unsigned int queue_size, - FAR orb_info_t *info) + FAR orb_info_t *info, bool non_wakeup) { char path[ORB_PATH_MAX]; int fd; @@ -123,6 +124,11 @@ static int orb_advsub_open(FAR const struct orb_metadata *meta, int flags, ioctl(fd, SNIOC_SET_BUFFER_NUMBER, (unsigned long)queue_size); } + if (non_wakeup) + { + ioctl(fd, SNIOC_SET_NONWAKEUP, (unsigned long)non_wakeup); + } + return fd; } @@ -139,7 +145,7 @@ orb_advertise_multi_queue_flags(FAR const struct orb_metadata *meta, inst = instance ? *instance : orb_group_count(meta); - fd = orb_advsub_open(meta, flags, inst, queue_size, info); + fd = orb_advsub_open(meta, flags, inst, queue_size, info, false); if (fd < 0) { uorberr("%s advertise failed (%i)", meta->o_name, fd); @@ -210,7 +216,13 @@ ssize_t orb_publish_multi(int fd, FAR const void *data, size_t len) int orb_subscribe_multi(FAR const struct orb_metadata *meta, unsigned instance) { - return orb_advsub_open(meta, O_RDONLY, instance, 0, NULL); + return orb_advsub_open(meta, O_RDONLY, instance, 0, NULL, false); +} + +int orb_subscribe_multi_nonwakeup(FAR const struct orb_metadata *meta, + unsigned instance) +{ + return orb_advsub_open(meta, O_RDONLY, instance, 0, NULL, true); } ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len) diff --git a/system/uorb/uORB/uORB.h b/system/uorb/uORB/uORB.h index 205edffb1..e30c52fdd 100644 --- a/system/uorb/uORB/uORB.h +++ b/system/uorb/uORB/uORB.h @@ -484,6 +484,44 @@ static inline int orb_subscribe(FAR const struct orb_metadata *meta) return orb_subscribe_multi(meta, 0); } +/**************************************************************************** + * Name: orb_subscribe_multi_nonwakeup/orb_subscribe_nonwakeup + * + * Description: + * Subscribe to a topic in a non-wakeup ways. + * + * The usage of orb_subscribe_multi_nonwakeup is similar to that of + * orb_subscribe_multi, with the key difference lying in whether the + * system's wakeup status needs to be concerned. This distinction is + * particularly beneficial for low-power consumption scenarios. + * If the subscription is in a non-wakeup mode, the subscriber will not + * receive data while the system is in sleep mode. In such cases, new data + * will overwrite old data until the system is awakened, at which point + * the subscriber will be notified. Typically, the subscriber and + * publisher of a topic reside in two separate systems. + * + * Input Parameters: + * meta The uORB metadata (usually from the ORB_ID() macro) + * instance The instance of the topic. Instance 0 matches the topic of + * the orb_subscribe() call. + * + * Returned Value: + * -1 on error, otherwise returns a fd + * that can be used to read and update the topic. + * If the topic in question is not known (due to an + * ORB_DEFINE_OPTIONAL with no corresponding ORB_DECLARE) + * this function will return -1 and set errno to ENOENT. + ****************************************************************************/ + +int orb_subscribe_multi_nonwakeup(FAR const struct orb_metadata *meta, + unsigned instance); + +static inline +int orb_subscribe_nonwakeup(FAR const struct orb_metadata *meta) +{ + return orb_subscribe_multi_nonwakeup(meta, 0); +} + /**************************************************************************** * Name: orb_unsubscribe * From 854d00e49ed236f1be6edb55974552d09b014210 Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Wed, 22 Jan 2025 22:26:26 +0800 Subject: [PATCH 179/568] system/uorb: uorb_listener add new features. Add nonwakeup ways to using uorb_listener Signed-off-by: dongjiuzhu1 Signed-off-by: likun17 --- system/uorb/listener.c | 61 +++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/system/uorb/listener.c b/system/uorb/listener.c index 8cd63b098..4a60b5185 100644 --- a/system/uorb/listener.c +++ b/system/uorb/listener.c @@ -84,7 +84,7 @@ static int listener_print(FAR const struct orb_metadata *meta, int fd); static void listener_monitor(FAR struct listen_list_s *objlist, int nb_objects, float topic_rate, int topic_latency, int nb_msgs, - int timeout, bool record); + int timeout, bool record, bool nonwakeup); static int listener_update(FAR struct listen_list_s *objlist, FAR struct orb_object *object); static void listener_top(FAR struct listen_list_s *objlist, @@ -140,6 +140,7 @@ listener [arguments...]\n\ \t[-l ] Top only execute once.\n\ \t[-i ] Get sensor device information based on topic.\n\ \t[-f ] Flush sensor drive data.\n\ +\t[-u ] Subscribe in non-wakeup mode to save power.\n\ "); } @@ -182,6 +183,34 @@ static int listener_create_dir(FAR char *dir, size_t size) return OK; } +/**************************************************************************** + * Name: listener_subscribe + * + * Description: + * Subscribe topic according to non wakeup mode. + * + * Input Parameters: + * tmp Given object + * nonwakeup State of nonwakeup. + * + * Returned Value: + * fd on success, otherwise -1. + ****************************************************************************/ + +static int listener_subscribe(FAR struct listen_object_s *tmp, + bool nonwakeup) +{ + if (nonwakeup) + { + return orb_subscribe_multi_nonwakeup(tmp->object.meta, + tmp->object.instance); + } + else + { + return orb_subscribe_multi(tmp->object.meta, tmp->object.instance); + } +} + /**************************************************************************** * Name: listener_get_state * @@ -542,13 +571,14 @@ static int listener_print(FAR const struct orb_metadata *meta, int fd) * objlist Topic object list. * nb_objects Length of objects list. * timeout Maximum poll waiting time(microsecond). + * nonwakeup The state of non wakeup * * Returned Value: * void ****************************************************************************/ static void listener_flush_topic(FAR const struct listen_list_s *objlist, - int nb_objects, int timeout) + int nb_objects, int timeout, bool nonwakeup) { FAR struct listen_object_s *tmp; FAR struct pollfd *fds; @@ -577,7 +607,7 @@ static void listener_flush_topic(FAR const struct listen_list_s *objlist, { int fd; - fd = orb_subscribe_multi(tmp->object.meta, tmp->object.instance); + fd = listener_subscribe(tmp, nonwakeup); if (fd < 0) { fds[i].fd = -1; @@ -672,13 +702,15 @@ static void listener_flush_topic(FAR const struct listen_list_s *objlist, * Print sensor device information. * * Input Parameters: - * objlist topic object list. + * objlist topic object list. + * nonwakeup The state of non wakeup * * Returned Value: * void ****************************************************************************/ -static void listener_print_info(FAR const struct listen_list_s *objlist) +static void listener_print_info(FAR const struct listen_list_s *objlist, + bool nonwakeup) { FAR struct listen_object_s *tmp; orb_info_t info; @@ -687,7 +719,7 @@ static void listener_print_info(FAR const struct listen_list_s *objlist) SLIST_FOREACH(tmp, objlist, node) { - fd = orb_subscribe_multi(tmp->object.meta, tmp->object.instance); + fd = listener_subscribe(tmp, nonwakeup); if (fd < 0) { continue; @@ -775,7 +807,7 @@ static int listener_record(FAR const struct orb_metadata *meta, int fd, static void listener_monitor(FAR struct listen_list_s *objlist, int nb_objects, float topic_rate, int topic_latency, int nb_msgs, - int timeout, bool record) + int timeout, bool record, bool nonwakeup) { FAR struct pollfd *fds; char path[PATH_MAX]; @@ -806,7 +838,7 @@ static void listener_monitor(FAR struct listen_list_s *objlist, { int fd; - fd = orb_subscribe_multi(tmp->object.meta, tmp->object.instance); + fd = listener_subscribe(tmp, nonwakeup); if (fd < 0) { fds[i].fd = -1; @@ -1047,6 +1079,7 @@ int main(int argc, FAR char *argv[]) bool info = false; bool flush = false; bool record = false; + bool nonwakeup = false; bool only_once = false; FAR char *filter = NULL; int ret; @@ -1060,7 +1093,7 @@ int main(int argc, FAR char *argv[]) /* Pasrse Argument */ - while ((ch = getopt(argc, argv, "r:b:n:t:Tfslhi")) != EOF) + while ((ch = getopt(argc, argv, "r:b:n:t:Tfslhiu")) != EOF) { switch (ch) { @@ -1118,6 +1151,10 @@ int main(int argc, FAR char *argv[]) info = true; break; + case 'u': + nonwakeup = true; + break; + case 'h': default: goto error; @@ -1140,13 +1177,13 @@ int main(int argc, FAR char *argv[]) if (flush) { - listener_flush_topic(&objlist, ret, timeout); + listener_flush_topic(&objlist, ret, timeout, nonwakeup); goto exit; } if (info) { - listener_print_info(&objlist); + listener_print_info(&objlist, nonwakeup); goto exit; } @@ -1165,7 +1202,7 @@ int main(int argc, FAR char *argv[]) } listener_monitor(&objlist, ret, topic_rate, topic_latency, - nb_msgs, timeout, record); + nb_msgs, timeout, record, nonwakeup); } exit: From 9a3778cb913aca74545e965766d253dd3d8b4bde Mon Sep 17 00:00:00 2001 From: hongfengchen Date: Sat, 24 May 2025 19:11:42 +0800 Subject: [PATCH 180/568] testing: add malloc.h for fstest.h Add malloc.h header file to fstest.h to fix missing malloc/free function declarations in filesystem test suites. Signed-off-by: hongfengchen --- testing/testsuites/kernel/fs/include/fstest.h | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/testsuites/kernel/fs/include/fstest.h b/testing/testsuites/kernel/fs/include/fstest.h index 0a590bf88..050b587c8 100644 --- a/testing/testsuites/kernel/fs/include/fstest.h +++ b/testing/testsuites/kernel/fs/include/fstest.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include From b56c785640c1b7efdd4af93014eaa3919c1894b1 Mon Sep 17 00:00:00 2001 From: hongfengchen Date: Thu, 22 May 2025 10:54:17 +0800 Subject: [PATCH 181/568] testing: add missing header files Add missing header files in netutils and lsan modules to fix implicit function declarations and improve compilation compatibility. Signed-off-by: hongfengchen --- .codespellrc | 3 +++ netutils/codecs/md5.c | 1 + netutils/ftpd/ftpd.c | 1 + system/lsan/lsan_main.c | 1 + 4 files changed, 6 insertions(+) diff --git a/.codespellrc b/.codespellrc index 442f4656c..ac22a4c37 100644 --- a/.codespellrc +++ b/.codespellrc @@ -8,3 +8,6 @@ exclude-file = .codespell-ignore-lines # Ignore complete files (e.g. legal text or other immutable material). skip = LICENSE, + +# Ignore words list (FTP protocol commands and technical terms) +ignore-words-list = ALLO diff --git a/netutils/codecs/md5.c b/netutils/codecs/md5.c index 75dfe3f0c..dade6abd1 100644 --- a/netutils/codecs/md5.c +++ b/netutils/codecs/md5.c @@ -53,6 +53,7 @@ #include #include #include +#include #include "netutils/md5.h" diff --git a/netutils/ftpd/ftpd.c b/netutils/ftpd/ftpd.c index 12491030a..4f5cc4667 100644 --- a/netutils/ftpd/ftpd.c +++ b/netutils/ftpd/ftpd.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include diff --git a/system/lsan/lsan_main.c b/system/lsan/lsan_main.c index d0c8a06ea..f4a1f8579 100644 --- a/system/lsan/lsan_main.c +++ b/system/lsan/lsan_main.c @@ -26,6 +26,7 @@ #include #include +#include /**************************************************************************** * Public Functions From d0e949cb2486f73c8b1ff68d017bffcd14eefb46 Mon Sep 17 00:00:00 2001 From: hongfengchen Date: Tue, 3 Jun 2025 12:07:41 +0800 Subject: [PATCH 182/568] testing: add unistd.h and pthread.h headers Add unistd.h and pthread.h for memorystress_main.c, unistd.h for dhm.c and cachetest_main.c, and pthread.h for kv_test_019.c to fix missing declarations. Signed-off-by: hongfengchen --- examples/mdnsd/mdnsd_daemon.c | 1 - testing/drivers/crypto/dhm.c | 1 + testing/mm/cachetest/cachetest_main.c | 1 + testing/mm/memstress/memorystress_main.c | 2 ++ 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/mdnsd/mdnsd_daemon.c b/examples/mdnsd/mdnsd_daemon.c index bfa7759e8..bc2ea4563 100644 --- a/examples/mdnsd/mdnsd_daemon.c +++ b/examples/mdnsd/mdnsd_daemon.c @@ -25,7 +25,6 @@ ****************************************************************************/ #include - #include #include diff --git a/testing/drivers/crypto/dhm.c b/testing/drivers/crypto/dhm.c index f1eafa2d7..9595e4cb4 100644 --- a/testing/drivers/crypto/dhm.c +++ b/testing/drivers/crypto/dhm.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/testing/mm/cachetest/cachetest_main.c b/testing/mm/cachetest/cachetest_main.c index 3906b58e6..2916932c8 100644 --- a/testing/mm/cachetest/cachetest_main.c +++ b/testing/mm/cachetest/cachetest_main.c @@ -27,6 +27,7 @@ #include #include #include +#include #include /**************************************************************************** diff --git a/testing/mm/memstress/memorystress_main.c b/testing/mm/memstress/memorystress_main.c index 6d9b2d98d..ab1ff8630 100644 --- a/testing/mm/memstress/memorystress_main.c +++ b/testing/mm/memstress/memorystress_main.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include From 34e4d7eacded506785c271908ce5dbd9358c6cda Mon Sep 17 00:00:00 2001 From: tengshuangshuang Date: Wed, 4 Jun 2025 19:32:55 +0800 Subject: [PATCH 183/568] testing: add unistd.h for drivertest_touchpanel.c Add unistd.h header file to drivertest_touchpanel.c to fix missing sleep/usleep function declarations in touchpanel driver tests. Signed-off-by: tengshuangshuang --- testing/drivers/drivertest/drivertest_touchpanel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/drivers/drivertest/drivertest_touchpanel.c b/testing/drivers/drivertest/drivertest_touchpanel.c index 3892c3d0f..7da74a168 100644 --- a/testing/drivers/drivertest/drivertest_touchpanel.c +++ b/testing/drivers/drivertest/drivertest_touchpanel.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include From c69df55cd043c1621e4c0fa3207ffd6ab7c71e18 Mon Sep 17 00:00:00 2001 From: hongfengchen Date: Tue, 10 Jun 2025 15:00:26 +0800 Subject: [PATCH 184/568] rexecd: fix type change Fix cast from pointer to integer of different size to ensure proper type conversion and avoid compilation warnings. Signed-off-by: hongfengchen --- netutils/ftpd/ftpd.c | 34 ++++++++++++------------ netutils/rexecd/rexecd.c | 2 +- testing/mm/memstress/memorystress_main.c | 4 +-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/netutils/ftpd/ftpd.c b/netutils/ftpd/ftpd.c index 4f5cc4667..73b8fc9b9 100644 --- a/netutils/ftpd/ftpd.c +++ b/netutils/ftpd/ftpd.c @@ -140,11 +140,11 @@ static uint8_t ftpd_listoption(FAR char **param); static int ftpd_listbuffer(FAR struct ftpd_session_s *session, FAR char *path, FAR struct stat *st, FAR char *buffer, size_t buflen, - unsigned int opton); + unsigned int option); static int fptd_listscan(FAR struct ftpd_session_s *session, - FAR char *path, unsigned int opton); + FAR char *path, unsigned int option); static int ftpd_list(FAR struct ftpd_session_s *session, - unsigned int opton); + unsigned int option); /* Command handlers */ @@ -2145,7 +2145,7 @@ static uint8_t ftpd_listoption(FAR char **param) static int ftpd_listbuffer(FAR struct ftpd_session_s *session, FAR char *path, FAR struct stat *st, FAR char *buffer, - size_t buflen, unsigned int opton) + size_t buflen, unsigned int option) { UNUSED(session); @@ -2154,7 +2154,7 @@ static int ftpd_listbuffer(FAR struct ftpd_session_s *session, name = basename(path); - if ((opton & FTPD_LISTOPTION_L) != 0) + if ((option & FTPD_LISTOPTION_L) != 0) { FAR const char *str; struct tm tm; @@ -2367,7 +2367,7 @@ static int ftpd_listbuffer(FAR struct ftpd_session_s *session, ****************************************************************************/ static int fptd_listscan(FAR struct ftpd_session_s *session, FAR char *path, - unsigned int opton) + unsigned int option) { FAR char *temp; DIR *dir; @@ -2384,7 +2384,7 @@ static int fptd_listscan(FAR struct ftpd_session_s *session, FAR char *path, if (!S_ISDIR(st.st_mode)) { ret = ftpd_listbuffer(session, path, &st, session->data.buffer, - session->data.buflen, opton); + session->data.buflen, option); if (ret == 0) { ret = ftpd_response(session->data.sd, session->txtimeout, @@ -2412,7 +2412,7 @@ static int fptd_listscan(FAR struct ftpd_session_s *session, FAR char *path, if (entry->d_name[0] == '.') { - if ((opton & FTPD_LISTOPTION_A) == 0) + if ((option & FTPD_LISTOPTION_A) == 0) { continue; } @@ -2432,7 +2432,7 @@ static int fptd_listscan(FAR struct ftpd_session_s *session, FAR char *path, } ret = ftpd_listbuffer(session, temp, &st, session->data.buffer, - session->data.buflen, opton); + session->data.buflen, option); if (ret >= 0) { ret = ftpd_response(session->data.sd, session->txtimeout, @@ -2454,7 +2454,7 @@ static int fptd_listscan(FAR struct ftpd_session_s *session, FAR char *path, * Name: ftpd_list ****************************************************************************/ -static int ftpd_list(FAR struct ftpd_session_s *session, unsigned int opton) +static int ftpd_list(FAR struct ftpd_session_s *session, unsigned int option) { FAR char *abspath; int ret; @@ -2462,7 +2462,7 @@ static int ftpd_list(FAR struct ftpd_session_s *session, unsigned int opton) ret = ftpd_getpath(session, session->param, &abspath, NULL); if (ret >= 0) { - ret = fptd_listscan(session, abspath, opton); + ret = fptd_listscan(session, abspath, option); free(abspath); } @@ -3417,7 +3417,7 @@ static int ftpd_command_epsv(FAR struct ftpd_session_s *session) static int ftpd_command_list(FAR struct ftpd_session_s *session) { - uint8_t opton = FTPD_LISTOPTION_L; + uint8_t option = FTPD_LISTOPTION_L; int ret; ret = ftpd_dataopen(session); @@ -3435,8 +3435,8 @@ static int ftpd_command_list(FAR struct ftpd_session_s *session) return ret; } - opton |= ftpd_listoption((char **)(&session->param)); - ftpd_list(session, opton); + option |= ftpd_listoption((char **)(&session->param)); + ftpd_list(session, option); ret = ftpd_response(session->cmd.sd, session->txtimeout, g_respfmt1, 226, ' ', "Transfer complete"); @@ -3451,7 +3451,7 @@ static int ftpd_command_list(FAR struct ftpd_session_s *session) static int ftpd_command_nlst(FAR struct ftpd_session_s *session) { - uint8_t opton = 0; + uint8_t option = 0; int ret; ret = ftpd_dataopen(session); @@ -3469,8 +3469,8 @@ static int ftpd_command_nlst(FAR struct ftpd_session_s *session) return ret; } - opton |= ftpd_listoption((char **)(&session->param)); - ftpd_list(session, opton); + option |= ftpd_listoption((char **)(&session->param)); + ftpd_list(session, option); ret = ftpd_response(session->cmd.sd, session->txtimeout, g_respfmt1, 226, ' ', "Transfer complete"); diff --git a/netutils/rexecd/rexecd.c b/netutils/rexecd/rexecd.c index 5c301c62a..2e462083c 100644 --- a/netutils/rexecd/rexecd.c +++ b/netutils/rexecd/rexecd.c @@ -85,7 +85,7 @@ static FAR void *doit(pthread_addr_t pvarg) char buf[REXECD_BUFSIZE]; struct pollfd fds[2]; FAR FILE *fp; - int sock = (int)pvarg; + int sock = (long)pvarg; int ret; /* we need to read err_sock, user and passwd, but ignore them */ diff --git a/testing/mm/memstress/memorystress_main.c b/testing/mm/memstress/memorystress_main.c index ab1ff8630..eca7b7735 100644 --- a/testing/mm/memstress/memorystress_main.c +++ b/testing/mm/memstress/memorystress_main.c @@ -122,7 +122,7 @@ static void show_usage(FAR const char *progname) { printf("\nUsage: %s -m [max allocsize Default:8192] " "-n [node length Default:1024] -t [sleep us Default:100]" - " -x [nthreads Default:1] -d [debuger mode]\n", + " -x [nthreads Default:1] -d [debugger mode]\n", progname); printf("\nWhere:\n"); printf(" -m [max-allocsize] max alloc size.\n"); @@ -217,7 +217,7 @@ static void checknode(FAR struct memorystress_thread_context_s *context, context->error.rwerror = rwerror; error_result(context->error); - lib_dumpbuffer("debuger", node->buf, size); + lib_dumpbuffer("debugger", node->buf, size); /* Trigger the ASSET once it occurs, retaining the error site */ From 71593dffad2cee60d6f704da114d6f399adaa072 Mon Sep 17 00:00:00 2001 From: yukangzhi Date: Fri, 25 Apr 2025 15:47:14 +0800 Subject: [PATCH 185/568] apps/system/trace: support binary dump of noteram This patch adds support for dumping binary contents from noteram via the `trace dump -b ` command. Changes include: - Add a `binary` parameter to `trace_dump()` and the public header `system/trace/trace.h` to indicate binary output mode. - Update `trace_dump()` to set the noteram read mode to binary using `NOTERAM_SETREADMODE` when requested. - Update `trace dump` CLI parsing in `system/trace/trace.c` to accept the `-b` flag and pass it through to `trace_dump()`. - Update usage/help text to include the new `-b` option. Signed-off-by: yukangzhi --- system/trace/trace.c | 22 +++++++++++++++++----- system/trace/trace.h | 2 +- system/trace/trace_dump.c | 14 +++++++++++++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/system/trace/trace.c b/system/trace/trace.c index f4a5454a4..f414c41ea 100644 --- a/system/trace/trace.c +++ b/system/trace/trace.c @@ -147,10 +147,20 @@ static int trace_cmd_dump(FAR const char *name, int index, int argc, { FAR FILE *out = stdout; bool changed = false; + bool binary = false; bool cont = false; int ret; - /* Usage: trace dump [-c][] */ + /* Usage: trace dump [-b][-c][] */ + + if (index < argc) + { + if (strcmp(argv[index], "-b") == 0) + { + binary = true; + index++; + } + } if (index < argc) { @@ -192,11 +202,14 @@ static int trace_cmd_dump(FAR const char *name, int index, int argc, /* Dump the trace header */ - fputs("# tracer: nop\n#\n", out); + if (!binary) + { + fputs("# tracer: nop\n#\n", out); + } /* Dump the trace data */ - ret = trace_dump(out); + ret = trace_dump(out, binary); if (changed) { @@ -803,9 +816,8 @@ static void show_usage(void) " Get the trace while running \n" #endif #ifdef CONFIG_DRIVERS_NOTERAM - " dump [-a][-c][] :" + " dump [-b][-c][] :" " Output the trace result\n" - " [-a] \n" #endif " mode [{+|-}{o|w|s|a|i|d}...] :" " Set task trace options\n" diff --git a/system/trace/trace.h b/system/trace/trace.h index 5ac104841..d94e3568b 100644 --- a/system/trace/trace.h +++ b/system/trace/trace.h @@ -57,7 +57,7 @@ extern "C" * ****************************************************************************/ -int trace_dump(FAR FILE *out); +int trace_dump(FAR FILE *out, bool binary); /**************************************************************************** * Name: trace_dump_clear diff --git a/system/trace/trace_dump.c b/system/trace/trace_dump.c index d51453da1..c91b7264e 100644 --- a/system/trace/trace_dump.c +++ b/system/trace/trace_dump.c @@ -67,7 +67,7 @@ static void note_ioctl(int cmd, unsigned long arg) * ****************************************************************************/ -int trace_dump(FAR FILE *out) +int trace_dump(FAR FILE *out, bool binary) { uint8_t tracedata[1024]; int ret; @@ -82,6 +82,18 @@ int trace_dump(FAR FILE *out) return ERROR; } + if (binary) + { + unsigned int mode = NOTERAM_MODE_READ_BINARY; + ret = ioctl(fd, NOTERAM_SETREADMODE, &mode); + if (ret < 0) + { + fprintf(stderr, "trace: cannot set read mode\n"); + close(fd); + return ERROR; + } + } + /* Read and output all notes */ while (1) From 2d2394201cde3e073fa059a0ac1536f5ad6243a9 Mon Sep 17 00:00:00 2001 From: wangxingxing Date: Fri, 21 Mar 2025 14:27:17 +0800 Subject: [PATCH 186/568] fs/bugfix: fix the fd error of fs test remove test_state of fs test cases Removes unnecessary test_state structure usage for tracking file descriptors Adds missing close(newfd) call in fs_dup_test.c to prevent file descriptor leaks Simplifies test code by eliminating redundant fd tracking that could lead to incorrect resource management Signed-off-by: wangxingxing --- testing/testsuites/kernel/fs/cases/fs_dup_test.c | 6 +----- testing/testsuites/kernel/fs/cases/fs_file_get_test.c | 3 --- testing/testsuites/kernel/fs/cases/fs_poll_test.c | 5 ----- testing/testsuites/kernel/fs/cases/fs_readdir_test.c | 4 ---- testing/testsuites/kernel/fs/cases/fs_seek_test.c | 7 ------- testing/testsuites/kernel/fs/cases/fs_truncate_test.c | 5 ----- testing/testsuites/kernel/fs/cases/fs_unlink_test.c | 5 ----- testing/testsuites/kernel/fs/cases/fs_write_test.c | 8 -------- 8 files changed, 1 insertion(+), 42 deletions(-) diff --git a/testing/testsuites/kernel/fs/cases/fs_dup_test.c b/testing/testsuites/kernel/fs/cases/fs_dup_test.c index 0600041f1..91ebf23d7 100644 --- a/testing/testsuites/kernel/fs/cases/fs_dup_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_dup_test.c @@ -60,15 +60,11 @@ void test_nuttx_fs_dup01(FAR void **state) char buffd[5] = "hello"; char bufnewfd[8] = "littleFS"; char readbuf[20] = ""; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* open file */ fd = open(TESTFILENAME, O_RDWR | O_CREAT | O_APPEND, 0700); assert_true(fd > 0); - test_state->fd1 = fd; /* do write */ @@ -83,7 +79,6 @@ void test_nuttx_fs_dup01(FAR void **state) newfd = dup(fd); close(fd); assert_int_not_equal(newfd, -1); - test_state->fd2 = newfd; /* check if file pos is shared */ @@ -112,4 +107,5 @@ void test_nuttx_fs_dup01(FAR void **state) /* check readbuf */ assert_int_equal(strncmp(readbuf, "hellolittleFS", 13), 0); + close(newfd); } diff --git a/testing/testsuites/kernel/fs/cases/fs_file_get_test.c b/testing/testsuites/kernel/fs/cases/fs_file_get_test.c index dd61c1f90..c06231f74 100644 --- a/testing/testsuites/kernel/fs/cases/fs_file_get_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_file_get_test.c @@ -63,7 +63,6 @@ void test_nuttx_fs_file_get01(FAR void **state) fd = creat(TEST_FILE, 0700); assert_true(fd > 0); - test_state->fd1 = fd; /* fdopen file */ @@ -109,8 +108,6 @@ void test_nuttx_fs_file_get01(FAR void **state) assert_int_equal(filep->f_pos, BUF_SIZE); - test_state->fd2 = fileno(fp); - /* put filep */ file_put(filep); diff --git a/testing/testsuites/kernel/fs/cases/fs_poll_test.c b/testing/testsuites/kernel/fs/cases/fs_poll_test.c index c442c7437..e51ae9ee9 100644 --- a/testing/testsuites/kernel/fs/cases/fs_poll_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_poll_test.c @@ -58,20 +58,15 @@ void test_nuttx_fs_poll01(FAR void **state) int poll01_fd2; int poll01_ret; struct pollfd poll01_fds[5]; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; poll01_fd1 = open(I_FILE1, O_RDONLY | O_CREAT); assert_true(poll01_fd1 >= 0); - test_state->fd1 = poll01_fd1; poll01_fds[0].fd = poll01_fd1; poll01_fds[0].events = POLLOUT; poll01_fd2 = open(I_FILE2, O_RDWR | O_CREAT); assert_true(poll01_fd2 >= 0); - test_state->fd2 = poll01_fd2; poll01_fds[1].fd = poll01_fd2; poll01_fds[1].events = POLLIN; diff --git a/testing/testsuites/kernel/fs/cases/fs_readdir_test.c b/testing/testsuites/kernel/fs/cases/fs_readdir_test.c index c5a259c5f..864f4ded0 100644 --- a/testing/testsuites/kernel/fs/cases/fs_readdir_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_readdir_test.c @@ -65,9 +65,6 @@ void test_nuttx_fs_readdir01(FAR void **state) DIR *test_dir; struct dirent *dptr; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; for (int i = 0; i < 6; i++) { @@ -75,7 +72,6 @@ void test_nuttx_fs_readdir01(FAR void **state) fd = open(filename[i], O_RDWR | O_CREAT, 0700); assert_true(fd > 0); - test_state->fd1 = fd; /* do wirte */ diff --git a/testing/testsuites/kernel/fs/cases/fs_seek_test.c b/testing/testsuites/kernel/fs/cases/fs_seek_test.c index e206e5e0d..3a9206c37 100644 --- a/testing/testsuites/kernel/fs/cases/fs_seek_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_seek_test.c @@ -57,15 +57,11 @@ void test_nuttx_fs_seek01(FAR void **state) char c[] = "This is fseek test !"; char buffer[sizeof(c)]; int ret; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* open file */ fp = fopen(TESTFILE, "w+"); assert_non_null(fp); - test_state->fd1 = fileno(fp); /* do fwrite */ @@ -251,11 +247,8 @@ static void test_nuttx_fs_clean(void) void test_nuttx_fs_seek02(FAR void **state) { int ret; - struct fs_testsuites_state_s *test_state; - test_state = (struct fs_testsuites_state_s *)*state; test_nuttx_fs_set(); - test_state->fd1 = fd; /* do verify lseek */ diff --git a/testing/testsuites/kernel/fs/cases/fs_truncate_test.c b/testing/testsuites/kernel/fs/cases/fs_truncate_test.c index ca2cef0bb..84e948bd5 100644 --- a/testing/testsuites/kernel/fs/cases/fs_truncate_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_truncate_test.c @@ -59,9 +59,6 @@ void test_nuttx_fs_truncate01(FAR void **state) char buf[80]; const char *s1 = "0123456789"; const char *s2 = "abcde"; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* open file */ @@ -71,7 +68,6 @@ void test_nuttx_fs_truncate01(FAR void **state) #else assert_int_in_range(fd, 0, 512); #endif - test_state->fd1 = fd; /* do write */ @@ -104,7 +100,6 @@ void test_nuttx_fs_truncate01(FAR void **state) fd = open(TESTFILE, O_RDONLY); assert_true(fd > 0); - test_state->fd1 = fd; /* read file */ diff --git a/testing/testsuites/kernel/fs/cases/fs_unlink_test.c b/testing/testsuites/kernel/fs/cases/fs_unlink_test.c index 7d52eb425..d07c84b36 100644 --- a/testing/testsuites/kernel/fs/cases/fs_unlink_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_unlink_test.c @@ -58,15 +58,10 @@ void test_nuttx_fs_unlink01(FAR void **state) { - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; - /* open file */ int fd = open(test_file, O_RDWR | O_CREAT, 0777); assert_true(fd > 0); - test_state->fd1 = fd; char buf[MAXSIZE] = { diff --git a/testing/testsuites/kernel/fs/cases/fs_write_test.c b/testing/testsuites/kernel/fs/cases/fs_write_test.c index 75bbc96ef..5318acbe2 100644 --- a/testing/testsuites/kernel/fs/cases/fs_write_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_write_test.c @@ -97,15 +97,11 @@ void test_nuttx_fs_write02(FAR void **state) FILE *fp; long offset; char content[15] = "asdfgtgtrf"; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* fopen file */ fp = fopen(TESTFILENAME, "a+"); assert_non_null(fp); - test_state->fd1 = fileno(fp); /* do fwrite */ @@ -147,15 +143,11 @@ void test_nuttx_fs_write03(FAR void **state) FILE *fp; long offset; char content[15] = "asdfgtgtrf"; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* fopen file */ fp = fopen(TESTFILENAME3, "a+"); assert_non_null(fp); - test_state->fd1 = fileno(fp); /* do fwrite */ From 9c022949e48503d840964a659458379c8436eb44 Mon Sep 17 00:00:00 2001 From: wangxingxing Date: Fri, 23 Jan 2026 19:22:09 +0800 Subject: [PATCH 187/568] fs/test:Fix formatting check issues fix the typo error of fs cases Signed-off-by: wangxingxing --- testing/testsuites/kernel/fs/cases/fs_fsync_test.c | 6 +++--- .../testsuites/kernel/fs/cases/fs_readdir_test.c | 2 +- .../testsuites/kernel/fs/cases/fs_rename_test.c | 2 +- .../testsuites/kernel/fs/cases/fs_stream_test.c | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/testing/testsuites/kernel/fs/cases/fs_fsync_test.c b/testing/testsuites/kernel/fs/cases/fs_fsync_test.c index 10c57becc..f69c50a87 100644 --- a/testing/testsuites/kernel/fs/cases/fs_fsync_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_fsync_test.c @@ -102,7 +102,7 @@ void test_nuttx_fs_fsync02(FAR void **state) int ret; char *buf = NULL; int bufsize = 4096; - ssize_t writen = 0; + ssize_t written = 0; struct statfs statfsbuf; struct fs_testsuites_state_s *test_state; struct mallinfo mem_info; @@ -154,8 +154,8 @@ void test_nuttx_fs_fsync02(FAR void **state) /* do write */ - writen = write(fd, buf, bufsize); - assert_int_in_range(writen, 1, bufsize); + written = write(fd, buf, bufsize); + assert_int_in_range(written, 1, bufsize); /* refresh to storage */ diff --git a/testing/testsuites/kernel/fs/cases/fs_readdir_test.c b/testing/testsuites/kernel/fs/cases/fs_readdir_test.c index 864f4ded0..8e821f3a1 100644 --- a/testing/testsuites/kernel/fs/cases/fs_readdir_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_readdir_test.c @@ -73,7 +73,7 @@ void test_nuttx_fs_readdir01(FAR void **state) fd = open(filename[i], O_RDWR | O_CREAT, 0700); assert_true(fd > 0); - /* do wirte */ + /* do write */ ret = write(fd, "hello!\n", 6); assert_uint_in_range(ret, 1, 6); diff --git a/testing/testsuites/kernel/fs/cases/fs_rename_test.c b/testing/testsuites/kernel/fs/cases/fs_rename_test.c index 36d1d5aba..b76fe2be9 100644 --- a/testing/testsuites/kernel/fs/cases/fs_rename_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_rename_test.c @@ -67,7 +67,7 @@ void test_nuttx_fs_rename01(FAR void **state) ret = write(fd, buffer, 50); assert_int_in_range(ret, 1, 50); - /* close file befor rename */ + /* close file before rename */ close(fd); diff --git a/testing/testsuites/kernel/fs/cases/fs_stream_test.c b/testing/testsuites/kernel/fs/cases/fs_stream_test.c index 2f7f1670f..dfc83ea93 100644 --- a/testing/testsuites/kernel/fs/cases/fs_stream_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_stream_test.c @@ -130,7 +130,7 @@ void test_nuttx_fs_stream02(FAR void **state) pos = ftell(stream); if (pos != 0) { - syslog(LOG_ERR, "file pointer descrepancy 1, errno %d\n", + syslog(LOG_ERR, "file pointer discrepancy 1, errno %d\n", errno); fclose(stream); assert_true(1 == 0); @@ -148,7 +148,7 @@ void test_nuttx_fs_stream02(FAR void **state) { syslog( LOG_ERR, - "strlen(junk)=%zi: file pointer descrepancy 2 (pos=%li)", + "strlen(junk)=%zi: file pointer discrepancy 2 (pos=%li)", strlen(junk), pos); fclose(stream); assert_true(1 == 0); @@ -161,7 +161,7 @@ void test_nuttx_fs_stream02(FAR void **state) { fclose(stream); syslog(LOG_ERR, - "file pointer descrepancy 3 (pos=%li, wanted pos=0)", + "file pointer discrepancy 3 (pos=%li, wanted pos=0)", pos); assert_true(1 == 0); } @@ -179,7 +179,7 @@ void test_nuttx_fs_stream02(FAR void **state) fclose(stream); syslog( LOG_ERR, - "strlen(junk)=%zi: file pointer descrepancy 4 (pos=%li)", + "strlen(junk)=%zi: file pointer discrepancy 4 (pos=%li)", strlen(junk), pos); assert_true(1 == 0); } @@ -197,7 +197,7 @@ void test_nuttx_fs_stream02(FAR void **state) fclose(stream); syslog( LOG_ERR, - "strlen(junk)=%zi: file pointer descrepancy 5 (pos=%li)", + "strlen(junk)=%zi: file pointer discrepancy 5 (pos=%li)", strlen(junk), pos); assert_true(1 == 0); } @@ -214,7 +214,7 @@ void test_nuttx_fs_stream02(FAR void **state) { fclose(stream); syslog(LOG_ERR, - "file pointer descrepancy 6 (pos=%li, wanted pos=0)", + "file pointer discrepancy 6 (pos=%li, wanted pos=0)", pos); assert_true(1 == 0); } @@ -226,7 +226,7 @@ void test_nuttx_fs_stream02(FAR void **state) { syslog( LOG_ERR, - "strlen(junk)=%zi: file pointer descrepancy 7 (pos=%li)", + "strlen(junk)=%zi: file pointer discrepancy 7 (pos=%li)", strlen(junk), pos); assert_true(1 == 0); } From 80c2b43197dd4b4be088519f3287377c51d56384 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Mon, 26 Jan 2026 19:52:18 +0800 Subject: [PATCH 188/568] testing/ostest: fix uninitialized variable warning in wdog test Initialize the flags variable to 0 to fix compiler warning about potential use of uninitialized variable. The flags variable is conditionally assigned in wdtest_rand() based on callback count. Signed-off-by: hujun5 --- testing/ostest/wdog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/ostest/wdog.c b/testing/ostest/wdog.c index c00a7f9b6..273a680e9 100644 --- a/testing/ostest/wdog.c +++ b/testing/ostest/wdog.c @@ -147,7 +147,7 @@ static void wdtest_rand(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, clock_t wdset_tick; sclock_t delay_tick; sclock_t diff; - irqstate_t flags; + irqstate_t flags = 0; /* Perform multiple iterations with random delays. */ From 35f3690a4c46ed8e81312d7211652bd5358a57c9 Mon Sep 17 00:00:00 2001 From: fangpeina Date: Tue, 16 Dec 2025 23:09:50 +0800 Subject: [PATCH 189/568] nshlib: Add stderr redirection support This commit implements stderr redirection in HSN, support Bash-like syntax for redirecting standard error output. Support both foreground and background commands. example: - nsh> ls noexists 2> err.log - nsh> ls noexists 2> err.log & - nsh> ls noexists 2>> err.log - nsh> sh < /dev/ttyS0 > /dev/ttyS0 2> /dev/ttyS1 & - nsh> sh < /dev/ttyS0 > /dev/ttyS0 2>&1 & Signed-off-by: fangpeina --- include/nshlib/nshlib.h | 11 ++-- nshlib/nsh.h | 1 + nshlib/nsh_console.c | 5 +- nshlib/nsh_console.h | 20 +++---- nshlib/nsh_fileapps.c | 33 +++++++++++ nshlib/nsh_parse.c | 119 ++++++++++++++++++++++++++++++++++++++-- nshlib/nsh_script.c | 2 +- 7 files changed, 168 insertions(+), 23 deletions(-) diff --git a/include/nshlib/nshlib.h b/include/nshlib/nshlib.h index f9565894a..f2153fed0 100644 --- a/include/nshlib/nshlib.h +++ b/include/nshlib/nshlib.h @@ -69,21 +69,24 @@ struct nsh_param_s { - /* Redirect input/output through `fd` OR `path_name` + /* Redirect input/output/error through `fd` OR `path_name` * * Select one: - * 1. Using fd_in/fd_out as oldfd for dup2() if greater than -1. - * 2. Using file_in/file_out as full path to the file if it is - * not NULL, and oflags_in/oflags_out as flags for open(). + * 1. Using fd_in/fd_out/fd_err as oldfd for dup2() if greater than -1. + * 2. Using file_in/file_out/file_err as full path to the file if it is + * not NULL, and oflags_in/oflags_out/oflags_err as flags for open(). */ int fd_in; int fd_out; + int fd_err; int oflags_in; int oflags_out; + int oflags_err; FAR const char *file_in; FAR const char *file_out; + FAR const char *file_err; }; /**************************************************************************** diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 74f4032cc..8ea334d07 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -655,6 +655,7 @@ struct nsh_parser_s #endif bool np_redir_out; /* true: Output from the last command was re-directed */ bool np_redir_in; /* true: Input from the last command was re-directed */ + bool np_redir_err; /* true: Error from the last command was re-directed */ bool np_fail; /* true: The last command failed */ pid_t np_lastpid; /* Pid of the last command executed */ #ifdef NSH_HAVE_VARS diff --git a/nshlib/nsh_console.c b/nshlib/nsh_console.c index 2d8c315ad..cb95e0342 100644 --- a/nshlib/nsh_console.c +++ b/nshlib/nsh_console.c @@ -76,7 +76,7 @@ static int nsh_erroroutput(FAR struct nsh_vtbl_s *vtbl, #endif static FAR char *nsh_consolelinebuffer(FAR struct nsh_vtbl_s *vtbl); static void nsh_consoleredirect(FAR struct nsh_vtbl_s *vtbl, int fd_in, - int fd_out, FAR uint8_t *save); + int fd_out, int fd_err, FAR uint8_t *save); static void nsh_consoleundirect(FAR struct nsh_vtbl_s *vtbl, FAR uint8_t *save); static void nsh_consoleexit(FAR struct nsh_vtbl_s *vtbl, @@ -332,7 +332,7 @@ static void nsh_consolerelease(FAR struct nsh_vtbl_s *vtbl) ****************************************************************************/ static void nsh_consoleredirect(FAR struct nsh_vtbl_s *vtbl, int fd_in, - int fd_out, FAR uint8_t *save) + int fd_out, int fd_err, FAR uint8_t *save) { FAR struct console_stdio_s *pstate = (FAR struct console_stdio_s *)vtbl; FAR struct serialsave_s *ssave = (FAR struct serialsave_s *)save; @@ -354,6 +354,7 @@ static void nsh_consoleredirect(FAR struct nsh_vtbl_s *vtbl, int fd_in, OUTFD(pstate) = fd_out; INFD(pstate) = fd_in; + ERRFD(pstate) = fd_err; } /**************************************************************************** diff --git a/nshlib/nsh_console.h b/nshlib/nsh_console.h index 0b94a2b6b..268d03379 100644 --- a/nshlib/nsh_console.h +++ b/nshlib/nsh_console.h @@ -43,15 +43,15 @@ /* Method access macros */ -#define nsh_clone(v) (v)->clone(v) -#define nsh_release(v) (v)->release(v) -#define nsh_write(v,b,n) (v)->write(v,b,n) -#define nsh_read(v,b,n) (v)->read(v,b,n) -#define nsh_ioctl(v,c,a) (v)->ioctl(v,c,a) -#define nsh_linebuffer(v) (v)->linebuffer(v) -#define nsh_redirect(v,fi,fo,s) (v)->redirect(v,fi,fo,s) -#define nsh_undirect(v,s) (v)->undirect(v,s) -#define nsh_exit(v,s) (v)->exit(v,s) +#define nsh_clone(v) (v)->clone(v) +#define nsh_release(v) (v)->release(v) +#define nsh_write(v,b,n) (v)->write(v,b,n) +#define nsh_read(v,b,n) (v)->read(v,b,n) +#define nsh_ioctl(v,c,a) (v)->ioctl(v,c,a) +#define nsh_linebuffer(v) (v)->linebuffer(v) +#define nsh_redirect(v,fi,fo,fe,s) (v)->redirect(v,fi,fo,fe,s) +#define nsh_undirect(v,s) (v)->undirect(v,s) +#define nsh_exit(v,s) (v)->exit(v,s) #ifdef CONFIG_CPP_HAVE_VARARGS # define nsh_error(v, ...) (v)->error(v, ##__VA_ARGS__) @@ -127,7 +127,7 @@ struct nsh_vtbl_s printf_like(2, 3); FAR char *(*linebuffer)(FAR struct nsh_vtbl_s *vtbl); void (*redirect)(FAR struct nsh_vtbl_s *vtbl, int fd_in, int fd_out, - FAR uint8_t *save); + int fd_err, FAR uint8_t *save); void (*undirect)(FAR struct nsh_vtbl_s *vtbl, FAR uint8_t *save); void (*exit)(FAR struct nsh_vtbl_s *vtbl, int status) noreturn_function; diff --git a/nshlib/nsh_fileapps.c b/nshlib/nsh_fileapps.c index 54efd6de2..66f41e36f 100644 --- a/nshlib/nsh_fileapps.c +++ b/nshlib/nsh_fileapps.c @@ -177,6 +177,39 @@ int nsh_fileapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, } } #endif + + /* Handle redirection of error output */ + + if (param->file_err) + { + /* 2> file: Redirect stderr to a file */ + + ret = posix_spawn_file_actions_addopen(&file_actions, 2, + param->file_err, + param->oflags_err, + 0644); + if (ret != 0) + { + nsh_error(vtbl, g_fmtcmdfailed, cmd, + "posix_spawn_file_actions_addopen", + NSH_ERRNO); + goto errout_with_attrs; + } + } + else if (param->fd_err != -1) + { + /* 2>&1: Redirect stderr to stdout */ + + ret = posix_spawn_file_actions_adddup2(&file_actions, + param->fd_err, 2); + if (ret != 0) + { + nsh_error(vtbl, g_fmtcmdfailed, cmd, + "posix_spawn_file_actions_adddup2", + NSH_ERRNO); + goto errout_with_attrs; + } + } } #ifdef CONFIG_BUILTIN diff --git a/nshlib/nsh_parse.c b/nshlib/nsh_parse.c index 9b1bde875..9a67cc845 100644 --- a/nshlib/nsh_parse.c +++ b/nshlib/nsh_parse.c @@ -264,6 +264,12 @@ static const char g_redirect_out2[] = ">>"; static const size_t g_redirect_out2_len = sizeof(g_redirect_out2) - 1; static const char g_redirect_in1[] = "<"; static const size_t g_redirect_in1_len = sizeof(g_redirect_in1) - 1; +static const char g_redirect_err1[] = "2>"; +static const size_t g_redirect_err1_len = sizeof(g_redirect_err1) - 1; +static const char g_redirect_err2[] = "2>>"; +static const size_t g_redirect_err2_len = sizeof(g_redirect_err2) - 1; +static const char g_redirect_err3[] = "2>&1"; +static const size_t g_redirect_err3_len = sizeof(g_redirect_err3) - 1; #ifdef CONFIG_NSH_PIPELINE static const char g_pipeline1[] = "|"; static const size_t g_pipeline1_len = sizeof(g_pipeline1) - 1; @@ -503,6 +509,7 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl, FAR const struct nsh_param_s *param) { int fd_out = STDOUT_FILENO; + int fd_err = STDERR_FILENO; int fd_in = STDIN_FILENO; int ret; @@ -703,11 +710,36 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl, } } - /* Handle redirection of stdin/stdout file descriptor */ + /* Redirected error output? */ - if (vtbl->np.np_redir_out || vtbl->np.np_redir_in) + if (vtbl->np.np_redir_err) { - nsh_redirect(vtbl, fd_in, fd_out, save); + if (param->file_err) + { + /* 2> file: Open the redirection file for stderr */ + + fd_err = open(param->file_err, param->oflags_err, 0666); + if (fd_err < 0) + { + nsh_error(vtbl, g_fmtcmdfailed, argv[0], "open", + NSH_ERRNO); + return nsh_saveresult(vtbl, true); + } + } + else + { + /* 2>&1: redirect stderr to current stdout fd */ + + fd_err = fd_out; + } + } + + /* Handle redirection of stdin/stdout/stderr file descriptor */ + + if (vtbl->np.np_redir_out || vtbl->np.np_redir_in || + vtbl->np.np_redir_err) + { + nsh_redirect(vtbl, fd_in, fd_out, fd_err, save); } /* Then execute the command in "foreground" -- i.e., while the user @@ -723,7 +755,8 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl, * file descriptor. */ - if (vtbl->np.np_redir_out || vtbl->np.np_redir_in) + if (vtbl->np.np_redir_out || vtbl->np.np_redir_in || + vtbl->np.np_redir_err) { nsh_undirect(vtbl, save); fd_out = -1; @@ -885,10 +918,13 @@ static FAR char *nsh_cmdparm(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline, { .fd_in = -1, .fd_out = -1, + .fd_err = -1, .oflags_in = 0, .oflags_out = O_WRONLY | O_CREAT | O_TRUNC, + .oflags_err = O_WRONLY | O_CREAT | O_TRUNC, .file_in = NULL, - .file_out = NULL + .file_out = NULL, + .file_err = NULL }; FAR char *tmpfile; @@ -2447,10 +2483,13 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) { .fd_in = -1, .fd_out = -1, + .fd_err = -1, .oflags_in = 0, .oflags_out = 0, + .oflags_err = 0, .file_in = NULL, - .file_out = NULL + .file_out = NULL, + .file_err = NULL }; #ifdef CONFIG_NSH_PIPELINE @@ -2469,6 +2508,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) int ret; bool redirect_out_save = false; bool redirect_in_save = false; + bool redirect_err_save = false; #ifdef CONFIG_NSH_PIPELINE bool bg_save = false; #endif @@ -2492,6 +2532,7 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) vtbl->np.np_redir_out = false; vtbl->np.np_redir_in = false; + vtbl->np.np_redir_err = false; /* Parse out the command at the beginning of the line */ @@ -2692,6 +2733,60 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline) param.oflags_in = O_RDONLY; param.file_in = nsh_getfullpath(vtbl, arg); } + else if (!strncmp(argv[argc], g_redirect_err3, g_redirect_err3_len)) + { + redirect_err_save = vtbl->np.np_redir_err; + vtbl->np.np_redir_err = true; + param.fd_err = STDOUT_FILENO; + } + else if (!strncmp(argv[argc], g_redirect_err2, g_redirect_err2_len)) + { + FAR char *arg; + if (argv[argc][g_redirect_err2_len]) + { + arg = &argv[argc][g_redirect_err2_len]; + } + else + { + arg = nsh_argument(vtbl, &saveptr, &memlist, NULL, &isenvvar); + } + + if (!arg) + { + nsh_error(vtbl, g_fmtarginvalid, cmd); + ret = ERROR; + goto dynlist_free; + } + + redirect_err_save = vtbl->np.np_redir_err; + vtbl->np.np_redir_err = true; + param.oflags_err = O_WRONLY | O_CREAT | O_APPEND; + param.file_err = nsh_getfullpath(vtbl, arg); + } + else if (!strncmp(argv[argc], g_redirect_err1, g_redirect_err1_len)) + { + FAR char *arg; + if (argv[argc][g_redirect_err1_len]) + { + arg = &argv[argc][g_redirect_err1_len]; + } + else + { + arg = nsh_argument(vtbl, &saveptr, &memlist, NULL, &isenvvar); + } + + if (!arg) + { + nsh_error(vtbl, g_fmtarginvalid, cmd); + ret = ERROR; + goto dynlist_free; + } + + redirect_err_save = vtbl->np.np_redir_err; + vtbl->np.np_redir_err = true; + param.oflags_err = O_WRONLY | O_CREAT | O_TRUNC; + param.file_err = nsh_getfullpath(vtbl, arg); + } #ifdef CONFIG_NSH_PIPELINE else if (!strncmp(argv[argc], g_pipeline1, g_pipeline1_len)) { @@ -2848,6 +2943,18 @@ dynlist_free: } #endif + /* Free the redirected error file path and restore state */ + + if (param.file_err) + { + nsh_freefullpath((char *)param.file_err); + } + + if (vtbl->np.np_redir_err) + { + vtbl->np.np_redir_err = redirect_err_save; + } + NSH_ALIASLIST_FREE(vtbl, &alist); NSH_MEMLIST_FREE(&memlist); #ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP diff --git a/nshlib/nsh_script.c b/nshlib/nsh_script.c index a0db4d6d0..21bef19e4 100644 --- a/nshlib/nsh_script.c +++ b/nshlib/nsh_script.c @@ -64,7 +64,7 @@ static int nsh_script_redirect(FAR struct nsh_vtbl_s *vtbl, fd = open(CONFIG_NSH_SCRIPT_REDIRECT_PATH, 0666); if (fd > 0) { - nsh_redirect(vtbl, 0, fd, save); + nsh_redirect(vtbl, 0, fd, fd, save); } } From 8aa48c4fb6a691a321bd167892c79a844ec52cf1 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Tue, 27 Jan 2026 14:14:26 +0800 Subject: [PATCH 190/568] examples: foc: Add critical section protection to FOC control loop Introduce CONFIG_EXAMPLES_FOC_CONTROL_CRITSEC configuration option to enable critical section protection in the FOC (Field-Oriented Control) motor control examples. This adds irq-safe critical sections around the main control loop processing to prevent race conditions and ensure atomic updates of motor control state and parameters during interrupt handling. Signed-off-by: hujun5 --- examples/foc/foc_fixed16_thr.c | 2 ++ examples/foc/foc_float_thr.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/examples/foc/foc_fixed16_thr.c b/examples/foc/foc_fixed16_thr.c index 2ba2998e6..3c9a8c77b 100644 --- a/examples/foc/foc_fixed16_thr.c +++ b/examples/foc/foc_fixed16_thr.c @@ -26,6 +26,8 @@ #include +#include + #include #include #include diff --git a/examples/foc/foc_float_thr.c b/examples/foc/foc_float_thr.c index af967f255..4c52b86bf 100644 --- a/examples/foc/foc_float_thr.c +++ b/examples/foc/foc_float_thr.c @@ -26,6 +26,8 @@ #include +#include + #include #include #include From 0faaed99a501bf6ba2cf54a339fd13ea48167def Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 22 Apr 2025 16:14:10 +0800 Subject: [PATCH 191/568] testing/drivertest: Fix timing issues on QEMU and sims. Since sim and qemu are not cycle accurate simulators, if the vCPU thread is preempted by other high priority tasks, it may cause timing issues. This is easy to happen when the test machine is busy. This commit modifies the condition of timing error and prints out the latency as a warning. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index 00b7fb203..d2855dfb4 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -41,7 +41,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define RTC_DEFAULT_DEVIATION 10 +#define RTC_DEFAULT_DEVIATION 100 #define DEFAULT_TIME_OUT 2 #define SLEEPSECONDS 10 @@ -159,6 +159,8 @@ static void posix_timer_callback(union sigval arg) (FAR struct posix_timer_state_s *)arg.sival_ptr; int range = get_timestamp() - (*sigev_para).tim; + syslog(0, "range: %d ms\n", range); + assert_in_range(range, sigev_para->it.it_interval.tv_sec * 1000 - sigev_para->deviation, sigev_para->it.it_interval.tv_sec * 1000 + sigev_para->deviation); From a4b43521f40ef60abaaaca393f4a064b91002b22 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 10 Jul 2025 11:05:42 +0800 Subject: [PATCH 192/568] testing/drivers: Fix posix timer assertions. On QEMU, if vcpus are preempted by other threads, the deviation of the timer might be very large, causing assertion failure. This commit addressed the problem. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index d2855dfb4..0870484cf 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -161,9 +161,7 @@ static void posix_timer_callback(union sigval arg) syslog(0, "range: %d ms\n", range); - assert_in_range(range, - sigev_para->it.it_interval.tv_sec * 1000 - sigev_para->deviation, - sigev_para->it.it_interval.tv_sec * 1000 + sigev_para->deviation); + assert(range >= sigev_para->it.it_interval.tv_sec * 1000); syslog(LOG_DEBUG, "callback trigger!!!\n"); (*sigev_para).tim = get_timestamp(); From 01e5e50619f53158f7d12a3f0eb2866944306c40 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 24 Jul 2025 20:31:32 +0800 Subject: [PATCH 193/568] testing/time: Relax the timing constraints. On SIM and QEMU, it is inevitable that the simulating vCPU got preempted by other threads, causing large timing delay. This commit relax the timing constraints to reduce the CT error. Signed-off-by: ouyangxiangzhen --- testing/testsuites/kernel/time/cases/clock_test_timer03.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/testsuites/kernel/time/cases/clock_test_timer03.c b/testing/testsuites/kernel/time/cases/clock_test_timer03.c index 7539f4479..76a42c760 100644 --- a/testing/testsuites/kernel/time/cases/clock_test_timer03.c +++ b/testing/testsuites/kernel/time/cases/clock_test_timer03.c @@ -123,7 +123,7 @@ void test_nuttx_clock_test_timer03(FAR void **state) start.tv_sec * (int64_t)(1e9) - start.tv_nsec; failed += (escaped < expected || - (escaped - expected) >= 20000000); /* 20000000, 2 ticks. */ + (escaped - expected) > 100000000ul); /* 100 ms */ syslog(LOG_INFO, "expected = %" PRId64 " escaped = %" PRId64 "failed = %d", expected, escaped, failed); } From ae7a0d81e9f4e1804b11116ea05adab73e5118bd Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 10 Jul 2025 11:05:42 +0800 Subject: [PATCH 194/568] testing/drivers: Fix posix timer assertions. On QEMU, if vcpus are preempted by other threads, the deviation of the timer might be very large, causing assertion failure. This commit addressed the problem. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index 0870484cf..a9db327b8 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -161,7 +161,8 @@ static void posix_timer_callback(union sigval arg) syslog(0, "range: %d ms\n", range); - assert(range >= sigev_para->it.it_interval.tv_sec * 1000); + assert(range >= sigev_para->it.it_interval.tv_sec * 1000 - + sigev_para->deviation); syslog(LOG_DEBUG, "callback trigger!!!\n"); (*sigev_para).tim = get_timestamp(); From a16c5451343528e6633be08088ea5170461a8e66 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Mon, 28 Jul 2025 14:12:18 +0800 Subject: [PATCH 195/568] testing/drivers: Fixed the wrong test-case. This commit fixed the wrong-test case where the time is acquired after the timer being set, leading to the assertion failure. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index a9db327b8..469ecc198 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -196,11 +196,11 @@ static void drivertest_posix_timer(FAR void **state) /* Start the timer */ + posix_timer_state->tim = get_timestamp(); + ret = timer_settime(timerid, 0, &(posix_timer_state->it), NULL); assert_return_code(ret, OK); - posix_timer_state->tim = get_timestamp(); - /* Get the timer status */ ret = timer_gettime(timerid, &it); From e0e9f3d7e564d3c746a1d9409869d46c0bafb88f Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 31 Dec 2024 09:45:44 +0800 Subject: [PATCH 196/568] apps/testing: Fix Coverity. This commit is to make Coverity happy. Signed-off-by: ouyangxiangzhen --- testing/sched/timerjitter/timerjitter.c | 29 +++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/testing/sched/timerjitter/timerjitter.c b/testing/sched/timerjitter/timerjitter.c index 214bbf735..3a73ee298 100644 --- a/testing/sched/timerjitter/timerjitter.c +++ b/testing/sched/timerjitter/timerjitter.c @@ -137,12 +137,15 @@ static FAR void *timerjitter(FAR void *arg) struct timespec next; struct timespec intv; struct itimerspec tspec; - struct sigevent sigev; sigset_t sigset; timer_t timer; int64_t diff; int sigs; int ret; + struct sigevent sigev = + { + 0 + }; sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); @@ -154,8 +157,20 @@ static FAR void *timerjitter(FAR void *arg) sigev.sigev_notify = SIGEV_SIGNAL; sigev.sigev_signo = SIGALRM; - timer_create(param->clockid, &sigev, &timer); - clock_gettime(param->clockid, &now); + ret = timer_create(param->clockid, &sigev, &timer); + + if (ret != 0) + { + printf("timer_create failed %d\n", ret); + return NULL; + } + + ret = clock_gettime(param->clockid, &now); + + if (ret) + { + printf("clock_gettime failed %d\n", ret); + } next = now; calc_next(&next, &intv); @@ -167,7 +182,13 @@ static FAR void *timerjitter(FAR void *arg) /* Using TIMER_ABSTIME */ tspec.it_value = next; - timer_settime(timer, TIMER_ABSTIME, &tspec, NULL); + ret = timer_settime(timer, TIMER_ABSTIME, &tspec, NULL); + + if (ret) + { + printf("timer_settime failed %d\n", ret); + return NULL; + } param->avg = 0; param->max = 0; From f687088453a5b670509939bcb74d556ef6e31afb Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Fri, 21 Feb 2025 10:57:37 +0800 Subject: [PATCH 197/568] apps/testing: Fix timerjitter interval This commit increased the default interval of the timerjitter to avoid errors with large USEC_PER_TICK setting. Signed-off-by: ouyangxiangzhen --- testing/sched/timerjitter/timerjitter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/sched/timerjitter/timerjitter.c b/testing/sched/timerjitter/timerjitter.c index 3a73ee298..56697b2bc 100644 --- a/testing/sched/timerjitter/timerjitter.c +++ b/testing/sched/timerjitter/timerjitter.c @@ -35,7 +35,7 @@ ****************************************************************************/ #define DEFAULT_CLOCKID CLOCK_REALTIME -#define DEFAULT_INTERVAL 1000 +#define DEFAULT_INTERVAL 1000 * USEC_PER_TICK #define DEFAULT_ITERATION 1000 /* Fix compilation error for Non-NuttX OS */ From 429a65901f86c6ec5062d79250cdd87b9fe90ea3 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Mon, 24 Feb 2025 09:51:38 +0800 Subject: [PATCH 198/568] apps/testing: Fix timerjitter iteration This commit used the interval to calculate the timejitter iteration. Signed-off-by: ouyangxiangzhen --- testing/sched/timerjitter/timerjitter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/sched/timerjitter/timerjitter.c b/testing/sched/timerjitter/timerjitter.c index 56697b2bc..01eed10d5 100644 --- a/testing/sched/timerjitter/timerjitter.c +++ b/testing/sched/timerjitter/timerjitter.c @@ -35,8 +35,8 @@ ****************************************************************************/ #define DEFAULT_CLOCKID CLOCK_REALTIME -#define DEFAULT_INTERVAL 1000 * USEC_PER_TICK -#define DEFAULT_ITERATION 1000 +#define DEFAULT_INTERVAL (1000 * USEC_PER_TICK) +#define DEFAULT_ITERATION (USEC_PER_SEC / DEFAULT_INTERVAL) /* Fix compilation error for Non-NuttX OS */ #ifndef FAR From ce3e35233cf461de13af73be8bf28f370a7e6935 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 3 Apr 2025 14:13:40 +0800 Subject: [PATCH 199/568] benchmark/taclebench: Add clock measurement. This commit added clock measurement for taclebench. Signed-off-by: ouyangxiangzhen --- ...dd-makefile-and-all-in-one-main-file.patch | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/benchmarks/tacle-bench/0001-tacle-bench-add-makefile-and-all-in-one-main-file.patch b/benchmarks/tacle-bench/0001-tacle-bench-add-makefile-and-all-in-one-main-file.patch index 4958ac5a8..fb1e2e400 100644 --- a/benchmarks/tacle-bench/0001-tacle-bench-add-makefile-and-all-in-one-main-file.patch +++ b/benchmarks/tacle-bench/0001-tacle-bench-add-makefile-and-all-in-one-main-file.patch @@ -1,10 +1,11 @@ -From 71f51cd5ca4f492a464fb12d5bce91e5fbba300a Mon Sep 17 00:00:00 2001 +From 6d0be04a4b4208447e75c369e9811d089f466739 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen -Date: Tue, 11 Jun 2024 16:01:23 +0800 +Date: Thu, 3 Apr 2025 11:59:02 +0800 Subject: [PATCH] tacle-bench: add makefile and all-in-one main file The original taclebench is used for WCET analysis. This commit allows most taclebench test cases (except parallel test cases) to be compiled and executed. +Change-Id: I707b8ac58d3ddc4b7974c5bedecac1a7b5c887f9 Signed-off-by: ouyangxiangzhen --- Makefile | 12 + @@ -65,14 +66,14 @@ Signed-off-by: ouyangxiangzhen bench/test/cover/cover.c | 3 + bench/test/duff/duff.c | 3 + bench/test/test3/test3.c | 3 + - taclebench.c | 349 ++++++++++++++++++ - 59 files changed, 532 insertions(+) + taclebench.c | 366 ++++++++++++++++++ + 59 files changed, 549 insertions(+) create mode 100644 Makefile create mode 100644 taclebench.c diff --git a/Makefile b/Makefile new file mode 100644 -index 0000000..2385c61 +index 0000000..75ca0a1 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ @@ -83,7 +84,7 @@ index 0000000..2385c61 +TEST_SRCS := $(shell find bench/test -name "*.c") + +all: -+ cc -DALL_IN_ONE ${APP_SRCS} ${KERNEL_SRCS} ${SEQUENTIAL_SRCS} ${TEST_SRCS} bench/kernel/cosf/wcclibm.c taclebench.c -static -o taclebench ++ cc -DALL_IN_ONE ${APP_SRCS} ${KERNEL_SRCS} ${SEQUENTIAL_SRCS} ${TEST_SRCS} bench/kernel/cosf/wcclibm.c taclebench.c -static -o taclebench -O3 + +clean: + rm -f taclebench @@ -888,11 +889,12 @@ index 0235738..6eaf8c2 100755 diff --git a/taclebench.c b/taclebench.c new file mode 100644 -index 0000000..1231b87 +index 0000000..aaff1bb --- /dev/null +++ b/taclebench.c -@@ -0,0 +1,349 @@ +@@ -0,0 +1,366 @@ +#include ++#include + +int main_epic(void); +int main_mpeg2(void); @@ -954,6 +956,10 @@ index 0000000..1231b87 + +int main(void) +{ ++ struct timespec start_ts; ++ struct timespec end_ts; ++ clock_gettime(CLOCK_MONOTONIC, &start_ts); ++ + if (main_epic() != 0) + { + printf("main_epic error\n"); @@ -1239,6 +1245,18 @@ index 0000000..1231b87 + printf("main_bitonic error\n"); + } + ++ clock_gettime(CLOCK_MONOTONIC, &end_ts); ++ long sec_diff = end_ts.tv_sec - start_ts.tv_sec; ++ long nsec_diff = end_ts.tv_nsec - start_ts.tv_nsec; ++ ++ if (nsec_diff < 0) ++ { ++ sec_diff -= 1; ++ nsec_diff += 1000000000; ++ } ++ ++ printf("%ld.%09ld seconds\n", sec_diff, nsec_diff); ++ + return 0; +} -- From 69bfda87361700d774f7a69ddeddc7b9d35bf05f Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Wed, 16 Apr 2025 19:55:07 +0800 Subject: [PATCH 200/568] apps/ostest: Fix wqueue_test in flat mode. This commit re-enabled wqueue_test in flat mode. Signed-off-by: ouyangxiangzhen --- testing/ostest/ostest_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 6bf75d86f..4e2ca3484 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -381,7 +381,7 @@ static int user_main(int argc, char *argv[]) check_test_memory_usage(); #endif -#if !defined(CONFIG_DISABLE_PTHREAD) && defined(__KERNEL__) && \ +#if !defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_BUILD_FLAT) && \ defined(CONFIG_SCHED_WORKQUEUE) /* Check work queues */ From 62fe1a3ac504f1e2af410ebbde4c34bb5d5abf2d Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Mon, 26 May 2025 21:07:14 +0800 Subject: [PATCH 201/568] ostest/wdog: Fix a synchronizing bug. If we updated `callback_cnt` before the `triggered_tick` in the wdog timer callback, the `wdtest_rand` might failed randomly. This commit fixed the synchronizing bug by swapping the execution order of updating. Signed-off-by: ouyangxiangzhen --- testing/ostest/wdog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testing/ostest/wdog.c b/testing/ostest/wdog.c index 273a680e9..e64f1246f 100644 --- a/testing/ostest/wdog.c +++ b/testing/ostest/wdog.c @@ -70,13 +70,13 @@ static void wdtest_callback(wdparm_t param) { FAR wdtest_param_t *wdtest_param = (FAR wdtest_param_t *)param; - /* Increment the callback count */ - - wdtest_param->callback_cnt += 1; - /* Record the system tick at which the callback was triggered */ wdtest_param->triggered_tick = clock_systime_ticks(); + + /* Increment the callback count */ + + wdtest_param->callback_cnt += 1; } static void wdtest_checkdelay(sclock_t diff, sclock_t delay_tick) From b9bf7f5c4fb7c0e2f789009b3123f7481b9378df Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 2 Sep 2025 10:50:17 +0800 Subject: [PATCH 202/568] testing/drivers: Change uint32_t time to uint64_t. This commmit fixed the time multiplication overflow issue. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index 469ecc198..ccca6e1c2 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -64,7 +64,7 @@ struct posix_timer_state_s { struct itimerspec it; - uint32_t tim; + uint64_t tim; uint32_t deviation; }; @@ -140,12 +140,12 @@ static void parse_commandline( * Name: get_timestamp ****************************************************************************/ -static uint32_t get_timestamp(void) +static uint64_t get_timestamp(void) { struct timespec ts; - uint32_t ms; + uint64_t ms; clock_gettime(CLOCK_MONOTONIC, &ts); - ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + ms = (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; return ms; } From 35cf746025fbd23f6367c0e8cb014bb110219b83 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 2 Sep 2025 11:06:03 +0800 Subject: [PATCH 203/568] testing/drivers: Fix wrong test-cases. This commit fixed totally wrong test-cases for the periodical timers. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index ccca6e1c2..13eb4425a 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -65,6 +65,7 @@ struct posix_timer_state_s { struct itimerspec it; uint64_t tim; + uint32_t trigger_count; uint32_t deviation; }; @@ -157,15 +158,16 @@ static void posix_timer_callback(union sigval arg) { FAR struct posix_timer_state_s *sigev_para = (FAR struct posix_timer_state_s *)arg.sival_ptr; - int range = get_timestamp() - (*sigev_para).tim; + uint64_t expected = (*sigev_para).tim + + DEFAULT_TIME_OUT * (*sigev_para).trigger_count; + int range = get_timestamp() - expected; syslog(0, "range: %d ms\n", range); - assert(range >= sigev_para->it.it_interval.tv_sec * 1000 - - sigev_para->deviation); + assert(range >= sigev_para->it.it_interval.tv_sec * 1000); syslog(LOG_DEBUG, "callback trigger!!!\n"); - (*sigev_para).tim = get_timestamp(); + (*sigev_para).trigger_count++; } /**************************************************************************** @@ -226,6 +228,7 @@ int main(int argc, FAR char *argv[]) .it.it_value.tv_nsec = 0, .it.it_interval.tv_sec = DEFAULT_TIME_OUT, .it.it_interval.tv_nsec = 0, + .trigger_count = 0, .deviation = RTC_DEFAULT_DEVIATION }; From 1b8c90c12d3f59b839fcbb2a18e51c9f55a25e0c Mon Sep 17 00:00:00 2001 From: jiangtao16 Date: Fri, 20 Jun 2025 16:41:02 +0800 Subject: [PATCH 204/568] ostest: Add spinlock/rspinlock. This commit added spinlock/rspinlock test. Signed-off-by: jiangtao16 --- testing/ostest/CMakeLists.txt | 2 +- testing/ostest/Kconfig | 9 ++ testing/ostest/Makefile | 2 +- testing/ostest/ostest.h | 4 + testing/ostest/ostest_main.c | 4 + testing/ostest/spinlock.c | 184 ++++++++++++++++++++++++++++++++++ 6 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 testing/ostest/spinlock.c diff --git a/testing/ostest/CMakeLists.txt b/testing/ostest/CMakeLists.txt index 777c68744..35b0c5596 100644 --- a/testing/ostest/CMakeLists.txt +++ b/testing/ostest/CMakeLists.txt @@ -22,7 +22,7 @@ if(CONFIG_TESTING_OSTEST) - set(SRCS getopt.c libc_memmem.c restart.c sighelper.c) + set(SRCS getopt.c libc_memmem.c restart.c sighelper.c spinlock.c) if(CONFIG_ENABLE_ALL_SIGNALS) list(APPEND SRCS sighand.c signest.c) diff --git a/testing/ostest/Kconfig b/testing/ostest/Kconfig index 83054fa68..100afb73e 100644 --- a/testing/ostest/Kconfig +++ b/testing/ostest/Kconfig @@ -115,4 +115,13 @@ config TESTING_OSTEST_POWEROFF default n depends on BOARDCTL_POWEROFF && TESTING_OSTEST_WAITRESULT +config TESTING_OSTEST_SPINLOCK_THREADS + int "Number of spinlock test threads" + default 2 + range 1 32 + +config TEST_LOOP_SCALE + int "Loop scale of spinlock test (N x 10,000)" + default 100 + endif # TESTING_OSTEST diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile index 1fedfcf54..b8be63a62 100644 --- a/testing/ostest/Makefile +++ b/testing/ostest/Makefile @@ -31,7 +31,7 @@ MODULE = $(CONFIG_TESTING_OSTEST) # NuttX OS Test -CSRCS = getopt.c libc_memmem.c restart.c sighelper.c +CSRCS = getopt.c libc_memmem.c restart.c sighelper.c spinlock.c ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) CSRCS += sighand.c signest.c diff --git a/testing/ostest/ostest.h b/testing/ostest/ostest.h index 321ecd2d3..1a396ba28 100644 --- a/testing/ostest/ostest.h +++ b/testing/ostest/ostest.h @@ -286,6 +286,10 @@ void setjmp_test(void); void smp_call_test(void); #endif +/* spinlock.c ***************************************************************/ + +void spinlock_test(void); + /* APIs exported (conditionally) by the OS specifically for testing of * priority inheritance */ diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 4e2ca3484..58ccc87fb 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -547,6 +547,10 @@ static int user_main(int argc, char *argv[]) #endif #endif + printf("\nuser_main: spinlock test\n"); + spinlock_test(); + check_test_memory_usage(); + #ifdef CONFIG_BUILD_FLAT printf("\nuser_main: wdog test\n"); wdog_test(); diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c new file mode 100644 index 000000000..2d71ea18f --- /dev/null +++ b/testing/ostest/spinlock.c @@ -0,0 +1,184 @@ +/**************************************************************************** + * apps/testing/ostest/spinlock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Preprocessor Definitions + ****************************************************************************/ + +#define THREAD_NUM CONFIG_TESTING_OSTEST_SPINLOCK_THREADS +#define LOOP_TIMES (CONFIG_TEST_LOOP_SCALE * 10000) + +enum lock_type_e +{ + RSPINLOCK, + SPINLOCK +}; + +struct spinlock_pub_args_s +{ + volatile uint32_t counter; + pthread_barrier_t barrier; + union + { + rspinlock_t rlock; + spinlock_t lock; + }; +}; + +struct spinlock_thread_args_s +{ + uint64_t delta; + FAR struct spinlock_pub_args_s *pub; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Helper functions for timespec calculating */ + +static inline uint64_t calc_diff(FAR struct timespec *start, + FAR struct timespec *end) +{ + uint64_t diff_sec = end->tv_sec - start->tv_sec; + long diff_nsec = end->tv_nsec - start->tv_nsec; + if (diff_nsec < 0) + { + diff_sec -= 1; + diff_nsec += 1000000000L; + } + + return diff_sec * 1000000000ULL + diff_nsec; +} + +#define LOCK_TEST_FUNC(lock_type, lock_func, unlock_func) \ +FAR static void * lock_type##_test_thread(FAR void *arg) \ +{ \ + struct spinlock_thread_args_s *param = \ + (struct spinlock_thread_args_s *)arg; \ + irqstate_t flags; \ + struct timespec start; \ + struct timespec end; \ + int i; \ + pthread_barrier_wait(¶m->pub->barrier); \ + clock_gettime(CLOCK_REALTIME, &start); \ + for (i = 0; i < LOOP_TIMES; i++) \ + { \ + flags = lock_func(¶m->pub->lock_type); \ + param->pub->counter++; \ + unlock_func(¶m->pub->lock_type, flags); \ + } \ + clock_gettime(CLOCK_REALTIME, &end); \ + param->delta = calc_diff(&start, &end); \ + return NULL; \ +} + +LOCK_TEST_FUNC(rlock, rspin_lock_irqsave, rspin_unlock_irqrestore) +LOCK_TEST_FUNC(lock, spin_lock_irqsave, spin_unlock_irqrestore) + +static inline void run_test_thread( + enum lock_type_e lock_type, + FAR void *(*thread_func)(FAR void *arg) + ) +{ + const char *test_type = (lock_type == RSPINLOCK) + ? "RSpin lock" : "Spin lock"; + printf("Test type: %s\n", test_type); + pthread_t tid[THREAD_NUM]; + struct spinlock_pub_args_s pub; + struct spinlock_thread_args_s param[THREAD_NUM]; + struct timespec stime; + struct timespec etime; + int i; + + pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1); + pub.counter = 0; + if (lock_type == RSPINLOCK) + { + rspin_lock_init(&pub.rlock); + } + else + { + spin_lock_init(&pub.lock); + } + + clock_gettime(CLOCK_REALTIME, &stime); + for (i = 0; i < THREAD_NUM; i++) + { + param[i].pub = &pub; + param[i].delta = 0; + pthread_create(&tid[i], NULL, thread_func, ¶m[i]); + } + + pthread_barrier_wait(&pub.barrier); + + for (i = 0; i < THREAD_NUM; i++) + { + pthread_join(tid[i], NULL); + } + + clock_gettime(CLOCK_REALTIME, &etime); + pthread_barrier_destroy(&pub.barrier); + uint64_t total_ns = 0; + for (i = 0; i < THREAD_NUM; i++) + { + total_ns += param[i].delta; + } + + printf("%s: Test Results:\n", test_type); + printf("%s: Final counter: %" PRIu32 "\n", test_type, pub.counter); + assert(pub.counter == THREAD_NUM * LOOP_TIMES); + printf("%s: Average time per thread: %" PRIu64 " ns\n" + , test_type, total_ns / THREAD_NUM); + printf("%s: Total execution time: %" PRIu64 " ns\n \n" + , test_type, calc_diff(&stime, &etime)); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spinlock_test + ****************************************************************************/ + +void spinlock_test(void) +{ + printf("Start Spin lock test:\n"); + printf("Thread num: %d, Loop times: %d\n\n", THREAD_NUM, LOOP_TIMES); + + run_test_thread(SPINLOCK, lock_test_thread); + + run_test_thread(RSPINLOCK, rlock_test_thread); +} From 7fb71aa57a8f6d6ebcb1429c77a441fcc0537986 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 10 Jul 2025 11:05:42 +0800 Subject: [PATCH 205/568] testing/drivers: Fix posix timer assertions. On QEMU, if vcpus are preempted by other threads, the deviation of the timer might be very large, causing assertion failure. This commit addressed the problem. Signed-off-by: ouyangxiangzhen --- testing/drivers/drivertest/drivertest_posix_timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index 13eb4425a..65b95ee24 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -164,7 +164,8 @@ static void posix_timer_callback(union sigval arg) syslog(0, "range: %d ms\n", range); - assert(range >= sigev_para->it.it_interval.tv_sec * 1000); + assert(range >= sigev_para->it.it_interval.tv_sec * 1000 - + sigev_para->deviation); syslog(LOG_DEBUG, "callback trigger!!!\n"); (*sigev_para).trigger_count++; From 36e701448cfd1b1f03369d91e6f27dd3f17eba1c Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 21 Oct 2025 17:47:59 +0800 Subject: [PATCH 206/568] ostest/spinlock: Check the return value. This commit added checking for the return value. Signed-off-by: ouyangxiangzhen --- testing/ostest/spinlock.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index 2d71ea18f..dd49c4d54 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -91,7 +91,7 @@ FAR static void * lock_type##_test_thread(FAR void *arg) \ struct timespec start; \ struct timespec end; \ int i; \ - pthread_barrier_wait(¶m->pub->barrier); \ + VERIFY(0 == pthread_barrier_wait(¶m->pub->barrier)); \ clock_gettime(CLOCK_REALTIME, &start); \ for (i = 0; i < LOOP_TIMES; i++) \ { \ @@ -122,7 +122,7 @@ static inline void run_test_thread( struct timespec etime; int i; - pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1); + VERIFY(0 == pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1)); pub.counter = 0; if (lock_type == RSPINLOCK) { @@ -141,7 +141,7 @@ static inline void run_test_thread( pthread_create(&tid[i], NULL, thread_func, ¶m[i]); } - pthread_barrier_wait(&pub.barrier); + VERIFY(0 == pthread_barrier_wait(&pub.barrier)); for (i = 0; i < THREAD_NUM; i++) { @@ -149,7 +149,8 @@ static inline void run_test_thread( } clock_gettime(CLOCK_REALTIME, &etime); - pthread_barrier_destroy(&pub.barrier); + VERIFY(0 == pthread_barrier_destroy(&pub.barrier)); + uint64_t total_ns = 0; for (i = 0; i < THREAD_NUM; i++) { From f86246f7c6a95f24ccaa605c4bb3d12d3cfd3415 Mon Sep 17 00:00:00 2001 From: anpeiyun Date: Sun, 26 Oct 2025 11:38:14 +0800 Subject: [PATCH 207/568] ostest/spinlock: fix the operations does not affect the result. When expanding the macro VERIY, (0 == pthread_barrier_wait(¶m->pub->barrier)) < 0 always false. Regardless of the value of its operands. Signed-off-by: anpeiyun --- testing/ostest/spinlock.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index dd49c4d54..df691d7ca 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -91,7 +91,12 @@ FAR static void * lock_type##_test_thread(FAR void *arg) \ struct timespec start; \ struct timespec end; \ int i; \ - VERIFY(0 == pthread_barrier_wait(¶m->pub->barrier)); \ + int ret; \ + ret = pthread_barrier_wait(¶m->pub->barrier); \ + if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) \ + { \ + ASSERT(false); \ + } \ clock_gettime(CLOCK_REALTIME, &start); \ for (i = 0; i < LOOP_TIMES; i++) \ { \ @@ -121,8 +126,14 @@ static inline void run_test_thread( struct timespec stime; struct timespec etime; int i; + int ret; + + ret = pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1); + if (ret != 0) + { + ASSERT(false); + } - VERIFY(0 == pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1)); pub.counter = 0; if (lock_type == RSPINLOCK) { @@ -141,7 +152,11 @@ static inline void run_test_thread( pthread_create(&tid[i], NULL, thread_func, ¶m[i]); } - VERIFY(0 == pthread_barrier_wait(&pub.barrier)); + ret = pthread_barrier_wait(&pub.barrier); + if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) + { + ASSERT(false); + } for (i = 0; i < THREAD_NUM; i++) { @@ -149,7 +164,11 @@ static inline void run_test_thread( } clock_gettime(CLOCK_REALTIME, &etime); - VERIFY(0 == pthread_barrier_destroy(&pub.barrier)); + ret = pthread_barrier_destroy(&pub.barrier); + if (ret != 0) + { + ASSERT(false); + } uint64_t total_ns = 0; for (i = 0; i < THREAD_NUM; i++) From 52c2a8909baaa49f3d4e1b5467a75970d04278ca Mon Sep 17 00:00:00 2001 From: anpeiyun Date: Sun, 26 Oct 2025 11:29:33 +0800 Subject: [PATCH 208/568] ostest/spinlock: Check the return value. This commit added checking for the return value. Signed-off-by: anpeiyun --- testing/ostest/spinlock.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index df691d7ca..7d66b64b6 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -149,7 +149,11 @@ static inline void run_test_thread( { param[i].pub = &pub; param[i].delta = 0; - pthread_create(&tid[i], NULL, thread_func, ¶m[i]); + ret = pthread_create(&tid[i], NULL, thread_func, ¶m[i]); + if (ret != 0) + { + ASSERT(false); + } } ret = pthread_barrier_wait(&pub.barrier); From 5eef7f324f513781c7cd96040a83f9ec8966a9ee Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Fri, 7 Nov 2025 09:52:20 +0800 Subject: [PATCH 209/568] testing/ostest: refactor the spinlock test. This commit refactored the spinlock test for better accuracy and minimized jitters introduced by scheduling. Signed-off-by: ouyangxiangzhen --- testing/ostest/spinlock.c | 205 ++++++++++++++++++++++++-------------- 1 file changed, 131 insertions(+), 74 deletions(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index 7d66b64b6..0e38ec03b 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -30,30 +30,23 @@ #include #include #include +#include #include +#include /**************************************************************************** * Preprocessor Definitions ****************************************************************************/ -#define THREAD_NUM CONFIG_TESTING_OSTEST_SPINLOCK_THREADS -#define LOOP_TIMES (CONFIG_TEST_LOOP_SCALE * 10000) +#define MAX_THREAD_NUM (CONFIG_SMP_NCPUS) +#define LOOP_TIMES (CONFIG_TEST_LOOP_SCALE * 100000) -enum lock_type_e -{ - RSPINLOCK, - SPINLOCK -}; - -struct spinlock_pub_args_s +aligned_data(64) struct spinlock_pub_args_s { + FAR void *lock; volatile uint32_t counter; - pthread_barrier_t barrier; - union - { - rspinlock_t rlock; - spinlock_t lock; - }; + atomic_t barrier; + uint32_t thread_num; }; struct spinlock_thread_args_s @@ -90,103 +83,145 @@ FAR static void * lock_type##_test_thread(FAR void *arg) \ irqstate_t flags; \ struct timespec start; \ struct timespec end; \ - int i; \ - int ret; \ - ret = pthread_barrier_wait(¶m->pub->barrier); \ - if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) \ + uint32_t i; \ + FAR struct spinlock_pub_args_s *pub = param->pub; \ + FAR lock_type *l = (FAR lock_type *)pub->lock; \ + atomic_fetch_add(&pub->barrier, 1); \ + while (atomic_read(&pub->barrier) != pub->thread_num) \ { \ - ASSERT(false); \ + sched_yield(); \ } \ clock_gettime(CLOCK_REALTIME, &start); \ for (i = 0; i < LOOP_TIMES; i++) \ { \ - flags = lock_func(¶m->pub->lock_type); \ - param->pub->counter++; \ - unlock_func(¶m->pub->lock_type, flags); \ + flags = lock_func(l); \ + pub->counter++; \ + unlock_func(l, flags); \ } \ clock_gettime(CLOCK_REALTIME, &end); \ param->delta = calc_diff(&start, &end); \ return NULL; \ } -LOCK_TEST_FUNC(rlock, rspin_lock_irqsave, rspin_unlock_irqrestore) -LOCK_TEST_FUNC(lock, spin_lock_irqsave, spin_unlock_irqrestore) +LOCK_TEST_FUNC(spinlock_t, spin_lock_irqsave, spin_unlock_irqrestore) +LOCK_TEST_FUNC(rspinlock_t, rspin_lock_irqsave, rspin_unlock_irqrestore) +LOCK_TEST_FUNC(seqcount_t, write_seqlock_irqsave, write_sequnlock_irqrestore) -static inline void run_test_thread( - enum lock_type_e lock_type, - FAR void *(*thread_func)(FAR void *arg) - ) +static inline +void run_test_thread(void *lock, FAR void *(*thread_func)(FAR void *arg), + uint32_t thread_num, const char *lock_type) { - const char *test_type = (lock_type == RSPINLOCK) - ? "RSpin lock" : "Spin lock"; - printf("Test type: %s\n", test_type); - pthread_t tid[THREAD_NUM]; + pthread_t tid[MAX_THREAD_NUM]; struct spinlock_pub_args_s pub; - struct spinlock_thread_args_s param[THREAD_NUM]; + pthread_attr_t attr; + struct sched_param sparam; + struct spinlock_thread_args_s param[MAX_THREAD_NUM]; struct timespec stime; struct timespec etime; + cpu_set_t cpu_set = 1u; + uint64_t total_ns = 0u; + int status; int i; - int ret; - ret = pthread_barrier_init(&pub.barrier, NULL, THREAD_NUM + 1); - if (ret != 0) + /* Initialize the public parameters. */ + + printf("Test type: %s\n", lock_type); + + pub.lock = lock; + pub.counter = 0u; + pub.thread_num = thread_num; + atomic_set_release(&pub.barrier, 0u); + + /* Set affinity to CPU0 */ + +#ifdef CONFIG_SMP + if (OK != sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpu_set)) { + printf("spinlock_test: ERROR: nxsched_set_affinity failed"); + ASSERT(false); + } +#else + UNUSED(cpu_set); +#endif + + /* Boost to maximum priority for test threads. */ + + status = pthread_attr_init(&attr); + if (status != 0) + { + printf("spinlock_test: ERROR: " + "pthread_attr_init failed, status=%d\n", status); ASSERT(false); } - pub.counter = 0; - if (lock_type == RSPINLOCK) + sparam.sched_priority = SCHED_PRIORITY_MAX; + status = pthread_attr_setschedparam(&attr, &sparam); + if (status != OK) { - rspin_lock_init(&pub.rlock); - } - else - { - spin_lock_init(&pub.lock); + printf("spinlock_test: ERROR: " + "pthread_attr_setschedparam failed, status=%d\n", status); + ASSERT(false); } clock_gettime(CLOCK_REALTIME, &stime); - for (i = 0; i < THREAD_NUM; i++) + + /* Create new test threads. */ + + for (i = 0; i < thread_num; i++) { param[i].pub = &pub; param[i].delta = 0; - ret = pthread_create(&tid[i], NULL, thread_func, ¶m[i]); - if (ret != 0) + + /* Set affinity */ + +#ifdef CONFIG_SMP + cpu_set = 1u << ((i + 1) % CONFIG_SMP_NCPUS); + + status = pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), + &cpu_set); + if (status != OK) { + printf("spinlock_test: ERROR: " + "pthread_attr_setaffinity_np failed, status=%d\n", status); + ASSERT(false); + } +#endif + + status = pthread_create(&tid[i], &attr, thread_func, ¶m[i]); + if (status != 0) + { + printf("spinlock_test: ERROR: " + "pthread_create failed, status=%d\n", status); ASSERT(false); } } - ret = pthread_barrier_wait(&pub.barrier); - if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) + for (i = 0; i < thread_num; i++) { - ASSERT(false); + status = pthread_join(tid[i], NULL); + if (status != 0) + { + printf("spinlock_test: ERROR: " + "pthread_join failed, status=%d\n", status); + ASSERT(false); + } } - for (i = 0; i < THREAD_NUM; i++) - { - pthread_join(tid[i], NULL); - } + /* Calculate the average throughput. */ clock_gettime(CLOCK_REALTIME, &etime); - ret = pthread_barrier_destroy(&pub.barrier); - if (ret != 0) - { - ASSERT(false); - } - - uint64_t total_ns = 0; - for (i = 0; i < THREAD_NUM; i++) + for (i = 0; i < thread_num; i++) { total_ns += param[i].delta; } - printf("%s: Test Results:\n", test_type); - printf("%s: Final counter: %" PRIu32 "\n", test_type, pub.counter); - assert(pub.counter == THREAD_NUM * LOOP_TIMES); - printf("%s: Average time per thread: %" PRIu64 " ns\n" - , test_type, total_ns / THREAD_NUM); - printf("%s: Total execution time: %" PRIu64 " ns\n \n" - , test_type, calc_diff(&stime, &etime)); + printf("%s: Test Results:\n", lock_type); + printf("%s: Final counter: %" PRIu32 "\n", lock_type, pub.counter); + assert(pub.counter == thread_num * LOOP_TIMES); + printf("%s: Average throughput : %" PRIu64 " op/s\n", lock_type, + (uint64_t)NSEC_PER_SEC * LOOP_TIMES * thread_num / total_ns); + printf("%s: Total execution time: %" PRIu64 " ns\n \n", + lock_type, calc_diff(&stime, &etime)); } /**************************************************************************** @@ -197,12 +232,34 @@ static inline void run_test_thread( * Name: spinlock_test ****************************************************************************/ +static void spinlock_test_thread_num(unsigned thread_num) +{ + aligned_data(64) union + { + spinlock_t spinlock; + rspinlock_t rspinlock; + seqcount_t seqcount; + } lock; + + printf("Start Lock test:\n"); + printf("Thread num: %u, Loop times: %d\n\n", thread_num, LOOP_TIMES); + + spin_lock_init(&lock.spinlock); + run_test_thread(&lock, spinlock_t_test_thread, thread_num, "spinlock"); + + rspin_lock_init(&lock.rspinlock); + run_test_thread(&lock, rspinlock_t_test_thread, thread_num, "rspinlock"); + + seqlock_init(&lock.seqcount); + run_test_thread(&lock, seqcount_t_test_thread, thread_num, "seqcount"); +} + void spinlock_test(void) { - printf("Start Spin lock test:\n"); - printf("Thread num: %d, Loop times: %d\n\n", THREAD_NUM, LOOP_TIMES); + unsigned tnr; - run_test_thread(SPINLOCK, lock_test_thread); - - run_test_thread(RSPINLOCK, rlock_test_thread); + for (tnr = 1; tnr < MAX_THREAD_NUM; tnr++) + { + spinlock_test_thread_num(tnr); + } } From 06d07b15228b9af04e23137ecd337604293f73d6 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 30 Dec 2025 10:07:46 +0800 Subject: [PATCH 210/568] testing/ostest: Fix Coverity for spinlock test. This commit fixed coverity for spinlock test. Signed-off-by: ouyangxiangzhen --- testing/ostest/spinlock.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index 0e38ec03b..1ebe290f1 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -215,13 +215,20 @@ void run_test_thread(void *lock, FAR void *(*thread_func)(FAR void *arg), total_ns += param[i].delta; } - printf("%s: Test Results:\n", lock_type); - printf("%s: Final counter: %" PRIu32 "\n", lock_type, pub.counter); - assert(pub.counter == thread_num * LOOP_TIMES); - printf("%s: Average throughput : %" PRIu64 " op/s\n", lock_type, - (uint64_t)NSEC_PER_SEC * LOOP_TIMES * thread_num / total_ns); - printf("%s: Total execution time: %" PRIu64 " ns\n \n", - lock_type, calc_diff(&stime, &etime)); + if (total_ns != 0) + { + printf("%s: Test Results:\n", lock_type); + printf("%s: Final counter: %" PRIu32 "\n", lock_type, pub.counter); + assert(pub.counter == thread_num * LOOP_TIMES); + printf("%s: Average throughput : %" PRIu64 " op/s\n", lock_type, + (uint64_t)NSEC_PER_SEC * LOOP_TIMES * thread_num / total_ns); + printf("%s: Total execution time: %" PRIu64 " ns\n \n", + lock_type, calc_diff(&stime, &etime)); + } + else + { + printf("spinlock_test: ERROR: total_ns is 0\n"); + } } /**************************************************************************** @@ -258,7 +265,7 @@ void spinlock_test(void) { unsigned tnr; - for (tnr = 1; tnr < MAX_THREAD_NUM; tnr++) + for (tnr = 1; tnr <= MAX_THREAD_NUM; tnr++) { spinlock_test_thread_num(tnr); } From 71561d29795901da23ccf34ca4c1ff7db3a851c3 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Tue, 27 Jan 2026 17:49:19 +0800 Subject: [PATCH 211/568] testing/ostest: run spinlock_test only in flat mode. Since the kernel spinlocks can only work in flat mode, this commit allowed spinlock_test only in flat mode. Signed-off-by: ouyangxiangzhen --- testing/ostest/CMakeLists.txt | 4 ++-- testing/ostest/Makefile | 4 ++-- testing/ostest/ostest_main.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/ostest/CMakeLists.txt b/testing/ostest/CMakeLists.txt index 35b0c5596..a8a2ca921 100644 --- a/testing/ostest/CMakeLists.txt +++ b/testing/ostest/CMakeLists.txt @@ -22,7 +22,7 @@ if(CONFIG_TESTING_OSTEST) - set(SRCS getopt.c libc_memmem.c restart.c sighelper.c spinlock.c) + set(SRCS getopt.c libc_memmem.c restart.c sighelper.c) if(CONFIG_ENABLE_ALL_SIGNALS) list(APPEND SRCS sighand.c signest.c) @@ -162,7 +162,7 @@ if(CONFIG_TESTING_OSTEST) endif() if(CONFIG_BUILD_FLAT) - list(APPEND SRCS wdog.c) + list(APPEND SRCS wdog.c spinlock.c) endif() set(OSTEST_SRCS ostest_main.c ${SRCS}) diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile index b8be63a62..817fcdb51 100644 --- a/testing/ostest/Makefile +++ b/testing/ostest/Makefile @@ -31,7 +31,7 @@ MODULE = $(CONFIG_TESTING_OSTEST) # NuttX OS Test -CSRCS = getopt.c libc_memmem.c restart.c sighelper.c spinlock.c +CSRCS = getopt.c libc_memmem.c restart.c sighelper.c ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y) CSRCS += sighand.c signest.c @@ -167,7 +167,7 @@ endif endif ifeq ($(CONFIG_BUILD_FLAT),y) -CSRCS += wdog.c +CSRCS += wdog.c spinlock.c endif include $(APPDIR)/Application.mk diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 58ccc87fb..8247b4788 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -547,11 +547,11 @@ static int user_main(int argc, char *argv[]) #endif #endif +#ifdef CONFIG_BUILD_FLAT printf("\nuser_main: spinlock test\n"); spinlock_test(); check_test_memory_usage(); -#ifdef CONFIG_BUILD_FLAT printf("\nuser_main: wdog test\n"); wdog_test(); check_test_memory_usage(); From ebe2dd57ddef45ac7c3d2db037fa4e5a5d5f26cd Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Tue, 27 Jan 2026 11:21:06 +0800 Subject: [PATCH 212/568] ostest/hrtimer: sync hrtimer ostest with latest hritmer update sync hrtimer ostest with latest hritmer update Signed-off-by: Chengdong Wang --- testing/ostest/hrtimer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index d503f878f..48ed46b99 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -223,7 +223,7 @@ static void * hrtimer_test_thread(void *arg) /* Cancel timer */ ret = hrtimer_cancel(&timer); - HRTIMER_TEST(ret, OK); + HRTIMER_TEST(ret >= 0, true); /* Start timer with fixed period */ @@ -241,7 +241,7 @@ static void * hrtimer_test_thread(void *arg) /* Cancel the timer synchronously */ ret = hrtimer_cancel_sync(&timer); - HRTIMER_TEST(ret, OK); + HRTIMER_TEST(ret >= 0, true); return NULL; } From 4ac37327348c9fa6808a25ff379d28367a9bf98e Mon Sep 17 00:00:00 2001 From: guohao15 Date: Wed, 16 Apr 2025 20:48:45 +0800 Subject: [PATCH 213/568] testing/fdcheck: fix fd close in other thread Fix file descriptor leak issue where fd was stored in test_state for deferred close, but could fail when CONFIG_FDCHECK is enabled because fd cannot be closed in a different thread. Signed-off-by: guohao15 --- testing/testsuites/kernel/fs/cases/fs_creat_test.c | 3 ++- testing/testsuites/kernel/fs/cases/fs_dup2_test.c | 8 +++----- testing/testsuites/kernel/fs/cases/fs_eventfd_test.c | 4 +--- testing/testsuites/kernel/fs/cases/fs_fcntl_test.c | 12 +++++------- testing/testsuites/kernel/fs/cases/fs_fstat_test.c | 7 ++----- testing/testsuites/kernel/fs/cases/fs_fstatfs_test.c | 2 +- testing/testsuites/kernel/fs/cases/fs_fsync_test.c | 8 +++----- testing/testsuites/kernel/fs/cases/fs_open_test.c | 7 ++----- testing/testsuites/kernel/fs/cases/fs_pread_test.c | 3 ++- testing/testsuites/kernel/fs/cases/fs_pwrite_test.c | 3 ++- testing/testsuites/kernel/fs/cases/fs_read_test.c | 8 ++------ .../testsuites/kernel/fs/cases/fs_readlink_test.c | 6 +----- testing/testsuites/kernel/fs/cases/fs_stat_test.c | 4 ---- testing/testsuites/kernel/fs/cases/fs_write_test.c | 6 ++---- 14 files changed, 28 insertions(+), 53 deletions(-) diff --git a/testing/testsuites/kernel/fs/cases/fs_creat_test.c b/testing/testsuites/kernel/fs/cases/fs_creat_test.c index 3d7d88330..19ff97fed 100644 --- a/testing/testsuites/kernel/fs/cases/fs_creat_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_creat_test.c @@ -73,10 +73,11 @@ void test_nuttx_fs_creat01(FAR void **state) fd = creat(test_state->filename, 0700); assert_true(fd > 0); - test_state->fd1 = fd; /* do write */ ret = write(fd, buf, sizeof(buf)); assert_int_in_range(ret, 1, 20); + + close(fd); } diff --git a/testing/testsuites/kernel/fs/cases/fs_dup2_test.c b/testing/testsuites/kernel/fs/cases/fs_dup2_test.c index 7ec1ece97..f7fb236a1 100644 --- a/testing/testsuites/kernel/fs/cases/fs_dup2_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_dup2_test.c @@ -60,21 +60,16 @@ void test_nuttx_fs_dup201(FAR void **state) }; off_t currpos; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* open file */ int fd1 = open(TESTFILE, O_RDWR | O_CREAT, 0777); assert_true(fd1 > 0); - test_state->fd1 = fd1; /* open file */ int fd2 = open(TESTFILE, O_RDWR | O_CREAT, 0777); assert_true(fd2 > 0); - test_state->fd2 = fd2; /* do dup2 */ @@ -114,4 +109,7 @@ void test_nuttx_fs_dup201(FAR void **state) ret = strncmp(buf, "hello world!", 12); assert_int_equal(ret, 0); + + close(fd1); + close(fd2); } diff --git a/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c b/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c index 1a70776af..9930e776d 100644 --- a/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c @@ -75,12 +75,9 @@ void test_nuttx_fs_eventfd(FAR void **state) int eventfd01_ret; int eventfd01_efd; pthread_t eventfd01_tid; - struct fs_testsuites_state_s *test_state; - test_state = (struct fs_testsuites_state_s *)*state; eventfd01_efd = eventfd(0, 0); assert_int_not_equal(eventfd01_efd, -1); - test_state->fd1 = eventfd01_efd; assert_true(pthread_create(&eventfd01_tid, NULL, threadfunc, &eventfd01_efd) >= 0); @@ -94,5 +91,6 @@ void test_nuttx_fs_eventfd(FAR void **state) } sleep(2); + close(eventfd01_efd); #endif } diff --git a/testing/testsuites/kernel/fs/cases/fs_fcntl_test.c b/testing/testsuites/kernel/fs/cases/fs_fcntl_test.c index 1c163690c..55c1b4208 100644 --- a/testing/testsuites/kernel/fs/cases/fs_fcntl_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_fcntl_test.c @@ -62,13 +62,11 @@ void test_nuttx_fs_fcntl01(FAR void **state) oldfd = open(TEST_FILE_1, O_CREAT | O_RDWR, 0700); assert_true(oldfd > 0); - test_state->fd1 = oldfd; /* do fcntl */ newfd = fcntl(oldfd, F_DUPFD, 0); assert_true(newfd > 0); - test_state->fd2 = newfd; /* malloc memory */ @@ -84,6 +82,9 @@ void test_nuttx_fs_fcntl01(FAR void **state) ret = write(newfd, buf, BUFSIZ); assert_int_in_range(ret, 1, BUFSIZ); + + close(oldfd); + close(newfd); } /**************************************************************************** @@ -105,9 +106,6 @@ void test_nuttx_fs_fcntl02(FAR void **state) int fd; int ret; int v; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* open file */ @@ -118,7 +116,6 @@ void test_nuttx_fs_fcntl02(FAR void **state) v = fcntl(fd, F_GETFD); assert_int_in_range(v, 0, 255); - test_state->fd1 = fd; v |= FD_CLOEXEC; @@ -126,9 +123,10 @@ void test_nuttx_fs_fcntl02(FAR void **state) ret = fcntl(fd, F_SETFD, v); assert_int_in_range(ret, 0, 255); - test_state->fd2 = ret; ret = (v == fcntl(fd, F_GETFD) ? 1 : 0); assert_int_equal(ret, 1); + + close(fd); } /**************************************************************************** diff --git a/testing/testsuites/kernel/fs/cases/fs_fstat_test.c b/testing/testsuites/kernel/fs/cases/fs_fstat_test.c index 315c3e991..7850b883c 100644 --- a/testing/testsuites/kernel/fs/cases/fs_fstat_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_fstat_test.c @@ -67,7 +67,6 @@ void test_nuttx_fs_fstat01(FAR void **state) fd = open(TEST_FILE_1, O_RDWR | O_CREAT, 0777); assert_true(fd > 0); - test_state->fd1 = fd; /* malloc memory */ @@ -98,6 +97,8 @@ void test_nuttx_fs_fstat01(FAR void **state) ret = (file_s.st_size == BUF_SIZE) ? 1 : 0; assert_int_equal(ret, 1); + + close(fd); } /**************************************************************************** @@ -113,15 +114,11 @@ void test_nuttx_fs_fstat02(FAR void **state) int fd; int ret; struct stat file_s; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* open file */ fd = open(TEST_FILE_2, O_RDWR | O_CREAT, 0777); assert_true(fd > 0); - test_state->fd1 = fd; /* get the file size before write */ diff --git a/testing/testsuites/kernel/fs/cases/fs_fstatfs_test.c b/testing/testsuites/kernel/fs/cases/fs_fstatfs_test.c index 0f804a6f8..240e74d90 100644 --- a/testing/testsuites/kernel/fs/cases/fs_fstatfs_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_fstatfs_test.c @@ -102,10 +102,10 @@ void test_nuttx_fs_fstatfs01(FAR void **state) fd = open(TEST_FILE, O_RDWR | O_CREAT, 0777); assert_true(fd > 0); - test_state->fd1 = fd; /* call fstatfs() */ ret = fstatfs(fd, &statfsbuf); assert_int_equal(ret, 0); + close(fd); } diff --git a/testing/testsuites/kernel/fs/cases/fs_fsync_test.c b/testing/testsuites/kernel/fs/cases/fs_fsync_test.c index f69c50a87..c0a03b82f 100644 --- a/testing/testsuites/kernel/fs/cases/fs_fsync_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_fsync_test.c @@ -64,15 +64,11 @@ void test_nuttx_fs_fsync01(FAR void **state) int fd; int rval; int ret; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* open file */ fd = open(TESTFILE, O_RDWR | O_CREAT, 0700); assert_true(fd > 0); - test_state->fd1 = fd; for (int i = 0; i < 20; i++) { @@ -86,6 +82,8 @@ void test_nuttx_fs_fsync01(FAR void **state) ret = fsync(fd); assert_int_equal(ret, 0); } + + close(fd); } /**************************************************************************** @@ -118,7 +116,6 @@ void test_nuttx_fs_fsync02(FAR void **state) fd = open(TESTFILE, O_CREAT | O_RDWR, 0777); assert_true(fd > 0); - test_state->fd1 = fd; /* call fstatfs() */ @@ -165,4 +162,5 @@ void test_nuttx_fs_fsync02(FAR void **state) ret = fstatfs(fd, &statfsbuf); assert_int_equal(ret, 0); + close(fd); } diff --git a/testing/testsuites/kernel/fs/cases/fs_open_test.c b/testing/testsuites/kernel/fs/cases/fs_open_test.c index f671438af..38b30d336 100644 --- a/testing/testsuites/kernel/fs/cases/fs_open_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_open_test.c @@ -62,10 +62,6 @@ void test_nuttx_fs_open01(FAR void **state) 0 }; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; - /* open file */ fd = open(TESTFILE, O_WRONLY | O_CREAT, 0700); @@ -81,12 +77,13 @@ void test_nuttx_fs_open01(FAR void **state) fd = open(TESTFILE, O_RDONLY); assert_true(fd > 0); - test_state->fd1 = fd; /* do read */ ret = read(fd, buffer, sizeof(buffer)); assert_true(ret > 0); + + close(fd); } /**************************************************************************** diff --git a/testing/testsuites/kernel/fs/cases/fs_pread_test.c b/testing/testsuites/kernel/fs/cases/fs_pread_test.c index 1095a4827..166c98e29 100644 --- a/testing/testsuites/kernel/fs/cases/fs_pread_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_pread_test.c @@ -69,7 +69,6 @@ void test_nuttx_fs_pread01(FAR void **state) fd = open(TEST_FILE, O_RDWR | O_CREAT, 0777); assert_int_not_equal(fd, -1); - test_state->fd1 = fd; /* do write */ @@ -98,4 +97,6 @@ void test_nuttx_fs_pread01(FAR void **state) pread(fd, buf, 3, 1); assert_int_equal(strncmp(buf, "BCD", 3), 0); + + close(fd); } diff --git a/testing/testsuites/kernel/fs/cases/fs_pwrite_test.c b/testing/testsuites/kernel/fs/cases/fs_pwrite_test.c index b44e87b09..ec8ca4c66 100644 --- a/testing/testsuites/kernel/fs/cases/fs_pwrite_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_pwrite_test.c @@ -64,7 +64,6 @@ void test_nuttx_fs_pwrite01(FAR void **state) fd = open(TEST_FILE, O_RDWR | O_CREAT, 0777); assert_true(fd > 0); - test_state->fd1 = fd; /* malloc memory */ @@ -108,4 +107,6 @@ void test_nuttx_fs_pwrite01(FAR void **state) /* check buf */ assert_true(strncmp(buf, "CBAA", BUF_SIZE) == 0); + + close(fd); } diff --git a/testing/testsuites/kernel/fs/cases/fs_read_test.c b/testing/testsuites/kernel/fs/cases/fs_read_test.c index d9659cf86..c20309fbe 100644 --- a/testing/testsuites/kernel/fs/cases/fs_read_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_read_test.c @@ -58,21 +58,17 @@ void test_nuttx_fs_read01(FAR void **state) int size; char s[] = "Test!"; char buffer[80]; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; fd = open(TESTFILE, O_WRONLY | O_CREAT, 0777); assert_true(fd > 0); - test_state->fd1 = fd; size = write(fd, s, sizeof(s)); assert_int_equal(size, sizeof(s)); - close(fd); + fd = open(TESTFILE, O_RDONLY, 0777); assert_true(fd > 0); - test_state->fd1 = fd; size = read(fd, buffer, sizeof(buffer)); assert_int_equal(size, sizeof(s)); + close(fd); } diff --git a/testing/testsuites/kernel/fs/cases/fs_readlink_test.c b/testing/testsuites/kernel/fs/cases/fs_readlink_test.c index c6318e439..32da71ed5 100644 --- a/testing/testsuites/kernel/fs/cases/fs_readlink_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_readlink_test.c @@ -70,15 +70,10 @@ void test_nuttx_fs_readlink01(FAR void **state) 0 }; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; - /* creat file */ fd = creat(TEST_FILE, 0700); assert_true(fd > 0); - test_state->fd1 = fd; getcwd(path, sizeof(path)); strcat(path, "/"); @@ -97,4 +92,5 @@ void test_nuttx_fs_readlink01(FAR void **state) /* delete test file */ assert_int_equal(unlink("/file_link"), 0); + close(fd); } diff --git a/testing/testsuites/kernel/fs/cases/fs_stat_test.c b/testing/testsuites/kernel/fs/cases/fs_stat_test.c index 2afb114e0..58fd9ef90 100644 --- a/testing/testsuites/kernel/fs/cases/fs_stat_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_stat_test.c @@ -91,9 +91,6 @@ void test_nuttx_fs_stat01(FAR void **state) time_t t_1; time_t t_2; time_t t_diff; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* set memory */ @@ -103,7 +100,6 @@ void test_nuttx_fs_stat01(FAR void **state) fd = open(TEST_FILE, O_RDWR | O_CREAT, 0777); assert_true(fd > 0); - test_state->fd1 = 0; /* do write */ diff --git a/testing/testsuites/kernel/fs/cases/fs_write_test.c b/testing/testsuites/kernel/fs/cases/fs_write_test.c index 5318acbe2..cfac9d6a1 100644 --- a/testing/testsuites/kernel/fs/cases/fs_write_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_write_test.c @@ -57,15 +57,11 @@ void test_nuttx_fs_write01(FAR void **state) int out; int rval; char buffer[1024]; - struct fs_testsuites_state_s *test_state; - - test_state = (struct fs_testsuites_state_s *)*state; /* open file */ out = open(TESTFILE, O_WRONLY | O_CREAT, 0700); assert_true(out > 0); - test_state->fd1 = out; /* set memory */ @@ -75,6 +71,8 @@ void test_nuttx_fs_write01(FAR void **state) rval = write(out, buffer, MAXLEN); assert_int_in_range(rval, 1, MAXLEN); + + close(out); } /**************************************************************************** From 050fb406c28b4a9cd0451fa5e74dac3165743fa8 Mon Sep 17 00:00:00 2001 From: ligd Date: Mon, 4 Aug 2025 17:32:35 +0800 Subject: [PATCH 214/568] testing/eventfd_test: avoid the orphan Thread Replace sleep() with pthread_join() to properly wait for the child thread to finish, avoiding orphan threads. Change sleep(1) to usleep(1000) to reduce test time while maintaining synchronization. Fix loop iteration count mismatch between reader thread (6 iterations) and writer (5 iterations). Signed-off-by: ligd --- testing/testsuites/kernel/fs/cases/fs_eventfd_test.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c b/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c index 9930e776d..42f8fe425 100644 --- a/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c @@ -51,10 +51,10 @@ __attribute__((unused)) static void *threadfunc(void *args) eventfd_t eventfd01_buffer; int fd = *(int *)args; - for (int i = 1; i < 6; i++) + for (int i = 0; i < 5; i++) { read(fd, &eventfd01_buffer, sizeof(eventfd_t)); - sleep(1); + usleep(1000); } return 0; @@ -81,16 +81,17 @@ void test_nuttx_fs_eventfd(FAR void **state) assert_true(pthread_create(&eventfd01_tid, NULL, threadfunc, &eventfd01_efd) >= 0); - for (int i = 1; i < 5; i++) + for (int i = 0; i < 5; i++) { eventfd01_ret = write(eventfd01_efd, &eventfd01_buf, sizeof(eventfd_t)); assert_int_equal(eventfd01_ret, sizeof(eventfd_t)); eventfd01_buf++; - sleep(1); + usleep(1000); } - sleep(2); + pthread_join(eventfd01_tid, NULL); close(eventfd01_efd); + #endif } From f2ba4883fa2b5af83fbb9c13244de69fff9f5334 Mon Sep 17 00:00:00 2001 From: wangxingxing Date: Mon, 17 Nov 2025 16:29:42 +0800 Subject: [PATCH 215/568] testing/fs:remove the usleep of evend_fd read to solve the questiong of sem wait Remove unnecessary usleep(1000) in the read thread of eventfd test. The eventfd read operation will block and wait for data naturally via semaphore, no additional delay is needed. Signed-off-by: wangxingxing --- testing/testsuites/kernel/fs/cases/fs_eventfd_test.c | 1 - 1 file changed, 1 deletion(-) diff --git a/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c b/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c index 42f8fe425..5cc2177b0 100644 --- a/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_eventfd_test.c @@ -54,7 +54,6 @@ __attribute__((unused)) static void *threadfunc(void *args) for (int i = 0; i < 5; i++) { read(fd, &eventfd01_buffer, sizeof(eventfd_t)); - usleep(1000); } return 0; From 42e3566147fd40f735569000eea68bc0c74d800c Mon Sep 17 00:00:00 2001 From: wangxingxing Date: Thu, 7 Aug 2025 20:48:22 +0800 Subject: [PATCH 216/568] testing/fs:reduce the test time of fs test Reduce TEST_NUM from 1000 to 100 in fs_opendir_test.c Reduce loop count from 100 to 30 in fs_stream_test.c Signed-off-by: wangxingxing --- testing/testsuites/kernel/fs/cases/fs_opendir_test.c | 2 +- testing/testsuites/kernel/fs/cases/fs_stream_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/testsuites/kernel/fs/cases/fs_opendir_test.c b/testing/testsuites/kernel/fs/cases/fs_opendir_test.c index a92a779d6..ec42bb777 100644 --- a/testing/testsuites/kernel/fs/cases/fs_opendir_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_opendir_test.c @@ -85,7 +85,7 @@ void test_nuttx_fs_opendir01(FAR void **state) * Pre-processor Definitions ****************************************************************************/ -#define TEST_NUM 1000 +#define TEST_NUM 100 /**************************************************************************** * Public Functions diff --git a/testing/testsuites/kernel/fs/cases/fs_stream_test.c b/testing/testsuites/kernel/fs/cases/fs_stream_test.c index dfc83ea93..c4f44e590 100644 --- a/testing/testsuites/kernel/fs/cases/fs_stream_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_stream_test.c @@ -119,7 +119,7 @@ void test_nuttx_fs_stream02(FAR void **state) char *junk = "abcdefghijklmnopqrstuvwxyz"; long pos; int lc; - for (lc = 0; lc < 100; lc++) + for (lc = 0; lc < 30; lc++) { if ((stream = fopen(TESTFILENAME, "a+")) == NULL) { From b80d67c6281356efde5bd72d2d1466d8bd1593fb Mon Sep 17 00:00:00 2001 From: liqinhui Date: Fri, 6 Jun 2025 10:07:25 +0800 Subject: [PATCH 217/568] netutils/netinit: Support the NETINIT_MACADDR Support getting MAC address from boardctl(BOARDIOC_MACADDR) via NETINIT_MACADDR. Signed-off-by: liqinhui --- include/netutils/netinit.h | 4 ---- netutils/netinit/Kconfig | 7 +++++++ netutils/netinit/netinit.c | 13 +++++++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/netutils/netinit.h b/include/netutils/netinit.h index 3c3c85d50..320fa1498 100644 --- a/include/netutils/netinit.h +++ b/include/netutils/netinit.h @@ -57,10 +57,6 @@ # define CONFIG_NETINIT_DNSIPADDR CONFIG_NETINIT_DRIPADDR #endif -#ifndef CONFIG_NETINIT_MACADDR -# define CONFIG_NETINIT_MACADDR 0x00e0deadbeef -#endif - #if !defined(CONFIG_NETINIT_THREAD) || !defined(CONFIG_ARCH_PHY_INTERRUPT) || \ !defined(CONFIG_NETDEV_PHY_IOCTL) || !defined(CONFIG_NET_UDP) # undef CONFIG_NETINIT_MONITOR diff --git a/netutils/netinit/Kconfig b/netutils/netinit/Kconfig index 2031c7bae..8d91b0b50 100644 --- a/netutils/netinit/Kconfig +++ b/netutils/netinit/Kconfig @@ -488,6 +488,13 @@ config NETINIT_SWMAC With this choice, you can assign a fixed MAC address determined by a NuttX configuration option. +config NETINIT_MACADDR + bool "Device MAC address" + depends on BOARDCTL_MACADDR + ---help--- + With this choice, you can assign a fixed MAC address in the file + device.info (DEVICE_INFO_PATH) defined by user. + endchoice # MAC address selection config NETINIT_MACADDR_1 diff --git a/netutils/netinit/netinit.c b/netutils/netinit/netinit.c index 4433eb4a5..c0a459725 100644 --- a/netutils/netinit/netinit.c +++ b/netutils/netinit/netinit.c @@ -286,7 +286,9 @@ static const uint16_t g_ipv6_netmask[8] = defined(HAVE_MAC) static void netinit_set_macaddr(void) { -#if defined(CONFIG_NETINIT_UIDMAC) +#if defined(CONFIG_NETINIT_MACADDR) + struct boardioc_macaddr_s req; +#elif defined(CONFIG_NETINIT_UIDMAC) uint8_t uid[CONFIG_BOARDCTL_UNIQUEID_SIZE]; #elif defined(CONFIG_NET_ETHERNET) uint8_t mac[IFHWADDRLEN]; @@ -296,7 +298,14 @@ static void netinit_set_macaddr(void) /* Many embedded network interfaces must have a software assigned MAC */ -#if defined(CONFIG_NETINIT_UIDMAC) +#if defined(CONFIG_NETINIT_MACADDR) + strlcpy(req.ifname, NET_DEVNAME, IFNAMSIZ); + if (boardctl(BOARDIOC_MACADDR, (uintptr_t)&req) == 0) + { + netlib_setmacaddr(NET_DEVNAME, req.macaddr); + } + +#elif defined(CONFIG_NETINIT_UIDMAC) boardctl(BOARDIOC_UNIQUEID, (uintptr_t)&uid); uid[0] = (uid[0] & 0b11110000) | 2; /* Locally Administered MAC */ netlib_setmacaddr(NET_DEVNAME, uid); From 367e9dca017ef790f2620c394e5d6f15a8d2f2fd Mon Sep 17 00:00:00 2001 From: makejian Date: Thu, 6 Mar 2025 22:19:29 +0800 Subject: [PATCH 218/568] testing: move nist-sts into drivers/rng directory Move NIST Statistical Test Suite (nist-sts) testing module from testing/drivers/ into testing/drivers/rng/ directory to better organize RNG (random number generator) related tests that utilize /dev/random device. Changes: - Create testing/drivers/rng/ directory structure - Move nist-sts from testing/drivers/ to testing/drivers/rng/nist-sts - Update build configuration file paths: - CMakeLists.txt - Makefile - Make.defs - Maintain all test patches and Kconfig settings Signed-off-by: makejian --- testing/{ => drivers/rng}/nist-sts/.gitignore | 0 .../0001-Solve-the-memory-out-of-bounds-problem-in-sts.patch | 0 ...ix-bug-that-crash-in-running-a-single-test-after-ru.patch | 0 testing/{ => drivers/rng}/nist-sts/CMakeLists.txt | 5 +++-- testing/{ => drivers/rng}/nist-sts/Kconfig | 0 testing/{ => drivers/rng}/nist-sts/Make.defs | 4 ++-- testing/{ => drivers/rng}/nist-sts/Makefile | 2 +- 7 files changed, 6 insertions(+), 5 deletions(-) rename testing/{ => drivers/rng}/nist-sts/.gitignore (100%) rename testing/{ => drivers/rng}/nist-sts/0001-Solve-the-memory-out-of-bounds-problem-in-sts.patch (100%) rename testing/{ => drivers/rng}/nist-sts/0002-Fix-bug-that-crash-in-running-a-single-test-after-ru.patch (100%) rename testing/{ => drivers/rng}/nist-sts/CMakeLists.txt (94%) rename testing/{ => drivers/rng}/nist-sts/Kconfig (100%) rename testing/{ => drivers/rng}/nist-sts/Make.defs (90%) rename testing/{ => drivers/rng}/nist-sts/Makefile (98%) diff --git a/testing/nist-sts/.gitignore b/testing/drivers/rng/nist-sts/.gitignore similarity index 100% rename from testing/nist-sts/.gitignore rename to testing/drivers/rng/nist-sts/.gitignore diff --git a/testing/nist-sts/0001-Solve-the-memory-out-of-bounds-problem-in-sts.patch b/testing/drivers/rng/nist-sts/0001-Solve-the-memory-out-of-bounds-problem-in-sts.patch similarity index 100% rename from testing/nist-sts/0001-Solve-the-memory-out-of-bounds-problem-in-sts.patch rename to testing/drivers/rng/nist-sts/0001-Solve-the-memory-out-of-bounds-problem-in-sts.patch diff --git a/testing/nist-sts/0002-Fix-bug-that-crash-in-running-a-single-test-after-ru.patch b/testing/drivers/rng/nist-sts/0002-Fix-bug-that-crash-in-running-a-single-test-after-ru.patch similarity index 100% rename from testing/nist-sts/0002-Fix-bug-that-crash-in-running-a-single-test-after-ru.patch rename to testing/drivers/rng/nist-sts/0002-Fix-bug-that-crash-in-running-a-single-test-after-ru.patch diff --git a/testing/nist-sts/CMakeLists.txt b/testing/drivers/rng/nist-sts/CMakeLists.txt similarity index 94% rename from testing/nist-sts/CMakeLists.txt rename to testing/drivers/rng/nist-sts/CMakeLists.txt index e61b2b191..7b2a9da79 100644 --- a/testing/nist-sts/CMakeLists.txt +++ b/testing/drivers/rng/nist-sts/CMakeLists.txt @@ -1,5 +1,5 @@ # ############################################################################## -# apps/testing/nist-sts/CMakeLists.txt +# apps/testing/drivers/rng/nist-sts/CMakeLists.txt # # SPDX-License-Identifier: Apache-2.0 # @@ -32,7 +32,8 @@ if(CONFIG_TESTING_NIST_STS) FetchContent_Declare( nist-sts_fetch URL ${CONFIG_NIST_URL} SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/nist-sts - BINARY_DIR ${CMAKE_BINARY_DIR}/apps/testing/nist-sts/nist-sts + BINARY_DIR + ${CMAKE_BINARY_DIR}/apps/testing/drivers/rng/nist-sts/nist-sts PATCH_COMMAND patch -p0 -d ${CMAKE_CURRENT_LIST_DIR}/nist-sts < ${CMAKE_CURRENT_LIST_DIR}/0001-Solve-the-memory-out-of-bounds-problem-in-sts.patch diff --git a/testing/nist-sts/Kconfig b/testing/drivers/rng/nist-sts/Kconfig similarity index 100% rename from testing/nist-sts/Kconfig rename to testing/drivers/rng/nist-sts/Kconfig diff --git a/testing/nist-sts/Make.defs b/testing/drivers/rng/nist-sts/Make.defs similarity index 90% rename from testing/nist-sts/Make.defs rename to testing/drivers/rng/nist-sts/Make.defs index 3bb4a2e35..8bd85ad87 100644 --- a/testing/nist-sts/Make.defs +++ b/testing/drivers/rng/nist-sts/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/testing/nist-sts/Make.defs +# apps/testing/drivers/rng/nist-sts/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -21,5 +21,5 @@ ############################################################################ ifneq ($(CONFIG_TESTING_NIST_STS),) -CONFIGURED_APPS += $(APPDIR)/testing/nist-sts +CONFIGURED_APPS += $(APPDIR)/testing/drivers/rng/nist-sts endif diff --git a/testing/nist-sts/Makefile b/testing/drivers/rng/nist-sts/Makefile similarity index 98% rename from testing/nist-sts/Makefile rename to testing/drivers/rng/nist-sts/Makefile index 4240db968..b7da67825 100644 --- a/testing/nist-sts/Makefile +++ b/testing/drivers/rng/nist-sts/Makefile @@ -1,5 +1,5 @@ ############################################################################ -# apps/testing/nist-sts/Makefile +# apps/testing/drivers/rng/nist-sts/Makefile # # SPDX-License-Identifier: Apache-2.0 # From 8804f086b3186d40c4708ba0ef9cff801a0fb9ac Mon Sep 17 00:00:00 2001 From: anjiahao Date: Mon, 10 Feb 2025 12:14:07 +0800 Subject: [PATCH 219/568] ymodem:sbrb.py send command need flush and reset input buffer These changes fix reliability issues when initiating ymodem transfers over serial connections. Signed-off-by: anjiahao --- system/ymodem/sbrb.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/system/ymodem/sbrb.py b/system/ymodem/sbrb.py index 0b9767384..a5c90930f 100755 --- a/system/ymodem/sbrb.py +++ b/system/ymodem/sbrb.py @@ -822,7 +822,9 @@ if __name__ == "__main__": recvfile += i + " " fd_serial.write(("sb %s\r\n" % (recvfile)).encode()) - tmp = fd_serial.read(len(("sb %s\r\n" % (recvfile)).encode())) + fd_serial.flush() + tmp = fd_serial.read(len(("sb %s\r\n" % (recvfile)).encode()) - 1) + fd_serial.reset_input_buffer() else: if args.sendto: cmd = ("rb -f %s\r\n" % (args.sendto[0])).encode() @@ -830,6 +832,7 @@ if __name__ == "__main__": cmd = ("rb\r\n").encode() fd_serial.write(cmd) + fd_serial.flush() fd_serial.read(len(cmd)) fd_serial.reset_input_buffer() From 2908f101549565c881b5ae422d66de7f1da3bbce Mon Sep 17 00:00:00 2001 From: wangxingxing Date: Mon, 14 Apr 2025 17:42:59 +0800 Subject: [PATCH 220/568] apps/system/ymodem: Optimized ymodem for burn during bootloader If device automatically enters the ymodem rb mode when it starts up, the PC tool does not need to send rb command anymore. Here, when a specified number of consecutive 'C' are received, the subsequent ymodem protocol content will continue. Signed-off-by: wangxingxing --- system/ymodem/sbrb.py | 104 +++++++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 22 deletions(-) diff --git a/system/ymodem/sbrb.py b/system/ymodem/sbrb.py index a5c90930f..8d93f1901 100755 --- a/system/ymodem/sbrb.py +++ b/system/ymodem/sbrb.py @@ -25,6 +25,7 @@ import io import os import sys import termios +import time import serial @@ -92,25 +93,31 @@ def ymodem_stdprogress(data): def ymodem_ser_read(size): - global fd_serial - data = fd_serial.read(size) return data def ymodem_ser_write(data): - global fd_serial fd_serial.write(data) fd_serial.flush() def ymodem_ser_clear(): - global fd_serial - fd_serial.reset_input_buffer() fd_serial.reset_output_buffer() +def ymodem_ser_recv_repeat_c(num, timeout): + except_data = b"C" * num + start_time = time.time() + + while time.time() - start_time < timeout: + read_data = ymodem_ser_read(num) + if read_data == except_data: + return 0 + return -1 + + def calc_crc16(data, crc=0): crctable = [ 0x0000, @@ -385,7 +392,7 @@ class ymodem: write=ymodem_stdwrite, progress=ymodem_stdprogress, clear=ymodem_stdclear, - timeout=100, + timeout=10, maxretry=RETRIESMAX, debug="", customsize=0, @@ -452,15 +459,30 @@ class ymodem: return PACKET_SIZE def recv_cmd(self, cmd): - chunk = self.read(1) - if chunk == NAK: - return -EAGAIN - if chunk != cmd: - self.debug("should be " + binascii.hexlify(cmd).decode("utf-8")) - self.debug("but receive " + binascii.hexlify(chunk).decode("utf-8") + "\n") - return -EINVAL - - return 0 + start_time = time.time() + unexpected_buffer = b"" + while time.time() - start_time < self.timeout: + chunk = self.read(1) + if chunk == cmd: + if unexpected_buffer: + # try to decode to UTF-8 + decoded = unexpected_buffer.decode("utf-8", errors="replace") + self.progress(f"Ignored unexpected text: {decoded}\n") + return 0 + elif chunk == NAK: + if unexpected_buffer: + decoded = unexpected_buffer.decode("utf-8", errors="replace") + self.progress(f"Ignored unexpected text: {decoded}\n") + print("EAGAIN!!!") + return -EAGAIN + elif chunk == b"": + continue + else: + unexpected_buffer += chunk + if unexpected_buffer: + decoded = unexpected_buffer.decode("utf-8", errors="replace") + self.progress(f"Ignored unexpected text: {decoded}\n") + return -EINVAL def send_handshake(self): self.write(CRC) @@ -686,7 +708,7 @@ class ymodem: return -1 self.progress("recv ret %d\n" % ret) - self.debug("recv frist packet\n") + self.debug("recv first packet\n") self.retries += 1 continue @@ -807,6 +829,29 @@ if __name__ == "__main__": help="This opthin set max retry for transmission", ) + parser.add_argument( + "-c", + "--countofc", + type=int, + default=0, + help=""" + When this value is greater than 0, it means that the rb command is not sent to + device, but to receive a specified number of consecutive 'C'. + If do not receive continuous 'C', time out and exit. + """, + ) + + parser.add_argument( + "-w", + "--waitctimeout", + type=int, + default=30, + help=""" + When the -c parameter is valid, this arg will determine whether it has timed out + while waiting for consecutive Cs. The unit is second. + """, + ) + parser.add_argument( "--debug", help="This opthin is save debug log on host", default="" ) @@ -821,19 +866,34 @@ if __name__ == "__main__": for i in args.recvfrom: recvfile += i + " " + if args.kblocksize: + recvfile += "-k %d " % (args.kblocksize) + fd_serial.write(("sb %s\r\n" % (recvfile)).encode()) fd_serial.flush() tmp = fd_serial.read(len(("sb %s\r\n" % (recvfile)).encode()) - 1) fd_serial.reset_input_buffer() else: - if args.sendto: - cmd = ("rb -f %s\r\n" % (args.sendto[0])).encode() + if args.countofc: + ret = ymodem_ser_recv_repeat_c(args.countofc, args.waitctimeout) + if ret < 0: + print("read C timeout") + fd_serial.close() + sys.exit(1) else: - cmd = ("rb\r\n").encode() + if args.sendto: + cmd = ("rb -f %s" % args.sendto[0]).encode() + else: + cmd = "rb".encode() - fd_serial.write(cmd) - fd_serial.flush() - fd_serial.read(len(cmd)) + if args.kblocksize: + cmd += (" -k %d" % args.kblocksize).encode() + + cmd += b"\r\n" + + fd_serial.write(cmd) + fd_serial.flush() + fd_serial.read(len(cmd)) fd_serial.reset_input_buffer() sbrb = ymodem( From 102c0788341f1c73d298a3acab9a81dc03a63b22 Mon Sep 17 00:00:00 2001 From: zhaoxingyu1 Date: Wed, 4 Jun 2025 14:53:31 +0800 Subject: [PATCH 221/568] mtd/nvs: modify config name to MTD_CONFIG_NVS part1 Because the MTD_CONFIG configuration item in drivers/mtd/Kconfig has changed Signed-off-by: zhaoxingyu1 --- system/cfgdata/Kconfig | 2 +- testing/fs/mtd_config_fs/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/cfgdata/Kconfig b/system/cfgdata/Kconfig index 23eb9ebce..64f51d40e 100644 --- a/system/cfgdata/Kconfig +++ b/system/cfgdata/Kconfig @@ -6,7 +6,7 @@ config SYSTEM_CFGDATA tristate "Cfgdata Command" default n - depends on MTD_CONFIG + depends on !MTD_CONFIG_NONE ---help--- Enable support for the CFGDATA tool. diff --git a/testing/fs/mtd_config_fs/Kconfig b/testing/fs/mtd_config_fs/Kconfig index 02f8b752a..d2c9c2e8c 100644 --- a/testing/fs/mtd_config_fs/Kconfig +++ b/testing/fs/mtd_config_fs/Kconfig @@ -6,7 +6,7 @@ config TESTING_MTD_CONFIG_FAIL_SAFE tristate "MTD Config fail-safe storage test" default n - depends on MTD_CONFIG_FAIL_SAFE + depends on MTD_CONFIG_NVS select MTD_CONFIG_NAMED ---help--- Enable the fail-safe storage test From d9d434d97eded8b303d20d48d46adf7b22205e3f Mon Sep 17 00:00:00 2001 From: zhaoxingyu1 Date: Tue, 3 Jun 2025 17:33:16 +0800 Subject: [PATCH 222/568] mtdconfig: lomtdconfig device change to depends on !MTD_CONFIG_NONE Because MTD_CONFIG configuration item in drivers/mtd/Kconfig has changed. Signed-off-by: zhaoxingyu1 --- nshlib/nsh_command.c | 2 +- nshlib/nsh_fscmds.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index cace8eeac..ec3f8a385 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -322,7 +322,7 @@ static const struct cmdmap_s g_cmdmap[] = #ifndef CONFIG_DISABLE_MOUNTPOINT # if defined(CONFIG_MTD_LOOP) && !defined(CONFIG_NSH_DISABLE_LOMTD) -# ifdef CONFIG_MTD_CONFIG +# ifndef CONFIG_MTD_CONFIG_NONE CMD_MAP("lomtd", cmd_lomtd, 3, 10, "[-d ] | [[-o ] [-e ] " "[-b ] [-c ] ]]"), diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index 447d45e72..13f26f694 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -1308,7 +1308,7 @@ int cmd_lomtd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) int sectsize = -1; off_t offset = 0; bool badarg = false; -# ifdef CONFIG_MTD_CONFIG +# ifndef CONFIG_MTD_CONFIG_NONE int configdata = 0; # endif int ret = ERROR; @@ -1324,7 +1324,7 @@ int cmd_lomtd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) * NOTE that the -o and -r options are accepted with the -d option, but * will be ignored. */ -# ifdef CONFIG_MTD_CONFIG +# ifndef CONFIG_MTD_CONFIG_NONE while ((option = getopt(argc, argv, "d:o:e:b:c:")) != ERROR) # else while ((option = getopt(argc, argv, "d:o:e:b:")) != ERROR) @@ -1349,7 +1349,7 @@ int cmd_lomtd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) sectsize = atoi(optarg); break; -# ifdef CONFIG_MTD_CONFIG +# ifndef CONFIG_MTD_CONFIG_NONE case 'c': configdata = atoi(optarg); break; @@ -1435,7 +1435,7 @@ int cmd_lomtd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) setup.sectsize = sectsize; /* The sector size to use with the block device */ setup.erasesize = erasesize; /* The sector size to use with the block device */ setup.offset = offset; /* An offset that may be applied to the device */ -# ifdef CONFIG_MTD_CONFIG +# ifndef CONFIG_MTD_CONFIG_NONE setup.configdata = configdata; /* Is a loop mtdconfig device */ # endif From eda1309745e4d3b7ee7bec107ebc93e52225b2eb Mon Sep 17 00:00:00 2001 From: zhaoxingyu1 Date: Wed, 28 Jan 2026 15:56:30 +0800 Subject: [PATCH 223/568] mtdconfig: modify config names for mtdconfig testcases 2 change nvs module testcase name TESTING_MTD_CONFIG_FAIL_SAFE to TESTING_MTD_CONFIG_NVS and modify the configuration names related to mtdconfig testing. Signed-off-by: zhaoxingyu1 --- testing/fs/mtd_config_fs/CMakeLists.txt | 10 +-- testing/fs/mtd_config_fs/Kconfig | 20 +++--- testing/fs/mtd_config_fs/Make.defs | 2 +- testing/fs/mtd_config_fs/Makefile | 8 +-- .../mtd_config_fs/mtd_config_fs_test_main.c | 66 +++++++++---------- 5 files changed, 53 insertions(+), 53 deletions(-) diff --git a/testing/fs/mtd_config_fs/CMakeLists.txt b/testing/fs/mtd_config_fs/CMakeLists.txt index 70201dca9..32651349b 100644 --- a/testing/fs/mtd_config_fs/CMakeLists.txt +++ b/testing/fs/mtd_config_fs/CMakeLists.txt @@ -20,16 +20,16 @@ # # ############################################################################## -if(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE) +if(CONFIG_TESTING_MTD_CONFIG_NVS) nuttx_add_application( NAME - ${CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_PROGNAME} + ${CONFIG_TESTING_MTD_CONFIG_PROGNAME} PRIORITY - ${CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_PRIORITY} + ${CONFIG_TESTING_MTD_CONFIG_PRIORITY} STACKSIZE - ${CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_STACKSIZE} + ${CONFIG_TESTING_MTD_CONFIG_STACKSIZE} MODULE - ${CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE} + ${CONFIG_TESTING_MTD_CONFIG_NVS} SRCS mtd_config_fs_test_main.c) endif() diff --git a/testing/fs/mtd_config_fs/Kconfig b/testing/fs/mtd_config_fs/Kconfig index d2c9c2e8c..0ca8d6d47 100644 --- a/testing/fs/mtd_config_fs/Kconfig +++ b/testing/fs/mtd_config_fs/Kconfig @@ -3,7 +3,7 @@ # see the file kconfig-language.txt in the NuttX tools repository. # -config TESTING_MTD_CONFIG_FAIL_SAFE +config TESTING_MTD_CONFIG_NVS tristate "MTD Config fail-safe storage test" default n depends on MTD_CONFIG_NVS @@ -11,40 +11,40 @@ config TESTING_MTD_CONFIG_FAIL_SAFE ---help--- Enable the fail-safe storage test -if TESTING_MTD_CONFIG_FAIL_SAFE +if TESTING_MTD_CONFIG_NVS -config TESTING_MTD_CONFIG_FAIL_SAFE_PROGNAME +config TESTING_MTD_CONFIG_PROGNAME string "Program name" default "mtdconfig_fs_test" ---help--- This is the name of the program that will be used when the NSH ELF program is installed. -config TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME +config TESTING_MTD_CONFIG_MOUNTPT_NAME string "MTD driver mount pt" default "/dev/mtdnvs_flash" -config TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_MAXNAME +config TESTING_MTD_CONFIG_MOUNTPT_MAXNAME int "MTD driver mount pt path len" default 64 -config TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE +config TESTING_MTD_CONFIG_FLASH_SECTION_SIZE int "MTD flash section size" default 4096 -config TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_COUNT +config TESTING_MTD_CONFIG_FLASH_SECTION_COUNT int "MTD flash section count" default 3 -config TESTING_MTD_CONFIG_FAIL_SAFE_PRIORITY +config TESTING_MTD_CONFIG_PRIORITY int "MTD nvs test task priority" default 100 -config TESTING_MTD_CONFIG_FAIL_SAFE_STACKSIZE +config TESTING_MTD_CONFIG_STACKSIZE int "MTD nvs test stack size" default 4096 -config TESTING_MTD_CONFIG_FAIL_SAFE_VERBOSE +config TESTING_MTD_CONFIG_VERBOSE bool "Verbose output" default n diff --git a/testing/fs/mtd_config_fs/Make.defs b/testing/fs/mtd_config_fs/Make.defs index 0c8bde14c..72fbf13e5 100644 --- a/testing/fs/mtd_config_fs/Make.defs +++ b/testing/fs/mtd_config_fs/Make.defs @@ -20,6 +20,6 @@ # ############################################################################ -ifneq ($(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE),) +ifneq ($(CONFIG_TESTING_MTD_CONFIG_NVS),) CONFIGURED_APPS += $(APPDIR)/testing/fs/mtd_config_fs endif diff --git a/testing/fs/mtd_config_fs/Makefile b/testing/fs/mtd_config_fs/Makefile index c3ad88386..359b210e6 100644 --- a/testing/fs/mtd_config_fs/Makefile +++ b/testing/fs/mtd_config_fs/Makefile @@ -24,10 +24,10 @@ include $(APPDIR)/Make.defs # MTD nvs test application info -PROGNAME = $(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_PROGNAME) -PRIORITY = $(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_PRIORITY) -STACKSIZE = $(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_STACKSIZE) -MODULE = $(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE) +PROGNAME = $(CONFIG_TESTING_MTD_CONFIG_PROGNAME) +PRIORITY = $(CONFIG_TESTING_MTD_CONFIG_PRIORITY) +STACKSIZE = $(CONFIG_TESTING_MTD_CONFIG_STACKSIZE) +MODULE = $(CONFIG_TESTING_MTD_CONFIG_NVS) # MTD nvs test diff --git a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c index 16ed4cb7e..c85df92aa 100644 --- a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c +++ b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c @@ -81,7 +81,7 @@ begin_packed_struct struct nvs_ate struct mtdnvs_ctx_s { - char mountdir[CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_MAXNAME]; + char mountdir[CONFIG_TESTING_MTD_CONFIG_MOUNTPT_MAXNAME]; struct mallinfo mmbefore; struct mallinfo mmprevious; struct mallinfo mmafter; @@ -351,7 +351,7 @@ static void show_useage(void) printf("Usage : mtdconfig_fs_test [OPTION [ARG]] ...\n"); printf("-h show this help statement\n"); printf("-m mount point to be tested e.g. [%s]\n", - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME); + CONFIG_TESTING_MTD_CONFIG_MOUNTPT_NAME); } /**************************************************************************** @@ -402,12 +402,12 @@ static int setup(struct mtdnvs_ctx_s *ctx) int ret; FAR struct inode *sys_node; - ret = find_mtddriver(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME, + ret = find_mtddriver(CONFIG_TESTING_MTD_CONFIG_MOUNTPT_NAME, &sys_node); if (ret < 0) { printf("ERROR: open %s failed: %d\n", - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME, ret); + CONFIG_TESTING_MTD_CONFIG_MOUNTPT_NAME, ret); return -errno; } @@ -608,7 +608,7 @@ static void test_nvs_corrupt_expire(struct mtdnvs_ctx_s *ctx) printf("%s: test begin\n", __func__); - mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME, O_RDWR); + mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_MOUNTPT_NAME, O_RDWR); if (mtd_fd < 0) { printf("%s:mtdnvs_register failed, ret=%d\n", __func__, mtd_fd); @@ -662,7 +662,7 @@ static void test_nvs_corrupt_expire(struct mtdnvs_ctx_s *ctx) /* set unused flash to 0xff */ for (i = 2 * (strlen(TEST_KEY1) + strlen(TEST_DATA1) + 2) + padding_size; - i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + i < CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - 4 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -699,7 +699,7 @@ static void test_nvs_corrupt_expire(struct mtdnvs_ctx_s *ctx) /* write close ate, mark section 0 as closed */ ret = write_close_ate(mtd_fd, ctx, - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - 4 * ate_size); if (ret < 0) { @@ -798,7 +798,7 @@ static void test_nvs_corrupted_write(struct mtdnvs_ctx_s *ctx) printf("%s: test begin\n", __func__); - mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME, O_RDWR); + mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_MOUNTPT_NAME, O_RDWR); if (mtd_fd < 0) { printf("%s:mtdnvs_register failed, ret=%d\n", __func__, mtd_fd); @@ -854,7 +854,7 @@ static void test_nvs_corrupted_write(struct mtdnvs_ctx_s *ctx) /* set unused flash to 0xff */ for (i = 2 * (sizeof(key1) + sizeof(wr_buf_1)) + padding_size; - i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + i < CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - 3 * nvs_ate_size(ctx); i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -966,7 +966,7 @@ static void test_nvs_gc(struct mtdnvs_ctx_s *ctx) size_t kv_size = nvs_align_up(ctx, 44 + 4) + ate_size; size_t block_max_write_size = - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE - ate_size; + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - ate_size; uint16_t block_max_write_nums = block_max_write_size / kv_size; const uint16_t max_writes = block_max_write_nums + 1; @@ -1235,9 +1235,9 @@ static void test_nvs_gc_3sectors(struct mtdnvs_ctx_s *ctx) size_t kv_size = nvs_align_up(ctx, 44 + 4) + ate_size; uint16_t max_id = - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE / kv_size; + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE / kv_size; const uint16_t max_writes = - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE * 2 / kv_size + 1; + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE * 2 / kv_size + 1; const uint16_t max_writes_2 = max_writes + max_id; const uint16_t max_writes_3 = max_writes_2 + max_id; const uint16_t max_writes_4 = max_writes_3 + max_id; @@ -1435,7 +1435,7 @@ static void test_nvs_corrupted_sector_close(struct mtdnvs_ctx_s *ctx) printf("%s: test begin\n", __func__); - mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME, O_RDWR); + mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_MOUNTPT_NAME, O_RDWR); if (mtd_fd < 0) { printf("%s:mtdnvs_register failed, ret=%d\n", __func__, mtd_fd); @@ -1446,7 +1446,7 @@ static void test_nvs_corrupted_sector_close(struct mtdnvs_ctx_s *ctx) for (loop_section = 0; loop_section < - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_COUNT - 1; + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_COUNT - 1; loop_section++) { /* write valid data */ @@ -1474,7 +1474,7 @@ static void test_nvs_corrupted_sector_close(struct mtdnvs_ctx_s *ctx) /* set unused flash to 0xff */ for (i = 2 * (sizeof(key1) + sizeof(wr_buf)); - i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + i < CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - 4 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -1490,7 +1490,7 @@ static void test_nvs_corrupted_sector_close(struct mtdnvs_ctx_s *ctx) ret = write_ate(mtd_fd, ctx, key1, sizeof(wr_buf), sizeof(wr_buf) + sizeof(key1), (loop_section == - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_COUNT - 2) + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_COUNT - 2) ? false : true); if (ret < 0) { @@ -1512,14 +1512,14 @@ static void test_nvs_corrupted_sector_close(struct mtdnvs_ctx_s *ctx) } if (loop_section == - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_COUNT - 2) + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_COUNT - 2) { ret = write_corrupted_close_ate(mtd_fd, ctx); } else { ret = write_close_ate(mtd_fd, ctx, - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - 4 * ate_size); } @@ -1787,7 +1787,7 @@ static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) printf("%s: test begin\n", __func__); - mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME, O_RDWR); + mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_MOUNTPT_NAME, O_RDWR); if (mtd_fd < 0) { printf("%s:mtdnvs_register failed, ret=%d\n", __func__, mtd_fd); @@ -1813,7 +1813,7 @@ static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) /* set unused flash to 0xff */ for (i = strlen(TEST_KEY1) + strlen(TEST_DATA1) + 2; - i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + i < CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - 6 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -1834,9 +1834,9 @@ static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) /* set unused flash to 0xff */ - for (i = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + for (i = CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - 5 * ate_size; - i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + i < CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - 2 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -1865,8 +1865,8 @@ static void test_nvs_gc_corrupt_close_ate(struct mtdnvs_ctx_s *ctx) /* set unused flash to 0xff in section 1 */ - for (i = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE; - i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + for (i = CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE; + i < CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -1964,7 +1964,7 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) printf("%s: test begin\n", __func__); - mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME, O_RDWR); + mtd_fd = open(CONFIG_TESTING_MTD_CONFIG_MOUNTPT_NAME, O_RDWR); if (mtd_fd < 0) { printf("%s:mtdnvs_register failed, ret=%d\n", __func__, mtd_fd); @@ -1974,7 +1974,7 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) /* set unused flash to 0xff */ for (i = 0 ; - i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE / 2; i++) + i < CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE / 2; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); if (ret != sizeof(erase_value)) @@ -1992,9 +1992,9 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) goto test_fail; } - for (i = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE / 2 + for (i = CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE / 2 + ate_size; - i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + i < CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - 2 * ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -2016,7 +2016,7 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) /* write close ate, mark section 0 as closed */ ret = write_close_ate(mtd_fd, ctx, - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE / 2); + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE / 2); if (ret < 0) { printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); @@ -2025,8 +2025,8 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) /* set unused flash to 0xff in section 1 */ - for (i = CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE; - i < CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE + for (i = CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE; + i < CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE - ate_size; i++) { ret = write(mtd_fd, &erase_value, sizeof(erase_value)); @@ -2040,7 +2040,7 @@ static void test_nvs_gc_corrupt_ate(struct mtdnvs_ctx_s *ctx) /* write close ate, mark section 1 as closed */ ret = write_close_ate(mtd_fd, ctx, - CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_FLASH_SECTION_SIZE / 2); + CONFIG_TESTING_MTD_CONFIG_FLASH_SECTION_SIZE / 2); if (ret < 0) { printf("%s:write gc_done ate failed, ret=%d\n", __func__, ret); @@ -2582,7 +2582,7 @@ int main(int argc, FAR char *argv[]) memset(ctx, 0, sizeof(struct mtdnvs_ctx_s)); - strlcpy(ctx->mountdir, CONFIG_TESTING_MTD_CONFIG_FAIL_SAFE_MOUNTPT_NAME, + strlcpy(ctx->mountdir, CONFIG_TESTING_MTD_CONFIG_MOUNTPT_NAME, sizeof(ctx->mountdir)); /* Opt Parse */ From b2d4ad67b1f789f80c8ce1903d1b75c7d535b38c Mon Sep 17 00:00:00 2001 From: hujun5 Date: Sun, 1 Feb 2026 15:16:37 +0800 Subject: [PATCH 224/568] testing/ostest: Add performance event time counter test Integrate up_perf_gettime() test into ostest suite with comprehensive test coverage including monotonicity verification, interval statistics, and frequency validation. The test verifies performance event counter functionality across 5 independent test cases with proper error handling. Signed-off-by: hujun5 --- testing/ostest/CMakeLists.txt | 4 + testing/ostest/Makefile | 4 + testing/ostest/ostest.h | 6 + testing/ostest/ostest_main.c | 8 ++ testing/ostest/perf_gettime.c | 231 ++++++++++++++++++++++++++++++++++ 5 files changed, 253 insertions(+) create mode 100644 testing/ostest/perf_gettime.c diff --git a/testing/ostest/CMakeLists.txt b/testing/ostest/CMakeLists.txt index a8a2ca921..6096c7ce6 100644 --- a/testing/ostest/CMakeLists.txt +++ b/testing/ostest/CMakeLists.txt @@ -161,6 +161,10 @@ if(CONFIG_TESTING_OSTEST) list(APPEND SRCS hrtimer.c) endif() + if(CONFIG_ARCH_HAVE_PERF_EVENTS) + list(APPEND SRCS perf_gettime.c) + endif() + if(CONFIG_BUILD_FLAT) list(APPEND SRCS wdog.c spinlock.c) endif() diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile index 817fcdb51..1f6a28b2f 100644 --- a/testing/ostest/Makefile +++ b/testing/ostest/Makefile @@ -166,6 +166,10 @@ CSRCS += hrtimer.c endif endif +ifeq ($(CONFIG_ARCH_HAVE_PERF_EVENTS),y) +CSRCS += perf_gettime.c +endif + ifeq ($(CONFIG_BUILD_FLAT),y) CSRCS += wdog.c spinlock.c endif diff --git a/testing/ostest/ostest.h b/testing/ostest/ostest.h index 1a396ba28..f4f09ca8b 100644 --- a/testing/ostest/ostest.h +++ b/testing/ostest/ostest.h @@ -290,6 +290,12 @@ void smp_call_test(void); void spinlock_test(void); +/* perf_gettime.c ***********************************************************/ + +#ifdef CONFIG_ARCH_HAVE_PERF_EVENTS +void perf_gettime_test(void); +#endif + /* APIs exported (conditionally) by the OS specifically for testing of * priority inheritance */ diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index 8247b4788..c711a8db6 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -635,6 +635,14 @@ static int user_main(int argc, char *argv[]) check_test_memory_usage(); #endif +#if defined(CONFIG_ARCH_PERF_EVENTS) && !defined(CONFIG_ARCH_PERF_EVENTS_USER_ACCESS) + /* Verify performance event time counter */ + + printf("\nuser_main: performance event time counter test\n"); + perf_gettime_test(); + check_test_memory_usage(); +#endif + #if defined(CONFIG_HRTIMER) && defined(CONFIG_BUILD_FLAT) /* Verify hrtimer */ diff --git a/testing/ostest/perf_gettime.c b/testing/ostest/perf_gettime.c new file mode 100644 index 000000000..35fcaabff --- /dev/null +++ b/testing/ostest/perf_gettime.c @@ -0,0 +1,231 @@ +/**************************************************************************** + * apps/testing/ostest/perf_gettime.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ostest.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Performance event test parameters */ + +#define PERF_ITERATIONS 10 +#define SLEEP_INTERVAL_USEC 100000 /* 100ms */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_ARCH_PERF_EVENTS +static clock_t g_prev_time = 0; +static clock_t g_min_interval = ULONG_MAX; +static clock_t g_max_interval = 0; +static unsigned long g_total_interval = 0; +static int g_iteration_count = 0; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: perf_gettime_test + * + * Description: + * Test performance event time counter: perf_gettime() + * + * This test verifies: + * 1. perf_gettime() returns non-zero values + * 2. Time values are monotonically increasing + * 3. Multiple calls return consistent intervals + * 4. Performance counter frequency is reasonable + * + ****************************************************************************/ + +void perf_gettime_test(void) +{ +#ifdef CONFIG_ARCH_PERF_EVENTS + int i; + clock_t curr_time; + clock_t time_interval; + unsigned long perf_freq; + + printf("\nperf_gettime_test: Starting performance event test\n"); + + /* Test 1: Get initial time value */ + + printf("\nTest 1: Getting initial performance time value\n"); + g_prev_time = perf_gettime(); + printf("perf_gettime_test: Initial time = %lu\n", + (unsigned long)g_prev_time); + + /* We expect the counter to not be zero (unless just initialized) */ + + if (g_prev_time == 0) + { + printf("perf_gettime_test: WARNING - Initial time is zero\n"); + } + + /* Test 2: Verify monotonically increasing time */ + + printf("\nTest 2: Verify monotonically increasing time values\n"); + g_total_interval = 0; + g_min_interval = ULONG_MAX; + g_max_interval = 0; + g_iteration_count = 0; + + for (i = 0; i < PERF_ITERATIONS; i++) + { + /* Sleep for a short interval */ + + usleep(SLEEP_INTERVAL_USEC); + + /* Get new time value */ + + curr_time = perf_gettime(); + time_interval = curr_time - g_prev_time; + + printf("perf_gettime_test [%d]: current=%lu, interval=%lu\n", + i, (unsigned long)curr_time, (unsigned long)time_interval); + + /* Verify time is monotonically increasing */ + + if (curr_time <= g_prev_time) + { + printf("perf_gettime_test: ERROR - Time not monotonically " + "increasing at iteration %d\n", i); + printf(" Previous time: %lu, Current time: %lu\n", + (unsigned long)g_prev_time, (unsigned long)curr_time); + ASSERT(false); + } + + /* Track intervals */ + + if (time_interval < g_min_interval) + { + g_min_interval = time_interval; + } + + if (time_interval > g_max_interval) + { + g_max_interval = time_interval; + } + + g_total_interval += time_interval; + g_iteration_count++; + + g_prev_time = curr_time; + } + + /* Test 3: Analyze time intervals */ + + printf("\nTest 3: Analyzing time intervals\n"); + + if (g_iteration_count > 0) + { + unsigned long avg_interval = g_total_interval / g_iteration_count; + + printf("perf_gettime_test: Interval statistics:\n"); + printf(" Minimum interval: %lu\n", (unsigned long)g_min_interval); + printf(" Maximum interval: %lu\n", (unsigned long)g_max_interval); + printf(" Average interval: %lu\n", avg_interval); + printf(" Total iterations: %d\n", g_iteration_count); + + /* Verify that intervals are within reasonable bounds */ + + if (g_max_interval == 0 || g_min_interval == ULONG_MAX) + { + printf("perf_gettime_test: WARNING - \ + No time intervals recorded\n"); + } + else + { + printf("perf_gettime_test: Time intervals look reasonable\n"); + } + } + + /* Test 4: Test perf_getfreq() if available */ + + printf("\nTest 4: Getting performance counter frequency\n"); + + perf_freq = perf_getfreq(); + printf("perf_gettime_test: Performance frequency = %lu Hz\n", perf_freq); + + if (perf_freq == ULONG_MAX || perf_freq == 0) + { + printf("perf_gettime_test: WARNING - Performance frequency is " \ + "invalid or uninitialized\n"); + } + else + { + printf("perf_gettime_test: Performance frequency is valid\n"); + } + + /* Test 5: Multiple rapid calls */ + + printf("\nTest 5: Testing multiple rapid calls\n"); + + curr_time = perf_gettime(); + printf("perf_gettime_test: Rapid call 1: %lu\n", (unsigned long)curr_time); + + /* Make several rapid calls */ + + for (i = 0; i < 5; i++) + { + clock_t t = perf_gettime(); + printf("perf_gettime_test: Rapid call %d: %lu\n", i + 2, + (unsigned long)t); + + /* Verify either monotonic increase or same value (on fast systems) */ + + if (t < curr_time) + { + printf("perf_gettime_test: ERROR - Time went backwards!\n"); + ASSERT(false); + } + + curr_time = t; + } + + printf("\nperf_gettime_test: All performance event tests PASSED\n"); + +#else /* CONFIG_ARCH_PERF_EVENTS */ + + printf("\nperf_gettime_test: Skipping test - " + "CONFIG_ARCH_PERF_EVENTS not enabled\n"); + +#endif /* CONFIG_ARCH_PERF_EVENTS */ +} From eb9b9a2d608c160bb25f67bce5eca499210b0bb5 Mon Sep 17 00:00:00 2001 From: fangpeina Date: Thu, 8 May 2025 22:10:40 +0800 Subject: [PATCH 225/568] netutils/rexecd: fix rpname mismatch with rexec when using AF_RPMSG When using AF_RPMSG (-r option), rexecd was setting the rp_name to the raw port number, while rexec was using htons(port). This caused a mismatch where rexec couldn't connect to rexecd. This commit fixes the issue by applying htons() to REXECD_PORT when setting rp_name in the AF_RPMSG case, making it consistent with the rexec client implementation. Signed-off-by: fangpeina --- netutils/rexecd/rexecd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netutils/rexecd/rexecd.c b/netutils/rexecd/rexecd.c index 2e462083c..6c238d586 100644 --- a/netutils/rexecd/rexecd.c +++ b/netutils/rexecd/rexecd.c @@ -223,7 +223,7 @@ int main(int argc, FAR char **argv) case AF_RPMSG: ((FAR struct sockaddr_rpmsg *)&addr)->rp_family = AF_RPMSG; snprintf(((FAR struct sockaddr_rpmsg *)&addr)->rp_name, - RPMSG_SOCKET_NAME_SIZE, "%d", REXECD_PORT); + RPMSG_SOCKET_NAME_SIZE, "%d", htons(REXECD_PORT)); ret = sizeof(struct sockaddr_rpmsg); } From f9dc9bc21e6a2b3c83826bc5efae78903f31455f Mon Sep 17 00:00:00 2001 From: fangpeina Date: Mon, 25 Nov 2024 10:44:11 +0800 Subject: [PATCH 226/568] testing: Fix cmocka_syscall_test crash when CONFIG_FDCHECK enable Fix cmocka_syscall_test crash when CONFIG_FDCHECK is enabled. Signed-off-by: fangpeina --- testing/testsuites/kernel/syscall/cases/connect_test.c | 6 ++++-- testing/testsuites/kernel/syscall/cases/dup_test.c | 2 +- testing/testsuites/kernel/syscall/cases/listen_test.c | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/testing/testsuites/kernel/syscall/cases/connect_test.c b/testing/testsuites/kernel/syscall/cases/connect_test.c index 530e9c8fd..8c808e1a4 100644 --- a/testing/testsuites/kernel/syscall/cases/connect_test.c +++ b/testing/testsuites/kernel/syscall/cases/connect_test.c @@ -77,11 +77,13 @@ __attribute__((unused)) static struct test_case_t tdat[] = { + #ifndef CONFIG_FDCHECK { PF_INET, SOCK_STREAM, 0, (struct sockaddr *)&sin1, sizeof(struct sockaddr_in), -1, EBADF, setup0, cleanup0, "bad file descriptor" }, + #endif #ifndef UCLINUX /* Skip since uClinux does not implement memory protection */ @@ -97,12 +99,12 @@ tdat[] = PF_INET, SOCK_STREAM, 0, (struct sockaddr *)&sin1, 3, -1, EINVAL, setup1, cleanup1, "invalid salen" }, - + #ifndef CONFIG_FDCHECK { 0, 0, 0, (struct sockaddr *)&sin1, sizeof(sin1), -1, ENOTSOCK, setup0, cleanup0, "invalid socket" }, - + #endif { PF_INET, SOCK_STREAM, 0, (struct sockaddr *)&sin1, sizeof(sin1), -1, EISCONN, setup2, cleanup1, diff --git a/testing/testsuites/kernel/syscall/cases/dup_test.c b/testing/testsuites/kernel/syscall/cases/dup_test.c index 0d31adae1..4794866be 100644 --- a/testing/testsuites/kernel/syscall/cases/dup_test.c +++ b/testing/testsuites/kernel/syscall/cases/dup_test.c @@ -78,7 +78,7 @@ void test_nuttx_syscall_dup01(FAR void **state) void test_nuttx_syscall_dup02(FAR void **state) { -#ifndef CONFIG_FDSAN +#if !defined(CONFIG_FDSAN) && !defined(CONFIG_FDCHECK) int fds[] = { -1, 1500 diff --git a/testing/testsuites/kernel/syscall/cases/listen_test.c b/testing/testsuites/kernel/syscall/cases/listen_test.c index 7dc4ba266..de016b009 100644 --- a/testing/testsuites/kernel/syscall/cases/listen_test.c +++ b/testing/testsuites/kernel/syscall/cases/listen_test.c @@ -68,10 +68,12 @@ void test_nuttx_syscall_listen01(FAR void **state) tdat[] = { + #ifndef CONFIG_FDCHECK { 0, 0, 0, 0, -1, EBADF, "setup0", "cleanup0", "bad file descriptor" }, + #endif { 0, 0, 0, 0, -1, ENOTSOCK, "setup0", "cleanup0", "not a socket" From bb9229de06e33baa6b24821aa15bebd51b272b6d Mon Sep 17 00:00:00 2001 From: fangpeina Date: Wed, 19 Mar 2025 21:38:01 +0800 Subject: [PATCH 227/568] testing/drivers: set default vendor dalay to 1 for rtc cases run correctly Set default VENDOR_DELAY to 1 for reliable test execution Signed-off-by: fangpeina --- testing/drivers/drivertest/drivertest_rtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/drivers/drivertest/drivertest_rtc.c b/testing/drivers/drivertest/drivertest_rtc.c index e25e93c55..62e4fd0a2 100644 --- a/testing/drivers/drivertest/drivertest_rtc.c +++ b/testing/drivers/drivertest/drivertest_rtc.c @@ -54,7 +54,7 @@ #define DEFAULT_TIME_OUT 5 #define SLEEPSECONDS 10 #define RTC_SIGNO 13 -#define VENDOR_DELAY 0 +#define VENDOR_DELAY 1 #define OPTARG_TO_VALUE(value, type, base) \ do \ From d48b45000d1d083082f7a1650f351573c36a87d0 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Mon, 23 Dec 2024 13:42:20 +0800 Subject: [PATCH 228/568] netlib_xarp: remove redundant cast removes redundant type casts in ARP-related network library functions. The casts from req.arp_dev (already a char array) to (FAR char *) are unnecessary and can be safely removed. Signed-off-by: zhanghongyu --- netutils/netlib/netlib_delarp.c | 3 +-- netutils/netlib/netlib_getarp.c | 3 +-- netutils/netlib/netlib_setarp.c | 3 +-- nshlib/nsh_netcmds.c | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/netutils/netlib/netlib_delarp.c b/netutils/netlib/netlib_delarp.c index 7a263211c..ac8fc1ad6 100644 --- a/netutils/netlib/netlib_delarp.c +++ b/netutils/netlib/netlib_delarp.c @@ -76,8 +76,7 @@ int netlib_del_arpmapping(FAR const struct sockaddr_in *inaddr, memset(&req.arp_ha, 0, sizeof(struct sockaddr_in)); if (ifname != NULL) { - strlcpy((FAR char *)&req.arp_dev, ifname, - sizeof(req.arp_dev)); + strlcpy(req.arp_dev, ifname, sizeof(req.arp_dev)); } else { diff --git a/netutils/netlib/netlib_getarp.c b/netutils/netlib/netlib_getarp.c index d023bce30..b98d99f9b 100644 --- a/netutils/netlib/netlib_getarp.c +++ b/netutils/netlib/netlib_getarp.c @@ -77,8 +77,7 @@ int netlib_get_arpmapping(FAR const struct sockaddr_in *inaddr, memcpy(&req.arp_pa, inaddr, sizeof(struct sockaddr_in)); if (ifname != NULL) { - strlcpy((FAR char *)&req.arp_dev, ifname, - sizeof(req.arp_dev)); + strlcpy(req.arp_dev, ifname, sizeof(req.arp_dev)); } else { diff --git a/netutils/netlib/netlib_setarp.c b/netutils/netlib/netlib_setarp.c index 1c2261d4c..a62ac9a9e 100644 --- a/netutils/netlib/netlib_setarp.c +++ b/netutils/netlib/netlib_setarp.c @@ -81,8 +81,7 @@ int netlib_set_arpmapping(FAR const struct sockaddr_in *inaddr, req.arp_flags = ATF_PERM; if (ifname != NULL) { - strlcpy((FAR char *)&req.arp_dev, ifname, - sizeof(req.arp_dev)); + strlcpy(req.arp_dev, ifname, sizeof(req.arp_dev)); } else { diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 6010e1084..8cd0d6cc3 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -1310,7 +1310,7 @@ int cmd_arp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) FAR uint8_t *ptr; if (ifname != NULL && - strcmp(ifname, (FAR char *)arptab[i].arp_dev) != 0) + strcmp(ifname, arptab[i].arp_dev) != 0) { continue; } From 7289c27a8509c4943ee359644067b9e9326e93eb Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Thu, 5 Feb 2026 15:15:25 -0500 Subject: [PATCH 229/568] testing/{ostest,sched/smp}: Remove BOARD_LOOPSPERMSEC references In an effort to avoid unexpected behaviour from users not calibrating BOARD_LOOPSPERMSEC, a compilation error occurs when it is undefined. On some systems, this is allowed (those that use timer implementations instead of busy-looping for delays). In these cases, we should busy-loop using the clock time instead of relying on a possibly undefined/uncalibrated macro. Signed-off-by: Matteo Golin --- testing/ostest/sporadic.c | 14 ++++++++++---- testing/ostest/sporadic2.c | 16 +++++++++++----- testing/sched/smp/smp_main.c | 15 +++++++++++---- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/testing/ostest/sporadic.c b/testing/ostest/sporadic.c index 5e6986ba7..98a8d755f 100644 --- a/testing/ostest/sporadic.c +++ b/testing/ostest/sporadic.c @@ -65,13 +65,19 @@ static time_t g_start_time; static void my_mdelay(unsigned int milliseconds) { - volatile unsigned int i; - volatile unsigned int j; + struct timespec start; + struct timespec cur; + struct timespec diff; - for (i = 0; i < milliseconds; i++) + clock_gettime(CLOCK_MONOTONIC, &start); + + for (; ; ) { - for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + clock_gettime(CLOCK_MONOTONIC, &cur); + clock_timespec_subtract(&cur, &start, &diff); + if (diff.tv_sec * 1000 + diff.tv_nsec / 1000000 > milliseconds) { + break; } } } diff --git a/testing/ostest/sporadic2.c b/testing/ostest/sporadic2.c index acc7f34e1..494dc8b29 100644 --- a/testing/ostest/sporadic2.c +++ b/testing/ostest/sporadic2.c @@ -80,13 +80,19 @@ static int32_t g_ms_cnt2[2] = static void my_mdelay(unsigned int milliseconds) { - volatile unsigned int i; - volatile unsigned int j; + struct timespec start; + struct timespec cur; + struct timespec diff; - for (i = 0; i < milliseconds; i++) + clock_gettime(CLOCK_MONOTONIC, &start); + + for (; ; ) { - for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + clock_gettime(CLOCK_MONOTONIC, &cur); + clock_timespec_subtract(&cur, &start, &diff); + if (diff.tv_sec * 1000 + diff.tv_nsec / 1000000 > milliseconds) { + break; } } } @@ -172,7 +178,7 @@ static void sporadic_test_case(int32_t budget_1_ns, int32_t budget_2_ns) sem_init(&g_sporadic_sem, 0, 0); - /* initilize global worker-thread millisecons-counters */ + /* Initialize global worker-thread milliseconds-counters */ g_ms_cnt1[PRIO_HI_NDX] = 0; g_ms_cnt1[PRIO_LO_NDX] = 0; diff --git a/testing/sched/smp/smp_main.c b/testing/sched/smp/smp_main.c index 8c3b94e7e..98f1894db 100644 --- a/testing/sched/smp/smp_main.c +++ b/testing/sched/smp/smp_main.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -87,13 +88,19 @@ static void show_cpu_conditional(FAR const char *caller, int threadno) static void hog_milliseconds(unsigned int milliseconds) { - volatile unsigned int i; - volatile unsigned int j; + struct timespec start; + struct timespec cur; + struct timespec diff; - for (i = 0; i < milliseconds; i++) + clock_gettime(CLOCK_MONOTONIC, &start); + + for (; ; ) { - for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + clock_gettime(CLOCK_MONOTONIC, &cur); + clock_timespec_subtract(&cur, &start, &diff); + if (diff.tv_sec * 1000 + diff.tv_nsec / 1000000 > milliseconds) { + break; } } } From 1ab486d1d040dfa8243dff9368c1f0b6bf73cc5f Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Thu, 12 Feb 2026 17:30:41 +0530 Subject: [PATCH 230/568] netutils/cjson: update download URL for cJSON tarball to include refs/tags Modified the CMakeLists.txt and Makefile to ensure the correct format for downloading the cJSON tarball from GitHub by including 'refs/tags/' in the URL. This change addresses issues with fetching the correct version of the library. Signed-off-by: Arjav Patel --- netutils/cjson/CMakeLists.txt | 3 ++- netutils/cjson/Makefile | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/netutils/cjson/CMakeLists.txt b/netutils/cjson/CMakeLists.txt index 83a6475cd..b497e4a01 100644 --- a/netutils/cjson/CMakeLists.txt +++ b/netutils/cjson/CMakeLists.txt @@ -30,12 +30,13 @@ if(CONFIG_NETUTILS_CJSON) set(CONFIG_NETUTILS_CJSON_VERSION "1.7.10") endif() + # GitHub requires refs/tags/ in the archive URL for tag downloads if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/cJSON) FetchContent_Declare( cJSON DOWNLOAD_NAME "v${CONFIG_NETUTILS_CJSON_VERSION}.tar.gz" DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR} - URL "${CONFIG_NETUTILS_CJSON_URL}/v${CONFIG_NETUTILS_CJSON_VERSION}.tar.gz" + URL "${CONFIG_NETUTILS_CJSON_URL}/refs/tags/v${CONFIG_NETUTILS_CJSON_VERSION}.tar.gz" SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/cJSON BINARY_DIR diff --git a/netutils/cjson/Makefile b/netutils/cjson/Makefile index d8993373d..683bdb3da 100644 --- a/netutils/cjson/Makefile +++ b/netutils/cjson/Makefile @@ -49,10 +49,12 @@ CSRCS = $(CJSON_SRCDIR)$(DELIM)cJSON.c CSRCS += $(CJSON_SRCDIR)$(DELIM)cJSON_Utils.c # Download and unpack tarball if no git repo found +# GitHub requires refs/tags/ in the archive URL for tag downloads (see +# https://docs.github.com/en/repositories/working-with-files/using-files/downloading-source-code-archives) ifeq ($(wildcard $(CJSON_UNPACKNAME)/.git),) $(CJSON_TARBALL): @echo "Downloading: $(CJSON_TARBALL)" - $(Q) curl -O -L $(CONFIG_NETUTILS_CJSON_URL)/$(CJSON_TARBALL) + $(Q) curl -O -L $(CONFIG_NETUTILS_CJSON_URL)/refs/tags/$(CJSON_TARBALL) $(CJSON_UNPACKNAME): $(CJSON_TARBALL) @echo "Unpacking: $(CJSON_TARBALL) -> $(CJSON_UNPACKNAME)" From 76e02c0dd6cf2fa2b536f25c6136c4f277cd3ca5 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Thu, 12 Feb 2026 17:54:54 +0530 Subject: [PATCH 231/568] netutils/cjson: update cJSON download URL format Modified CMakeLists.txt, Kconfig, and Makefile to change the cJSON download URL to include 'refs/tags/' for proper version fetching. This ensures compatibility with GitHub's archive download requirements. Signed-off-by: Arjav Patel --- netutils/cjson/CMakeLists.txt | 6 +++--- netutils/cjson/Kconfig | 2 +- netutils/cjson/Makefile | 6 ++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/netutils/cjson/CMakeLists.txt b/netutils/cjson/CMakeLists.txt index b497e4a01..729dbc619 100644 --- a/netutils/cjson/CMakeLists.txt +++ b/netutils/cjson/CMakeLists.txt @@ -23,20 +23,20 @@ if(CONFIG_NETUTILS_CJSON) if(NOT CONFIG_NETUTILS_CJSON_URL) - set(CONFIG_NETUTILS_CJSON_URL "https://github.com/DaveGamble/cJSON/archive") + set(CONFIG_NETUTILS_CJSON_URL + "https://github.com/DaveGamble/cJSON/archive/refs/tags") endif() if(NOT CONFIG_NETUTILS_CJSON_VERSION) set(CONFIG_NETUTILS_CJSON_VERSION "1.7.10") endif() - # GitHub requires refs/tags/ in the archive URL for tag downloads if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/cJSON) FetchContent_Declare( cJSON DOWNLOAD_NAME "v${CONFIG_NETUTILS_CJSON_VERSION}.tar.gz" DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR} - URL "${CONFIG_NETUTILS_CJSON_URL}/refs/tags/v${CONFIG_NETUTILS_CJSON_VERSION}.tar.gz" + URL "${CONFIG_NETUTILS_CJSON_URL}/v${CONFIG_NETUTILS_CJSON_VERSION}.tar.gz" SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/cJSON BINARY_DIR diff --git a/netutils/cjson/Kconfig b/netutils/cjson/Kconfig index 4a360de6a..05773f157 100644 --- a/netutils/cjson/Kconfig +++ b/netutils/cjson/Kconfig @@ -14,7 +14,7 @@ if NETUTILS_CJSON config NETUTILS_CJSON_URL string "URL where cJSON library can be downloaded" - default "https://github.com/DaveGamble/cJSON/archive" + default "https://github.com/DaveGamble/cJSON/archive/refs/tags" config NETUTILS_CJSON_VERSION string "Version number" diff --git a/netutils/cjson/Makefile b/netutils/cjson/Makefile index 683bdb3da..050e5cf86 100644 --- a/netutils/cjson/Makefile +++ b/netutils/cjson/Makefile @@ -28,7 +28,7 @@ include $(APPDIR)/Make.defs WD := ${shell echo $(CURDIR) | sed -e 's/ /\\ /g'} -CONFIG_NETUTILS_CJSON_URL ?= "https://github.com/DaveGamble/cJSON/archive" +CONFIG_NETUTILS_CJSON_URL ?= "https://github.com/DaveGamble/cJSON/archive/refs/tags" CONFIG_NETUTILS_CJSON_VERSION ?= "1.7.10" CJSON_VERSION = $(patsubst "%",%,$(strip $(CONFIG_NETUTILS_CJSON_VERSION))) @@ -49,12 +49,10 @@ CSRCS = $(CJSON_SRCDIR)$(DELIM)cJSON.c CSRCS += $(CJSON_SRCDIR)$(DELIM)cJSON_Utils.c # Download and unpack tarball if no git repo found -# GitHub requires refs/tags/ in the archive URL for tag downloads (see -# https://docs.github.com/en/repositories/working-with-files/using-files/downloading-source-code-archives) ifeq ($(wildcard $(CJSON_UNPACKNAME)/.git),) $(CJSON_TARBALL): @echo "Downloading: $(CJSON_TARBALL)" - $(Q) curl -O -L $(CONFIG_NETUTILS_CJSON_URL)/refs/tags/$(CJSON_TARBALL) + $(Q) curl -O -L $(CONFIG_NETUTILS_CJSON_URL)/$(CJSON_TARBALL) $(CJSON_UNPACKNAME): $(CJSON_TARBALL) @echo "Unpacking: $(CJSON_TARBALL) -> $(CJSON_UNPACKNAME)" From be2cdfa5972b04e0d9584fed317ecc46a07ba4aa Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Sun, 15 Feb 2026 16:23:26 -0500 Subject: [PATCH 232/568] !interpreters/bas: Align naming of configuration options Aligns `CONFIG_INTERPRETER_*` options to `CONFIG_INTERPRETERS_*` options to be consistent with other interpreters. BREAKING CHANGE: All configurations using `CONFIG_INTERPRETER_BAS_*` options will no longer compile due to missing symbol errors. The fix is very quick: any configurations using this options should add a trailing S following INTERPRETER in the affected Kconfig variables. I believe `./tools/refresh.sh` should also be capable of doing this automatically. Signed-off-by: Matteo Golin --- interpreters/bas/CMakeLists.txt | 6 +++--- interpreters/bas/Kconfig | 14 +++++++------- interpreters/bas/Makefile | 6 +++--- interpreters/bas/bas.c | 4 ++-- interpreters/bas/bas_fs.c | 16 ++++++++-------- interpreters/bas/bas_main.c | 2 +- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/interpreters/bas/CMakeLists.txt b/interpreters/bas/CMakeLists.txt index 86219418a..527353d7c 100644 --- a/interpreters/bas/CMakeLists.txt +++ b/interpreters/bas/CMakeLists.txt @@ -27,9 +27,9 @@ if(CONFIG_INTERPRETERS_BAS) SRCS bas_main.c STACKSIZE - ${CONFIG_INTERPRETER_BAS_STACKSIZE} + ${CONFIG_INTERPRETERS_BAS_STACKSIZE} PRIORITY - ${CONFIG_INTERPRETER_BAS_PRIORITY}) + ${CONFIG_INTERPRETERS_BAS_PRIORITY}) set(CSRCS bas_str.c @@ -42,7 +42,7 @@ if(CONFIG_INTERPRETERS_BAS) bas_global.c bas_program.c) - if(CONFIG_INTERPRETER_BAS_VT100) + if(CONFIG_INTERPRETERS_BAS_VT100) list(APPEND CSRCS bas_vt100.c) endif() diff --git a/interpreters/bas/Kconfig b/interpreters/bas/Kconfig index db84d3d07..39b502902 100644 --- a/interpreters/bas/Kconfig +++ b/interpreters/bas/Kconfig @@ -33,37 +33,37 @@ config INTERPRETERS_BAS if INTERPRETERS_BAS -config INTERPRETER_BAS_VERSION +config INTERPRETERS_BAS_VERSION string "Version number" default "2.4" -config INTERPRETER_BAS_PRIORITY +config INTERPRETERS_BAS_PRIORITY int "Basic interpreter priority" default 100 ---help--- Task priority of the Basic interpreter main task -config INTERPRETER_BAS_STACKSIZE +config INTERPRETERS_BAS_STACKSIZE int "Basic interpreter stack size" default 4096 ---help--- Size of the stack allocated for the Basic interpreter main task -config INTERPRETER_BAS_VT100 +config INTERPRETERS_BAS_VT100 bool "VT100 terminal support" default y -config INTERPRETER_BAS_USE_LR0 +config INTERPRETERS_BAS_USE_LR0 bool "LR0 parser" default n ---help--- Select if you want LR0 parser. -config INTERPRETER_BAS_USE_SELECT +config INTERPRETERS_BAS_USE_SELECT bool "Use select()" default n -config INTERPRETER_BAS_HAVE_FTRUNCATE +config INTERPRETERS_BAS_HAVE_FTRUNCATE bool default n ---help--- diff --git a/interpreters/bas/Makefile b/interpreters/bas/Makefile index 332cb17df..532c74043 100644 --- a/interpreters/bas/Makefile +++ b/interpreters/bas/Makefile @@ -27,7 +27,7 @@ include $(APPDIR)/Make.defs CSRCS = bas.c bas_auto.c bas_fs.c bas_global.c bas_program.c CSRCS += bas_str.c bas_token.c bas_value.c bas_var.c -ifeq ($(CONFIG_INTERPRETER_BAS_VT100),y) +ifeq ($(CONFIG_INTERPRETERS_BAS_VT100),y) CSRCS += bas_vt100.c endif @@ -36,8 +36,8 @@ MAINSRC = bas_main.c # BAS built-in application info PROGNAME = bas -PRIORITY = $(CONFIG_INTERPRETER_BAS_PRIORITY) -STACKSIZE = $(CONFIG_INTERPRETER_BAS_STACKSIZE) +PRIORITY = $(CONFIG_INTERPRETERS_BAS_PRIORITY) +STACKSIZE = $(CONFIG_INTERPRETERS_BAS_STACKSIZE) MODULE = $(CONFIG_INTERPRETERS_BAS) include $(APPDIR)/Application.mk diff --git a/interpreters/bas/bas.c b/interpreters/bas/bas.c index 3ccaea3b9..18b08876f 100644 --- a/interpreters/bas/bas.c +++ b/interpreters/bas/bas.c @@ -614,7 +614,7 @@ static struct Value *func(struct Value *value) return value; } -#ifdef CONFIG_INTERPRETER_BAS_USE_LR0 +#ifdef CONFIG_INTERPRETERS_BAS_USE_LR0 /* Grammar with LR(0) sets */ @@ -2368,7 +2368,7 @@ void bas_interpreter(void) { if (FS_istty(STDCHANNEL)) { - FS_putChars(STDCHANNEL, "bas " CONFIG_INTERPRETER_BAS_VERSION "\n"); + FS_putChars(STDCHANNEL, "bas " CONFIG_INTERPRETERS_BAS_VERSION "\n"); FS_putChars(STDCHANNEL, "Copyright 1999-2014 Michael Haardt.\n"); FS_putChars(STDCHANNEL, "This is free software with ABSOLUTELY NO WARRANTY.\n"); diff --git a/interpreters/bas/bas_fs.c b/interpreters/bas/bas_fs.c index 199f41bb9..ad708a912 100644 --- a/interpreters/bas/bas_fs.c +++ b/interpreters/bas/bas_fs.c @@ -270,7 +270,7 @@ static int edit(int chn, int nl) { if (f->inCapacity) { -#ifdef CONFIG_INTERPRETER_BAS_VT100 +#ifdef CONFIG_INTERPRETERS_BAS_VT100 /* Could use vt100_clrtoeol */ #endif /* Is the previous char in buffer 2 char escape sequence? */ @@ -319,7 +319,7 @@ static int edit(int chn, int nl) static int cls(int chn) { -#ifdef CONFIG_INTERPRETER_BAS_VT100 +#ifdef CONFIG_INTERPRETERS_BAS_VT100 vt100_clrscreen(chn); vt100_cursorhome(chn); return 0; @@ -331,7 +331,7 @@ static int cls(int chn) static int locate(int chn, int line, int column) { -#ifdef CONFIG_INTERPRETER_BAS_VT100 +#ifdef CONFIG_INTERPRETERS_BAS_VT100 vt100_setcursor(chn, line, column); return 0; #else @@ -342,7 +342,7 @@ static int locate(int chn, int line, int column) static int colour(int chn, int foreground, int background) { -#ifdef CONFIG_INTERPRETER_BAS_VT100 +#ifdef CONFIG_INTERPRETERS_BAS_VT100 if (foreground >= 0) { vt100_foreground_color(chn, foreground); @@ -362,7 +362,7 @@ static int colour(int chn, int foreground, int background) static int resetcolour(int chn) { -#ifdef CONFIG_INTERPRETER_BAS_VT100 +#ifdef CONFIG_INTERPRETERS_BAS_VT100 vt100_foreground_color(chn, VT100_DEFAULT); vt100_background_color(chn, VT100_DEFAULT); #endif @@ -837,7 +837,7 @@ int FS_lock(int chn, off_t offset, off_t length, int mode, int w) int FS_truncate(int chn) { -#ifdef CONFIG_INTERPRETER_BAS_HAVE_FTRUNCATE +#ifdef CONFIG_INTERPRETERS_BAS_HAVE_FTRUNCATE int fd; off_t o; @@ -1411,7 +1411,7 @@ int FS_inkeyChar(int dev, int ms) struct FileStream *f; char c; ssize_t len; -#ifdef CONFIG_INTERPRETER_BAS_USE_SELECT +#ifdef CONFIG_INTERPRETERS_BAS_USE_SELECT fd_set just_infd; struct timeval timeout; #endif @@ -1427,7 +1427,7 @@ int FS_inkeyChar(int dev, int ms) return f->inBuf[f->inSize++]; } -#ifdef CONFIG_INTERPRETER_BAS_USE_SELECT +#ifdef CONFIG_INTERPRETERS_BAS_USE_SELECT FD_ZERO(&just_infd); FD_SET(f->infd, &just_infd); timeout.tv_sec = ms / 1000; diff --git a/interpreters/bas/bas_main.c b/interpreters/bas/bas_main.c index 4bb2d0f12..833721dab 100644 --- a/interpreters/bas/bas_main.c +++ b/interpreters/bas/bas_main.c @@ -84,7 +84,7 @@ int main(int argc, FAR char *argv[]) break; case 'V': - printf("bas %s\n", CONFIG_INTERPRETER_BAS_VERSION); + printf("bas %s\n", CONFIG_INTERPRETERS_BAS_VERSION); exit(0); break; From 468ded86bb02e054c0d730bd02314a11bc95da47 Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Sun, 15 Feb 2026 16:24:23 -0500 Subject: [PATCH 233/568] !interpreters/lua: Align naming of configuration options Aligns `CONFIG_INTERPRETER_*` options to `CONFIG_INTERPRETERS_*` options to be consistent with other interpreters. BREAKING CHANGE: All configurations using `CONFIG_INTERPRETER_LUA_*` options will no longer compile due to missing symbol errors. The fix is very quick: any configurations using this options should add a trailing S following INTERPRETER in the affected Kconfig variables. I believe `./tools/refresh.sh` should also be capable of doing this automatically. Signed-off-by: Matteo Golin --- interpreters/lua/CMakeLists.txt | 20 ++++++++++---------- interpreters/lua/Kconfig | 18 +++++++++--------- interpreters/lua/Makefile | 20 ++++++++++---------- interpreters/lua/nuttx_linit.c | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/interpreters/lua/CMakeLists.txt b/interpreters/lua/CMakeLists.txt index 8083a605d..863c63514 100644 --- a/interpreters/lua/CMakeLists.txt +++ b/interpreters/lua/CMakeLists.txt @@ -32,7 +32,7 @@ if(CONFIG_INTERPRETERS_LUA) set(LUA_URL https://github.com/lua/lua/archive/refs/tags/) FetchContent_Declare( lua_fetch - URL ${LUA_URL}/v${CONFIG_INTERPRETER_LUA_VERSION}.tar.gz SOURCE_DIR + URL ${LUA_URL}/v${CONFIG_INTERPRETERS_LUA_VERSION}.tar.gz SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/lua BINARY_DIR ${CMAKE_BINARY_DIR}/apps/interpreters/lua/lua DOWNLOAD_NO_PROGRESS true @@ -49,17 +49,17 @@ if(CONFIG_INTERPRETERS_LUA) # Flags # ############################################################################ - set(CFLAGS -DLUA_MAXINPUT=${CONFIG_INTERPRETER_LUA_IOBUFSIZE} + set(CFLAGS -DLUA_MAXINPUT=${CONFIG_INTERPRETERS_LUA_IOBUFSIZE} -DLUA_PROGNAME=\"lua\") - if(CONFIG_INTERPRETER_LUA_32BITS) + if(CONFIG_INTERPRETERS_LUA_32BITS) list(APPEND CFLAGS -DLUA_32BITS) endif() - if(NOT "${CONFIG_INTERPRETER_LUA_PATH}" STREQUAL "") - list(APPEND CFLAGS -DLUA_PATH_DEFAULT=\"${CONFIG_INTERPRETER_LUA_PATH}\") + if(NOT "${CONFIG_INTERPRETERS_LUA_PATH}" STREQUAL "") + list(APPEND CFLAGS -DLUA_PATH_DEFAULT=\"${CONFIG_INTERPRETERS_LUA_PATH}\") endif() - if(NOT "${CONFIG_INTERPRETER_LUA_CPATH}" STREQUAL "") - list(APPEND CFLAGS -DLUA_CPATH_DEFAULT=\"${CONFIG_INTERPRETER_LUA_CPATH}\") + if(NOT "${CONFIG_INTERPRETERS_LUA_CPATH}" STREQUAL "") + list(APPEND CFLAGS -DLUA_CPATH_DEFAULT=\"${CONFIG_INTERPRETERS_LUA_CPATH}\") endif() if(CONFIG_SYSTEM_READLINE) @@ -96,7 +96,7 @@ if(CONFIG_INTERPRETERS_LUA) ${CORELIBS_SRCS}) list(APPEND CSRCS nuttx_linit.c) - if(CONFIG_INTERPRETER_LUA_CORELIBS) + if(CONFIG_INTERPRETERS_LUA_CORELIBS) list(APPEND CSRCS ${CORELIBS_SRCS}) set(LUA_LIB_H_PATH ${LUA_DIR}/lualib.h) @@ -135,9 +135,9 @@ if(CONFIG_INTERPRETERS_LUA) NAME lua STACKSIZE - ${CONFIG_INTERPRETER_LUA_STACKSIZE} + ${CONFIG_INTERPRETERS_LUA_STACKSIZE} PRIORITY - ${CONFIG_INTERPRETER_LUA_PRIORITY} + ${CONFIG_INTERPRETERS_LUA_PRIORITY} SRCS ${LUA_DIR}/lua.c ${CSRCS} diff --git a/interpreters/lua/Kconfig b/interpreters/lua/Kconfig index 8afeb0549..418cf8472 100644 --- a/interpreters/lua/Kconfig +++ b/interpreters/lua/Kconfig @@ -10,55 +10,55 @@ menuconfig INTERPRETERS_LUA select LIBC_LOCALE ---help--- Embed Lua language interpreter. - Select the Lua version with the INTERPRETER_LUA_VERSION config. + Select the Lua version with the INTERPRETERS_LUA_VERSION config. A math library is required. Use the LIBM config or a toolchain library. It's suggested to enable the SYSTEM_READLINE and LIBC_FLOATINGPOINT configs. if INTERPRETERS_LUA -config INTERPRETER_LUA_VERSION +config INTERPRETERS_LUA_VERSION string "Lua interpreter version" default "5.4.0" ---help--- Lua release version to fetch and build. Versions 5.2.0 and up are supported. -config INTERPRETER_LUA_CORELIBS +config INTERPRETERS_LUA_CORELIBS bool "Load core Lua modules" default y select SYSTEM_SYSTEM ---help--- Load core Lua modules like "os", "string", and "table". -config INTERPRETER_LUA_PATH +config INTERPRETERS_LUA_PATH string "Lua modules search path" ---help--- Override default package.path search path for Lua modules. -config INTERPRETER_LUA_CPATH +config INTERPRETERS_LUA_CPATH string "Lua C modules search path" ---help--- Override default package.cpath search path for C modules. -config INTERPRETER_LUA_32BIT +config INTERPRETERS_LUA_32BIT bool "Use 32-bit integers and floats" default y ---help--- "Use int and float instead of long and double for Lua numbers." -config INTERPRETER_LUA_PRIORITY +config INTERPRETERS_LUA_PRIORITY int "Lua interpreter priority" default 100 ---help--- Task priority of the Lua interpreter main task. -config INTERPRETER_LUA_STACKSIZE +config INTERPRETERS_LUA_STACKSIZE int "Lua interpreter stack size" default 32768 ---help--- Size of the stack allocated for the Lua interpreter main task. -config INTERPRETER_LUA_IOBUFSIZE +config INTERPRETERS_LUA_IOBUFSIZE int "I/O buffer size" default 1024 ---help--- diff --git a/interpreters/lua/Makefile b/interpreters/lua/Makefile index 86e446667..40daf76ed 100644 --- a/interpreters/lua/Makefile +++ b/interpreters/lua/Makefile @@ -25,13 +25,13 @@ include $(APPDIR)/Make.defs # Lua built-in application info PROGNAME = lua -PRIORITY = $(CONFIG_INTERPRETER_LUA_PRIORITY) -STACKSIZE = $(CONFIG_INTERPRETER_LUA_STACKSIZE) +PRIORITY = $(CONFIG_INTERPRETERS_LUA_PRIORITY) +STACKSIZE = $(CONFIG_INTERPRETERS_LUA_STACKSIZE) MODULE = $(CONFIG_INTERPRETERS_LUA) # Lua library -LUA_VERSION = $(patsubst "%",%,$(strip $(CONFIG_INTERPRETER_LUA_VERSION))) +LUA_VERSION = $(patsubst "%",%,$(strip $(CONFIG_INTERPRETERS_LUA_VERSION))) LUA_TARBALL = v$(LUA_VERSION).tar.gz LUA_UNPACK = lua LUA_URL_BASE = https://github.com/lua/lua/archive/refs/tags/ @@ -44,19 +44,19 @@ EXCLUDE_SRCS = $(MAINSRC) $(CORELIBS_SRCS) $(LUA_SRC)$(DELIM)onelua.c $(LUA_SRC CSRCS = $(filter-out $(EXCLUDE_SRCS),$(wildcard $(LUA_SRC)$(DELIM)*.c)) CSRCS += nuttx_linit.c -CFLAGS += -DLUA_MAXINPUT=$(CONFIG_INTERPRETER_LUA_IOBUFSIZE) +CFLAGS += -DLUA_MAXINPUT=$(CONFIG_INTERPRETERS_LUA_IOBUFSIZE) CFLAGS += -DLUA_PROGNAME=\"$(PROGNAME)\" -ifeq ($(CONFIG_INTERPRETER_LUA_32BITS),y) +ifeq ($(CONFIG_INTERPRETERS_LUA_32BITS),y) CFLAGS += -DLUA_32BITS endif -ifneq ($(CONFIG_INTERPRETER_LUA_PATH),"") -CFLAGS += -DLUA_PATH_DEFAULT=\"$(CONFIG_INTERPRETER_LUA_PATH)\" +ifneq ($(CONFIG_INTERPRETERS_LUA_PATH),"") +CFLAGS += -DLUA_PATH_DEFAULT=\"$(CONFIG_INTERPRETERS_LUA_PATH)\" endif -ifneq ($(CONFIG_INTERPRETER_LUA_CPATH),"") -CFLAGS += -DLUA_CPATH_DEFAULT=\"$(CONFIG_INTERPRETER_LUA_CPATH)\" +ifneq ($(CONFIG_INTERPRETERS_LUA_CPATH),"") +CFLAGS += -DLUA_CPATH_DEFAULT=\"$(CONFIG_INTERPRETERS_LUA_CPATH)\" endif ifeq ($(CONFIG_SYSTEM_READLINE),y) @@ -83,7 +83,7 @@ endif # Register core modules -ifeq ($(CONFIG_INTERPRETER_LUA_CORELIBS),y) +ifeq ($(CONFIG_INTERPRETERS_LUA_CORELIBS),y) CSRCS += $(CORELIBS_SRCS) register:: diff --git a/interpreters/lua/nuttx_linit.c b/interpreters/lua/nuttx_linit.c index 3e47a9c99..904eb9f81 100644 --- a/interpreters/lua/nuttx_linit.c +++ b/interpreters/lua/nuttx_linit.c @@ -48,7 +48,7 @@ static const luaL_Reg g_loadedlibs[] = { -#ifdef CONFIG_INTERPRETER_LUA_CORELIBS +#ifdef CONFIG_INTERPRETERS_LUA_CORELIBS {LUA_GNAME, luaopen_base}, #endif #include "luamod_list.h" From a604c46b00b9f379c7d2b7c968297b3d76adc03f Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Sun, 15 Feb 2026 16:24:44 -0500 Subject: [PATCH 234/568] !interpreters/minibasic: Align naming of configuration options Aligns `CONFIG_INTERPRETER_*` options to `CONFIG_INTERPRETERS_*` options to be consistent with other interpreters. BREAKING CHANGE: All configurations using `CONFIG_INTERPRETER_MINIBASIC_*` options will no longer compile due to missing symbol errors. The fix is very quick: any configurations using this options should add a trailing S following INTERPRETER in the affected Kconfig variables. I believe `./tools/refresh.sh` should also be capable of doing this automatically. Signed-off-by: Matteo Golin --- interpreters/minibasic/CMakeLists.txt | 4 ++-- interpreters/minibasic/Kconfig | 8 ++++---- interpreters/minibasic/Makefile | 4 ++-- interpreters/minibasic/basic.c | 6 +++--- interpreters/minibasic/script.c | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/interpreters/minibasic/CMakeLists.txt b/interpreters/minibasic/CMakeLists.txt index 7c1e1401d..c13cef5b1 100644 --- a/interpreters/minibasic/CMakeLists.txt +++ b/interpreters/minibasic/CMakeLists.txt @@ -28,7 +28,7 @@ if(CONFIG_INTERPRETERS_MINIBASIC) script.c basic.c STACKSIZE - ${CONFIG_INTERPRETER_MINIBASIC_STACKSIZE} + ${CONFIG_INTERPRETERS_MINIBASIC_STACKSIZE} PRIORITY - ${CONFIG_INTERPRETER_MINIBASIC_PRIORITY}) + ${CONFIG_INTERPRETERS_MINIBASIC_PRIORITY}) endif() diff --git a/interpreters/minibasic/Kconfig b/interpreters/minibasic/Kconfig index bab275fc0..0d54790b5 100644 --- a/interpreters/minibasic/Kconfig +++ b/interpreters/minibasic/Kconfig @@ -33,25 +33,25 @@ config INTERPRETERS_MINIBASIC if INTERPRETERS_MINIBASIC -config INTERPRETER_MINIBASIC_PRIORITY +config INTERPRETERS_MINIBASIC_PRIORITY int "Basic interpreter priority" default 100 ---help--- Task priority of the Basic interpreter main task -config INTERPRETER_MINIBASIC_STACKSIZE +config INTERPRETERS_MINIBASIC_STACKSIZE int "Basic interpreter stack size" default 4096 ---help--- Size of the stack allocated for the Basic interpreter main task -config INTERPRETER_MINIBASIC_IOBUFSIZE +config INTERPRETERS_MINIBASIC_IOBUFSIZE int "I/O buffer size" default 1024 ---help--- Size of the statically allocated I/O buffer. -config INTERPRETER_MINIBASIC_TESTSCRIPT +config INTERPRETERS_MINIBASIC_TESTSCRIPT bool "Test script" default n ---help--- diff --git a/interpreters/minibasic/Makefile b/interpreters/minibasic/Makefile index 40f597750..61a439873 100644 --- a/interpreters/minibasic/Makefile +++ b/interpreters/minibasic/Makefile @@ -31,8 +31,8 @@ MAINSRC = script.c # Mini Basic built-in application info PROGNAME = basic -PRIORITY = $(CONFIG_INTERPRETER_MINIBASIC_PRIORITY) -STACKSIZE = $(CONFIG_INTERPRETER_MINIBASIC_STACKSIZE) +PRIORITY = $(CONFIG_INTERPRETERS_MINIBASIC_PRIORITY) +STACKSIZE = $(CONFIG_INTERPRETERS_MINIBASIC_STACKSIZE) MODULE = $(CONFIG_INTERPRETERS_MINIBASIC) include $(APPDIR)/Application.mk diff --git a/interpreters/minibasic/basic.c b/interpreters/minibasic/basic.c index 791463a30..054ff11f7 100644 --- a/interpreters/minibasic/basic.c +++ b/interpreters/minibasic/basic.c @@ -48,11 +48,11 @@ /* Configuration */ -#ifndef CONFIG_INTERPRETER_MINIBASIC_IOBUFSIZE -# define CONFIG_INTERPRETER_MINIBASIC_IOBUFSIZE 1024 +#ifndef CONFIG_INTERPRETERS_MINIBASIC_IOBUFSIZE +# define CONFIG_INTERPRETERS_MINIBASIC_IOBUFSIZE 1024 #endif -#define IOBUFSIZE CONFIG_INTERPRETER_MINIBASIC_IOBUFSIZE +#define IOBUFSIZE CONFIG_INTERPRETERS_MINIBASIC_IOBUFSIZE /* Tokens defined */ diff --git a/interpreters/minibasic/script.c b/interpreters/minibasic/script.c index af3b668f9..c4070889b 100644 --- a/interpreters/minibasic/script.c +++ b/interpreters/minibasic/script.c @@ -45,7 +45,7 @@ * Private Data ****************************************************************************/ -#ifdef CONFIG_INTERPRETER_MINIBASIC_TESTSCRIPT +#ifdef CONFIG_INTERPRETERS_MINIBASIC_TESTSCRIPT /* Here is a simple script to play with */ static FAR char *script = @@ -147,7 +147,7 @@ int main(int argc, FAR char *argv[]) if (argc == 1) { -#ifdef CONFIG_INTERPRETER_MINIBASIC_TESTSCRIPT +#ifdef CONFIG_INTERPRETERS_MINIBASIC_TESTSCRIPT basic(script, stdin, stdout, stderr); #else fprintf(stderr, "ERROR: Missing argument.\n"); From 3ce356378daead4a405d04b4efeb10c99a2d2786 Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Sun, 15 Feb 2026 16:25:09 -0500 Subject: [PATCH 235/568] !interpreters/python: Align naming of configuration options Aligns `CONFIG_INTERPRETER_*` options to `CONFIG_INTERPRETERS_*` options to be consistent with other interpreters. BREAKING CHANGE: All configurations using `CONFIG_INTERPRETER_PYTHON_*` options will no longer compile due to missing symbol errors. The fix is very quick: any configurations using this options should add a trailing S following INTERPRETER in the affected Kconfig variables. I believe `./tools/refresh.sh` should also be capable of doing this automatically. Signed-off-by: Matteo Golin --- interpreters/python/Kconfig | 12 ++++++------ interpreters/python/Make.defs | 4 ++-- interpreters/python/Makefile | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/interpreters/python/Kconfig b/interpreters/python/Kconfig index 947a71e6d..dfc3f5ee8 100644 --- a/interpreters/python/Kconfig +++ b/interpreters/python/Kconfig @@ -3,7 +3,7 @@ # see the file kconfig-language.txt in the NuttX tools repository. # -config INTERPRETER_CPYTHON +config INTERPRETERS_CPYTHON tristate "CPython" depends on LIB_ZLIB depends on EXPERIMENTAL @@ -13,25 +13,25 @@ config INTERPRETER_CPYTHON interpreter to NuttX. Initially, it is tweaked to work with the RISC-V QEMU virtual board (`rv-virt`). -if INTERPRETER_CPYTHON +if INTERPRETERS_CPYTHON -config INTERPRETER_CPYTHON_VERSION +config INTERPRETERS_CPYTHON_VERSION string "Python Version" default "3.13.0" -config INTERPRETER_CPYTHON_STACKSIZE +config INTERPRETERS_CPYTHON_STACKSIZE int "CPython stack size" default 307200 ---help--- This is the stack size allocated when the CPython task runs. -config INTERPRETER_CPYTHON_PRIORITY +config INTERPRETERS_CPYTHON_PRIORITY int "CPython task priority" default 100 ---help--- This is the priority of the CPython task. -config INTERPRETER_CPYTHON_PROGNAME +config INTERPRETERS_CPYTHON_PROGNAME string "CPython name" default "python" ---help--- diff --git a/interpreters/python/Make.defs b/interpreters/python/Make.defs index 39472e7a1..c02973e5a 100644 --- a/interpreters/python/Make.defs +++ b/interpreters/python/Make.defs @@ -20,9 +20,9 @@ # ############################################################################ -ifneq ($(CONFIG_INTERPRETER_CPYTHON),) +ifneq ($(CONFIG_INTERPRETERS_CPYTHON),) -CPYTHON_VERSION = $(patsubst "%",%,$(strip $(CONFIG_INTERPRETER_CPYTHON_VERSION))) +CPYTHON_VERSION = $(patsubst "%",%,$(strip $(CONFIG_INTERPRETERS_CPYTHON_VERSION))) CPYTHON_VERSION_MINOR=$(basename $(CPYTHON_VERSION)) EXTRA_LIBPATHS += -L$(APPDIR)/interpreters/python/install/target diff --git a/interpreters/python/Makefile b/interpreters/python/Makefile index bf20c9ae4..954f07b30 100644 --- a/interpreters/python/Makefile +++ b/interpreters/python/Makefile @@ -23,7 +23,7 @@ include $(APPDIR)/Make.defs CPYTHON_URL ?= "https://github.com/python/cpython/archive" -CPYTHON_VERSION = $(patsubst "%",%,$(strip $(CONFIG_INTERPRETER_CPYTHON_VERSION))) +CPYTHON_VERSION = $(patsubst "%",%,$(strip $(CONFIG_INTERPRETERS_CPYTHON_VERSION))) CPYTHON_VERSION_MINOR=$(basename $(CPYTHON_VERSION)) CPYTHON_ZIP = v$(CPYTHON_VERSION).zip @@ -171,11 +171,11 @@ $(TARGETLIBPYTHON): $(TARGETBUILD)/Makefile $(Q) ( cp $(TARGETBUILD)/libpython$(CPYTHON_VERSION_MINOR).a $(TARGETLIBPYTHON) ) $(Q) $(UNPACK) $(TARGETMODULESPACK) -d $(TARGETMODULES)/python$(CPYTHON_VERSION_MINOR) -MODULE = $(CONFIG_INTERPRETER_CPYTHON) +MODULE = $(CONFIG_INTERPRETERS_CPYTHON) -PROGNAME += $(CONFIG_INTERPRETER_CPYTHON_PROGNAME) -PRIORITY += $(CONFIG_INTERPRETER_CPYTHON_PRIORITY) -STACKSIZE += $(CONFIG_INTERPRETER_CPYTHON_STACKSIZE) +PROGNAME += $(CONFIG_INTERPRETERS_CPYTHON_PROGNAME) +PRIORITY += $(CONFIG_INTERPRETERS_CPYTHON_PRIORITY) +STACKSIZE += $(CONFIG_INTERPRETERS_CPYTHON_STACKSIZE) MAINSRC += python_wrapper.c From 448b0bd0a6847e8e0976b86462e4a79029a90799 Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Sun, 15 Feb 2026 16:50:09 -0500 Subject: [PATCH 236/568] interpreters: Fix spelling errors Fix some spelling errors for CI. Signed-off-by: Matteo Golin --- interpreters/bas/bas_main.c | 2 +- interpreters/minibasic/basic.c | 6 +++--- interpreters/minibasic/script.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interpreters/bas/bas_main.c b/interpreters/bas/bas_main.c index 833721dab..c6c9a70ec 100644 --- a/interpreters/bas/bas_main.c +++ b/interpreters/bas/bas_main.c @@ -129,7 +129,7 @@ int main(int argc, FAR char *argv[]) fputs(_("-u Output all tokens in uppercase\n"), stdout); fputs(_("-h Display this help and exit\n"), stdout); - fputs(_("-V Ooutput version information and exit\n"), + fputs(_("-V Output version information and exit\n"), stdout); exit(0); } diff --git a/interpreters/minibasic/basic.c b/interpreters/minibasic/basic.c index 054ff11f7..2547f963e 100644 --- a/interpreters/minibasic/basic.c +++ b/interpreters/minibasic/basic.c @@ -22,7 +22,7 @@ /**************************************************************************** * - * This file was taken from Mini Basic, versino 1.0 developed by Malcolm + * This file was taken from Mini Basic, version 1.0 developed by Malcolm * McLean, Leeds University. Mini Basic version 1.0 was released the * Creative Commons Attribution license which, from my reading, appears to * be compatible with the NuttX license: @@ -990,7 +990,7 @@ static int doif(void) * Name: dogoto * * Description: - * The GOTO satement + * The GOTO statement * Returns new line number * ****************************************************************************/ @@ -3804,7 +3804,7 @@ static int isstring(int tokenid) * Description: * Get a numerical value from the parse string * Params: str - the string to search - * len - return pinter for no chars read + * len - return pointer for no chars read * Returns: the value of the string. * ****************************************************************************/ diff --git a/interpreters/minibasic/script.c b/interpreters/minibasic/script.c index c4070889b..3e0212464 100644 --- a/interpreters/minibasic/script.c +++ b/interpreters/minibasic/script.c @@ -22,7 +22,7 @@ /**************************************************************************** * - * This file was taken from Mini Basic, versino 1.0 developed by Malcolm + * This file was taken from Mini Basic, version 1.0 developed by Malcolm * McLean, Leeds University. Mini Basic version 1.0 was released the * Creative Commons Attribution license which, from my reading, appears to * be compatible with the NuttX BSD-style license: From fe546acfc7c50bb2af89d8fc1c032952d3ab7616 Mon Sep 17 00:00:00 2001 From: Lup Yuen Lee Date: Mon, 23 Feb 2026 14:10:37 +0800 Subject: [PATCH 237/568] github/workflow: Sync the new PR Labeling Workflow from NuttX Repo to NuttX Apps This PR replicates the new PR Labeling Workflow from NuttX Repo to NuttX Apps Repo. For Future Syncing: - Copy from NuttX Repo to NuttX Apps: `.github/workflows/labeler.yml` and `.github/workflows/pr_labeler.yml` - Edit `.github/workflows/labeler.yml` and change `repository: apache/nuttx` to `repository: apache/nuttx-apps` - Don't overwrite `.github/labeler.yml` by NuttX Repo The new workflow reimplements PR Labeling with two triggers: pull_request and workflow_run. We no longer need pull_request_target, which is an unsafe trigger and may introduce security vulnerabilities. The New PR Labeler is explained here: - https://lupyuen.org/articles/prtarget - https://github.com/apache/nuttx/issues/18359 Modified Files: `.github/workflows/labeler.yml`: Changed the (read-write) pull_request_target trigger to (read-only) pull_request trigger. Compute the Size Label (e.g. Size: XS) and Arch Labels (e.g. Area: Examples). Save the PR Labels into a PR Artifact. `.github/labeler.yml`: Added comment to clarify that NuttX PR Labeler only supports a subset of the `actions/labeler` syntax: `changed-files` and `any-glob-to-any-file`. Note: Don't overwrite this file by NuttX Repo. New Files: `.github/workflows/pr_labeler.yml`: Contains the workflow_run trigger, which is executed upon completion of the pull_request trigger. Download the PR Labels from the PR Artifact. Write the PR Labels into the PR. Signed-off-by: Lup Yuen Lee --- .github/labeler.yml | 3 + .github/workflows/labeler.yml | 143 +++++++++++++++++++++++++++---- .github/workflows/pr_labeler.yml | 90 +++++++++++++++++++ 3 files changed, 217 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/pr_labeler.yml diff --git a/.github/labeler.yml b/.github/labeler.yml index 88336e8ae..278cc551a 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -17,6 +17,9 @@ # specific language governing permissions and limitations # under the License. # +# Note: NuttX PR Labeler only supports a subset of the +# `actions/labeler` syntax: `changed-files` and +# `any-glob-to-any-file`. See .github/workflows/labeler.yml # add arch labels diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 1c38d38da..bf1c459ec 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -12,34 +12,139 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# This workflow will fetch the updated PR filenames, compute the Size Label +# and Arch Labels, then save the PR Labels into a PR Artifact. The +# PR Labels will be written to the PR inside the "workflow_run" trigger +# (pr_labeler.yml), because this "pull_request" trigger has read-only +# permission. Don't use "pull_request_target", it's unsafe. +# See https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=321719166#GitHubActionsSecurity-Buildstriggeredwithpull_request_target name: "Pull Request Labeler" on: - - pull_request_target + - pull_request jobs: labeler: permissions: contents: read - pull-requests: write - issues: write + pull-requests: read + issues: read runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Assign labels based on paths - uses: actions/labeler@main + # Checkout one file from our trusted source: .github/labeler.yml + # Never checkout and execute any untrusted code from the PR. + - name: Checkout labeler config + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - sync-labels: true + repository: apache/nuttx-apps + ref: master + path: labeler + fetch-depth: 1 + persist-credentials: false + sparse-checkout: .github/labeler.yml + sparse-checkout-cone-mode: false - - name: Assign labels based on the PR's size - uses: codelytv/pr-size-labeler@v1.10.3 + # Fetch the updated PR filenames. Compute the Size Label and Arch Labels. + - name: Compute PR labels + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ignore_file_deletions: true - xs_label: 'Size: XS' - s_label: 'Size: S' - m_label: 'Size: M' - l_label: 'Size: L' - xl_label: 'Size: XL' + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const pull_number = context.issue.number; + + // Fetch the array of updated PR filenames: + // { status: 'added', filename: 'arch/arm/test.txt', additions: 3, deletions: 0, changes: 3 } + // { status: 'removed', filename: 'Documentation/legacy_README.md', additions: 0, deletions: 2531, changes: 2531 } + // { status: 'modified', filename: 'Documentation/security.rst', additions: 1, deletions: 0, changes: 1 } + const listFilesOptions = github.rest.pulls.listFiles + .endpoint.merge({ owner, repo, pull_number }); + const listFilesResponse = await github.paginate(listFilesOptions); + + // Sum up the number of lines changed + const sizeFiles = listFilesResponse + .filter(f => (f.status != 'removed')); // Ignore deleted files + var linesChanged = 0; + for (const file of sizeFiles) { + linesChanged += file.changes; + } + console.log({ linesChanged }); + + // Compute the Size Label + const sizeLabel = + (linesChanged <= 10) ? 'Size: XS' + : (linesChanged <= 100) ? 'Size: S' + : (linesChanged <= 500) ? 'Size: M' + : (linesChanged <= 1000) ? 'Size: L' + : 'Size: XL'; + var prLabels = [ sizeLabel ]; + + // Parse the Arch Label Patterns in .github/labeler.yml. Condense into: + // "Arch: arm": + // - any-glob-to-any-file: 'arch/arm/**' + // - any-glob-to-any-file: ... + const fs = require('fs'); + const config = fs.readFileSync('labeler/.github/labeler.yml', 'utf8') + .split('\n') // Split by newline + .map(s => s.trim()) // Remove leading and trailing spaces + .filter(s => (s != '')) // Remove empty lines + .filter(s => !s.startsWith('#')) // Remove comments + .filter(s => !s.startsWith('- changed-files:')); // Remove "changed-files" + + // Convert the Arch Label Patterns from config to archLabels. + // archLabels will contain the mappings for Arch Label and Filename Pattern: + // { label: "Arch: arm", pattern: "arch/arm/.*" }, + // { label: "Arch: arm64", pattern: "arch/arm64/.*" }, ... + var archLabels = []; + var label = ""; + for (const c of config) { + // Get the Arch Label + if (c.startsWith('"')) { // "Arch: arm": + label = c.split('"')[1]; // Arch: arm + + } else if (c.startsWith('- any-glob-to-any-file:')) { // - any-glob-to-any-file: 'arch/arm/**' + // Convert the Glob Pattern to Regex Pattern + const pattern = c.split("'")[1] // arch/arm/** + .split('.').join('\\.') // . becomes \. + .split('*').join('[^/]*') // * becomes [^/]* + .split('[^/]*[^/]*').join('.*'); // ** becomes .* + archLabels.push({ + label, // Arch: arm + pattern: '^' + pattern + '$' // Match the Line Start and Line End + }); + + } else { + // We don't support all rules of `actions/labeler` + throw new Error('.github/labeler.yml should contain only changed-files and any-glob-to-any-file, not: ' + c); + } + } + + // Search the filenames for matching Arch Labels + for (const archLabel of archLabels) { + if (prLabels.includes(archLabel.label)) { + break; + } + for (const file of listFilesResponse) { + const re = new RegExp(archLabel.pattern); + const match = re.test(file.filename); + if (match && !prLabels.includes(archLabel.label)) { + prLabels.push(archLabel.label); + break; + } + } + } + console.log({ prLabels }); + + // Save the PR Number and PR Labels into a PR Artifact + // e.g. 'Size: XS\nArch: avr\n' + const dir = 'pr'; + fs.mkdirSync(dir); + fs.writeFileSync(dir + '/pr-id.txt', pull_number + '\n'); + fs.writeFileSync(dir + '/pr-labels.txt', prLabels.join('\n') + '\n'); + + # Upload the PR Artifact as pr.zip + - name: Upload PR artifact + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: pr + path: pr/ diff --git a/.github/workflows/pr_labeler.yml b/.github/workflows/pr_labeler.yml new file mode 100644 index 000000000..f8af53e05 --- /dev/null +++ b/.github/workflows/pr_labeler.yml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This workflow will fetch the PR Labels from the PR Artifact, and write +# the PR Labels into the PR. The workflow is called after the +# "pull_request" trigger (labeler.yml). This "workflow_run" trigger uses a +# GitHub Token with Write Permission, so we must never run any untrusted +# code from the PR, and we must always extract and use the PR Artifact +# safely. See https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=321719166#GitHubActionsSecurity-Buildstriggeredwithworkflow_run +name: "Set Pull Request Labels" +on: + workflow_run: + workflows: ["Pull Request Labeler"] + types: + - completed + +jobs: + pr_labeler: + permissions: + contents: read + pull-requests: write + issues: write + runs-on: ubuntu-latest + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + steps: + # Download the PR Artifact, containing PR Number and PR Labels + - name: Download PR artifact + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + script: | + const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.event.workflow_run.id }}, + }); + const matchArtifact = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "pr" + })[0]; + const download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + const fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data)); + + # Unzip the PR Artifact + - name: Unzip PR artifact + run: unzip pr.zip + + # Write the PR Labels into the PR + - name: Write PR labels + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const fs = require('fs'); + + // Read the PR Number and PR Labels from the PR Artifact + // e.g. 'Size: XS\nArch: avr\n' + const issue_number = Number(fs.readFileSync('pr-id.txt')); + const labels = fs.readFileSync('pr-labels.txt', 'utf8') + .split('\n') // Split by newline + .filter(s => (s != '')); // Remove empty lines + console.log({ issue_number, labels }); + + // Write the PR Labels into the PR + // e.g. [ 'Size: XS', 'Arch: avr' ] + await github.rest.issues.setLabels({ + owner, + repo, + issue_number, + labels + }); From 0b084ded88b397e13f39c18dae97784af189833f Mon Sep 17 00:00:00 2001 From: Eren Terzioglu Date: Fri, 20 Feb 2026 17:22:59 +0100 Subject: [PATCH 238/568] testing/crypto: Add options to disable hash tests Add options to disable individual hash tests for devices not supported each hash Signed-off-by: Eren Terzioglu --- testing/drivers/crypto/Kconfig | 16 +++++++ testing/drivers/crypto/hash.c | 77 ++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/testing/drivers/crypto/Kconfig b/testing/drivers/crypto/Kconfig index 8eca7f728..40983778a 100644 --- a/testing/drivers/crypto/Kconfig +++ b/testing/drivers/crypto/Kconfig @@ -36,6 +36,22 @@ config TESTING_CRYPTO_HASH_HUGE_BLOCK bool "hash huge block crypto test" default y +config TESTING_CRYPTO_HASH_DISABLE_MD5 + bool "disable md5 tests" + default n + +config TESTING_CRYPTO_HASH_DISABLE_SHA1 + bool "disable sha1 tests" + default n + +config TESTING_CRYPTO_HASH_DISABLE_SHA256 + bool "disable sha256 tests" + default n + +config TESTING_CRYPTO_HASH_DISABLE_SHA512 + bool "disable sha512 tests" + default n + endif config TESTING_CRYPTO_CRC32 diff --git a/testing/drivers/crypto/hash.c b/testing/drivers/crypto/hash.c index a4688124e..b0be9306c 100644 --- a/testing/drivers/crypto/hash.c +++ b/testing/drivers/crypto/hash.c @@ -29,9 +29,16 @@ #include #include #include -#include -#include -#include +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5 +# include +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA1 +# include +#endif +#if !defined(CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA256) || \ + !defined(CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA512) +# include +#endif #ifdef CONFIG_TESTING_CRYPTO_HASH_HUGE_BLOCK # define HASH_HUGE_BLOCK_SIZE (600 * 1024) /* 600k */ @@ -53,6 +60,7 @@ typedef struct tb } tb; +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5 tb md5_testcase[] = { { @@ -85,7 +93,10 @@ tb md5_testcase[] = 80, } }; +#endif +#if !defined(CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA1) || \ + !defined(CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA256) tb sha_testcase[] = { { @@ -101,7 +112,9 @@ tb sha_testcase[] = 1000, } }; +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA512 tb sha512_testcase[] = { { @@ -118,7 +131,9 @@ tb sha512_testcase[] = 1000, } }; +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5 /* RFC 1321 test vectors */ static const unsigned char md5_result[7][16] = @@ -138,7 +153,9 @@ static const unsigned char md5_result[7][16] = { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }; +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA1 /* FIPS-180-1 test vectors */ static const unsigned char sha1_result[3][20] = @@ -150,7 +167,9 @@ static const unsigned char sha1_result[3][20] = { 0x34, 0xaa, 0x97, 0x3c, 0xd4, 0xc4, 0xda, 0xa4, 0xf6, 0x1e, 0xeb, 0x2b, 0xdb, 0xad, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6f } }; +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA256 /* FIPS-180-2 test vectors */ static const unsigned char sha256_result[3][32] = @@ -168,7 +187,9 @@ static const unsigned char sha256_result[3][32] = 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 } }; +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA512 /* FIPS-180-2 test vectors */ static const unsigned char sha512_result[3][64] = @@ -198,20 +219,26 @@ static const unsigned char sha512_result[3][64] = 0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e, 0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b } }; +#endif #ifdef CONFIG_TESTING_CRYPTO_HASH_HUGE_BLOCK +# ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5 static const unsigned char md5_huge_block_result[16] = { 0xef, 0x6d, 0xcc, 0xc8, 0xe1, 0xcc, 0x7f, 0x08, 0xc2, 0x71, 0xd4, 0xc4, 0xe0, 0x13, 0xa3, 0x9b }; +# endif +# ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA1 static const unsigned char sha1_huge_block_result[20] = { 0xf2, 0x35, 0x65, 0x81, 0x79, 0x4d, 0xac, 0x20, 0x79, 0x7b, 0xff, 0x38, 0xee, 0x2b, 0xdc, 0x44, 0x24, 0xd3, 0xf0, 0x4a }; +# endif +# ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA256 static const unsigned char sha256_huge_block_result[32] = { 0x79, 0xb1, 0xf2, 0x65, 0x7e, 0x33, 0x25, 0xff, @@ -219,7 +246,9 @@ static const unsigned char sha256_huge_block_result[32] = 0x0d, 0xd5, 0xa1, 0x45, 0xb5, 0x30, 0xe0, 0x91, 0x54, 0x01, 0x40, 0x0c, 0xff, 0x35, 0x1d, 0xd3 }; +# endif +# ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA512 static const unsigned char sha512_huge_block_result[64] = { 0xa4, 0x3a, 0x66, 0xe8, 0xf7, 0x59, 0x95, 0x6d, @@ -231,6 +260,7 @@ static const unsigned char sha512_huge_block_result[64] = 0xce, 0x3a, 0xcf, 0xb6, 0x9c, 0x8b, 0x6e, 0x07, 0x13, 0xca, 0xe1, 0x94, 0x3c, 0x41, 0x50, 0xcc }; +# endif #endif static void syshash_free(FAR crypto_context *ctx) @@ -381,25 +411,42 @@ static int testing_hash_huge_block(crypto_context *ctx, int op, int main(void) { +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5 crypto_context md5_ctx; +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA1 crypto_context sha1_ctx; +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA256 crypto_context sha2_256_ctx; +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA512 crypto_context sha2_512_ctx; +#endif unsigned char output[64]; unsigned char buf[1024]; int ret = 0; int i; int j; +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5 ret += syshash_init(&md5_ctx); +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA1 ret += syshash_init(&sha1_ctx); +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA256 ret += syshash_init(&sha2_256_ctx); +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA512 ret += syshash_init(&sha2_512_ctx); +#endif if (ret != 0) { printf("syshash init failed\n"); } +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5 for (i = 0; i < nitems(md5_testcase); i++) { ret = syshash_start(&md5_ctx, CRYPTO_MD5); @@ -435,7 +482,9 @@ int main(void) printf("hash md5 success\n"); } } +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA1 for (i = 0; i < nitems(sha_testcase); i++) { ret = syshash_start(&sha1_ctx, CRYPTO_SHA1); @@ -490,7 +539,9 @@ int main(void) printf("hash sha1 success\n"); } } +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA256 for (i = 0; i < nitems(sha_testcase); i++) { ret = syshash_start(&sha2_256_ctx, CRYPTO_SHA2_256); @@ -543,7 +594,9 @@ int main(void) printf("hash sha256 success\n"); } } +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA512 for (i = 0; i < nitems(sha512_testcase); i++) { ret = syshash_start(&sha2_512_ctx, CRYPTO_SHA2_512); @@ -598,6 +651,7 @@ int main(void) printf("hash sha512 success\n"); } } +#endif #ifdef CONFIG_TESTING_CRYPTO_HASH_HUGE_BLOCK unsigned char *huge_block; @@ -609,6 +663,7 @@ int main(void) } memset(huge_block, 'a', HASH_HUGE_BLOCK_SIZE); +# ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5 ret = testing_hash_huge_block(&md5_ctx, CRYPTO_MD5, huge_block, HASH_HUGE_BLOCK_SIZE, md5_huge_block_result, @@ -622,6 +677,9 @@ int main(void) printf("md5 huge block test success\n"); } +# endif + +# ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA1 ret = testing_hash_huge_block(&sha1_ctx, CRYPTO_SHA1, huge_block, HASH_HUGE_BLOCK_SIZE, sha1_huge_block_result, @@ -635,6 +693,8 @@ int main(void) printf("sha1 huge block test success\n"); } +#endif +# ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA256 ret = testing_hash_huge_block(&sha2_256_ctx, CRYPTO_SHA2_256, huge_block, HASH_HUGE_BLOCK_SIZE, sha256_huge_block_result, @@ -647,7 +707,9 @@ int main(void) { printf("sha256 huge block test success\n"); } +#endif +# ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA512 ret = testing_hash_huge_block(&sha2_512_ctx, CRYPTO_SHA2_512, huge_block, HASH_HUGE_BLOCK_SIZE, sha512_huge_block_result, @@ -660,14 +722,23 @@ int main(void) { printf("sha512 huge block test success\n"); } +# endif free(huge_block); #endif err: +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5 syshash_free(&md5_ctx); +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA1 syshash_free(&sha1_ctx); +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA256 syshash_free(&sha2_256_ctx); +#endif +#ifndef CONFIG_TESTING_CRYPTO_HASH_DISABLE_SHA512 syshash_free(&sha2_512_ctx); +#endif return 0; } From e0d118e3491ac294e8e936f17d701d6abd95bf0f Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Tue, 24 Feb 2026 14:54:05 -0500 Subject: [PATCH 239/568] examples/powerled: Fix board initialization compilation When NSH_ARCHINIT is not enabled, initialization is to be performed by boardctl(BOARDIOC_INIT). However, the boardctl header is not included so this causes compilation to fail. This commit corrects that issue. Signed-off-by: Matteo Golin --- examples/powerled/powerled_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/powerled/powerled_main.c b/examples/powerled/powerled_main.c index c0b3cd29d..4478d2ee7 100644 --- a/examples/powerled/powerled_main.c +++ b/examples/powerled/powerled_main.c @@ -38,6 +38,10 @@ #include #include +#ifndef CONFIG_NSH_ARCHINIT +#include +#endif + #include #include From da105afee2186f6b971df38802823ab6748e8621 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 29 Jan 2026 15:48:01 +0800 Subject: [PATCH 240/568] ostest/hrtimer: Add missing assert.h This commit added missing assert.h. Signed-off-by: ouyangxiangzhen --- testing/ostest/hrtimer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index 48ed46b99..4cd9eb157 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include From 05e8b0ae609a1e37881c5f607f729611250e52cf Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 29 Jan 2026 15:51:19 +0800 Subject: [PATCH 241/568] ostest/hrtimer: Remove HRTIMER_TEST to simplify the code. This commit removed HRTIMER_TEST to simplify the code. Signed-off-by: ouyangxiangzhen --- testing/ostest/hrtimer.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index 4cd9eb157..5b2961179 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -59,20 +59,6 @@ #define HRTIMER_TEST_MARGIN (NSEC_PER_MSEC) -/* Simple assertion macro for HRTimer test cases */ -#define HRTIMER_TEST(expr, value) \ - do \ - { \ - ret = (expr); \ - if (ret != (value)) \ - { \ - printf("ERROR: HRTimer test failed, line=%d ret=%d\n", \ - __LINE__, ret); \ - ASSERT(false); \ - } \ - } \ - while (0) - /**************************************************************************** * Private Types ****************************************************************************/ @@ -167,8 +153,8 @@ test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) diff = (uint32_t)(now - test->previous); - HRTIMER_TEST(NSEC_PER_50MS < diff + HRTIMER_TEST_MARGIN, true); - HRTIMER_TEST(NSEC_PER_50MS > diff - HRTIMER_TEST_MARGIN, true); + ASSERT(NSEC_PER_50MS < diff + HRTIMER_TEST_MARGIN); + ASSERT(NSEC_PER_50MS > diff - HRTIMER_TEST_MARGIN); } test->previous = now; @@ -224,25 +210,24 @@ static void * hrtimer_test_thread(void *arg) /* Cancel timer */ ret = hrtimer_cancel(&timer); - HRTIMER_TEST(ret >= 0, true); + ASSERT(ret == OK); /* Start timer with fixed period */ ret = hrtimer_start(&timer, hrtimer_test_callback, 10 * NSEC_PER_USEC, HRTIMER_MODE_REL); - HRTIMER_TEST(ret, OK); + ASSERT(ret == OK); /* Start timer with random delay */ ret = hrtimer_start(&timer, hrtimer_test_callback, delay, HRTIMER_MODE_REL); - HRTIMER_TEST(ret, OK); + ASSERT(ret == OK); } /* Cancel the timer synchronously */ - ret = hrtimer_cancel_sync(&timer); - HRTIMER_TEST(ret >= 0, true); + ASSERT(hrtimer_cancel_sync(&timer) == OK); return NULL; } @@ -293,7 +278,8 @@ void hrtimer_test(void) hrtimer_test.period, HRTIMER_MODE_REL); - HRTIMER_TEST(ret, OK); + ASSERT(ret == OK); + /* Wait until the test completes */ @@ -309,8 +295,8 @@ void hrtimer_test(void) for (thread_id = 0; thread_id < HRTIMER_TEST_THREAD_NR; thread_id++) { - HRTIMER_TEST(pthread_create(&pthreads[thread_id], &attr, - hrtimer_test_thread, NULL), 0); + ASSERT(pthread_create(&pthreads[thread_id], &attr, + hrtimer_test_thread, NULL) == 0); } /* Wait for all threads to complete */ @@ -320,5 +306,5 @@ void hrtimer_test(void) pthread_join(pthreads[thread_id], NULL); } - HRTIMER_TEST(pthread_attr_destroy(&attr), 0); + ASSERT(pthread_attr_destroy(&attr) == 0); } From 9b84a0ab02fe5b3cdab7a1949958de40a9c73993 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 29 Jan 2026 16:02:10 +0800 Subject: [PATCH 242/568] sched/hrtimer: Simplify the hrtimer test. This commit simplified the hrtimer test. Signed-off-by: ouyangxiangzhen --- testing/ostest/hrtimer.c | 94 +++++++++++++--------------------------- 1 file changed, 29 insertions(+), 65 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index 5b2961179..585c6f30a 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -65,43 +65,18 @@ /* Structure for HRTimer test tracking */ -struct hrtimer_test_s +typedef struct hrtimer_test_s { - hrtimer_t timer; /* HRTimer instance */ - uint64_t previous; /* Previous timestamp in nanoseconds */ - uint32_t count; /* Number of timer expirations */ - uint32_t period; /* Expected period between expirations */ - bool active; /* True while the test is still running */ -}; + struct hrtimer_s timer; /* HRTimer instance */ + volatile uint64_t timestamp; /* Previous timestamp in nanoseconds */ + volatile uint64_t count; /* Number of timer expirations */ + uint64_t period; /* Expected period between expirations */ +} hrtimer_test_t; /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: hrtimer_test_init - * - * Description: - * Initialize a hrtimer_test_s structure for a new test. - * - * Input Parameters: - * hrtimer_test - Pointer to the test structure to initialize - * period - Expected timer period in nanoseconds - * - * Returned Value: - * None - * - ****************************************************************************/ - -static void hrtimer_test_init(FAR struct hrtimer_test_s *hrtimer_test, - uint32_t period) -{ - hrtimer_test->previous = 0; - hrtimer_test->count = 0; - hrtimer_test->active = true; - hrtimer_test->period = period; -} - /**************************************************************************** * Name: test_hrtimer_callback * @@ -129,8 +104,6 @@ test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) uint64_t now; int ret; - UNUSED(expired); - FAR struct hrtimer_test_s *test = (FAR struct hrtimer_test_s *)hrtimer; @@ -151,13 +124,13 @@ test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) * 500ms with nsec resolution */ - diff = (uint32_t)(now - test->previous); + diff = (uint32_t)(now - expired); ASSERT(NSEC_PER_50MS < diff + HRTIMER_TEST_MARGIN); ASSERT(NSEC_PER_50MS > diff - HRTIMER_TEST_MARGIN); } - test->previous = now; + test->timestamp = now; /* Stop the test after PERIOD_TEST_COUNT expirations */ @@ -196,11 +169,28 @@ hrtimer_test_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) static void * hrtimer_test_thread(void *arg) { - hrtimer_t timer; - int ret; - int i = 0; + hrtimer_test_t test; + int ret; + uint64_t stamp; + int i = 0; + hrtimer_t *timer = &test.timer; - hrtimer_init(&timer); + /* Initialize the high-resolution timer */ + + hrtimer_init(timer); + + /* Start the timer with 500ms relative timeout */ + + stamp = test.timestamp; + ASSERT(hrtimer_start(timer, test_hrtimer_callback, + NSEC_PER_50MS, HRTIMER_MODE_REL) == OK); + + /* Wait until the test completes */ + + while (test.timestamp != stamp) + { + usleep(USEC_PER_MSEC); + } while (i < THREAD_LOOP_COUNT) { @@ -260,34 +250,8 @@ void hrtimer_test(void) unsigned int thread_id; pthread_attr_t attr; pthread_t pthreads[HRTIMER_TEST_THREAD_NR]; - struct hrtimer_test_s hrtimer_test; int ret; - /* Initialize test structure */ - - hrtimer_test_init(&hrtimer_test, NSEC_PER_50MS); - - /* Initialize the high-resolution timer */ - - hrtimer_init(&hrtimer_test.timer); - - /* Start the timer with 500ms relative timeout */ - - ret = hrtimer_start(&hrtimer_test.timer, - test_hrtimer_callback, - hrtimer_test.period, - HRTIMER_MODE_REL); - - ASSERT(ret == OK); - - - /* Wait until the test completes */ - - while (hrtimer_test.active) - { - usleep(USEC_PER_MSEC); - } - pthread_attr_init(&attr); sparam.sched_priority = PTHREAD_DEFAULT_PRIORITY; From e69f9e902b354a94a37672296af41bcb4a0e5ef4 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 29 Jan 2026 16:08:24 +0800 Subject: [PATCH 243/568] sched/hrtimer: Fix test in QEMU. This commit fixed the hrtimer test. In a QEMU environment, the hrtimer latency can be arbitrary because vCPUs can be preempted. We can not assert the latency. we can only issue alerts for excessively high latency. Signed-off-by: ouyangxiangzhen --- testing/ostest/hrtimer.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index 585c6f30a..d82cf171a 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -100,9 +100,9 @@ static uint64_t test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) { struct timespec ts; - uint32_t diff; + int64_t diff; uint64_t now; - int ret; + int ret; FAR struct hrtimer_test_s *test = (FAR struct hrtimer_test_s *)hrtimer; @@ -116,18 +116,20 @@ test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) clock_systime_timespec(&ts); now = clock_time2nsec(&ts); - /* Skip comparison for first two invocations */ + /* Verify the timer interval is exactly + * 500ms with nsec resolution + */ - if (test->count > 2) + diff = now - expired; + + /* Ensure the time diff is valid. */ + + ASSERT(diff >= 0); + + if (diff > HRTIMER_TEST_MARGIN) { - /* Verify the timer interval is exactly - * 500ms with nsec resolution - */ - - diff = (uint32_t)(now - expired); - - ASSERT(NSEC_PER_50MS < diff + HRTIMER_TEST_MARGIN); - ASSERT(NSEC_PER_50MS > diff - HRTIMER_TEST_MARGIN); + printf("hrtimer_test: warning diff=%" PRIu64 " > %" PRIu64 "\n", + diff, HRTIMER_TEST_MARGIN); } test->timestamp = now; From 1c0281be1520ff33e90264866798964914f0f35f Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 29 Jan 2026 16:13:52 +0800 Subject: [PATCH 244/568] sched/hrtimer: relocate the hrtimer test to simplify. This commit relocated the hrtimer test to simplify the code. Signed-off-by: ouyangxiangzhen --- testing/ostest/CMakeLists.txt | 7 +++---- testing/ostest/Makefile | 10 ++++------ testing/ostest/ostest.h | 10 ++++++---- testing/ostest/ostest_main.c | 16 ++++++++-------- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/testing/ostest/CMakeLists.txt b/testing/ostest/CMakeLists.txt index 6096c7ce6..fba7f4c47 100644 --- a/testing/ostest/CMakeLists.txt +++ b/testing/ostest/CMakeLists.txt @@ -157,16 +157,15 @@ if(CONFIG_TESTING_OSTEST) list(APPEND SRCS nxevent.c) endif() - if(CONFIG_HRTIMER AND CONFIG_BUILD_FLAT) - list(APPEND SRCS hrtimer.c) - endif() - if(CONFIG_ARCH_HAVE_PERF_EVENTS) list(APPEND SRCS perf_gettime.c) endif() if(CONFIG_BUILD_FLAT) list(APPEND SRCS wdog.c spinlock.c) + if(CONFIG_HRTIMER) + list(APPEND SRCS hrtimer.c) + endif() endif() set(OSTEST_SRCS ostest_main.c ${SRCS}) diff --git a/testing/ostest/Makefile b/testing/ostest/Makefile index 1f6a28b2f..6fc3a7b76 100644 --- a/testing/ostest/Makefile +++ b/testing/ostest/Makefile @@ -160,18 +160,16 @@ CSRCS += nxevent.c endif endif -ifeq ($(CONFIG_HRTIMER),y) -ifeq ($(CONFIG_BUILD_FLAT),y) -CSRCS += hrtimer.c -endif -endif - ifeq ($(CONFIG_ARCH_HAVE_PERF_EVENTS),y) CSRCS += perf_gettime.c endif ifeq ($(CONFIG_BUILD_FLAT),y) CSRCS += wdog.c spinlock.c + +ifeq ($(CONFIG_HRTIMER),y) +CSRCS += hrtimer.c +endif endif include $(APPDIR)/Application.mk diff --git a/testing/ostest/ostest.h b/testing/ostest/ostest.h index f4f09ca8b..0fb2b8d31 100644 --- a/testing/ostest/ostest.h +++ b/testing/ostest/ostest.h @@ -215,6 +215,12 @@ void suspend_test(void); void wdog_test(void); +/* hrtimer.c ****************************************************************/ + +#ifdef CONFIG_HRTIMER +void hrtimer_test(void); +#endif + /* posixtimers.c ************************************************************/ void timer_test(void); @@ -314,8 +320,4 @@ int sem_nfreeholders(void); void nxevent_test(void); #endif -#if defined(CONFIG_HRTIMER) && defined(CONFIG_BUILD_FLAT) -void hrtimer_test(void); -#endif - #endif /* __APPS_TESTING_OSTEST_OSTEST_H */ diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c index c711a8db6..89022b4bc 100644 --- a/testing/ostest/ostest_main.c +++ b/testing/ostest/ostest_main.c @@ -555,6 +555,14 @@ static int user_main(int argc, char *argv[]) printf("\nuser_main: wdog test\n"); wdog_test(); check_test_memory_usage(); + + /* Verify hrtimer */ + +# ifdef CONFIG_HRTIMER + printf("\nuser_main: hrtimer test\n"); + hrtimer_test(); + check_test_memory_usage(); +# endif #endif #if !defined(CONFIG_DISABLE_POSIX_TIMERS) && \ @@ -643,14 +651,6 @@ static int user_main(int argc, char *argv[]) check_test_memory_usage(); #endif -#if defined(CONFIG_HRTIMER) && defined(CONFIG_BUILD_FLAT) - /* Verify hrtimer */ - - printf("\nuser_main: hrtimer test\n"); - hrtimer_test(); - check_test_memory_usage(); -#endif - /* Compare memory usage at time ostest_main started until * user_main exits. These should not be identical, but should * be similar enough that we can detect any serious OS memory From 0bbf5dc0924fe3c602d85a9cccfe3268b1578ffe Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 29 Jan 2026 16:18:14 +0800 Subject: [PATCH 245/568] sched/hrtimer: Improve code readability This commit improved the code readability. Signed-off-by: ouyangxiangzhen --- testing/ostest/hrtimer.c | 45 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index d82cf171a..eedd53b86 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -41,23 +41,22 @@ /* Timer constants */ -#define NSEC_PER_50MS (50 * NSEC_PER_MSEC) -#define PERIOD_TEST_COUNT 15 -#define THREAD_LOOP_COUNT 50 -#define HRTIMER_TEST_THREAD_NR (CONFIG_SMP_NCPUS * 5) +#define HRTIMER_PERIOD_TEST_NR 15 +#define HRTIMER_THREAD_LOOP_NR 50 +#define HRTIMER_TEST_THREAD_NR (CONFIG_SMP_NCPUS * 5) -/* Set a 1ms margin to allow hrtimertest to pass in QEMU. +/* Set a 1ms latency to allow hrtimertest to pass in QEMU. * * QEMU is a virtual platform, and its timer resolution and scheduling * latency may be less precise than on real hardware. Using a larger - * margin ensures that tests do not fail due to timing inaccuracies. + * latency ensures that tests do not fail due to timing inaccuracies. * * On real hardware (verified on the a2g-tc397-5v-tft board), this - * margin can be reduced to less than 5 ns because timers are precise + * latency can be reduced to less than 5 ns because timers are precise * and deterministic. */ -#define HRTIMER_TEST_MARGIN (NSEC_PER_MSEC) +#define HRTIMER_TEST_TOLERENT_LATENCY (NSEC_PER_MSEC) /**************************************************************************** * Private Types @@ -126,17 +125,17 @@ test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) ASSERT(diff >= 0); - if (diff > HRTIMER_TEST_MARGIN) + if (diff > HRTIMER_TEST_TOLERENT_LATENCY) { printf("hrtimer_test: warning diff=%" PRIu64 " > %" PRIu64 "\n", - diff, HRTIMER_TEST_MARGIN); + diff, HRTIMER_TEST_TOLERENT_LATENCY); } test->timestamp = now; - /* Stop the test after PERIOD_TEST_COUNT expirations */ + /* Stop the test after HRTIMER_PERIOD_TEST_NR expirations */ - if (test->count < PERIOD_TEST_COUNT) + if (test->count < HRTIMER_PERIOD_TEST_NR) { return test->period; } @@ -174,7 +173,7 @@ static void * hrtimer_test_thread(void *arg) hrtimer_test_t test; int ret; uint64_t stamp; - int i = 0; + int loop_cnt = 0; hrtimer_t *timer = &test.timer; /* Initialize the high-resolution timer */ @@ -185,7 +184,7 @@ static void * hrtimer_test_thread(void *arg) stamp = test.timestamp; ASSERT(hrtimer_start(timer, test_hrtimer_callback, - NSEC_PER_50MS, HRTIMER_MODE_REL) == OK); + 50 * NSEC_PER_MSEC, HRTIMER_MODE_REL) == OK); /* Wait until the test completes */ @@ -194,9 +193,8 @@ static void * hrtimer_test_thread(void *arg) usleep(USEC_PER_MSEC); } - while (i < THREAD_LOOP_COUNT) + while (loop_cnt++ < HRTIMER_THREAD_LOOP_NR) { - i++; uint64_t delay = rand() % NSEC_PER_MSEC; /* Cancel timer */ @@ -249,15 +247,16 @@ static void * hrtimer_test_thread(void *arg) void hrtimer_test(void) { struct sched_param sparam; - unsigned int thread_id; - pthread_attr_t attr; - pthread_t pthreads[HRTIMER_TEST_THREAD_NR]; - int ret; + unsigned int thread_id; + pthread_attr_t attr; + pthread_t pthreads[HRTIMER_TEST_THREAD_NR]; - pthread_attr_init(&attr); + printf("hrtimer_test start...\n"); + + ASSERT(pthread_attr_init(&attr) == 0); sparam.sched_priority = PTHREAD_DEFAULT_PRIORITY; - pthread_attr_setschedparam(&attr, &sparam); + ASSERT(pthread_attr_setschedparam(&attr, &sparam) == 0); for (thread_id = 0; thread_id < HRTIMER_TEST_THREAD_NR; thread_id++) { @@ -273,4 +272,6 @@ void hrtimer_test(void) } ASSERT(pthread_attr_destroy(&attr) == 0); + + printf("hrtimer_test end...\n"); } From d33830e83fe99fc56e5a53642196a1d9e45ef702 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Mon, 2 Feb 2026 16:17:22 +0800 Subject: [PATCH 246/568] ostest/hrtimer: Increase the tolerent latency. For QEMU, virtual CPUs can be preempted by any high priority thread in test environments. This can cause the timer to be triggered later than expected. This commit increased the tolerant latency to avoid the test failures. Signed-off-by: ouyangxiangzhen --- testing/ostest/hrtimer.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index eedd53b86..3cf847eb3 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -45,18 +45,22 @@ #define HRTIMER_THREAD_LOOP_NR 50 #define HRTIMER_TEST_THREAD_NR (CONFIG_SMP_NCPUS * 5) -/* Set a 1ms latency to allow hrtimertest to pass in QEMU. +/* Set the tolerent latency to 10ms to allow hrtimer_test to pass + * in QEMU. * - * QEMU is a virtual platform, and its timer resolution and scheduling - * latency may be less precise than on real hardware. Using a larger - * latency ensures that tests do not fail due to timing inaccuracies. + * QEMU is a virtual platform, vCPUs can be preempted by any + * high priority thread. This can cause the timer to be triggered + * later than expected. This is especially true on QEMU because it + * has a lot of overhead. The timer resolution is also less precise + * than on real hardware. Using a larger latency ensures that tests + * do not fail due to timing inaccuracies. * * On real hardware (verified on the a2g-tc397-5v-tft board), this * latency can be reduced to less than 5 ns because timers are precise * and deterministic. */ -#define HRTIMER_TEST_TOLERENT_LATENCY (NSEC_PER_MSEC) +#define HRTIMER_TEST_TOLERENT_LATENCY (10 * NSEC_PER_MSEC) /**************************************************************************** * Private Types From 256d6685d57788ec47cf34957124d87f229e2571 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Wed, 25 Feb 2026 09:48:19 +0800 Subject: [PATCH 247/568] sched/hrtimer: Refactor the hrtimer_test. This commit refactored the hrtimer_test and provided significantly improved test-cases for both SMP and non-SMP. Signed-off-by: ouyangxiangzhen --- testing/ostest/hrtimer.c | 572 +++++++++++++++++++++++++++++++-------- 1 file changed, 466 insertions(+), 106 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index 3cf847eb3..63040697c 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -41,9 +41,9 @@ /* Timer constants */ -#define HRTIMER_PERIOD_TEST_NR 15 -#define HRTIMER_THREAD_LOOP_NR 50 -#define HRTIMER_TEST_THREAD_NR (CONFIG_SMP_NCPUS * 5) +#define HRTIMER_TEST_RAND_ITER (1024 * 2) +#define HRTIMER_TEST_CSECTION 1024 +#define HRTIMER_TEST_THREAD_NR (CONFIG_SMP_NCPUS * 8) /* Set the tolerent latency to 10ms to allow hrtimer_test to pass * in QEMU. @@ -62,6 +62,8 @@ #define HRTIMER_TEST_TOLERENT_LATENCY (10 * NSEC_PER_MSEC) +#define hrtimer_test_ndelay(delay_ns) usleep(delay_ns / 1000 + 1) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -71,99 +73,458 @@ typedef struct hrtimer_test_s { struct hrtimer_s timer; /* HRTimer instance */ + spinlock_t lock; /* Spinlock */ volatile uint64_t timestamp; /* Previous timestamp in nanoseconds */ volatile uint64_t count; /* Number of timer expirations */ uint64_t period; /* Expected period between expirations */ + volatile uint8_t state; /* Test state */ } hrtimer_test_t; /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: test_hrtimer_callback - * - * Description: - * HRTimer callback function for test. - * - * - Verifies the timer interval is exactly 500ms (nanosecond precision) - * - Stops the test after 15 expirations - * - Re-arms the timer in absolute mode - * - * Input Parameters: - * hrtimer - Pointer to the expired HRTimer instance - * expired - The expired value of hrtimer - * - * Returned Value: - * Timer period in nanoseconds (NSEC_PER_50MS) - * - ****************************************************************************/ - -static uint64_t -test_hrtimer_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) +static uint64_t hrtimer_test_callback_oneshot(FAR const hrtimer_t *timer, + uint64_t expired_ns) { - struct timespec ts; - int64_t diff; - uint64_t now; - int ret; + FAR hrtimer_test_t *param = (FAR hrtimer_test_t *)timer; - FAR struct hrtimer_test_s *test = - (FAR struct hrtimer_test_s *)hrtimer; + /* Save the timestamp when the callback was triggered */ - /* Increment expiration count */ + param->timestamp = clock_systime_nsec(); - test->count++; + /* Increment the callback count */ - /* Get current system time */ + param->count++; - clock_systime_timespec(&ts); - now = clock_time2nsec(&ts); + return 0; +} - /* Verify the timer interval is exactly - * 500ms with nsec resolution - */ +static void hrtimer_test_checkdelay(uint64_t timestamp, uint64_t expected) +{ + int64_t diff = timestamp - expected; - diff = now - expired; - - /* Ensure the time diff is valid. */ + /* Ensure the hrtimer trigger time is not earlier than expected. */ ASSERT(diff >= 0); + /* If the timer latency exceeds the tolerance, print a warning. */ + if (diff > HRTIMER_TEST_TOLERENT_LATENCY) { - printf("hrtimer_test: warning diff=%" PRIu64 " > %" PRIu64 "\n", - diff, HRTIMER_TEST_TOLERENT_LATENCY); - } - - test->timestamp = now; - - /* Stop the test after HRTIMER_PERIOD_TEST_NR expirations */ - - if (test->count < HRTIMER_PERIOD_TEST_NR) - { - return test->period; - } - else - { - test->active = false; - return 0; + printf("hrtimer_test: [WARNING] hrtimer latency %" PRId64 + " is too late!!! (> %u)\n", diff, + (unsigned)HRTIMER_TEST_TOLERENT_LATENCY); } } -/**************************************************************************** - * Name: hrtimer_test_callback - * - * Description: - * Simple HRTimer callback for threaded tests. - * - ****************************************************************************/ - -static uint64_t -hrtimer_test_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) +static void hrtimer_test_oneshot(FAR hrtimer_test_t *param, uint64_t delay) { + uint64_t count; + uint64_t now; + FAR hrtimer_t *timer = ¶m->timer; + + printf("hrtimer_test_oneshot %" PRIu64 " ns\n", delay); + + /* Save the current callback count. */ + + count = param->count; + + /* Save the current system time. */ + + now = clock_systime_nsec(); + + ASSERT(hrtimer_start(timer, hrtimer_test_callback_oneshot, + delay + now, HRTIMER_MODE_ABS) == OK); + + /* Wait until the callback is triggered exactly once. */ + + while (count + 1 != param->count) + { + hrtimer_test_ndelay(delay); + } + + /* Check if the delay is within the acceptable tolerance. */ + + hrtimer_test_checkdelay(param->timestamp, now + delay); + + /* Cancel the timer. */ + + hrtimer_cancel_sync(timer); +} + +static void hrtimer_test_maximum(FAR hrtimer_test_t *param) +{ + uint64_t count; + uint64_t rest; + FAR hrtimer_t *timer = ¶m->timer; + + count = param->count; + + /* Start the hrtimer with maximum */ + + ASSERT(hrtimer_start(timer, hrtimer_test_callback_oneshot, UINT64_MAX, + HRTIMER_MODE_REL) == OK); + + /* Sleep for at least 1s */ + + hrtimer_test_ndelay(USEC_PER_SEC / 100); + + /* Ensure hrtimer is not alarmed */ + + ASSERT(count == param->count); + + rest = hrtimer_gettime(timer); + + ASSERT(rest < UINT64_MAX); + + ASSERT(hrtimer_cancel_sync(timer) == OK); + + printf("hrtimer_start with maximum delay, rest %" PRIu64 "\n", rest); +} + +static void hrtimer_test_rand(FAR hrtimer_test_t *param, uint64_t rand_ns) +{ + uint64_t count; + uint64_t now; + unsigned int idx; + uint64_t delay; + irqstate_t flags; + FAR hrtimer_t *timer = ¶m->timer; + + printf("hrtimer_test_rand %" PRIu64 " ns\n", rand_ns); + + /* Perform multiple iterations with random delays. */ + + for (idx = 0; idx < HRTIMER_TEST_RAND_ITER; idx++) + { + /* Generate a random delay within the specified range. */ + + delay = rand() % rand_ns; + + ASSERT(timer->func == NULL); + + /* Enter critical section if the callback count is odd. */ + + count = param->count; + + if (count % 2u) + { + flags = up_irq_save(); + } + + now = clock_systime_nsec(); + ASSERT(hrtimer_start(timer, hrtimer_test_callback_oneshot, + delay, HRTIMER_MODE_REL) == 0); + if (count % 2u) + { + up_irq_restore(flags); + } + + /* Decide to wait for the callback or cancel the hrtimer. */ + + if (delay % 2u) + { + /* Wait for the callback. */ + + while (count + 1u != param->count) + { + hrtimer_test_ndelay(delay); + } + + /* Check the delay if the callback count is odd. */ + + if (count % 2u) + { + hrtimer_test_checkdelay(param->timestamp, now + delay); + } + } + + hrtimer_cancel_sync(timer); + ASSERT(timer->func == NULL); + } + + hrtimer_cancel_sync(timer); +} + +static uint64_t hrtimer_test_cancel_callback(FAR const hrtimer_t *timer, + uint64_t expired_ns) +{ + FAR hrtimer_test_t *param = (FAR hrtimer_test_t *)timer; + FAR spinlock_t *lock = ¶m->lock; + uint64_t delay = 0; + irqstate_t flags = spin_lock_irqsave(lock); + + /* Random sleep */ + + delay = expired_ns % param->period; + + /* Check if the version is same. */ + + if (expired_ns == timer->expired) + { + param->timestamp = clock_systime_nsec(); + + /* Increment the callback count */ + + param->count++; + } + + spin_unlock_irqrestore(lock, flags); + + up_ndelay(delay); + return 0; } +static void hrtimer_test_rand_cancel(FAR hrtimer_test_t *param, + uint64_t rand_ns) +{ + uint64_t now; + unsigned int idx; + uint64_t count; + uint64_t delay; + irqstate_t flags; + spinlock_t *lock = ¶m->lock; + + printf("hrtimer_test_rand cancel %" PRIu64 " ns\n", rand_ns); + + param->period = rand_ns; + + /* Perform multiple iterations with random delays. */ + + for (idx = 0; idx < HRTIMER_TEST_RAND_ITER; idx++) + { + /* Generate a random delay within the specified range. */ + + delay = rand() % rand_ns; + + flags = spin_lock_irqsave(lock); + + now = clock_systime_nsec(); + count = param->count; + ASSERT(hrtimer_start(¶m->timer, hrtimer_test_cancel_callback, + delay, HRTIMER_MODE_REL) == 0); + + spin_unlock_irqrestore(lock, flags); + + /* Decide to wait for the callback or cancel the hrtimer. */ + + if (delay % 2u) + { + /* Wait for the callback finished. */ + + while (param->count != count + 1u) + { + hrtimer_test_ndelay(delay); + } + + hrtimer_test_checkdelay(param->timestamp, now + delay); + } + + hrtimer_cancel(¶m->timer); + } + + hrtimer_cancel_sync(¶m->timer); +} + +static uint64_t hrtimer_test_callback_period(FAR const hrtimer_t *timer, + uint64_t expired_ns) +{ + FAR hrtimer_test_t *param = (FAR hrtimer_test_t *)timer; + uint64_t interval = param->period; + + param->count++; + param->timestamp = clock_systime_nsec(); + + return interval; +} + +static void hrtimer_test_period(FAR hrtimer_test_t *param, + uint64_t delay_ns, + unsigned int iters) +{ + uint64_t timestamp; + uint64_t count = param->count; + FAR hrtimer_t *timer = ¶m->timer; + + printf("hrtimer_test_period %" PRIu64 " ns\n", delay_ns); + + param->period = delay_ns; + ASSERT(param->period > 0); + + timestamp = clock_systime_nsec(); + + ASSERT(hrtimer_start(timer, hrtimer_test_callback_period, + delay_ns, HRTIMER_MODE_REL) == OK); + + hrtimer_test_ndelay(iters * delay_ns); + + hrtimer_cancel_sync(timer); + ASSERT(timer->func == NULL); + + printf("periodical hrtimer triggered %" PRIu64 " times, " + "elapsed nsec %" PRIu64 "\n", param->count - count, + param->timestamp - timestamp); + + if (param->count - count < iters) + { + printf("hrtimer_test: [WARNING] periodical hrtimer" + "triggered times < %u\n", iters); + } +} + +#ifdef CONFIG_SMP +static uint64_t hrtimer_test_callback_crita(FAR const hrtimer_t *timer, + uint64_t expired_ns) +{ + FAR hrtimer_test_t *param = (FAR hrtimer_test_t *)timer; + + /* change status */ + + if (param->state == 0) + { + param->state = 1; + param->count++; + } + + /* check whether parameter be changed by another critical section */ + + ASSERT(param->state == 1); + param->state = 0; + + return 0; +} + +static uint64_t hrtimer_test_callback_critb(FAR const hrtimer_t *timer, + uint64_t expired_ns) +{ + FAR hrtimer_test_t *param = (FAR hrtimer_test_t *)timer; + + /* change status */ + + if (param->state == 1) + { + param->state = 0; + param->count++; + } + + /* check whether parameter be changed by another critical section */ + + ASSERT(param->state == 0); + param->state = 1; + + return 0; +} + +static uint64_t hrtimer_test_callback_critdelay(FAR const hrtimer_t *timer, + uint64_t expired_ns) +{ + FAR hrtimer_test_t *param = (FAR hrtimer_test_t *)timer; + FAR spinlock_t *lock = ¶m->lock; + irqstate_t flags; + + flags = spin_lock_irqsave(lock); + param->count++; + spin_unlock_irqrestore(lock, flags); + + up_ndelay(100 * NSEC_PER_USEC); + + return 300 * NSEC_PER_USEC; +} + +static void hrtimer_test_cancel_sync(FAR hrtimer_test_t *param) +{ + unsigned int idx = 0; + + ASSERT(!param->timer.func); + + param->count = 0; + + /* This test is to validate if the hrtimer can ensure the + * callback function be finished after the hrtimer_cancel_sync + * is called. + */ + + for (idx = 0; idx < HRTIMER_TEST_CSECTION; ) + { + param->state = 0; + hrtimer_start(¶m->timer, hrtimer_test_callback_crita, + 0, HRTIMER_MODE_REL); + + hrtimer_cancel_sync(¶m->timer); + param->state = 1; + hrtimer_start(¶m->timer, hrtimer_test_callback_critb, + 0, HRTIMER_MODE_REL); + + if (++idx % (HRTIMER_TEST_CSECTION / 4) == 0) + { + printf("hrtimer_test_cancel_sync passed %d times.\n", idx); + } + + hrtimer_cancel_sync(¶m->timer); + } +} + +static void hrtimer_test_cancel_periodic(FAR hrtimer_test_t *param) +{ + uint64_t count; + unsigned int idx = 0; + FAR spinlock_t *lock = ¶m->lock; + + ASSERT(!param->timer.func); + + param->count = 0; + + /* This test to check if the hrtimer can ensure the perodical callback + * can not restart the timer again after the hrtimer_cancel_sync is + * called. + */ + + for (idx = 0; idx < HRTIMER_TEST_CSECTION; idx++) + { + irqstate_t flags = spin_lock_irqsave(lock); + + hrtimer_start(¶m->timer, hrtimer_test_callback_critdelay, + 0, HRTIMER_MODE_REL); + + spin_unlock_irqrestore(lock, flags); + + up_ndelay(10000); + + flags = spin_lock_irqsave(lock); + + hrtimer_start(¶m->timer, hrtimer_test_callback_critdelay, + 0, HRTIMER_MODE_REL); + + spin_unlock_irqrestore(lock, flags); + + hrtimer_cancel(¶m->timer); + + up_ndelay(10000); + + /* The hrtimer should not be restarted again after the cancellation. */ + + ASSERT(!param->timer.func); + + hrtimer_cancel_sync(¶m->timer); + count = param->count; + + hrtimer_test_ndelay(10000); + + ASSERT(count == param->count); + + if (++idx % (HRTIMER_TEST_CSECTION / 4) == 0) + { + printf("hrtimer_test_cancel_periodic passed %d times. count %" + PRIu64 "\n", idx, param->count); + } + } + + hrtimer_cancel_sync(¶m->timer); +} +#endif + /**************************************************************************** * Name: hrtimer_test_thread * @@ -174,56 +535,55 @@ hrtimer_test_callback(FAR const hrtimer_t *hrtimer, uint64_t expired) static void * hrtimer_test_thread(void *arg) { - hrtimer_test_t test; - int ret; - uint64_t stamp; - int loop_cnt = 0; - hrtimer_t *timer = &test.timer; - - /* Initialize the high-resolution timer */ - - hrtimer_init(timer); - - /* Start the timer with 500ms relative timeout */ - - stamp = test.timestamp; - ASSERT(hrtimer_start(timer, test_hrtimer_callback, - 50 * NSEC_PER_MSEC, HRTIMER_MODE_REL) == OK); - - /* Wait until the test completes */ - - while (test.timestamp != stamp) + hrtimer_test_t param = { - usleep(USEC_PER_MSEC); - } + 0 + }; - while (loop_cnt++ < HRTIMER_THREAD_LOOP_NR) - { - uint64_t delay = rand() % NSEC_PER_MSEC; + hrtimer_init(¶m.timer); - /* Cancel timer */ + /* Delay = 0 */ - ret = hrtimer_cancel(&timer); - ASSERT(ret == OK); + hrtimer_test_oneshot(¶m, 0u); - /* Start timer with fixed period */ + /* 0 < Delay < 10000 */ - ret = hrtimer_start(&timer, hrtimer_test_callback, - 10 * NSEC_PER_USEC, HRTIMER_MODE_REL); - ASSERT(ret == OK); + hrtimer_test_oneshot(¶m, 1u); + hrtimer_test_oneshot(¶m, 10u); + hrtimer_test_oneshot(¶m, 100u); + hrtimer_test_oneshot(¶m, 1000u); + hrtimer_test_oneshot(¶m, 10000u); - /* Start timer with random delay */ + /* 10000 < Delay < 10000000 */ - ret = hrtimer_start(&timer, hrtimer_test_callback, - delay, HRTIMER_MODE_REL); - ASSERT(ret == OK); - } + hrtimer_test_oneshot(¶m, 100000u); + hrtimer_test_oneshot(¶m, 1000000u); + hrtimer_test_oneshot(¶m, 10000000u); - /* Cancel the timer synchronously */ +#ifdef CONFIG_SMP + /* Test hrtimer_cancel_sync */ - ASSERT(hrtimer_cancel_sync(&timer) == OK); + hrtimer_test_cancel_sync(¶m); - return NULL; + /* Test hrtimer_cancel */ + + hrtimer_test_cancel_periodic(¶m); +#endif + + /* Maximum hrtimer delay test. */ + + hrtimer_test_maximum(¶m); + + /* Period hrtimer delay 100000ns */ + + hrtimer_test_period(¶m, 1000000u, 128u); + + /* Random delay 12345ns and 67890ns */ + + hrtimer_test_rand(¶m, 12345u); + hrtimer_test_rand_cancel(¶m, 67890u); + + return 0; } /**************************************************************************** From e4b84b29d47b98a666df524d6f2d38904c972de5 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Wed, 25 Feb 2026 10:01:21 +0800 Subject: [PATCH 248/568] ostest/hrtimer: Update the comments. This commit updated the comments. Signed-off-by: ouyangxiangzhen --- testing/ostest/hrtimer.c | 388 ++++++++++++++++++++++++++++++++------- 1 file changed, 322 insertions(+), 66 deletions(-) diff --git a/testing/ostest/hrtimer.c b/testing/ostest/hrtimer.c index 63040697c..3220ef2db 100644 --- a/testing/ostest/hrtimer.c +++ b/testing/ostest/hrtimer.c @@ -39,14 +39,13 @@ * Pre-processor Definitions ****************************************************************************/ -/* Timer constants */ +/* HRTimer test constants */ -#define HRTIMER_TEST_RAND_ITER (1024 * 2) -#define HRTIMER_TEST_CSECTION 1024 -#define HRTIMER_TEST_THREAD_NR (CONFIG_SMP_NCPUS * 8) +#define HRTIMER_TEST_RAND_ITER (1024 * 2) /* Random delay iterations */ +#define HRTIMER_TEST_CSECTION 1024 /* Critical section iterations */ +#define HRTIMER_TEST_THREAD_NR (CONFIG_SMP_NCPUS * 8) /* Test threads */ -/* Set the tolerent latency to 10ms to allow hrtimer_test to pass - * in QEMU. +/* Tolerable latency for timer expiration * * QEMU is a virtual platform, vCPUs can be preempted by any * high priority thread. This can cause the timer to be triggered @@ -62,7 +61,9 @@ #define HRTIMER_TEST_TOLERENT_LATENCY (10 * NSEC_PER_MSEC) -#define hrtimer_test_ndelay(delay_ns) usleep(delay_ns / 1000 + 1) +/* Helper macro for nanosecond delay */ + +#define hrtimer_test_ndelay(delay_ns) usleep((delay_ns) / 1000 + 1) /**************************************************************************** * Private Types @@ -73,23 +74,40 @@ typedef struct hrtimer_test_s { struct hrtimer_s timer; /* HRTimer instance */ - spinlock_t lock; /* Spinlock */ + spinlock_t lock; /* Spinlock for thread-safe operations */ volatile uint64_t timestamp; /* Previous timestamp in nanoseconds */ volatile uint64_t count; /* Number of timer expirations */ uint64_t period; /* Expected period between expirations */ - volatile uint8_t state; /* Test state */ + volatile uint8_t state; /* Test state (used for synchronization tests) */ } hrtimer_test_t; /**************************************************************************** * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: hrtimer_test_callback_oneshot + * + * Description: + * One-shot timer callback function. This callback is invoked when a + * one-shot HRTimer expires. It records the exact timestamp and increments + * the expiration counter. + * + * Input Parameters: + * timer - Pointer to the HRTimer instance + * expired_ns - Time when the timer expired (unused) + * + * Returned Value: + * 0 (oneshot hrtimer) + * + ****************************************************************************/ + static uint64_t hrtimer_test_callback_oneshot(FAR const hrtimer_t *timer, uint64_t expired_ns) { FAR hrtimer_test_t *param = (FAR hrtimer_test_t *)timer; - /* Save the timestamp when the callback was triggered */ + /* Record the exact timestamp when the callback was triggered */ param->timestamp = clock_systime_nsec(); @@ -100,6 +118,24 @@ static uint64_t hrtimer_test_callback_oneshot(FAR const hrtimer_t *timer, return 0; } +/**************************************************************************** + * Name: hrtimer_test_checkdelay + * + * Description: + * Check timer delay against tolerance threshold. This function verifies + * that the actual timer expiration time is within the acceptable + * tolerance. + * It warns if the delay exceeds the threshold. + * + * Input Parameters: + * timestamp - Actual expiration timestamp (nanoseconds) + * expected - Expected expiration timestamp (nanoseconds) + * + * Returned Value: + * None. + * + ****************************************************************************/ + static void hrtimer_test_checkdelay(uint64_t timestamp, uint64_t expected) { int64_t diff = timestamp - expected; @@ -113,76 +149,131 @@ static void hrtimer_test_checkdelay(uint64_t timestamp, uint64_t expected) if (diff > HRTIMER_TEST_TOLERENT_LATENCY) { printf("hrtimer_test: [WARNING] hrtimer latency %" PRId64 - " is too late!!! (> %u)\n", diff, + " ns is too late (> %u ns)\n", diff, (unsigned)HRTIMER_TEST_TOLERENT_LATENCY); } } +/**************************************************************************** + * Name: hrtimer_test_oneshot + * + * Description: + * Test one-shot HRTimer functionality. This function tests a one-shot + * HRTimer by starting it with a specified delay and verifying that it + * expires at the expected time. + * + * Input Parameters: + * param - Test context structure containing timer and state information + * delay - Delay in nanoseconds for the one-shot timer + * + * Returned Value: + * None. + * + ****************************************************************************/ + static void hrtimer_test_oneshot(FAR hrtimer_test_t *param, uint64_t delay) { uint64_t count; uint64_t now; FAR hrtimer_t *timer = ¶m->timer; - printf("hrtimer_test_oneshot %" PRIu64 " ns\n", delay); + printf("hrtimer_test_oneshot: delay = %" PRIu64 " ns\n", delay); - /* Save the current callback count. */ + /* Save the current callback count and system time */ count = param->count; - - /* Save the current system time. */ - now = clock_systime_nsec(); + /* Start the one-shot timer */ + ASSERT(hrtimer_start(timer, hrtimer_test_callback_oneshot, delay + now, HRTIMER_MODE_ABS) == OK); - /* Wait until the callback is triggered exactly once. */ + /* Wait until the callback is triggered exactly once */ while (count + 1 != param->count) { hrtimer_test_ndelay(delay); } - /* Check if the delay is within the acceptable tolerance. */ + /* Verify the delay is within acceptable tolerance */ hrtimer_test_checkdelay(param->timestamp, now + delay); - /* Cancel the timer. */ + /* Cancel the timer to clean up */ hrtimer_cancel_sync(timer); } +/**************************************************************************** + * Name: hrtimer_test_maximum + * + * Description: + * Test HRTimer with maximum delay value. This function tests the behavior + * of HRTimer when started with the maximum possible delay (UINT64_MAX + * nanoseconds). The timer should not expire within a reasonable test + * period. + * + * Input Parameters: + * param - Test context structure containing timer and state information + * + * Returned Value: + * None. + * + ****************************************************************************/ + static void hrtimer_test_maximum(FAR hrtimer_test_t *param) { uint64_t count; uint64_t rest; FAR hrtimer_t *timer = ¶m->timer; + printf("hrtimer_test_maximum: testing with UINT64_MAX delay\n"); + count = param->count; - /* Start the hrtimer with maximum */ + /* Start the hrtimer with maximum delay */ ASSERT(hrtimer_start(timer, hrtimer_test_callback_oneshot, UINT64_MAX, HRTIMER_MODE_REL) == OK); - /* Sleep for at least 1s */ + /* Sleep for at least 100ms to verify timer doesn't expire */ hrtimer_test_ndelay(USEC_PER_SEC / 100); - /* Ensure hrtimer is not alarmed */ + /* Ensure hrtimer has not expired (count should remain unchanged) */ ASSERT(count == param->count); + /* Get the remaining time until expiration */ + rest = hrtimer_gettime(timer); + /* Verify the remaining time is still large (less than UINT64_MAX) */ + ASSERT(rest < UINT64_MAX); + /* Cancel the timer */ + ASSERT(hrtimer_cancel_sync(timer) == OK); - printf("hrtimer_start with maximum delay, rest %" PRIu64 "\n", rest); + printf("hrtimer_test_maximum: remaining time = %" PRIu64 " ns\n", rest); } +/**************************************************************************** + * Name: hrtimer_test_rand + * + * Description: + * Test HRTimer with random delays. This function tests HRTimer behavior + * with random delay values within a specified range. It performs multiple + * iterations, testing both timer expiration and cancellation scenarios. + * + * Input Parameters: + * param - Test context structure containing timer and state information + * rand_ns - Maximum random delay value in nanoseconds + * + ****************************************************************************/ + static void hrtimer_test_rand(FAR hrtimer_test_t *param, uint64_t rand_ns) { uint64_t count; @@ -192,19 +283,19 @@ static void hrtimer_test_rand(FAR hrtimer_test_t *param, uint64_t rand_ns) irqstate_t flags; FAR hrtimer_t *timer = ¶m->timer; - printf("hrtimer_test_rand %" PRIu64 " ns\n", rand_ns); + printf("hrtimer_test_rand: max delay = %" PRIu64 " ns\n", rand_ns); - /* Perform multiple iterations with random delays. */ + /* Perform multiple iterations with random delays */ for (idx = 0; idx < HRTIMER_TEST_RAND_ITER; idx++) { - /* Generate a random delay within the specified range. */ + /* Generate a random delay within the specified range */ delay = rand() % rand_ns; ASSERT(timer->func == NULL); - /* Enter critical section if the callback count is odd. */ + /* Enter critical section if the callback count is odd */ count = param->count; @@ -221,18 +312,18 @@ static void hrtimer_test_rand(FAR hrtimer_test_t *param, uint64_t rand_ns) up_irq_restore(flags); } - /* Decide to wait for the callback or cancel the hrtimer. */ + /* Decide to wait for the callback or cancel the hrtimer */ if (delay % 2u) { - /* Wait for the callback. */ + /* Wait for the callback */ while (count + 1u != param->count) { hrtimer_test_ndelay(delay); } - /* Check the delay if the callback count is odd. */ + /* Check the delay if the callback count is odd */ if (count % 2u) { @@ -247,6 +338,23 @@ static void hrtimer_test_rand(FAR hrtimer_test_t *param, uint64_t rand_ns) hrtimer_cancel_sync(timer); } +/**************************************************************************** + * Name: hrtimer_test_cancel_callback + * + * Description: + * Callback function for cancel test. This callback is used in the cancel + * test to simulate a long-running callback that can be interrupted by + * timer cancellation. + * + * Input Parameters: + * timer - Pointer to the HRTimer instance + * expired_ns - Time when the timer expired + * + * Returned Value: + * 0 (oneshot hrtimer) + * + ****************************************************************************/ + static uint64_t hrtimer_test_cancel_callback(FAR const hrtimer_t *timer, uint64_t expired_ns) { @@ -255,11 +363,11 @@ static uint64_t hrtimer_test_cancel_callback(FAR const hrtimer_t *timer, uint64_t delay = 0; irqstate_t flags = spin_lock_irqsave(lock); - /* Random sleep */ + /* Calculate random sleep delay based on period */ delay = expired_ns % param->period; - /* Check if the version is same. */ + /* Check if the expiration time matches (prevents duplicate processing) */ if (expired_ns == timer->expired) { @@ -272,11 +380,28 @@ static uint64_t hrtimer_test_cancel_callback(FAR const hrtimer_t *timer, spin_unlock_irqrestore(lock, flags); + /* Simulate work with random delay */ + up_ndelay(delay); return 0; } +/**************************************************************************** + * Name: hrtimer_test_rand_cancel + * + * Description: + * Test HRTimer cancellation with random delays. This function tests + * HRTimer cancellation behavior with random delay values. It verifies + * that timers can be properly cancelled and that callbacks behave + * correctly when cancellation occurs. + * + * Input Parameters: + * param - Test context structure containing timer and state information + * rand_ns - Maximum random delay value in nanoseconds + * + ****************************************************************************/ + static void hrtimer_test_rand_cancel(FAR hrtimer_test_t *param, uint64_t rand_ns) { @@ -287,15 +412,15 @@ static void hrtimer_test_rand_cancel(FAR hrtimer_test_t *param, irqstate_t flags; spinlock_t *lock = ¶m->lock; - printf("hrtimer_test_rand cancel %" PRIu64 " ns\n", rand_ns); + printf("hrtimer_test_rand_cancel: max delay = %" PRIu64 " ns\n", rand_ns); param->period = rand_ns; - /* Perform multiple iterations with random delays. */ + /* Perform multiple iterations with random delays */ for (idx = 0; idx < HRTIMER_TEST_RAND_ITER; idx++) { - /* Generate a random delay within the specified range. */ + /* Generate a random delay within the specified range */ delay = rand() % rand_ns; @@ -308,11 +433,11 @@ static void hrtimer_test_rand_cancel(FAR hrtimer_test_t *param, spin_unlock_irqrestore(lock, flags); - /* Decide to wait for the callback or cancel the hrtimer. */ + /* Decide to wait for the callback or cancel the hrtimer */ if (delay % 2u) { - /* Wait for the callback finished. */ + /* Wait for the callback to finish */ while (param->count != count + 1u) { @@ -328,6 +453,23 @@ static void hrtimer_test_rand_cancel(FAR hrtimer_test_t *param, hrtimer_cancel_sync(¶m->timer); } +/**************************************************************************** + * Name: hrtimer_test_callback_period + * + * Description: + * Periodic timer callback function. This callback is invoked when a + * periodic HRTimer expires. It records the timestamp, increments the + * count, and returns the interval for the next expiration. + * + * Input Parameters: + * timer - Pointer to the HRTimer instance + * expired_ns - Time when the timer expired (unused) + * + * Returned Value: + * The interval in nanoseconds for the next expiration + * + ****************************************************************************/ + static uint64_t hrtimer_test_callback_period(FAR const hrtimer_t *timer, uint64_t expired_ns) { @@ -340,6 +482,24 @@ static uint64_t hrtimer_test_callback_period(FAR const hrtimer_t *timer, return interval; } +/**************************************************************************** + * Name: hrtimer_test_period + * + * Description: + * Test periodic HRTimer functionality. This function tests a periodic + * HRTimer by starting it with a specified interval and verifying that + * it triggers multiple times as expected. + * + * Input Parameters: + * param - Test context structure containing timer and state information + * delay_ns - Period interval in nanoseconds + * iters - Expected number of timer expirations + * + * Returned Value: + * None. + * + ****************************************************************************/ + static void hrtimer_test_period(FAR hrtimer_test_t *param, uint64_t delay_ns, unsigned int iters) @@ -348,7 +508,8 @@ static void hrtimer_test_period(FAR hrtimer_test_t *param, uint64_t count = param->count; FAR hrtimer_t *timer = ¶m->timer; - printf("hrtimer_test_period %" PRIu64 " ns\n", delay_ns); + printf("hrtimer_test_period: period = %" PRIu64 " ns, iters = %u\n", + delay_ns, iters); param->period = delay_ns; ASSERT(param->period > 0); @@ -358,29 +519,52 @@ static void hrtimer_test_period(FAR hrtimer_test_t *param, ASSERT(hrtimer_start(timer, hrtimer_test_callback_period, delay_ns, HRTIMER_MODE_REL) == OK); + /* Wait for expected number of periods */ + hrtimer_test_ndelay(iters * delay_ns); hrtimer_cancel_sync(timer); ASSERT(timer->func == NULL); - printf("periodical hrtimer triggered %" PRIu64 " times, " + /* Report results */ + + printf("hrtimer_test_period: triggered %" PRIu64 " times, " "elapsed nsec %" PRIu64 "\n", param->count - count, param->timestamp - timestamp); + /* Warn if fewer expirations than expected */ + if (param->count - count < iters) { - printf("hrtimer_test: [WARNING] periodical hrtimer" + printf("hrtimer_test_period: [WARNING] periodical hrtimer " "triggered times < %u\n", iters); } } #ifdef CONFIG_SMP +/**************************************************************************** + * Name: hrtimer_test_callback_crita + * + * Description: + * Critical section test callback A. This callback is used to test + * critical section protection in SMP systems. It verifies that timer + * callbacks can safely access shared state. + * + * Input Parameters: + * timer - Pointer to the HRTimer instance + * expired_ns - Time when the timer expired (unused) + * + * Returned Value: + * 0 (oneshot hrtimer) + * + ****************************************************************************/ + static uint64_t hrtimer_test_callback_crita(FAR const hrtimer_t *timer, uint64_t expired_ns) { FAR hrtimer_test_t *param = (FAR hrtimer_test_t *)timer; - /* change status */ + /* Change status if in initial state */ if (param->state == 0) { @@ -388,7 +572,7 @@ static uint64_t hrtimer_test_callback_crita(FAR const hrtimer_t *timer, param->count++; } - /* check whether parameter be changed by another critical section */ + /* Verify state wasn't changed by another critical section */ ASSERT(param->state == 1); param->state = 0; @@ -396,12 +580,29 @@ static uint64_t hrtimer_test_callback_crita(FAR const hrtimer_t *timer, return 0; } +/**************************************************************************** + * Name: hrtimer_test_callback_critb + * + * Description: + * Critical section test callback B. This callback is used to test + * critical section protection in SMP systems. It verifies that timer + * callbacks can safely access shared state. + * + * Input Parameters: + * timer - Pointer to the HRTimer instance + * expired_ns - Time when the timer expired (unused) + * + * Returned Value: + * 0 (oneshot hrtimer) + * + ****************************************************************************/ + static uint64_t hrtimer_test_callback_critb(FAR const hrtimer_t *timer, uint64_t expired_ns) { FAR hrtimer_test_t *param = (FAR hrtimer_test_t *)timer; - /* change status */ + /* Change status if in expected state */ if (param->state == 1) { @@ -409,7 +610,7 @@ static uint64_t hrtimer_test_callback_critb(FAR const hrtimer_t *timer, param->count++; } - /* check whether parameter be changed by another critical section */ + /* Verify state wasn't changed by another critical section */ ASSERT(param->state == 0); param->state = 1; @@ -417,6 +618,23 @@ static uint64_t hrtimer_test_callback_critb(FAR const hrtimer_t *timer, return 0; } +/**************************************************************************** + * Name: hrtimer_test_callback_critdelay + * + * Description: + * Critical section delay test callback. This callback simulates a + * long-running timer callback with spinlock protection. It's used to + * test timer cancellation behavior with in-progress callbacks. + * + * Input Parameters: + * timer - Pointer to the HRTimer instance + * expired_ns - Time when the timer expired (unused) + * + * Returned Value: + * 300 microseconds (reschedules timer for periodic behavior) + * + ****************************************************************************/ + static uint64_t hrtimer_test_callback_critdelay(FAR const hrtimer_t *timer, uint64_t expired_ns) { @@ -424,15 +642,35 @@ static uint64_t hrtimer_test_callback_critdelay(FAR const hrtimer_t *timer, FAR spinlock_t *lock = ¶m->lock; irqstate_t flags; + /* Protect count increment with spinlock */ + flags = spin_lock_irqsave(lock); param->count++; spin_unlock_irqrestore(lock, flags); + /* Simulate work with 100 microsecond delay */ + up_ndelay(100 * NSEC_PER_USEC); + /* Return reschedule interval for periodic behavior */ + return 300 * NSEC_PER_USEC; } +/**************************************************************************** + * Name: hrtimer_test_cancel_sync + * + * Description: + * Test HRTimer cancel synchronization. This function tests that + * hrtimer_cancel_sync properly waits for callback completion before + * returning. It verifies that timer callbacks complete execution even + * when cancellation is requested. + * + * Input Parameters: + * param - Test context structure containing timer and state information + * + ****************************************************************************/ + static void hrtimer_test_cancel_sync(FAR hrtimer_test_t *param) { unsigned int idx = 0; @@ -441,11 +679,6 @@ static void hrtimer_test_cancel_sync(FAR hrtimer_test_t *param) param->count = 0; - /* This test is to validate if the hrtimer can ensure the - * callback function be finished after the hrtimer_cancel_sync - * is called. - */ - for (idx = 0; idx < HRTIMER_TEST_CSECTION; ) { param->state = 0; @@ -459,13 +692,27 @@ static void hrtimer_test_cancel_sync(FAR hrtimer_test_t *param) if (++idx % (HRTIMER_TEST_CSECTION / 4) == 0) { - printf("hrtimer_test_cancel_sync passed %d times.\n", idx); + printf("hrtimer_test_cancel_sync: passed %u times\n", idx); } hrtimer_cancel_sync(¶m->timer); } } +/**************************************************************************** + * Name: hrtimer_test_cancel_periodic + * + * Description: + * Test periodic HRTimer cancellation. This function tests that periodic + * timers can be properly cancelled and that they don't restart after + * cancellation. It verifies that timer cancellation is effective and + * persistent. + * + * Input Parameters: + * param - Test context structure containing timer and state information + * + ****************************************************************************/ + static void hrtimer_test_cancel_periodic(FAR hrtimer_test_t *param) { uint64_t count; @@ -476,11 +723,6 @@ static void hrtimer_test_cancel_periodic(FAR hrtimer_test_t *param) param->count = 0; - /* This test to check if the hrtimer can ensure the perodical callback - * can not restart the timer again after the hrtimer_cancel_sync is - * called. - */ - for (idx = 0; idx < HRTIMER_TEST_CSECTION; idx++) { irqstate_t flags = spin_lock_irqsave(lock); @@ -503,7 +745,7 @@ static void hrtimer_test_cancel_periodic(FAR hrtimer_test_t *param) up_ndelay(10000); - /* The hrtimer should not be restarted again after the cancellation. */ + /* The hrtimer should not restart after cancellation */ ASSERT(!param->timer.func); @@ -516,7 +758,7 @@ static void hrtimer_test_cancel_periodic(FAR hrtimer_test_t *param) if (++idx % (HRTIMER_TEST_CSECTION / 4) == 0) { - printf("hrtimer_test_cancel_periodic passed %d times. count %" + printf("hrtimer_test_cancel_periodic: passed %u times, count = %" PRIu64 "\n", idx, param->count); } } @@ -529,11 +771,20 @@ static void hrtimer_test_cancel_periodic(FAR hrtimer_test_t *param) * Name: hrtimer_test_thread * * Description: - * Thread function to repeatedly test HRTimer start/cancel behavior. + * HRTimer test thread function. This function runs a comprehensive test + * suite for HRTimer functionality. It tests various scenarios including + * one-shot timers, periodic timers, random delays, maximum delays, and + * cancellation behavior. + * + * Input Parameters: + * arg - Thread argument (unused) + * + * Returned Value: + * NULL. * ****************************************************************************/ -static void * hrtimer_test_thread(void *arg) +static void *hrtimer_test_thread(void *arg) { hrtimer_test_t param = { @@ -542,6 +793,8 @@ static void * hrtimer_test_thread(void *arg) hrtimer_init(¶m.timer); + /* Test one-shot timers with various delays */ + /* Delay = 0 */ hrtimer_test_oneshot(¶m, 0u); @@ -561,24 +814,21 @@ static void * hrtimer_test_thread(void *arg) hrtimer_test_oneshot(¶m, 10000000u); #ifdef CONFIG_SMP - /* Test hrtimer_cancel_sync */ + /* Test SMP-specific cancellation behavior */ hrtimer_test_cancel_sync(¶m); - - /* Test hrtimer_cancel */ - hrtimer_test_cancel_periodic(¶m); #endif - /* Maximum hrtimer delay test. */ + /* Test maximum delay handling */ hrtimer_test_maximum(¶m); - /* Period hrtimer delay 100000ns */ + /* Test periodic timer with 1ms period */ hrtimer_test_period(¶m, 1000000u, 128u); - /* Random delay 12345ns and 67890ns */ + /* Test random delay and cancel scenarios */ hrtimer_test_rand(¶m, 12345u); hrtimer_test_rand_cancel(¶m, 67890u); @@ -617,11 +867,15 @@ void hrtimer_test(void) printf("hrtimer_test start...\n"); + /* Initialize thread attributes */ + ASSERT(pthread_attr_init(&attr) == 0); sparam.sched_priority = PTHREAD_DEFAULT_PRIORITY; ASSERT(pthread_attr_setschedparam(&attr, &sparam) == 0); + /* Create multiple test threads */ + for (thread_id = 0; thread_id < HRTIMER_TEST_THREAD_NR; thread_id++) { ASSERT(pthread_create(&pthreads[thread_id], &attr, @@ -635,6 +889,8 @@ void hrtimer_test(void) pthread_join(pthreads[thread_id], NULL); } + /* Clean up thread attributes */ + ASSERT(pthread_attr_destroy(&attr) == 0); printf("hrtimer_test end...\n"); From c46ed184edceea1a2d4c63ed428aeeefb066b9c4 Mon Sep 17 00:00:00 2001 From: Mihai Pacuraru Date: Sat, 28 Feb 2026 11:43:31 +0200 Subject: [PATCH 249/568] examples/mqttc: Fix QOS arguments parsing (char->long). Modify the switch cases in parsearg function for QOS levels definition. The comparison was made between a long value and a char. Signed-off-by: Mihai Pacuraru --- examples/mqttc/mqttc_pub.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/mqttc/mqttc_pub.c b/examples/mqttc/mqttc_pub.c index 6948afb42..9beae6885 100644 --- a/examples/mqttc/mqttc_pub.c +++ b/examples/mqttc/mqttc_pub.c @@ -192,13 +192,13 @@ static void parsearg(int argc, FAR char *argv[], case 'q': switch (strtol(optarg, NULL, 10)) { - case '0': + case 0L: cfg->qos = MQTT_PUBLISH_QOS_0; break; - case '1': + case 1L: cfg->qos = MQTT_PUBLISH_QOS_1; break; - case '2': + case 2L: cfg->qos = MQTT_PUBLISH_QOS_2; break; } From 7d13ee204b6fb8545d5eac3b5a1eae9cde3ba14d Mon Sep 17 00:00:00 2001 From: Mihai Pacuraru Date: Sun, 1 Mar 2026 22:50:09 +0200 Subject: [PATCH 250/568] examples/mqttc: Fix mqtt_init() failed message typo (ERRPR -> ERROR). Modify the message logged when mqtt_init() failed to execute properly. Signed-off-by: Mihai Pacuraru --- examples/mqttc/mqttc_pub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mqttc/mqttc_pub.c b/examples/mqttc/mqttc_pub.c index 9beae6885..306df6dcc 100644 --- a/examples/mqttc/mqttc_pub.c +++ b/examples/mqttc/mqttc_pub.c @@ -528,7 +528,7 @@ int main(int argc, FAR char *argv[]) NULL); if (mqtterr != MQTT_OK) { - printf("ERRPR! mqtt_init() failed.\n"); + printf("ERROR! mqtt_init() failed.\n"); goto err_with_conn; } From af7222ec9f6206ec46bedea254cd7d78bad924c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 23:47:16 +0000 Subject: [PATCH 251/568] build(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/labeler.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 907497cba..7cdb24fa2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,7 +106,7 @@ jobs: run: tar zcf sources.tar.gz sources - name: Archive Source Bundle - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7.0.0 with: name: source-bundle path: sources.tar.gz @@ -222,7 +222,7 @@ jobs: if: always() run: df -h - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7.0.0 if: ${{ always() }} with: name: linux-${{matrix.boards}}-builds @@ -267,7 +267,7 @@ jobs: cd sources/nuttx ./tools/ci/cibuild-oot.sh - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7.0.0 if: ${{ always() }} with: name: oot-build-artifacts @@ -328,7 +328,7 @@ jobs: cd sources/nuttx/tools/ci ./cibuild.sh -i -c -A -R testlist/${{matrix.boards}}.dat - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7.0.0 with: name: macos-${{matrix.boards}}-builds path: buildartifacts/ @@ -411,7 +411,7 @@ jobs: cd sources/nuttx/tools/ci ./cibuild.sh -g -i -A -C -N -R testlist/${{matrix.boards}}.dat - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7.0.0 with: name: msys2-${{matrix.boards}}-builds path: buildartifacts/ @@ -463,7 +463,7 @@ jobs: cd sources\nuttx\tools\ci .\cibuild.ps1 -n -i -A -C -N testlist\windows.dat - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7.0.0 with: name: msvc-builds path: ./sources/buildartifacts/ diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index bf1c459ec..cd98874b8 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -144,7 +144,7 @@ jobs: # Upload the PR Artifact as pr.zip - name: Upload PR artifact - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: pr path: pr/ From 45d4c7098bb3a7a6d9b5642efc47df5998c048d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 23:47:08 +0000 Subject: [PATCH 252/568] build(deps): bump actions/download-artifact from 7 to 8 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v7...v8) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7cdb24fa2..835754444 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -154,7 +154,7 @@ jobs: run: df -h - name: Download Source Artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: source-bundle path: . @@ -237,7 +237,7 @@ jobs: DOCKER_BUILDKIT: 1 steps: - name: Download Source Artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: source-bundle path: . @@ -296,7 +296,7 @@ jobs: boards: ${{ fromJSON(needs.macOS-Arch.outputs.selected_builds) }} steps: - name: Download Source Artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: source-bundle path: . @@ -391,7 +391,7 @@ jobs: - run: git config --global core.autocrlf false - name: Download Source Artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: source-bundle path: . @@ -445,7 +445,7 @@ jobs: - run: git config --global core.autocrlf false - name: Download Source Artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: source-bundle path: . From 2964c8cc3dfde40f74e2824b2cf86aaa88dcda7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 22:50:02 +0000 Subject: [PATCH 253/568] build(deps): bump docker/login-action from 3 to 4 Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 835754444..cc12b797d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -163,7 +163,7 @@ jobs: run: tar zxf sources.tar.gz - name: Docker Login - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} @@ -246,7 +246,7 @@ jobs: run: tar zxf sources.tar.gz - name: Docker Login - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} From 8579459bb0bf4fa28c044b7b7de71a7a09029b4d Mon Sep 17 00:00:00 2001 From: Neil Berkman Date: Sun, 8 Mar 2026 17:22:48 -0700 Subject: [PATCH 254/568] boot/nxboot: fix Clang warnings for format and va_start Use PRIdOFF instead of %ld for off_t arguments in flash.c syslog calls, fixing -Wformat errors when off_t is not long. Change nxboot_progress parameter from enum progress_type_e to int to avoid undefined behavior from va_start on a parameter that undergoes default argument promotion (-Wvarargs). Signed-off-by: Neil Berkman --- boot/nxboot/include/nxboot.h | 2 +- boot/nxboot/loader/flash.c | 13 ++++++++----- boot/nxboot/nxboot_main.c | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/boot/nxboot/include/nxboot.h b/boot/nxboot/include/nxboot.h index 6821cc703..3d92e9753 100644 --- a/boot/nxboot/include/nxboot.h +++ b/boot/nxboot/include/nxboot.h @@ -169,7 +169,7 @@ enum progress_msg_e ****************************************************************************/ #ifdef CONFIG_NXBOOT_PROGRESS -void nxboot_progress(enum progress_type_e type, ...); +void nxboot_progress(int type, ...); #else #define nxboot_progress(type, ...) do {} while (0) #endif diff --git a/boot/nxboot/loader/flash.c b/boot/nxboot/loader/flash.c index 9142b25d9..f1a359573 100644 --- a/boot/nxboot/loader/flash.c +++ b/boot/nxboot/loader/flash.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -137,14 +138,15 @@ int flash_partition_write(int fd, const void *buf, size_t count, off_t off) pos = lseek(fd, off, SEEK_SET); if (pos != off) { - syslog(LOG_ERR, "Could not seek to %ld: %s\n", off, strerror(errno)); + syslog(LOG_ERR, "Could not seek to %" PRIdOFF ": %s\n", + off, strerror(errno)); return ERROR; } nbytes = write(fd, buf, count); if (nbytes != count) { - syslog(LOG_ERR, "Write to offset %ld failed %s\n", + syslog(LOG_ERR, "Write to offset %" PRIdOFF " failed %s\n", off, strerror(errno)); return ERROR; } @@ -195,15 +197,16 @@ int flash_partition_read(int fd, void *buf, size_t count, off_t off) pos = lseek(fd, off, SEEK_SET); if (pos != off) { - syslog(LOG_ERR, "Could not seek to %ld: %s\n", off, strerror(errno)); + syslog(LOG_ERR, "Could not seek to %" PRIdOFF ": %s\n", + off, strerror(errno)); return ERROR; } nbytes = read(fd, buf, count); if (nbytes != count) { - syslog(LOG_ERR, "Read from offset %ld failed %s\n", off, - strerror(errno)); + syslog(LOG_ERR, "Read from offset %" PRIdOFF " failed %s\n", + off, strerror(errno)); return ERROR; } diff --git a/boot/nxboot/nxboot_main.c b/boot/nxboot/nxboot_main.c index ddc2f2284..976b03b4c 100644 --- a/boot/nxboot/nxboot_main.c +++ b/boot/nxboot/nxboot_main.c @@ -124,7 +124,7 @@ static const char *progress_msgs[] = ****************************************************************************/ #ifdef CONFIG_NXBOOT_PROGRESS -void nxboot_progress(enum progress_type_e type, ...) +void nxboot_progress(int type, ...) { #ifdef CONFIG_NXBOOT_PRINTF_PROGRESS va_list arg; From b5d151f73ffe0897011b299772705653827650ff Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Tue, 10 Mar 2026 09:45:33 +0800 Subject: [PATCH 255/568] cmake/tools: Fix panic_immediate_abort deprecation in Rust build Replace deprecated -Zbuild-std-features=panic_immediate_abort with -Cpanic=immediate-abort compiler flag via RUSTFLAGS. The panic_immediate_abort feature has been stabilized as a real panic strategy in recent Rust nightly versions. The old method of enabling it via -Zbuild-std-features is no longer supported and triggers a compile error in core/src/panicking.rs. Changes: * cmake/nuttx_add_rust.cmake: Use RUSTFLAGS with -Cpanic=immediate-abort * tools/Rust.mk: Use RUSTFLAGS with -Cpanic=immediate-abort Signed-off-by: Huang Qi --- cmake/nuttx_add_rust.cmake | 10 +++++----- tools/Rust.mk | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/nuttx_add_rust.cmake b/cmake/nuttx_add_rust.cmake index 97ecdcec7..d50482ef7 100644 --- a/cmake/nuttx_add_rust.cmake +++ b/cmake/nuttx_add_rust.cmake @@ -128,10 +128,10 @@ function(nuttx_add_rust) # Determine build profile based on CONFIG_DEBUG_FULLOPT if(CONFIG_DEBUG_FULLOPT) set(RUST_PROFILE "release") - set(RUST_DEBUG_FLAGS "-Zbuild-std-features=panic_immediate_abort") + set(RUST_PANIC_FLAGS "-Zunstable-options -Cpanic=immediate-abort") else() set(RUST_PROFILE "debug") - set(RUST_DEBUG_FLAGS "") + set(RUST_PANIC_FLAGS "") endif() # Get the Rust target triple @@ -152,9 +152,9 @@ function(nuttx_add_rust) COMMAND ${CMAKE_COMMAND} -E env NUTTX_INCLUDE_DIR=${PROJECT_SOURCE_DIR}/include:${CMAKE_BINARY_DIR}/include:${CMAKE_BINARY_DIR}/include/arch - cargo build --${RUST_PROFILE} -Zbuild-std=std,panic_abort - ${RUST_DEBUG_FLAGS} --manifest-path ${CRATE_PATH}/Cargo.toml --target - ${RUST_TARGET} --target-dir ${RUST_BUILD_DIR} + RUSTFLAGS=${RUST_PANIC_FLAGS} cargo build --${RUST_PROFILE} + -Zbuild-std=std,panic_abort --manifest-path ${CRATE_PATH}/Cargo.toml + --target ${RUST_TARGET} --target-dir ${RUST_BUILD_DIR} COMMENT "Building Rust crate ${CRATE_NAME}" VERBATIM) diff --git a/tools/Rust.mk b/tools/Rust.mk index 9a77ae57b..ad2fb3a82 100644 --- a/tools/Rust.mk +++ b/tools/Rust.mk @@ -90,8 +90,8 @@ endef ifeq ($(CONFIG_DEBUG_FULLOPT),y) define RUST_CARGO_BUILD NUTTX_INCLUDE_DIR=$(TOPDIR)/include:$(TOPDIR)/include/arch \ + RUSTFLAGS="-Zunstable-options -Cpanic=immediate-abort" \ cargo build --release -Zbuild-std=std,panic_abort \ - -Zbuild-std-features=panic_immediate_abort \ --manifest-path $(2)/$(1)/Cargo.toml \ --target $(call RUST_TARGET_TRIPLE) endef From 68f9e5424b45096361d2bc45e31fe7f278a4dd12 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Tue, 10 Mar 2026 10:18:37 +0800 Subject: [PATCH 256/568] codespell: Add ARCHTYPE to ignore list ARCHTYPE is a valid abbreviation for 'architecture type' used consistently across the codebase. This matches the nuttx repo's .codespellrc configuration. Signed-off-by: Huang Qi --- .codespellrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.codespellrc b/.codespellrc index ac22a4c37..c2a1ecdfc 100644 --- a/.codespellrc +++ b/.codespellrc @@ -10,4 +10,4 @@ skip = LICENSE, # Ignore words list (FTP protocol commands and technical terms) -ignore-words-list = ALLO +ignore-words-list = ALLO, ARCHTYPE From f90e1e184ff5eefe147f1386cf172058b50ff98a Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Fri, 13 Mar 2026 14:29:19 +0800 Subject: [PATCH 257/568] tools/build: Make Rust target triples for x86 use JSON files X86 support for Rust needs more test and verification, and not upstreamed to Rust side yet. It's better to use custom target triples for x86 by json files for now, and it can be upstreamed to Rust side if stable enough. Changed the Rust target triples in the CMake configuration to reference JSON files for x86_64 and i486 architectures. This improves the build process by providing more detailed target specifications. * Added JSON files for i486 and x86_64 targets * Updated CMake functions to use the new target triples * Enhanced build directory structure for Rust crates Signed-off-by: Huang Qi --- cmake/nuttx_add_rust.cmake | 18 +++++++++++------ tools/Rust.mk | 8 +++++--- tools/i486-unknown-nuttx.json | 33 ++++++++++++++++++++++++++++++ tools/x86_64-unknown-nuttx.json | 36 +++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 tools/i486-unknown-nuttx.json create mode 100644 tools/x86_64-unknown-nuttx.json diff --git a/cmake/nuttx_add_rust.cmake b/cmake/nuttx_add_rust.cmake index d50482ef7..0d1f09839 100644 --- a/cmake/nuttx_add_rust.cmake +++ b/cmake/nuttx_add_rust.cmake @@ -48,9 +48,9 @@ include(nuttx_parse_function_args) function(nuttx_rust_target_triple ARCHTYPE ABITYPE CPUTYPE OUTPUT) if(ARCHTYPE STREQUAL "x86_64") - set(TARGET_TRIPLE "x86_64-unknown-nuttx") + set(TARGET_TRIPLE "${APPDIR}/tools/x86_64-unknown-nuttx.json") elseif(ARCHTYPE STREQUAL "x86") - set(TARGET_TRIPLE "i686-unknown-nuttx") + set(TARGET_TRIPLE "${APPDIR}/tools/i486-unknown-nuttx.json") elseif(ARCHTYPE MATCHES "thumb") if(ARCHTYPE MATCHES "thumbv8m") # Extract just the base architecture type (thumbv8m.main or thumbv8m.base) @@ -138,10 +138,16 @@ function(nuttx_add_rust) nuttx_rust_target_triple(${LLVM_ARCHTYPE} ${LLVM_ABITYPE} ${LLVM_CPUTYPE} RUST_TARGET) - # Set up build directory in current binary dir - set(RUST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CRATE_NAME}) - set(RUST_LIB_PATH - ${RUST_BUILD_DIR}/${RUST_TARGET}/${RUST_PROFILE}/lib${CRATE_NAME}.a) + # Get binary directory path using target triple base name if it's a JSON file + if(RUST_TARGET MATCHES ".json$") + get_filename_component(TARGET_BASE ${RUST_TARGET} NAME_WE) + else() + set(TARGET_BASE ${RUST_TARGET}) + endif() + + set(RUST_BUILD_DIR + ${CMAKE_CURRENT_BINARY_DIR}/${CRATE_NAME}/target/${TARGET_BASE}) + set(RUST_LIB_PATH ${RUST_BUILD_DIR}/${RUST_PROFILE}/lib${CRATE_NAME}.a) # Create build directory file(MAKE_DIRECTORY ${RUST_BUILD_DIR}) diff --git a/tools/Rust.mk b/tools/Rust.mk index ad2fb3a82..8e037aef6 100644 --- a/tools/Rust.mk +++ b/tools/Rust.mk @@ -47,10 +47,10 @@ define RUST_TARGET_TRIPLE $(or \ $(and $(filter x86_64,$(LLVM_ARCHTYPE)), \ - x86_64-unknown-nuttx \ + $(APPDIR)/tools/x86_64-unknown-nuttx.json \ ), \ $(and $(filter x86,$(LLVM_ARCHTYPE)), \ - i686-unknown-nuttx \ + $(APPDIR)/tools/i486-unknown-nuttx.json \ ), \ $(and $(filter thumb%,$(LLVM_ARCHTYPE)), \ $(if $(filter thumbv8m%,$(LLVM_ARCHTYPE)), \ @@ -132,5 +132,7 @@ endef # Path to the Rust binary (e.g. path/to/project/target/riscv32imac-unknown-nuttx-elf/release/libhello.a) define RUST_GET_BINDIR -$(2)/$(1)/target/$(strip $(call RUST_TARGET_TRIPLE))/$(if $(CONFIG_DEBUG_FULLOPT),release,debug)/lib$(1).a +$(2)/$(1)/target/$(strip $(if $(findstring .json,$(call RUST_TARGET_TRIPLE)), \ + $(basename $(notdir $(call RUST_TARGET_TRIPLE))), \ + $(call RUST_TARGET_TRIPLE)))/$(if $(CONFIG_DEBUG_FULLOPT),release,debug)/lib$(1).a endef diff --git a/tools/i486-unknown-nuttx.json b/tools/i486-unknown-nuttx.json new file mode 100644 index 000000000..8d52aa161 --- /dev/null +++ b/tools/i486-unknown-nuttx.json @@ -0,0 +1,33 @@ +{ + "arch": "x86", + "cpu": "i486", + "crt-objects-fallback": "false", + "data-layout": "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128", + "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float", + "default-dwarf-version": 2, + "dynamic-linking": true, + "has-rpath": true, + "has-thread-local": true, + "linker-flavor": "gnu-lld", + "llvm-target": "i486-unknown-nuttx", + "max-atomic-width": 64, + "metadata": { + "description": "32-bit x86, resricted to i486", + "host_tools": false, + "std": true, + "tier": 3 + }, + "no-default-libraries": true, + "os": "nuttx", + "position-independent-executables": false, + "relro-level": "full", + "rustc-abi": "x86-softfloat", + "stack-probes": { + "kind": "inline" + }, + "target-family": [ + "unix" + ], + "target-mcount": "__mcount", + "target-pointer-width": "32" +} diff --git a/tools/x86_64-unknown-nuttx.json b/tools/x86_64-unknown-nuttx.json new file mode 100644 index 000000000..4a5b84901 --- /dev/null +++ b/tools/x86_64-unknown-nuttx.json @@ -0,0 +1,36 @@ +{ + "arch": "x86_64", + "cpu": "x86-64", + "crt-objects-fallback": "false", + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", + "disable-redzone": true, + "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float", + "linker": "rust-lld", + "linker-flavor": "gnu-lld", + "llvm-target": "x86_64-unknown-nuttx", + "max-atomic-width": 64, + "metadata": { + "description": "x86_64 target for NuttX RTOS with softfloat", + "host_tools": false, + "std": true, + "tier": 3 + }, + "panic-strategy": "abort", + "plt-by-default": false, + "position-independent-executables": true, + "relro-level": "full", + "rustc-abi": "x86-softfloat", + "stack-probes": { + "kind": "inline" + }, + "static-position-independent-executables": true, + "supported-sanitizers": [ + "kcfi", + "kernel-address" + ], + "os": "nuttx", + "target-family": [ + "unix" + ], + "target-pointer-width": "64" +} \ No newline at end of file From ea22a66dcf22baff5013d7c5073d59b33499b809 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Fri, 13 Mar 2026 14:29:37 +0800 Subject: [PATCH 258/568] tools: Fix target-pointer-width type in x86 target configs Remove quotes around target-pointer-width values in i486 and x86_64 target configuration files to change from string to numeric type. This change is required due to recent rustc JSON format modifications that expect numeric values instead of strings for target-pointer-width. Signed-off-by: Huang Qi --- tools/i486-unknown-nuttx.json | 2 +- tools/x86_64-unknown-nuttx.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/i486-unknown-nuttx.json b/tools/i486-unknown-nuttx.json index 8d52aa161..93cd43418 100644 --- a/tools/i486-unknown-nuttx.json +++ b/tools/i486-unknown-nuttx.json @@ -29,5 +29,5 @@ "unix" ], "target-mcount": "__mcount", - "target-pointer-width": "32" + "target-pointer-width": 32 } diff --git a/tools/x86_64-unknown-nuttx.json b/tools/x86_64-unknown-nuttx.json index 4a5b84901..d12fecb8a 100644 --- a/tools/x86_64-unknown-nuttx.json +++ b/tools/x86_64-unknown-nuttx.json @@ -32,5 +32,5 @@ "target-family": [ "unix" ], - "target-pointer-width": "64" + "target-pointer-width": 64 } \ No newline at end of file From 3a156581ca4de611c221f97815e10c842f993913 Mon Sep 17 00:00:00 2001 From: Filipe Cavalcanti Date: Wed, 11 Mar 2026 16:07:39 -0300 Subject: [PATCH 259/568] examples/rmtchar: fix source file ordering for RMTCHAR rmtchar_main.c is coming after rmtchar_common.c, which causes an undefined reference error. This change fixes the problem. Signed-off-by: Filipe Cavalcanti --- examples/rmtchar/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rmtchar/CMakeLists.txt b/examples/rmtchar/CMakeLists.txt index 0d03174f5..a01ebe080 100644 --- a/examples/rmtchar/CMakeLists.txt +++ b/examples/rmtchar/CMakeLists.txt @@ -29,8 +29,8 @@ if(CONFIG_EXAMPLES_RMTCHAR) MODULE ${CONFIG_EXAMPLES_RMTCHAR} SRCS - rmtchar_common.c rmtchar_main.c) + target_sources(apps PRIVATE rmtchar_common.c) if(CONFIG_EXAMPLES_RMTCHAR_TX) target_sources(apps PRIVATE rmtchar_transmitter.c) endif() From 10056077f4f0c6f7d7f4e8638eac810073dfaea8 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Mon, 16 Mar 2026 20:18:18 +0800 Subject: [PATCH 260/568] examples/camera: fix build error and still capture logic Add missing #include in camera_bkgd.c to fix implicit declaration of boardctl() and undeclared BOARDIOC_NX_START. Also fix capture_num check in camera_main.c to only apply still capture size enumeration when capture_type is STILL_CAPTURE. Signed-off-by: wangjianyu3 --- examples/camera/camera_bkgd.c | 1 + examples/camera/camera_main.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/camera/camera_bkgd.c b/examples/camera/camera_bkgd.c index c53b11ab8..4703b1ea5 100644 --- a/examples/camera/camera_bkgd.c +++ b/examples/camera/camera_bkgd.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/examples/camera/camera_main.c b/examples/camera/camera_main.c index 43f1fff9d..32ad1a460 100644 --- a/examples/camera/camera_main.c +++ b/examples/camera/camera_main.c @@ -537,7 +537,7 @@ int main(int argc, FAR char *argv[]) * And all allocated memorys are VIDIOC_QBUFed. */ - if (capture_num != 0) + if (capture_num != 0 && capture_type == V4L2_BUF_TYPE_STILL_CAPTURE) { /* Determine image size from connected image sensor name, * because video driver does not support VIDIOC_ENUM_FRAMESIZES From 8cd9e9acc23d35a8bcc5f38e7f49cbb05951675e Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Mon, 16 Mar 2026 20:31:54 +0800 Subject: [PATCH 261/568] examples/camera: fix spelling errors Fix typos found by codespell: - camera_bkgd.c: defaul -> default - camera_main.c: memorys -> memories (2 occurrences) - camera_main.c: freame -> frame - camera_main.c: valiable -> variable Signed-off-by: wangjianyu3 --- examples/camera/camera_bkgd.c | 2 +- examples/camera/camera_main.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/camera/camera_bkgd.c b/examples/camera/camera_bkgd.c index 4703b1ea5..aa1464471 100644 --- a/examples/camera/camera_bkgd.c +++ b/examples/camera/camera_bkgd.c @@ -249,7 +249,7 @@ int nximage_initialize(void) } /* Start a separate thread to listen for server events. - * For simplicity, use defaul thread attribute. + * For simplicity, use default thread attribute. */ ret = pthread_create(&thread, NULL, nximage_listener, NULL); diff --git a/examples/camera/camera_main.c b/examples/camera/camera_main.c index 32ad1a460..a342008b5 100644 --- a/examples/camera/camera_main.c +++ b/examples/camera/camera_main.c @@ -534,7 +534,7 @@ int main(int argc, FAR char *argv[]) * Set FULLHD size in ISX012 case, QUADVGA size in ISX019 case or other * image sensors, * Number of frame buffers is defined as STILL_BUFNUM(1). - * And all allocated memorys are VIDIOC_QBUFed. + * And all allocated memories are VIDIOC_QBUFed. */ if (capture_num != 0 && capture_type == V4L2_BUF_TYPE_STILL_CAPTURE) @@ -580,9 +580,9 @@ int main(int argc, FAR char *argv[]) * order from the captured frame buffer and a new camera image is * recaptured. * - * Allocate freame buffers for QVGA RGB565 size (320x240x2=150KB). + * Allocate frame buffers for QVGA RGB565 size (320x240x2=150KB). * Number of frame buffers is defined as VIDEO_BUFNUM(3). - * And all allocated memorys are VIDIOC_QBUFed. + * And all allocated memories are VIDIOC_QBUFed. */ ret = camera_prepare(v_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, @@ -603,7 +603,7 @@ int main(int argc, FAR char *argv[]) * * APP_STATE_UNDER_CAPTURE: * This state will start taking picture and store the image into files. - * Number of taking pictures is set capture_num valiable. + * Number of taking pictures is set capture_num variable. * It can be changed by command line argument. * After finishing taking pictures, the state will be changed to * APP_STATE_AFTER_CAPTURE. From 4decc1699a18cc81f4b72837626fa32a1059b9fd Mon Sep 17 00:00:00 2001 From: Neil Berkman Date: Tue, 17 Mar 2026 15:39:02 -0700 Subject: [PATCH 262/568] boot/nxboot: add flush barriers and CRC-validate primary before boot Two hardening fixes for nxboot power-loss resilience: 1. Add flash_partition_flush() calls between critical partition operations in perform_update(). Without explicit flush barriers, writes may remain buffered in RAM (e.g. via FTL rwbuffer) when nxboot proceeds to the next phase. A power loss between phases can leave the recovery image uncommitted while the staging partition has already been consumed. Flush points added: - After copy_partition(primary, recovery) completes - After copy_partition(update, primary) completes, before erasing the staging first sector 2. Replace validate_image_header() with validate_image() in the final primary validation path of nxboot_perform_update(). The header-only check validates magic and platform identifier but does not CRC-check the image body. After an interrupted update, a corrupt primary with an intact header would pass this check and be booted, resulting in a persistent boot failure. Signed-off-by: Neil Berkman --- boot/nxboot/loader/boot.c | 6 ++++-- boot/nxboot/loader/flash.c | 20 ++++++++++++++++++++ boot/nxboot/loader/flash.h | 16 ++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/boot/nxboot/loader/boot.c b/boot/nxboot/loader/boot.c index 6de9659ac..8bcd24cef 100644 --- a/boot/nxboot/loader/boot.c +++ b/boot/nxboot/loader/boot.c @@ -417,6 +417,7 @@ static int perform_update(struct nxboot_state *state, bool check_only) syslog(LOG_INFO, "Creating recovery image.\n"); nxboot_progress(nxboot_progress_start, recovery_create); copy_partition(primary, recovery, state, false); + flash_partition_flush(recovery); nxboot_progress(nxboot_progress_end); nxboot_progress(nxboot_progress_start, validate_recovery); successful = validate_image(recovery); @@ -444,6 +445,8 @@ static int perform_update(struct nxboot_state *state, bool check_only) nxboot_progress(nxboot_progress_start, update_from_update); if (copy_partition(update, primary, state, true) >= 0) { + flash_partition_flush(primary); + /* Erase the first sector of update partition. This marks the * partition as updated so we don't end up in an update loop. * The sector is written back again during the image @@ -919,8 +922,7 @@ int nxboot_perform_update(bool check_only) return ERROR; } - get_image_header(primary, &header); - if (!validate_image_header(&header)) + if (!validate_image(primary)) { ret = ERROR; } diff --git a/boot/nxboot/loader/flash.c b/boot/nxboot/loader/flash.c index f1a359573..ab6a24320 100644 --- a/boot/nxboot/loader/flash.c +++ b/boot/nxboot/loader/flash.c @@ -76,6 +76,26 @@ int flash_partition_open(const char *path) return fd; } +/**************************************************************************** + * Name: flash_partition_flush + * + * Description: + * Flushes any buffered writes to the underlying storage. This ensures + * data is physically committed to flash before the caller proceeds. + * + * Input parameters: + * fd: Valid file descriptor. + * + * Returned Value: + * 0 on success, -1 on failure. + * + ****************************************************************************/ + +int flash_partition_flush(int fd) +{ + return fsync(fd); +} + /**************************************************************************** * Name: flash_partition_close * diff --git a/boot/nxboot/loader/flash.h b/boot/nxboot/loader/flash.h index ef1dee09d..69906490d 100644 --- a/boot/nxboot/loader/flash.h +++ b/boot/nxboot/loader/flash.h @@ -79,6 +79,22 @@ int flash_partition_open(const char *path); int flash_partition_close(int fd); +/**************************************************************************** + * Name: flash_partition_flush + * + * Description: + * Flushes any buffered writes to the underlying storage. + * + * Input parameters: + * fd: Valid file descriptor. + * + * Returned Value: + * 0 on success, -1 on failure. + * + ****************************************************************************/ + +int flash_partition_flush(int fd); + /**************************************************************************** * Name: flash_partition_write * From 83af0a011e17066c36223467614853f4647dc03d Mon Sep 17 00:00:00 2001 From: Neil Berkman Date: Wed, 18 Mar 2026 00:33:41 -0700 Subject: [PATCH 263/568] boot/nxboot: update stale comment to reflect CRC validation The comment previously stated CRC was not calculated before boot. This is no longer accurate after adding full image CRC validation in validate_image(). Signed-off-by: Neil Berkman --- boot/nxboot/loader/boot.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boot/nxboot/loader/boot.c b/boot/nxboot/loader/boot.c index 8bcd24cef..703148754 100644 --- a/boot/nxboot/loader/boot.c +++ b/boot/nxboot/loader/boot.c @@ -911,9 +911,9 @@ int nxboot_perform_update(bool check_only) } } - /* Check whether there is a valid image in the primary slot. This just - * checks whether the header is valid, but does not calculate the CRC - * of the image as this would prolong the boot process. + /* Check whether there is a valid image in the primary slot. Validates + * both the header and the full image CRC to ensure integrity before + * booting. */ primary = flash_partition_open(CONFIG_NXBOOT_PRIMARY_SLOT_PATH); From cb880b72578c9501710dacf74f2683ea8cfd8a51 Mon Sep 17 00:00:00 2001 From: Neil Berkman Date: Wed, 18 Mar 2026 00:42:13 -0700 Subject: [PATCH 264/568] boot/nxboot: remove unused header variable The header variable in nxboot_perform_update() is no longer used after validate_image() was changed to take only the fd. Signed-off-by: Neil Berkman --- boot/nxboot/loader/boot.c | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/nxboot/loader/boot.c b/boot/nxboot/loader/boot.c index 703148754..c4f936d23 100644 --- a/boot/nxboot/loader/boot.c +++ b/boot/nxboot/loader/boot.c @@ -887,7 +887,6 @@ int nxboot_perform_update(bool check_only) int ret; int primary; struct nxboot_state state; - struct nxboot_img_header header; ret = nxboot_get_state(&state); if (ret < 0) From 193fadfaa88bcdafccbef87e6b120404aa9c9f54 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Fri, 13 Mar 2026 11:49:18 +0100 Subject: [PATCH 265/568] logging/nxscope: add UDP transfer interface add UDP transfer interface for nxscope Signed-off-by: raiden00pl --- include/logging/nxscope/nxscope_intf.h | 25 +++ logging/nxscope/CMakeLists.txt | 4 + logging/nxscope/Kconfig | 6 + logging/nxscope/Makefile | 4 + logging/nxscope/nxscope_iudp.c | 271 +++++++++++++++++++++++++ 5 files changed, 310 insertions(+) create mode 100644 logging/nxscope/nxscope_iudp.c diff --git a/include/logging/nxscope/nxscope_intf.h b/include/logging/nxscope/nxscope_intf.h index b422e0d77..937619f3a 100644 --- a/include/logging/nxscope/nxscope_intf.h +++ b/include/logging/nxscope/nxscope_intf.h @@ -99,6 +99,16 @@ struct nxscope_ser_cfg_s }; #endif +#ifdef CONFIG_LOGGING_NXSCOPE_INTF_UDP +/* Nxscope UDP interface configuration */ + +struct nxscope_udp_cfg_s +{ + uint16_t port; /* Local UDP port */ + bool nonblock; /* Nonblocking operation */ +}; +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -133,6 +143,21 @@ int nxscope_ser_init(FAR struct nxscope_intf_s *intf, void nxscope_ser_deinit(FAR struct nxscope_intf_s *intf); #endif +#ifdef CONFIG_LOGGING_NXSCOPE_INTF_UDP +/**************************************************************************** + * Name: nxscope_udp_init + ****************************************************************************/ + +int nxscope_udp_init(FAR struct nxscope_intf_s *intf, + FAR struct nxscope_udp_cfg_s *cfg); + +/**************************************************************************** + * Name: nxscope_udp_deinit + ****************************************************************************/ + +void nxscope_udp_deinit(FAR struct nxscope_intf_s *intf); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/logging/nxscope/CMakeLists.txt b/logging/nxscope/CMakeLists.txt index 378ebefd5..98594accd 100644 --- a/logging/nxscope/CMakeLists.txt +++ b/logging/nxscope/CMakeLists.txt @@ -27,6 +27,10 @@ if(CONFIG_LOGGING_NXSCOPE) list(APPEND CSRCS nxscope_iser.c) endif() + if(CONFIG_LOGGING_NXSCOPE_INTF_UDP) + list(APPEND CSRCS nxscope_iudp.c) + endif() + if(CONFIG_LOGGING_NXSCOPE_INTF_DUMMY) list(APPEND CSRCS nxscope_idummy.c) endif() diff --git a/logging/nxscope/Kconfig b/logging/nxscope/Kconfig index 3649b25e9..bb187ea43 100644 --- a/logging/nxscope/Kconfig +++ b/logging/nxscope/Kconfig @@ -15,6 +15,12 @@ config LOGGING_NXSCOPE_INTF_SERIAL ---help--- For details, see logging/nxscope/nxscope_iserial.c +config LOGGING_NXSCOPE_INTF_UDP + bool "NxScope UDP interface support" + default n + ---help--- + For details, see logging/nxscope/nxscope_iudp.c + config LOGGING_NXSCOPE_INTF_DUMMY bool "NxScope dummy interface support" default n diff --git a/logging/nxscope/Makefile b/logging/nxscope/Makefile index 3e45148fc..c8fc05489 100644 --- a/logging/nxscope/Makefile +++ b/logging/nxscope/Makefile @@ -34,6 +34,10 @@ ifeq ($(CONFIG_LOGGING_NXSCOPE_INTF_DUMMY),y) CSRCS += nxscope_idummy.c endif +ifeq ($(CONFIG_LOGGING_NXSCOPE_INTF_UDP),y) +CSRCS += nxscope_iudp.c +endif + ifeq ($(CONFIG_LOGGING_NXSCOPE_PROTO_SER),y) CSRCS += nxscope_pser.c endif diff --git a/logging/nxscope/nxscope_iudp.c b/logging/nxscope/nxscope_iudp.c new file mode 100644 index 000000000..07aae7711 --- /dev/null +++ b/logging/nxscope/nxscope_iudp.c @@ -0,0 +1,271 @@ +/**************************************************************************** + * apps/logging/nxscope/nxscope_iudp.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct nxscope_intf_udp_s +{ + FAR struct nxscope_udp_cfg_s *cfg; + int fd; + bool peer_valid; + struct sockaddr_in peer; +}; + +/**************************************************************************** + * Private Function Protototypes + ****************************************************************************/ + +static int nxscope_udp_send(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len); +static int nxscope_udp_recv(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct nxscope_intf_ops_s g_nxscope_udp_ops = +{ + nxscope_udp_send, + nxscope_udp_recv +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_udp_send + ****************************************************************************/ + +static int nxscope_udp_send(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len) +{ + FAR struct nxscope_intf_udp_s *priv = NULL; + + DEBUGASSERT(intf); + DEBUGASSERT(intf->priv); + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_udp_s *)intf->priv; + + if (!priv->peer_valid) + { + return -ENOTCONN; + } + + return sendto(priv->fd, buff, len, 0, + (FAR const struct sockaddr *)&priv->peer, + sizeof(priv->peer)); +} + +/**************************************************************************** + * Name: nxscope_udp_recv + ****************************************************************************/ + +static int nxscope_udp_recv(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len) +{ + FAR struct nxscope_intf_udp_s *priv = NULL; + struct sockaddr_in from; + socklen_t fromlen; + int ret = OK; + + DEBUGASSERT(intf); + DEBUGASSERT(intf->priv); + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_udp_s *)intf->priv; + + fromlen = sizeof(from); + ret = recvfrom(priv->fd, buff, len, 0, (FAR struct sockaddr *)&from, + &fromlen); + + if (ret < 0) + { + if (priv->cfg->nonblock && (errno == EAGAIN || errno == EWOULDBLOCK)) + { + ret = 0; + } + + return ret; + } + + priv->peer = from; + priv->peer_valid = true; + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_udp_init + ****************************************************************************/ + +int nxscope_udp_init(FAR struct nxscope_intf_s *intf, + FAR struct nxscope_udp_cfg_s *cfg) +{ + FAR struct nxscope_intf_udp_s *priv = NULL; + struct sockaddr_in addr; + int ret = OK; + int flags = 0; + + DEBUGASSERT(intf); + DEBUGASSERT(cfg); + + /* Allocate priv data */ + + intf->priv = zalloc(sizeof(struct nxscope_intf_udp_s)); + if (intf->priv == NULL) + { + _err("ERROR: intf->priv alloc failed %d\n", errno); + ret = -errno; + goto errout; + } + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_udp_s *)intf->priv; + priv->fd = -1; + + /* Connect configuration */ + + priv->cfg = (FAR struct nxscope_udp_cfg_s *)cfg; + + /* Connect ops */ + + intf->ops = &g_nxscope_udp_ops; + + /* Open UDP socket */ + + priv->fd = socket(AF_INET, SOCK_DGRAM, 0); + if (priv->fd < 0) + { + _err("ERROR: failed to create UDP socket %d\n", errno); + ret = -errno; + goto errout; + } + + /* Configure non-blocking if enabled */ + + if (priv->cfg->nonblock) + { + flags = fcntl(priv->fd, F_GETFL, 0); + if (flags < 0) + { + _err("ERROR: failed to get socket flags %d\n", errno); + ret = -errno; + goto errout; + } + + ret = fcntl(priv->fd, F_SETFL, flags | O_NONBLOCK); + if (ret < 0) + { + _err("ERROR: failed to set O_NONBLOCK %d\n", errno); + ret = -errno; + goto errout; + } + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(priv->cfg->port); + + ret = bind(priv->fd, (FAR struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) + { + _err("ERROR: failed to bind UDP port %u errno=%d\n", + priv->cfg->port, + errno); + ret = -errno; + goto errout; + } + + /* Initialized */ + + intf->initialized = true; + return OK; + +errout: + if (priv != NULL && priv->fd >= 0) + { + close(priv->fd); + priv->fd = -1; + } + + return ret; +} + +/**************************************************************************** + * Name: nxscope_udp_deinit + ****************************************************************************/ + +void nxscope_udp_deinit(FAR struct nxscope_intf_s *intf) +{ + FAR struct nxscope_intf_udp_s *priv = NULL; + + DEBUGASSERT(intf); + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_udp_s *)intf->priv; + + if (priv != NULL && priv->fd != -1) + { + close(priv->fd); + } + + if (priv != NULL) + { + free(priv); + } + + /* Reset structure */ + + memset(intf, 0, sizeof(struct nxscope_intf_s)); +} From 7884410be2d18957d7ee951f42cfd8d62d79d44d Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 16 Mar 2026 13:56:01 +0100 Subject: [PATCH 266/568] examples/nxscope: add UDP interface add UDP interface for examples/nxscope Signed-off-by: raiden00pl --- examples/nxscope/Kconfig | 9 +++++++++ examples/nxscope/nxscope_main.c | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/examples/nxscope/Kconfig b/examples/nxscope/Kconfig index b29f97f26..49d36f270 100644 --- a/examples/nxscope/Kconfig +++ b/examples/nxscope/Kconfig @@ -43,6 +43,15 @@ config EXAMPLES_NXSCOPE_CDCACM endif # LOGGING_NXSCOPE_INTF_SERIAL +if LOGGING_NXSCOPE_INTF_UDP + +config EXAMPLES_NXSCOPE_UDP_PORT + int "nxscope UDP local port" + default 50000 + range 1 65535 + +endif # LOGGING_NXSCOPE_INTF_UDP + config EXAMPLES_NXSCOPE_FORCE_ENABLE bool "nxscope force enable" default n diff --git a/examples/nxscope/nxscope_main.c b/examples/nxscope/nxscope_main.c index b2311a74a..5d5102e99 100644 --- a/examples/nxscope/nxscope_main.c +++ b/examples/nxscope/nxscope_main.c @@ -431,6 +431,9 @@ int main(int argc, FAR char *argv[]) #ifdef CONFIG_LOGGING_NXSCOPE_INTF_SERIAL struct nxscope_ser_cfg_s nxs_ser_cfg; #endif +#ifdef CONFIG_LOGGING_NXSCOPE_INTF_UDP + struct nxscope_udp_cfg_s nxs_udp_cfg; +#endif #ifdef CONFIG_LOGGING_NXSCOPE_INTF_DUMMY struct nxscope_dummy_cfg_s nxs_dummy_cfg; #endif @@ -484,6 +487,22 @@ int main(int argc, FAR char *argv[]) } #endif +#ifdef CONFIG_LOGGING_NXSCOPE_INTF_UDP + /* Configuration */ + + nxs_udp_cfg.port = CONFIG_EXAMPLES_NXSCOPE_UDP_PORT; + nxs_udp_cfg.nonblock = true; + + /* Initialize UDP interface */ + + ret = nxscope_udp_init(&intf, &nxs_udp_cfg); + if (ret < 0) + { + printf("ERROR: nxscope_udp_init failed %d\n", ret); + goto errout_nointf; + } +#endif + #ifdef CONFIG_LOGGING_NXSCOPE_INTF_DUMMY /* Configuration */ @@ -733,6 +752,9 @@ errout_nonxscope: #if defined(CONFIG_LOGGING_NXSCOPE_INTF_SERIAL) nxscope_ser_deinit(&intf); #endif +#if defined(CONFIG_LOGGING_NXSCOPE_INTF_UDP) + nxscope_udp_deinit(&intf); +#endif #if defined(CONFIG_LOGGING_NXSCOPE_INTF_DUMMY) nxscope_dummy_deinit(&intf); #endif From 5fe08779897d1a566d7b555ea85131c2608a868f Mon Sep 17 00:00:00 2001 From: Lup Yuen Lee Date: Sun, 22 Mar 2026 08:02:39 +0800 Subject: [PATCH 267/568] CI: Revert GitHub Actions for Docker All CI Builds have been failing since 18 hours ago: - https://github.com/apache/nuttx/pull/18571#issuecomment-4104792750 - https://github.com/apache/nuttx/actions/runs/23389990049 > _The action docker/login-action@v4 is not allowed in apache/nuttx because all actions must be from a repository owned by your enterprise, created by GitHub, or match one of the patterns: 1Password/load-secrets-action@13f58eec611f8e5db52ec16247f58c508398f3e6, 1Password/load-secrets-action@8d0d610af187e78a2772c2d18d627f4c52d3fbfb, 1Password/load-secrets-action@dafbe7cb03502b260e2b2893c753c352eee545bf, AdoptOpenJDK/install-jdk@*, BobAnkh/auto-generate-changelog@*, DavidAnson/markdownlint-cli2-action@07035fd053f7be764496c0f8d8f9f41f98305101, DavidAnson/markdownlint-cli2-action@30a0e04f1870d58f8d717450cc6134995f993c63, EnricoMi/publish-unit-test-result-action@*, JamesIves/github-pages-deploy-action@4a3abc783e1a24aeb44c16e869ad83caf6b4cc23, JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f, Jimver/cuda-toolkit@6008063726ffe3309d1b22e413d9e88fed91a2f2, Jimver/cuda-toolkit@b6fc3a9f3f15256d9d94ffe1254f9c5a2565cde6, JustinBeckwith/linkinator-action@af984b9f30f63e796..._ That's because ASF Infrastructure Team has mandated that we use the Hash Versions of GitHub Actions for Docker, stated below: - https://github.com/apache/infrastructure-actions/blob/main/actions.yml - Which generates: https://github.com/apache/infrastructure-actions/blob/main/approved_patterns.yml - Due to: https://github.com/apache/infrastructure-actions/pull/547 ```yaml docker/build-push-action: 10e90e3645eae34f1e60eeb005ba3a3d33f178e8: tag: v6.19.2 docker/login-action: c94ce9fb468520275223c153574b00df6fe4bcc9: tag: v3.7.0 docker/metadata-action: c299e40c65443455700f0fdfc63efafe5b349051: tag: v5.10.0 docker/setup-buildx-action: 8d2750c68a42422c14e847fe6c8ac0403b4cbd6f: tag: v3.12.0 ``` This PR reverts our GitHub Actions for Docker to the hash versions stated above. Signed-off-by: Lup Yuen Lee --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cc12b797d..6c4a7367e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -163,7 +163,7 @@ jobs: run: tar zxf sources.tar.gz - name: Docker Login - uses: docker/login-action@v4 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -246,7 +246,7 @@ jobs: run: tar zxf sources.tar.gz - name: Docker Login - uses: docker/login-action@v4 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: registry: ghcr.io username: ${{ github.actor }} From b986eef7a71b0932ee23349afaf63e7b7d0758bc Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sun, 22 Mar 2026 10:59:13 +0100 Subject: [PATCH 268/568] system/sensorscope: fix compilation fix compilation error: sensorscope_main.c:314:3: error: implicit declaration of function 'list_initialize'; did you mean 'fs_initialize'? [-Wimplicit-function-declaration] Signed-off-by: raiden00pl --- system/sensorscope/sensorscope_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/sensorscope/sensorscope_main.c b/system/sensorscope/sensorscope_main.c index 2248afaec..2c8f2ecbe 100644 --- a/system/sensorscope/sensorscope_main.c +++ b/system/sensorscope/sensorscope_main.c @@ -26,6 +26,7 @@ #include +#include #include #include @@ -58,7 +59,7 @@ struct nxsensor_info_s FAR const char *name; size_t data_size; /* Sensor read data size */ size_t data_offset; /* Read data offset (no timestamp) */ - size_t dim; /* Data vector dimenstion */ + size_t dim; /* Data vector dimension */ int dtype; /* Data vector type */ }; @@ -313,7 +314,7 @@ static int nxscope_channels(FAR struct nxscope_thr_env_s *envp) list_initialize(&envp->objlist); - /* Open sensors direcotry */ + /* Open sensors directory */ dir = opendir(SENSOR_PATH); if (!dir) From 460281a90f8356dc5d25d9fee110550c59a7c2ff Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Fri, 20 Mar 2026 13:53:36 +0800 Subject: [PATCH 269/568] system/fastboot: fix socket() parameter order for TCP transport SOCK_CLOEXEC and SOCK_NONBLOCK were incorrectly passed as the third argument (protocol) instead of being OR'd into the second argument (type). This caused socket() to fail with EPROTONOSUPPORT (errno 93) on NuttX. Move SOCK_CLOEXEC | SOCK_NONBLOCK to the type parameter and set protocol to 0. Signed-off-by: wangjianyu3 --- system/fastboot/fastboot.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/fastboot/fastboot.c b/system/fastboot/fastboot.c index 4ba39b5d3..d443bb9c8 100644 --- a/system/fastboot/fastboot.c +++ b/system/fastboot/fastboot.c @@ -1295,8 +1295,9 @@ static int fastboot_tcp_initialize(FAR struct fastboot_ctx_s *ctx) netinit_bringup(); #endif - ctx->tran_fd[0] = socket(AF_INET, SOCK_STREAM, - SOCK_CLOEXEC | SOCK_NONBLOCK); + ctx->tran_fd[0] = socket(AF_INET, + SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, + 0); if (ctx->tran_fd[0] < 0) { fb_err("create socket failed %d", errno); From 509b8074620e47aa08d87a7ad13ce34a73c1984d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 22:22:50 +0000 Subject: [PATCH 270/568] build(deps): bump docker/login-action from 3.7.0 to 4.0.0 Bumps [docker/login-action](https://github.com/docker/login-action) from 3.7.0 to 4.0.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/c94ce9fb468520275223c153574b00df6fe4bcc9...b45d80f862d83dbcd57f89517bcf500b2ab88fb2) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6c4a7367e..95ba5d943 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -163,7 +163,7 @@ jobs: run: tar zxf sources.tar.gz - name: Docker Login - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -246,7 +246,7 @@ jobs: run: tar zxf sources.tar.gz - name: Docker Login - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: registry: ghcr.io username: ${{ github.actor }} From 6a1b2c69035ee1ad54b366586d34f64ebb406f22 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Wed, 18 Mar 2026 11:15:45 +0800 Subject: [PATCH 271/568] system/nxrecorder: Fix null pointer dereference in argument parsing When a command has no arguments (e.g., 'q', 'quit', 'stop'), the strtok_r() function returns NULL for the arg parameter. The argument trimming loop was dereferencing this NULL pointer without checking, causing undefined behavior and system hang on ESP32-S3. This commit adds a null check before dereferencing the arg pointer in the leading space trimming loop. Tested on ESP32-S3 (lckfb-szpi-esp32s3) - quit command now works correctly. Signed-off-by: wangjianyu3 --- system/nxrecorder/nxrecorder_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/nxrecorder/nxrecorder_main.c b/system/nxrecorder/nxrecorder_main.c index 8ba3ad4b4..a8a4c63d6 100644 --- a/system/nxrecorder/nxrecorder_main.c +++ b/system/nxrecorder/nxrecorder_main.c @@ -588,7 +588,7 @@ int main(int argc, FAR char *argv[]) /* Remove leading spaces from arg */ - while (*arg == ' ') + while (arg && *arg == ' ') { arg++; } From f3a7282230bdd1c3f09148d6bc5cc1acd9fd3e4a Mon Sep 17 00:00:00 2001 From: Filipe Cavalcanti Date: Tue, 24 Mar 2026 14:57:03 -0300 Subject: [PATCH 272/568] netutils/cjson: fix apps path in CMake Fix mismatch on apps directory naming when it is cloned under 'nuttx-apps' instead of 'apps'. Signed-off-by: Filipe Cavalcanti --- netutils/cjson/CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/netutils/cjson/CMakeLists.txt b/netutils/cjson/CMakeLists.txt index 729dbc619..315326793 100644 --- a/netutils/cjson/CMakeLists.txt +++ b/netutils/cjson/CMakeLists.txt @@ -40,7 +40,7 @@ if(CONFIG_NETUTILS_CJSON) SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/cJSON BINARY_DIR - ${CMAKE_BINARY_DIR}/apps/netutils/cjson/cJSON + ${NUTTX_APPS_BINDIR}/netutils/cjson/cJSON DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -51,13 +51,13 @@ if(CONFIG_NETUTILS_CJSON) endif() endif() - if(NOT EXISTS ${CMAKE_BINARY_DIR}/apps/include/netutils/cJSON.h - OR NOT EXISTS ${CMAKE_BINARY_DIR}/apps/include/netutils/cJSON_Utils.h) - file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/apps/include/netutils) + if(NOT EXISTS ${NUTTX_APPS_BINDIR}/include/netutils/cJSON.h + OR NOT EXISTS ${NUTTX_APPS_BINDIR}/include/netutils/cJSON_Utils.h) + file(MAKE_DIRECTORY ${NUTTX_APPS_BINDIR}/include/netutils) file(CREATE_LINK ${CMAKE_CURRENT_LIST_DIR}/cJSON/cJSON.h - ${CMAKE_BINARY_DIR}/apps/include/netutils/cJSON.h SYMBOLIC) + ${NUTTX_APPS_BINDIR}/include/netutils/cJSON.h SYMBOLIC) file(CREATE_LINK ${CMAKE_CURRENT_LIST_DIR}/cJSON/cJSON_Utils.h - ${CMAKE_BINARY_DIR}/apps/include/netutils/cJSON_Utils.h SYMBOLIC) + ${NUTTX_APPS_BINDIR}/include/netutils/cJSON_Utils.h SYMBOLIC) endif() target_sources(apps PRIVATE cJSON/cJSON.c cJSON/cJSON_Utils.c) From e564816e1d931edb2cd01d7202511ec0a8fbd068 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Fri, 27 Mar 2026 10:41:40 +0100 Subject: [PATCH 273/568] .github: install NTFC from PIP install NTFC package from PIP Signed-off-by: raiden00pl --- .github/workflows/build.yml | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 95ba5d943..34cc01a43 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -175,42 +175,26 @@ jobs: - name: Export NuttX Repo SHA run: echo "nuttx_sha=`git -C sources/nuttx rev-parse HEAD`" >> $GITHUB_ENV - - name: Install NTFC - uses: ./sources/nuttx/.github/actions/ci-container - env: - BLOBDIR: /tools/blobs - with: - run: | - # install python venv - apt-get update - apt-get install -y python3 python3-dev python3-venv - - # get NTFC sources - git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-ntfc - cd /github/workspace/nuttx-ntfc - - # install NTFC with venv - python3 -m venv /github/workspace/nuttx-ntfc/venv - source /github/workspace/nuttx-ntfc/venv/bin/activate - pip3 install . - deactivate - - # get NTFC test cases - cd external - git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-testing - - name: Run builds uses: ./sources/nuttx/.github/actions/ci-container env: BLOBDIR: /tools/blobs with: run: | + pip install ntfc==0.0.1 + mkdir /github/workspace/nuttx-ntfc + mkdir /github/workspace/nuttx-ntfc/external + cd /github/workspace/nuttx-ntfc + # get NTFC test cases + cd external + git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-testing + echo "::add-matcher::sources/nuttx/.github/gcc.json" export ARTIFACTDIR=`pwd`/buildartifacts export NTFCDIR=/github/workspace/nuttx-ntfc git config --global --add safe.directory /github/workspace/sources/nuttx git config --global --add safe.directory /github/workspace/sources/apps - cd sources/nuttx/tools/ci + cd /github/workspace/sources/nuttx/tools/ci if [ "X${{matrix.boards}}" = "Xcodechecker" ]; then ./cibuild.sh -c -A -N -R --codechecker testlist/${{matrix.boards}}.dat else From cd2b0c0e877f718dca44ca7cc13586b655409fb8 Mon Sep 17 00:00:00 2001 From: Vlad Pruteanu Date: Thu, 26 Mar 2026 00:12:49 +0200 Subject: [PATCH 274/568] testing/crypto: Add pbkdf2 test app This adds support for testing PBKDF2 implementation. Test vectors for SHA1 are taken from RFC6070. SHA256 vectors were extrapolated using an online PBKDF2 generator which was checked against RFC6070. Signed-off-by: Vlad Pruteanu --- testing/drivers/crypto/CMakeLists.txt | 14 ++ testing/drivers/crypto/Kconfig | 4 + testing/drivers/crypto/Makefile | 5 + testing/drivers/crypto/pbkdf2.c | 278 ++++++++++++++++++++++++++ 4 files changed, 301 insertions(+) create mode 100644 testing/drivers/crypto/pbkdf2.c diff --git a/testing/drivers/crypto/CMakeLists.txt b/testing/drivers/crypto/CMakeLists.txt index 3918043a1..6e7fb369f 100644 --- a/testing/drivers/crypto/CMakeLists.txt +++ b/testing/drivers/crypto/CMakeLists.txt @@ -175,4 +175,18 @@ if(CONFIG_TESTING_CRYPTO) rsa.c) endif() + if(CONFIG_TESTING_CRYPTO_PBKDF2) + nuttx_add_application( + NAME + pbkdf2 + PRIORITY + ${CONFIG_TESTING_CRYPTO_PRIORITY} + STACKSIZE + ${CONFIG_TESTING_CRYPTO_STACKSIZE} + MODULE + ${CONFIG_TESTING_CRYPTO} + SRCS + pbkdf2.c) + endif() + endif() diff --git a/testing/drivers/crypto/Kconfig b/testing/drivers/crypto/Kconfig index 40983778a..18a4f3521 100644 --- a/testing/drivers/crypto/Kconfig +++ b/testing/drivers/crypto/Kconfig @@ -74,6 +74,10 @@ config TESTING_CRYPTO_RSA bool "rsa crypto test" default n +config TESTING_CRYPTO_PBKDF2 + bool "pbkdf2 crypto test" + default n + config TESTING_CRYPTO_PRIORITY int "crypto test task priority" default 100 diff --git a/testing/drivers/crypto/Makefile b/testing/drivers/crypto/Makefile index 64c6dfac7..82aeebef0 100644 --- a/testing/drivers/crypto/Makefile +++ b/testing/drivers/crypto/Makefile @@ -78,6 +78,11 @@ PROGNAME += rsa MAINSRC += rsa.c endif +ifeq ($(CONFIG_TESTING_CRYPTO_PBKDF2),y) +PROGNAME += pbkdf2 +MAINSRC += pbkdf2.c +endif + PRIORITY = $(CONFIG_TESTING_CRYPTO_PRIORITY) STACKSIZE = $(CONFIG_TESTING_CRYPTO_STACKSIZE) MODULE = $(CONFIG_TESTING_CRYPTO) diff --git a/testing/drivers/crypto/pbkdf2.c b/testing/drivers/crypto/pbkdf2.c new file mode 100644 index 000000000..10e7174ef --- /dev/null +++ b/testing/drivers/crypto/pbkdf2.c @@ -0,0 +1,278 @@ +/**************************************************************************** + * apps/testing/drivers/crypto/pbkdf2.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct tb +{ + FAR char *key; + int keylen; + FAR char *data; + int datalen; + int iterations; + int dklen; +} +pbkdf2_testcases[] = +{ + { + "password", + 8, + "salt", + 4, + 1, + 20, + }, + { + "password", + 8, + "salt", + 4, + 2, + 20, + }, + { + "password", + 8, + "salt", + 4, + 4096, + 20, + }, + { + "password", + 8, + "salt", + 4, + 16777216, + 20, + }, + { + "passwordPASSWORDpassword", + 24, + "saltSALTsaltSALTsaltSALTsaltSALTsalt", + 36, + 4096, + 25, + }, + { + "pass\0word", + 9, + "sa\0lt", + 5, + 4096, + 16, + }, +}; + +FAR char *pbkdf2_sha1_result[] = +{ + "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06" + "\x2f\xe0\x37\xa6", + "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0" + "\xd8\xde\x89\x57", + "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0" + "\x65\xa4\x29\xc1", + "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94\x5b\x3d\x6b\xa2\x15\x8c" + "\x26\x34\xe9\x84", + "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62\xc0\xe4\x4a" + "\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38", + "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34\x25\xe0\xc3", +}; + +FAR char *pbkdf2_sha256_result[] = +{ + "\x12\x0f\xb6\xcf\xfc\xf8\xb3\x2c\x43\xe7\x22\x52\x56\xc4\xf8\x37" + "\xa8\x65\x48\xc9", + "\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9\x28\xf0\x6d\xd0" + "\x2a\x30\x3f\x8e", + "\xc5\xe4\x78\xd5\x92\x88\xc8\x41\xaa\x53\x0d\xb6\x84\x5c\x4c\x8d" + "\x96\x28\x93\xa0", + "\xcf\x81\xc6\x6f\xe8\xcf\xc0\x4d\x1f\x31\xec\xb6\x5d\xab\x40\x89" + "\xf7\xf1\x79\xe8", + "\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11\x6e\x84\xcf" + "\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c", + "\x89\xb6\x9d\x05\x16\xf8\x29\x89\x3c\x69\x62\x26\x65\x0a\x86\x87", +}; + +int syspbkdf2(int mac, FAR const char *key, size_t keylen, + FAR const char *s, size_t len, int iterations, + size_t dklen, FAR char *out) +{ + struct session_op session; + struct crypt_op cryp; + int cryptodev_fd = -1; + int fd = -1; + + if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) + { + warn("/dev/crypto"); + goto err; + } + + if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) + { + warn("CRIOGET"); + goto err; + } + + memset(&session, 0, sizeof(session)); + session.cipher = 0; + session.mac = mac; + session.mackey = (caddr_t)key; + session.mackeylen = keylen; + if (ioctl(cryptodev_fd, CIOCGSESSION, &session) == -1) + { + warn("CIOCGSESSION"); + goto err; + } + memset(&cryp, 0, sizeof(cryp)); + cryp.ses = session.ses; + cryp.flags = 0; + cryp.src = (caddr_t)s; + cryp.len = len; + cryp.dst = 0; + cryp.mac = (caddr_t) out; + cryp.iv = 0; + cryp.iterations = iterations; + cryp.olen = dklen; + + if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) + { + warn("CIOCCRYPT"); + goto err; + } + + close(cryptodev_fd); + close(fd); + + return 0; +err: + if (cryptodev_fd != -1) + { + close(cryptodev_fd); + } + + if (fd != -1) + { + close(fd); + } + + return 1; +} + +static int match(unsigned char *a, unsigned char *b, size_t len) +{ + int i; + + if (memcmp(a, b, len) == 0) + return (0); + + warnx("pbkdf2 mismatch\n"); + + for (i = 0; i < len; i++) + { + printf("%02x", a[i]); + } + + printf("\n"); + for (i = 0; i < len; i++) + { + printf("%02x", b[i]); + } + + printf("\n"); + + return (1); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(void) +{ + char output[40]; + int ret = 0; + for (int i = 0; i < 6; i++) + { + ret = syspbkdf2(CRYPTO_PBKDF2_HMAC_SHA1, pbkdf2_testcases[i].key, + pbkdf2_testcases[i].keylen, + pbkdf2_testcases[i].data, + pbkdf2_testcases[i].datalen, + pbkdf2_testcases[i].iterations, + pbkdf2_testcases[i].dklen, output); + if (ret) + { + printf("PBKDF2 SHA1 failed\n"); + } + + ret += match((unsigned char *)pbkdf2_sha1_result[i], + (unsigned char *)output, + pbkdf2_testcases[i].dklen); + if (ret) + { + printf("match PBKDF2 SHA1 failed\n"); + } + else + { + printf("hmac PBKDF2 SHA1 success\n"); + } + } + + for (int i = 0; i < 6; i++) + { + ret = syspbkdf2(CRYPTO_PBKDF2_HMAC_SHA256, pbkdf2_testcases[i].key, + pbkdf2_testcases[i].keylen, + pbkdf2_testcases[i].data, + pbkdf2_testcases[i].datalen, + pbkdf2_testcases[i].iterations, + pbkdf2_testcases[i].dklen, output); + if (ret) + { + printf("PBKDF2 SHA256 failed\n"); + } + + ret += match((unsigned char *)pbkdf2_sha256_result[i], + (unsigned char *)output, + pbkdf2_testcases[i].dklen); + if (ret) + { + printf("match PBKDF2 SHA256 failed\n"); + } + else + { + printf("hmac PBKDF2 SHA256 success\n"); + } + } + + return 0; +} From dc4ecc973e41435d7f253ef0ff5f14ffe45b1d2f Mon Sep 17 00:00:00 2001 From: Tiago Medicci Date: Fri, 27 Mar 2026 13:45:32 -0300 Subject: [PATCH 275/568] ci: split xtensa jobs into three separate jobs (instead of two) This is necessary because new defconfig were recently added to Xtensa-based Espressif SoCs and the build job may exceed 2 hours. In order to avoid increasing job timeout, a specific job for each supported SoC (ESP32, ESP32-S2 and ESP32-S3) was created instead. Signed-off-by: Tiago Medicci --- .github/workflows/arch.yml | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/arch.yml b/.github/workflows/arch.yml index 278d5f666..02e39ab2b 100644 --- a/.github/workflows/arch.yml +++ b/.github/workflows/arch.yml @@ -230,7 +230,7 @@ jobs: skip_build=1 fi - # For "Arch / Board: xtensa": Build xtensa-01, xtensa-02 + # For "Arch / Board: xtensa": Build xtensa-01, xtensa-02, xtensa-03 elif [[ "$arch_contains_xtensa" == "1" || "$board_contains_xtensa" == "1" ]]; then if [[ "$board" != *"xtensa-"* ]]; then skip_build=1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 34cc01a43..fc106e7d6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -121,7 +121,7 @@ jobs: [ "arm-01", "risc-v-01", "sim-01", "xtensa-01", "arm64-01", "x86_64-01", "other", "arm-02", "risc-v-02", "sim-02", "xtensa-02", - "arm-03", "risc-v-03", "sim-03", + "arm-03", "risc-v-03", "sim-03", "xtensa-03", "arm-04", "risc-v-04", "arm-05", "risc-v-05", "arm-06", "risc-v-06", From 073df9d1dec8d569e971e39c9dc71504f40836ea Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Mon, 16 Mar 2026 18:22:43 +0800 Subject: [PATCH 276/568] examples/uvc_cam: add UVC camera streaming app Usage: uvc_cam [nframes] [video_dev] [uvc_dev] V4L2 capture -> write UVC gadget device. Uses boardctl to initialize/deinitialize UVC gadget. Queries sensor pixel format, resolution and frame rate via V4L2. Uses poll() to wait for USB host streaming state. Supports optional device path arguments (default /dev/video0, /dev/uvc0). Supports configurable frame count (0=infinite). Signed-off-by: wangjianyu3 --- examples/uvc_cam/CMakeLists.txt | 35 +++ examples/uvc_cam/Kconfig | 32 +++ examples/uvc_cam/Make.defs | 25 ++ examples/uvc_cam/Makefile | 34 +++ examples/uvc_cam/uvc_cam_main.c | 482 ++++++++++++++++++++++++++++++++ 5 files changed, 608 insertions(+) create mode 100644 examples/uvc_cam/CMakeLists.txt create mode 100644 examples/uvc_cam/Kconfig create mode 100644 examples/uvc_cam/Make.defs create mode 100644 examples/uvc_cam/Makefile create mode 100644 examples/uvc_cam/uvc_cam_main.c diff --git a/examples/uvc_cam/CMakeLists.txt b/examples/uvc_cam/CMakeLists.txt new file mode 100644 index 000000000..952fd3e4b --- /dev/null +++ b/examples/uvc_cam/CMakeLists.txt @@ -0,0 +1,35 @@ +# ############################################################################## +# apps/examples/uvc_cam/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_EXAMPLES_UVC_CAM) + nuttx_add_application( + NAME + ${CONFIG_EXAMPLES_UVC_CAM_PROGNAME} + PRIORITY + ${CONFIG_EXAMPLES_UVC_CAM_PRIORITY} + STACKSIZE + ${CONFIG_EXAMPLES_UVC_CAM_STACKSIZE} + MODULE + ${CONFIG_EXAMPLES_UVC_CAM} + SRCS + uvc_cam_main.c) +endif() diff --git a/examples/uvc_cam/Kconfig b/examples/uvc_cam/Kconfig new file mode 100644 index 000000000..83e6ca52d --- /dev/null +++ b/examples/uvc_cam/Kconfig @@ -0,0 +1,32 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_UVC_CAM + tristate "UVC Camera streaming example" + default n + depends on USBUVC && VIDEO + ---help--- + Captures frames from V4L2 camera and streams to USB host + via UVC gadget driver (/dev/uvc0). + +if EXAMPLES_UVC_CAM + +config EXAMPLES_UVC_CAM_PROGNAME + string "Program name" + default "uvc_cam" + +config EXAMPLES_UVC_CAM_PRIORITY + int "Task priority" + default 100 + +config EXAMPLES_UVC_CAM_STACKSIZE + int "Stack size" + default 4096 + +config EXAMPLES_UVC_CAM_NFRAMES + int "Number of frames (0=infinite)" + default 0 + +endif diff --git a/examples/uvc_cam/Make.defs b/examples/uvc_cam/Make.defs new file mode 100644 index 000000000..8a5c46a47 --- /dev/null +++ b/examples/uvc_cam/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/examples/uvc_cam/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_UVC_CAM),) +CONFIGURED_APPS += $(APPDIR)/examples/uvc_cam +endif diff --git a/examples/uvc_cam/Makefile b/examples/uvc_cam/Makefile new file mode 100644 index 000000000..409bc2494 --- /dev/null +++ b/examples/uvc_cam/Makefile @@ -0,0 +1,34 @@ +############################################################################ +# apps/examples/uvc_cam/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# UVC Camera streaming application + +PROGNAME = $(CONFIG_EXAMPLES_UVC_CAM_PROGNAME) +PRIORITY = $(CONFIG_EXAMPLES_UVC_CAM_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_UVC_CAM_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_UVC_CAM) + +MAINSRC = uvc_cam_main.c + +include $(APPDIR)/Application.mk diff --git a/examples/uvc_cam/uvc_cam_main.c b/examples/uvc_cam/uvc_cam_main.c new file mode 100644 index 000000000..a47d97e84 --- /dev/null +++ b/examples/uvc_cam/uvc_cam_main.c @@ -0,0 +1,482 @@ +/**************************************************************************** + * apps/examples/uvc_cam/uvc_cam_main.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * USB Video Class camera streaming application. + * Captures frames from V4L2 camera and streams to /dev/uvc0. + * + * Queries the sensor's native pixel format, resolution and frame rate + * via V4L2, then streams frames to the UVC gadget. + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define UVC_DEV_DEFAULT "/dev/uvc0" +#define VIDEO_DEV_DEFAULT "/dev/video0" + +#ifndef CONFIG_EXAMPLES_UVC_CAM_NFRAMES +# define CONFIG_EXAMPLES_UVC_CAM_NFRAMES 0 /* 0 = infinite */ +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pixfmt_to_bpp + * + * Description: + * Return bytes-per-pixel for common V4L2 pixel formats. + * + ****************************************************************************/ + +static int pixfmt_to_bpp(uint32_t pixfmt) +{ + switch (pixfmt) + { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_RGB565: + return 2; + case V4L2_PIX_FMT_RGB24: + return 3; + default: + return 0; + } +} + +/**************************************************************************** + * Name: camera_init + * + * Description: + * Open and configure the V4L2 camera device. + * Queries the sensor's native pixel format, resolution and frame rate + * and returns them via output parameters. + * + ****************************************************************************/ + +static int camera_init(int fd, FAR uint32_t *pixfmt, FAR uint16_t *width, + FAR uint16_t *height, FAR uint16_t *fps) +{ + struct v4l2_fmtdesc fmtdesc; + struct v4l2_frmivalenum frmival; + struct v4l2_frmsizeenum frmsize; + struct v4l2_format fmt; + struct v4l2_requestbuffers req; + int ret; + + /* Query native pixel format from sensor */ + + memset(&fmtdesc, 0, sizeof(fmtdesc)); + fmtdesc.index = 0; + fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc); + if (ret < 0) + { + printf("VIDIOC_ENUM_FMT failed: %d\n", errno); + return -errno; + } + + printf("Sensor format: %.4s\n", (FAR const char *)&fmtdesc.pixelformat); + + /* Query native resolution from sensor */ + + memset(&frmsize, 0, sizeof(frmsize)); + frmsize.index = 0; + frmsize.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + frmsize.pixel_format = fmtdesc.pixelformat; + + ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize); + if (ret < 0) + { + printf("VIDIOC_ENUM_FRAMESIZES failed: %d\n", errno); + return -errno; + } + + printf("Sensor native: %dx%d\n", + frmsize.discrete.width, frmsize.discrete.height); + + /* Set format — capture at native resolution */ + + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.width = frmsize.discrete.width; + fmt.fmt.pix.height = frmsize.discrete.height; + fmt.fmt.pix.field = V4L2_FIELD_ANY; + fmt.fmt.pix.pixelformat = fmtdesc.pixelformat; + + ret = ioctl(fd, VIDIOC_S_FMT, &fmt); + if (ret < 0) + { + printf("VIDIOC_S_FMT failed: %d\n", errno); + return -errno; + } + + /* Request buffers — match camcap: USERPTR + FIFO */ + + memset(&req, 0, sizeof(req)); + req.count = 1; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_USERPTR; + req.mode = V4L2_BUF_MODE_FIFO; + + ret = ioctl(fd, VIDIOC_REQBUFS, &req); + if (ret < 0) + { + printf("VIDIOC_REQBUFS failed: %d\n", errno); + return -errno; + } + + /* NOTE: Do NOT call VIDIOC_STREAMON here. + * With USERPTR + FIFO mode, STREAMON would start DMA capture + * immediately using the container's uninitialized userptr (0), + * causing DMA to write 153KB of video data to address 0 and + * corrupt memory. STREAMON must be called AFTER the first QBUF + * so that userptr points to a valid buffer. + */ + + /* Query frame interval from sensor */ + + memset(&frmival, 0, sizeof(frmival)); + frmival.index = 0; + frmival.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + frmival.pixel_format = fmtdesc.pixelformat; + frmival.width = frmsize.discrete.width; + frmival.height = frmsize.discrete.height; + + ret = ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival); + if (ret < 0) + { + printf("VIDIOC_ENUM_FRAMEINTERVALS failed: %d\n", errno); + return -errno; + } + + *pixfmt = fmtdesc.pixelformat; + *width = frmsize.discrete.width; + *height = frmsize.discrete.height; + *fps = frmival.discrete.numerator > 0 + ? frmival.discrete.denominator / frmival.discrete.numerator + : 0; + return OK; +} + +/**************************************************************************** + * Name: camera_capture_frame + * + * Description: + * Capture one frame from V4L2 into the provided buffer. + * + ****************************************************************************/ + +static int camera_capture_frame(int camfd, FAR uint8_t *buf, size_t buflen, + bool do_streamon) +{ + struct v4l2_buffer vbuf; + int ret; + + memset(&vbuf, 0, sizeof(vbuf)); + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_USERPTR; + vbuf.index = 0; + vbuf.m.userptr = (uintptr_t)buf; + vbuf.length = buflen; + + ret = ioctl(camfd, VIDIOC_QBUF, &vbuf); + if (ret < 0) + { + printf("VIDIOC_QBUF failed: %d\n", errno); + return -errno; + } + + /* Start streaming after the first QBUF so DMA has a valid buffer */ + + if (do_streamon) + { + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + ret = ioctl(camfd, VIDIOC_STREAMON, &type); + if (ret < 0) + { + printf("VIDIOC_STREAMON failed: %d\n", errno); + return -errno; + } + } + + ret = ioctl(camfd, VIDIOC_DQBUF, &vbuf); + if (ret < 0) + { + printf("VIDIOC_DQBUF failed: %d\n", errno); + return -errno; + } + + return vbuf.bytesused > 0 ? (int)vbuf.bytesused : (int)buflen; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + struct boardioc_usbdev_ctrl_s ctrl; + struct uvc_params_s uvc_params; + FAR void *uvc_handle = NULL; + FAR const char *video_dev = VIDEO_DEV_DEFAULT; + FAR const char *uvc_dev = UVC_DEV_DEFAULT; + FAR uint8_t *framebuf; + ssize_t written; + enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + uint32_t pixfmt = 0; + uint16_t width = 0; + uint16_t height = 0; + uint16_t fps = 0; + uint32_t frame_size; + int bpp; + int camfd; + int uvcfd; + int nframes; + int count = 0; + int ret; + + nframes = CONFIG_EXAMPLES_UVC_CAM_NFRAMES; + if (argc > 1) + { + nframes = atoi(argv[1]); + } + + if (argc > 2) + { + video_dev = argv[2]; + } + + if (argc > 3) + { + uvc_dev = argv[3]; + } + + /* Create capture device */ + + ret = capture_initialize(video_dev); + if (ret < 0 && ret != -EEXIST) + { + printf("Failed to initialize capture: %d\n", ret); + return EXIT_FAILURE; + } + + /* Open camera and query resolution */ + + camfd = open(video_dev, O_RDWR); + if (camfd < 0) + { + printf("Failed to open %s: %d\n", video_dev, errno); + return EXIT_FAILURE; + } + + ret = camera_init(camfd, &pixfmt, &width, &height, &fps); + if (ret < 0) + { + printf("Camera init failed: %d\n", ret); + close(camfd); + return EXIT_FAILURE; + } + + bpp = pixfmt_to_bpp(pixfmt); + if (bpp == 0) + { + printf("Unsupported pixel format: 0x%08lx\n", + (unsigned long)pixfmt); + close(camfd); + return EXIT_FAILURE; + } + + frame_size = (uint32_t)width * height * bpp; + printf("UVC Camera: %dx%d %.4s @%dfps, frames=%d (0=infinite)\n", + width, height, (FAR const char *)&pixfmt, fps, nframes); + + /* Allocate frame buffer — 32-byte aligned for DMA (same as camcap) */ + + framebuf = memalign(32, frame_size); + if (!framebuf) + { + printf("Failed to allocate frame buffer (%lu bytes)\n", + (unsigned long)frame_size); + close(camfd); + return EXIT_FAILURE; + } + + /* Initialize and connect UVC gadget via boardctl. + * Pass video params queried from camera so USB descriptors + * match the actual sensor resolution. + */ + + uvc_params.width = width; + uvc_params.height = height; + uvc_params.fps = fps; + + uvc_handle = (FAR void *)&uvc_params; +#ifdef CONFIG_USBUVC_COMPOSITE + ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; +#else + ctrl.usbdev = BOARDIOC_USBDEV_UVC; +#endif + ctrl.action = BOARDIOC_USBDEV_CONNECT; + ctrl.instance = 0; + ctrl.config = 0; + ctrl.handle = &uvc_handle; + + ret = boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); + + if (ret < 0) + { + printf("Failed to initialize UVC device: %d\n", ret); + close(camfd); + free(framebuf); + return EXIT_FAILURE; + } + + /* Open UVC device */ + + uvcfd = open(uvc_dev, O_WRONLY); + if (uvcfd < 0) + { + printf("Failed to open %s: %d\n", uvc_dev, errno); + ctrl.action = BOARDIOC_USBDEV_DISCONNECT; + boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); + close(camfd); + free(framebuf); + return EXIT_FAILURE; + } + + /* Wait for USB host to enumerate and start streaming */ + + struct pollfd pfd; + pfd.fd = uvcfd; + pfd.events = POLLOUT; + + printf("Waiting for USB host to connect...\n"); + while (poll(&pfd, 1, 500) <= 0 || !(pfd.revents & POLLOUT)) + { + } + + printf("Streaming started...\n"); + + /* Main capture-stream loop */ + + while (nframes == 0 || count < nframes) + { + ret = camera_capture_frame(camfd, framebuf, frame_size, + count == 0); + if (ret < 0) + { + printf("Capture failed: %d\n", ret); + break; + } + + /* Write frame to UVC directly from framebuf. + * DMA won't touch framebuf until next QBUF. + */ + + written = 0; + while (written < (ssize_t)frame_size) + { + ret = write(uvcfd, framebuf + written, + frame_size - written); + if (ret < 0) + { + if (errno == EAGAIN) + { + /* Host stopped streaming - wait for reconnect. + * + * NOTE: The printf inside the loop is required + * on boards where the USB-UART bridge (CH341) + * and the ESP32-S3 OTG share an on-board USB + * hub (e.g. lckfb-szpi). Continuous UART TX + * keeps the hub active and prevents the host + * from power-cycling the hub port, which would + * cause a full board POWERON reset. + */ + + printf("Host disconnected, waiting...\n"); + pfd.revents = 0; + while (poll(&pfd, 1, 500) <= 0 + || !(pfd.revents & POLLOUT)) + { + printf(".\n"); + } + + printf("Streaming restarted.\n"); + written = 0; + break; + } + + printf("UVC write failed: %d\n", errno); + goto out; + } + + written += ret; + } + + count++; + if ((count % 10) == 0) + { + printf("Streamed %d frames\n", count); + } + } + + printf("Done. Streamed %d frames total.\n", count); + +out: + ioctl(camfd, VIDIOC_STREAMOFF, &cap_type); + + close(uvcfd); + close(camfd); + + /* Disconnect UVC gadget */ + + ctrl.action = BOARDIOC_USBDEV_DISCONNECT; + boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); + + free(framebuf); + return EXIT_SUCCESS; +} From b8718d8c5264ff0d4bcca033b93d9b1a9d0b1af6 Mon Sep 17 00:00:00 2001 From: simbit18 Date: Wed, 1 Apr 2026 17:26:30 +0200 Subject: [PATCH 277/568] build.yml: Fix No files were found with the provided path Fix Warning: No files were found with the provided path: buildartifacts/. Signed-off-by: simbit18 --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fc106e7d6..f4f33fda9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -181,6 +181,8 @@ jobs: BLOBDIR: /tools/blobs with: run: | + export ARTIFACTDIR=`pwd`/buildartifacts + pip install ntfc==0.0.1 mkdir /github/workspace/nuttx-ntfc mkdir /github/workspace/nuttx-ntfc/external @@ -188,10 +190,9 @@ jobs: # get NTFC test cases cd external git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-testing + export NTFCDIR=/github/workspace/nuttx-ntfc echo "::add-matcher::sources/nuttx/.github/gcc.json" - export ARTIFACTDIR=`pwd`/buildartifacts - export NTFCDIR=/github/workspace/nuttx-ntfc git config --global --add safe.directory /github/workspace/sources/nuttx git config --global --add safe.directory /github/workspace/sources/apps cd /github/workspace/sources/nuttx/tools/ci From 5c867b21e600d430c8c3336efa2ae2456d5357b9 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 16 Mar 2026 12:39:41 +0100 Subject: [PATCH 278/568] examples/nxscope: control stream interval from CLI add the ability to control the stream interval from the CLI which is useful for performance testing Signed-off-by: raiden00pl --- examples/nxscope/nxscope_main.c | 105 +++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 8 deletions(-) diff --git a/examples/nxscope/nxscope_main.c b/examples/nxscope/nxscope_main.c index 5d5102e99..afad9052b 100644 --- a/examples/nxscope/nxscope_main.c +++ b/examples/nxscope/nxscope_main.c @@ -29,15 +29,17 @@ #include #include +#include +#include #include #include +#include #include #include #ifdef CONFIG_EXAMPLES_NXSCOPE_TIMER # include # include -# include # include # include #endif @@ -52,7 +54,8 @@ # error "math library must be selected for this example" #endif -#define SIN_DT (0.01f) +#define SIN_DT (0.01f) +#define STREAM_THREAD_USLEP 100 /**************************************************************************** * Private Types @@ -61,6 +64,7 @@ struct nxscope_thr_env_s { FAR struct nxscope_s *nxs; + int interval; }; /**************************************************************************** @@ -93,12 +97,76 @@ static int nxscope_cb_start(FAR void *priv, bool start) return OK; } +/**************************************************************************** + * Name: nxscope_show_usage + ****************************************************************************/ + +static void nxscope_show_usage(FAR const char *progname) +{ + printf("Usage: %s [-i ]\n", progname); + printf(" [-m ]\n"); +} + +/**************************************************************************** + * Name: nxscope_parse_args + ****************************************************************************/ + +static int nxscope_parse_args(int argc, FAR char *argv[], + FAR int *stream_interval, + FAR int *main_interval) +{ + unsigned long value = 0; + int opt = 0; + + DEBUGASSERT(argv); + DEBUGASSERT(stream_interval); + DEBUGASSERT(main_interval); + + while ((opt = getopt(argc, argv, "i:m:")) != -1) + { + switch (opt) + { + case 'i': + { + value = strtoul(optarg, NULL, 10); + if (value == 0) + { + printf("ERROR: invalid interval: %s\n", optarg); + return -EINVAL; + } + + *stream_interval = (int)value; + break; + } + + case 'm': + { + value = strtoul(optarg, NULL, 10); + if (value == 0) + { + printf("ERROR: invalid interval: %s\n", optarg); + return -EINVAL; + } + + *main_interval = (int)value; + break; + } + + default: + printf("ERROR: unsupported argument\n"); + return -EINVAL; + } + } + + return OK; +} + #ifdef CONFIG_EXAMPLES_NXSCOPE_TIMER /**************************************************************************** * Name: nxscope_timer_init ****************************************************************************/ -static int nxscope_timer_init(void) +static int nxscope_timer_init(int interval_us) { int fd = 0; int ret = 0; @@ -116,8 +184,7 @@ static int nxscope_timer_init(void) /* Set the timer interval */ - ret = ioctl(fd, TCIOC_SETTIMEOUT, - CONFIG_EXAMPLES_NXSCOPE_TIMER_INTERVAL); + ret = ioctl(fd, TCIOC_SETTIMEOUT, interval_us); if (ret < 0) { printf("ERROR: Failed to set the timer interval: %d\n", errno); @@ -197,7 +264,7 @@ static FAR void *nxscope_samples_thr(FAR void *arg) #ifdef CONFIG_EXAMPLES_NXSCOPE_TIMER /* Initialize timer for periodic signal. */ - ret = nxscope_timer_init(); + ret = nxscope_timer_init(envp->interval); if (ret < 0) { printf("ERROR: nxscope_timer_init() failed: %d\n", errno); @@ -307,7 +374,7 @@ static FAR void *nxscope_samples_thr(FAR void *arg) goto errout; } #else - usleep(100); + usleep(envp->interval); #endif } @@ -421,6 +488,7 @@ int main(int argc, FAR char *argv[]) { struct nxscope_s nxs; int ret = OK; + int interval; pthread_t thread; struct nxscope_thr_env_s env; struct nxscope_cfg_s nxs_cfg; @@ -438,6 +506,27 @@ int main(int argc, FAR char *argv[]) struct nxscope_dummy_cfg_s nxs_dummy_cfg; #endif + /* Default settings */ + + interval = CONFIG_EXAMPLES_NXSCOPE_MAIN_INTERVAL; +#ifdef CONFIG_EXAMPLES_NXSCOPE_TIMER + env.interval = CONFIG_EXAMPLES_NXSCOPE_TIMER_INTERVAL; +#else + env.interval = STREAM_THREAD_USLEP; +#endif + + /* Parse args */ + + ret = nxscope_parse_args(argc, argv, &env.interval, &interval); + if (ret < 0) + { + nxscope_show_usage(argv[0]); + return EXIT_FAILURE; + } + + printf("stream interval = %d\n", env.interval); + printf("main interval = %d\n", interval); + #ifndef CONFIG_NSH_ARCHINIT /* Perform architecture-specific initialization (if configured) */ @@ -736,7 +825,7 @@ int main(int argc, FAR char *argv[]) printf("ERROR: nxscope_recv failed %d\n", ret); } - usleep(CONFIG_EXAMPLES_NXSCOPE_MAIN_INTERVAL); + usleep(interval); } errout: From 231ac397a7fd01cdd2bac13b4ff9c57c7253c36e Mon Sep 17 00:00:00 2001 From: Shunchao Hu Date: Thu, 2 Apr 2026 15:27:57 +0800 Subject: [PATCH 279/568] canutils/lely-canopen: avoid patch reapply on repeated builds. The patch step currently uses a phony target, so it is executed again when the build is repeated in the same source tree. In that case `patch -N` detects previously applied patches and returns 1, which make treats as a failure. Replace the phony patch target with a stamped `.patched` file so the patch step is not re-run unnecessarily. Fixes #3188 Signed-off-by: Shunchao Hu --- canutils/lely-canopen/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/canutils/lely-canopen/Makefile b/canutils/lely-canopen/Makefile index ca124b833..2304c1580 100644 --- a/canutils/lely-canopen/Makefile +++ b/canutils/lely-canopen/Makefile @@ -179,7 +179,7 @@ $(LELYCANOPEN_SRCNAME): $(LELYCANOPEN_TARBALL) @echo "Unpacking: $(LELYCANOPEN_TARBALL) -> $(LELYCANOPEN_UNPACKNAME)" $(Q) $(UNPACK) $(LELYCANOPEN_TARBALL) -patch_src: $(LELYCANOPEN_SRCNAME) +$(LELYCANOPEN_SRCNAME)/.patched : $(LELYCANOPEN_SRCNAME) # Get the name of the directory created by the tar command $(eval LELYCANOPEN_UNPACKNAME := $(shell ls -d lely-core-master*)) $(Q) mv $(LELYCANOPEN_UNPACKNAME) $(LELYCANOPEN_SRCNAME) @@ -188,9 +188,10 @@ patch_src: $(LELYCANOPEN_SRCNAME) $(Q) cat 0003-src-co-nmt.c-fix-compilation.patch | patch -s -N -d $(LELYCANOPEN_SRCNAME) -p1 $(Q) cat 0004-tools-coctl.c-add-missing-mutex-init.patch | patch -s -N -d $(LELYCANOPEN_SRCNAME) -p1 $(Q) cat 0005-add-NuttX-support.patch | patch -s -N -d $(LELYCANOPEN_SRCNAME) -p1 + $(Q) touch $@ $(Q) echo "Patching $(LELYCANOPEN_SRCNAME)" -context:: patch_src +context:: $(LELYCANOPEN_SRCNAME)/.patched else context:: $(LELYCANOPEN_SRCNAME) endif From 9db3e26c85484344f34bd3163136ad7136fe7d7d Mon Sep 17 00:00:00 2001 From: Lup Yuen Lee Date: Wed, 8 Apr 2026 11:45:33 +0800 Subject: [PATCH 280/568] graphics/libyuv: Download libyuv from NuttX Mirror Repo NuttX Build Target `sim:nxcamera` failed to build because chromium.googlesource.com is blocking our download of libyuv library: https://github.com/apache/nuttx/actions/runs/24106742084/job/70356374433#step:10:603 ``` Configuration/Tool: sim/nxcamera Building NuttX... curl -L https://chromium.googlesource.com/libyuv/libyuv/+archive/refs/heads/stable.tar.gz -o libyuv.tar.gz gzip: stdin: not in gzip format ``` This PR updates the libyuv Makefile to download libyuv from the NuttX Mirror Repo instead: https://github.com/NuttX/nuttx/releases/tag/libyuv Signed-off-by: Lup Yuen Lee --- graphics/libyuv/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphics/libyuv/Makefile b/graphics/libyuv/Makefile index d15033fd1..e4421ee1d 100644 --- a/graphics/libyuv/Makefile +++ b/graphics/libyuv/Makefile @@ -29,7 +29,7 @@ CXXFLAGS += -Wno-shadow -Wno-undef CXXSRCS = $(wildcard $(SRCDIR)/source/*.cc) libyuv.tar.gz: - $(Q) curl -L https://chromium.googlesource.com/libyuv/libyuv/+archive/refs/heads/$(CONFIG_LIBYUV_BRANCH).tar.gz -o libyuv.tar.gz + $(Q) curl -L https://github.com/NuttX/nuttx/releases/download/libyuv/libyuv-refs_heads_$(CONFIG_LIBYUV_BRANCH).tar.gz -o libyuv.tar.gz $(Q) mkdir -p $(SRCDIR) $(Q) tar zxf libyuv.tar.gz --directory $(SRCDIR) ifeq ($(CONFIG_LIBYUV_BRANCH),"stable") From a6286ee0ea746a135fd769bdd94d3e35dcbf7d04 Mon Sep 17 00:00:00 2001 From: liuhongchao Date: Fri, 28 Mar 2025 14:59:52 +0800 Subject: [PATCH 281/568] graphics/input: Add getevent input event monitor tool. Add getevent utility for monitoring input events including mouse clicks/movement, multi-touch coordinates/pressure, and keyboard key presses. Supports automatic device detection in /dev and command-line device path specification with non-blocking I/O. Signed-off-by: liuhongchao --- graphics/input/CMakeLists.txt | 14 + graphics/input/Kconfig | 36 ++ graphics/input/Make.defs | 2 +- graphics/input/Makefile | 12 + graphics/input/getevent/getevent.c | 562 +++++++++++++++++++++++++++++ 5 files changed, 625 insertions(+), 1 deletion(-) create mode 100644 graphics/input/getevent/getevent.c diff --git a/graphics/input/CMakeLists.txt b/graphics/input/CMakeLists.txt index 2ec8eb86f..8213d364a 100644 --- a/graphics/input/CMakeLists.txt +++ b/graphics/input/CMakeLists.txt @@ -62,3 +62,17 @@ if(CONFIG_GRAPHICS_INPUT_TOOL) SRCS generator/input.c) endif() + +if(CONFIG_GRAPHICS_INPUT_GETEVENT) + nuttx_add_application( + MODULE + ${CONFIG_GRAPHICS_INPUT_GETEVENT} + NAME + getevent + STACKSIZE + ${CONFIG_GRAPHICS_INPUT_GETEVENT_STACKSIZE} + PRIORITY + ${CONFIG_GRAPHICS_INPUT_GETEVENT_PRIORITY} + SRCS + getevent/getevent.c) +endif() diff --git a/graphics/input/Kconfig b/graphics/input/Kconfig index 08430e8d8..7cda0c370 100644 --- a/graphics/input/Kconfig +++ b/graphics/input/Kconfig @@ -59,3 +59,39 @@ config GRAPHICS_INPUT_TOOL_PRIORITY The priority of the input task. endif # GRAPHICS_INPUT_TOOL + +menuconfig GRAPHICS_INPUT_GETEVENT + tristate "Enable getevent tool" + default n + ---help--- + The getevent is a command-line input event monitor. It + captures and displays real-time events from mouse, + touchscreen, and keyboard devices via the input subsystem. + + Use getevent to debug and verify input drivers, inspect + raw event data during device bring-up, or diagnose + input issues on a running system. It supports automatic + device detection in /dev as well as manual device path + specification. + +if GRAPHICS_INPUT_GETEVENT + +config GRAPHICS_INPUT_GETEVENT_STACKSIZE + int "getevent stack size" + default DEFAULT_TASK_STACKSIZE + ---help--- + The size of stack allocated for the getevent task. + +config GRAPHICS_INPUT_GETEVENT_PRIORITY + int "getevent priority" + default 100 + ---help--- + The priority of the getevent task. + +config GRAPHICS_INPUT_GETEVENT_DETAIL_INFO + bool "getevent detail info" + default n + ---help--- + Enable detailed information in getevent output. + +endif # GRAPHICS_INPUT_GETEVENT diff --git a/graphics/input/Make.defs b/graphics/input/Make.defs index 8bf4cb9c1..5931c7950 100644 --- a/graphics/input/Make.defs +++ b/graphics/input/Make.defs @@ -20,6 +20,6 @@ # ############################################################################ -ifneq ($(CONFIG_GRAPHICS_INPUT_GENERATOR),) +ifneq ($(CONFIG_GRAPHICS_INPUT_GENERATOR)$(CONFIG_GRAPHICS_INPUT_GETEVENT),) CONFIGURED_APPS += $(APPDIR)/graphics/input endif diff --git a/graphics/input/Makefile b/graphics/input/Makefile index b88166a09..e0a974b51 100644 --- a/graphics/input/Makefile +++ b/graphics/input/Makefile @@ -50,4 +50,16 @@ MODULE += $(CONFIG_GRAPHICS_INPUT_TOOL) MAINSRC += generator/input.c endif +# getevent tool + +ifneq ($(CONFIG_GRAPHICS_INPUT_GETEVENT),) +PROGNAME += getevent +PRIORITY += $(CONFIG_GRAPHICS_INPUT_GETEVENT_PRIORITY) +STACKSIZE += $(CONFIG_GRAPHICS_INPUT_GETEVENT_STACKSIZE) +MODULE += $(CONFIG_GRAPHICS_INPUT_GETEVENT) + +MAINSRC += getevent/getevent.c +CFLAGS += -Wno-discarded-qualifiers +endif + include $(APPDIR)/Application.mk diff --git a/graphics/input/getevent/getevent.c b/graphics/input/getevent/getevent.c new file mode 100644 index 000000000..c70f90d47 --- /dev/null +++ b/graphics/input/getevent/getevent.c @@ -0,0 +1,562 @@ +/**************************************************************************** + * apps/graphics/input/getevent/getevent.c + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define GETEVENT_INFO(format, ...) \ + printf("[getevent]: " format, ##__VA_ARGS__) + +#define GETEVENT_ERR(format, ...) \ + fprintf(stderr, "[getevent]: " format, ##__VA_ARGS__) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct input_device_s; + +typedef CODE int (*input_init_cb)(FAR struct input_device_s *); +typedef CODE void (*input_read_cb)(FAR struct input_device_s *); + +struct touch_priv_s +{ + uint8_t maxpoint; + struct touch_sample_s sample[]; +}; + +struct input_device_s +{ + int fd; + input_init_cb init_cb; + input_read_cb read_cb; + FAR void *priv; + FAR struct input_device_s *next; + char path[]; +}; + +struct input_devices_ctx_s +{ + FAR struct input_device_s *head; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: open_device + ****************************************************************************/ + +static int open_device(FAR struct input_device_s *dev) +{ + GETEVENT_INFO("opening %s\n", dev->path); + dev->fd = open(dev->path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); + + if (dev->fd < 0) + { + GETEVENT_ERR("open %s failed, errno: %d\n", dev->path, errno); + return -errno; + } + + if (dev->init_cb) + { + return dev->init_cb(dev); + } + + return 0; +} + +/**************************************************************************** + * Name: touch_init + ****************************************************************************/ + +static int touch_init(FAR struct input_device_s *dev) +{ + FAR struct touch_priv_s *priv; + uint8_t maxpoint; + int ret; + + ret = ioctl(dev->fd, TSIOC_GETMAXPOINTS, &maxpoint); + if (ret < 0) + { + GETEVENT_ERR("ioctl GETMAXPOINTS failed: %d, " + "errno: %d\n", ret, errno); + return -errno; + } + + priv = calloc(1, sizeof(struct touch_priv_s) + + SIZEOF_TOUCH_SAMPLE_S(maxpoint)); + if (!priv) + { + GETEVENT_ERR("Memory allocation failed for touch_priv_s\n"); + return -ENOMEM; + } + + priv->maxpoint = maxpoint; + dev->priv = priv; + GETEVENT_INFO("ioctl TSIOC_GETMAXPOINTS: %d\n", maxpoint); + return ret; +} + +/**************************************************************************** + * Name: read_mouse_event + ****************************************************************************/ + +static void read_mouse_event(FAR struct input_device_s *dev) +{ + struct mouse_report_s sample; + ssize_t nbytes; + + /* Read one sample */ + + nbytes = read(dev->fd, &sample, sizeof(struct mouse_report_s)); + + /* Print the sample data on successful return */ + + if (nbytes == sizeof(struct mouse_report_s)) + { + GETEVENT_INFO("mouse event: %s\n", dev->path); + GETEVENT_INFO(" buttons : %02" PRIx8 "\n", sample.buttons); + GETEVENT_INFO(" x : %d\n", sample.x); + GETEVENT_INFO(" y : %d\n", sample.y); +#ifdef CONFIG_INPUT_MOUSE_WHEEL + GETEVENT_INFO(" wheel : %d\n", sample.wheel); +#endif + } +} + +/**************************************************************************** + * Name: read_touch_event + ****************************************************************************/ + +static void read_touch_event(FAR struct input_device_s *dev) +{ + FAR struct touch_priv_s *priv = (FAR struct touch_priv_s *)dev->priv; + ssize_t nbytes; + size_t i; + + /* Read one sample */ + + nbytes = read(dev->fd, priv->sample, + SIZEOF_TOUCH_SAMPLE_S(priv->maxpoint)); + + /* Print the sample data on successful return */ + + if (nbytes == SIZEOF_TOUCH_SAMPLE_S(priv->maxpoint)) + { + GETEVENT_INFO("touch event: %s\n", dev->path); + GETEVENT_INFO(" npoints : %" PRId32 "\n", priv->sample->npoints); + for (i = 0; i < priv->maxpoint; i++) + { + if (priv->sample->point[i].flags == 0) + { + break; + } + + GETEVENT_INFO("Point : %d\n", priv->sample->point[i].id); + GETEVENT_INFO(" flags : %02x\n", priv->sample->point[i].flags); + GETEVENT_INFO(" x : %d\n", priv->sample->point[i].x); + GETEVENT_INFO(" y : %d\n", priv->sample->point[i].y); +#ifdef CONFIG_GRAPHICS_INPUT_GETEVENT_DETAIL_INFO + GETEVENT_INFO(" h : %d\n", priv->sample->point[i].h); + GETEVENT_INFO(" w : %d\n", priv->sample->point[i].w); + GETEVENT_INFO(" pressure : %d\n", + priv->sample->point[i].pressure); +#endif + GETEVENT_INFO(" timestamp : %" PRIu64"\n", + priv->sample->point[i].timestamp); + } + } +} + +/**************************************************************************** + * Name: read_keyboard_event + ****************************************************************************/ + +static void read_keyboard_event(FAR struct input_device_s *dev) +{ + struct keyboard_event_s sample; + ssize_t nbytes; + + /* Read one sample */ + + nbytes = read(dev->fd, &sample, sizeof(struct keyboard_event_s)); + + /* Print the sample data on successful return */ + + if (nbytes == sizeof(struct keyboard_event_s)) + { + GETEVENT_INFO("keyboard event: %s\n", dev->path); + GETEVENT_INFO(" type : %" PRIu32 "\n", sample.type); + GETEVENT_INFO(" code : %" PRIu32 "\n", sample.code); + } +} + +/**************************************************************************** + * Name: cleanup_input_devices + ****************************************************************************/ + +static void cleanup_input_devices(FAR struct input_devices_ctx_s *ctx) +{ + FAR struct input_device_s *dev = ctx->head; + FAR struct input_device_s *next; + + while (dev) + { + next = dev->next; + if (dev->fd >= 0) + { + close(dev->fd); + } + + free(dev->priv); + free(dev); + dev = next; + } + + ctx->head = NULL; +} + +/**************************************************************************** + * Name: signal_handler + ****************************************************************************/ + +static void +signal_handler(int signum, FAR siginfo_t *info, FAR void *context) +{ + FAR volatile sig_atomic_t *running = info->si_user; + *running = 0; +} + +/**************************************************************************** + * Name: run_event_loop + ****************************************************************************/ + +static void run_event_loop(FAR struct input_devices_ctx_s *ctx) +{ + FAR struct input_device_s *dev; + FAR struct pollfd *fds = NULL; + volatile sig_atomic_t running = 1; + struct sigaction sa; + int fd_count = 0; + int timeout = 500; + int i = 0; + int ret; + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_user = (FAR void *)&running; + sigaction(SIGINT, &sa, NULL); + + for (dev = ctx->head; dev; dev = dev->next) + { + if (dev->fd >= 0) + { + fd_count++; + } + } + + fds = calloc(fd_count, sizeof(struct pollfd)); + + if (!fds) + { + GETEVENT_ERR("Memory allocation failed for fds\n"); + return; + } + + for (dev = ctx->head; dev; dev = dev->next) + { + if (dev->fd >= 0) + { + fds[i].fd = dev->fd; + fds[i].events = POLLIN; + fds[i].revents = 0; + i++; + } + } + + while (running) + { + ret = poll(fds, fd_count, timeout); + if (ret < 0 && errno != EINTR) + { + GETEVENT_ERR("poll error: %d\n", errno); + break; + } + + for (i = 0; i < fd_count; i++) + { + if (!(fds[i].revents & POLLIN)) + { + continue; + } + + for (dev = ctx->head; dev; dev = dev->next) + { + if (dev->fd == fds[i].fd) + { + dev->read_cb(dev); + break; + } + } + } + } + + free(fds); +} + +/**************************************************************************** + * Name: show_usage + ****************************************************************************/ + +static void show_usage(void) +{ + printf("Usage: getevent [OPTIONS]\n"); + printf("Options:\n"); + printf(" -h Show this help message\n"); + printf(" -m /dev/mouse -- mouse device path\n"); + printf(" -t /dev/input -- touch device path\n"); + printf(" -k /dev/keyboard -- keyboard device path\n"); + printf("No options: Auto detect devices in /dev\n"); +} + +/**************************************************************************** + * Name: alloc_input_device + ****************************************************************************/ + +static FAR struct input_device_s * +alloc_input_device(FAR struct input_devices_ctx_s *ctx, + FAR const char *path) +{ + FAR struct input_device_s *dev; + FAR struct input_device_s *cur; + size_t path_len = strlen(path) + 1; + + dev = calloc(1, sizeof(struct input_device_s) + path_len); + if (!dev) + { + GETEVENT_ERR("Memory allocation failed for device\n"); + return NULL; + } + + memcpy(dev->path, path, path_len); + + if (!ctx->head) + { + ctx->head = dev; + } + else + { + cur = ctx->head; + while (cur->next) + { + cur = cur->next; + } + + cur->next = dev; + } + + return dev; +} + +/**************************************************************************** + * Name: add_input_device + ****************************************************************************/ + +static int add_input_device(FAR struct input_devices_ctx_s *ctx, + input_init_cb init_cb, + input_read_cb read_cb, + FAR const char *path) +{ + FAR struct input_device_s *dev = alloc_input_device(ctx, path); + + if (!dev) + { + return -ENOMEM; + } + + dev->fd = -1; + dev->init_cb = init_cb; + dev->read_cb = read_cb; + + return open_device(dev); +} + +/**************************************************************************** + * Name: detect_devices + ****************************************************************************/ + +static int detect_devices(FAR struct input_devices_ctx_s *ctx) +{ + FAR struct dirent *entry; + char path[PATH_MAX]; + FAR DIR *dir; + int ret = 0; + + dir = opendir("/dev"); + if (!dir) + { + GETEVENT_ERR("Failed to open /dev directory, errno: %d\n", errno); + return -errno; + } + + while ((entry = readdir(dir))) + { + if (entry->d_type == DT_CHR) + { + if (snprintf(path, sizeof(path), "/dev/%s", entry->d_name) < 0) + { + GETEVENT_ERR("Memory allocation failed for path\n"); + continue; + } + + if (strncmp(entry->d_name, "mouse", 5) == 0) + { + ret = add_input_device(ctx, NULL, read_mouse_event, path); + } + else if (strncmp(entry->d_name, "input", 5) == 0) + { + ret = add_input_device(ctx, touch_init, read_touch_event, + path); + } + else if (strncmp(entry->d_name, "kbd", 3) == 0) + { + ret = add_input_device(ctx, NULL, read_keyboard_event, path); + } + + if (ret < 0) + { + break; + } + } + } + + closedir(dir); + return ret; +} + +/**************************************************************************** + * Name: parse_commandline + ****************************************************************************/ + +static int parse_commandline(FAR struct input_devices_ctx_s *ctx, + int argc, FAR char **argv) +{ + int ret = -EINVAL; + int ch; + + if (argc == 1) + { + return detect_devices(ctx); + } + + while ((ch = getopt(argc, argv, "hn:m:t:k:")) != -1) + { + switch (ch) + { + case 'm': + ret = add_input_device(ctx, NULL, read_mouse_event, optarg); + break; + case 't': + ret = add_input_device(ctx, touch_init, read_touch_event, optarg); + break; + case 'k': + ret = add_input_device(ctx, NULL, read_keyboard_event, optarg); + break; + case '?': + case 'h': + default: + show_usage(); + break; + } + + if (ret < 0) + { + break; + } + } + + return ret; +} + +/**************************************************************************** + * Name: main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + struct input_devices_ctx_s ctx; + int ret; + + memset(&ctx, 0, sizeof(ctx)); + + /* Parse the command line arguments */ + + ret = parse_commandline(&ctx, argc, argv); + if (ret < 0) + { + goto cleanup; + } + + /* Start event loop for input processing */ + + run_event_loop(&ctx); + + /* Clean up resources */ + +cleanup: + cleanup_input_devices(&ctx); + + GETEVENT_INFO("Terminating!\n"); + + return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} From 52b36deb13a30c8cbeb4be9b82d030b9bc87bf9a Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Thu, 2 Apr 2026 10:51:02 +0800 Subject: [PATCH 282/568] examples/camera: use MMAP with USERPTR fallback and fix NX stride Use MMAP buffer allocation by default so the driver can manage DMA-capable memory with proper alignment and cache attributes. Fall back to USERPTR if the driver does not support MMAP. Also fix NX framebuffer stride calculation to use the actual display width instead of hardcoded values. Signed-off-by: wangjianyu3 --- examples/camera/camera_bkgd.c | 15 +++-- examples/camera/camera_main.c | 114 ++++++++++++++++++++++++---------- 2 files changed, 92 insertions(+), 37 deletions(-) diff --git a/examples/camera/camera_bkgd.c b/examples/camera/camera_bkgd.c index aa1464471..e53010dad 100644 --- a/examples/camera/camera_bkgd.c +++ b/examples/camera/camera_bkgd.c @@ -307,21 +307,28 @@ void nximage_draw(FAR void *image, int w, int h) FAR struct nxgl_rect_s dest; FAR const void *src[CONFIG_NX_NPLANES]; int ret; + int dest_w; + int dest_h; origin.x = 0; origin.y = 0; - /* Set up the destination to whole LCD screen */ + /* Clip destination to the smaller of image size and screen size */ + + dest_w = w < g_nximage.xres ? w : g_nximage.xres; + dest_h = h < g_nximage.yres ? h : g_nximage.yres; dest.pt1.x = 0; dest.pt1.y = 0; - dest.pt2.x = g_nximage.xres - 1; - dest.pt2.y = g_nximage.yres - 1; + dest.pt2.x = dest_w - 1; + dest.pt2.y = dest_h - 1; src[0] = image; + /* stride must match the source image width, not the screen width */ + ret = nx_bitmap(g_nximage.hbkgd, &dest, src, &origin, - g_nximage.xres * sizeof(nxgl_mxpixel_t)); + w * sizeof(nxgl_mxpixel_t)); if (ret < 0) { printf("nximage_image: nx_bitmap failed: %d\n", errno); diff --git a/examples/camera/camera_main.c b/examples/camera/camera_main.c index a342008b5..10bcda47e 100644 --- a/examples/camera/camera_main.c +++ b/examples/camera/camera_main.c @@ -84,13 +84,14 @@ static int camera_prepare(int fd, enum v4l2_buf_type type, uint32_t buf_mode, uint32_t pixformat, uint16_t hsize, uint16_t vsize, FAR struct v_buffer **vbuf, - uint8_t buffernum, int buffersize); + uint8_t buffernum, int buffersize, + FAR uint32_t *memory); static void free_buffer(FAR struct v_buffer *buffers, uint8_t bufnum); static int parse_arguments(int argc, FAR char *argv[], FAR int *capture_num, FAR enum v4l2_buf_type *type); static int get_camimage(int fd, FAR struct v4l2_buffer *v4l2_buf, - enum v4l2_buf_type buf_type); + enum v4l2_buf_type buf_type, uint32_t memory); static int release_camimage(int fd, FAR struct v4l2_buffer *v4l2_buf); static int start_stillcapture(int v_fd, enum v4l2_buf_type capture_type); static int stop_stillcapture(int v_fd, enum v4l2_buf_type capture_type); @@ -119,7 +120,8 @@ static int camera_prepare(int fd, enum v4l2_buf_type type, uint32_t buf_mode, uint32_t pixformat, uint16_t hsize, uint16_t vsize, FAR struct v_buffer **vbuf, - uint8_t buffernum, int buffersize) + uint8_t buffernum, int buffersize, + FAR uint32_t *memory) { int ret; int cnt; @@ -153,21 +155,30 @@ static int camera_prepare(int fd, enum v4l2_buf_type type, return ret; } - /* VIDIOC_REQBUFS initiate user pointer I/O */ + /* VIDIOC_REQBUFS: try MMAP first (driver-managed DMA buffers). + * Fall back to USERPTR if the driver does not support MMAP. + */ req.type = type; - req.memory = V4L2_MEMORY_USERPTR; + req.memory = V4L2_MEMORY_MMAP; req.count = buffernum; req.mode = buf_mode; ret = ioctl(fd, VIDIOC_REQBUFS, (uintptr_t)&req); if (ret < 0) { - printf("Failed to VIDIOC_REQBUFS: errno = %d\n", errno); - return ret; + req.memory = V4L2_MEMORY_USERPTR; + ret = ioctl(fd, VIDIOC_REQBUFS, (uintptr_t)&req); + if (ret < 0) + { + printf("Failed to VIDIOC_REQBUFS: errno = %d\n", errno); + return ret; + } } - /* Prepare video memory to store images */ + *memory = req.memory; + + /* Prepare v_buffer array to track buffer metadata */ *vbuf = malloc(sizeof(v_buffer_t) * buffernum); if (!(*vbuf)) @@ -178,29 +189,54 @@ static int camera_prepare(int fd, enum v4l2_buf_type type, for (cnt = 0; cnt < buffernum; cnt++) { - (*vbuf)[cnt].length = buffersize; - - /* Note: - * VIDIOC_QBUF set buffer pointer. - * Buffer pointer must be 32bytes aligned. - */ - - (*vbuf)[cnt].start = memalign(32, buffersize); - if (!(*vbuf)[cnt].start) + if (req.memory == V4L2_MEMORY_MMAP) { - printf("Out of memory for image buffer of %d/%d\n", - cnt, buffernum); + /* VIDIOC_QUERYBUF: get driver-allocated buffer metadata */ - /* Release allocated memory. */ + memset(&buf, 0, sizeof(v4l2_buffer_t)); + buf.type = type; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = cnt; - while (cnt--) + ret = ioctl(fd, VIDIOC_QUERYBUF, (uintptr_t)&buf); + if (ret < 0) { - free((*vbuf)[cnt].start); + printf("Failed to VIDIOC_QUERYBUF %d: errno = %d\n", + cnt, errno); + free(*vbuf); + *vbuf = NULL; + return ret; } - free(*vbuf); - *vbuf = NULL; - return ERROR; + (*vbuf)[cnt].start = NULL; + (*vbuf)[cnt].length = buf.length; + } + else + { + (*vbuf)[cnt].length = buffersize; + + /* Note: + * VIDIOC_QBUF set buffer pointer. + * Buffer pointer must be 32bytes aligned. + */ + + (*vbuf)[cnt].start = memalign(32, buffersize); + if (!(*vbuf)[cnt].start) + { + printf("Out of memory for image buffer of %d/%d\n", + cnt, buffernum); + + /* Release allocated memory. */ + + while (cnt--) + { + free((*vbuf)[cnt].start); + } + + free(*vbuf); + *vbuf = NULL; + return ERROR; + } } } @@ -210,11 +246,15 @@ static int camera_prepare(int fd, enum v4l2_buf_type type, { memset(&buf, 0, sizeof(v4l2_buffer_t)); buf.type = type; - buf.memory = V4L2_MEMORY_USERPTR; + buf.memory = req.memory; buf.index = cnt; - buf.m.userptr = (uintptr_t)(*vbuf)[cnt].start; buf.length = (*vbuf)[cnt].length; + if (req.memory == V4L2_MEMORY_USERPTR) + { + buf.m.userptr = (uintptr_t)(*vbuf)[cnt].start; + } + ret = ioctl(fd, VIDIOC_QBUF, (uintptr_t)&buf); if (ret) { @@ -336,7 +376,7 @@ static int parse_arguments(int argc, FAR char *argv[], ****************************************************************************/ static int get_camimage(int fd, FAR struct v4l2_buffer *v4l2_buf, - enum v4l2_buf_type buf_type) + enum v4l2_buf_type buf_type, uint32_t memory) { int ret; @@ -344,7 +384,7 @@ static int get_camimage(int fd, FAR struct v4l2_buffer *v4l2_buf, memset(v4l2_buf, 0, sizeof(v4l2_buffer_t)); v4l2_buf->type = buf_type; - v4l2_buf->memory = V4L2_MEMORY_USERPTR; + v4l2_buf->memory = memory; ret = ioctl(fd, VIDIOC_DQBUF, (uintptr_t)v4l2_buf); if (ret) @@ -476,6 +516,8 @@ int main(int argc, FAR char *argv[]) FAR struct v_buffer *buffers_video = NULL; FAR struct v_buffer *buffers_still = NULL; + uint32_t video_memory = V4L2_MEMORY_USERPTR; + uint32_t still_memory = V4L2_MEMORY_USERPTR; /* ===== Parse and Check arguments ===== */ @@ -564,7 +606,8 @@ int main(int argc, FAR char *argv[]) ret = camera_prepare(v_fd, V4L2_BUF_TYPE_STILL_CAPTURE, V4L2_BUF_MODE_FIFO, V4L2_PIX_FMT_JPEG, w, h, - &buffers_still, STILL_BUFNUM, IMAGE_JPG_SIZE); + &buffers_still, STILL_BUFNUM, IMAGE_JPG_SIZE, + &still_memory); if (ret != OK) { goto exit_this_app; @@ -588,7 +631,8 @@ int main(int argc, FAR char *argv[]) ret = camera_prepare(v_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_BUF_MODE_RING, V4L2_PIX_FMT_RGB565, VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA, - &buffers_video, VIDEO_BUFNUM, IMAGE_RGB_SIZE); + &buffers_video, VIDEO_BUFNUM, IMAGE_RGB_SIZE, + &video_memory); if (ret != OK) { goto exit_this_app; @@ -659,7 +703,8 @@ int main(int argc, FAR char *argv[]) case APP_STATE_BEFORE_CAPTURE: case APP_STATE_AFTER_CAPTURE: - ret = get_camimage(v_fd, &v4l2_buf, V4L2_BUF_TYPE_VIDEO_CAPTURE); + ret = get_camimage(v_fd, &v4l2_buf, + V4L2_BUF_TYPE_VIDEO_CAPTURE, video_memory); if (ret != OK) { goto exit_this_app; @@ -712,7 +757,10 @@ int main(int argc, FAR char *argv[]) while (capture_num) { - ret = get_camimage(v_fd, &v4l2_buf, capture_type); + ret = get_camimage(v_fd, &v4l2_buf, capture_type, + capture_type == + V4L2_BUF_TYPE_STILL_CAPTURE ? + still_memory : video_memory); if (ret != OK) { goto exit_this_app; From 21dd3082c1f2756ffd51b9fdf82e821a4991e483 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Fri, 3 Apr 2026 14:44:42 +0800 Subject: [PATCH 283/568] examples/camera: handle RGB565X (BE) format from 8-bit DVP camera MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some image sensors on 8-bit DVP buses (e.g. GC0308) produce RGB565X (big-endian) pixel data — the high byte is clocked out first and stored first in PSRAM by the ESP32-S3 CAM controller. The V4L2 framework does not negotiate formats automatically, so try RGB565 first and fall back to RGB565X if S_FMT fails. When the sensor reports RGB565X: - Invalidate D-Cache after DQBUF so the CPU reads fresh DMA data - Byte-swap each pixel in place from BE to LE RGB565 for display Signed-off-by: wangjianyu3 --- examples/camera/camera_main.c | 51 +++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/examples/camera/camera_main.c b/examples/camera/camera_main.c index 10bcda47e..f725460ca 100644 --- a/examples/camera/camera_main.c +++ b/examples/camera/camera_main.c @@ -38,6 +38,7 @@ #include #include +#include #include "camera_fileutil.h" #include "camera_bkgd.h" @@ -85,7 +86,8 @@ static int camera_prepare(int fd, enum v4l2_buf_type type, uint16_t hsize, uint16_t vsize, FAR struct v_buffer **vbuf, uint8_t buffernum, int buffersize, - FAR uint32_t *memory); + FAR uint32_t *memory, + FAR uint32_t *actual_fmt); static void free_buffer(FAR struct v_buffer *buffers, uint8_t bufnum); static int parse_arguments(int argc, FAR char *argv[], FAR int *capture_num, @@ -121,7 +123,8 @@ static int camera_prepare(int fd, enum v4l2_buf_type type, uint16_t hsize, uint16_t vsize, FAR struct v_buffer **vbuf, uint8_t buffernum, int buffersize, - FAR uint32_t *memory) + FAR uint32_t *memory, + FAR uint32_t *actual_fmt) { int ret; int cnt; @@ -149,12 +152,27 @@ static int camera_prepare(int fd, enum v4l2_buf_type type, fmt.fmt.pix.pixelformat = pixformat; ret = ioctl(fd, VIDIOC_S_FMT, (uintptr_t)&fmt); + if (ret < 0 && pixformat == V4L2_PIX_FMT_RGB565) + { + /* Some sensors on 8-bit DVP output big-endian RGB565 (RGB565X). + * Retry with RGB565X if RGB565 is not supported. + */ + + fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565X; + ret = ioctl(fd, VIDIOC_S_FMT, (uintptr_t)&fmt); + } + if (ret < 0) { printf("Failed to VIDIOC_S_FMT: errno = %d\n", errno); return ret; } + if (actual_fmt) + { + *actual_fmt = fmt.fmt.pix.pixelformat; + } + /* VIDIOC_REQBUFS: try MMAP first (driver-managed DMA buffers). * Fall back to USERPTR if the driver does not support MMAP. */ @@ -518,6 +536,7 @@ int main(int argc, FAR char *argv[]) FAR struct v_buffer *buffers_still = NULL; uint32_t video_memory = V4L2_MEMORY_USERPTR; uint32_t still_memory = V4L2_MEMORY_USERPTR; + uint32_t video_pixfmt = V4L2_PIX_FMT_RGB565; /* ===== Parse and Check arguments ===== */ @@ -607,7 +626,7 @@ int main(int argc, FAR char *argv[]) V4L2_BUF_MODE_FIFO, V4L2_PIX_FMT_JPEG, w, h, &buffers_still, STILL_BUFNUM, IMAGE_JPG_SIZE, - &still_memory); + &still_memory, NULL); if (ret != OK) { goto exit_this_app; @@ -632,7 +651,7 @@ int main(int argc, FAR char *argv[]) V4L2_BUF_MODE_RING, V4L2_PIX_FMT_RGB565, VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA, &buffers_video, VIDEO_BUFNUM, IMAGE_RGB_SIZE, - &video_memory); + &video_memory, &video_pixfmt); if (ret != OK) { goto exit_this_app; @@ -704,13 +723,35 @@ int main(int argc, FAR char *argv[]) case APP_STATE_BEFORE_CAPTURE: case APP_STATE_AFTER_CAPTURE: ret = get_camimage(v_fd, &v4l2_buf, - V4L2_BUF_TYPE_VIDEO_CAPTURE, video_memory); + V4L2_BUF_TYPE_VIDEO_CAPTURE, video_memory); if (ret != OK) { goto exit_this_app; } #ifdef CONFIG_EXAMPLES_CAMERA_OUTPUT_LCD + /* If the sensor outputs RGB565X (big-endian), invalidate + * D-Cache so we read fresh DMA data from PSRAM, then + * byte-swap in place for display and swap back before + * returning the buffer to the driver. + */ + + if (video_pixfmt == V4L2_PIX_FMT_RGB565X) + { + FAR uint16_t *p = (FAR uint16_t *)v4l2_buf.m.userptr; + uint32_t npixels = v4l2_buf.bytesused / 2; + uint32_t i; + + up_invalidate_dcache((uintptr_t)p, + (uintptr_t)p + v4l2_buf.bytesused); + + for (i = 0; i < npixels; i++) + { + uint16_t v = p[i]; + p[i] = (v >> 8) | (v << 8); + } + } + nximage_draw((FAR void *)v4l2_buf.m.userptr, VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA); #endif From f95b53d15b1c15c9b313750499b0b38d647dce4f Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Tue, 7 Apr 2026 11:22:32 +0800 Subject: [PATCH 284/568] examples/camera: add -m option for horizontal mirror preview Add -m command line option to enable horizontal mirror on the camera sensor via VIDIOC_S_CTRL + V4L2_CID_HFLIP. This uses the sensor hardware mirror (e.g. GC0308 register 0x14 bit[0]) with zero CPU overhead. Also refactor parse_arguments to use a loop-based parser so options can appear in any order. Usage: camera 0 -m (mirror preview) camera -jpg -m (mirror still capture) Signed-off-by: wangjianyu3 --- examples/camera/camera_main.c | 75 ++++++++++++++++------------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/examples/camera/camera_main.c b/examples/camera/camera_main.c index f725460ca..c2c83e762 100644 --- a/examples/camera/camera_main.c +++ b/examples/camera/camera_main.c @@ -91,7 +91,8 @@ static int camera_prepare(int fd, enum v4l2_buf_type type, static void free_buffer(FAR struct v_buffer *buffers, uint8_t bufnum); static int parse_arguments(int argc, FAR char *argv[], FAR int *capture_num, - FAR enum v4l2_buf_type *type); + FAR enum v4l2_buf_type *type, + FAR bool *mirror); static int get_camimage(int fd, FAR struct v4l2_buffer *v4l2_buf, enum v4l2_buf_type buf_type, uint32_t memory); static int release_camimage(int fd, FAR struct v4l2_buffer *v4l2_buf); @@ -330,58 +331,36 @@ static void free_buffer(FAR struct v_buffer *buffers, uint8_t bufnum) static int parse_arguments(int argc, FAR char *argv[], FAR int *capture_num, - FAR enum v4l2_buf_type *type) + FAR enum v4l2_buf_type *type, + FAR bool *mirror) { - if (argc == 1) + int i; + + *capture_num = DEFAULT_CAPTURE_NUM; + *type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + *mirror = false; + + for (i = 1; i < argc; i++) { - *capture_num = DEFAULT_CAPTURE_NUM; - *type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - else if (argc == 2) - { - if (strncmp(argv[1], "-jpg", 5) == 0) + if (strncmp(argv[i], "-jpg", 5) == 0) { - *capture_num = DEFAULT_CAPTURE_NUM; *type = V4L2_BUF_TYPE_STILL_CAPTURE; } + else if (strncmp(argv[i], "-m", 3) == 0) + { + *mirror = true; + } else { - *capture_num = atoi(argv[1]); + *capture_num = atoi(argv[i]); if (*capture_num < 0 || *capture_num > MAX_CAPTURE_NUM) { printf("Invalid capture num(%d). must be >=0 and <=%d\n", *capture_num, MAX_CAPTURE_NUM); return ERROR; } - - *type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } } - else if (argc == 3) - { - if (strncmp(argv[1], "-jpg", 5) == 0) - { - *capture_num = atoi(argv[2]); - if (*capture_num < 0 || *capture_num > MAX_CAPTURE_NUM) - { - printf("Invalid capture num(%d). must be >=0 and <=%d\n", - *capture_num, MAX_CAPTURE_NUM); - return ERROR; - } - - *type = V4L2_BUF_TYPE_STILL_CAPTURE; - } - else - { - printf("Invalid argument 1 : %s\n", argv[1]); - return ERROR; - } - } - else - { - printf("Too many arguments\n"); - return ERROR; - } return OK; } @@ -537,13 +516,14 @@ int main(int argc, FAR char *argv[]) uint32_t video_memory = V4L2_MEMORY_USERPTR; uint32_t still_memory = V4L2_MEMORY_USERPTR; uint32_t video_pixfmt = V4L2_PIX_FMT_RGB565; + bool mirror = false; /* ===== Parse and Check arguments ===== */ - ret = parse_arguments(argc, argv, &capture_num, &capture_type); + ret = parse_arguments(argc, argv, &capture_num, &capture_type, &mirror); if (ret != OK) { - printf("usage: %s ([-jpg]) ([capture num])\n", argv[0]); + printf("usage: %s [-jpg] [-m] [capture num]\n", argv[0]); return ERROR; } @@ -583,6 +563,21 @@ int main(int argc, FAR char *argv[]) goto exit_without_cleaning_buffer; } + /* Set horizontal mirror if requested */ + + if (mirror) + { + struct v4l2_control ctrl; + + ctrl.id = V4L2_CID_HFLIP; + ctrl.value = 1; + ret = ioctl(v_fd, VIDIOC_S_CTRL, (uintptr_t)&ctrl); + if (ret < 0) + { + printf("WARNING: VIDIOC_S_CTRL HFLIP failed: %d\n", errno); + } + } + /* Prepare for STILL_CAPTURE stream. * * The video buffer mode is V4L2_BUF_MODE_FIFO mode. From bfbeafabbfd6d4638f5892544ab51a55baf5a999 Mon Sep 17 00:00:00 2001 From: Filipe Cavalcanti Date: Tue, 31 Mar 2026 21:16:00 -0300 Subject: [PATCH 285/568] netutils/mqttc: fix patch and add mbedtls dependency Add mbedtls dependecy and fix patch path. Signed-off-by: Filipe Cavalcanti --- netutils/mqttc/CMakeLists.txt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/netutils/mqttc/CMakeLists.txt b/netutils/mqttc/CMakeLists.txt index ae03435be..420c987b1 100644 --- a/netutils/mqttc/CMakeLists.txt +++ b/netutils/mqttc/CMakeLists.txt @@ -33,7 +33,7 @@ if(CONFIG_NETUTILS_MQTTC) FetchContent_Declare( mqttc_fetch URL ${MQTTC_URL}/${CONFIG_NETUTILS_MQTTC_VERSION}.tar.gz SOURCE_DIR - ${MQTTC_DIR} BINARY_DIR ${CMAKE_BINARY_DIR}/apps/netutils/mqttc/MQTT-C + ${MQTTC_DIR} BINARY_DIR ${NUTTX_APPS_BINDIR}/netutils/mqttc/MQTT-C DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -44,9 +44,8 @@ if(CONFIG_NETUTILS_MQTTC) endif() execute_process( - COMMAND - sh -c - "cat 0001_add_connection_status.patch | patch -s -N -d $(MQTTC_DIR) -p1" + COMMAND patch -s -N -d ${MQTTC_DIR} -p1 -i + ${CMAKE_CURRENT_LIST_DIR}/0001_add_connection_status.patch WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) endif() @@ -65,6 +64,10 @@ if(CONFIG_NETUTILS_MQTTC) target_sources(mqttc PRIVATE ${CSRCS}) target_compile_options(mqttc PRIVATE ${CFLAGS}) + if(CONFIG_NETUTILS_MQTTC_WITH_MBEDTLS AND CONFIG_CRYPTO_MBEDTLS) + nuttx_add_dependencies(TARGET mqttc DEPENDS mbedtls) + endif() + if(CONFIG_NETUTILS_MQTTC_EXAMPLE) if(CONFIG_NETUTILS_MQTTC_WITH_MBEDTLS) nuttx_add_application( @@ -79,7 +82,8 @@ if(CONFIG_NETUTILS_MQTTC) COMPILE_FLAGS ${CFLAGS} DEPENDS - mqttc) + mqttc + mbedtls) else() set(MQTT_PUB_CFLAGS ${CFLAGS} From 3591378113d72806e8ca4cb523f8b9bc2d95bdaa Mon Sep 17 00:00:00 2001 From: Filipe Cavalcanti Date: Tue, 31 Mar 2026 21:16:47 -0300 Subject: [PATCH 286/568] crypto/mbedtls: expose include paths as public Expose include paths as public when using CMake. Signed-off-by: Filipe Cavalcanti --- crypto/mbedtls/CMakeLists.txt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/crypto/mbedtls/CMakeLists.txt b/crypto/mbedtls/CMakeLists.txt index 9a80ffab9..478a257bd 100644 --- a/crypto/mbedtls/CMakeLists.txt +++ b/crypto/mbedtls/CMakeLists.txt @@ -129,18 +129,16 @@ if(CONFIG_CRYPTO_MBEDTLS) # Library Configuration # ############################################################################ - set_property( - TARGET nuttx - APPEND - PROPERTY NUTTX_INCLUDE_DIRECTORIES ${INCDIR}) - set_property( - TARGET nuttx - APPEND - PROPERTY NUTTX_CXX_INCLUDE_DIRECTORIES ${INCDIR}) - nuttx_add_library(mbedtls STATIC) target_sources(mbedtls PRIVATE ${CSRCS}) - target_include_directories(mbedtls PRIVATE ${INCDIR}) + target_include_directories(mbedtls PUBLIC ${INCDIR}) + nuttx_export_header(TARGET mbedtls INCLUDE_DIRECTORIES ${MBEDTLS_DIR}/include) + # Overlay mbedtls_config.h cannot be in the same nuttx_export_header() as + # ${MBEDTLS_DIR}/include (duplicate path). Alt headers need no export; INCDIR + # supplies them for this library only. + nuttx_create_symlink( + ${CMAKE_CURRENT_LIST_DIR}/include/mbedtls/mbedtls_config.h + ${NUTTX_APPS_BINDIR}/include/mbedtls/mbedtls/mbedtls_config.h) target_compile_definitions(mbedtls PRIVATE unix) if(CONFIG_ARCH_SIM) From 9d849adfabac2a33ef1ee73ecfdc3648eb5f7454 Mon Sep 17 00:00:00 2001 From: Piyush Patle Date: Wed, 1 Apr 2026 16:29:59 +0530 Subject: [PATCH 287/568] include/debug.h: Use in apps Replace app-side includes of with to use the header from the NuttX tree explicitly after the header move. Signed-off-by: Piyush Patle --- builtin/exec_builtin.c | 2 +- canutils/canlib/canlib_getbaud.c | 2 +- canutils/canlib/canlib_getloopback.c | 2 +- canutils/canlib/canlib_getsilent.c | 2 +- canutils/canlib/canlib_setbaud.c | 2 +- canutils/canlib/canlib_setloopback.c | 2 +- canutils/canlib/canlib_setsilent.c | 2 +- examples/adc/adc_main.c | 4 ++-- examples/ajoystick/ajoy_main.c | 2 +- examples/battery/batt_main.c | 4 ++-- examples/bridge/bridge_main.c | 2 +- examples/camera/camera_bkgd.c | 2 +- examples/can/can_main.c | 2 +- examples/capture/cap_main.c | 2 +- examples/chat/chat_main.c | 2 +- examples/configdata/configdata_main.c | 4 ++-- examples/cordic/cordic_main.c | 2 +- examples/discover/discover_main.c | 2 +- examples/djoystick/djoy_main.c | 2 +- examples/elf/main/elf_main.c | 2 +- examples/etl/etl_main.cxx | 2 +- examples/fbcon/fbcon_main.c | 5 ++--- examples/flowc/flowc.h | 2 +- examples/ft80x/ft80x.h | 2 +- examples/ftpd/ftpd_main.c | 2 +- examples/hall/hall_main.c | 2 +- examples/helloxx/helloxx_main.cxx | 2 +- examples/hts221_reader/hts221_reader_main.c | 2 +- examples/i2schar/i2schar_main.c | 2 +- examples/i2schar/i2schar_receiver.c | 2 +- examples/i2schar/i2schar_transmitter.c | 2 +- examples/igmp/igmp.c | 2 +- examples/igmp/igmp.h | 2 +- examples/ipcfg/ipcfg_main.c | 2 +- examples/keyboard/kbd_main.c | 2 +- examples/lis3dsh_reader/lis3dsh_reader_main.c | 2 +- examples/lsm303_reader/lsm303_reader_main.c | 2 +- examples/lsm6dsl_reader/lsm6dsl_reader_main.c | 2 +- examples/lvglterm/lvglterm.c | 2 +- examples/mld/mld.h | 2 +- examples/mld/mld_main.c | 2 +- examples/module/chardev/chardev.c | 2 +- examples/module/main/module_main.c | 2 +- examples/mtdpart/mtdpart_main.c | 2 +- examples/mtdrwb/mtdrwb_main.c | 2 +- examples/netloop/lo_listener.c | 2 +- examples/netloop/lo_main.c | 2 +- examples/nettest/nettest.h | 2 +- examples/nettest/nettest_netinit.c | 2 +- examples/nettest/nettest_target1.c | 2 +- examples/nng_test/pubsub.c | 2 +- examples/nrf24l01_btle/nrf24l01_btle.c | 2 +- examples/nrf24l01_btle/nrf24l01_btle.h | 2 +- examples/nrf24l01_term/nrf24l01_term.c | 2 +- examples/nunchuck/nunchuck_main.c | 2 +- examples/nx/nx_events.c | 2 +- examples/nx/nx_kbdin.c | 2 +- examples/nx/nx_main.c | 2 +- examples/nxdemo/nxdemo_bkgd.c | 2 +- examples/nxdemo/nxdemo_main.c | 2 +- examples/nxflat/nxflat_main.c | 2 +- examples/nxhello/nxhello_bkgd.c | 2 +- examples/nxhello/nxhello_main.c | 2 +- examples/nximage/nximage_bkgd.c | 2 +- examples/nximage/nximage_main.c | 2 +- examples/nxlines/nxlines_bkgd.c | 2 +- examples/nxlines/nxlines_main.c | 2 +- examples/nxterm/nxterm_main.c | 2 +- examples/nxterm/nxterm_toolbar.c | 2 +- examples/nxterm/nxterm_wndo.c | 2 +- examples/nxtext/nxtext_bkgd.c | 2 +- examples/nxtext/nxtext_main.c | 2 +- examples/nxtext/nxtext_popup.c | 2 +- examples/nxtext/nxtext_putc.c | 4 ++-- examples/pf_ieee802154/pfieee802154.h | 2 +- examples/poll/net_listener.c | 2 +- examples/poll/net_reader.c | 2 +- examples/poll/poll_listener.c | 2 +- examples/poll/poll_main.c | 2 +- examples/poll/select_listener.c | 2 +- examples/posix_spawn/spawn_main.c | 2 +- examples/powerled/powerled_main.c | 2 +- examples/powermonitor/powermonitor_main.c | 2 +- examples/pwfb/pwfb_events.c | 2 +- examples/pwfb/pwfb_main.c | 2 +- examples/pwlines/pwlines_events.c | 2 +- examples/pwlines/pwlines_main.c | 2 +- examples/pwlines/pwlines_update.c | 2 +- examples/pwm/pwm_main.c | 4 ++-- examples/qencoder/qe_main.c | 4 ++-- examples/random/random_main.c | 2 +- examples/relays/relays_main.c | 2 +- examples/rmtchar/rmtchar_common.c | 2 +- examples/rmtchar/rmtchar_main.c | 4 ++-- examples/rmtchar/rmtchar_receiver.c | 2 +- examples/rmtchar/rmtchar_transmitter.c | 2 +- examples/smps/smps_main.c | 2 +- examples/sotest/main/sotest_main.c | 2 +- examples/sx127x_demo/sx127x_demo.c | 2 +- examples/tcpblaster/tcpblaster.h | 2 +- examples/tcpblaster/tcpblaster_netinit.c | 2 +- examples/tcpblaster/tcpblaster_target1.c | 2 +- examples/tcpecho/tcpecho_main.c | 2 +- examples/thttpd/thttpd_main.c | 2 +- examples/touchscreen/tc_main.c | 2 +- examples/udp/udp.h | 2 +- examples/udp/udp_netinit.c | 2 +- examples/udpblaster/udpblaster_target.c | 2 +- examples/usbserial/usbserial_main.c | 2 +- examples/usrsocktest/usrsocktest_daemon.c | 2 +- examples/usrsocktest/usrsocktest_main.c | 2 +- examples/watchdog/watchdog_main.c | 2 +- examples/watcher/wdt.c | 2 +- examples/webserver/webserver_main.c | 2 +- examples/wgetjson/wgetjson_main.c | 2 +- examples/ws2812/ws2812_main.c | 4 ++-- examples/ws2812esp32rmt/ws2812esp32rmt_main.c | 2 +- examples/xmlrpc/xmlrpc_main.c | 2 +- examples/zerocross/zerocross_main.c | 2 +- fsutils/flash_eraseall/flash_eraseall.c | 2 +- fsutils/flashtool/flashtool_main.c | 2 +- fsutils/inifile/inifile.c | 2 +- fsutils/ipcfg/ipcfg.c | 2 +- fsutils/ipcfg/ipcfg_binary.c | 12 ++++++------ fsutils/ipcfg/ipcfg_text.c | 14 +++++++------- fsutils/mkfatfs/configfat.c | 2 +- fsutils/mkfatfs/mkfatfs.c | 2 +- fsutils/mkfatfs/writefat.c | 6 +++--- fsutils/mkgpt/mkgpt.c | 2 +- graphics/ft80x/ft80x.h | 2 +- graphics/input/generator/input_gen_ctx.c | 2 +- graphics/input/generator/input_gen_dev.c | 2 +- graphics/input/generator/input_gen_event.c | 2 +- .../nxwidgets/UnitTests/CButton/cbutton_main.cxx | 2 +- .../nxwidgets/UnitTests/CButton/cbuttontest.cxx | 2 +- .../nxwidgets/UnitTests/CButton/cbuttontest.hxx | 2 +- .../UnitTests/CButtonArray/cbuttonarray_main.cxx | 2 +- .../UnitTests/CButtonArray/cbuttonarraytest.cxx | 2 +- .../UnitTests/CButtonArray/cbuttonarraytest.hxx | 2 +- .../UnitTests/CCheckBox/ccheckbox_main.cxx | 2 +- .../UnitTests/CCheckBox/ccheckboxtest.cxx | 2 +- .../UnitTests/CCheckBox/ccheckboxtest.hxx | 2 +- .../UnitTests/CGlyphButton/cglyphbutton_main.cxx | 2 +- .../UnitTests/CGlyphButton/cglyphbuttontest.cxx | 2 +- .../UnitTests/CGlyphButton/cglyphbuttontest.hxx | 2 +- .../cglyphsliderhorizontal_main.cxx | 2 +- .../cglyphsliderhorizontaltest.cxx | 2 +- .../cglyphsliderhorizontaltest.hxx | 2 +- .../nxwidgets/UnitTests/CImage/cimage_main.cxx | 2 +- graphics/nxwidgets/UnitTests/CImage/cimagetest.cxx | 2 +- graphics/nxwidgets/UnitTests/CImage/cimagetest.hxx | 2 +- .../nxwidgets/UnitTests/CKeypad/ckeypad_main.cxx | 2 +- .../nxwidgets/UnitTests/CKeypad/ckeypadtest.cxx | 2 +- .../nxwidgets/UnitTests/CKeypad/ckeypadtest.hxx | 2 +- .../nxwidgets/UnitTests/CLabel/clabel_main.cxx | 2 +- graphics/nxwidgets/UnitTests/CLabel/clabeltest.cxx | 2 +- graphics/nxwidgets/UnitTests/CLabel/clabeltest.hxx | 2 +- .../UnitTests/CLatchButton/clatchbutton_main.cxx | 2 +- .../UnitTests/CLatchButton/clatchbuttontest.cxx | 2 +- .../UnitTests/CLatchButton/clatchbuttontest.hxx | 2 +- .../CLatchButtonArray/clatchbuttonarray_main.cxx | 2 +- .../CLatchButtonArray/clatchbuttonarraytest.cxx | 2 +- .../CLatchButtonArray/clatchbuttonarraytest.hxx | 2 +- .../nxwidgets/UnitTests/CListBox/clistbox_main.cxx | 2 +- .../nxwidgets/UnitTests/CListBox/clistboxtest.cxx | 2 +- .../nxwidgets/UnitTests/CListBox/clistboxtest.hxx | 2 +- .../UnitTests/CProgressBar/cprogressbar_main.cxx | 2 +- .../UnitTests/CProgressBar/cprogressbartest.cxx | 2 +- .../UnitTests/CProgressBar/cprogressbartest.hxx | 2 +- .../UnitTests/CRadioButton/cradiobutton_main.cxx | 2 +- .../UnitTests/CRadioButton/cradiobuttontest.cxx | 2 +- .../UnitTests/CRadioButton/cradiobuttontest.hxx | 2 +- .../cscrollbarhorizontal_main.cxx | 2 +- .../cscrollbarhorizontaltest.cxx | 2 +- .../cscrollbarhorizontaltest.hxx | 2 +- .../CScrollbarVertical/cscrollbarvertical_main.cxx | 2 +- .../CScrollbarVertical/cscrollbarverticaltest.cxx | 2 +- .../CScrollbarVertical/cscrollbarverticaltest.hxx | 2 +- .../CSliderHorizonal/csliderhorizontal_main.cxx | 2 +- .../CSliderHorizonal/csliderhorizontaltest.cxx | 2 +- .../CSliderHorizonal/csliderhorizontaltest.hxx | 2 +- .../CSliderVertical/cslidervertical_main.cxx | 2 +- .../CSliderVertical/csliderverticaltest.cxx | 2 +- .../CSliderVertical/csliderverticaltest.hxx | 2 +- .../nxwidgets/UnitTests/CTextBox/ctextbox_main.cxx | 2 +- .../nxwidgets/UnitTests/CTextBox/ctextboxtest.cxx | 2 +- .../nxwidgets/UnitTests/CTextBox/ctextboxtest.hxx | 2 +- graphics/nxwidgets/src/ccallback.cxx | 4 ++-- graphics/nxwidgets/src/cgraphicsport.cxx | 2 +- graphics/nxwidgets/src/cimage.cxx | 2 +- graphics/nxwidgets/src/clabelgrid.cxx | 2 +- graphics/nxwidgets/src/cnumericedit.cxx | 2 +- graphics/nxwidgets/src/cnxserver.cxx | 2 +- graphics/nxwidgets/src/cnxtimer.cxx | 2 +- graphics/nxwidgets/src/cscaledbitmap.cxx | 4 ++-- graphics/nxwidgets/src/cscrollingpanel.cxx | 2 +- graphics/nxwidgets/src/cwidgetcontrol.cxx | 2 +- graphics/nxwidgets/src/singletons.cxx | 2 +- graphics/nxwm/src/ccalibration.cxx | 2 +- graphics/nxwm/src/chexcalculator.cxx | 2 +- graphics/nxwm/src/ckeyboard.cxx | 4 ++-- graphics/nxwm/src/cmediaplayer.cxx | 2 +- graphics/nxwm/src/cnxterm.cxx | 2 +- graphics/nxwm/src/ctaskbar.cxx | 4 ++-- graphics/nxwm/src/ctouchscreen.cxx | 6 +++--- graphics/nxwm/src/cwindowmessenger.cxx | 2 +- graphics/slcd/cslcd.cxx | 2 +- graphics/tiff/tiff_addstrip.c | 2 +- graphics/tiff/tiff_finalize.c | 2 +- graphics/tiff/tiff_initialize.c | 10 +++++----- graphics/tiff/tiff_utils.c | 4 ++-- graphics/twm4nx/apps/ccalibration.cxx | 2 +- graphics/twm4nx/apps/cclock.cxx | 2 +- graphics/twm4nx/apps/cnxterm.cxx | 2 +- graphics/twm4nx/src/cmainmenu.cxx | 2 +- include/graphics/nxwidgets/cscaledbitmap.hxx | 2 +- include/graphics/nxwm/cstartwindow.hxx | 2 +- include/graphics/twm4nx/apps/calib_config.hxx | 2 +- include/graphics/twm4nx/apps/clock_config.hxx | 2 +- include/graphics/twm4nx/apps/nxterm_config.hxx | 2 +- include/graphics/twm4nx/ciconwidget.hxx | 2 +- include/graphics/twm4nx/twm4nx_config.hxx | 2 +- include/netutils/cmux.h | 2 +- industry/foc/fixed16/foc_cordic.c | 2 +- industry/foc/float/foc_cordic.c | 2 +- interpreters/python/python_wrapper.c | 2 +- logging/nxscope/nxscope.c | 4 ++-- logging/nxscope/nxscope_chan.c | 2 +- logging/nxscope/nxscope_idummy.c | 2 +- logging/nxscope/nxscope_internals.c | 2 +- logging/nxscope/nxscope_iser.c | 2 +- logging/nxscope/nxscope_iudp.c | 2 +- logging/nxscope/nxscope_pser.c | 4 ++-- lte/alt1250/alt1250_dbg.h | 2 +- lte/lapi/src/lapi_dbg.h | 2 +- netutils/chat/chat.c | 2 +- netutils/cmux/cmux.h | 2 +- netutils/dhcp6c/dhcp6c.c | 2 +- netutils/dhcpc/dhcpc.c | 2 +- netutils/dhcpd/dhcpd.c | 2 +- netutils/discover/discover.c | 2 +- netutils/esp8266/esp8266.c | 2 +- netutils/ftpc/ftpc_chmod.c | 2 +- netutils/ftpc/ftpc_cmd.c | 2 +- netutils/ftpc/ftpc_connect.c | 2 +- netutils/ftpc/ftpc_getfile.c | 2 +- netutils/ftpc/ftpc_getreply.c | 2 +- netutils/ftpc/ftpc_idle.c | 2 +- netutils/ftpc/ftpc_listdir.c | 2 +- netutils/ftpc/ftpc_login.c | 2 +- netutils/ftpc/ftpc_putfile.c | 2 +- netutils/ftpc/ftpc_rpwd.c | 2 +- netutils/ftpc/ftpc_socket.c | 2 +- netutils/ftpc/ftpc_transfer.c | 2 +- netutils/ftpd/ftpd.c | 2 +- netutils/libcurl4nx/curl4nx_easy_cleanup.c | 2 +- netutils/libcurl4nx/curl4nx_easy_duphandle.c | 2 +- netutils/libcurl4nx/curl4nx_easy_escape.c | 2 +- netutils/libcurl4nx/curl4nx_easy_getinfo.c | 2 +- netutils/libcurl4nx/curl4nx_easy_init.c | 2 +- netutils/libcurl4nx/curl4nx_easy_perform.c | 2 +- netutils/libcurl4nx/curl4nx_easy_reset.c | 2 +- netutils/libcurl4nx/curl4nx_easy_setopt.c | 2 +- netutils/libcurl4nx/curl4nx_easy_unescape.c | 2 +- netutils/mdns/mdnsd.c | 2 +- netutils/netinit/netinit.c | 2 +- netutils/netlib/netlib_checkhttpconnectivity.c | 2 +- netutils/netlib/netlib_checkifconflict.c | 2 +- netutils/netlib/netlib_checkifconnectivity.c | 2 +- netutils/netlib/netlib_checkipconnectivity.c | 2 +- netutils/netlib/netlib_getifstatistics.c | 2 +- netutils/netlib/netlib_ipmsfilter.c | 2 +- netutils/netlib/netlib_listenon.c | 2 +- netutils/netlib/netlib_nodeaddrconv.c | 2 +- netutils/netlib/netlib_obtainipv4addr.c | 2 +- netutils/netlib/netlib_obtainipv6addr.c | 2 +- netutils/netlib/netlib_server.c | 2 +- netutils/ntpclient/ntpclient.c | 2 +- netutils/pppd/ppp.h | 2 +- netutils/pppd/pppd.c | 2 +- netutils/ptpd/ptpd.c | 2 +- netutils/telnetd/telnetd_daemon.c | 2 +- netutils/tftpc/tftpc_get.c | 2 +- netutils/tftpc/tftpc_packets.c | 2 +- netutils/tftpc/tftpc_put.c | 2 +- netutils/thttpd/fdwatch.c | 2 +- netutils/thttpd/libhttpd.c | 2 +- netutils/thttpd/tdate_parse.c | 2 +- netutils/thttpd/thttpd.c | 2 +- netutils/thttpd/thttpd_alloc.c | 2 +- netutils/thttpd/thttpd_cgi.c | 4 ++-- netutils/thttpd/timers.c | 2 +- netutils/webclient/webclient.c | 4 ++-- netutils/webserver/httpd.c | 2 +- netutils/webserver/httpd_dirlist.c | 2 +- netutils/webserver/httpd_mmap.c | 2 +- netutils/webserver/httpd_sendfile.c | 2 +- nshlib/nsh_altconsole.c | 2 +- nshlib/nsh_codeccmd.c | 2 +- nshlib/nsh_console.c | 2 +- nshlib/nsh_fscmds.c | 2 +- nshlib/nsh_mntcmds.c | 2 +- nshlib/nsh_netcmds.c | 2 +- nshlib/nsh_parse.c | 2 +- nshlib/nsh_telnetd.c | 2 +- nshlib/nsh_usbconsole.c | 2 +- nshlib/nsh_usbtrace.c | 2 +- platform/mikroe-stm32f4/mikroe_configdata.c | 4 ++-- system/cdcacm/sercon_main.c | 2 +- system/cdcacm/serdis_main.c | 2 +- system/cle/cle.c | 2 +- system/composite/composite_main.c | 2 +- system/cu/cu_main.c | 2 +- system/dd/dd_main.c | 2 +- system/dhcp6c/renew6_main.c | 2 +- system/i2c/i2c_main.c | 4 ++-- system/nxcamera/nxcamera.c | 2 +- system/nxlooper/nxlooper.c | 2 +- system/nxplayer/nxplayer.c | 2 +- system/nxplayer/nxplayer_common.c | 2 +- system/nxrecorder/nxrecorder.c | 2 +- system/nxrecorder/nxrecorder_common.c | 2 +- system/popen/popen.c | 2 +- system/readline/readline_common.c | 2 +- system/spi/spi_main.c | 2 +- system/system/system.c | 2 +- system/tee/tee.c | 2 +- system/termcurses/tcurses_vt100.c | 2 +- system/termcurses/termcurses.c | 2 +- system/ubloxmodem/ubloxmodem_main.c | 2 +- system/usbmsc/usbmsc_main.c | 2 +- system/vi/vi.c | 2 +- system/zmodem/zm.h | 6 +++--- testing/drivers/drivertest/drivertest_audio.c | 2 +- .../drivers/drivertest/drivertest_framebuffer.c | 2 +- testing/drivers/drivertest/drivertest_lcd.c | 2 +- testing/drivers/drivertest/drivertest_pwm.c | 4 ++-- testing/drivers/drivertest/drivertest_watchdog.c | 2 +- testing/drivers/nand_sim/nand_sim_main.c | 6 +++--- testing/fs/epoll/epoll.c | 10 +++++----- testing/fs/mtd_config_fs/mtd_config_fs_test_main.c | 2 +- testing/fs/nxffs/nxffs_main.c | 4 ++-- testing/fs/smart/smart_main.c | 4 ++-- testing/libc/arch_libc/arch_libc_test_main.c | 2 +- testing/libc/scanftest/scanftest_main.c | 2 +- testing/mm/memstress/memorystress_main.c | 2 +- testing/ostest/signest.c | 4 ++-- wireless/bluetooth/nimble/include/logcfg/logcfg.h | 2 +- wireless/gs2200m/gs2200m_main.c | 2 +- wireless/ieee802154/i8shark/i8shark_main.c | 2 +- wireless/wapi/src/driver_wext.c | 2 +- wireless/wapi/src/util.h | 2 +- 352 files changed, 403 insertions(+), 404 deletions(-) diff --git a/builtin/exec_builtin.c b/builtin/exec_builtin.c index 325d594cf..b87133243 100644 --- a/builtin/exec_builtin.c +++ b/builtin/exec_builtin.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include "builtin/builtin.h" diff --git a/canutils/canlib/canlib_getbaud.c b/canutils/canlib/canlib_getbaud.c index af123edea..61ebb4de9 100644 --- a/canutils/canlib/canlib_getbaud.c +++ b/canutils/canlib/canlib_getbaud.c @@ -25,7 +25,7 @@ ****************************************************************************/ #include -#include +#include #include #include diff --git a/canutils/canlib/canlib_getloopback.c b/canutils/canlib/canlib_getloopback.c index 443161e96..b931301d5 100644 --- a/canutils/canlib/canlib_getloopback.c +++ b/canutils/canlib/canlib_getloopback.c @@ -25,7 +25,7 @@ ****************************************************************************/ #include -#include +#include #include #include diff --git a/canutils/canlib/canlib_getsilent.c b/canutils/canlib/canlib_getsilent.c index 868072eb1..18e2b0637 100644 --- a/canutils/canlib/canlib_getsilent.c +++ b/canutils/canlib/canlib_getsilent.c @@ -25,7 +25,7 @@ ****************************************************************************/ #include -#include +#include #include #include diff --git a/canutils/canlib/canlib_setbaud.c b/canutils/canlib/canlib_setbaud.c index b3ee68f26..f8bbb23ff 100644 --- a/canutils/canlib/canlib_setbaud.c +++ b/canutils/canlib/canlib_setbaud.c @@ -25,7 +25,7 @@ ****************************************************************************/ #include -#include +#include #include #include diff --git a/canutils/canlib/canlib_setloopback.c b/canutils/canlib/canlib_setloopback.c index 7e78b1a34..18164210c 100644 --- a/canutils/canlib/canlib_setloopback.c +++ b/canutils/canlib/canlib_setloopback.c @@ -25,7 +25,7 @@ ****************************************************************************/ #include -#include +#include #include #include diff --git a/canutils/canlib/canlib_setsilent.c b/canutils/canlib/canlib_setsilent.c index 0900f9261..bf8ef1722 100644 --- a/canutils/canlib/canlib_setsilent.c +++ b/canutils/canlib/canlib_setsilent.c @@ -25,7 +25,7 @@ ****************************************************************************/ #include -#include +#include #include #include diff --git a/examples/adc/adc_main.c b/examples/adc/adc_main.c index 68f4f1955..e5678e123 100644 --- a/examples/adc/adc_main.c +++ b/examples/adc/adc_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include @@ -95,7 +95,7 @@ static void adc_help(FAR struct adc_state_s *adc) printf("Usage: adc [OPTIONS]\n"); printf("\nArguments are \"sticky\". " "For example, once the ADC device is\n"); - printf("specified, that device will be re-used until it is changed.\n"); + printf("specified, that device will be reused until it is changed.\n"); printf("\n\"sticky\" OPTIONS include:\n"); printf(" [-p devpath] selects the ADC device. " "Default: %s Current: %s\n", diff --git a/examples/ajoystick/ajoy_main.c b/examples/ajoystick/ajoy_main.c index 178608b2f..8a58b66a9 100644 --- a/examples/ajoystick/ajoy_main.c +++ b/examples/ajoystick/ajoy_main.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/battery/batt_main.c b/examples/battery/batt_main.c index d88a2885f..384d78147 100644 --- a/examples/battery/batt_main.c +++ b/examples/battery/batt_main.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include @@ -117,7 +117,7 @@ void health_report(int health) case BATTERY_HEALTH_GOOD: { - printf("Battery is in good condiction!\n"); + printf("Battery is in good condition!\n"); } break; diff --git a/examples/bridge/bridge_main.c b/examples/bridge/bridge_main.c index 8d2165514..183ccedbe 100644 --- a/examples/bridge/bridge_main.c +++ b/examples/bridge/bridge_main.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/camera/camera_bkgd.c b/examples/camera/camera_bkgd.c index e53010dad..a0c0bd2fa 100644 --- a/examples/camera/camera_bkgd.c +++ b/examples/camera/camera_bkgd.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/can/can_main.c b/examples/can/can_main.c index b62f565fe..422458a33 100644 --- a/examples/can/can_main.c +++ b/examples/can/can_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include diff --git a/examples/capture/cap_main.c b/examples/capture/cap_main.c index 2ba238a60..1c44e0383 100644 --- a/examples/capture/cap_main.c +++ b/examples/capture/cap_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include diff --git a/examples/chat/chat_main.c b/examples/chat/chat_main.c index caf6cca28..291e88824 100644 --- a/examples/chat/chat_main.c +++ b/examples/chat/chat_main.c @@ -45,7 +45,7 @@ #include #include -#include +#include #include #include #include diff --git a/examples/configdata/configdata_main.c b/examples/configdata/configdata_main.c index 236d8e267..3218569f6 100644 --- a/examples/configdata/configdata_main.c +++ b/examples/configdata/configdata_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include @@ -450,7 +450,7 @@ static int configdata_verifyconfig(void) { g_nverified++; #if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0 - printf(" Verifed entry %04X, %d\n", + printf(" Verified entry %04X, %d\n", entry->id, entry->instance); #endif } diff --git a/examples/cordic/cordic_main.c b/examples/cordic/cordic_main.c index 204a755ac..3d4aede0c 100644 --- a/examples/cordic/cordic_main.c +++ b/examples/cordic/cordic_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/discover/discover_main.c b/examples/discover/discover_main.c index cd14720ed..9f5941587 100644 --- a/examples/discover/discover_main.c +++ b/examples/discover/discover_main.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/djoystick/djoy_main.c b/examples/djoystick/djoy_main.c index 110de4531..b3d1134c9 100644 --- a/examples/djoystick/djoy_main.c +++ b/examples/djoystick/djoy_main.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/elf/main/elf_main.c b/examples/elf/main/elf_main.c index 7a52b5f6e..000339e00 100644 --- a/examples/elf/main/elf_main.c +++ b/examples/elf/main/elf_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/etl/etl_main.cxx b/examples/etl/etl_main.cxx index efb4aa835..f8628cdfc 100644 --- a/examples/etl/etl_main.cxx +++ b/examples/etl/etl_main.cxx @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include diff --git a/examples/fbcon/fbcon_main.c b/examples/fbcon/fbcon_main.c index 2aa95e0c5..da0833800 100644 --- a/examples/fbcon/fbcon_main.c +++ b/examples/fbcon/fbcon_main.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include @@ -1913,7 +1913,7 @@ static void fbcon_write(FAR struct fbcon_state_s *st, do { - /* Is the character part of a VT100 escape sequnce? */ + /* Is the character part of a VT100 escape sequence? */ state = fbcon_vt100(st, ch); switch (state) @@ -2652,4 +2652,3 @@ errout: fprintf(stderr, "FBCON exiting with error %d\n", exitcode); return exitcode; } - diff --git a/examples/flowc/flowc.h b/examples/flowc/flowc.h index c96fe76af..12caefa93 100644 --- a/examples/flowc/flowc.h +++ b/examples/flowc/flowc.h @@ -29,7 +29,7 @@ #ifdef EXAMPLES_FLOWC_HOST #else -# include +# include #endif /**************************************************************************** diff --git a/examples/ft80x/ft80x.h b/examples/ft80x/ft80x.h index 0349f6eb4..70492f24e 100644 --- a/examples/ft80x/ft80x.h +++ b/examples/ft80x/ft80x.h @@ -31,7 +31,7 @@ #include #include -#include +#include #ifdef CONFIG_EXAMPLES_FT80X diff --git a/examples/ftpd/ftpd_main.c b/examples/ftpd/ftpd_main.c index 5c7888b24..e2673572a 100644 --- a/examples/ftpd/ftpd_main.c +++ b/examples/ftpd/ftpd_main.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/hall/hall_main.c b/examples/hall/hall_main.c index ed3c3b570..e0fdc2e78 100644 --- a/examples/hall/hall_main.c +++ b/examples/hall/hall_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include diff --git a/examples/helloxx/helloxx_main.cxx b/examples/helloxx/helloxx_main.cxx index c3425ff6b..8df920916 100644 --- a/examples/helloxx/helloxx_main.cxx +++ b/examples/helloxx/helloxx_main.cxx @@ -27,7 +27,7 @@ #include #include -#include +#include //*************************************************************************** // Definitions diff --git a/examples/hts221_reader/hts221_reader_main.c b/examples/hts221_reader/hts221_reader_main.c index ac00ede5e..5c1c39664 100644 --- a/examples/hts221_reader/hts221_reader_main.c +++ b/examples/hts221_reader/hts221_reader_main.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include diff --git a/examples/i2schar/i2schar_main.c b/examples/i2schar/i2schar_main.c index dec7b70c1..176def927 100644 --- a/examples/i2schar/i2schar_main.c +++ b/examples/i2schar/i2schar_main.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/examples/i2schar/i2schar_receiver.c b/examples/i2schar/i2schar_receiver.c index fdcc0c8ba..e088bee9f 100644 --- a/examples/i2schar/i2schar_receiver.c +++ b/examples/i2schar/i2schar_receiver.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/i2schar/i2schar_transmitter.c b/examples/i2schar/i2schar_transmitter.c index df1560ac6..14e4ec347 100644 --- a/examples/i2schar/i2schar_transmitter.c +++ b/examples/i2schar/i2schar_transmitter.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/igmp/igmp.c b/examples/igmp/igmp.c index da904fa34..7da32c680 100644 --- a/examples/igmp/igmp.c +++ b/examples/igmp/igmp.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/igmp/igmp.h b/examples/igmp/igmp.h index 11ffb57f9..3cf99b1b0 100644 --- a/examples/igmp/igmp.h +++ b/examples/igmp/igmp.h @@ -27,7 +27,7 @@ * Included Files ****************************************************************************/ -#include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/examples/ipcfg/ipcfg_main.c b/examples/ipcfg/ipcfg_main.c index f64a73ea8..51c411081 100644 --- a/examples/ipcfg/ipcfg_main.c +++ b/examples/ipcfg/ipcfg_main.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/keyboard/kbd_main.c b/examples/keyboard/kbd_main.c index ff832c862..d793e6344 100644 --- a/examples/keyboard/kbd_main.c +++ b/examples/keyboard/kbd_main.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include diff --git a/examples/lis3dsh_reader/lis3dsh_reader_main.c b/examples/lis3dsh_reader/lis3dsh_reader_main.c index dad00b312..98194ea66 100644 --- a/examples/lis3dsh_reader/lis3dsh_reader_main.c +++ b/examples/lis3dsh_reader/lis3dsh_reader_main.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/lsm303_reader/lsm303_reader_main.c b/examples/lsm303_reader/lsm303_reader_main.c index b48e81a2d..51611720d 100644 --- a/examples/lsm303_reader/lsm303_reader_main.c +++ b/examples/lsm303_reader/lsm303_reader_main.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include diff --git a/examples/lsm6dsl_reader/lsm6dsl_reader_main.c b/examples/lsm6dsl_reader/lsm6dsl_reader_main.c index c3ec68ff7..6f7cf0355 100644 --- a/examples/lsm6dsl_reader/lsm6dsl_reader_main.c +++ b/examples/lsm6dsl_reader/lsm6dsl_reader_main.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include diff --git a/examples/lvglterm/lvglterm.c b/examples/lvglterm/lvglterm.c index 90269daa8..71c5e650e 100644 --- a/examples/lvglterm/lvglterm.c +++ b/examples/lvglterm/lvglterm.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/examples/mld/mld.h b/examples/mld/mld.h index 69d8f13a4..936a37062 100644 --- a/examples/mld/mld.h +++ b/examples/mld/mld.h @@ -27,7 +27,7 @@ * Included Files ****************************************************************************/ -#include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/examples/mld/mld_main.c b/examples/mld/mld_main.c index 363a7e41d..594115a22 100644 --- a/examples/mld/mld_main.c +++ b/examples/mld/mld_main.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/module/chardev/chardev.c b/examples/module/chardev/chardev.c index f0faa3bfb..b2fd7b61d 100644 --- a/examples/module/chardev/chardev.c +++ b/examples/module/chardev/chardev.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/module/main/module_main.c b/examples/module/main/module_main.c index 37da14fee..9eb9b205e 100644 --- a/examples/module/main/module_main.c +++ b/examples/module/main/module_main.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/mtdpart/mtdpart_main.c b/examples/mtdpart/mtdpart_main.c index 35ba65ce7..428eddc57 100644 --- a/examples/mtdpart/mtdpart_main.c +++ b/examples/mtdpart/mtdpart_main.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/mtdrwb/mtdrwb_main.c b/examples/mtdrwb/mtdrwb_main.c index 1ebbe44f5..93b9d3290 100644 --- a/examples/mtdrwb/mtdrwb_main.c +++ b/examples/mtdrwb/mtdrwb_main.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/netloop/lo_listener.c b/examples/netloop/lo_listener.c index 8b51027bb..20f72ad9c 100644 --- a/examples/netloop/lo_listener.c +++ b/examples/netloop/lo_listener.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/netloop/lo_main.c b/examples/netloop/lo_main.c index cfdfab429..513278b08 100644 --- a/examples/netloop/lo_main.c +++ b/examples/netloop/lo_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nettest/nettest.h b/examples/nettest/nettest.h index e4ff7f3cc..fd314befb 100644 --- a/examples/nettest/nettest.h +++ b/examples/nettest/nettest.h @@ -31,7 +31,7 @@ #ifdef NETTEST_HOST #else -# include +# include #endif /**************************************************************************** diff --git a/examples/nettest/nettest_netinit.c b/examples/nettest/nettest_netinit.c index 5c29ca411..e2e786164 100644 --- a/examples/nettest/nettest_netinit.c +++ b/examples/nettest/nettest_netinit.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include diff --git a/examples/nettest/nettest_target1.c b/examples/nettest/nettest_target1.c index 3875be272..47db8916b 100644 --- a/examples/nettest/nettest_target1.c +++ b/examples/nettest/nettest_target1.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include "nettest.h" diff --git a/examples/nng_test/pubsub.c b/examples/nng_test/pubsub.c index 4f285906e..78e427eb2 100644 --- a/examples/nng_test/pubsub.c +++ b/examples/nng_test/pubsub.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nrf24l01_btle/nrf24l01_btle.c b/examples/nrf24l01_btle/nrf24l01_btle.c index ee373798f..6e1490f45 100644 --- a/examples/nrf24l01_btle/nrf24l01_btle.c +++ b/examples/nrf24l01_btle/nrf24l01_btle.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nrf24l01_btle/nrf24l01_btle.h b/examples/nrf24l01_btle/nrf24l01_btle.h index 73d166356..9394ee568 100644 --- a/examples/nrf24l01_btle/nrf24l01_btle.h +++ b/examples/nrf24l01_btle/nrf24l01_btle.h @@ -31,7 +31,7 @@ #include #include -#include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/examples/nrf24l01_term/nrf24l01_term.c b/examples/nrf24l01_term/nrf24l01_term.c index b8af3dca0..c120cafc1 100644 --- a/examples/nrf24l01_term/nrf24l01_term.c +++ b/examples/nrf24l01_term/nrf24l01_term.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nunchuck/nunchuck_main.c b/examples/nunchuck/nunchuck_main.c index fa72e1ce6..63200288c 100644 --- a/examples/nunchuck/nunchuck_main.c +++ b/examples/nunchuck/nunchuck_main.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nx/nx_events.c b/examples/nx/nx_events.c index 360856584..4e5616641 100644 --- a/examples/nx/nx_events.c +++ b/examples/nx/nx_events.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nx/nx_kbdin.c b/examples/nx/nx_kbdin.c index 856323a24..cdab7fe20 100644 --- a/examples/nx/nx_kbdin.c +++ b/examples/nx/nx_kbdin.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nx/nx_main.c b/examples/nx/nx_main.c index a7b9134c0..942d59870 100644 --- a/examples/nx/nx_main.c +++ b/examples/nx/nx_main.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxdemo/nxdemo_bkgd.c b/examples/nxdemo/nxdemo_bkgd.c index fd03f08c0..ecd82b238 100644 --- a/examples/nxdemo/nxdemo_bkgd.c +++ b/examples/nxdemo/nxdemo_bkgd.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxdemo/nxdemo_main.c b/examples/nxdemo/nxdemo_main.c index ca5d5b878..e6875b9cd 100644 --- a/examples/nxdemo/nxdemo_main.c +++ b/examples/nxdemo/nxdemo_main.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxflat/nxflat_main.c b/examples/nxflat/nxflat_main.c index 0c8425e2e..c7ea6cf19 100644 --- a/examples/nxflat/nxflat_main.c +++ b/examples/nxflat/nxflat_main.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxhello/nxhello_bkgd.c b/examples/nxhello/nxhello_bkgd.c index ee73f2614..323b4870d 100644 --- a/examples/nxhello/nxhello_bkgd.c +++ b/examples/nxhello/nxhello_bkgd.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxhello/nxhello_main.c b/examples/nxhello/nxhello_main.c index 13e2b8a62..8165d9abe 100644 --- a/examples/nxhello/nxhello_main.c +++ b/examples/nxhello/nxhello_main.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nximage/nximage_bkgd.c b/examples/nximage/nximage_bkgd.c index 36ac04eda..8a86f0498 100644 --- a/examples/nximage/nximage_bkgd.c +++ b/examples/nximage/nximage_bkgd.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nximage/nximage_main.c b/examples/nximage/nximage_main.c index 4598ae4f6..fd2beac0b 100644 --- a/examples/nximage/nximage_main.c +++ b/examples/nximage/nximage_main.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxlines/nxlines_bkgd.c b/examples/nxlines/nxlines_bkgd.c index 22b068c64..f3e3940fd 100644 --- a/examples/nxlines/nxlines_bkgd.c +++ b/examples/nxlines/nxlines_bkgd.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxlines/nxlines_main.c b/examples/nxlines/nxlines_main.c index 7b3d4ba0d..85b75177e 100644 --- a/examples/nxlines/nxlines_main.c +++ b/examples/nxlines/nxlines_main.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxterm/nxterm_main.c b/examples/nxterm/nxterm_main.c index c1a912a08..6fbf0be6d 100644 --- a/examples/nxterm/nxterm_main.c +++ b/examples/nxterm/nxterm_main.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #ifdef CONFIG_NX_LCDDRIVER # include diff --git a/examples/nxterm/nxterm_toolbar.c b/examples/nxterm/nxterm_toolbar.c index 24bcee463..0fa7c0802 100644 --- a/examples/nxterm/nxterm_toolbar.c +++ b/examples/nxterm/nxterm_toolbar.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxterm/nxterm_wndo.c b/examples/nxterm/nxterm_wndo.c index 2bba6016a..c326e0449 100644 --- a/examples/nxterm/nxterm_wndo.c +++ b/examples/nxterm/nxterm_wndo.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxtext/nxtext_bkgd.c b/examples/nxtext/nxtext_bkgd.c index 1e0d4a18d..8eb55ba09 100644 --- a/examples/nxtext/nxtext_bkgd.c +++ b/examples/nxtext/nxtext_bkgd.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxtext/nxtext_main.c b/examples/nxtext/nxtext_main.c index 1ad8bb9b3..d3d02956f 100644 --- a/examples/nxtext/nxtext_main.c +++ b/examples/nxtext/nxtext_main.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxtext/nxtext_popup.c b/examples/nxtext/nxtext_popup.c index 4ca10e1b7..19dbd3cc5 100644 --- a/examples/nxtext/nxtext_popup.c +++ b/examples/nxtext/nxtext_popup.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/nxtext/nxtext_putc.c b/examples/nxtext/nxtext_putc.c index 47fdd9ba5..384ae22bb 100644 --- a/examples/nxtext/nxtext_putc.c +++ b/examples/nxtext/nxtext_putc.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include @@ -365,7 +365,7 @@ nxtext_getglyph(NXHANDLE hfont, FAR struct nxtext_state_s *st, uint8_t ch) * * Description: * This is part of the nxtext_putc logic. It creates and positions a - * the character and renders (or re-uses) a glyph for font. + * the character and renders (or reuses) a glyph for font. * ****************************************************************************/ diff --git a/examples/pf_ieee802154/pfieee802154.h b/examples/pf_ieee802154/pfieee802154.h index ee7a88b5c..adf9e3bd6 100644 --- a/examples/pf_ieee802154/pfieee802154.h +++ b/examples/pf_ieee802154/pfieee802154.h @@ -27,7 +27,7 @@ * Included Files ****************************************************************************/ -#include +#include #include /**************************************************************************** diff --git a/examples/poll/net_listener.c b/examples/poll/net_listener.c index 9db855477..e20306d6c 100644 --- a/examples/poll/net_listener.c +++ b/examples/poll/net_listener.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/poll/net_reader.c b/examples/poll/net_reader.c index 5e22822e3..288179763 100644 --- a/examples/poll/net_reader.c +++ b/examples/poll/net_reader.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/poll/poll_listener.c b/examples/poll/poll_listener.c index 5864c4222..ce912357d 100644 --- a/examples/poll/poll_listener.c +++ b/examples/poll/poll_listener.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include diff --git a/examples/poll/poll_main.c b/examples/poll/poll_main.c index 817916839..5dfb2d938 100644 --- a/examples/poll/poll_main.c +++ b/examples/poll/poll_main.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include "poll_internal.h" diff --git a/examples/poll/select_listener.c b/examples/poll/select_listener.c index 69cfe92d6..e99eda06d 100644 --- a/examples/poll/select_listener.c +++ b/examples/poll/select_listener.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include "poll_internal.h" diff --git a/examples/posix_spawn/spawn_main.c b/examples/posix_spawn/spawn_main.c index 100030b6c..34428d472 100644 --- a/examples/posix_spawn/spawn_main.c +++ b/examples/posix_spawn/spawn_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/powerled/powerled_main.c b/examples/powerled/powerled_main.c index 4478d2ee7..b949aadfa 100644 --- a/examples/powerled/powerled_main.c +++ b/examples/powerled/powerled_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #ifndef CONFIG_NSH_ARCHINIT diff --git a/examples/powermonitor/powermonitor_main.c b/examples/powermonitor/powermonitor_main.c index 3a335dd66..0e13e3b4b 100644 --- a/examples/powermonitor/powermonitor_main.c +++ b/examples/powermonitor/powermonitor_main.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include diff --git a/examples/pwfb/pwfb_events.c b/examples/pwfb/pwfb_events.c index 142985ab7..bec7a845a 100644 --- a/examples/pwfb/pwfb_events.c +++ b/examples/pwfb/pwfb_events.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/pwfb/pwfb_main.c b/examples/pwfb/pwfb_main.c index 6a7bfc438..3b5993372 100644 --- a/examples/pwfb/pwfb_main.c +++ b/examples/pwfb/pwfb_main.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/pwlines/pwlines_events.c b/examples/pwlines/pwlines_events.c index 73a2b80a6..3dcd0504c 100644 --- a/examples/pwlines/pwlines_events.c +++ b/examples/pwlines/pwlines_events.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/pwlines/pwlines_main.c b/examples/pwlines/pwlines_main.c index dc776d744..8d448cc11 100644 --- a/examples/pwlines/pwlines_main.c +++ b/examples/pwlines/pwlines_main.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/pwlines/pwlines_update.c b/examples/pwlines/pwlines_update.c index 2dbe4e39e..37d41456e 100644 --- a/examples/pwlines/pwlines_update.c +++ b/examples/pwlines/pwlines_update.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/pwm/pwm_main.c b/examples/pwm/pwm_main.c index 7a1a83c16..683587f08 100644 --- a/examples/pwm/pwm_main.c +++ b/examples/pwm/pwm_main.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include @@ -199,7 +199,7 @@ static void pwm_help(FAR struct pwm_state_s *pwm) printf("Usage: pwm [OPTIONS]\n"); printf("\nArguments are \"sticky\". " "For example, once the PWM frequency is\n"); - printf("specified, that frequency will be re-used until it is changed.\n"); + printf("specified, that frequency will be reused until it is changed.\n"); printf("\n\"sticky\" OPTIONS include:\n"); printf(" [-p devpath] selects the PWM device. " "Default: %s Current: %s\n", diff --git a/examples/qencoder/qe_main.c b/examples/qencoder/qe_main.c index 2614fe7fb..504db260d 100644 --- a/examples/qencoder/qe_main.c +++ b/examples/qencoder/qe_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include @@ -317,7 +317,7 @@ int main(int argc, FAR char *argv[]) goto errout_with_dev; } - /* GETINDEX succesful */ + /* GETINDEX successful */ else { diff --git a/examples/random/random_main.c b/examples/random/random_main.c index 2b1be2827..3a35b4e89 100644 --- a/examples/random/random_main.c +++ b/examples/random/random_main.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include /**************************************************************************** diff --git a/examples/relays/relays_main.c b/examples/relays/relays_main.c index f5ab6fb7b..83e108419 100644 --- a/examples/relays/relays_main.c +++ b/examples/relays/relays_main.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #ifdef CONFIG_ARCH_RELAYS diff --git a/examples/rmtchar/rmtchar_common.c b/examples/rmtchar/rmtchar_common.c index 663f0abd5..098e5363a 100644 --- a/examples/rmtchar/rmtchar_common.c +++ b/examples/rmtchar/rmtchar_common.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include "rmtchar.h" diff --git a/examples/rmtchar/rmtchar_main.c b/examples/rmtchar/rmtchar_main.c index dcf2c54f2..63a8ced85 100644 --- a/examples/rmtchar/rmtchar_main.c +++ b/examples/rmtchar/rmtchar_main.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "rmtchar.h" @@ -112,7 +112,7 @@ static void rmtchar_help(FAR struct rmtchar_state_s *rmtchar) printf("Usage: rmtchar [OPTIONS]\n"); printf("\nArguments are \"sticky\".\n"); printf("For example, once the RMT character device is\n"); - printf("specified, that device will be re-used until it is changed.\n"); + printf("specified, that device will be reused until it is changed.\n"); printf("\n\"sticky\" OPTIONS include:\n"); printf(" [-i items] selects the number of words (items) to be transmitted" " or received by the RMT character device. " diff --git a/examples/rmtchar/rmtchar_receiver.c b/examples/rmtchar/rmtchar_receiver.c index b6d94800e..2e1b20e36 100644 --- a/examples/rmtchar/rmtchar_receiver.c +++ b/examples/rmtchar/rmtchar_receiver.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include "rmtchar.h" diff --git a/examples/rmtchar/rmtchar_transmitter.c b/examples/rmtchar/rmtchar_transmitter.c index 8c0528e2a..75fc0103b 100644 --- a/examples/rmtchar/rmtchar_transmitter.c +++ b/examples/rmtchar/rmtchar_transmitter.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/smps/smps_main.c b/examples/smps/smps_main.c index ba6a7b079..852696855 100644 --- a/examples/smps/smps_main.c +++ b/examples/smps/smps_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/sotest/main/sotest_main.c b/examples/sotest/main/sotest_main.c index 98b11730c..0d399568f 100644 --- a/examples/sotest/main/sotest_main.c +++ b/examples/sotest/main/sotest_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/sx127x_demo/sx127x_demo.c b/examples/sx127x_demo/sx127x_demo.c index 05175a6ed..a93fe74fe 100644 --- a/examples/sx127x_demo/sx127x_demo.c +++ b/examples/sx127x_demo/sx127x_demo.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/tcpblaster/tcpblaster.h b/examples/tcpblaster/tcpblaster.h index 9fc7c4dcc..5d645f4ab 100644 --- a/examples/tcpblaster/tcpblaster.h +++ b/examples/tcpblaster/tcpblaster.h @@ -31,7 +31,7 @@ #ifdef TCPBLASTER_HOST #else -# include +# include #endif /**************************************************************************** diff --git a/examples/tcpblaster/tcpblaster_netinit.c b/examples/tcpblaster/tcpblaster_netinit.c index 6007674f4..f9719d295 100644 --- a/examples/tcpblaster/tcpblaster_netinit.c +++ b/examples/tcpblaster/tcpblaster_netinit.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include diff --git a/examples/tcpblaster/tcpblaster_target1.c b/examples/tcpblaster/tcpblaster_target1.c index f46fd0da8..827fe3a7d 100644 --- a/examples/tcpblaster/tcpblaster_target1.c +++ b/examples/tcpblaster/tcpblaster_target1.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include "tcpblaster.h" diff --git a/examples/tcpecho/tcpecho_main.c b/examples/tcpecho/tcpecho_main.c index 96aba8096..2de49f6af 100644 --- a/examples/tcpecho/tcpecho_main.c +++ b/examples/tcpecho/tcpecho_main.c @@ -28,7 +28,7 @@ * Included Files ****************************************************************************/ -#include +#include #include #include #include diff --git a/examples/thttpd/thttpd_main.c b/examples/thttpd/thttpd_main.c index 291e7552c..5ee01b455 100644 --- a/examples/thttpd/thttpd_main.c +++ b/examples/thttpd/thttpd_main.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/touchscreen/tc_main.c b/examples/touchscreen/tc_main.c index 129de8d27..b2f40a8f7 100644 --- a/examples/touchscreen/tc_main.c +++ b/examples/touchscreen/tc_main.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #ifdef CONFIG_EXAMPLES_TOUCHSCREEN_MOUSE # include diff --git a/examples/udp/udp.h b/examples/udp/udp.h index 415317f50..2f15d8ea3 100644 --- a/examples/udp/udp.h +++ b/examples/udp/udp.h @@ -29,7 +29,7 @@ #ifdef EXAMPLES_UDP_HOST #else -# include +# include #endif #include diff --git a/examples/udp/udp_netinit.c b/examples/udp/udp_netinit.c index 3cd2625b7..d5851b22a 100644 --- a/examples/udp/udp_netinit.c +++ b/examples/udp/udp_netinit.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include diff --git a/examples/udpblaster/udpblaster_target.c b/examples/udpblaster/udpblaster_target.c index 0df0072d4..be5908fbd 100644 --- a/examples/udpblaster/udpblaster_target.c +++ b/examples/udpblaster/udpblaster_target.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/usbserial/usbserial_main.c b/examples/usbserial/usbserial_main.c index 66e4790b9..e1eec27c8 100644 --- a/examples/usbserial/usbserial_main.c +++ b/examples/usbserial/usbserial_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/usrsocktest/usrsocktest_daemon.c b/examples/usrsocktest/usrsocktest_daemon.c index 3d84d8396..efa543591 100644 --- a/examples/usrsocktest/usrsocktest_daemon.c +++ b/examples/usrsocktest/usrsocktest_daemon.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/examples/usrsocktest/usrsocktest_main.c b/examples/usrsocktest/usrsocktest_main.c index d09036c38..c6109423e 100644 --- a/examples/usrsocktest/usrsocktest_main.c +++ b/examples/usrsocktest/usrsocktest_main.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/examples/watchdog/watchdog_main.c b/examples/watchdog/watchdog_main.c index 06a36c75d..4e22001a1 100644 --- a/examples/watchdog/watchdog_main.c +++ b/examples/watchdog/watchdog_main.c @@ -26,7 +26,7 @@ #include -#include +#include #include #include #include diff --git a/examples/watcher/wdt.c b/examples/watcher/wdt.c index ccfbeaa98..667240dee 100644 --- a/examples/watcher/wdt.c +++ b/examples/watcher/wdt.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/webserver/webserver_main.c b/examples/webserver/webserver_main.c index 7a16c8c45..8309f59c8 100644 --- a/examples/webserver/webserver_main.c +++ b/examples/webserver/webserver_main.c @@ -51,7 +51,7 @@ #include #include #include -#include +#include #include #include diff --git a/examples/wgetjson/wgetjson_main.c b/examples/wgetjson/wgetjson_main.c index 860a0fb5b..083d68e93 100644 --- a/examples/wgetjson/wgetjson_main.c +++ b/examples/wgetjson/wgetjson_main.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include "netutils/netlib.h" #include "netutils/webclient.h" diff --git a/examples/ws2812/ws2812_main.c b/examples/ws2812/ws2812_main.c index 438e68f11..ebb16b575 100644 --- a/examples/ws2812/ws2812_main.c +++ b/examples/ws2812/ws2812_main.c @@ -26,7 +26,7 @@ #include -#include +#include #include #include #include @@ -77,7 +77,7 @@ static void help(FAR struct neo_config_s *conf) printf("\nArguments are \"sticky\". " "For example, once the device path is\n"); - printf("specified, that path will be re-used until it is changed.\n"); + printf("specified, that path will be reused until it is changed.\n"); printf(" [-p path] selects the ws2812 device. " "Default: %s Current: %s\n", diff --git a/examples/ws2812esp32rmt/ws2812esp32rmt_main.c b/examples/ws2812esp32rmt/ws2812esp32rmt_main.c index 3f451436e..7eb8dd6fe 100644 --- a/examples/ws2812esp32rmt/ws2812esp32rmt_main.c +++ b/examples/ws2812esp32rmt/ws2812esp32rmt_main.c @@ -26,7 +26,7 @@ #include -#include +#include #include #include #include diff --git a/examples/xmlrpc/xmlrpc_main.c b/examples/xmlrpc/xmlrpc_main.c index feeb0bf4e..0d90626e5 100644 --- a/examples/xmlrpc/xmlrpc_main.c +++ b/examples/xmlrpc/xmlrpc_main.c @@ -52,7 +52,7 @@ * Included Files ****************************************************************************/ -#include +#include #include #include #include diff --git a/examples/zerocross/zerocross_main.c b/examples/zerocross/zerocross_main.c index d2f49fa5b..2b6da5b62 100644 --- a/examples/zerocross/zerocross_main.c +++ b/examples/zerocross/zerocross_main.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/fsutils/flash_eraseall/flash_eraseall.c b/fsutils/flash_eraseall/flash_eraseall.c index 2dde3a1ee..f7462c152 100644 --- a/fsutils/flash_eraseall/flash_eraseall.c +++ b/fsutils/flash_eraseall/flash_eraseall.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include "fsutils/flash_eraseall.h" diff --git a/fsutils/flashtool/flashtool_main.c b/fsutils/flashtool/flashtool_main.c index 8e4f288f3..b1f7f29a4 100644 --- a/fsutils/flashtool/flashtool_main.c +++ b/fsutils/flashtool/flashtool_main.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/fsutils/inifile/inifile.c b/fsutils/inifile/inifile.c index 16c9da6af..8bb52326b 100644 --- a/fsutils/inifile/inifile.c +++ b/fsutils/inifile/inifile.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include "fsutils/inifile.h" diff --git a/fsutils/ipcfg/ipcfg.c b/fsutils/ipcfg/ipcfg.c index c1d4f9f9d..9f6deab5b 100644 --- a/fsutils/ipcfg/ipcfg.c +++ b/fsutils/ipcfg/ipcfg.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include "fsutils/ipcfg.h" #include "ipcfg.h" diff --git a/fsutils/ipcfg/ipcfg_binary.c b/fsutils/ipcfg/ipcfg_binary.c index 0247a4e88..c12a7ada4 100644 --- a/fsutils/ipcfg/ipcfg_binary.c +++ b/fsutils/ipcfg/ipcfg_binary.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "fsutils/ipcfg.h" #include "ipcfg.h" @@ -154,7 +154,7 @@ static int ipcfg_read_binary(int fd, FAR void *buffer, size_t nbytes) * Input Parameters: * fd - File descriptor of the open file to write to * buffer - Location to write to - * nbytes - Number of bytes to wrtie + * nbytes - Number of bytes to write * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -265,7 +265,7 @@ static int ipcfg_find_binary(int fd, sa_family_t af) * * Input Parameters: * path - The full path to the IP configuration file - * ipv4cfg - Location to read IPv4 configration to + * ipv4cfg - Location to read IPv4 configuration to * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -316,7 +316,7 @@ errout_with_fd: * * Input Parameters: * path - The full path to the IP configuration file - * ipv6cfg - Location to read IPv6 configration to + * ipv6cfg - Location to read IPv6 configuration to * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -367,7 +367,7 @@ errout_with_fd: * * Input Parameters: * path - The full path to the IP configuration file - * ipv4cfg - The IPv4 configration to write + * ipv4cfg - The IPv4 configuration to write * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -474,7 +474,7 @@ errout_with_fd: * * Input Parameters: * path - The full path to the IP configuration file - * ipv6cfg - The IPv6 configration to write + * ipv6cfg - The IPv6 configuration to write * * Returned Value: * Zero is returned on success; a negated errno value is returned on any diff --git a/fsutils/ipcfg/ipcfg_text.c b/fsutils/ipcfg/ipcfg_text.c index 738bde088..f0e64f8e8 100644 --- a/fsutils/ipcfg/ipcfg_text.c +++ b/fsutils/ipcfg/ipcfg_text.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include @@ -238,7 +238,7 @@ static int ipcfg_put_ipv6addr(FAR FILE *stream, FAR const char *variable, * * Input Parameters: * stream - Stream of the open file to write to - * ipv4cfg - The IPv4 configration to write + * ipv4cfg - The IPv4 configuration to write * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -278,7 +278,7 @@ static int ipcfg_write_ipv4(FAR FILE *stream, * * Input Parameters: * stream - Stream of the open file to write to - * ipv6cfg - The IPv6 configration to write + * ipv6cfg - The IPv6 configuration to write * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -322,7 +322,7 @@ static int ipcfg_write_ipv6(FAR FILE *stream, * Input Parameters: * path - The full path to the IP configuration file * netdev - Network device name string - * ipv4cfg - Location to read IPv4 configration to + * ipv4cfg - Location to read IPv4 configuration to * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -473,7 +473,7 @@ int ipcfg_read_text_ipv4(FAR const char *path, FAR const char *netdev, * Input Parameters: * path - The full path to the IP configuration file * netdev - Network device name string - * ipv6cfg - Location to read IPv6 configration to + * ipv6cfg - Location to read IPv6 configuration to * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -639,7 +639,7 @@ int ipcfg_read_text_ipv6(FAR const char *path, FAR const char *netdev, * Input Parameters: * path - The full path to the IP configuration file * netdev - Network device name string - * ipv4cfg - The IPv4 configration to write + * ipv4cfg - The IPv4 configuration to write * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -726,7 +726,7 @@ int ipcfg_write_text_ipv4(FAR const char *path, FAR const char *netdev, * Input Parameters: * path - The full path to the IP configuration file * netdev - Network device name string - * ipv6cfg - The IPv6 configration to write + * ipv6cfg - The IPv6 configuration to write * * Returned Value: * Zero is returned on success; a negated errno value is returned on any diff --git a/fsutils/mkfatfs/configfat.c b/fsutils/mkfatfs/configfat.c index cb6d41da4..a3550cf7a 100644 --- a/fsutils/mkfatfs/configfat.c +++ b/fsutils/mkfatfs/configfat.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include "fsutils/mkfatfs.h" diff --git a/fsutils/mkfatfs/mkfatfs.c b/fsutils/mkfatfs/mkfatfs.c index 2bf7e56b8..8b2227e02 100644 --- a/fsutils/mkfatfs/mkfatfs.c +++ b/fsutils/mkfatfs/mkfatfs.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/fsutils/mkfatfs/writefat.c b/fsutils/mkfatfs/writefat.c index d88e0bbb7..01837d05c 100644 --- a/fsutils/mkfatfs/writefat.c +++ b/fsutils/mkfatfs/writefat.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include @@ -206,7 +206,7 @@ static inline void mkfatfs_initmbr(FAR struct fat_format_s *fmt, /* The following fields are only valid for FAT12/16 */ - /* 1@36: Drive number for MSDOS bootstrap -- left zero */ + /* 1@36: Drive number for MS-DOS bootstrap -- left zero */ /* 1@37: Reserved (zero) */ @@ -268,7 +268,7 @@ static inline void mkfatfs_initmbr(FAR struct fat_format_s *fmt, /* 12@52: Reserved (zero) */ - /* 1@64: Drive number for MSDOS bootstrap -- left zero */ + /* 1@64: Drive number for MS-DOS bootstrap -- left zero */ /* 1@65: Reserved (zero) */ diff --git a/fsutils/mkgpt/mkgpt.c b/fsutils/mkgpt/mkgpt.c index e7621fab0..994902067 100644 --- a/fsutils/mkgpt/mkgpt.c +++ b/fsutils/mkgpt/mkgpt.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/ft80x/ft80x.h b/graphics/ft80x/ft80x.h index 6462f1ce1..64254691c 100644 --- a/graphics/ft80x/ft80x.h +++ b/graphics/ft80x/ft80x.h @@ -32,7 +32,7 @@ #include #include -#include +#include #ifdef CONFIG_GRAPHICS_FT80X diff --git a/graphics/input/generator/input_gen_ctx.c b/graphics/input/generator/input_gen_ctx.c index 6449979fd..ea415e020 100644 --- a/graphics/input/generator/input_gen_ctx.c +++ b/graphics/input/generator/input_gen_ctx.c @@ -26,7 +26,7 @@ #include -#include +#include #include #include #include diff --git a/graphics/input/generator/input_gen_dev.c b/graphics/input/generator/input_gen_dev.c index 117946d9c..9c921107c 100644 --- a/graphics/input/generator/input_gen_dev.c +++ b/graphics/input/generator/input_gen_dev.c @@ -26,7 +26,7 @@ #include -#include +#include #include #include diff --git a/graphics/input/generator/input_gen_event.c b/graphics/input/generator/input_gen_event.c index 64637bb85..51219d51b 100644 --- a/graphics/input/generator/input_gen_event.c +++ b/graphics/input/generator/input_gen_event.c @@ -26,7 +26,7 @@ #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CButton/cbutton_main.cxx b/graphics/nxwidgets/UnitTests/CButton/cbutton_main.cxx index 472348ba5..663048593 100644 --- a/graphics/nxwidgets/UnitTests/CButton/cbutton_main.cxx +++ b/graphics/nxwidgets/UnitTests/CButton/cbutton_main.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CButton/cbuttontest.cxx b/graphics/nxwidgets/UnitTests/CButton/cbuttontest.cxx index 773f0435e..c7628b41a 100644 --- a/graphics/nxwidgets/UnitTests/CButton/cbuttontest.cxx +++ b/graphics/nxwidgets/UnitTests/CButton/cbuttontest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CButton/cbuttontest.hxx b/graphics/nxwidgets/UnitTests/CButton/cbuttontest.hxx index 8b1749d88..608e77929 100644 --- a/graphics/nxwidgets/UnitTests/CButton/cbuttontest.hxx +++ b/graphics/nxwidgets/UnitTests/CButton/cbuttontest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarray_main.cxx b/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarray_main.cxx index 8af3de7d1..51a09a16c 100644 --- a/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarray_main.cxx +++ b/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarray_main.cxx @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx b/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx index a19c6f880..e84caf02f 100644 --- a/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx +++ b/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx b/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx index a13783bd5..0d69a2838 100644 --- a/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx +++ b/graphics/nxwidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CCheckBox/ccheckbox_main.cxx b/graphics/nxwidgets/UnitTests/CCheckBox/ccheckbox_main.cxx index 8719611ba..087e31499 100644 --- a/graphics/nxwidgets/UnitTests/CCheckBox/ccheckbox_main.cxx +++ b/graphics/nxwidgets/UnitTests/CCheckBox/ccheckbox_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CCheckBox/ccheckboxtest.cxx b/graphics/nxwidgets/UnitTests/CCheckBox/ccheckboxtest.cxx index 1ff5a0a53..8f8398324 100644 --- a/graphics/nxwidgets/UnitTests/CCheckBox/ccheckboxtest.cxx +++ b/graphics/nxwidgets/UnitTests/CCheckBox/ccheckboxtest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CCheckBox/ccheckboxtest.hxx b/graphics/nxwidgets/UnitTests/CCheckBox/ccheckboxtest.hxx index 1bd72dba5..205884f47 100644 --- a/graphics/nxwidgets/UnitTests/CCheckBox/ccheckboxtest.hxx +++ b/graphics/nxwidgets/UnitTests/CCheckBox/ccheckboxtest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbutton_main.cxx b/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbutton_main.cxx index ec673c5f2..01081b38e 100644 --- a/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbutton_main.cxx +++ b/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbutton_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx b/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx index f46468626..acee748fa 100644 --- a/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx +++ b/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx b/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx index d7593734f..89884872f 100644 --- a/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx +++ b/graphics/nxwidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontal_main.cxx b/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontal_main.cxx index e40c78be7..59546fa73 100644 --- a/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontal_main.cxx +++ b/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontal_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontaltest.cxx b/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontaltest.cxx index 2809bfb26..a9e38f00a 100644 --- a/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontaltest.cxx +++ b/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontaltest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontaltest.hxx b/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontaltest.hxx index c3fd43ecc..0d563eecb 100644 --- a/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontaltest.hxx +++ b/graphics/nxwidgets/UnitTests/CGlyphSliderHorizontal/cglyphsliderhorizontaltest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CImage/cimage_main.cxx b/graphics/nxwidgets/UnitTests/CImage/cimage_main.cxx index 3423d6e74..339627a74 100644 --- a/graphics/nxwidgets/UnitTests/CImage/cimage_main.cxx +++ b/graphics/nxwidgets/UnitTests/CImage/cimage_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CImage/cimagetest.cxx b/graphics/nxwidgets/UnitTests/CImage/cimagetest.cxx index 2472f19f2..9eedd8aa4 100644 --- a/graphics/nxwidgets/UnitTests/CImage/cimagetest.cxx +++ b/graphics/nxwidgets/UnitTests/CImage/cimagetest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CImage/cimagetest.hxx b/graphics/nxwidgets/UnitTests/CImage/cimagetest.hxx index 34568a5f4..99970b6f1 100644 --- a/graphics/nxwidgets/UnitTests/CImage/cimagetest.hxx +++ b/graphics/nxwidgets/UnitTests/CImage/cimagetest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CKeypad/ckeypad_main.cxx b/graphics/nxwidgets/UnitTests/CKeypad/ckeypad_main.cxx index bfd5dfd2c..9e9d4b269 100644 --- a/graphics/nxwidgets/UnitTests/CKeypad/ckeypad_main.cxx +++ b/graphics/nxwidgets/UnitTests/CKeypad/ckeypad_main.cxx @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CKeypad/ckeypadtest.cxx b/graphics/nxwidgets/UnitTests/CKeypad/ckeypadtest.cxx index 64cf7c366..a51555e44 100644 --- a/graphics/nxwidgets/UnitTests/CKeypad/ckeypadtest.cxx +++ b/graphics/nxwidgets/UnitTests/CKeypad/ckeypadtest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CKeypad/ckeypadtest.hxx b/graphics/nxwidgets/UnitTests/CKeypad/ckeypadtest.hxx index f566d8bcd..783fb0b52 100644 --- a/graphics/nxwidgets/UnitTests/CKeypad/ckeypadtest.hxx +++ b/graphics/nxwidgets/UnitTests/CKeypad/ckeypadtest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CLabel/clabel_main.cxx b/graphics/nxwidgets/UnitTests/CLabel/clabel_main.cxx index bed815541..c822abf1a 100644 --- a/graphics/nxwidgets/UnitTests/CLabel/clabel_main.cxx +++ b/graphics/nxwidgets/UnitTests/CLabel/clabel_main.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CLabel/clabeltest.cxx b/graphics/nxwidgets/UnitTests/CLabel/clabeltest.cxx index 1851674ad..1b439125f 100644 --- a/graphics/nxwidgets/UnitTests/CLabel/clabeltest.cxx +++ b/graphics/nxwidgets/UnitTests/CLabel/clabeltest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CLabel/clabeltest.hxx b/graphics/nxwidgets/UnitTests/CLabel/clabeltest.hxx index 57ccc1f0d..317a08bec 100644 --- a/graphics/nxwidgets/UnitTests/CLabel/clabeltest.hxx +++ b/graphics/nxwidgets/UnitTests/CLabel/clabeltest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CLatchButton/clatchbutton_main.cxx b/graphics/nxwidgets/UnitTests/CLatchButton/clatchbutton_main.cxx index ca0310ae2..0663f74c3 100644 --- a/graphics/nxwidgets/UnitTests/CLatchButton/clatchbutton_main.cxx +++ b/graphics/nxwidgets/UnitTests/CLatchButton/clatchbutton_main.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CLatchButton/clatchbuttontest.cxx b/graphics/nxwidgets/UnitTests/CLatchButton/clatchbuttontest.cxx index 58fe9b6a1..a8dbe2603 100644 --- a/graphics/nxwidgets/UnitTests/CLatchButton/clatchbuttontest.cxx +++ b/graphics/nxwidgets/UnitTests/CLatchButton/clatchbuttontest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CLatchButton/clatchbuttontest.hxx b/graphics/nxwidgets/UnitTests/CLatchButton/clatchbuttontest.hxx index 71946d325..641ccb9ec 100644 --- a/graphics/nxwidgets/UnitTests/CLatchButton/clatchbuttontest.hxx +++ b/graphics/nxwidgets/UnitTests/CLatchButton/clatchbuttontest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarray_main.cxx b/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarray_main.cxx index fd6dcbeb0..a1e713660 100644 --- a/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarray_main.cxx +++ b/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarray_main.cxx @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx b/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx index 3da02db99..146f9172a 100644 --- a/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx +++ b/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx b/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx index 212d512a7..9ebfed210 100644 --- a/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx +++ b/graphics/nxwidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CListBox/clistbox_main.cxx b/graphics/nxwidgets/UnitTests/CListBox/clistbox_main.cxx index 45864f1e5..c9bb459ed 100644 --- a/graphics/nxwidgets/UnitTests/CListBox/clistbox_main.cxx +++ b/graphics/nxwidgets/UnitTests/CListBox/clistbox_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CListBox/clistboxtest.cxx b/graphics/nxwidgets/UnitTests/CListBox/clistboxtest.cxx index 7bd3836de..b81fff628 100644 --- a/graphics/nxwidgets/UnitTests/CListBox/clistboxtest.cxx +++ b/graphics/nxwidgets/UnitTests/CListBox/clistboxtest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CListBox/clistboxtest.hxx b/graphics/nxwidgets/UnitTests/CListBox/clistboxtest.hxx index 452240dc9..7171c26cd 100644 --- a/graphics/nxwidgets/UnitTests/CListBox/clistboxtest.hxx +++ b/graphics/nxwidgets/UnitTests/CListBox/clistboxtest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbar_main.cxx b/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbar_main.cxx index d5c5d4b9f..3df02715f 100644 --- a/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbar_main.cxx +++ b/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbar_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbartest.cxx b/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbartest.cxx index 11ad6bb07..537774ea8 100644 --- a/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbartest.cxx +++ b/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbartest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbartest.hxx b/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbartest.hxx index dd8dcf103..657da3d8e 100644 --- a/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbartest.hxx +++ b/graphics/nxwidgets/UnitTests/CProgressBar/cprogressbartest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CRadioButton/cradiobutton_main.cxx b/graphics/nxwidgets/UnitTests/CRadioButton/cradiobutton_main.cxx index fd0c13b40..b093382a1 100644 --- a/graphics/nxwidgets/UnitTests/CRadioButton/cradiobutton_main.cxx +++ b/graphics/nxwidgets/UnitTests/CRadioButton/cradiobutton_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CRadioButton/cradiobuttontest.cxx b/graphics/nxwidgets/UnitTests/CRadioButton/cradiobuttontest.cxx index 683dc02dc..5d0be7bb5 100644 --- a/graphics/nxwidgets/UnitTests/CRadioButton/cradiobuttontest.cxx +++ b/graphics/nxwidgets/UnitTests/CRadioButton/cradiobuttontest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CRadioButton/cradiobuttontest.hxx b/graphics/nxwidgets/UnitTests/CRadioButton/cradiobuttontest.hxx index fc8d7ee29..8a5c1f0df 100644 --- a/graphics/nxwidgets/UnitTests/CRadioButton/cradiobuttontest.hxx +++ b/graphics/nxwidgets/UnitTests/CRadioButton/cradiobuttontest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontal_main.cxx b/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontal_main.cxx index 51ea0e6e2..2429a75d1 100644 --- a/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontal_main.cxx +++ b/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontal_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx b/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx index e59f0fe3b..21501c125 100644 --- a/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx +++ b/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx b/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx index c8b31b392..b53d318d5 100644 --- a/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx +++ b/graphics/nxwidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarvertical_main.cxx b/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarvertical_main.cxx index 04664b08b..9497febe5 100644 --- a/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarvertical_main.cxx +++ b/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarvertical_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx b/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx index bbf21f2c2..8770f5df4 100644 --- a/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx +++ b/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx b/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx index 159fb3bf2..fc062fed2 100644 --- a/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx +++ b/graphics/nxwidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontal_main.cxx b/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontal_main.cxx index 9b8f21b54..6c122a20b 100644 --- a/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontal_main.cxx +++ b/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontal_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx b/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx index 8a9e19496..5dd3880f7 100644 --- a/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx +++ b/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx b/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx index 538af2daf..9f9297399 100644 --- a/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx +++ b/graphics/nxwidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CSliderVertical/cslidervertical_main.cxx b/graphics/nxwidgets/UnitTests/CSliderVertical/cslidervertical_main.cxx index 40872745c..2d109b35a 100644 --- a/graphics/nxwidgets/UnitTests/CSliderVertical/cslidervertical_main.cxx +++ b/graphics/nxwidgets/UnitTests/CSliderVertical/cslidervertical_main.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx b/graphics/nxwidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx index efad3275e..aa2241764 100644 --- a/graphics/nxwidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx +++ b/graphics/nxwidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx b/graphics/nxwidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx index 7bad5e81d..0bac9b3d6 100644 --- a/graphics/nxwidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx +++ b/graphics/nxwidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CTextBox/ctextbox_main.cxx b/graphics/nxwidgets/UnitTests/CTextBox/ctextbox_main.cxx index 92de3dd85..ef9a5e362 100644 --- a/graphics/nxwidgets/UnitTests/CTextBox/ctextbox_main.cxx +++ b/graphics/nxwidgets/UnitTests/CTextBox/ctextbox_main.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/UnitTests/CTextBox/ctextboxtest.cxx b/graphics/nxwidgets/UnitTests/CTextBox/ctextboxtest.cxx index 4d0fad790..d34d937b9 100644 --- a/graphics/nxwidgets/UnitTests/CTextBox/ctextboxtest.cxx +++ b/graphics/nxwidgets/UnitTests/CTextBox/ctextboxtest.cxx @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/UnitTests/CTextBox/ctextboxtest.hxx b/graphics/nxwidgets/UnitTests/CTextBox/ctextboxtest.hxx index 427824422..21e994d74 100644 --- a/graphics/nxwidgets/UnitTests/CTextBox/ctextboxtest.hxx +++ b/graphics/nxwidgets/UnitTests/CTextBox/ctextboxtest.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/src/ccallback.cxx b/graphics/nxwidgets/src/ccallback.cxx index 510f55161..f07deaf93 100644 --- a/graphics/nxwidgets/src/ccallback.cxx +++ b/graphics/nxwidgets/src/ccallback.cxx @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include @@ -308,7 +308,7 @@ void CCallback::newKeyboardEvent(NXHANDLE hwnd, uint8_t nCh, * NXEVENT_SYCNCHED - Synchronization handshake * * This completes the handshake started by nx_synch(). nx_synch() - * sends a syncrhonization messages to the NX server which responds + * sends a synchronization message to the NX server which responds * with this event. The sleeping client is awakened and continues * graphics processing, completing the handshake. * diff --git a/graphics/nxwidgets/src/cgraphicsport.cxx b/graphics/nxwidgets/src/cgraphicsport.cxx index 2e299162d..ffe56033e 100644 --- a/graphics/nxwidgets/src/cgraphicsport.cxx +++ b/graphics/nxwidgets/src/cgraphicsport.cxx @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/src/cimage.cxx b/graphics/nxwidgets/src/cimage.cxx index a500c3b4e..337b7fea4 100644 --- a/graphics/nxwidgets/src/cimage.cxx +++ b/graphics/nxwidgets/src/cimage.cxx @@ -62,7 +62,7 @@ #include #include -#include +#include #include diff --git a/graphics/nxwidgets/src/clabelgrid.cxx b/graphics/nxwidgets/src/clabelgrid.cxx index 6302f4c6a..175535bba 100644 --- a/graphics/nxwidgets/src/clabelgrid.cxx +++ b/graphics/nxwidgets/src/clabelgrid.cxx @@ -59,7 +59,7 @@ ****************************************************************************/ #include -#include +#include #include "graphics/nxwidgets/clabelgrid.hxx" #include "graphics/nxwidgets/clabel.hxx" diff --git a/graphics/nxwidgets/src/cnumericedit.cxx b/graphics/nxwidgets/src/cnumericedit.cxx index 770f727c7..22556c7d8 100644 --- a/graphics/nxwidgets/src/cnumericedit.cxx +++ b/graphics/nxwidgets/src/cnumericedit.cxx @@ -66,7 +66,7 @@ #include #include -#include +#include #include "graphics/nxwidgets/cnumericedit.hxx" #include "graphics/nxwidgets/cbutton.hxx" diff --git a/graphics/nxwidgets/src/cnxserver.cxx b/graphics/nxwidgets/src/cnxserver.cxx index 67ad93332..60f841833 100644 --- a/graphics/nxwidgets/src/cnxserver.cxx +++ b/graphics/nxwidgets/src/cnxserver.cxx @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include diff --git a/graphics/nxwidgets/src/cnxtimer.cxx b/graphics/nxwidgets/src/cnxtimer.cxx index 81ba0da64..dd6be5101 100644 --- a/graphics/nxwidgets/src/cnxtimer.cxx +++ b/graphics/nxwidgets/src/cnxtimer.cxx @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include diff --git a/graphics/nxwidgets/src/cscaledbitmap.cxx b/graphics/nxwidgets/src/cscaledbitmap.cxx index ec46ca5c4..65f1a372f 100644 --- a/graphics/nxwidgets/src/cscaledbitmap.cxx +++ b/graphics/nxwidgets/src/cscaledbitmap.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include @@ -64,7 +64,7 @@ CScaledBitmap::CScaledBitmap(IBitmap *bitmap, struct nxgl_size_s &newSize) m_xScale = itob16((uint32_t)m_bitmap->getWidth()) / newSize.w; // Similarly, yScale will be used to convert a request Y position to a Y - // positionin the contained bitmap: + // position in the contained bitmap: // // yImage = yRequested * oldHeight / newHeight // = yRequested * yScale diff --git a/graphics/nxwidgets/src/cscrollingpanel.cxx b/graphics/nxwidgets/src/cscrollingpanel.cxx index d369d42fc..80f51c87c 100644 --- a/graphics/nxwidgets/src/cscrollingpanel.cxx +++ b/graphics/nxwidgets/src/cscrollingpanel.cxx @@ -62,7 +62,7 @@ #include #include -#include +#include #include "graphics/nxwidgets/cwidgetcontrol.hxx" #include "graphics/nxwidgets/cscrollingpanel.hxx" diff --git a/graphics/nxwidgets/src/cwidgetcontrol.cxx b/graphics/nxwidgets/src/cwidgetcontrol.cxx index 921b05412..3107d7729 100644 --- a/graphics/nxwidgets/src/cwidgetcontrol.cxx +++ b/graphics/nxwidgets/src/cwidgetcontrol.cxx @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include "graphics/nxwidgets/nxconfig.hxx" diff --git a/graphics/nxwidgets/src/singletons.cxx b/graphics/nxwidgets/src/singletons.cxx index e6c4da73e..a6e44797c 100644 --- a/graphics/nxwidgets/src/singletons.cxx +++ b/graphics/nxwidgets/src/singletons.cxx @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include "graphics/nxwidgets/nxconfig.hxx" #include "graphics/nxwidgets/cnxserver.hxx" diff --git a/graphics/nxwm/src/ccalibration.cxx b/graphics/nxwm/src/ccalibration.cxx index 21adb2183..262a9d567 100644 --- a/graphics/nxwm/src/ccalibration.cxx +++ b/graphics/nxwm/src/ccalibration.cxx @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_NXWM_TOUCHSCREEN_CONFIGDATA diff --git a/graphics/nxwm/src/chexcalculator.cxx b/graphics/nxwm/src/chexcalculator.cxx index e5ab0d9e8..f2cf62018 100644 --- a/graphics/nxwm/src/chexcalculator.cxx +++ b/graphics/nxwm/src/chexcalculator.cxx @@ -27,7 +27,7 @@ #include #include -#include +#include #include "graphics/nxwidgets/cwidgetcontrol.hxx" diff --git a/graphics/nxwm/src/ckeyboard.cxx b/graphics/nxwm/src/ckeyboard.cxx index 20dcc44cc..7afb0b0ae 100644 --- a/graphics/nxwm/src/ckeyboard.cxx +++ b/graphics/nxwm/src/ckeyboard.cxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include "graphics/nxwm/nxwmconfig.hxx" @@ -188,7 +188,7 @@ int CKeyboard::open(void) if (errcode == ENOENT || errcode == ENODEV) { - // REVIST: Can we inject a constant string here to let the + // REVISIT: Can we inject a constant string here to let the // user know that we are waiting for a USB keyboard to be // connected? diff --git a/graphics/nxwm/src/cmediaplayer.cxx b/graphics/nxwm/src/cmediaplayer.cxx index bcfb95718..8561eb469 100644 --- a/graphics/nxwm/src/cmediaplayer.cxx +++ b/graphics/nxwm/src/cmediaplayer.cxx @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "system/nxplayer.h" #include diff --git a/graphics/nxwm/src/cnxterm.cxx b/graphics/nxwm/src/cnxterm.cxx index 0c4d20455..40bc5997b 100644 --- a/graphics/nxwm/src/cnxterm.cxx +++ b/graphics/nxwm/src/cnxterm.cxx @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include "nshlib/nshlib.h" diff --git a/graphics/nxwm/src/ctaskbar.cxx b/graphics/nxwm/src/ctaskbar.cxx index d66d36850..7160b93d9 100644 --- a/graphics/nxwm/src/ctaskbar.cxx +++ b/graphics/nxwm/src/ctaskbar.cxx @@ -26,7 +26,7 @@ #include -#include +#include #include @@ -617,7 +617,7 @@ bool CTaskbar::maximizeApplication(IApplication *app) /** * Minimize an application by moving its window to the bottom of the and - * redrawing the next visible appliation. + * redrawing the next visible application. * * @param app. The new application to add to the task bar * @return true on success diff --git a/graphics/nxwm/src/ctouchscreen.cxx b/graphics/nxwm/src/ctouchscreen.cxx index bbebc0f7a..b7807c710 100644 --- a/graphics/nxwm/src/ctouchscreen.cxx +++ b/graphics/nxwm/src/ctouchscreen.cxx @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include @@ -181,7 +181,7 @@ void CTouchscreen::setCalibrationData(const struct SCalibrationData &caldata) m_calibData = caldata; // Note that we have calibration data. Data will now be scaled and forwarded - // to NX (unless we are still in cpature mode) + // to NX (unless we are still in capture mode) m_calibrated = true; @@ -205,7 +205,7 @@ bool CTouchscreen::waitRawTouchData(struct touch_sample_s *touch) { _info("Capturing touch input\n"); - // Setup to cpature raw data into the user provided buffer + // Setup to capture raw data into the user provided buffer sched_lock(); m_touch = touch; diff --git a/graphics/nxwm/src/cwindowmessenger.cxx b/graphics/nxwm/src/cwindowmessenger.cxx index 8761e4799..92a2ba91a 100644 --- a/graphics/nxwm/src/cwindowmessenger.cxx +++ b/graphics/nxwm/src/cwindowmessenger.cxx @@ -28,7 +28,7 @@ #include -#include +#include #include #include "graphics/nxwm/nxwmconfig.hxx" diff --git a/graphics/slcd/cslcd.cxx b/graphics/slcd/cslcd.cxx index 8f7320e1e..f732b8e42 100644 --- a/graphics/slcd/cslcd.cxx +++ b/graphics/slcd/cslcd.cxx @@ -25,7 +25,7 @@ ///////////////////////////////////////////////////////////////////////////// #include -#include +#include #include diff --git a/graphics/tiff/tiff_addstrip.c b/graphics/tiff/tiff_addstrip.c index ff4a9d598..5db952088 100644 --- a/graphics/tiff/tiff_addstrip.c +++ b/graphics/tiff/tiff_addstrip.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include "graphics/tiff.h" diff --git a/graphics/tiff/tiff_finalize.c b/graphics/tiff/tiff_finalize.c index 2ad01a06e..da49343c9 100644 --- a/graphics/tiff/tiff_finalize.c +++ b/graphics/tiff/tiff_finalize.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include "graphics/tiff.h" diff --git a/graphics/tiff/tiff_initialize.c b/graphics/tiff/tiff_initialize.c index b6de8408d..263f650cf 100644 --- a/graphics/tiff/tiff_initialize.c +++ b/graphics/tiff/tiff_initialize.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include "graphics/tiff.h" @@ -68,7 +68,7 @@ * 172 XResolution Hard-coded to 300/1 * 180 YResolution Hard-coded to 300/1 * 188 "NuttX" Length = 6 (including NUL terminator) - * 194 "YYYY:MM:DD HH:MM:SS" Length = 20 (ncluding NUL terminator) + * 194 "YYYY:MM:DD HH:MM:SS" Length = 20 (including NUL terminator) * 214 [2 bytes padding] * 216 StripByteCounts Beginning of strip byte counts * xxx StripOffsets Beginning of strip offsets @@ -121,7 +121,7 @@ * 184 XResolution Hard-coded to 300/1 * 192 YResolution Hard-coded to 300/1 * 200 "NuttX" Length = 6 (including NUL terminator) - * 206 "YYYY:MM:DD HH:MM:SS" Length = 20 (ncluding NUL terminator) + * 206 "YYYY:MM:DD HH:MM:SS" Length = 20 (including NUL terminator) * 226 [2 bytes padding] * 228 StripByteCounts Beginning of strip byte counts * xxx StripOffsets Beginning of strip offsets @@ -170,7 +170,7 @@ * 212 BitsPerSample 8, 8, 8 * 218 [2 bytes padding] * 220 "NuttX" Length = 6 (including NUL terminator) - * 226 "YYYY:MM:DD HH:MM:SS" Length = 20 (ncluding NUL terminator) + * 226 "YYYY:MM:DD HH:MM:SS" Length = 20 (including NUL terminator) * 246 [2 bytes padding] * 248 StripByteCounts Beginning of strip byte counts * xxx StripOffsets Beginning of strip offsets @@ -410,7 +410,7 @@ static int tiff_datetime(FAR char *timbuf, unsigned int buflen) gmtime_r((FAR const time_t*)&ts.tv_sec, &tm); - /* Comvert the current time in the TIFF format */ + /* Convert the current time to TIFF format */ strftime(timbuf, buflen, TIFF_DATETIME_FORMAT, &tm); return OK; diff --git a/graphics/tiff/tiff_utils.c b/graphics/tiff/tiff_utils.c index c16f7b3e3..17e72689b 100644 --- a/graphics/tiff/tiff_utils.c +++ b/graphics/tiff/tiff_utils.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "graphics/tiff.h" @@ -335,7 +335,7 @@ int tiff_putstring(int fd, FAR const char *string, int len) * Name: tiff_wordalign * * Description: - * Pad a file with zeros as necessary to achieve word alignament. + * Pad a file with zeros as necessary to achieve word alignment. * * Input Parameters: * fd - File descriptor to be used. diff --git a/graphics/twm4nx/apps/ccalibration.cxx b/graphics/twm4nx/apps/ccalibration.cxx index 7eab8067a..40317cdb6 100644 --- a/graphics/twm4nx/apps/ccalibration.cxx +++ b/graphics/twm4nx/apps/ccalibration.cxx @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include diff --git a/graphics/twm4nx/apps/cclock.cxx b/graphics/twm4nx/apps/cclock.cxx index 55c6c3e34..e9d3b55bd 100644 --- a/graphics/twm4nx/apps/cclock.cxx +++ b/graphics/twm4nx/apps/cclock.cxx @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include diff --git a/graphics/twm4nx/apps/cnxterm.cxx b/graphics/twm4nx/apps/cnxterm.cxx index 1918775a8..a36edc4db 100644 --- a/graphics/twm4nx/apps/cnxterm.cxx +++ b/graphics/twm4nx/apps/cnxterm.cxx @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include "nshlib/nshlib.h" diff --git a/graphics/twm4nx/src/cmainmenu.cxx b/graphics/twm4nx/src/cmainmenu.cxx index 2c2034f3b..e2b9c1992 100644 --- a/graphics/twm4nx/src/cmainmenu.cxx +++ b/graphics/twm4nx/src/cmainmenu.cxx @@ -27,7 +27,7 @@ #include #include -#include +#include #include diff --git a/include/graphics/nxwidgets/cscaledbitmap.hxx b/include/graphics/nxwidgets/cscaledbitmap.hxx index b2cc5f577..f175dd6ee 100644 --- a/include/graphics/nxwidgets/cscaledbitmap.hxx +++ b/include/graphics/nxwidgets/cscaledbitmap.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/graphics/nxwm/cstartwindow.hxx b/include/graphics/nxwm/cstartwindow.hxx index fb4fb2acb..2c1d0178a 100644 --- a/include/graphics/nxwm/cstartwindow.hxx +++ b/include/graphics/nxwm/cstartwindow.hxx @@ -29,7 +29,7 @@ #include -#include +#include #include "graphics/nxwidgets/tnxarray.hxx" diff --git a/include/graphics/twm4nx/apps/calib_config.hxx b/include/graphics/twm4nx/apps/calib_config.hxx index 85abc746a..ffcdfc6a7 100644 --- a/include/graphics/twm4nx/apps/calib_config.hxx +++ b/include/graphics/twm4nx/apps/calib_config.hxx @@ -28,7 +28,7 @@ ///////////////////////////////////////////////////////////////////////////// #include -#include +#include #include "graphics/nxwidgets/nxconfig.hxx" #include "graphics/twm4nx/twm4nx_config.hxx" diff --git a/include/graphics/twm4nx/apps/clock_config.hxx b/include/graphics/twm4nx/apps/clock_config.hxx index b6c059060..2e2db213c 100644 --- a/include/graphics/twm4nx/apps/clock_config.hxx +++ b/include/graphics/twm4nx/apps/clock_config.hxx @@ -28,7 +28,7 @@ ///////////////////////////////////////////////////////////////////////////// #include -#include +#include #include "graphics/nxglyphs.hxx" #include "graphics/nxwidgets/crlepalettebitmap.hxx" diff --git a/include/graphics/twm4nx/apps/nxterm_config.hxx b/include/graphics/twm4nx/apps/nxterm_config.hxx index e90be9b90..2d0661e9e 100644 --- a/include/graphics/twm4nx/apps/nxterm_config.hxx +++ b/include/graphics/twm4nx/apps/nxterm_config.hxx @@ -28,7 +28,7 @@ ///////////////////////////////////////////////////////////////////////////// #include -#include +#include #include "graphics/nxglyphs.hxx" #include "graphics/nxwidgets/crlepalettebitmap.hxx" diff --git a/include/graphics/twm4nx/ciconwidget.hxx b/include/graphics/twm4nx/ciconwidget.hxx index e96b69ca8..e9152fc19 100644 --- a/include/graphics/twm4nx/ciconwidget.hxx +++ b/include/graphics/twm4nx/ciconwidget.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/graphics/twm4nx/twm4nx_config.hxx b/include/graphics/twm4nx/twm4nx_config.hxx index 679cc887e..60b34d09d 100644 --- a/include/graphics/twm4nx/twm4nx_config.hxx +++ b/include/graphics/twm4nx/twm4nx_config.hxx @@ -28,7 +28,7 @@ ///////////////////////////////////////////////////////////////////////////// #include -#include +#include #include "graphics/nxglyphs.hxx" #include "graphics/nxwidgets/nxconfig.hxx" diff --git a/include/netutils/cmux.h b/include/netutils/cmux.h index 42f0d5ca0..8bbf2e1f0 100644 --- a/include/netutils/cmux.h +++ b/include/netutils/cmux.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include /**************************************************************************** diff --git a/industry/foc/fixed16/foc_cordic.c b/industry/foc/fixed16/foc_cordic.c index fdd4cc059..22af88a46 100644 --- a/industry/foc/fixed16/foc_cordic.c +++ b/industry/foc/fixed16/foc_cordic.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include diff --git a/industry/foc/float/foc_cordic.c b/industry/foc/float/foc_cordic.c index f53c05674..d4fe510ff 100644 --- a/industry/foc/float/foc_cordic.c +++ b/industry/foc/float/foc_cordic.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include diff --git a/interpreters/python/python_wrapper.c b/interpreters/python/python_wrapper.c index 1eb1d3cc3..6617bae98 100644 --- a/interpreters/python/python_wrapper.c +++ b/interpreters/python/python_wrapper.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include diff --git a/logging/nxscope/nxscope.c b/logging/nxscope/nxscope.c index f919bf62c..094395dd8 100644 --- a/logging/nxscope/nxscope.c +++ b/logging/nxscope/nxscope.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include @@ -150,7 +150,7 @@ static int nxscope_chinfo_send(FAR struct nxscope_s *s, uint8_t ch) namelen = strnlen(s->chinfo[ch].name, CHAN_NAMELEN_MAX); memcpy(&data[tmp], s->chinfo[ch].name, namelen); - /* Treminate name wit a null-character */ + /* Terminate name with a null character */ txlen = tmp + namelen + 1; data[txlen - 1] = '\0'; diff --git a/logging/nxscope/nxscope_chan.c b/logging/nxscope/nxscope_chan.c index 10c30ad25..a68451f47 100644 --- a/logging/nxscope/nxscope_chan.c +++ b/logging/nxscope/nxscope_chan.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/logging/nxscope/nxscope_idummy.c b/logging/nxscope/nxscope_idummy.c index 8615748af..f139ce4dd 100644 --- a/logging/nxscope/nxscope_idummy.c +++ b/logging/nxscope/nxscope_idummy.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/logging/nxscope/nxscope_internals.c b/logging/nxscope/nxscope_internals.c index 43ffdd610..b001b4187 100644 --- a/logging/nxscope/nxscope_internals.c +++ b/logging/nxscope/nxscope_internals.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include diff --git a/logging/nxscope/nxscope_iser.c b/logging/nxscope/nxscope_iser.c index b1722042b..492617723 100644 --- a/logging/nxscope/nxscope_iser.c +++ b/logging/nxscope/nxscope_iser.c @@ -26,7 +26,7 @@ #include -#include +#include #include #include #include diff --git a/logging/nxscope/nxscope_iudp.c b/logging/nxscope/nxscope_iudp.c index 07aae7711..5a5e1eed0 100644 --- a/logging/nxscope/nxscope_iudp.c +++ b/logging/nxscope/nxscope_iudp.c @@ -26,7 +26,7 @@ #include -#include +#include #include #include #include diff --git a/logging/nxscope/nxscope_pser.c b/logging/nxscope/nxscope_pser.c index 2d0917d51..2f8d5ad41 100644 --- a/logging/nxscope/nxscope_pser.c +++ b/logging/nxscope/nxscope_pser.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include @@ -274,7 +274,7 @@ int nxscope_proto_ser_init(FAR struct nxscope_proto_s *proto, FAR void *cfg) { DEBUGASSERT(proto); - /* cfg argument not used, but keept here for compatibility with + /* cfg argument not used, but kept here for compatibility with * future protocol implementations. */ diff --git a/lte/alt1250/alt1250_dbg.h b/lte/alt1250/alt1250_dbg.h index 82b9bb27a..0034bea82 100644 --- a/lte/alt1250/alt1250_dbg.h +++ b/lte/alt1250/alt1250_dbg.h @@ -29,7 +29,7 @@ #include #include -#include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/lte/lapi/src/lapi_dbg.h b/lte/lapi/src/lapi_dbg.h index 403847653..ebe02523a 100644 --- a/lte/lapi/src/lapi_dbg.h +++ b/lte/lapi/src/lapi_dbg.h @@ -27,7 +27,7 @@ * Included Files ****************************************************************************/ -#include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/netutils/chat/chat.c b/netutils/chat/chat.c index 3849631df..c1af84ae8 100644 --- a/netutils/chat/chat.c +++ b/netutils/chat/chat.c @@ -45,7 +45,7 @@ #include #include -#include +#include #include #include #include diff --git a/netutils/cmux/cmux.h b/netutils/cmux/cmux.h index 470aacfa4..7758f83b5 100644 --- a/netutils/cmux/cmux.h +++ b/netutils/cmux/cmux.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include #define CMUX_BIT0 (0) diff --git a/netutils/dhcp6c/dhcp6c.c b/netutils/dhcp6c/dhcp6c.c index 5418c0a98..3989bee0c 100644 --- a/netutils/dhcp6c/dhcp6c.c +++ b/netutils/dhcp6c/dhcp6c.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/netutils/dhcpc/dhcpc.c b/netutils/dhcpc/dhcpc.c index 003d7d8cb..e899b6930 100644 --- a/netutils/dhcpc/dhcpc.c +++ b/netutils/dhcpc/dhcpc.c @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/dhcpd/dhcpd.c b/netutils/dhcpd/dhcpd.c index a382709a2..a166e9123 100644 --- a/netutils/dhcpd/dhcpd.c +++ b/netutils/dhcpd/dhcpd.c @@ -40,7 +40,7 @@ # define OK (0) #else # include /* NuttX configuration */ -# include /* For nerr, info */ +# include /* For nerr, info */ # include /* For CONFIG_CPP_HAVE_WARNING */ # include "netutils/dhcpd.h" /* Advertised DHCPD APIs */ #endif diff --git a/netutils/discover/discover.c b/netutils/discover/discover.c index 6bb3f675b..ba11fbe87 100644 --- a/netutils/discover/discover.c +++ b/netutils/discover/discover.c @@ -24,7 +24,7 @@ * Included Files ****************************************************************************/ -#include +#include #include #include #include diff --git a/netutils/esp8266/esp8266.c b/netutils/esp8266/esp8266.c index 51de514b7..051dd15fc 100644 --- a/netutils/esp8266/esp8266.c +++ b/netutils/esp8266/esp8266.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/ftpc/ftpc_chmod.c b/netutils/ftpc/ftpc_chmod.c index 5710b7c8b..d9b490b0a 100644 --- a/netutils/ftpc/ftpc_chmod.c +++ b/netutils/ftpc/ftpc_chmod.c @@ -26,7 +26,7 @@ #include "ftpc_config.h" -#include +#include #include "netutils/ftpc.h" #include "ftpc_internal.h" diff --git a/netutils/ftpc/ftpc_cmd.c b/netutils/ftpc/ftpc_cmd.c index b6b7556b5..1e3ff9ea8 100644 --- a/netutils/ftpc/ftpc_cmd.c +++ b/netutils/ftpc/ftpc_cmd.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "ftpc_internal.h" diff --git a/netutils/ftpc/ftpc_connect.c b/netutils/ftpc/ftpc_connect.c index 8624f4905..61defa614 100644 --- a/netutils/ftpc/ftpc_connect.c +++ b/netutils/ftpc/ftpc_connect.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include diff --git a/netutils/ftpc/ftpc_getfile.c b/netutils/ftpc/ftpc_getfile.c index 83524df4e..3ca989a80 100644 --- a/netutils/ftpc/ftpc_getfile.c +++ b/netutils/ftpc/ftpc_getfile.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include "netutils/ftpc.h" diff --git a/netutils/ftpc/ftpc_getreply.c b/netutils/ftpc/ftpc_getreply.c index d5a3d0983..e63e0ed2b 100644 --- a/netutils/ftpc/ftpc_getreply.c +++ b/netutils/ftpc/ftpc_getreply.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include "ftpc_internal.h" diff --git a/netutils/ftpc/ftpc_idle.c b/netutils/ftpc/ftpc_idle.c index 42e2fdbef..dd5ab5c23 100644 --- a/netutils/ftpc/ftpc_idle.c +++ b/netutils/ftpc/ftpc_idle.c @@ -26,7 +26,7 @@ #include "ftpc_config.h" -#include +#include #include "netutils/ftpc.h" #include "ftpc_internal.h" diff --git a/netutils/ftpc/ftpc_listdir.c b/netutils/ftpc/ftpc_listdir.c index 92461f6e3..02947ad5c 100644 --- a/netutils/ftpc/ftpc_listdir.c +++ b/netutils/ftpc/ftpc_listdir.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "netutils/ftpc.h" diff --git a/netutils/ftpc/ftpc_login.c b/netutils/ftpc/ftpc_login.c index 9e99c0dc5..4ee477e00 100644 --- a/netutils/ftpc/ftpc_login.c +++ b/netutils/ftpc/ftpc_login.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include "netutils/ftpc.h" diff --git a/netutils/ftpc/ftpc_putfile.c b/netutils/ftpc/ftpc_putfile.c index 9ac75cc0e..a0ea6bc3e 100644 --- a/netutils/ftpc/ftpc_putfile.c +++ b/netutils/ftpc/ftpc_putfile.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include "netutils/ftpc.h" diff --git a/netutils/ftpc/ftpc_rpwd.c b/netutils/ftpc/ftpc_rpwd.c index 8ff608d9b..c2673b20e 100644 --- a/netutils/ftpc/ftpc_rpwd.c +++ b/netutils/ftpc/ftpc_rpwd.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include "netutils/ftpc.h" diff --git a/netutils/ftpc/ftpc_socket.c b/netutils/ftpc/ftpc_socket.c index db9b4ccd0..4a769a3d3 100644 --- a/netutils/ftpc/ftpc_socket.c +++ b/netutils/ftpc/ftpc_socket.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include "ftpc_internal.h" diff --git a/netutils/ftpc/ftpc_transfer.c b/netutils/ftpc/ftpc_transfer.c index 7d294d52d..b6ef5a65c 100644 --- a/netutils/ftpc/ftpc_transfer.c +++ b/netutils/ftpc/ftpc_transfer.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include "netutils/ftpc.h" diff --git a/netutils/ftpd/ftpd.c b/netutils/ftpd/ftpd.c index 73b8fc9b9..a6ed75324 100644 --- a/netutils/ftpd/ftpd.c +++ b/netutils/ftpd/ftpd.c @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include diff --git a/netutils/libcurl4nx/curl4nx_easy_cleanup.c b/netutils/libcurl4nx/curl4nx_easy_cleanup.c index 1c3000671..0533693e8 100644 --- a/netutils/libcurl4nx/curl4nx_easy_cleanup.c +++ b/netutils/libcurl4nx/curl4nx_easy_cleanup.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/netutils/libcurl4nx/curl4nx_easy_duphandle.c b/netutils/libcurl4nx/curl4nx_easy_duphandle.c index 4de16e0af..9bf44580c 100644 --- a/netutils/libcurl4nx/curl4nx_easy_duphandle.c +++ b/netutils/libcurl4nx/curl4nx_easy_duphandle.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/netutils/libcurl4nx/curl4nx_easy_escape.c b/netutils/libcurl4nx/curl4nx_easy_escape.c index ff76d6d8c..8c5919b72 100644 --- a/netutils/libcurl4nx/curl4nx_easy_escape.c +++ b/netutils/libcurl4nx/curl4nx_easy_escape.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/netutils/libcurl4nx/curl4nx_easy_getinfo.c b/netutils/libcurl4nx/curl4nx_easy_getinfo.c index ed8e90a9d..ff64739ad 100644 --- a/netutils/libcurl4nx/curl4nx_easy_getinfo.c +++ b/netutils/libcurl4nx/curl4nx_easy_getinfo.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/netutils/libcurl4nx/curl4nx_easy_init.c b/netutils/libcurl4nx/curl4nx_easy_init.c index 1817bf734..661cfde76 100644 --- a/netutils/libcurl4nx/curl4nx_easy_init.c +++ b/netutils/libcurl4nx/curl4nx_easy_init.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/netutils/libcurl4nx/curl4nx_easy_perform.c b/netutils/libcurl4nx/curl4nx_easy_perform.c index 466b3efe7..529aaa22d 100644 --- a/netutils/libcurl4nx/curl4nx_easy_perform.c +++ b/netutils/libcurl4nx/curl4nx_easy_perform.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/netutils/libcurl4nx/curl4nx_easy_reset.c b/netutils/libcurl4nx/curl4nx_easy_reset.c index 7ece89011..9ee355a2f 100644 --- a/netutils/libcurl4nx/curl4nx_easy_reset.c +++ b/netutils/libcurl4nx/curl4nx_easy_reset.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/netutils/libcurl4nx/curl4nx_easy_setopt.c b/netutils/libcurl4nx/curl4nx_easy_setopt.c index 03f8ff5d1..378862b9e 100644 --- a/netutils/libcurl4nx/curl4nx_easy_setopt.c +++ b/netutils/libcurl4nx/curl4nx_easy_setopt.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/netutils/libcurl4nx/curl4nx_easy_unescape.c b/netutils/libcurl4nx/curl4nx_easy_unescape.c index 23f169afe..7e3955497 100644 --- a/netutils/libcurl4nx/curl4nx_easy_unescape.c +++ b/netutils/libcurl4nx/curl4nx_easy_unescape.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/netutils/mdns/mdnsd.c b/netutils/mdns/mdnsd.c index 1f648950b..d060a8849 100644 --- a/netutils/mdns/mdnsd.c +++ b/netutils/mdns/mdnsd.c @@ -32,7 +32,7 @@ #include #include #include -#include /* For nerr, info */ +#include /* For nerr, info */ #include "netutils/netlib.h" #include "netutils/mdnsd.h" diff --git a/netutils/netinit/netinit.c b/netutils/netinit/netinit.c index c0a459725..24feea642 100644 --- a/netutils/netinit/netinit.c +++ b/netutils/netinit/netinit.c @@ -36,7 +36,7 @@ #endif #include -#include +#include #include #include #include diff --git a/netutils/netlib/netlib_checkhttpconnectivity.c b/netutils/netlib/netlib_checkhttpconnectivity.c index 4b0df89c2..a4ed482e5 100644 --- a/netutils/netlib/netlib_checkhttpconnectivity.c +++ b/netutils/netlib/netlib_checkhttpconnectivity.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #ifdef CONFIG_LIBC_NETDB # include diff --git a/netutils/netlib/netlib_checkifconflict.c b/netutils/netlib/netlib_checkifconflict.c index 5aebddd8e..c8c8fc2c1 100644 --- a/netutils/netlib/netlib_checkifconflict.c +++ b/netutils/netlib/netlib_checkifconflict.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include "netutils/netlib.h" diff --git a/netutils/netlib/netlib_checkifconnectivity.c b/netutils/netlib/netlib_checkifconnectivity.c index c08995366..bfc06001a 100644 --- a/netutils/netlib/netlib_checkifconnectivity.c +++ b/netutils/netlib/netlib_checkifconnectivity.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/netlib/netlib_checkipconnectivity.c b/netutils/netlib/netlib_checkipconnectivity.c index 44a5c636a..04b3c3c0b 100644 --- a/netutils/netlib/netlib_checkipconnectivity.c +++ b/netutils/netlib/netlib_checkipconnectivity.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/netlib/netlib_getifstatistics.c b/netutils/netlib/netlib_getifstatistics.c index b838d556d..e6c52abba 100644 --- a/netutils/netlib/netlib_getifstatistics.c +++ b/netutils/netlib/netlib_getifstatistics.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include diff --git a/netutils/netlib/netlib_ipmsfilter.c b/netutils/netlib/netlib_ipmsfilter.c index d7f9b0ff1..9fa2f23aa 100644 --- a/netutils/netlib/netlib_ipmsfilter.c +++ b/netutils/netlib/netlib_ipmsfilter.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/netlib/netlib_listenon.c b/netutils/netlib/netlib_listenon.c index 608937ff7..a80cd8158 100644 --- a/netutils/netlib/netlib_listenon.c +++ b/netutils/netlib/netlib_listenon.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/netlib/netlib_nodeaddrconv.c b/netutils/netlib/netlib_nodeaddrconv.c index 67c6ee2f7..1df293788 100644 --- a/netutils/netlib/netlib_nodeaddrconv.c +++ b/netutils/netlib/netlib_nodeaddrconv.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include "nuttx/wireless/pktradio.h" #include "netutils/netlib.h" diff --git a/netutils/netlib/netlib_obtainipv4addr.c b/netutils/netlib/netlib_obtainipv4addr.c index 5390466fe..cab55b74c 100644 --- a/netutils/netlib/netlib_obtainipv4addr.c +++ b/netutils/netlib/netlib_obtainipv4addr.c @@ -24,7 +24,7 @@ * Included Files ****************************************************************************/ -#include +#include #include #include "netutils/dhcpc.h" diff --git a/netutils/netlib/netlib_obtainipv6addr.c b/netutils/netlib/netlib_obtainipv6addr.c index f55667705..c1a74b8ce 100644 --- a/netutils/netlib/netlib_obtainipv6addr.c +++ b/netutils/netlib/netlib_obtainipv6addr.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/netlib/netlib_server.c b/netutils/netlib/netlib_server.c index 98ff5e907..9436481bc 100644 --- a/netutils/netlib/netlib_server.c +++ b/netutils/netlib/netlib_server.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include diff --git a/netutils/ntpclient/ntpclient.c b/netutils/ntpclient/ntpclient.c index 22c448fdd..ce7d2f0d9 100644 --- a/netutils/ntpclient/ntpclient.c +++ b/netutils/ntpclient/ntpclient.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/pppd/ppp.h b/netutils/pppd/ppp.h index f436a1206..519b7f168 100644 --- a/netutils/pppd/ppp.h +++ b/netutils/pppd/ppp.h @@ -51,7 +51,7 @@ #include "netutils/chat.h" -#include "debug.h" +#include #include "ppp_conf.h" #include "ahdlc.h" #include "lcp.h" diff --git a/netutils/pppd/pppd.c b/netutils/pppd/pppd.c index 73efa27c9..849e3e874 100644 --- a/netutils/pppd/pppd.c +++ b/netutils/pppd/pppd.c @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index f85619093..74b43084d 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/telnetd/telnetd_daemon.c b/netutils/telnetd/telnetd_daemon.c index 989de34f9..c1512113c 100644 --- a/netutils/telnetd/telnetd_daemon.c +++ b/netutils/telnetd/telnetd_daemon.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include diff --git a/netutils/tftpc/tftpc_get.c b/netutils/tftpc/tftpc_get.c index 36227e29a..84be9b223 100644 --- a/netutils/tftpc/tftpc_get.c +++ b/netutils/tftpc/tftpc_get.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include diff --git a/netutils/tftpc/tftpc_packets.c b/netutils/tftpc/tftpc_packets.c index 05d56083c..9f6af0c65 100644 --- a/netutils/tftpc/tftpc_packets.c +++ b/netutils/tftpc/tftpc_packets.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include diff --git a/netutils/tftpc/tftpc_put.c b/netutils/tftpc/tftpc_put.c index 3f3a9c849..456100bdb 100644 --- a/netutils/tftpc/tftpc_put.c +++ b/netutils/tftpc/tftpc_put.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include "netutils/tftp.h" diff --git a/netutils/thttpd/fdwatch.c b/netutils/thttpd/fdwatch.c index 105fea30f..dcbd782e5 100644 --- a/netutils/thttpd/fdwatch.c +++ b/netutils/thttpd/fdwatch.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include "config.h" diff --git a/netutils/thttpd/libhttpd.c b/netutils/thttpd/libhttpd.c index 2d6a558e6..19acb562c 100644 --- a/netutils/thttpd/libhttpd.c +++ b/netutils/thttpd/libhttpd.c @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include "netutils/thttpd.h" diff --git a/netutils/thttpd/tdate_parse.c b/netutils/thttpd/tdate_parse.c index 113059223..2b49d3995 100644 --- a/netutils/thttpd/tdate_parse.c +++ b/netutils/thttpd/tdate_parse.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include "tdate_parse.h" diff --git a/netutils/thttpd/thttpd.c b/netutils/thttpd/thttpd.c index 22338665b..f7de45177 100644 --- a/netutils/thttpd/thttpd.c +++ b/netutils/thttpd/thttpd.c @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include diff --git a/netutils/thttpd/thttpd_alloc.c b/netutils/thttpd/thttpd_alloc.c index 7999f7823..6deade0be 100644 --- a/netutils/thttpd/thttpd_alloc.c +++ b/netutils/thttpd/thttpd_alloc.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include "config.h" diff --git a/netutils/thttpd/thttpd_cgi.c b/netutils/thttpd/thttpd_cgi.c index 5c8914560..a0cacf03e 100644 --- a/netutils/thttpd/thttpd_cgi.c +++ b/netutils/thttpd/thttpd_cgi.c @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #include "netutils/thttpd.h" @@ -766,7 +766,7 @@ static int cgi_child(int argc, char **argv) /* Close all file descriptors EXCEPT for stdin, stdout, stderr and * hc->conn_fd. We'll keep stderr open for error reporting; stdin and * stdout will be closed later by dup2(). Keeping stdin and stdout open - * now prevents re-use of fd=0 and 1 by pipe(). + * now prevents reuse of fd=0 and 1 by pipe(). */ ninfo("Closing descriptors\n"); diff --git a/netutils/thttpd/timers.c b/netutils/thttpd/timers.c index a3bd89831..d2026bd1b 100644 --- a/netutils/thttpd/timers.c +++ b/netutils/thttpd/timers.c @@ -39,7 +39,7 @@ #include #include -#include +#include #include "thttpd_alloc.h" #include "timers.h" diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c index 8784b68b5..61f56cb4f 100644 --- a/netutils/webclient/webclient.c +++ b/netutils/webclient/webclient.c @@ -48,7 +48,7 @@ #include #include -#include +#include #include #include @@ -857,7 +857,7 @@ static inline int wget_parsechunkheader(struct webclient_context *ctx, if (semicolon != NULL) { found_extension = true; - ninfo("Ignoring extentions in chunk header\n"); + ninfo("Ignoring extensions in chunk header\n"); *semicolon = 0; } } diff --git a/netutils/webserver/httpd.c b/netutils/webserver/httpd.c index 23f69a949..1cc8d58fc 100644 --- a/netutils/webserver/httpd.c +++ b/netutils/webserver/httpd.c @@ -52,7 +52,7 @@ #include #include #include -#include +#include #ifndef CONFIG_NETUTILS_HTTPD_SINGLECONNECT # include diff --git a/netutils/webserver/httpd_dirlist.c b/netutils/webserver/httpd_dirlist.c index bac1b2d77..6dda65286 100644 --- a/netutils/webserver/httpd_dirlist.c +++ b/netutils/webserver/httpd_dirlist.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/netutils/webserver/httpd_mmap.c b/netutils/webserver/httpd_mmap.c index a4f47427d..b17ad54c4 100644 --- a/netutils/webserver/httpd_mmap.c +++ b/netutils/webserver/httpd_mmap.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include "netutils/httpd.h" diff --git a/netutils/webserver/httpd_sendfile.c b/netutils/webserver/httpd_sendfile.c index 7ff8a5ccd..3a8286fe9 100644 --- a/netutils/webserver/httpd_sendfile.c +++ b/netutils/webserver/httpd_sendfile.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include "netutils/httpd.h" diff --git a/nshlib/nsh_altconsole.c b/nshlib/nsh_altconsole.c index 7423fedf7..bb9fc30f2 100644 --- a/nshlib/nsh_altconsole.c +++ b/nshlib/nsh_altconsole.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include "nsh.h" diff --git a/nshlib/nsh_codeccmd.c b/nshlib/nsh_codeccmd.c index 91b3953ff..0d677669f 100644 --- a/nshlib/nsh_codeccmd.c +++ b/nshlib/nsh_codeccmd.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #if defined(CONFIG_NSH_DISABLE_URLENCODE) && defined(CONFIG_NSH_DISABLE_URLDECODE) # undef CONFIG_CODECS_URLCODE diff --git a/nshlib/nsh_console.c b/nshlib/nsh_console.c index cb95e0342..ebcbe6fb2 100644 --- a/nshlib/nsh_console.c +++ b/nshlib/nsh_console.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include "nsh.h" #include "nsh_console.h" diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index 13f26f694..a88c1a20d 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include "nsh.h" diff --git a/nshlib/nsh_mntcmds.c b/nshlib/nsh_mntcmds.c index f4a2e903b..a58d6ef9c 100644 --- a/nshlib/nsh_mntcmds.c +++ b/nshlib/nsh_mntcmds.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 8cd0d6cc3..3171bdfbb 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -45,7 +45,7 @@ #include /* Needed for basename */ #include #include -#include +#include #include #if defined(CONFIG_LIBC_NETDB) && !defined(CONFIG_NSH_DISABLE_NSLOOKUP) diff --git a/nshlib/nsh_parse.c b/nshlib/nsh_parse.c index 9a67cc845..61ed7de55 100644 --- a/nshlib/nsh_parse.c +++ b/nshlib/nsh_parse.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/nshlib/nsh_telnetd.c b/nshlib/nsh_telnetd.c index 62f87e479..83fc36ca6 100644 --- a/nshlib/nsh_telnetd.c +++ b/nshlib/nsh_telnetd.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include diff --git a/nshlib/nsh_usbconsole.c b/nshlib/nsh_usbconsole.c index cc7f97005..74f8a4795 100644 --- a/nshlib/nsh_usbconsole.c +++ b/nshlib/nsh_usbconsole.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #ifdef CONFIG_CDCACM # include diff --git a/nshlib/nsh_usbtrace.c b/nshlib/nsh_usbtrace.c index df05d45a3..f57a81ac6 100644 --- a/nshlib/nsh_usbtrace.c +++ b/nshlib/nsh_usbtrace.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include diff --git a/platform/mikroe-stm32f4/mikroe_configdata.c b/platform/mikroe-stm32f4/mikroe_configdata.c index b6d9bb6fc..d65e695c7 100644 --- a/platform/mikroe-stm32f4/mikroe_configdata.c +++ b/platform/mikroe-stm32f4/mikroe_configdata.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include @@ -233,7 +233,7 @@ int platform_getconfig(enum config_data_e id, int instance, case CONFIGDATA_TSCALIBRATION: #ifdef CONFIG_MIKROE_STM32F4_CONFIGDATA_FS - /* Load config data fram a file on the filesystem. Try to open + /* Load config data from a file on the filesystem. Try to open * the file. */ diff --git a/system/cdcacm/sercon_main.c b/system/cdcacm/sercon_main.c index 9b8ab41d8..c03ce2d18 100644 --- a/system/cdcacm/sercon_main.c +++ b/system/cdcacm/sercon_main.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include diff --git a/system/cdcacm/serdis_main.c b/system/cdcacm/serdis_main.c index 834ae186b..56e5fbfe0 100644 --- a/system/cdcacm/serdis_main.c +++ b/system/cdcacm/serdis_main.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include diff --git a/system/cle/cle.c b/system/cle/cle.c index 21b442806..bfa01c11f 100644 --- a/system/cle/cle.c +++ b/system/cle/cle.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include diff --git a/system/composite/composite_main.c b/system/composite/composite_main.c index 9dc4399e8..f6dc54bff 100644 --- a/system/composite/composite_main.c +++ b/system/composite/composite_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/system/cu/cu_main.c b/system/cu/cu_main.c index fa5b31900..f0767ddc3 100644 --- a/system/cu/cu_main.c +++ b/system/cu/cu_main.c @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/system/dd/dd_main.c b/system/dd/dd_main.c index 9be5de7ac..a240ae3fe 100644 --- a/system/dd/dd_main.c +++ b/system/dd/dd_main.c @@ -32,7 +32,7 @@ #include #ifdef __NuttX__ -#include +#include #endif #include #include diff --git a/system/dhcp6c/renew6_main.c b/system/dhcp6c/renew6_main.c index d0f44382b..7149af1f2 100644 --- a/system/dhcp6c/renew6_main.c +++ b/system/dhcp6c/renew6_main.c @@ -25,7 +25,7 @@ ****************************************************************************/ #include -#include +#include #include #include diff --git a/system/i2c/i2c_main.c b/system/i2c/i2c_main.c index 7abe9bdd1..80e7974d2 100644 --- a/system/i2c/i2c_main.c +++ b/system/i2c/i2c_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include "i2ctool.h" @@ -165,7 +165,7 @@ static int i2ccmd_help(FAR struct i2ctool_s *i2ctool, int argc, "o Arguments are \"sticky\". For example, once " "the I2C address is\n"); i2ctool_printf(i2ctool, - " specified, that address will be re-used until " + " specified, that address will be reused until " "it is changed.\n"); i2ctool_printf(i2ctool, "\nWARNING:\n"); i2ctool_printf(i2ctool, diff --git a/system/nxcamera/nxcamera.c b/system/nxcamera/nxcamera.c index d2070e966..d698b9e20 100644 --- a/system/nxcamera/nxcamera.c +++ b/system/nxcamera/nxcamera.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/system/nxlooper/nxlooper.c b/system/nxlooper/nxlooper.c index 3d8404520..6c142ee26 100644 --- a/system/nxlooper/nxlooper.c +++ b/system/nxlooper/nxlooper.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/system/nxplayer/nxplayer.c b/system/nxplayer/nxplayer.c index 0de66f68a..173ad622f 100644 --- a/system/nxplayer/nxplayer.c +++ b/system/nxplayer/nxplayer.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/system/nxplayer/nxplayer_common.c b/system/nxplayer/nxplayer_common.c index 94b794c2c..c33c38690 100644 --- a/system/nxplayer/nxplayer_common.c +++ b/system/nxplayer/nxplayer_common.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/system/nxrecorder/nxrecorder.c b/system/nxrecorder/nxrecorder.c index 6a75f6a57..2f6d01d22 100644 --- a/system/nxrecorder/nxrecorder.c +++ b/system/nxrecorder/nxrecorder.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/system/nxrecorder/nxrecorder_common.c b/system/nxrecorder/nxrecorder_common.c index d063f140c..c78a360ca 100644 --- a/system/nxrecorder/nxrecorder_common.c +++ b/system/nxrecorder/nxrecorder_common.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/system/popen/popen.c b/system/popen/popen.c index d9286c959..b52fbaafe 100644 --- a/system/popen/popen.c +++ b/system/popen/popen.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/system/readline/readline_common.c b/system/readline/readline_common.c index 273821357..0fd3b9396 100644 --- a/system/readline/readline_common.c +++ b/system/readline/readline_common.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/system/spi/spi_main.c b/system/spi/spi_main.c index 140826e43..8950a48b8 100644 --- a/system/spi/spi_main.c +++ b/system/spi/spi_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include "spitool.h" diff --git a/system/system/system.c b/system/system/system.c index 3fd9850d7..46db1719b 100644 --- a/system/system/system.c +++ b/system/system/system.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/system/tee/tee.c b/system/tee/tee.c index cb934c7a9..844c94c11 100644 --- a/system/tee/tee.c +++ b/system/tee/tee.c @@ -50,7 +50,7 @@ #include #include #include -#include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/system/termcurses/tcurses_vt100.c b/system/termcurses/tcurses_vt100.c index 84c369cce..ac4685a4e 100644 --- a/system/termcurses/tcurses_vt100.c +++ b/system/termcurses/tcurses_vt100.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/system/termcurses/termcurses.c b/system/termcurses/termcurses.c index 4d042b6eb..6e3273c31 100644 --- a/system/termcurses/termcurses.c +++ b/system/termcurses/termcurses.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include "tcurses_priv.h" diff --git a/system/ubloxmodem/ubloxmodem_main.c b/system/ubloxmodem/ubloxmodem_main.c index 0a54b9240..3f7baa601 100644 --- a/system/ubloxmodem/ubloxmodem_main.c +++ b/system/ubloxmodem/ubloxmodem_main.c @@ -45,7 +45,7 @@ #include #include -#include +#include #include #include #include diff --git a/system/usbmsc/usbmsc_main.c b/system/usbmsc/usbmsc_main.c index 6b08e4da0..3cddcc230 100644 --- a/system/usbmsc/usbmsc_main.c +++ b/system/usbmsc/usbmsc_main.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/system/vi/vi.c b/system/vi/vi.c index d2c894cf3..e94bc4361 100644 --- a/system/vi/vi.c +++ b/system/vi/vi.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/system/zmodem/zm.h b/system/zmodem/zm.h index a7971c00e..8593e1ff7 100644 --- a/system/zmodem/zm.h +++ b/system/zmodem/zm.h @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include @@ -206,7 +206,7 @@ #define ZM_XFRDONE 1 /* Success - Transfer complete */ /* The actual packet buffer size includes 5 bytes to hold the transfer type - * and the maxmimum size 4-byte CRC. + * and the maximum size 4-byte CRC. */ #define ZM_PKTBUFSIZE (CONFIG_SYSTEM_ZMODEM_PKTBUFSIZE + 5) @@ -332,7 +332,7 @@ struct zm_state_s uint16_t flags; /* See ZM_FLAG_* definitions */ uint16_t nerrors; /* Number of data errors */ timer_t timer; /* Watchdog timer */ - int remfd; /* The R/W file descritor used for communication with remote */ + int remfd; /* The R/W file descriptor used for communication with remote */ /* Buffers. * diff --git a/testing/drivers/drivertest/drivertest_audio.c b/testing/drivers/drivertest/drivertest_audio.c index a467f6f26..de12da3d1 100644 --- a/testing/drivers/drivertest/drivertest_audio.c +++ b/testing/drivers/drivertest/drivertest_audio.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include diff --git a/testing/drivers/drivertest/drivertest_framebuffer.c b/testing/drivers/drivertest/drivertest_framebuffer.c index ac8f6f266..cf57d3f8a 100644 --- a/testing/drivers/drivertest/drivertest_framebuffer.c +++ b/testing/drivers/drivertest/drivertest_framebuffer.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/testing/drivers/drivertest/drivertest_lcd.c b/testing/drivers/drivertest/drivertest_lcd.c index 647d8cbe2..405b129f0 100644 --- a/testing/drivers/drivertest/drivertest_lcd.c +++ b/testing/drivers/drivertest/drivertest_lcd.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include diff --git a/testing/drivers/drivertest/drivertest_pwm.c b/testing/drivers/drivertest/drivertest_pwm.c index a587fead1..3dd3bae64 100644 --- a/testing/drivers/drivertest/drivertest_pwm.c +++ b/testing/drivers/drivertest/drivertest_pwm.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include @@ -107,7 +107,7 @@ static void pwm_help(FAR const char *progname, progname); printf("\nArguments are \"sticky\". " "For example, once the PWM frequency is\n"); - printf("specified, that frequency will be re-used until it is changed.\n"); + printf("specified, that frequency will be reused until it is changed.\n"); printf("\n\"sticky\" OPTIONS include:\n"); printf(" [-p devpath] selects the PWM device. " "Default: %s Current: %s\n", PWM_DEFAULT_DEVPATH, diff --git a/testing/drivers/drivertest/drivertest_watchdog.c b/testing/drivers/drivertest/drivertest_watchdog.c index 1021e8e10..72f5abe0e 100644 --- a/testing/drivers/drivertest/drivertest_watchdog.c +++ b/testing/drivers/drivertest/drivertest_watchdog.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/testing/drivers/nand_sim/nand_sim_main.c b/testing/drivers/nand_sim/nand_sim_main.c index 9e91227a4..70ea24227 100644 --- a/testing/drivers/nand_sim/nand_sim_main.c +++ b/testing/drivers/nand_sim/nand_sim_main.c @@ -24,7 +24,7 @@ * Included Files ****************************************************************************/ -#include +#include #include #include @@ -72,7 +72,7 @@ FAR struct nand_raw_s *g_nand_mtd_raw; * Name: wrapper_init * * Description: - * Initializes the wrapper by allocating memory and assiging the methods. + * Initializes the wrapper by allocating memory and assigning the methods. * * Returned Value: * 0: Successful @@ -114,7 +114,7 @@ int wrapper_init(void) * Name: terminate * * Description: - * Handles the SIGTERM signal by exitting gracefully. + * Handles the SIGTERM signal by exiting gracefully. * ****************************************************************************/ diff --git a/testing/fs/epoll/epoll.c b/testing/fs/epoll/epoll.c index cd1d6cc0f..8422c5fe7 100644 --- a/testing/fs/epoll/epoll.c +++ b/testing/fs/epoll/epoll.c @@ -26,7 +26,7 @@ #include -#include +#include #include #include #include @@ -193,7 +193,7 @@ static void epoll01(FAR void **state) ret = timerfd_stop(args->fd[0]); assert_true(ret == 0); - /* 3rd wait should directly return 0, timer has stoped */ + /* 3rd wait should directly return 0, timer has stopped */ ret = epoll_wait(args->efd, &evs, 1, 0); TIME_ASSERT_RANGE(get_elapse(args->start), 1000); @@ -274,7 +274,7 @@ static void epoll02(FAR void **state) struct epoll_event evs[2]; int ret; - /* 1st wait, shoud return after 1000ms */ + /* 1st wait, should return after 1000ms */ ret = epoll_wait(args->efd, evs, 2, 1100); TIME_ASSERT_RANGE(get_elapse(args->start), 1000); @@ -406,7 +406,7 @@ static void epoll03(FAR void **state) /* 1st wait should timeout, because server accept will trigger * EPOLLOUT event, but we do not set EPOLLOUT in ev.events. - * Even the server has writen the data, but to check the EPOLLIN event, + * Even the server has written the data, but to check the EPOLLIN event, * client need call epoll_wait again, because local socket internal state * changed, we need setup it again to get the EPOLLIN event. */ @@ -416,7 +416,7 @@ static void epoll03(FAR void **state) TIME_ASSERT_RANGE(get_elapse(args->start), 1000); assert_true(ret == 0); - /* 2nd wait shoud return immediately, because server has send + /* 2nd wait should return immediately, because server has sent * data to client. */ diff --git a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c index c85df92aa..7b8390150 100644 --- a/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c +++ b/testing/fs/mtd_config_fs/mtd_config_fs_test_main.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include /**************************************************************************** diff --git a/testing/fs/nxffs/nxffs_main.c b/testing/fs/nxffs/nxffs_main.c index 25c15513a..3305aa684 100644 --- a/testing/fs/nxffs/nxffs_main.c +++ b/testing/fs/nxffs/nxffs_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include @@ -598,7 +598,7 @@ static int nxffs_verifyfs(void) else { #if CONFIG_TESTING_NXFFS_VERBOSE != 0 - printf(" Verifed file %s\n", file->name); + printf(" Verified file %s\n", file->name); #endif } } diff --git a/testing/fs/smart/smart_main.c b/testing/fs/smart/smart_main.c index 671f5b5cb..9c8717a9d 100644 --- a/testing/fs/smart/smart_main.c +++ b/testing/fs/smart/smart_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include @@ -611,7 +611,7 @@ static int smart_verifyfs(void) else { #if CONFIG_TESTING_SMART_VERBOSE != 0 - printf(" Verifed file %s\n", file->name); + printf(" Verified file %s\n", file->name); #endif } } diff --git a/testing/libc/arch_libc/arch_libc_test_main.c b/testing/libc/arch_libc/arch_libc_test_main.c index 1e1a06b19..b69c1dfc4 100644 --- a/testing/libc/arch_libc/arch_libc_test_main.c +++ b/testing/libc/arch_libc/arch_libc_test_main.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include /**************************************************************************** diff --git a/testing/libc/scanftest/scanftest_main.c b/testing/libc/scanftest/scanftest_main.c index 6334c3074..0b1e614ae 100644 --- a/testing/libc/scanftest/scanftest_main.c +++ b/testing/libc/scanftest/scanftest_main.c @@ -75,7 +75,7 @@ #include #include #include -#include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/testing/mm/memstress/memorystress_main.c b/testing/mm/memstress/memorystress_main.c index eca7b7735..f3952e08d 100644 --- a/testing/mm/memstress/memorystress_main.c +++ b/testing/mm/memstress/memorystress_main.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/testing/ostest/signest.c b/testing/ostest/signest.c index 5e8e65961..d79b40119 100644 --- a/testing/ostest/signest.c +++ b/testing/ostest/signest.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include "ostest.h" @@ -532,7 +532,7 @@ errout_with_waiter: total_handled = g_odd_handled + g_even_handled; total_nested = g_odd_nested + g_even_nested; - printf("signest_test: With intefering thread\n"); + printf("signest_test: With interfering thread\n"); printf(" Total signalled %-3d Odd=%-3d Even=%-3d\n", total_signals, odd_signals, even_signals); printf(" Total handled %-3d Odd=%-3d Even=%-3d\n", diff --git a/wireless/bluetooth/nimble/include/logcfg/logcfg.h b/wireless/bluetooth/nimble/include/logcfg/logcfg.h index 419c1373d..de738d51f 100644 --- a/wireless/bluetooth/nimble/include/logcfg/logcfg.h +++ b/wireless/bluetooth/nimble/include/logcfg/logcfg.h @@ -27,7 +27,7 @@ * Included Files ****************************************************************************/ -#include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/wireless/gs2200m/gs2200m_main.c b/wireless/gs2200m/gs2200m_main.c index f58cf882c..39749761c 100644 --- a/wireless/gs2200m/gs2200m_main.c +++ b/wireless/gs2200m/gs2200m_main.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/wireless/ieee802154/i8shark/i8shark_main.c b/wireless/ieee802154/i8shark/i8shark_main.c index 8d7af6f7f..c213045dc 100644 --- a/wireless/ieee802154/i8shark/i8shark_main.c +++ b/wireless/ieee802154/i8shark/i8shark_main.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include diff --git a/wireless/wapi/src/driver_wext.c b/wireless/wapi/src/driver_wext.c index 23b158328..f7dc2906e 100644 --- a/wireless/wapi/src/driver_wext.c +++ b/wireless/wapi/src/driver_wext.c @@ -59,7 +59,7 @@ #include #include -#include +#include #include "wireless/wapi.h" diff --git a/wireless/wapi/src/util.h b/wireless/wapi/src/util.h index 4639d3159..a2a0e2e78 100644 --- a/wireless/wapi/src/util.h +++ b/wireless/wapi/src/util.h @@ -39,7 +39,7 @@ ****************************************************************************/ #include -#include +#include #include /**************************************************************************** From 96a003072d596d2e1b81ff3fd944692877e5bae3 Mon Sep 17 00:00:00 2001 From: Piyush Patle Date: Sat, 11 Apr 2026 03:50:44 +0530 Subject: [PATCH 288/568] include/debug.h: fix checkpatch fallout in touched apps files Clean up style issues in the files touched by the include migration so the full apps-side PR passes checkpatch. Signed-off-by: Piyush Patle --- examples/nx/nx_events.c | 54 ++++--- examples/nx/nx_kbdin.c | 83 ++++++----- examples/nx/nx_main.c | 158 +++++++++++++-------- examples/nxhello/nxhello_bkgd.c | 72 +++++----- examples/nxhello/nxhello_main.c | 75 +++++----- examples/nximage/nximage_bkgd.c | 61 ++++---- examples/nximage/nximage_main.c | 79 ++++++----- examples/nxlines/nxlines_main.c | 78 +++++----- examples/nxterm/nxterm_toolbar.c | 9 +- examples/nxterm/nxterm_wndo.c | 16 ++- examples/nxtext/nxtext_bkgd.c | 33 +++-- examples/nxtext/nxtext_main.c | 86 ++++++----- examples/nxtext/nxtext_putc.c | 86 +++++------ examples/pwfb/pwfb_main.c | 59 ++++---- examples/pwlines/pwlines_main.c | 65 +++++---- examples/qencoder/qe_main.c | 19 ++- fsutils/flash_eraseall/flash_eraseall.c | 5 +- graphics/tiff/tiff_addstrip.c | 25 +++- graphics/tiff/tiff_initialize.c | 180 +++++++++++++++++------- graphics/tiff/tiff_utils.c | 37 +++-- system/nxcamera/nxcamera.c | 120 ++++++++-------- 21 files changed, 820 insertions(+), 580 deletions(-) diff --git a/examples/nx/nx_events.c b/examples/nx/nx_events.c index 4e5616641..065c4e3cf 100644 --- a/examples/nx/nx_events.c +++ b/examples/nx/nx_events.c @@ -52,25 +52,30 @@ static void nxeg_redraw(NXEGWINDOW hwnd, FAR const struct nxgl_rect_s *rect, bool morem, FAR void *arg); -static void nxeg_position(NXEGWINDOW hwnd, FAR const struct nxgl_size_s *size, +static void nxeg_position(NXEGWINDOW hwnd, + FAR const struct nxgl_size_s *size, FAR const struct nxgl_point_s *pos, FAR const struct nxgl_rect_s *bounds, FAR void *arg); #ifdef CONFIG_NX_XYINPUT -static void nxeg_mousein(NXEGWINDOW hwnd, FAR const struct nxgl_point_s *pos, +static void nxeg_mousein(NXEGWINDOW hwnd, + FAR const struct nxgl_point_s *pos, uint8_t buttons, FAR void *arg); #endif #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS -static void nxeg_tbredraw(NXEGWINDOW hwnd, FAR const struct nxgl_rect_s *rect, +static void nxeg_tbredraw(NXEGWINDOW hwnd, + FAR const struct nxgl_rect_s *rect, bool morem, FAR void *arg); -static void nxeg_tbposition(NXEGWINDOW hwnd, FAR const struct nxgl_size_s *size, +static void nxeg_tbposition(NXEGWINDOW hwnd, + FAR const struct nxgl_size_s *size, FAR const struct nxgl_point_s *pos, FAR const struct nxgl_rect_s *bounds, FAR void *arg); #ifdef CONFIG_NX_XYINPUT -static void nxeg_tbmousein(NXEGWINDOW hwnd, FAR const struct nxgl_point_s *pos, - uint8_t buttons, FAR void *arg); +static void nxeg_tbmousein(NXEGWINDOW hwnd, + FAR const struct nxgl_point_s *pos, + uint8_t buttons, FAR void *arg); #endif #endif @@ -137,6 +142,7 @@ static inline void nxeg_fillwindow(NXEGWINDOW hwnd, printf("nxeg_fillwindow: nxtk_fillwindow failed: %d\n", errno); } #endif + #ifdef CONFIG_NX_KBD nxeg_filltext(hwnd, rect, st); #endif @@ -148,8 +154,8 @@ static inline void nxeg_fillwindow(NXEGWINDOW hwnd, #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS static inline void nxeg_filltoolbar(NXTKWINDOW htb, - FAR const struct nxgl_rect_s *rect, - nxgl_mxpixel_t color[CONFIG_NX_NPLANES]) + FAR const struct nxgl_rect_s *rect, + nxgl_mxpixel_t color[CONFIG_NX_NPLANES]) { int ret; @@ -181,7 +187,8 @@ static void nxeg_redraw(NXEGWINDOW hwnd, FAR const struct nxgl_rect_s *rect, * Name: nxeg_position ****************************************************************************/ -static void nxeg_position(NXEGWINDOW hwnd, FAR const struct nxgl_size_s *size, +static void nxeg_position(NXEGWINDOW hwnd, + FAR const struct nxgl_size_s *size, FAR const struct nxgl_point_s *pos, FAR const struct nxgl_rect_s *bounds, FAR void *arg) @@ -190,7 +197,8 @@ static void nxeg_position(NXEGWINDOW hwnd, FAR const struct nxgl_size_s *size, /* Report the position */ - printf("nxeg_position%d: hwnd=%p size=(%d,%d) pos=(%d,%d) bounds={(%d,%d),(%d,%d)}\n", + printf("nxeg_position%d: hwnd=%p size=(%d,%d) pos=(%d,%d) " + "bounds={(%d,%d),(%d,%d)}\n", st->wnum, hwnd, size->w, size->h, pos->x, pos->y, bounds->pt1.x, bounds->pt1.y, bounds->pt2.x, bounds->pt2.y); @@ -198,7 +206,9 @@ static void nxeg_position(NXEGWINDOW hwnd, FAR const struct nxgl_size_s *size, if (!b_haveresolution) { - /* Save the window limits (these should be the same for all places and all windows */ + /* Save the window limits (these should be the same for all places + * and all windows. + */ g_xres = bounds->pt2.x; g_yres = bounds->pt2.y; @@ -228,7 +238,8 @@ static void nxeg_mousein(NXEGWINDOW hwnd, FAR const struct nxgl_point_s *pos, ****************************************************************************/ #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS -static void nxeg_tbredraw(NXEGWINDOW hwnd, FAR const struct nxgl_rect_s *rect, +static void nxeg_tbredraw(NXEGWINDOW hwnd, + FAR const struct nxgl_rect_s *rect, bool more, FAR void *arg) { FAR struct nxeg_state_s *st = (FAR struct nxeg_state_s *)arg; @@ -245,16 +256,18 @@ static void nxeg_tbredraw(NXEGWINDOW hwnd, FAR const struct nxgl_rect_s *rect, ****************************************************************************/ #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS -static void nxeg_tbposition(NXEGWINDOW hwnd, FAR const struct nxgl_size_s *size, - FAR const struct nxgl_point_s *pos, - FAR const struct nxgl_rect_s *bounds, - FAR void *arg) +static void nxeg_tbposition(NXEGWINDOW hwnd, + FAR const struct nxgl_size_s *size, + FAR const struct nxgl_point_s *pos, + FAR const struct nxgl_rect_s *bounds, + FAR void *arg) { FAR struct nxeg_state_s *st = (FAR struct nxeg_state_s *)arg; /* Report the position */ - printf("nxeg_ptbosition%d: hwnd=%p size=(%d,%d) pos=(%d,%d) bounds={(%d,%d),(%d,%d)}\n", + printf("nxeg_ptbosition%d: hwnd=%p size=(%d,%d) pos=(%d,%d) " + "bounds={(%d,%d),(%d,%d)}\n", st->wnum, hwnd, size->w, size->h, pos->x, pos->y, bounds->pt1.x, bounds->pt1.y, bounds->pt2.x, bounds->pt2.y); } @@ -266,8 +279,9 @@ static void nxeg_tbposition(NXEGWINDOW hwnd, FAR const struct nxgl_size_s *size, #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS #ifdef CONFIG_NX_XYINPUT -static void nxeg_tbmousein(NXEGWINDOW hwnd, FAR const struct nxgl_point_s *pos, - uint8_t buttons, FAR void *arg) +static void nxeg_tbmousein(NXEGWINDOW hwnd, + FAR const struct nxgl_point_s *pos, + uint8_t buttons, FAR void *arg) { FAR struct nxeg_state_s *st = (FAR struct nxeg_state_s *)arg; @@ -291,7 +305,7 @@ FAR void *nx_listenerthread(FAR void *arg) /* Process events forever */ - for (;;) + for (; ; ) { /* Handle the next event. If we were configured blocking, then * we will stay right here until the next event is received. Since diff --git a/examples/nx/nx_kbdin.c b/examples/nx/nx_kbdin.c index cdab7fe20..51f0e7efd 100644 --- a/examples/nx/nx_kbdin.c +++ b/examples/nx/nx_kbdin.c @@ -109,7 +109,8 @@ static void nxeg_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, if (!nxgl_nullrect(&intersection)) { #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS - ret = nxtk_bitmapwindow((NXTKWINDOW)hwnd, &intersection, (FAR const void **)&src, + ret = nxtk_bitmapwindow((NXTKWINDOW)hwnd, &intersection, + (FAR const void **)&src, &bm->bounds.pt1, (unsigned int)bm->glyph->stride); if (ret < 0) @@ -165,7 +166,7 @@ nxeg_renderglyph(FAR struct nxeg_state_s *st, /* Allocate memory to hold the glyph with its offsets */ glyph->stride = (glyph->width * CONFIG_EXAMPLES_NX_BPP + 7) / 8; - bmsize = glyph->stride * glyph->height; + bmsize = glyph->stride * glyph->height; glyph->bitmap = (FAR uint8_t *)malloc(bmsize); if (glyph->bitmap) @@ -178,13 +179,13 @@ nxeg_renderglyph(FAR struct nxeg_state_s *st, /* Pack 1-bit pixels into a 2-bits */ pixel &= 0x01; - pixel = (pixel) << 1 |pixel; + pixel = (pixel) << 1 | pixel; # endif # if CONFIG_EXAMPLES_NX_BPP < 4 /* Pack 2-bit pixels into a nibble */ pixel &= 0x03; - pixel = (pixel) << 2 |pixel; + pixel = (pixel) << 2 | pixel; # endif /* Pack 4-bit nibbles into a byte */ @@ -222,7 +223,7 @@ nxeg_renderglyph(FAR struct nxeg_state_s *st, /* Then render the glyph into the allocated memory */ - ret = RENDERER((FAR nxgl_mxpixel_t*)glyph->bitmap, + ret = RENDERER((FAR nxgl_mxpixel_t *)glyph->bitmap, glyph->height, glyph->width, glyph->stride, bm, CONFIG_EXAMPLES_NX_FONTCOLOR); if (ret < 0) @@ -236,9 +237,9 @@ nxeg_renderglyph(FAR struct nxeg_state_s *st, } else { - /* Make it permanent */ + /* Make it permanent */ - st->nglyphs++; + st->nglyphs++; } } } @@ -269,6 +270,7 @@ nxeg_addspace(FAR struct nxeg_state_s *st, uint8_t ch) st->nglyphs++; } + return glyph; } @@ -283,13 +285,14 @@ nxeg_findglyph(FAR struct nxeg_state_s *st, uint8_t ch) /* First, try to find the glyph in the cache of pre-rendered glyphs */ - for (i = 0; i < st->nglyphs; i++) + for (i = 0; i < st->nglyphs; i++) { if (st->glyph[i].code == ch) { return &st->glyph[i]; } } + return NULL; } @@ -313,21 +316,22 @@ nxeg_getglyph(FAR struct nxeg_state_s *st, uint8_t ch) bm = nxf_getbitmap(g_fonthandle, ch); if (!bm) { - /* No, there is no glyph for this code. Use space */ + /* No, there is no glyph for this code. Use space. */ glyph = nxeg_findglyph(st, ' '); if (!glyph) { - /* There isn't fake glyph for ' ' yet... create one */ + /* There isn't a fake glyph for ' ' yet... create one */ glyph = nxeg_addspace(st, ' '); } } else { - glyph = nxeg_renderglyph(st, bm, ch); + glyph = nxeg_renderglyph(st, bm, ch); } } + return glyph; } @@ -346,41 +350,42 @@ nxeg_addchar(FAR struct nxeg_state_s *st, uint8_t ch) if (st->nchars < NXTK_MAXKBDCHARS) { - /* Yes, setup the bitmap */ + /* Yes, setup the bitmap */ - bm = &st->bm[st->nchars]; + bm = &st->bm[st->nchars]; - /* Find the matching glyph */ + /* Find the matching glyph */ - bm->glyph = nxeg_getglyph(st, ch); - if (!bm->glyph) - { - return NULL; - } + bm->glyph = nxeg_getglyph(st, ch); + if (!bm->glyph) + { + return NULL; + } - /* Set up the bounds for the bitmap */ + /* Set up the bounds for the bitmap */ - if (st->nchars <= 0) - { - /* The first character is one space from the left */ + if (st->nchars <= 0) + { + /* The first character is one space from the left */ - leftx = st->spwidth; - } - else - { - /* Otherwise, it is to the left of the preceding char */ + leftx = st->spwidth; + } + else + { + /* Otherwise, it is to the left of the preceding char */ - bmleft = &st->bm[st->nchars-1]; - leftx = bmleft->bounds.pt2.x + 1; - } + bmleft = &st->bm[st->nchars - 1]; + leftx = bmleft->bounds.pt2.x + 1; + } - bm->bounds.pt1.x = leftx; - bm->bounds.pt1.y = 2; - bm->bounds.pt2.x = leftx + bm->glyph->width - 1; - bm->bounds.pt2.y = 2 + bm->glyph->height - 1; + bm->bounds.pt1.x = leftx; + bm->bounds.pt1.y = 2; + bm->bounds.pt2.x = leftx + bm->glyph->width - 1; + bm->bounds.pt2.y = 2 + bm->glyph->height - 1; - st->nchars++; + st->nchars++; } + return bm; } @@ -424,10 +429,12 @@ void nxeg_kbdin(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, ****************************************************************************/ #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS -void nxeg_tbkbdin(NXWINDOW hwnd, uint8_t nch, const uint8_t *ch, FAR void *arg) +void nxeg_tbkbdin(NXWINDOW hwnd, uint8_t nch, const uint8_t *ch, + FAR void *arg) { FAR struct nxeg_state_s *st = (FAR struct nxeg_state_s *)arg; - printf("nxeg_tbkbdin: ERROR -- toolbar should not received keyboard input\n"); + printf("nxeg_tbkbdin: ERROR -- toolbar should not received keyboard " + "input\n"); printf("nxeg_tbkbdin%d: hwnd=%p nch=%d\n", st->wnum, hwnd, nch); } #endif diff --git a/examples/nx/nx_main.c b/examples/nx/nx_main.c index 942d59870..9bdeded9c 100644 --- a/examples/nx/nx_main.c +++ b/examples/nx/nx_main.c @@ -54,6 +54,7 @@ ****************************************************************************/ /* Configuration ************************************************************/ + /* If not specified, assume that the hardware supports one video plane */ #ifndef CONFIG_EXAMPLES_NX_VPLANE @@ -98,7 +99,10 @@ nxgl_coord_t g_yres; bool b_haveresolution = false; bool g_connected = false; -sem_t g_semevent = {0}; +sem_t g_semevent = +{ + 0 +}; /* Colors used to fill window 1 & 2 */ @@ -181,14 +185,16 @@ static void nxeg_freestate(FAR struct nxeg_state_s *st) { for (i = 0; i < st->nglyphs; i++) { - if (st->glyph[i].bitmap) - { - free(st->glyph[i].bitmap); - } - st->glyph[i].bitmap = NULL; + if (st->glyph[i].bitmap) + { + free(st->glyph[i].bitmap); + } + + st->glyph[i].bitmap = NULL; } + st->nchars = 0; - } + } #endif } #endif @@ -199,7 +205,7 @@ static void nxeg_freestate(FAR struct nxeg_state_s *st) #ifdef CONFIG_EXAMPLES_NX_RAWWINDOWS static inline NXEGWINDOW nxeg_openwindow(FAR const struct nx_callback_s *cb, - FAR struct nxeg_state_s *state) + FAR struct nxeg_state_s *state) { NXEGWINDOW hwnd; @@ -209,8 +215,10 @@ static inline NXEGWINDOW nxeg_openwindow(FAR const struct nx_callback_s *cb, printf("nxeg_openwindow: nx_openwindow failed: %d\n", errno); g_exitcode = NXEXIT_NXOPENWINDOW; } + return hwnd; } + #else static inline NXEGWINDOW nxeg_openwindow(FAR const struct nx_callback_s *cb, FAR struct nxeg_state_s *state) @@ -223,8 +231,10 @@ static inline NXEGWINDOW nxeg_openwindow(FAR const struct nx_callback_s *cb, printf("nxeg_openwindow: nxtk_openwindow failed: %d\n", errno); g_exitcode = NXEXIT_NXOPENWINDOW; } + return hwnd; } + #endif /**************************************************************************** @@ -232,7 +242,8 @@ static inline NXEGWINDOW nxeg_openwindow(FAR const struct nx_callback_s *cb, ****************************************************************************/ #ifdef CONFIG_EXAMPLES_NX_RAWWINDOWS -static inline int nxeg_closewindow(NXEGWINDOW hwnd, FAR struct nxeg_state_s *state) +static inline int nxeg_closewindow(NXEGWINDOW hwnd, + FAR struct nxeg_state_s *state) { int ret = nx_closewindow(hwnd); if (ret < 0) @@ -240,10 +251,13 @@ static inline int nxeg_closewindow(NXEGWINDOW hwnd, FAR struct nxeg_state_s *sta printf("nxeg_closewindow: nx_closewindow failed: %d\n", errno); g_exitcode = NXEXIT_NXCLOSEWINDOW; } + return ret; } + #else -static inline int nxeg_closewindow(NXEGWINDOW hwnd, FAR struct nxeg_state_s *state) +static inline int nxeg_closewindow(NXEGWINDOW hwnd, + FAR struct nxeg_state_s *state) { int ret = nxtk_closewindow(hwnd); if (ret < 0) @@ -251,9 +265,11 @@ static inline int nxeg_closewindow(NXEGWINDOW hwnd, FAR struct nxeg_state_s *sta printf("nxeg_closewindow: nxtk_closewindow failed: %d\n", errno); g_exitcode = NXEXIT_NXCLOSEWINDOW; } + nxeg_freestate(state); return ret; } + #endif /**************************************************************************** @@ -261,7 +277,8 @@ static inline int nxeg_closewindow(NXEGWINDOW hwnd, FAR struct nxeg_state_s *sta ****************************************************************************/ #ifdef CONFIG_EXAMPLES_NX_RAWWINDOWS -static inline int nxeg_setsize(NXEGWINDOW hwnd, FAR struct nxgl_size_s *size) +static inline int nxeg_setsize(NXEGWINDOW hwnd, + FAR struct nxgl_size_s *size) { int ret = nx_setsize(hwnd, size); if (ret < 0) @@ -269,10 +286,13 @@ static inline int nxeg_setsize(NXEGWINDOW hwnd, FAR struct nxgl_size_s *size) printf("nxeg_setsize: nx_setsize failed: %d\n", errno); g_exitcode = NXEXIT_NXSETSIZE; } + return ret; } + #else -static inline int nxeg_setsize(NXEGWINDOW hwnd, FAR struct nxgl_size_s *size) +static inline int nxeg_setsize(NXEGWINDOW hwnd, + FAR struct nxgl_size_s *size) { int ret = nxtk_setsize(hwnd, size); if (ret < 0) @@ -280,8 +300,10 @@ static inline int nxeg_setsize(NXEGWINDOW hwnd, FAR struct nxgl_size_s *size) printf("nxeg_setsize: nxtk_setsize failed: %d\n", errno); g_exitcode = NXEXIT_NXSETSIZE; } + return ret; } + #endif /**************************************************************************** @@ -289,7 +311,8 @@ static inline int nxeg_setsize(NXEGWINDOW hwnd, FAR struct nxgl_size_s *size) ****************************************************************************/ #ifdef CONFIG_EXAMPLES_NX_RAWWINDOWS -static inline int nxeg_setposition(NXEGWINDOW hwnd, FAR struct nxgl_point_s *pos) +static inline int nxeg_setposition(NXEGWINDOW hwnd, + FAR struct nxgl_point_s *pos) { int ret = nx_setposition(hwnd, pos); if (ret < 0) @@ -297,10 +320,13 @@ static inline int nxeg_setposition(NXEGWINDOW hwnd, FAR struct nxgl_point_s *pos printf("nxeg_setposition: nx_setposition failed: %d\n", errno); g_exitcode = NXEXIT_NXSETPOSITION; } + return ret; } + #else -static inline int nxeg_setposition(NXEGWINDOW hwnd, FAR struct nxgl_point_s *pos) +static inline int nxeg_setposition(NXEGWINDOW hwnd, + FAR struct nxgl_point_s *pos) { int ret = nxtk_setposition(hwnd, pos); if (ret < 0) @@ -308,8 +334,10 @@ static inline int nxeg_setposition(NXEGWINDOW hwnd, FAR struct nxgl_point_s *pos printf("nxeg_setposition: nxtk_setposition failed: %d\n", errno); g_exitcode = NXEXIT_NXSETPOSITION; } + return ret; } + #endif /**************************************************************************** @@ -328,8 +356,10 @@ static inline int nxeq_opentoolbar(NXEGWINDOW hwnd, nxgl_coord_t height, printf("nxeq_opentoolbar: nxtk_opentoolbar failed: %d\n", errno); g_exitcode = NXEXIT_NXOPENTOOLBAR; } + return ret; } + #endif /**************************************************************************** @@ -345,8 +375,10 @@ static inline int nxeg_lower(NXEGWINDOW hwnd) printf("nxeg_lower: nx_lower failed: %d\n", errno); g_exitcode = NXEXIT_NXLOWER; } + return ret; } + #else static inline int nxeg_lower(NXEGWINDOW hwnd) { @@ -356,8 +388,10 @@ static inline int nxeg_lower(NXEGWINDOW hwnd) printf("nxeg_lower: nxtk_lower failed: %d\n", errno); g_exitcode = NXEXIT_NXLOWER; } + return ret; } + #endif /**************************************************************************** @@ -373,8 +407,10 @@ static inline int nxeg_raise(NXEGWINDOW hwnd) printf("nxeg_raise: nx_raise failed: %d\n", errno); g_exitcode = NXEXIT_NXRAISE; } + return ret; } + #else static inline int nxeg_raise(NXEGWINDOW hwnd) { @@ -384,8 +420,10 @@ static inline int nxeg_raise(NXEGWINDOW hwnd) printf("nxeg_raise: nxtk_raise failed: %d\n", errno); g_exitcode = NXEXIT_NXRAISE; } + return ret; } + #endif /**************************************************************************** @@ -416,7 +454,7 @@ static int nxeg_initialize(void) ret = sched_setparam(0, ¶m); if (ret < 0) { - printf("nxeg_initialize: sched_setparam failed: %d\n" , ret); + printf("nxeg_initialize: sched_setparam failed: %d\n", ret); g_exitcode = NXEXIT_SCHEDSETPARAM; return ERROR; } @@ -426,7 +464,8 @@ static int nxeg_initialize(void) ret = boardctl(BOARDIOC_NX_START, 0); if (ret < 0) { - printf("nxeg_initialize: Failed to start the NX server: %d\n", errno); + printf("nxeg_initialize: Failed to start the NX server: %d\n", + errno); g_exitcode = NXEXIT_TASKCREATE; return ERROR; } @@ -436,54 +475,54 @@ static int nxeg_initialize(void) g_hnx = nx_connect(); if (g_hnx) { - pthread_attr_t attr; + pthread_attr_t attr; #ifdef CONFIG_VNCSERVER /* Setup the VNC server to support keyboard/mouse inputs */ - struct boardioc_vncstart_s vnc = - { - 0, g_hnx - }; + struct boardioc_vncstart_s vnc = + { + 0, g_hnx + }; - ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); - if (ret < 0) - { - printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); - nx_disconnect(g_hnx); - g_exitcode = NXEXIT_FBINITIALIZE; - return ERROR; - } + ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); + if (ret < 0) + { + printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); + nx_disconnect(g_hnx); + g_exitcode = NXEXIT_FBINITIALIZE; + return ERROR; + } #endif - /* Start a separate thread to listen for server events. This is probably - * the least efficient way to do this, but it makes this example flow more - * smoothly. - */ + /* Start a separate thread to listen for server events. This is + * probably the least efficient way to do this, but it makes this + * example flow more smoothly. + */ - pthread_attr_init(&attr); - param.sched_priority = CONFIG_EXAMPLES_NX_LISTENERPRIO; - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_NX_STACKSIZE); + pthread_attr_init(&attr); + param.sched_priority = CONFIG_EXAMPLES_NX_LISTENERPRIO; + pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_NX_STACKSIZE); - ret = pthread_create(&thread, &attr, nx_listenerthread, NULL); - if (ret != 0) - { - printf("nxeg_initialize: pthread_create failed: %d\n", ret); - g_exitcode = NXEXIT_PTHREADCREATE; - return ERROR; - } + ret = pthread_create(&thread, &attr, nx_listenerthread, NULL); + if (ret != 0) + { + printf("nxeg_initialize: pthread_create failed: %d\n", ret); + g_exitcode = NXEXIT_PTHREADCREATE; + return ERROR; + } - /* Don't return until we are connected to the server */ + /* Don't return until we are connected to the server */ - while (!g_connected) - { - /* Wait for the listener thread to wake us up when we really - * are connected. - */ + while (!g_connected) + { + /* Wait for the listener thread to wake us up when we really + * are connected. + */ - sem_wait(&g_semevent); - } + sem_wait(&g_semevent); + } } else { @@ -562,6 +601,7 @@ int main(int argc, FAR char *argv[]) { sem_wait(&g_semevent); } + printf("nx_main: Screen resolution (%d,%d)\n", g_xres, g_yres); /* Set the size of the window 1 */ @@ -576,9 +616,8 @@ int main(int argc, FAR char *argv[]) goto errout_with_hwnd1; } - /* Sleep a bit -- both so that we can see the result of the above operations - * but also, in the multi-user case, so that the server can get a chance to - * actually do them! + /* Sleep a bit. This lets us see the result of the above operations and, + * in the multi-user case, gives the server a chance to actually do them. */ printf("nx_main: Sleeping\n\n"); @@ -605,7 +644,8 @@ int main(int argc, FAR char *argv[]) #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS printf("nx_main: Add toolbar to window #1\n"); - ret = nxeq_opentoolbar(hwnd1, CONFIG_EXAMPLES_NX_TOOLBAR_HEIGHT, &g_tbcb, &g_wstate[0]); + ret = nxeq_opentoolbar(hwnd1, CONFIG_EXAMPLES_NX_TOOLBAR_HEIGHT, + &g_tbcb, &g_wstate[0]); if (ret < 0) { goto errout_with_hwnd1; @@ -633,7 +673,7 @@ int main(int argc, FAR char *argv[]) printf("nx_main: Sleeping\n\n"); sleep(1); - /* Set the size of the window 2 == size of window 1*/ + /* Set the size of window 2 equal to the size of window 1 */ printf("nx_main: Set hwnd2 size to (%d,%d)\n", size.w, size.h); ret = nxeg_setsize(hwnd2, &size); @@ -666,7 +706,8 @@ int main(int argc, FAR char *argv[]) #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS printf("nx_main: Add toolbar to window #2\n"); - ret = nxeq_opentoolbar(hwnd2, CONFIG_EXAMPLES_NX_TOOLBAR_HEIGHT, &g_tbcb, &g_wstate[1]); + ret = nxeq_opentoolbar(hwnd2, CONFIG_EXAMPLES_NX_TOOLBAR_HEIGHT, + &g_tbcb, &g_wstate[1]); if (ret < 0) { goto errout_with_hwnd2; @@ -770,6 +811,7 @@ errout_with_hwnd1: nxeg_closewindow(hwnd1, &g_wstate[0]); errout_with_nx: + /* Disconnect from the server */ printf("nx_main: Disconnect from the server\n"); diff --git a/examples/nxhello/nxhello_bkgd.c b/examples/nxhello/nxhello_bkgd.c index 323b4870d..5e0a5b80e 100644 --- a/examples/nxhello/nxhello_bkgd.c +++ b/examples/nxhello/nxhello_bkgd.c @@ -76,19 +76,21 @@ ****************************************************************************/ static void nxhello_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, - bool morem, FAR void *arg); -static void nxhello_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, - FAR const struct nxgl_point_s *pos, - FAR const struct nxgl_rect_s *bounds, - FAR void *arg); + bool morem, FAR void *arg); +static void nxhello_position(NXWINDOW hwnd, + FAR const struct nxgl_size_s *size, + FAR const struct nxgl_point_s *pos, + FAR const struct nxgl_rect_s *bounds, + FAR void *arg); #ifdef CONFIG_NX_XYINPUT -static void nxhello_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, - uint8_t buttons, FAR void *arg); +static void nxhello_mousein(NXWINDOW hwnd, + FAR const struct nxgl_point_s *pos, + uint8_t buttons, FAR void *arg); #endif #ifdef CONFIG_NX_KBD -static void nxhello_kbdin(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, - FAR void *arg); +static void nxhello_kbdin(NXWINDOW hwnd, uint8_t nch, + FAR const uint8_t *ch, FAR void *arg); #endif /**************************************************************************** @@ -125,7 +127,7 @@ const struct nx_callback_s g_nxhellocb = ****************************************************************************/ static void nxhello_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, - bool more, FAR void *arg) + bool more, FAR void *arg) { ginfo("hwnd=%p rect={(%d,%d),(%d,%d)} more=%s\n", hwnd, rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y, @@ -136,10 +138,11 @@ static void nxhello_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, * Name: nxhello_position ****************************************************************************/ -static void nxhello_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, - FAR const struct nxgl_point_s *pos, - FAR const struct nxgl_rect_s *bounds, - FAR void *arg) +static void nxhello_position(NXWINDOW hwnd, + FAR const struct nxgl_size_s *size, + FAR const struct nxgl_point_s *pos, + FAR const struct nxgl_rect_s *bounds, + FAR void *arg) { /* Report the position */ @@ -171,8 +174,9 @@ static void nxhello_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, ****************************************************************************/ #ifdef CONFIG_NX_XYINPUT -static void nxhello_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, - uint8_t buttons, FAR void *arg) +static void nxhello_mousein(NXWINDOW hwnd, + FAR const struct nxgl_point_s *pos, + uint8_t buttons, FAR void *arg) { printf("nxhello_mousein: hwnd=%p pos=(%d,%d) button=%02x\n", hwnd, pos->x, pos->y, buttons); @@ -184,16 +188,16 @@ static void nxhello_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, ****************************************************************************/ #ifdef CONFIG_NX_KBD -static void nxhello_kbdin(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, - FAR void *arg) +static void nxhello_kbdin(NXWINDOW hwnd, uint8_t nch, + FAR const uint8_t *ch, FAR void *arg) { ginfo("hwnd=%p nch=%d\n", hwnd, nch); - /* In this example, there is no keyboard so a keyboard event is not - * expected. - */ + /* In this example, there is no keyboard so a keyboard event is not + * expected. + */ - printf("nxhello_kbdin: Unexpected keyboard callback\n"); + printf("nxhello_kbdin: Unexpected keyboard callback\n"); } #endif @@ -212,7 +216,7 @@ static void nxhello_center(FAR struct nxgl_point_s *pos, * hello world message. */ - for (ptr = (uint8_t*)g_hello, width = 0; *ptr; ptr++) + for (ptr = (uint8_t *)g_hello, width = 0; *ptr; ptr++) { /* Get the font bitmap for this character */ @@ -225,7 +229,7 @@ static void nxhello_center(FAR struct nxgl_point_s *pos, } else { - /* Use the width of a space */ + /* Use the width of a space */ width += fontset->spwidth; } @@ -266,7 +270,7 @@ static void nxhello_initglyph(FAR uint8_t *glyph, uint8_t height, /* Pack 1-bit pixels into a 2-bits */ pixel &= 0x01; - pixel = (pixel) << 1 |pixel; + pixel = (pixel) << 1 | pixel; # endif # if CONFIG_EXAMPLES_NXHELLO_BPP < 4 @@ -274,7 +278,7 @@ static void nxhello_initglyph(FAR uint8_t *glyph, uint8_t height, /* Pack 2-bit pixels into a nibble */ pixel &= 0x03; - pixel = (pixel) << 2 |pixel; + pixel = (pixel) << 2 | pixel; # endif @@ -348,10 +352,10 @@ void nxhello_hello(NXWINDOW hwnd) mxstride = (fontset->mxwidth * CONFIG_EXAMPLES_NXHELLO_BPP + 7) >> 3; glyphsize = (unsigned int)fontset->mxheight * mxstride; - glyph = (FAR uint8_t*)malloc(glyphsize); + glyph = (FAR uint8_t *)malloc(glyphsize); - /* NOTE: no check for failure to allocate the memory. In a real application - * you would need to handle that event. + /* NOTE: no check for failure to allocate the memory. In a real + * application you would need to handle that event. */ /* Get a position so the "Hello, World!" string will be centered on the @@ -389,7 +393,7 @@ void nxhello_hello(NXWINDOW hwnd) #if CONFIG_NX_NPLANES > 1 # warning "More logic is needed for the case where CONFIG_NX_PLANES > 1" #endif - RENDERER((FAR nxgl_mxpixel_t*)glyph, fheight, fwidth, + RENDERER((FAR nxgl_mxpixel_t *)glyph, fheight, fwidth, fstride, fbm, CONFIG_EXAMPLES_NXHELLO_FONTCOLOR); /* Describe the destination of the font with a rectangle */ @@ -411,15 +415,15 @@ void nxhello_hello(NXWINDOW hwnd) printf("nxhello_write: nx_bitmapwindow failed: %d\n", errno); } - /* Skip to the right the width of the font */ + /* Skip to the right the width of the font */ pos.x += fwidth; } else { - /* No bitmap (probably because the font is a space). Skip to the - * right the width of a space. - */ + /* No bitmap (probably because the font is a space). Skip to the + * right the width of a space. + */ pos.x += fontset->spwidth; } diff --git a/examples/nxhello/nxhello_main.c b/examples/nxhello/nxhello_main.c index 8165d9abe..d524f6f2c 100644 --- a/examples/nxhello/nxhello_main.c +++ b/examples/nxhello/nxhello_main.c @@ -95,7 +95,8 @@ static inline int nxhello_initialize(void) ret = boardctl(BOARDIOC_NX_START, 0); if (ret < 0) { - printf("nxhello_initialize: Failed to start the NX server: %d\n", errno); + printf("nxhello_initialize: Failed to start the NX server: %d\n", + errno); return ERROR; } @@ -104,52 +105,53 @@ static inline int nxhello_initialize(void) g_nxhello.hnx = nx_connect(); if (g_nxhello.hnx) { - pthread_attr_t attr; + pthread_attr_t attr; #ifdef CONFIG_VNCSERVER /* Setup the VNC server to support keyboard/mouse inputs */ - struct boardioc_vncstart_s vnc = - { - 0, g_nxhello.hnx - }; + struct boardioc_vncstart_s vnc = + { + 0, g_nxhello.hnx + }; - ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); - if (ret < 0) - { - printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); - nx_disconnect(g_nxhello.hnx); - return ERROR; - } + ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); + if (ret < 0) + { + printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); + nx_disconnect(g_nxhello.hnx); + return ERROR; + } #endif - /* Start a separate thread to listen for server events. This is probably - * the least efficient way to do this, but it makes this example flow more - * smoothly. - */ + /* Start a separate thread to listen for server events. This is + * probably the least efficient way to do this, but it makes this + * example flow more smoothly. + */ - pthread_attr_init(&attr); - param.sched_priority = CONFIG_EXAMPLES_NXHELLO_LISTENERPRIO; - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_NXHELLO_LISTENER_STACKSIZE); + pthread_attr_init(&attr); + param.sched_priority = CONFIG_EXAMPLES_NXHELLO_LISTENERPRIO; + pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setstacksize(&attr, + CONFIG_EXAMPLES_NXHELLO_LISTENER_STACKSIZE); - ret = pthread_create(&thread, &attr, nxhello_listener, NULL); - if (ret != 0) - { - printf("nxhello_initialize: pthread_create failed: %d\n", ret); - return ERROR; - } + ret = pthread_create(&thread, &attr, nxhello_listener, NULL); + if (ret != 0) + { + printf("nxhello_initialize: pthread_create failed: %d\n", ret); + return ERROR; + } - /* Don't return until we are connected to the server */ + /* Don't return until we are connected to the server */ - while (!g_nxhello.connected) - { - /* Wait for the listener thread to wake us up when we really - * are connected. - */ + while (!g_nxhello.connected) + { + /* Wait for the listener thread to wake us up when we really + * are connected. + */ - sem_wait(&g_nxhello.eventsem); - } + sem_wait(&g_nxhello.eventsem); + } } else { @@ -225,7 +227,8 @@ int main(int argc, FAR char *argv[]) sem_wait(&g_nxhello.eventsem); } - printf("nxhello_main: Screen resolution (%d,%d)\n", g_nxhello.xres, g_nxhello.yres); + printf("nxhello_main: Screen resolution (%d,%d)\n", + g_nxhello.xres, g_nxhello.yres); /* Now, say hello and exit, sleeping a little before each. */ diff --git a/examples/nximage/nximage_bkgd.c b/examples/nximage/nximage_bkgd.c index 8a86f0498..8e3a2f651 100644 --- a/examples/nximage/nximage_bkgd.c +++ b/examples/nximage/nximage_bkgd.c @@ -109,19 +109,21 @@ struct nximage_run_s ****************************************************************************/ static void nximage_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, - bool more, FAR void *arg); -static void nximage_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, - FAR const struct nxgl_point_s *pos, - FAR const struct nxgl_rect_s *bounds, - FAR void *arg); + bool more, FAR void *arg); +static void nximage_position(NXWINDOW hwnd, + FAR const struct nxgl_size_s *size, + FAR const struct nxgl_point_s *pos, + FAR const struct nxgl_rect_s *bounds, + FAR void *arg); #ifdef CONFIG_NX_XYINPUT -static void nximage_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, - uint8_t buttons, FAR void *arg); +static void nximage_mousein(NXWINDOW hwnd, + FAR const struct nxgl_point_s *pos, + uint8_t buttons, FAR void *arg); #endif #ifdef CONFIG_NX_KBD -static void nximage_kbdin(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, - FAR void *arg); +static void nximage_kbdin(NXWINDOW hwnd, uint8_t nch, + FAR const uint8_t *ch, FAR void *arg); #endif /**************************************************************************** @@ -164,7 +166,7 @@ const struct nx_callback_s g_nximagecb = ****************************************************************************/ static void nximage_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, - bool more, FAR void *arg) + bool more, FAR void *arg) { ginfo("hwnd=%p rect={(%d,%d),(%d,%d)} more=%s\n", hwnd, rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y, @@ -179,10 +181,11 @@ static void nximage_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, * ****************************************************************************/ -static void nximage_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, - FAR const struct nxgl_point_s *pos, - FAR const struct nxgl_rect_s *bounds, - FAR void *arg) +static void nximage_position(NXWINDOW hwnd, + FAR const struct nxgl_size_s *size, + FAR const struct nxgl_point_s *pos, + FAR const struct nxgl_rect_s *bounds, + FAR void *arg) { /* Report the position */ @@ -218,8 +221,9 @@ static void nximage_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, ****************************************************************************/ #ifdef CONFIG_NX_XYINPUT -static void nximage_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, - uint8_t buttons, FAR void *arg) +static void nximage_mousein(NXWINDOW hwnd, + FAR const struct nxgl_point_s *pos, + uint8_t buttons, FAR void *arg) { printf("nximage_mousein: hwnd=%p pos=(%d,%d) button=%02x\n", hwnd, pos->x, pos->y, buttons); @@ -235,16 +239,16 @@ static void nximage_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, ****************************************************************************/ #ifdef CONFIG_NX_KBD -static void nximage_kbdin(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, - FAR void *arg) +static void nximage_kbdin(NXWINDOW hwnd, uint8_t nch, + FAR const uint8_t *ch, FAR void *arg) { ginfo("hwnd=%p nch=%d\n", hwnd, nch); - /* In this example, there is no keyboard so a keyboard event is not - * expected. - */ + /* In this example, there is no keyboard so a keyboard event is not + * expected. + */ - printf("nximage_kbdin: Unexpected keyboard callback\n"); + printf("nximage_kbdin: Unexpected keyboard callback\n"); } #endif @@ -288,9 +292,9 @@ void nximage_image(NXWINDOW hwnd) { /* Read input row(s) */ - nximage_blitrow(g_runs[0].run, &state); + nximage_blitrow(g_runs[0].run, &state); #if NINPUT_ROWS > 1 - nximage_blitrow(g_runs[1].run, &state); + nximage_blitrow(g_runs[1].run, &state); #endif /* Output rows before averaging */ @@ -306,7 +310,8 @@ void nximage_image(NXWINDOW hwnd) #if CONFIG_NX_NPLANES > 1 # warning "More logic is needed for the case where CONFIG_NX_PLANES > 1" #endif - ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, SCALED_WIDTH*sizeof(nxgl_mxpixel_t)); + ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, + SCALED_WIDTH * sizeof(nxgl_mxpixel_t)); if (ret < 0) { printf("nximage_image: nx_bitmapwindow failed: %d\n", errno); @@ -348,7 +353,8 @@ void nximage_image(NXWINDOW hwnd) #if CONFIG_NX_NPLANES > 1 # warning "More logic is needed for the case where CONFIG_NX_PLANES > 1" #endif - ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, SCALED_WIDTH*sizeof(nxgl_mxpixel_t)); + ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, + SCALED_WIDTH * sizeof(nxgl_mxpixel_t)); if (ret < 0) { printf("nximage_image: nx_bitmapwindow failed: %d\n", errno); @@ -369,7 +375,8 @@ void nximage_image(NXWINDOW hwnd) #if CONFIG_NX_NPLANES > 1 # warning "More logic is needed for the case where CONFIG_NX_PLANES > 1" #endif - ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, SCALED_WIDTH*sizeof(nxgl_mxpixel_t)); + ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, + SCALED_WIDTH * sizeof(nxgl_mxpixel_t)); if (ret < 0) { printf("nximage_image: nx_bitmapwindow failed: %d\n", errno); diff --git a/examples/nximage/nximage_main.c b/examples/nximage/nximage_main.c index fd2beac0b..4d9648f0f 100644 --- a/examples/nximage/nximage_main.c +++ b/examples/nximage/nximage_main.c @@ -90,7 +90,7 @@ static inline int nximage_initialize(void) ret = sched_setparam(0, ¶m); if (ret < 0) { - printf("nximage_initialize: sched_setparam failed: %d\n" , ret); + printf("nximage_initialize: sched_setparam failed: %d\n", ret); return ERROR; } @@ -99,7 +99,8 @@ static inline int nximage_initialize(void) ret = boardctl(BOARDIOC_NX_START, 0); if (ret < 0) { - printf("nximage_initialize: Failed to start the NX server: %d\n", errno); + printf("nximage_initialize: Failed to start the NX server: %d\n", + errno); return ERROR; } @@ -108,52 +109,53 @@ static inline int nximage_initialize(void) g_nximage.hnx = nx_connect(); if (g_nximage.hnx) { - pthread_attr_t attr; + pthread_attr_t attr; #ifdef CONFIG_VNCSERVER /* Setup the VNC server to support keyboard/mouse inputs */ - struct boardioc_vncstart_s vnc = - { - 0, g_nximage.hnx - }; + struct boardioc_vncstart_s vnc = + { + 0, g_nximage.hnx + }; - ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); - if (ret < 0) - { - printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); - nx_disconnect(g_nximage.hnx); - return ERROR; - } + ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); + if (ret < 0) + { + printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); + nx_disconnect(g_nximage.hnx); + return ERROR; + } #endif - /* Start a separate thread to listen for server events. This is probably - * the least efficient way to do this, but it makes this example flow more - * smoothly. - */ + /* Start a separate thread to listen for server events. This is + * probably the least efficient way to do this, but it makes this + * example flow more smoothly. + */ - pthread_attr_init(&attr); - param.sched_priority = CONFIG_EXAMPLES_NXIMAGE_LISTENERPRIO; - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_NXIMAGE_LISTENER_STACKSIZE); + pthread_attr_init(&attr); + param.sched_priority = CONFIG_EXAMPLES_NXIMAGE_LISTENERPRIO; + pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setstacksize(&attr, + CONFIG_EXAMPLES_NXIMAGE_LISTENER_STACKSIZE); - ret = pthread_create(&thread, &attr, nximage_listener, NULL); - if (ret != 0) - { - printf("nximage_initialize: pthread_create failed: %d\n", ret); - return ERROR; - } + ret = pthread_create(&thread, &attr, nximage_listener, NULL); + if (ret != 0) + { + printf("nximage_initialize: pthread_create failed: %d\n", ret); + return ERROR; + } - /* Don't return until we are connected to the server */ + /* Don't return until we are connected to the server */ - while (!g_nximage.connected) - { - /* Wait for the listener thread to wake us up when we really - * are connected. - */ + while (!g_nximage.connected) + { + /* Wait for the listener thread to wake us up when we really + * are connected. + */ - sem_wait(&g_nximage.eventsem); - } + sem_wait(&g_nximage.eventsem); + } } else { @@ -194,7 +196,7 @@ int main(int argc, FAR char *argv[]) /* Set the background to the configured background color */ - color = nximage_bgcolor(); + color = nximage_bgcolor(); printf("nximage_main: Set background color=%u\n", color); ret = nx_setbgcolor(g_nximage.hnx, &color); @@ -222,7 +224,8 @@ int main(int argc, FAR char *argv[]) sem_wait(&g_nximage.eventsem); } - printf("nximage_main: Screen resolution (%d,%d)\n", g_nximage.xres, g_nximage.yres); + printf("nximage_main: Screen resolution (%d,%d)\n", + g_nximage.xres, g_nximage.yres); /* Now, put up the NuttX logo and wait a bit so that it visible. */ diff --git a/examples/nxlines/nxlines_main.c b/examples/nxlines/nxlines_main.c index 85b75177e..f13294fd0 100644 --- a/examples/nxlines/nxlines_main.c +++ b/examples/nxlines/nxlines_main.c @@ -51,6 +51,7 @@ ****************************************************************************/ /* Configuration ************************************************************/ + /* If not specified, assume that the hardware supports one video plane */ #ifndef CONFIG_EXAMPLES_NXLINES_VPLANE @@ -111,7 +112,7 @@ static inline int nxlines_initialize(void) ret = sched_setparam(0, ¶m); if (ret < 0) { - printf("nxlines_initialize: sched_setparam failed: %d\n" , ret); + printf("nxlines_initialize: sched_setparam failed: %d\n", ret); return ERROR; } @@ -120,7 +121,8 @@ static inline int nxlines_initialize(void) ret = boardctl(BOARDIOC_NX_START, 0); if (ret < 0) { - printf("nxlines_initialize: Failed to start the NX server: %d\n", errno); + printf("nxlines_initialize: Failed to start the NX server: %d\n", + errno); return ERROR; } @@ -129,52 +131,53 @@ static inline int nxlines_initialize(void) g_nxlines.hnx = nx_connect(); if (g_nxlines.hnx) { - pthread_attr_t attr; + pthread_attr_t attr; #ifdef CONFIG_VNCSERVER /* Setup the VNC server to support keyboard/mouse inputs */ - struct boardioc_vncstart_s vnc = - { - 0, g_nxlines.hnx - }; + struct boardioc_vncstart_s vnc = + { + 0, g_nxlines.hnx + }; - ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); - if (ret < 0) - { - printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); - nx_disconnect(g_nxlines.hnx); - return ERROR; - } + ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); + if (ret < 0) + { + printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); + nx_disconnect(g_nxlines.hnx); + return ERROR; + } #endif - /* Start a separate thread to listen for server events. This is probably - * the least efficient way to do this, but it makes this example flow more - * smoothly. - */ + /* Start a separate thread to listen for server events. This is + * probably the least efficient way to do this, but it makes this + * example flow more smoothly. + */ - pthread_attr_init(&attr); - param.sched_priority = CONFIG_EXAMPLES_NXLINES_LISTENERPRIO; - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_NXLINES_LISTENER_STACKSIZE); + pthread_attr_init(&attr); + param.sched_priority = CONFIG_EXAMPLES_NXLINES_LISTENERPRIO; + pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setstacksize(&attr, + CONFIG_EXAMPLES_NXLINES_LISTENER_STACKSIZE); - ret = pthread_create(&thread, &attr, nxlines_listener, NULL); - if (ret != 0) - { - printf("nxlines_initialize: pthread_create failed: %d\n", ret); - return ERROR; - } + ret = pthread_create(&thread, &attr, nxlines_listener, NULL); + if (ret != 0) + { + printf("nxlines_initialize: pthread_create failed: %d\n", ret); + return ERROR; + } - /* Don't return until we are connected to the server */ + /* Don't return until we are connected to the server */ - while (!g_nxlines.connected) - { - /* Wait for the listener thread to wake us up when we really - * are connected. - */ + while (!g_nxlines.connected) + { + /* Wait for the listener thread to wake us up when we really + * are connected. + */ - sem_wait(&g_nxlines.eventsem); - } + sem_wait(&g_nxlines.eventsem); + } } else { @@ -240,7 +243,8 @@ int main(int argc, FAR char *argv[]) sem_wait(&g_nxlines.eventsem); } - printf("nxlines_main: Screen resolution (%d,%d)\n", g_nxlines.xres, g_nxlines.yres); + printf("nxlines_main: Screen resolution (%d,%d)\n", + g_nxlines.xres, g_nxlines.yres); /* Now, say perform the lines (these test does not return so the remaining * logic is cosmetic). diff --git a/examples/nxterm/nxterm_toolbar.c b/examples/nxterm/nxterm_toolbar.c index 0fa7c0802..327a54057 100644 --- a/examples/nxterm/nxterm_toolbar.c +++ b/examples/nxterm/nxterm_toolbar.c @@ -54,12 +54,14 @@ static void nxtool_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, bool morem, FAR void *arg); -static void nxtool_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, +static void nxtool_position(NXWINDOW hwnd, + FAR const struct nxgl_size_s *size, FAR const struct nxgl_point_s *pos, FAR const struct nxgl_rect_s *bounds, FAR void *arg); #ifdef CONFIG_NX_XYINPUT -static void nxtool_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, +static void nxtool_mousein(NXWINDOW hwnd, + FAR const struct nxgl_point_s *pos, uint8_t buttons, FAR void *arg); #endif @@ -121,7 +123,8 @@ static void nxtool_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, * Name: nxtool_position ****************************************************************************/ -static void nxtool_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, +static void nxtool_position(NXWINDOW hwnd, + FAR const struct nxgl_size_s *size, FAR const struct nxgl_point_s *pos, FAR const struct nxgl_rect_s *bounds, FAR void *arg) diff --git a/examples/nxterm/nxterm_wndo.c b/examples/nxterm/nxterm_wndo.c index c326e0449..ca88204ae 100644 --- a/examples/nxterm/nxterm_wndo.c +++ b/examples/nxterm/nxterm_wndo.c @@ -49,12 +49,14 @@ static void nxwndo_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, bool morem, FAR void *arg); -static void nxwndo_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, +static void nxwndo_position(NXWINDOW hwnd, + FAR const struct nxgl_size_s *size, FAR const struct nxgl_point_s *pos, FAR const struct nxgl_rect_s *bounds, FAR void *arg); #ifdef CONFIG_NX_XYINPUT -static void nxwndo_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, +static void nxwndo_mousein(NXWINDOW hwnd, + FAR const struct nxgl_point_s *pos, uint8_t buttons, FAR void *arg); #endif @@ -119,7 +121,9 @@ static void nxwndo_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, } else { - /* If the driver has not been opened, then just redraw the window color */ + /* If the driver has not been opened, then just redraw the window + * color. + */ wcolor[0] = CONFIG_EXAMPLES_NXTERM_WCOLOR; nxtk_fillwindow(hwnd, rect, wcolor); @@ -130,7 +134,8 @@ static void nxwndo_redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, * Name: nxwndo_position ****************************************************************************/ -static void nxwndo_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, +static void nxwndo_position(NXWINDOW hwnd, + FAR const struct nxgl_size_s *size, FAR const struct nxgl_point_s *pos, FAR const struct nxgl_rect_s *bounds, FAR void *arg) @@ -163,7 +168,8 @@ static void nxwndo_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, g_nxterm_vars.haveres = true; sem_post(&g_nxterm_vars.eventsem); - ginfo("Have xres=%d yres=%d\n", g_nxterm_vars.xres, g_nxterm_vars.yres); + ginfo("Have xres=%d yres=%d\n", + g_nxterm_vars.xres, g_nxterm_vars.yres); } } diff --git a/examples/nxtext/nxtext_bkgd.c b/examples/nxtext/nxtext_bkgd.c index 8eb55ba09..b0957bb7a 100644 --- a/examples/nxtext/nxtext_bkgd.c +++ b/examples/nxtext/nxtext_bkgd.c @@ -107,7 +107,8 @@ NXHANDLE g_bgwnd; * Name: nxbg_redrawrect ****************************************************************************/ -static void nxbg_redrawrect(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect) +static void nxbg_redrawrect(NXWINDOW hwnd, + FAR const struct nxgl_rect_s *rect) { int ret; int i; @@ -172,7 +173,9 @@ static void nxbg_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, st->wsize.w = size->w; st->wsize.h = size->h; - /* Save the window limits (these should be the same for all places and all windows */ + /* Save the window limits (these should be the same for all places + * and all windows. + */ g_xres = bounds->pt2.x + 1; g_yres = bounds->pt2.y + 1; @@ -219,7 +222,8 @@ static void nxbg_kbdin(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, * only. ****************************************************************************/ -static inline void nxbg_movedisplay(NXWINDOW hwnd, int bottom, int lineheight) +static inline void nxbg_movedisplay(NXWINDOW hwnd, int bottom, + int lineheight) { FAR struct nxtext_bitmap_s *bm; struct nxgl_rect_s rect; @@ -227,10 +231,10 @@ static inline void nxbg_movedisplay(NXWINDOW hwnd, int bottom, int lineheight) int ret; int i; - /* Move each row, one at a time. They could all be moved at once (by calling - * nxbg_redrawrect), but the since the region is cleared, then re-written, the - * effect would not be good. Below the region is also cleared and re-written, - * however, in much smaller chunks. + /* Move each row, one at a time. They could all be moved at once (by + * calling nxbg_redrawrect), but since the region is cleared, then + * rewritten, the effect would not be good. Below the region is also + * cleared and rewritten, however, in much smaller chunks. */ rect.pt1.x = 0; @@ -256,7 +260,8 @@ static inline void nxbg_movedisplay(NXWINDOW hwnd, int bottom, int lineheight) for (i = 0; i < g_bgstate.nchars; i++) { bm = &g_bgstate.bm[i]; - if (bm->pos.y <= rect.pt2.y && bm->pos.y + g_bgstate.fheight >= rect.pt1.y) + if (bm->pos.y <= rect.pt2.y && + bm->pos.y + g_bgstate.fheight >= rect.pt1.y) { nxtext_fillchar(hwnd, &rect, &g_bgstate, g_bghfont, bm); } @@ -266,7 +271,7 @@ static inline void nxbg_movedisplay(NXWINDOW hwnd, int bottom, int lineheight) /* Finally, clear the bottom part of the display */ rect.pt1.y = bottom; - rect.pt2.y = g_bgstate.wsize.h- 1; + rect.pt2.y = g_bgstate.wsize.h - 1; ret = nx_fill(hwnd, &rect, g_bgstate.wcolor); if (ret < 0) @@ -296,13 +301,15 @@ static inline void nxbg_scroll(NXWINDOW hwnd, int lineheight) { /* Yes... Delete the character by moving all of the data */ - for (j = i; j < g_bgstate.nchars-1; j++) + for (j = i; j < g_bgstate.nchars - 1; j++) { - memcpy(&g_bgstate.bm[j], &g_bgstate.bm[j+1], sizeof(struct nxtext_bitmap_s)); + memcpy(&g_bgstate.bm[j], &g_bgstate.bm[j + 1], + sizeof(struct nxtext_bitmap_s)); } - /* Decrement the number of cached characters ('i' is not incremented - * in this case because it already points to the next character) + /* Decrement the number of cached characters. 'i' is not + * incremented in this case because it already points to the next + * character. */ g_bgstate.nchars--; diff --git a/examples/nxtext/nxtext_main.c b/examples/nxtext/nxtext_main.c index d3d02956f..c749cd53a 100644 --- a/examples/nxtext/nxtext_main.c +++ b/examples/nxtext/nxtext_main.c @@ -60,6 +60,7 @@ ****************************************************************************/ /* Configuration ************************************************************/ + /* If not specified, assume that the hardware supports one video plane */ #ifndef CONFIG_EXAMPLES_NXTEXT_VPLANE @@ -138,7 +139,10 @@ nxgl_coord_t g_yres; bool b_haveresolution = false; bool g_connected = false; -sem_t g_semevent = {0}; +sem_t g_semevent = +{ + 0 +}; int g_exitcode = NXEXIT_SUCCESS; @@ -162,7 +166,7 @@ static int nxtext_initialize(void) ret = sched_setparam(0, ¶m); if (ret < 0) { - printf("nxtext_initialize: sched_setparam failed: %d\n" , ret); + printf("nxtext_initialize: sched_setparam failed: %d\n", ret); g_exitcode = NXEXIT_SCHEDSETPARAM; return ERROR; } @@ -173,7 +177,8 @@ static int nxtext_initialize(void) ret = boardctl(BOARDIOC_NX_START, 0); if (ret < 0) { - printf("nxtext_initialize: Failed to start the NX server: %d\n", errno); + printf("nxtext_initialize: Failed to start the NX server: %d\n", + errno); g_exitcode = NXEXIT_SERVERSTART; return ERROR; } @@ -188,24 +193,24 @@ static int nxtext_initialize(void) #ifdef CONFIG_VNCSERVER /* Setup the VNC server to support keyboard/mouse inputs */ - struct boardioc_vncstart_s vnc = - { - 0, g_hnx - }; + struct boardioc_vncstart_s vnc = + { + 0, g_hnx + }; - ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); - if (ret < 0) - { - printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); - nx_disconnect(g_hnx); - g_exitcode = NXEXIT_FBINITIALIZE; - return ERROR; - } + ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); + if (ret < 0) + { + printf("boardctl(BOARDIOC_VNC_START) failed: %d\n", ret); + nx_disconnect(g_hnx); + g_exitcode = NXEXIT_FBINITIALIZE; + return ERROR; + } #endif - /* Start a separate thread to listen for server events. This is probably - * the least efficient way to do this, but it makes this example flow more - * smoothly. + /* Start a separate thread to listen for server events. This is + * probably the least efficient way to do this, but it makes this + * example flow more smoothly. */ pthread_attr_init(&attr); @@ -216,10 +221,10 @@ static int nxtext_initialize(void) ret = pthread_create(&thread, &attr, nxtext_listener, NULL); if (ret != 0) { - printf("nxtext_initialize: pthread_create failed: %d\n", ret); + printf("nxtext_initialize: pthread_create failed: %d\n", ret); - g_exitcode = NXEXIT_PTHREADCREATE; - return ERROR; + g_exitcode = NXEXIT_PTHREADCREATE; + return ERROR; } /* Don't return until we are connected to the server */ @@ -277,7 +282,8 @@ int main(int argc, FAR char *argv[]) g_bghfont = nxf_getfonthandle(CONFIG_EXAMPLES_NXTEXT_BGFONTID); if (!g_bghfont) { - printf("nxtext_main: Failed to get background font handle: %d\n", errno); + printf("nxtext_main: Failed to get background font handle: %d\n", + errno); g_exitcode = NXEXIT_FONTOPEN; goto errout; } @@ -285,14 +291,16 @@ int main(int argc, FAR char *argv[]) g_puhfont = nxf_getfonthandle(CONFIG_EXAMPLES_NXTEXT_PUFONTID); if (!g_puhfont) { - printf("nxtext_main: Failed to get pop-up font handle: %d\n", errno); + printf("nxtext_main: Failed to get pop-up font handle: %d\n", + errno); g_exitcode = NXEXIT_FONTOPEN; goto errout; } /* Set the background to the configured background color */ - printf("nxtext_main: Set background color=%d\n", CONFIG_EXAMPLES_NXTEXT_BGCOLOR); + printf("nxtext_main: Set background color=%d\n", + CONFIG_EXAMPLES_NXTEXT_BGCOLOR); color = CONFIG_EXAMPLES_NXTEXT_BGCOLOR; ret = nx_setbgcolor(g_hnx, &color); if (ret < 0) @@ -328,7 +336,7 @@ int main(int argc, FAR char *argv[]) popcnt = 0; bkgndx = 0; - for (;;) + for (; ; ) { /* Sleep for one second */ @@ -346,15 +354,18 @@ int main(int argc, FAR char *argv[]) hwnd = nxpu_open(); #ifdef CONFIG_NX_KBD - /* Give keyboard input to the top window (which should be the pop-up) */ + /* Give keyboard input to the top window (which should be the + * pop-up). + */ printf("nxtext_main: Send keyboard input: %s\n", g_pumsg); - ret = nx_kbdin(g_hnx, strlen((FAR const char *)g_pumsg), g_pumsg); + ret = nx_kbdin(g_hnx, strlen((FAR const char *)g_pumsg), + g_pumsg); if (ret < 0) - { - printf("nxtext_main: nx_kbdin failed: %d\n", errno); - goto errout_with_hwnd; - } + { + printf("nxtext_main: nx_kbdin failed: %d\n", errno); + goto errout_with_hwnd; + } #endif } else if (popcnt == 5) @@ -367,11 +378,12 @@ int main(int argc, FAR char *argv[]) } /* Give another line of text to the background window. Force this - * text to go the background by calling the background window interfaces - * directly. + * text to the background by calling the background window + * interfaces directly. */ - nxbg_write(g_bgwnd, (FAR const uint8_t *)g_bgmsg[bkgndx], strlen(g_bgmsg[bkgndx])); + nxbg_write(g_bgwnd, (FAR const uint8_t *)g_bgmsg[bkgndx], + strlen(g_bgmsg[bkgndx])); if (++bkgndx >= BGMSG_LINES) { bkgndx = 0; @@ -386,13 +398,15 @@ errout_with_hwnd: if (popcnt >= 3) { printf("nxtext_main: Close pop-up\n"); - nxpu_close(hwnd); + nxpu_close(hwnd); } -//errout_with_bkgd: + /* errout_with_bkgd: */ + nx_releasebkgd(g_bgwnd); errout_with_nx: + /* Disconnect from the server */ printf("nxtext_main: Disconnect from the server\n"); diff --git a/examples/nxtext/nxtext_putc.c b/examples/nxtext/nxtext_putc.c index 384ae22bb..325132caf 100644 --- a/examples/nxtext/nxtext_putc.c +++ b/examples/nxtext/nxtext_putc.c @@ -95,6 +95,7 @@ static void nxtext_freeglyph(FAR struct nxtext_glyph_s *glyph) { free(glyph->bitmap); } + memset(glyph, 0, sizeof(struct nxtext_glyph_s)); } @@ -111,11 +112,11 @@ nxtext_allocglyph(FAR struct nxtext_state_s *st) int i; /* Search through the glyph cache looking for an unused glyph. Also, keep - * track of the least used glyph as well. We need that if we have to replace - * a glyph in the cache. + * track of the least used glyph as well. We need that if we have to + * replace a glyph in the cache. */ - for (i = 0; i < st->maxglyphs; i++) + for (i = 0; i < st->maxglyphs; i++) { /* Is this glyph in use? */ @@ -149,9 +150,9 @@ nxtext_allocglyph(FAR struct nxtext_state_s *st) if (luusecnt > 1) { - uint8_t decr = luusecnt - 1; + uint8_t decr = luusecnt - 1; - for (i = 0; i < st->maxglyphs; i++) + for (i = 0; i < st->maxglyphs; i++) { /* Is this glyph in use? */ @@ -180,7 +181,7 @@ nxtext_findglyph(FAR struct nxtext_state_s *st, uint8_t ch) /* First, try to find the glyph in the cache of pre-rendered glyphs */ - for (i = 0; i < st->maxglyphs; i++) + for (i = 0; i < st->maxglyphs; i++) { FAR struct nxtext_glyph_s *glyph = &st->glyph[i]; if (glyph->usecnt > 0 && glyph->code == ch) @@ -189,7 +190,7 @@ nxtext_findglyph(FAR struct nxtext_state_s *st, uint8_t ch) if (glyph->usecnt < MAX_USECNT) { - glyph->usecnt++; + glyph->usecnt++; } /* And return the glyph that we found */ @@ -197,6 +198,7 @@ nxtext_findglyph(FAR struct nxtext_state_s *st, uint8_t ch) return glyph; } } + return NULL; } @@ -248,13 +250,13 @@ nxtext_renderglyph(FAR struct nxtext_state_s *st, /* Pack 1-bit pixels into a 2-bits */ pixel &= 0x01; - pixel = (pixel) << 1 |pixel; + pixel = (pixel) << 1 | pixel; # endif # if CONFIG_EXAMPLES_NXTEXT_BPP < 4 /* Pack 2-bit pixels into a nibble */ pixel &= 0x03; - pixel = (pixel) << 2 |pixel; + pixel = (pixel) << 2 | pixel; # endif /* Pack 4-bit nibbles into a byte */ @@ -292,7 +294,7 @@ nxtext_renderglyph(FAR struct nxtext_state_s *st, /* Then render the glyph into the allocated memory */ - ret = RENDERER((FAR nxgl_mxpixel_t*)glyph->bitmap, + ret = RENDERER((FAR nxgl_mxpixel_t *)glyph->bitmap, glyph->height, glyph->width, glyph->stride, fbm, st->fcolor[0]); if (ret < 0) @@ -312,7 +314,8 @@ nxtext_renderglyph(FAR struct nxtext_state_s *st, * Name: nxtext_fontsize ****************************************************************************/ -static int nxtext_fontsize(NXHANDLE hfont, uint8_t ch, FAR struct nxgl_size_s *size) +static int nxtext_fontsize(NXHANDLE hfont, uint8_t ch, + FAR struct nxgl_size_s *size) { FAR const struct nx_fontbitmap_s *fbm; @@ -379,37 +382,39 @@ nxtext_addchar(NXHANDLE hfont, FAR struct nxtext_state_s *st, uint8_t ch) if (st->nchars < st->maxchars) { - /* Yes, setup the bitmap information */ + /* Yes, setup the bitmap information */ - bm = &st->bm[st->nchars]; - bm->code = ch; - bm->flags = 0; - bm->pos.x = st->fpos.x; - bm->pos.y = st->fpos.y; + bm = &st->bm[st->nchars]; + bm->code = ch; + bm->flags = 0; + bm->pos.x = st->fpos.x; + bm->pos.y = st->fpos.y; - /* Find (or create) the matching glyph */ + /* Find (or create) the matching glyph */ - glyph = nxtext_getglyph(hfont, st, ch); - if (!glyph) - { - /* No, there is no font for this code. Just mark this as a space. */ + glyph = nxtext_getglyph(hfont, st, ch); + if (!glyph) + { + /* No, there is no font for this code. Just mark this as a + * space. + */ - bm->flags |= BMFLAGS_NOGLYPH; + bm->flags |= BMFLAGS_NOGLYPH; - /* Set up the next character position */ + /* Set up the next character position */ - st->fpos.x += st->spwidth; - } - else - { - /* Set up the next character position */ + st->fpos.x += st->spwidth; + } + else + { + /* Set up the next character position */ - st->fpos.x += glyph->width; - } + st->fpos.x += glyph->width; + } - /* Success.. increment nchars to retain this character */ + /* Success.. increment nchars to retain this character */ - st->nchars++; + st->nchars++; } return bm; @@ -465,7 +470,8 @@ void nxtext_newline(FAR struct nxtext_state_s *st) * ****************************************************************************/ -void nxtext_putc(NXWINDOW hwnd, FAR struct nxtext_state_s *st, NXHANDLE hfont, uint8_t ch) +void nxtext_putc(NXWINDOW hwnd, FAR struct nxtext_state_s *st, + NXHANDLE hfont, uint8_t ch) { FAR const struct nxtext_bitmap_s *bm; @@ -562,13 +568,13 @@ void nxtext_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, /* Find (or create) the glyph that goes with this font */ - glyph = nxtext_getglyph(hfont, st, bm->code); - if (!glyph) - { - /* Shouldn't happen */ + glyph = nxtext_getglyph(hfont, st, bm->code); + if (!glyph) + { + /* Shouldn't happen */ - return; - } + return; + } /* Blit the font bitmap into the window */ diff --git a/examples/pwfb/pwfb_main.c b/examples/pwfb/pwfb_main.c index 3b5993372..cd98a48e2 100644 --- a/examples/pwfb/pwfb_main.c +++ b/examples/pwfb/pwfb_main.c @@ -57,6 +57,8 @@ #include "pwfb_internal.h" +#define ARROW1_CURSOR_IMAGE g_arrow1##Cursor + /**************************************************************************** * Private Data ****************************************************************************/ @@ -115,22 +117,22 @@ static bool pwfb_server_initialize(FAR struct pwfb_state_s *st) #ifdef CONFIG_VNCSERVER /* Setup the VNC server to support keyboard/mouse inputs */ - struct boardioc_vncstart_s vnc = - { - 0, st->hnx - }; + struct boardioc_vncstart_s vnc = + { + 0, st->hnx + }; - ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); - if (ret < 0) - { - printf("pwfb_server_initialize: ERROR: " - "boardctl(BOARDIOC_VNC_START) failed: %d\n", - ret); + ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); + if (ret < 0) + { + printf("pwfb_server_initialize: ERROR: " + "boardctl(BOARDIOC_VNC_START) failed: %d\n", + ret); - nx_disconnect(st->hnx); - g_exitcode = NXEXIT_FBINITIALIZE; - return ERROR; - } + nx_disconnect(st->hnx); + g_exitcode = NXEXIT_FBINITIALIZE; + return ERROR; + } #endif } else @@ -168,10 +170,10 @@ static bool pwfb_listener_initialize(FAR struct pwfb_state_s *st) ret = pthread_create(&thread, &attr, pwfb_listener, st); if (ret != 0) { - printf("pwfb_listener_initialize: ERROR: " - "pthread_create failed: %d\n", - ret); - return false; + printf("pwfb_listener_initialize: ERROR: " + "pthread_create failed: %d\n", + ret); + return false; } /* Don't return until we are connected to the server */ @@ -340,8 +342,8 @@ static bool pwfb_putc(FAR struct pwfb_state_s *st, /* Render the glyph into the window */ src = glyph->bitmap; - ret = nxtk_bitmapwindow(wndo->hwnd, &bounds, &src, - fpos, (unsigned int)glyph->stride); + ret = nxtk_bitmapwindow(wndo->hwnd, &bounds, &src, + fpos, (unsigned int)glyph->stride); if (ret < 0) { printf("pwfb_putc: ERROR: " @@ -510,8 +512,8 @@ static bool pwfb_configure_cursor(FAR struct pwfb_state_s *st, st->cursor.state = PFWB_CURSOR_MOVING; st->cursor.countdown = CURSOR_MOVING_DELAY; st->cursor.blinktime = 0; - st->cursor.xmax = itob16(st->xres - g_arrow1Cursor.size.w - 1); - st->cursor.ymax = itob16(st->yres - g_arrow1Cursor.size.h - 1); + st->cursor.xmax = itob16(st->xres - ARROW1_CURSOR_IMAGE.size.w - 1); + st->cursor.ymax = itob16(st->yres - ARROW1_CURSOR_IMAGE.size.h - 1); st->cursor.xpos = itob16(pos->x); st->cursor.ypos = itob16(pos->y); st->cursor.deltax = dtob16(deltax); @@ -519,7 +521,7 @@ static bool pwfb_configure_cursor(FAR struct pwfb_state_s *st, /* Set the cursor image */ - ret = nxcursor_setimage(st->hnx, &g_arrow1Cursor); + ret = nxcursor_setimage(st->hnx, &ARROW1_CURSOR_IMAGE); if (ret < 0) { printf("pwfb_configure_cursor: ERROR: " @@ -651,7 +653,8 @@ int main(int argc, FAR char *argv[]) pos.x = wstate.xres / 8; pos.y = wstate.yres / 8; - if (!pwfb_configure_window(&wstate, 0, &size, &pos, g_wndomsg1, 4.200, 4.285)) + if (!pwfb_configure_window(&wstate, 0, &size, &pos, g_wndomsg1, + 4.200, 4.285)) { printf("pwfb_main: ERROR: " "pwfb_configure_window failed for window 1\n"); @@ -681,7 +684,8 @@ int main(int argc, FAR char *argv[]) pos.x = wstate.xres / 4; pos.y = wstate.yres / 4; - if (!pwfb_configure_window(&wstate, 1, &size, &pos, g_wndomsg2, -3.317, 5.0)) + if (!pwfb_configure_window(&wstate, 1, &size, &pos, g_wndomsg2, + -3.317, 5.0)) { printf("pwfb_main: ERROR: " "pwfb_configure_window failed for window 2\n"); @@ -711,7 +715,8 @@ int main(int argc, FAR char *argv[]) pos.x = (3 * wstate.xres) / 8; pos.y = (3 * wstate.yres) / 8; - if (!pwfb_configure_window(&wstate, 2, &size, &pos, g_wndomsg3, 4.600, -3.852)) + if (!pwfb_configure_window(&wstate, 2, &size, &pos, g_wndomsg3, + 4.600, -3.852)) { printf("pwfb_main: ERROR: " "pwfb_configure_window failed for window 2\n"); @@ -797,6 +802,7 @@ errout_with_hwnd1: #endif errout_with_fontcache: + /* Release the font cache */ nxf_cache_disconnect(wstate.wndo[0].fcache); @@ -804,6 +810,7 @@ errout_with_fontcache: nxf_cache_disconnect(wstate.wndo[2].fcache); errout_with_nx: + /* Disconnect from the server */ printf("pwfb_main: Disconnect from the server\n"); diff --git a/examples/pwlines/pwlines_main.c b/examples/pwlines/pwlines_main.c index 8d448cc11..53a2b3a53 100644 --- a/examples/pwlines/pwlines_main.c +++ b/examples/pwlines/pwlines_main.c @@ -94,21 +94,21 @@ static bool pwlines_server_initialize(FAR struct pwlines_state_s *st) #ifdef CONFIG_VNCSERVER /* Setup the VNC server to support keyboard/mouse inputs */ - struct boardioc_vncstart_s vnc = - { - 0, st->hnx - }; + struct boardioc_vncstart_s vnc = + { + 0, st->hnx + }; - ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); - if (ret < 0) - { - printf("pwlines_server_initialize: ERROR: " - "boardctl(BOARDIOC_VNC_START) failed: %d\n", - ret); + ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc); + if (ret < 0) + { + printf("pwlines_server_initialize: ERROR: " + "boardctl(BOARDIOC_VNC_START) failed: %d\n", + ret); - nx_disconnect(st->hnx); - return false; - } + nx_disconnect(st->hnx); + return false; + } #endif } else @@ -141,15 +141,16 @@ static bool pwlines_listener_initialize(FAR struct pwlines_state_s *st) pthread_attr_init(&attr); param.sched_priority = CONFIG_EXAMPLES_PWLINES_LISTENER_PRIO; pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_PWLINES_LISTENER_STACKSIZE); + pthread_attr_setstacksize(&attr, + CONFIG_EXAMPLES_PWLINES_LISTENER_STACKSIZE); ret = pthread_create(&thread, &attr, pwlines_listener, st); if (ret != 0) { - printf("pwlines_listener_initialize: ERROR: " - "pthread_create failed: %d\n", - ret); - return false; + printf("pwlines_listener_initialize: ERROR: " + "pthread_create failed: %d\n", + ret); + return false; } /* Don't return until we are connected to the server */ @@ -193,7 +194,8 @@ static bool pwlines_state_initialize(FAR struct pwlines_state_s *st) * Name: pwlines_configure_window ****************************************************************************/ -static bool pwlines_configure_window(FAR struct pwlines_state_s *st, int wndx, +static bool pwlines_configure_window(FAR struct pwlines_state_s *st, + int wndx, FAR struct nxgl_size_s *size, FAR struct nxgl_point_s *pos, double deltax, double deltay) @@ -353,8 +355,9 @@ int main(int argc, FAR char *argv[]) printf("pwlines_main: Open window 1\n"); - wstate.wndo[0].hwnd = nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED, - &g_pwlines_wncb, (FAR void *)&wstate); + wstate.wndo[0].hwnd = + nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED, + &g_pwlines_wncb, (FAR void *)&wstate); if (wstate.wndo[0].hwnd == NULL) { printf("pwlines_main: ERROR: " @@ -386,7 +389,8 @@ int main(int argc, FAR char *argv[]) pos.x = wstate.xres / 8; pos.y = wstate.yres / 8; - if (!pwlines_configure_window(&wstate, 0, &size, &pos, 4.200, 4.285)) + if (!pwlines_configure_window(&wstate, 0, &size, &pos, + 4.200, 4.285)) { printf("pwlines_main: ERROR: " "pwlines_configure_window failed for window 1\n"); @@ -397,8 +401,9 @@ int main(int argc, FAR char *argv[]) printf("pwlines_main: Open window 2\n"); - wstate.wndo[1].hwnd = nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED, - &g_pwlines_wncb, (FAR void *)&wstate); + wstate.wndo[1].hwnd = + nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED, + &g_pwlines_wncb, (FAR void *)&wstate); if (wstate.wndo[1].hwnd == NULL) { printf("pwlines_main: ERROR: " @@ -414,7 +419,8 @@ int main(int argc, FAR char *argv[]) pos.x = wstate.xres / 4; pos.y = wstate.yres / 4; - if (!pwlines_configure_window(&wstate, 1, &size, &pos, -3.317, 5.0)) + if (!pwlines_configure_window(&wstate, 1, &size, &pos, + -3.317, 5.0)) { printf("pwlines_main: ERROR: " "pwlines_configure_window failed for window 2\n"); @@ -425,8 +431,9 @@ int main(int argc, FAR char *argv[]) printf("pwlines_main: Open window 3\n"); - wstate.wndo[2].hwnd = nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED, - &g_pwlines_wncb, (FAR void *)&wstate); + wstate.wndo[2].hwnd = + nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED, + &g_pwlines_wncb, (FAR void *)&wstate); if (wstate.wndo[2].hwnd == NULL) { printf("pwlines_main: ERROR: " @@ -442,7 +449,8 @@ int main(int argc, FAR char *argv[]) pos.x = (3 * wstate.xres) / 8; pos.y = (3 * wstate.yres) / 8; - if (!pwlines_configure_window(&wstate, 2, &size, &pos, 4.600, -3.852)) + if (!pwlines_configure_window(&wstate, 2, &size, &pos, + 4.600, -3.852)) { printf("pwlines_main: ERROR: " "pwlines_configure_window failed for window 2\n"); @@ -512,6 +520,7 @@ errout_with_hwnd1: } errout_with_nx: + /* Disconnect from the server */ printf("pwlines_main: Disconnect from the server\n"); diff --git a/examples/qencoder/qe_main.c b/examples/qencoder/qe_main.c index 504db260d..23e529802 100644 --- a/examples/qencoder/qe_main.c +++ b/examples/qencoder/qe_main.c @@ -307,11 +307,14 @@ int main(int argc, FAR char *argv[]) if (g_qeexample.use_qeindex) { - ret = ioctl(fd, QEIOC_GETINDEX, (unsigned long)((uintptr_t)&index)); + ret = ioctl(fd, QEIOC_GETINDEX, + (unsigned long)((uintptr_t)&index)); if (ret < 0) { - printf("qe_main: ioctl(QEIOC_GETINDEX) failed: %d\n", errno); - printf("Your MCU probably does not support this ioctl call.\n"); + printf("qe_main: ioctl(QEIOC_GETINDEX) failed: %d\n", + errno); + printf("Your MCU probably does not support this ioctl " + "call.\n"); printf("Consider using this example without the -i option.\n"); exitval = EXIT_FAILURE; goto errout_with_dev; @@ -321,13 +324,17 @@ int main(int argc, FAR char *argv[]) else { - printf("qe_main: %3d. pos: %" PRIi32 ", last index: %" PRIi32 ", hit indexes: %" \ - PRIi16 "\n", nloops + 1, index.qenc_pos, index.indx_pos, index.indx_cnt); + printf("qe_main: %3d. pos: %" PRIi32 ", " + "last index: %" PRIi32 ", " + "hit indexes: %" PRIi16 "\n", + nloops + 1, index.qenc_pos, index.indx_pos, + index.indx_cnt); } } else { - ret = ioctl(fd, QEIOC_POSITION, (unsigned long)((uintptr_t)&position)); + ret = ioctl(fd, QEIOC_POSITION, + (unsigned long)((uintptr_t)&position)); if (ret < 0) { printf("qe_main: ioctl(QEIOC_POSITION) failed: %d\n", errno); diff --git a/fsutils/flash_eraseall/flash_eraseall.c b/fsutils/flash_eraseall/flash_eraseall.c index f7462c152..fda7b7e04 100644 --- a/fsutils/flash_eraseall/flash_eraseall.c +++ b/fsutils/flash_eraseall/flash_eraseall.c @@ -71,13 +71,14 @@ int flash_eraseall(FAR const char *driver) if (ret < 0) { errcode = errno; - ferr("ERROR: MTD ioctl(%04x) failed: %d\n", MTDIOC_BULKERASE, errcode); + ferr("ERROR: MTD ioctl(%04x) failed: %d\n", + MTDIOC_BULKERASE, errcode); ret = -errcode; } /* Close the block driver */ - close(fd); + close(fd); } return ret; diff --git a/graphics/tiff/tiff_addstrip.c b/graphics/tiff/tiff_addstrip.c index 5db952088..965152eac 100644 --- a/graphics/tiff/tiff_addstrip.c +++ b/graphics/tiff/tiff_addstrip.c @@ -65,13 +65,15 @@ * tiff_initialize(). * * Input Parameters: - * info - A pointer to the caller allocated parameter passing/TIFF state instance. + * info - A pointer to the caller allocated parameter passing/TIFF + * state instance. * buffer - A buffer containing a single row of data. * * Returned Value: * Zero (OK) on success. A negated errno value on failure. * ****************************************************************************/ + int tiff_convstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip) { #ifdef CONFIG_DEBUG_GRAPHICS @@ -100,9 +102,9 @@ int tiff_convstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip) /* Convert RGB565 to RGB888 */ rgb565 = *src++; - *dest++ = (rgb565 >> (11-3)) & 0xf8; /* Move bits 11-15 to 3-7 */ - *dest++ = (rgb565 >> ( 5-2)) & 0xfc; /* Move bits 5-10 to 2-7 */ - *dest++ = (rgb565 << ( 3)) & 0xf8; /* Move bits 0- 4 to 3-7 */ + *dest++ = (rgb565 >> (11 - 3)) & 0xf8; /* Move bits 11-15 to 3-7 */ + *dest++ = (rgb565 >> (5 - 2)) & 0xfc; /* Move bits 5-10 to 2-7 */ + *dest++ = (rgb565 << 3) & 0xf8; /* Move bits 0- 4 to 3-7 */ /* Update the byte count */ @@ -113,7 +115,7 @@ int tiff_convstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip) /* Flush the conversion buffer to tmpfile2 when it becomes full */ - if (nbytes > (info->iosize-3)) + if (nbytes > (info->iosize - 3)) { ret = tiff_write(info->tmp2fd, info->iobuffer, nbytes); if (ret < 0) @@ -134,6 +136,7 @@ int tiff_convstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip) #ifdef CONFIG_DEBUG_GRAPHICS DEBUGASSERT(ntotal == info->bps); #endif + return ret; } @@ -150,7 +153,8 @@ int tiff_convstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip) * tiff_initialize(). * * Input Parameters: - * info - A pointer to the caller allocated parameter passing/TIFF state instance. + * info - A pointer to the caller allocated parameter passing/TIFF + * state instance. * buffer - A buffer containing a single row of data. * * Returned Value: @@ -172,7 +176,9 @@ int tiff_addstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip) ret = tiff_convstrip(info, strip); } - /* For other formats, it is a simple write using the number of bytes per strip */ + /* For other formats, it is a simple write using the number of bytes per + * strip. + */ else { @@ -191,6 +197,7 @@ int tiff_addstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip) { goto errout; } + info->outsize += 4; ret = tiff_putint32(info->tmp1fd, info->tmp2size); @@ -198,6 +205,7 @@ int tiff_addstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip) { goto errout; } + info->tmp1size += 4; /* Increment the size of tmp2file. */ @@ -212,14 +220,17 @@ int tiff_addstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip) ret = (int)newsize; goto errout; } + info->tmp2size = (size_t)newsize; /* Increment the number of strips in the TIFF file */ info->nstrips++; + return OK; errout: + tiff_abort(info); return ret; } diff --git a/graphics/tiff/tiff_initialize.c b/graphics/tiff/tiff_initialize.c index 263f650cf..2c4f5921a 100644 --- a/graphics/tiff/tiff_initialize.c +++ b/graphics/tiff/tiff_initialize.c @@ -41,6 +41,7 @@ /**************************************************************************** * Pre-Processor Definitions ****************************************************************************/ + /* Bi-level Images * * Offset Description Contents/Notes @@ -50,13 +51,18 @@ * 8 [2 bytes padding] * IFD: 10 Number of Directory Entries 13 * 12 NewSubfileType - * 24 ImageWidth Number of columns is a user parameter - * 36 ImageLength Number of rows is a user parameter - * 48 Compression Hard-coded no compression (for now) + * 24 ImageWidth Number of columns is a user + * parameter + * 36 ImageLength Number of rows is a user + * parameter + * 48 Compression Hard-coded no compression + * (for now) * 60 PhotometricInterpretation Value is a user parameter - * 72 StripOffsets Offset and count determined as strips added + * 72 StripOffsets Offset and count determined + * as strips added * 84 RowsPerStrip Value is a user parameter - * 96 StripByteCounts Offset and count determined as strips added + * 96 StripByteCounts Offset and count determined + * as strips added * 108 XResolution Value is a user parameter * 120 YResolution Value is a user parameter * 132 Resolution Unit Hard-coded to "inches" @@ -67,8 +73,10 @@ * Values: * 172 XResolution Hard-coded to 300/1 * 180 YResolution Hard-coded to 300/1 - * 188 "NuttX" Length = 6 (including NUL terminator) - * 194 "YYYY:MM:DD HH:MM:SS" Length = 20 (including NUL terminator) + * 188 "NuttX" Length = 6 (including NUL + * terminator) + * 194 "YYYY:MM:DD HH:MM:SS" Length = 20 (including NUL + * terminator) * 214 [2 bytes padding] * 216 StripByteCounts Beginning of strip byte counts * xxx StripOffsets Beginning of strip offsets @@ -76,7 +84,7 @@ * xxx Data for strips Beginning of strip data */ -#define TIFF_IFD_OFFSET (SIZEOF_TIFF_HEADER+2) +#define TIFF_IFD_OFFSET (SIZEOF_TIFF_HEADER + 2) #define TIFF_BILEV_NIFDENTRIES 13 #define TIFF_BILEV_STRIPIFDOFFS 72 @@ -102,14 +110,19 @@ * 8 [2 bytes padding] * IFD: 10 Number of Directory Entries 14 * 12 NewSubfileType - * 24 ImageWidth Number of columns is a user parameter - * 36 ImageLength Number of rows is a user parameter + * 24 ImageWidth Number of columns is a user + * parameter + * 36 ImageLength Number of rows is a user + * parameter * 48 BitsPerSample - * 60 Compression Hard-coded no compression (for now) + * 60 Compression Hard-coded no compression + * (for now) * 72 PhotometricInterpretation Value is a user parameter - * 84 StripOffsets Offset and count determined as strips added + * 84 StripOffsets Offset and count determined + * as strips added * 96 RowsPerStrip Value is a user parameter - * 108 StripByteCounts Offset and count determined as strips added + * 108 StripByteCounts Offset and count determined + * as strips added * 120 XResolution Value is a user parameter * 132 YResolution Value is a user parameter * 144 Resolution Unit Hard-coded to "inches" @@ -120,8 +133,10 @@ * Values: * 184 XResolution Hard-coded to 300/1 * 192 YResolution Hard-coded to 300/1 - * 200 "NuttX" Length = 6 (including NUL terminator) - * 206 "YYYY:MM:DD HH:MM:SS" Length = 20 (including NUL terminator) + * 200 "NuttX" Length = 6 (including NUL + * terminator) + * 206 "YYYY:MM:DD HH:MM:SS" Length = 20 (including NUL + * terminator) * 226 [2 bytes padding] * 228 StripByteCounts Beginning of strip byte counts * xxx StripOffsets Beginning of strip offsets @@ -148,15 +163,20 @@ * 8 [2 bytes padding] * IFD: 10 Number of Directory Entries 15 * 12 NewSubfileType - * 24 ImageWidth Number of columns is a user parameter - * 36 ImageLength Number of rows is a user parameter + * 24 ImageWidth Number of columns is a user + * parameter + * 36 ImageLength Number of rows is a user + * parameter * 48 BitsPerSample 8, 8, 8 - * 60 Compression Hard-coded no compression (for now) + * 60 Compression Hard-coded no compression + * (for now) * 72 PhotometricInterpretation Value is a user parameter - * 84 StripOffsets Offset and count determined as strips added + * 84 StripOffsets Offset and count determined + * as strips added * 96 SamplesPerPixel Hard-coded to 3 * 108 RowsPerStrip Value is a user parameter - * 120 StripByteCounts Offset and count determined as strips added + * 120 StripByteCounts Offset and count determined + * as strips added * 132 XResolution Value is a user parameter * 144 YResolution Value is a user parameter * 156 Resolution Unit Hard-coded to "inches" @@ -169,8 +189,10 @@ * 204 YResolution Hard-coded to 300/1 * 212 BitsPerSample 8, 8, 8 * 218 [2 bytes padding] - * 220 "NuttX" Length = 6 (including NUL terminator) - * 226 "YYYY:MM:DD HH:MM:SS" Length = 20 (including NUL terminator) + * 220 "NuttX" Length = 6 (including NUL + * terminator) + * 226 "YYYY:MM:DD HH:MM:SS" Length = 20 (including NUL + * terminator) * 246 [2 bytes padding] * 248 StripByteCounts Beginning of strip byte counts * xxx StripOffsets Beginning of strip offsets @@ -189,8 +211,12 @@ #define TIFF_RGB_DATEOFFSET 226 #define TIFF_RGB_STRIPBCOFFSET 248 -/* Debug *******************************************************************/ -/* CONFIG_DEBUG_TIFFOFFSETS may be defined (along with CONFIG_DEBUG_FEATURES and +/**************************************************************************** + * Debug + ****************************************************************************/ + +/* CONFIG_DEBUG_TIFFOFFSETS may be defined (along with CONFIG_DEBUG_FEATURES + * and * CONFIG_DEBUG_GRAPHICS) in order to verify the pre-determined TIFF file * offsets. */ @@ -200,11 +226,11 @@ #endif #ifdef CONFIG_DEBUG_TIFFOFFSETS -# define tiff_offset(o,l) (o) += (l) -# define tiff_checkoffs(o,x) DEBUGASSERT((o) == (x)) +# define tiff_offset(o, l) (o) += (l) +# define tiff_checkoffs(o, x) DEBUGASSERT((o) == (x)) #else -# define tiff_offset(o,l) -# define tiff_checkoffs(o,x) +# define tiff_offset(o, l) +# define tiff_checkoffs(o, x) #endif /**************************************************************************** @@ -408,7 +434,7 @@ static int tiff_datetime(FAR char *timbuf, unsigned int buflen) /* Break the current time up into the format needed by strftime */ - gmtime_r((FAR const time_t*)&ts.tv_sec, &tm); + gmtime_r((FAR const time_t *)&ts.tv_sec, &tm); /* Convert the current time to TIFF format */ @@ -427,7 +453,8 @@ static int tiff_datetime(FAR char *timbuf, unsigned int buflen) * Setup to create a new TIFF file. * * Input Parameters: - * info - A pointer to the caller allocated parameter passing/TIFF state instance. + * info - A pointer to the caller allocated parameter passing/TIFF state + * instance. * * Returned Value: * Zero (OK) on success. A negated errno value on failure. @@ -447,7 +474,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) /* Open all output files */ - info->outfd = open(info->outfile, O_RDWR|O_CREAT|O_TRUNC, 0666); + info->outfd = open(info->outfile, O_RDWR | O_CREAT | O_TRUNC, 0666); if (info->outfd < 0) { gerr("ERROR: Failed to open %s for reading/writing: %d\n", @@ -455,7 +482,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) goto errout; } - info->tmp1fd = open(info->tmpfile1, O_RDWR|O_CREAT|O_TRUNC, 0666); + info->tmp1fd = open(info->tmpfile1, O_RDWR | O_CREAT | O_TRUNC, 0666); if (info->tmp1fd < 0) { gerr("ERROR: Failed to open %s for reading/writing: %d\n", @@ -463,7 +490,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) goto errout; } - info->tmp2fd = open(info->tmpfile2, O_RDWR|O_CREAT|O_TRUNC, 0666); + info->tmp2fd = open(info->tmpfile2, O_RDWR | O_CREAT | O_TRUNC, 0666); if (info->tmp2fd < 0) { gerr("ERROR: Failed to open %s for reading/writing: %d\n", @@ -505,7 +532,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) case FB_FMT_RGB24: /* BPP=24 R=8, G=8, B=8 */ info->filefmt = &g_rgbinfo; /* RGB file image file info */ info->imgflags = IMGFLAGS_FMT_RGB24; /* Bit encoded image characteristics */ - info->bps = 3 *info->pps; /* Bytes per strip */ + info->bps = 3 * info->pps; /* Bytes per strip */ break; default: @@ -526,6 +553,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) { goto errout; } + tiff_offset(offset, TIFF_IFD_OFFSET); /* Write the Number of directory entries @@ -538,6 +566,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) { goto errout; } + tiff_offset(offset, 2); /* Write the NewSubfileType IFD entry @@ -545,11 +574,13 @@ int tiff_initialize(FAR struct tiff_info_s *info) * All formats: Offset 12 NewSubfileType */ - ret = tiff_putifdentry16(info, IFD_TAG_NEWSUBFILETYPE, IFD_FIELD_LONG, 1, 0); + ret = tiff_putifdentry16(info, IFD_TAG_NEWSUBFILETYPE, + IFD_FIELD_LONG, 1, 0); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); /* Write ImageWidth and ImageLength @@ -558,17 +589,20 @@ int tiff_initialize(FAR struct tiff_info_s *info) * 36 ImageLength Number of rows is a user parameter */ - ret = tiff_putifdentry16(info, IFD_TAG_IMAGEWIDTH, IFD_FIELD_SHORT, 1, info->imgwidth); + ret = tiff_putifdentry16(info, IFD_TAG_IMAGEWIDTH, + IFD_FIELD_SHORT, 1, info->imgwidth); if (ret == OK) { - ret= tiff_putifdentry16(info, IFD_TAG_IMAGELENGTH, IFD_FIELD_SHORT, 1, info->imgheight); + ret = tiff_putifdentry16(info, IFD_TAG_IMAGELENGTH, + IFD_FIELD_SHORT, 1, info->imgheight); } if (ret < 0) { goto errout; } - tiff_offset(offset, 2*SIZEOF_IFD_ENTRY); + + tiff_offset(offset, 2 * SIZEOF_IFD_ENTRY); /* Write BitsPerSample * @@ -589,20 +623,24 @@ int tiff_initialize(FAR struct tiff_info_s *info) val16 = 4; } - ret = tiff_putifdentry16(info, IFD_TAG_BITSPERSAMPLE, IFD_FIELD_SHORT, 1, val16); + ret = tiff_putifdentry16(info, IFD_TAG_BITSPERSAMPLE, + IFD_FIELD_SHORT, 1, val16); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); } else if (IMGFLAGS_ISRGB(info->imgflags)) { - ret = tiff_putifdentry(info, IFD_TAG_BITSPERSAMPLE, IFD_FIELD_SHORT, 3, TIFF_RGB_BPSOFFSET); + ret = tiff_putifdentry(info, IFD_TAG_BITSPERSAMPLE, + IFD_FIELD_SHORT, 3, TIFF_RGB_BPSOFFSET); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); } @@ -613,11 +651,13 @@ int tiff_initialize(FAR struct tiff_info_s *info) * RGB: Offset 60 " " " " "" " " " " " " */ - ret = tiff_putifdentry16(info, IFD_TAG_COMPRESSION, IFD_FIELD_SHORT, 1, TAG_COMP_NONE); + ret = tiff_putifdentry16(info, IFD_TAG_COMPRESSION, + IFD_FIELD_SHORT, 1, TAG_COMP_NONE); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); /* Write PhotometricInterpretation: @@ -641,6 +681,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); /* Write StripOffsets: @@ -656,6 +697,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); /* Write SamplesPerPixel @@ -667,11 +709,13 @@ int tiff_initialize(FAR struct tiff_info_s *info) if (IMGFLAGS_ISRGB(info->imgflags)) { - ret = tiff_putifdentry16(info, IFD_TAG_SAMPLESPERPIXEL, IFD_FIELD_SHORT, 1, 3); + ret = tiff_putifdentry16(info, IFD_TAG_SAMPLESPERPIXEL, + IFD_FIELD_SHORT, 1, 3); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); } @@ -682,26 +726,33 @@ int tiff_initialize(FAR struct tiff_info_s *info) * RGB: Offset 108 Value is a user parameter */ - ret = tiff_putifdentry16(info, IFD_TAG_ROWSPERSTRIP, IFD_FIELD_SHORT, 1, info->rps); + ret = tiff_putifdentry16(info, IFD_TAG_ROWSPERSTRIP, + IFD_FIELD_SHORT, 1, info->rps); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); /* Write StripByteCounts: * - * Bi-level Images: Offset 96 Count determined as strips added, Value offset = 216 - * Greyscale: Offset 108 Count determined as strips added, Value offset = 228 - * RGB: Offset 120 Count determined as strips added, Value offset = 248 + * Bi-level Images: Offset 96 Count determined as strips added, Value + * offset = 216 + * Greyscale: Offset 108 Count determined as strips added, Value + * offset = 228 + * RGB: Offset 120 Count determined as strips added, Value + * offset = 248 */ tiff_checkoffs(offset, info->filefmt->sbcifdoffset); - ret = tiff_putifdentry(info, IFD_TAG_STRIPCOUNTS, IFD_FIELD_LONG, 0, info->filefmt->sbcoffset); + ret = tiff_putifdentry(info, IFD_TAG_STRIPCOUNTS, + IFD_FIELD_LONG, 0, info->filefmt->sbcoffset); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); /* Write XResolution and YResolution: @@ -711,17 +762,22 @@ int tiff_initialize(FAR struct tiff_info_s *info) * RGB: Offset 132 and 144, Values are a user parameters */ - ret = tiff_putifdentry(info, IFD_TAG_XRESOLUTION, IFD_FIELD_RATIONAL, 1, info->filefmt->xresoffset); + ret = tiff_putifdentry(info, IFD_TAG_XRESOLUTION, + IFD_FIELD_RATIONAL, 1, + info->filefmt->xresoffset); if (ret == OK) { - ret = tiff_putifdentry(info, IFD_TAG_YRESOLUTION, IFD_FIELD_RATIONAL, 1, info->filefmt->yresoffset); + ret = tiff_putifdentry(info, IFD_TAG_YRESOLUTION, + IFD_FIELD_RATIONAL, 1, + info->filefmt->yresoffset); } if (ret < 0) { goto errout; } - tiff_offset(offset, 2*SIZEOF_IFD_ENTRY); + + tiff_offset(offset, 2 * SIZEOF_IFD_ENTRY); /* Write ResolutionUnit: * @@ -730,11 +786,13 @@ int tiff_initialize(FAR struct tiff_info_s *info) * RGB: Offset 156, Hard-coded to "inches" */ - ret = tiff_putifdentry16(info, IFD_TAG_RESUNIT, IFD_FIELD_SHORT, 1, TAG_RESUNIT_INCH); + ret = tiff_putifdentry16(info, IFD_TAG_RESUNIT, + IFD_FIELD_SHORT, 1, TAG_RESUNIT_INCH); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); /* Write Software: @@ -744,11 +802,14 @@ int tiff_initialize(FAR struct tiff_info_s *info) * RGB: Offset 168 Count, Hard-coded "NuttX" */ - ret = tiff_putifdentry(info, IFD_TAG_SOFTWARE, IFD_FIELD_ASCII, TIFF_SOFTWARE_STRLEN, info->filefmt->swoffset); + ret = tiff_putifdentry(info, IFD_TAG_SOFTWARE, + IFD_FIELD_ASCII, TIFF_SOFTWARE_STRLEN, + info->filefmt->swoffset); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); /* Write DateTime: @@ -758,11 +819,14 @@ int tiff_initialize(FAR struct tiff_info_s *info) * RGB: Offset 180 Count, Format "YYYY:MM:DD HH:MM:SS" */ - ret = tiff_putifdentry(info, IFD_TAG_DATETIME, IFD_FIELD_ASCII, TIFF_DATETIME_STRLEN, info->filefmt->dateoffset); + ret = tiff_putifdentry(info, IFD_TAG_DATETIME, + IFD_FIELD_ASCII, TIFF_DATETIME_STRLEN, + info->filefmt->dateoffset); if (ret < 0) { goto errout; } + tiff_offset(offset, SIZEOF_IFD_ENTRY); /* Write Next IFD Offset and 2 bytes of padding: @@ -780,6 +844,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) { goto errout; } + tiff_offset(offset, 4); /* Now we begin the value section of the file */ @@ -807,6 +872,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) { goto errout; } + tiff_offset(offset, 8); tiff_checkoffs(offset, info->filefmt->yresoffset); @@ -820,6 +886,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) { goto errout; } + tiff_offset(offset, 8); /* Write RGB BitsPerSample Data: @@ -837,6 +904,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) tiff_putint16(info->outfd, 8); tiff_putint16(info->outfd, 8); tiff_putint16(info->outfd, 0); + tiff_offset(offset, 8); } @@ -849,11 +917,13 @@ int tiff_initialize(FAR struct tiff_info_s *info) */ tiff_checkoffs(offset, info->filefmt->swoffset); - ret = tiff_putstring(info->outfd, TIFF_SOFTWARE_STRING, TIFF_SOFTWARE_STRLEN); + ret = tiff_putstring(info->outfd, TIFF_SOFTWARE_STRING, + TIFF_SOFTWARE_STRLEN); if (ret < 0) { goto errout; } + tiff_offset(offset, TIFF_SOFTWARE_STRLEN); /* Write the DateTime string: @@ -876,6 +946,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) { goto errout; } + tiff_offset(offset, TIFF_DATETIME_STRLEN); /* Add two bytes of padding */ @@ -885,6 +956,7 @@ int tiff_initialize(FAR struct tiff_info_s *info) { goto errout; } + tiff_offset(offset, 2); /* And that should do it! */ diff --git a/graphics/tiff/tiff_utils.c b/graphics/tiff/tiff_utils.c index 17e72689b..12aa4bb8e 100644 --- a/graphics/tiff/tiff_utils.c +++ b/graphics/tiff/tiff_utils.c @@ -93,10 +93,10 @@ void tiff_put32(FAR uint8_t *dest, uint32_t value) { #ifdef CONFIG_ENDIAN_BIG tiff_put16(dest, (uint16_t)(value >> 16)); - tiff_put16(dest+2, (uint16_t)(value & 0xffff)); + tiff_put16(dest + 2, (uint16_t)(value & 0xffff)); #else tiff_put16(dest, (uint16_t)(value & 0xffff)); - tiff_put16(dest+2, (uint16_t)(value >> 16)); + tiff_put16(dest + 2, (uint16_t)(value >> 16)); #endif } @@ -112,11 +112,10 @@ uint16_t tiff_get16(FAR uint8_t *src) uint32_t tiff_get32(FAR uint8_t *src) { #ifdef CONFIG_ENDIAN_BIG - return (uint32_t)tiff_get16(src) << 16 | (uint32_t)tiff_get16(src+2); + return (uint32_t)tiff_get16(src) << 16 | (uint32_t)tiff_get16(src + 2); #else - return (uint32_t)tiff_get16(src+2) << 16 | (uint32_t)tiff_get16(src); + return (uint32_t)tiff_get16(src + 2) << 16 | (uint32_t)tiff_get16(src); #endif - } /**************************************************************************** @@ -153,7 +152,7 @@ ssize_t tiff_read(int fd, FAR void *buffer, size_t count) * (ntotal). */ - nbytes = read(fd, buffer, count-ntotal); + nbytes = read(fd, buffer, count - ntotal); /* Check for an error */ @@ -166,22 +165,26 @@ ssize_t tiff_read(int fd, FAR void *buffer, size_t count) errval = errno; if (errval != EINTR) { - /* Other errors are bad news and we will break out with an error */ + /* Other errors are bad news and we will break out with an + * error. + */ return -errval; } } - /* Zero is a special case and means that the end of file was encountered. */ + /* Zero is a special case and means that the end of file was + * encountered. + */ else if (nbytes == 0) { break; } - /* What if read returns some number of bytes other than the requested number? - * This probably means that the end-of-file will be encountered the next time - * that we call read(). + /* What if read returns some number of bytes other than the requested + * number? This probably means that the end-of-file will be + * encountered the next time that we call read(). */ else @@ -236,13 +239,17 @@ int tiff_write(int fd, FAR const void *buffer, size_t count) errval = errno; if (errval != EINTR) { - /* Other errors are bad news and we will break out with an error */ + /* Other errors are bad news and we will break out with an + * error. + */ return -errval; } } - /* What if write returns some number of bytes other than the requested number? */ + /* What if write returns some number of bytes other than the requested + * number? + */ else { @@ -326,7 +333,7 @@ int tiff_putstring(int fd, FAR const char *string, int len) #ifdef CONFIG_DEBUG_GRAPHICS int actual = strlen(string); - DEBUGASSERT(len = actual+1); + DEBUGASSERT(len == actual + 1); #endif return tiff_write(fd, string, len); } @@ -362,7 +369,9 @@ ssize_t tiff_wordalign(int fd, size_t size) { return (ssize_t)ret; } + size += nbytes; } + return size; } diff --git a/system/nxcamera/nxcamera.c b/system/nxcamera/nxcamera.c index d698b9e20..b8f5d41aa 100644 --- a/system/nxcamera/nxcamera.c +++ b/system/nxcamera/nxcamera.c @@ -52,6 +52,10 @@ #ifdef CONFIG_LIBYUV # include + +# define CONVERT_TO_ARGB ConvertToARGB +# define CONVERT_FROM_I420 ConvertFromI420 +# define CONVERT_TO_I420 ConvertToI420 #endif /**************************************************************************** @@ -91,38 +95,38 @@ static int show_image(FAR struct nxcamera_s *pcam, FAR v4l2_buffer_t *buf) #ifdef CONFIG_LIBYUV if (pcam->display_vinfo.fmt == FB_FMT_RGB32) { - return ConvertToARGB(pcam->bufs[buf->index], - pcam->buf_sizes[buf->index], - pcam->display_pinfo.fbmem, - pcam->display_pinfo.stride, - 0, - 0, - pcam->fmt.fmt.pix.width, - pcam->fmt.fmt.pix.height, - pcam->fmt.fmt.pix.width, - pcam->fmt.fmt.pix.height, - 0, - pcam->fmt.fmt.pix.pixelformat); + return CONVERT_TO_ARGB(pcam->bufs[buf->index], + pcam->buf_sizes[buf->index], + pcam->display_pinfo.fbmem, + pcam->display_pinfo.stride, + 0, + 0, + pcam->fmt.fmt.pix.width, + pcam->fmt.fmt.pix.height, + pcam->fmt.fmt.pix.width, + pcam->fmt.fmt.pix.height, + 0, + pcam->fmt.fmt.pix.pixelformat); } else if (pcam->display_vinfo.fmt == FB_FMT_RGB16_565) { if (pcam->fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) { - return ConvertFromI420(pcam->bufs[buf->index], - pcam->fmt.fmt.pix.width, - &pcam->bufs[buf->index][ - pcam->fmt.fmt.pix.width * - pcam->fmt.fmt.pix.height], - pcam->fmt.fmt.pix.width / 2, - &pcam->bufs[buf->index][ - pcam->fmt.fmt.pix.width * - pcam->fmt.fmt.pix.height * 5 / 4], - pcam->fmt.fmt.pix.width / 2, - pcam->display_pinfo.fbmem, - pcam->display_pinfo.stride, - pcam->fmt.fmt.pix.width, - pcam->fmt.fmt.pix.height, - V4L2_PIX_FMT_RGB565); + return CONVERT_FROM_I420(pcam->bufs[buf->index], + pcam->fmt.fmt.pix.width, + &pcam->bufs[buf->index][ + pcam->fmt.fmt.pix.width * + pcam->fmt.fmt.pix.height], + pcam->fmt.fmt.pix.width / 2, + &pcam->bufs[buf->index][ + pcam->fmt.fmt.pix.width * + pcam->fmt.fmt.pix.height * 5 / 4], + pcam->fmt.fmt.pix.width / 2, + pcam->display_pinfo.fbmem, + pcam->display_pinfo.stride, + pcam->fmt.fmt.pix.width, + pcam->fmt.fmt.pix.height, + V4L2_PIX_FMT_RGB565); } else { @@ -134,42 +138,42 @@ static int show_image(FAR struct nxcamera_s *pcam, FAR v4l2_buffer_t *buf) return -ENOMEM; } - ret = ConvertToI420(pcam->bufs[buf->index], - pcam->buf_sizes[buf->index], - dst, - pcam->fmt.fmt.pix.width, - &dst[pcam->fmt.fmt.pix.width * - pcam->fmt.fmt.pix.height], - pcam->fmt.fmt.pix.width / 2, - &dst[pcam->fmt.fmt.pix.width * - pcam->fmt.fmt.pix.height * 5 / 4], - pcam->fmt.fmt.pix.width / 2, - 0, - 0, - pcam->fmt.fmt.pix.width, - pcam->fmt.fmt.pix.height, - pcam->fmt.fmt.pix.width, - pcam->fmt.fmt.pix.height, - 0, - pcam->fmt.fmt.pix.pixelformat); + ret = CONVERT_TO_I420(pcam->bufs[buf->index], + pcam->buf_sizes[buf->index], + dst, + pcam->fmt.fmt.pix.width, + &dst[pcam->fmt.fmt.pix.width * + pcam->fmt.fmt.pix.height], + pcam->fmt.fmt.pix.width / 2, + &dst[pcam->fmt.fmt.pix.width * + pcam->fmt.fmt.pix.height * 5 / 4], + pcam->fmt.fmt.pix.width / 2, + 0, + 0, + pcam->fmt.fmt.pix.width, + pcam->fmt.fmt.pix.height, + pcam->fmt.fmt.pix.width, + pcam->fmt.fmt.pix.height, + 0, + pcam->fmt.fmt.pix.pixelformat); if (ret < 0) { goto err; } - ret = ConvertFromI420(dst, - pcam->fmt.fmt.pix.width, - &dst[pcam->fmt.fmt.pix.width * - pcam->fmt.fmt.pix.height], - pcam->fmt.fmt.pix.width / 2, - &dst[pcam->fmt.fmt.pix.width * - pcam->fmt.fmt.pix.height * 5 / 4], - pcam->fmt.fmt.pix.width / 2, - pcam->display_pinfo.fbmem, - pcam->display_pinfo.stride, - pcam->fmt.fmt.pix.width, - pcam->fmt.fmt.pix.height, - V4L2_PIX_FMT_RGB565); + ret = CONVERT_FROM_I420(dst, + pcam->fmt.fmt.pix.width, + &dst[pcam->fmt.fmt.pix.width * + pcam->fmt.fmt.pix.height], + pcam->fmt.fmt.pix.width / 2, + &dst[pcam->fmt.fmt.pix.width * + pcam->fmt.fmt.pix.height * 5 / 4], + pcam->fmt.fmt.pix.width / 2, + pcam->display_pinfo.fbmem, + pcam->display_pinfo.stride, + pcam->fmt.fmt.pix.width, + pcam->fmt.fmt.pix.height, + V4L2_PIX_FMT_RGB565); if (ret < 0) { goto err; From 7dc8cec1ac0f151e13ce37e57256bff377de9cb7 Mon Sep 17 00:00:00 2001 From: Michal Lenc Date: Sun, 12 Apr 2026 14:33:32 +0200 Subject: [PATCH 289/568] examples/hello_nim/Kconfig: name consistent with other Hello World apps Use "Hello, language" scheme to keep the naming consistency with other Hello World applications for different languages. Signed-off-by: Michal Lenc --- examples/hello_nim/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/hello_nim/Kconfig b/examples/hello_nim/Kconfig index a34c8fcdb..e955ef88f 100644 --- a/examples/hello_nim/Kconfig +++ b/examples/hello_nim/Kconfig @@ -4,10 +4,10 @@ # config EXAMPLES_HELLO_NIM - tristate "\"Hello, World!\" example (Nim)" + tristate "\"Hello, Nim!\" example" default n ---help--- - Enable the \"Hello, World!\" example + Enable the \"Hello, Nim!\" example in Nim language if EXAMPLES_HELLO_NIM From a6c11a1db70472eb74e723f0041012759971a8ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 22:47:22 +0000 Subject: [PATCH 290/568] build(deps): bump actions/github-script from 8.0.0 to 9.0.0 Bumps [actions/github-script](https://github.com/actions/github-script) from 8.0.0 to 9.0.0. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v8...v9) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: 9.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/issue_labeler.yml | 2 +- .github/workflows/labeler.yml | 2 +- .github/workflows/pr_labeler.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/issue_labeler.yml b/.github/workflows/issue_labeler.yml index 2363ece67..2965bf5a6 100644 --- a/.github/workflows/issue_labeler.yml +++ b/.github/workflows/issue_labeler.yml @@ -23,7 +23,7 @@ jobs: issues: write steps: - name: Add labels issues automatically based on their body. - uses: actions/github-script@v8 + uses: actions/github-script@v9.0.0 with: script: | const body = context.payload.issue.body; diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index cd98874b8..cafc52676 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -45,7 +45,7 @@ jobs: # Fetch the updated PR filenames. Compute the Size Label and Arch Labels. - name: Compute PR labels - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/pr_labeler.yml b/.github/workflows/pr_labeler.yml index f8af53e05..26ed16441 100644 --- a/.github/workflows/pr_labeler.yml +++ b/.github/workflows/pr_labeler.yml @@ -38,7 +38,7 @@ jobs: steps: # Download the PR Artifact, containing PR Number and PR Labels - name: Download PR artifact - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ @@ -64,7 +64,7 @@ jobs: # Write the PR Labels into the PR - name: Write PR labels - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | From f22a8d0d4fd44c351b04ade9a7a7f1b14304f028 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 22:47:19 +0000 Subject: [PATCH 291/568] build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v7...v7.0.1) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/labeler.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f4f33fda9..740d6f81d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,7 +106,7 @@ jobs: run: tar zcf sources.tar.gz sources - name: Archive Source Bundle - uses: actions/upload-artifact@v7.0.0 + uses: actions/upload-artifact@v7.0.1 with: name: source-bundle path: sources.tar.gz @@ -207,7 +207,7 @@ jobs: if: always() run: df -h - - uses: actions/upload-artifact@v7.0.0 + - uses: actions/upload-artifact@v7.0.1 if: ${{ always() }} with: name: linux-${{matrix.boards}}-builds @@ -252,7 +252,7 @@ jobs: cd sources/nuttx ./tools/ci/cibuild-oot.sh - - uses: actions/upload-artifact@v7.0.0 + - uses: actions/upload-artifact@v7.0.1 if: ${{ always() }} with: name: oot-build-artifacts @@ -313,7 +313,7 @@ jobs: cd sources/nuttx/tools/ci ./cibuild.sh -i -c -A -R testlist/${{matrix.boards}}.dat - - uses: actions/upload-artifact@v7.0.0 + - uses: actions/upload-artifact@v7.0.1 with: name: macos-${{matrix.boards}}-builds path: buildartifacts/ @@ -396,7 +396,7 @@ jobs: cd sources/nuttx/tools/ci ./cibuild.sh -g -i -A -C -N -R testlist/${{matrix.boards}}.dat - - uses: actions/upload-artifact@v7.0.0 + - uses: actions/upload-artifact@v7.0.1 with: name: msys2-${{matrix.boards}}-builds path: buildartifacts/ @@ -448,7 +448,7 @@ jobs: cd sources\nuttx\tools\ci .\cibuild.ps1 -n -i -A -C -N testlist\windows.dat - - uses: actions/upload-artifact@v7.0.0 + - uses: actions/upload-artifact@v7.0.1 with: name: msvc-builds path: ./sources/buildartifacts/ diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index cafc52676..224911be2 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -144,7 +144,7 @@ jobs: # Upload the PR Artifact as pr.zip - name: Upload PR artifact - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: pr path: pr/ From 722f3193ceb43b11fe7f2d2172402867c48b4f3e Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 13 Apr 2026 12:07:12 +0200 Subject: [PATCH 292/568] modbus: move freemodbus to a separate directory move freemodbus to modbus/freemodbus so it is possible to add other modbus implementations Signed-off-by: raiden00pl --- modbus/.gitignore | 1 + modbus/CMakeLists.txt | 80 +------------- modbus/Make.defs | 4 +- modbus/Makefile | 24 +---- modbus/freemodbus/CMakeLists.txt | 101 ++++++++++++++++++ modbus/{ => freemodbus}/Kconfig | 0 modbus/freemodbus/Make.defs | 25 +++++ modbus/freemodbus/Makefile | 45 ++++++++ modbus/{ => freemodbus}/ascii/Make.defs | 4 +- modbus/{ => freemodbus}/ascii/mbascii.c | 0 modbus/{ => freemodbus}/ascii/mbascii.h | 0 modbus/{ => freemodbus}/functions/Make.defs | 4 +- .../{ => freemodbus}/functions/mbfunccoils.c | 0 .../functions/mbfunccoils_m.c | 0 .../{ => freemodbus}/functions/mbfuncdiag.c | 0 .../{ => freemodbus}/functions/mbfuncdisc.c | 0 .../{ => freemodbus}/functions/mbfuncdisc_m.c | 0 .../functions/mbfuncholding.c | 0 .../functions/mbfuncholding_m.c | 0 .../{ => freemodbus}/functions/mbfuncinput.c | 0 .../functions/mbfuncinput_m.c | 0 .../{ => freemodbus}/functions/mbfuncother.c | 0 modbus/{ => freemodbus}/functions/mbutils.c | 0 modbus/{ => freemodbus}/mb.c | 0 modbus/{ => freemodbus}/mb_m.c | 0 modbus/{ => freemodbus}/nuttx/Make.defs | 4 +- modbus/{ => freemodbus}/nuttx/port.h | 0 modbus/{ => freemodbus}/nuttx/portevent.c | 0 modbus/{ => freemodbus}/nuttx/portevent_m.c | 0 modbus/{ => freemodbus}/nuttx/portother.c | 0 modbus/{ => freemodbus}/nuttx/portother_m.c | 0 modbus/{ => freemodbus}/nuttx/portserial.c | 0 modbus/{ => freemodbus}/nuttx/portserial_m.c | 0 modbus/{ => freemodbus}/nuttx/porttimer.c | 0 modbus/{ => freemodbus}/nuttx/porttimer_m.c | 0 modbus/{ => freemodbus}/rtu/Make.defs | 4 +- modbus/{ => freemodbus}/rtu/mbcrc.c | 0 modbus/{ => freemodbus}/rtu/mbcrc.h | 0 modbus/{ => freemodbus}/rtu/mbrtu.c | 0 modbus/{ => freemodbus}/rtu/mbrtu.h | 0 modbus/{ => freemodbus}/rtu/mbrtu_m.c | 0 modbus/{ => freemodbus}/rtu/mbrtu_m.h | 0 modbus/{ => freemodbus}/tcp/Make.defs | 4 +- modbus/{ => freemodbus}/tcp/mbtcp.c | 0 modbus/{ => freemodbus}/tcp/mbtcp.h | 0 45 files changed, 187 insertions(+), 113 deletions(-) create mode 100644 modbus/.gitignore create mode 100644 modbus/freemodbus/CMakeLists.txt rename modbus/{ => freemodbus}/Kconfig (100%) create mode 100644 modbus/freemodbus/Make.defs create mode 100644 modbus/freemodbus/Makefile rename modbus/{ => freemodbus}/ascii/Make.defs (91%) rename modbus/{ => freemodbus}/ascii/mbascii.c (100%) rename modbus/{ => freemodbus}/ascii/mbascii.h (100%) rename modbus/{ => freemodbus}/functions/Make.defs (92%) rename modbus/{ => freemodbus}/functions/mbfunccoils.c (100%) rename modbus/{ => freemodbus}/functions/mbfunccoils_m.c (100%) rename modbus/{ => freemodbus}/functions/mbfuncdiag.c (100%) rename modbus/{ => freemodbus}/functions/mbfuncdisc.c (100%) rename modbus/{ => freemodbus}/functions/mbfuncdisc_m.c (100%) rename modbus/{ => freemodbus}/functions/mbfuncholding.c (100%) rename modbus/{ => freemodbus}/functions/mbfuncholding_m.c (100%) rename modbus/{ => freemodbus}/functions/mbfuncinput.c (100%) rename modbus/{ => freemodbus}/functions/mbfuncinput_m.c (100%) rename modbus/{ => freemodbus}/functions/mbfuncother.c (100%) rename modbus/{ => freemodbus}/functions/mbutils.c (100%) rename modbus/{ => freemodbus}/mb.c (100%) rename modbus/{ => freemodbus}/mb_m.c (100%) rename modbus/{ => freemodbus}/nuttx/Make.defs (92%) rename modbus/{ => freemodbus}/nuttx/port.h (100%) rename modbus/{ => freemodbus}/nuttx/portevent.c (100%) rename modbus/{ => freemodbus}/nuttx/portevent_m.c (100%) rename modbus/{ => freemodbus}/nuttx/portother.c (100%) rename modbus/{ => freemodbus}/nuttx/portother_m.c (100%) rename modbus/{ => freemodbus}/nuttx/portserial.c (100%) rename modbus/{ => freemodbus}/nuttx/portserial_m.c (100%) rename modbus/{ => freemodbus}/nuttx/porttimer.c (100%) rename modbus/{ => freemodbus}/nuttx/porttimer_m.c (100%) rename modbus/{ => freemodbus}/rtu/Make.defs (93%) rename modbus/{ => freemodbus}/rtu/mbcrc.c (100%) rename modbus/{ => freemodbus}/rtu/mbcrc.h (100%) rename modbus/{ => freemodbus}/rtu/mbrtu.c (100%) rename modbus/{ => freemodbus}/rtu/mbrtu.h (100%) rename modbus/{ => freemodbus}/rtu/mbrtu_m.c (100%) rename modbus/{ => freemodbus}/rtu/mbrtu_m.h (100%) rename modbus/{ => freemodbus}/tcp/Make.defs (91%) rename modbus/{ => freemodbus}/tcp/mbtcp.c (100%) rename modbus/{ => freemodbus}/tcp/mbtcp.h (100%) diff --git a/modbus/.gitignore b/modbus/.gitignore new file mode 100644 index 000000000..9e1d2593e --- /dev/null +++ b/modbus/.gitignore @@ -0,0 +1 @@ +/Kconfig diff --git a/modbus/CMakeLists.txt b/modbus/CMakeLists.txt index edba762df..781050084 100644 --- a/modbus/CMakeLists.txt +++ b/modbus/CMakeLists.txt @@ -20,82 +20,6 @@ # # ############################################################################## -if(CONFIG_MODBUS) +nuttx_add_subdirectory() - set(CSRCS) - - if(CONFIG_MODBUS_SLAVE) - list(APPEND CSRCS mb.c) - endif() - - if(CONFIG_MB_RTU_MASTER) - list(APPEND CSRCS mb_m.c) - endif() - - # ascii/Make.defs - - if(CONFIG_MB_ASCII_ENABLED) - list(APPEND CSRCS ascii/mbascii.c) - endif() - - # functions/Make.defs - - list( - APPEND - CSRCS - functions/mbfunccoils.c - functions/mbfuncdiag.c - functions/mbfuncdisc.c - functions/mbfuncholding.c - functions/mbfuncinput.c - functions/mbfuncother.c - functions/mbutils.c) - - if(CONFIG_MB_ASCII_MASTER) - list(APPEND CSRCS functions/mbfunccoils_m.c functions/mbfuncdisc_m.c - functions/mbfuncholding_m.c functions/mbfuncinput_m.c) - elseif(CONFIG_MB_RTU_MASTER) - list(APPEND CSRCS functions/mbfunccoils_m.c functions/mbfuncdisc_m.c - functions/mbfuncholding_m.c functions/mbfuncinput_m.c) - endif() - - # nuttx/Make.defs - - list(APPEND CSRCS nuttx/portother.c) - - if(CONFIG_MODBUS_SLAVE) - list(APPEND CSRCS nuttx/portevent.c nuttx/portserial.c nuttx/porttimer.c) - endif() - - if(CONFIG_MB_RTU_MASTER) - list(APPEND CSRCS nuttx/portother_m.c nuttx/portserial_m.c - nuttx/porttimer_m.c nuttx/portevent_m.c) - endif() - - # rtu/Make.defs - - if(CONFIG_MB_RTU_ENABLED OR CONFIG_MB_RTU_MASTER) - list(APPEND CSRCS rtu/mbcrc.c) - if(CONFIG_MB_RTU_ENABLED) - list(APPEND CSRCS rtu/mbrtu.c) - endif() - - if(CONFIG_MB_RTU_MASTER) - list(APPEND CSRCS rtu/mbrtu_m.c) - endif() - endif() - - # tcp/Make.defs - - if(CONFIG_MB_TCP_ENABLED) - list(APPEND CSRCS tcp/mbtcp.c) - endif() - - # include private headers - - target_include_directories(apps PRIVATE nuttx) - target_include_directories(apps PRIVATE rtu) - - target_sources(apps PRIVATE ${CSRCS}) - -endif() +nuttx_generate_kconfig(MENUDESC "Modbus") diff --git a/modbus/Make.defs b/modbus/Make.defs index 10fd914c3..03e07693a 100644 --- a/modbus/Make.defs +++ b/modbus/Make.defs @@ -20,6 +20,4 @@ # ############################################################################ -ifneq ($(CONFIG_MODBUS),) -CONFIGURED_APPS += $(APPDIR)/modbus -endif +include $(wildcard $(APPDIR)/modbus/*/Make.defs) diff --git a/modbus/Makefile b/modbus/Makefile index ce7eac1d5..5858b4b4a 100644 --- a/modbus/Makefile +++ b/modbus/Makefile @@ -20,26 +20,6 @@ # ############################################################################ -include $(APPDIR)/Make.defs +MENUDESC = "Modbus" -# FreeModBus Library - -ifeq ($(CONFIG_MODBUS),y) - - ifeq ($(CONFIG_MODBUS_SLAVE),y) - CSRCS += mb.c - endif - - ifeq ($(CONFIG_MB_RTU_MASTER),y) - CSRCS += mb_m.c - endif - - include ascii/Make.defs - include functions/Make.defs - include nuttx/Make.defs - include rtu/Make.defs - include tcp/Make.defs - -endif - -include $(APPDIR)/Application.mk +include $(APPDIR)/Directory.mk diff --git a/modbus/freemodbus/CMakeLists.txt b/modbus/freemodbus/CMakeLists.txt new file mode 100644 index 000000000..a9980f597 --- /dev/null +++ b/modbus/freemodbus/CMakeLists.txt @@ -0,0 +1,101 @@ +# ############################################################################## +# apps/modbus/freemodbus/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_MODBUS) + + set(CSRCS) + + if(CONFIG_MODBUS_SLAVE) + list(APPEND CSRCS mb.c) + endif() + + if(CONFIG_MB_RTU_MASTER) + list(APPEND CSRCS mb_m.c) + endif() + + # ascii/Make.defs + + if(CONFIG_MB_ASCII_ENABLED) + list(APPEND CSRCS ascii/mbascii.c) + endif() + + # functions/Make.defs + + list( + APPEND + CSRCS + functions/mbfunccoils.c + functions/mbfuncdiag.c + functions/mbfuncdisc.c + functions/mbfuncholding.c + functions/mbfuncinput.c + functions/mbfuncother.c + functions/mbutils.c) + + if(CONFIG_MB_ASCII_MASTER) + list(APPEND CSRCS functions/mbfunccoils_m.c functions/mbfuncdisc_m.c + functions/mbfuncholding_m.c functions/mbfuncinput_m.c) + elseif(CONFIG_MB_RTU_MASTER) + list(APPEND CSRCS functions/mbfunccoils_m.c functions/mbfuncdisc_m.c + functions/mbfuncholding_m.c functions/mbfuncinput_m.c) + endif() + + # nuttx/Make.defs + + list(APPEND CSRCS nuttx/portother.c) + + if(CONFIG_MODBUS_SLAVE) + list(APPEND CSRCS nuttx/portevent.c nuttx/portserial.c nuttx/porttimer.c) + endif() + + if(CONFIG_MB_RTU_MASTER) + list(APPEND CSRCS nuttx/portother_m.c nuttx/portserial_m.c + nuttx/porttimer_m.c nuttx/portevent_m.c) + endif() + + # rtu/Make.defs + + if(CONFIG_MB_RTU_ENABLED OR CONFIG_MB_RTU_MASTER) + list(APPEND CSRCS rtu/mbcrc.c) + if(CONFIG_MB_RTU_ENABLED) + list(APPEND CSRCS rtu/mbrtu.c) + endif() + + if(CONFIG_MB_RTU_MASTER) + list(APPEND CSRCS rtu/mbrtu_m.c) + endif() + endif() + + # tcp/Make.defs + + if(CONFIG_MB_TCP_ENABLED) + list(APPEND CSRCS tcp/mbtcp.c) + endif() + + # include private headers + + target_include_directories(apps PRIVATE nuttx) + target_include_directories(apps PRIVATE rtu) + + target_sources(apps PRIVATE ${CSRCS}) + +endif() diff --git a/modbus/Kconfig b/modbus/freemodbus/Kconfig similarity index 100% rename from modbus/Kconfig rename to modbus/freemodbus/Kconfig diff --git a/modbus/freemodbus/Make.defs b/modbus/freemodbus/Make.defs new file mode 100644 index 000000000..6eac9db77 --- /dev/null +++ b/modbus/freemodbus/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/modbus/freemodbus/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_MODBUS),) +CONFIGURED_APPS += $(APPDIR)/modbus/freemodbus +endif diff --git a/modbus/freemodbus/Makefile b/modbus/freemodbus/Makefile new file mode 100644 index 000000000..6d45f7650 --- /dev/null +++ b/modbus/freemodbus/Makefile @@ -0,0 +1,45 @@ +############################################################################ +# apps/modbus/freemodbus/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# FreeModBus Library + +ifeq ($(CONFIG_MODBUS),y) + + ifeq ($(CONFIG_MODBUS_SLAVE),y) + CSRCS += mb.c + endif + + ifeq ($(CONFIG_MB_RTU_MASTER),y) + CSRCS += mb_m.c + endif + + include ascii/Make.defs + include functions/Make.defs + include nuttx/Make.defs + include rtu/Make.defs + include tcp/Make.defs + +endif + +include $(APPDIR)/Application.mk diff --git a/modbus/ascii/Make.defs b/modbus/freemodbus/ascii/Make.defs similarity index 91% rename from modbus/ascii/Make.defs rename to modbus/freemodbus/ascii/Make.defs index 972cd903f..2f2745828 100644 --- a/modbus/ascii/Make.defs +++ b/modbus/freemodbus/ascii/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/ascii/Make.defs +# apps/modbus/freemodbus/ascii/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -26,6 +26,6 @@ CSRCS += mbascii.c DEPPATH += --dep-path ascii VPATH += :ascii -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/ascii +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/ascii endif diff --git a/modbus/ascii/mbascii.c b/modbus/freemodbus/ascii/mbascii.c similarity index 100% rename from modbus/ascii/mbascii.c rename to modbus/freemodbus/ascii/mbascii.c diff --git a/modbus/ascii/mbascii.h b/modbus/freemodbus/ascii/mbascii.h similarity index 100% rename from modbus/ascii/mbascii.h rename to modbus/freemodbus/ascii/mbascii.h diff --git a/modbus/functions/Make.defs b/modbus/freemodbus/functions/Make.defs similarity index 92% rename from modbus/functions/Make.defs rename to modbus/freemodbus/functions/Make.defs index a4e6ea90c..c59393a2a 100644 --- a/modbus/functions/Make.defs +++ b/modbus/freemodbus/functions/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/functions/Make.defs +# apps/modbus/freemodbus/functions/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -33,4 +33,4 @@ endif DEPPATH += --dep-path functions VPATH += :functions -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/functions +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/functions diff --git a/modbus/functions/mbfunccoils.c b/modbus/freemodbus/functions/mbfunccoils.c similarity index 100% rename from modbus/functions/mbfunccoils.c rename to modbus/freemodbus/functions/mbfunccoils.c diff --git a/modbus/functions/mbfunccoils_m.c b/modbus/freemodbus/functions/mbfunccoils_m.c similarity index 100% rename from modbus/functions/mbfunccoils_m.c rename to modbus/freemodbus/functions/mbfunccoils_m.c diff --git a/modbus/functions/mbfuncdiag.c b/modbus/freemodbus/functions/mbfuncdiag.c similarity index 100% rename from modbus/functions/mbfuncdiag.c rename to modbus/freemodbus/functions/mbfuncdiag.c diff --git a/modbus/functions/mbfuncdisc.c b/modbus/freemodbus/functions/mbfuncdisc.c similarity index 100% rename from modbus/functions/mbfuncdisc.c rename to modbus/freemodbus/functions/mbfuncdisc.c diff --git a/modbus/functions/mbfuncdisc_m.c b/modbus/freemodbus/functions/mbfuncdisc_m.c similarity index 100% rename from modbus/functions/mbfuncdisc_m.c rename to modbus/freemodbus/functions/mbfuncdisc_m.c diff --git a/modbus/functions/mbfuncholding.c b/modbus/freemodbus/functions/mbfuncholding.c similarity index 100% rename from modbus/functions/mbfuncholding.c rename to modbus/freemodbus/functions/mbfuncholding.c diff --git a/modbus/functions/mbfuncholding_m.c b/modbus/freemodbus/functions/mbfuncholding_m.c similarity index 100% rename from modbus/functions/mbfuncholding_m.c rename to modbus/freemodbus/functions/mbfuncholding_m.c diff --git a/modbus/functions/mbfuncinput.c b/modbus/freemodbus/functions/mbfuncinput.c similarity index 100% rename from modbus/functions/mbfuncinput.c rename to modbus/freemodbus/functions/mbfuncinput.c diff --git a/modbus/functions/mbfuncinput_m.c b/modbus/freemodbus/functions/mbfuncinput_m.c similarity index 100% rename from modbus/functions/mbfuncinput_m.c rename to modbus/freemodbus/functions/mbfuncinput_m.c diff --git a/modbus/functions/mbfuncother.c b/modbus/freemodbus/functions/mbfuncother.c similarity index 100% rename from modbus/functions/mbfuncother.c rename to modbus/freemodbus/functions/mbfuncother.c diff --git a/modbus/functions/mbutils.c b/modbus/freemodbus/functions/mbutils.c similarity index 100% rename from modbus/functions/mbutils.c rename to modbus/freemodbus/functions/mbutils.c diff --git a/modbus/mb.c b/modbus/freemodbus/mb.c similarity index 100% rename from modbus/mb.c rename to modbus/freemodbus/mb.c diff --git a/modbus/mb_m.c b/modbus/freemodbus/mb_m.c similarity index 100% rename from modbus/mb_m.c rename to modbus/freemodbus/mb_m.c diff --git a/modbus/nuttx/Make.defs b/modbus/freemodbus/nuttx/Make.defs similarity index 92% rename from modbus/nuttx/Make.defs rename to modbus/freemodbus/nuttx/Make.defs index 7960ecee4..723284cc4 100644 --- a/modbus/nuttx/Make.defs +++ b/modbus/freemodbus/nuttx/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/nuttx/Make.defs +# apps/modbus/freemodbus/nuttx/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -32,4 +32,4 @@ endif DEPPATH += --dep-path nuttx VPATH += :nuttx -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/nuttx +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/nuttx diff --git a/modbus/nuttx/port.h b/modbus/freemodbus/nuttx/port.h similarity index 100% rename from modbus/nuttx/port.h rename to modbus/freemodbus/nuttx/port.h diff --git a/modbus/nuttx/portevent.c b/modbus/freemodbus/nuttx/portevent.c similarity index 100% rename from modbus/nuttx/portevent.c rename to modbus/freemodbus/nuttx/portevent.c diff --git a/modbus/nuttx/portevent_m.c b/modbus/freemodbus/nuttx/portevent_m.c similarity index 100% rename from modbus/nuttx/portevent_m.c rename to modbus/freemodbus/nuttx/portevent_m.c diff --git a/modbus/nuttx/portother.c b/modbus/freemodbus/nuttx/portother.c similarity index 100% rename from modbus/nuttx/portother.c rename to modbus/freemodbus/nuttx/portother.c diff --git a/modbus/nuttx/portother_m.c b/modbus/freemodbus/nuttx/portother_m.c similarity index 100% rename from modbus/nuttx/portother_m.c rename to modbus/freemodbus/nuttx/portother_m.c diff --git a/modbus/nuttx/portserial.c b/modbus/freemodbus/nuttx/portserial.c similarity index 100% rename from modbus/nuttx/portserial.c rename to modbus/freemodbus/nuttx/portserial.c diff --git a/modbus/nuttx/portserial_m.c b/modbus/freemodbus/nuttx/portserial_m.c similarity index 100% rename from modbus/nuttx/portserial_m.c rename to modbus/freemodbus/nuttx/portserial_m.c diff --git a/modbus/nuttx/porttimer.c b/modbus/freemodbus/nuttx/porttimer.c similarity index 100% rename from modbus/nuttx/porttimer.c rename to modbus/freemodbus/nuttx/porttimer.c diff --git a/modbus/nuttx/porttimer_m.c b/modbus/freemodbus/nuttx/porttimer_m.c similarity index 100% rename from modbus/nuttx/porttimer_m.c rename to modbus/freemodbus/nuttx/porttimer_m.c diff --git a/modbus/rtu/Make.defs b/modbus/freemodbus/rtu/Make.defs similarity index 93% rename from modbus/rtu/Make.defs rename to modbus/freemodbus/rtu/Make.defs index ac4ab7e2a..43576f993 100644 --- a/modbus/rtu/Make.defs +++ b/modbus/freemodbus/rtu/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/rtu/Make.defs +# apps/modbus/freemodbus/rtu/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -40,6 +40,6 @@ endif DEPPATH += --dep-path rtu VPATH += :rtu -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/rtu +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/rtu endif diff --git a/modbus/rtu/mbcrc.c b/modbus/freemodbus/rtu/mbcrc.c similarity index 100% rename from modbus/rtu/mbcrc.c rename to modbus/freemodbus/rtu/mbcrc.c diff --git a/modbus/rtu/mbcrc.h b/modbus/freemodbus/rtu/mbcrc.h similarity index 100% rename from modbus/rtu/mbcrc.h rename to modbus/freemodbus/rtu/mbcrc.h diff --git a/modbus/rtu/mbrtu.c b/modbus/freemodbus/rtu/mbrtu.c similarity index 100% rename from modbus/rtu/mbrtu.c rename to modbus/freemodbus/rtu/mbrtu.c diff --git a/modbus/rtu/mbrtu.h b/modbus/freemodbus/rtu/mbrtu.h similarity index 100% rename from modbus/rtu/mbrtu.h rename to modbus/freemodbus/rtu/mbrtu.h diff --git a/modbus/rtu/mbrtu_m.c b/modbus/freemodbus/rtu/mbrtu_m.c similarity index 100% rename from modbus/rtu/mbrtu_m.c rename to modbus/freemodbus/rtu/mbrtu_m.c diff --git a/modbus/rtu/mbrtu_m.h b/modbus/freemodbus/rtu/mbrtu_m.h similarity index 100% rename from modbus/rtu/mbrtu_m.h rename to modbus/freemodbus/rtu/mbrtu_m.h diff --git a/modbus/tcp/Make.defs b/modbus/freemodbus/tcp/Make.defs similarity index 91% rename from modbus/tcp/Make.defs rename to modbus/freemodbus/tcp/Make.defs index dfd220f41..b9f82c6de 100644 --- a/modbus/tcp/Make.defs +++ b/modbus/freemodbus/tcp/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/tcp/Make.defs +# apps/modbus/freemodbus/tcp/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -26,6 +26,6 @@ CSRCS += mbtcp.c DEPPATH += --dep-path tcp VPATH += :tcp -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/tcp +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/tcp endif diff --git a/modbus/tcp/mbtcp.c b/modbus/freemodbus/tcp/mbtcp.c similarity index 100% rename from modbus/tcp/mbtcp.c rename to modbus/freemodbus/tcp/mbtcp.c diff --git a/modbus/tcp/mbtcp.h b/modbus/freemodbus/tcp/mbtcp.h similarity index 100% rename from modbus/tcp/mbtcp.h rename to modbus/freemodbus/tcp/mbtcp.h From 8e9f5a8d3aa318fb9b3fb67db3577fac7cf84116 Mon Sep 17 00:00:00 2001 From: Michal Lenc Date: Fri, 17 Apr 2026 11:57:40 +0200 Subject: [PATCH 293/568] nshlib/nsh_timcmds.c: fix incorrect time set during summer time Value zero in tm_isdst means daylight saving time (or summer time) is not in effect. This is obviously not true for half of the year in most timezones and keeping it at zero leads to incorrect time being set. This commit sets tm_isdst to -1, which means the information is not available and it should be handled according to timezone rules. Signed-off-by: Michal Lenc --- nshlib/nsh_timcmds.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nshlib/nsh_timcmds.c b/nshlib/nsh_timcmds.c index a0952acc1..de5dd8adf 100644 --- a/nshlib/nsh_timcmds.c +++ b/nshlib/nsh_timcmds.c @@ -265,6 +265,10 @@ static inline int date_settime(FAR struct nsh_vtbl_s *vtbl, tm.tm_year = (int)result - 1900; + /* Information about daylight saving not available -> let TZ handle it */ + + tm.tm_isdst = -1; + /* Convert this to the right form, then set the timer */ ts.tv_sec = utc ? timegm(&tm): mktime(&tm); From 2ee08209a099718be0cfbbc9846c91fee9a4e7e8 Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Wed, 15 Apr 2026 09:44:45 -0300 Subject: [PATCH 294/568] apps/modbus: Move modbus to inside industry/ Modbus is a protocol mostly used on industries and since it is a protocol it is not a category to be at root of apps/ Signed-off-by: Alan C. Assis --- {modbus => industry/modbus}/.gitignore | 0 {modbus => industry/modbus}/CMakeLists.txt | 2 +- {modbus => industry/modbus}/Make.defs | 2 +- {modbus => industry/modbus}/Makefile | 2 +- .../modbus}/freemodbus/CMakeLists.txt | 8 ++++---- {modbus => industry/modbus}/freemodbus/Kconfig | 14 +++++++------- {modbus => industry/modbus}/freemodbus/Make.defs | 6 +++--- {modbus => industry/modbus}/freemodbus/Makefile | 6 +++--- .../modbus}/freemodbus/ascii/Make.defs | 4 ++-- .../modbus}/freemodbus/ascii/mbascii.c | 2 +- .../modbus}/freemodbus/ascii/mbascii.h | 2 +- .../modbus}/freemodbus/functions/Make.defs | 4 ++-- .../modbus}/freemodbus/functions/mbfunccoils.c | 0 .../modbus}/freemodbus/functions/mbfunccoils_m.c | 2 +- .../modbus}/freemodbus/functions/mbfuncdiag.c | 2 +- .../modbus}/freemodbus/functions/mbfuncdisc.c | 0 .../modbus}/freemodbus/functions/mbfuncdisc_m.c | 2 +- .../modbus}/freemodbus/functions/mbfuncholding.c | 0 .../modbus}/freemodbus/functions/mbfuncholding_m.c | 2 +- .../modbus}/freemodbus/functions/mbfuncinput.c | 0 .../modbus}/freemodbus/functions/mbfuncinput_m.c | 2 +- .../modbus}/freemodbus/functions/mbfuncother.c | 0 .../modbus}/freemodbus/functions/mbutils.c | 0 {modbus => industry/modbus}/freemodbus/mb.c | 2 +- {modbus => industry/modbus}/freemodbus/mb_m.c | 0 .../modbus}/freemodbus/nuttx/Make.defs | 6 +++--- .../modbus}/freemodbus/nuttx/port.h | 10 +++++----- .../modbus}/freemodbus/nuttx/portevent.c | 2 +- .../modbus}/freemodbus/nuttx/portevent_m.c | 2 +- .../modbus}/freemodbus/nuttx/portother.c | 4 ++-- .../modbus}/freemodbus/nuttx/portother_m.c | 2 +- .../modbus}/freemodbus/nuttx/portserial.c | 2 +- .../modbus}/freemodbus/nuttx/portserial_m.c | 2 +- .../modbus}/freemodbus/nuttx/porttimer.c | 2 +- .../modbus}/freemodbus/nuttx/porttimer_m.c | 2 +- .../modbus}/freemodbus/rtu/Make.defs | 4 ++-- {modbus => industry/modbus}/freemodbus/rtu/mbcrc.c | 2 +- {modbus => industry/modbus}/freemodbus/rtu/mbcrc.h | 0 {modbus => industry/modbus}/freemodbus/rtu/mbrtu.c | 2 +- {modbus => industry/modbus}/freemodbus/rtu/mbrtu.h | 2 +- .../modbus}/freemodbus/rtu/mbrtu_m.c | 2 +- .../modbus}/freemodbus/rtu/mbrtu_m.h | 2 +- .../modbus}/freemodbus/tcp/Make.defs | 4 ++-- {modbus => industry/modbus}/freemodbus/tcp/mbtcp.c | 2 +- {modbus => industry/modbus}/freemodbus/tcp/mbtcp.h | 2 +- 45 files changed, 60 insertions(+), 60 deletions(-) rename {modbus => industry/modbus}/.gitignore (100%) rename {modbus => industry/modbus}/CMakeLists.txt (96%) rename {modbus => industry/modbus}/Make.defs (96%) rename {modbus => industry/modbus}/Makefile (96%) rename {modbus => industry/modbus}/freemodbus/CMakeLists.txt (94%) rename {modbus => industry/modbus}/freemodbus/Kconfig (97%) rename {modbus => industry/modbus}/freemodbus/Make.defs (87%) rename {modbus => industry/modbus}/freemodbus/Makefile (91%) rename {modbus => industry/modbus}/freemodbus/ascii/Make.defs (90%) rename {modbus => industry/modbus}/freemodbus/ascii/mbascii.c (99%) rename {modbus => industry/modbus}/freemodbus/ascii/mbascii.h (98%) rename {modbus => industry/modbus}/freemodbus/functions/Make.defs (91%) rename {modbus => industry/modbus}/freemodbus/functions/mbfunccoils.c (100%) rename {modbus => industry/modbus}/freemodbus/functions/mbfunccoils_m.c (99%) rename {modbus => industry/modbus}/freemodbus/functions/mbfuncdiag.c (97%) rename {modbus => industry/modbus}/freemodbus/functions/mbfuncdisc.c (100%) rename {modbus => industry/modbus}/freemodbus/functions/mbfuncdisc_m.c (99%) rename {modbus => industry/modbus}/freemodbus/functions/mbfuncholding.c (100%) rename {modbus => industry/modbus}/freemodbus/functions/mbfuncholding_m.c (99%) rename {modbus => industry/modbus}/freemodbus/functions/mbfuncinput.c (100%) rename {modbus => industry/modbus}/freemodbus/functions/mbfuncinput_m.c (99%) rename {modbus => industry/modbus}/freemodbus/functions/mbfuncother.c (100%) rename {modbus => industry/modbus}/freemodbus/functions/mbutils.c (100%) rename {modbus => industry/modbus}/freemodbus/mb.c (99%) rename {modbus => industry/modbus}/freemodbus/mb_m.c (100%) rename {modbus => industry/modbus}/freemodbus/nuttx/Make.defs (88%) rename {modbus => industry/modbus}/freemodbus/nuttx/port.h (94%) rename {modbus => industry/modbus}/freemodbus/nuttx/portevent.c (98%) rename {modbus => industry/modbus}/freemodbus/nuttx/portevent_m.c (99%) rename {modbus => industry/modbus}/freemodbus/nuttx/portother.c (97%) rename {modbus => industry/modbus}/freemodbus/nuttx/portother_m.c (98%) rename {modbus => industry/modbus}/freemodbus/nuttx/portserial.c (99%) rename {modbus => industry/modbus}/freemodbus/nuttx/portserial_m.c (99%) rename {modbus => industry/modbus}/freemodbus/nuttx/porttimer.c (98%) rename {modbus => industry/modbus}/freemodbus/nuttx/porttimer_m.c (99%) rename {modbus => industry/modbus}/freemodbus/rtu/Make.defs (91%) rename {modbus => industry/modbus}/freemodbus/rtu/mbcrc.c (99%) rename {modbus => industry/modbus}/freemodbus/rtu/mbcrc.h (100%) rename {modbus => industry/modbus}/freemodbus/rtu/mbrtu.c (99%) rename {modbus => industry/modbus}/freemodbus/rtu/mbrtu.h (98%) rename {modbus => industry/modbus}/freemodbus/rtu/mbrtu_m.c (99%) rename {modbus => industry/modbus}/freemodbus/rtu/mbrtu_m.h (98%) rename {modbus => industry/modbus}/freemodbus/tcp/Make.defs (90%) rename {modbus => industry/modbus}/freemodbus/tcp/mbtcp.c (99%) rename {modbus => industry/modbus}/freemodbus/tcp/mbtcp.h (98%) diff --git a/modbus/.gitignore b/industry/modbus/.gitignore similarity index 100% rename from modbus/.gitignore rename to industry/modbus/.gitignore diff --git a/modbus/CMakeLists.txt b/industry/modbus/CMakeLists.txt similarity index 96% rename from modbus/CMakeLists.txt rename to industry/modbus/CMakeLists.txt index 781050084..89038a9a7 100644 --- a/modbus/CMakeLists.txt +++ b/industry/modbus/CMakeLists.txt @@ -1,5 +1,5 @@ # ############################################################################## -# apps/modbus/CMakeLists.txt +# apps/industry/modbus/CMakeLists.txt # # SPDX-License-Identifier: Apache-2.0 # diff --git a/modbus/Make.defs b/industry/modbus/Make.defs similarity index 96% rename from modbus/Make.defs rename to industry/modbus/Make.defs index 03e07693a..fde0dd716 100644 --- a/modbus/Make.defs +++ b/industry/modbus/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/Make.defs +# apps/industry/modbus/Make.defs # # SPDX-License-Identifier: Apache-2.0 # diff --git a/modbus/Makefile b/industry/modbus/Makefile similarity index 96% rename from modbus/Makefile rename to industry/modbus/Makefile index 5858b4b4a..320c97faf 100644 --- a/modbus/Makefile +++ b/industry/modbus/Makefile @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/Makefile +# apps/industry/modbus/Makefile # # SPDX-License-Identifier: Apache-2.0 # diff --git a/modbus/freemodbus/CMakeLists.txt b/industry/modbus/freemodbus/CMakeLists.txt similarity index 94% rename from modbus/freemodbus/CMakeLists.txt rename to industry/modbus/freemodbus/CMakeLists.txt index a9980f597..d49e6c069 100644 --- a/modbus/freemodbus/CMakeLists.txt +++ b/industry/modbus/freemodbus/CMakeLists.txt @@ -1,5 +1,5 @@ # ############################################################################## -# apps/modbus/freemodbus/CMakeLists.txt +# apps/industry/modbus/freemodbus/CMakeLists.txt # # SPDX-License-Identifier: Apache-2.0 # @@ -20,11 +20,11 @@ # # ############################################################################## -if(CONFIG_MODBUS) +if(CONFIG_INDUSTRY_MODBUS) set(CSRCS) - if(CONFIG_MODBUS_SLAVE) + if(CONFIG_INDUSTRY_MODBUS_SLAVE) list(APPEND CSRCS mb.c) endif() @@ -63,7 +63,7 @@ if(CONFIG_MODBUS) list(APPEND CSRCS nuttx/portother.c) - if(CONFIG_MODBUS_SLAVE) + if(CONFIG_INDUSTRY_MODBUS_SLAVE) list(APPEND CSRCS nuttx/portevent.c nuttx/portserial.c nuttx/porttimer.c) endif() diff --git a/modbus/freemodbus/Kconfig b/industry/modbus/freemodbus/Kconfig similarity index 97% rename from modbus/freemodbus/Kconfig rename to industry/modbus/freemodbus/Kconfig index d891d181c..dd46bbe3c 100644 --- a/modbus/freemodbus/Kconfig +++ b/industry/modbus/freemodbus/Kconfig @@ -4,11 +4,11 @@ # menu "FreeModBus" -config MODBUS +config INDUSTRY_MODBUS bool "Modbus support using FreeModbus" default n -if MODBUS +if INDUSTRY_MODBUS config MB_FUNC_HANDLERS_MAX int "Maximum number of Modbus functions" @@ -20,11 +20,11 @@ config MB_FUNC_HANDLERS_MAX the sum of all enabled functions in this file and custom function handlers. If set to small adding more functions will fail. -config MODBUS_SLAVE +config INDUSTRY_MODBUS_SLAVE bool "Modbus slave support via FreeModBus" default n -if MODBUS_SLAVE +if INDUSTRY_MODBUS_SLAVE config MB_ASCII_ENABLED bool "Modbus ASCII support" default y @@ -144,9 +144,9 @@ config MB_FUNC_READWRITE_HOLDING_ENABLED ---help--- If the Read/Write Multiple Registers function should be enabled. -endif # MODBUS_SLAVE +endif # INDUSTRY_MODBUS_SLAVE -config MODBUS_MASTER +config INDUSTRY_MODBUS_MASTER bool "Modbus Master support via FreeModBus" default n @@ -252,7 +252,7 @@ config MB_MASTER_FUNC_READWRITE_HOLDING_ENABLED endif # MB_ASCII_MASTER || MB_RTU_MASTER endif # MODBUS -config MODBUS_DISABLE_LOG +config INDUSTRY_MODBUS_DISABLE_LOG bool "Disable logging for FreeModBus" default !FILE_STREAM ---help--- diff --git a/modbus/freemodbus/Make.defs b/industry/modbus/freemodbus/Make.defs similarity index 87% rename from modbus/freemodbus/Make.defs rename to industry/modbus/freemodbus/Make.defs index 6eac9db77..7d867a0aa 100644 --- a/modbus/freemodbus/Make.defs +++ b/industry/modbus/freemodbus/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/freemodbus/Make.defs +# apps/industry/modbus/freemodbus/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -20,6 +20,6 @@ # ############################################################################ -ifneq ($(CONFIG_MODBUS),) -CONFIGURED_APPS += $(APPDIR)/modbus/freemodbus +ifneq ($(CONFIG_INDUSTRY_MODBUS),) +CONFIGURED_APPS += $(APPDIR)/industry/modbus/freemodbus endif diff --git a/modbus/freemodbus/Makefile b/industry/modbus/freemodbus/Makefile similarity index 91% rename from modbus/freemodbus/Makefile rename to industry/modbus/freemodbus/Makefile index 6d45f7650..dddb6559a 100644 --- a/modbus/freemodbus/Makefile +++ b/industry/modbus/freemodbus/Makefile @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/freemodbus/Makefile +# apps/industry/modbus/freemodbus/Makefile # # SPDX-License-Identifier: Apache-2.0 # @@ -24,9 +24,9 @@ include $(APPDIR)/Make.defs # FreeModBus Library -ifeq ($(CONFIG_MODBUS),y) +ifeq ($(CONFIG_INDUSTRY_MODBUS),y) - ifeq ($(CONFIG_MODBUS_SLAVE),y) + ifeq ($(CONFIG_INDUSTRY_MODBUS_SLAVE),y) CSRCS += mb.c endif diff --git a/modbus/freemodbus/ascii/Make.defs b/industry/modbus/freemodbus/ascii/Make.defs similarity index 90% rename from modbus/freemodbus/ascii/Make.defs rename to industry/modbus/freemodbus/ascii/Make.defs index 2f2745828..c2fcf2218 100644 --- a/modbus/freemodbus/ascii/Make.defs +++ b/industry/modbus/freemodbus/ascii/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/freemodbus/ascii/Make.defs +# apps/industry/modbus/freemodbus/ascii/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -26,6 +26,6 @@ CSRCS += mbascii.c DEPPATH += --dep-path ascii VPATH += :ascii -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/ascii +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/industry/modbus/freemodbus/ascii endif diff --git a/modbus/freemodbus/ascii/mbascii.c b/industry/modbus/freemodbus/ascii/mbascii.c similarity index 99% rename from modbus/freemodbus/ascii/mbascii.c rename to industry/modbus/freemodbus/ascii/mbascii.c index 3540628ad..d64505125 100644 --- a/modbus/freemodbus/ascii/mbascii.c +++ b/industry/modbus/freemodbus/ascii/mbascii.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/ascii/mbascii.c + * apps/industry/modbus/ascii/mbascii.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/ascii/mbascii.h b/industry/modbus/freemodbus/ascii/mbascii.h similarity index 98% rename from modbus/freemodbus/ascii/mbascii.h rename to industry/modbus/freemodbus/ascii/mbascii.h index 355484103..5351de010 100644 --- a/modbus/freemodbus/ascii/mbascii.h +++ b/industry/modbus/freemodbus/ascii/mbascii.h @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/ascii/mbascii.h + * apps/industry/modbus/ascii/mbascii.h * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/functions/Make.defs b/industry/modbus/freemodbus/functions/Make.defs similarity index 91% rename from modbus/freemodbus/functions/Make.defs rename to industry/modbus/freemodbus/functions/Make.defs index c59393a2a..7c53d5bfc 100644 --- a/modbus/freemodbus/functions/Make.defs +++ b/industry/modbus/freemodbus/functions/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/freemodbus/functions/Make.defs +# apps/industry/modbus/freemodbus/functions/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -33,4 +33,4 @@ endif DEPPATH += --dep-path functions VPATH += :functions -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/functions +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/industry/modbus/freemodbus/functions diff --git a/modbus/freemodbus/functions/mbfunccoils.c b/industry/modbus/freemodbus/functions/mbfunccoils.c similarity index 100% rename from modbus/freemodbus/functions/mbfunccoils.c rename to industry/modbus/freemodbus/functions/mbfunccoils.c diff --git a/modbus/freemodbus/functions/mbfunccoils_m.c b/industry/modbus/freemodbus/functions/mbfunccoils_m.c similarity index 99% rename from modbus/freemodbus/functions/mbfunccoils_m.c rename to industry/modbus/freemodbus/functions/mbfunccoils_m.c index c258d757d..ca59e4caf 100644 --- a/modbus/freemodbus/functions/mbfunccoils_m.c +++ b/industry/modbus/freemodbus/functions/mbfunccoils_m.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/functions/mbfunccoils_m.c + * apps/industry/modbus/functions/mbfunccoils_m.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2013 Armink diff --git a/modbus/freemodbus/functions/mbfuncdiag.c b/industry/modbus/freemodbus/functions/mbfuncdiag.c similarity index 97% rename from modbus/freemodbus/functions/mbfuncdiag.c rename to industry/modbus/freemodbus/functions/mbfuncdiag.c index b34581e6e..c9add6fd4 100644 --- a/modbus/freemodbus/functions/mbfuncdiag.c +++ b/industry/modbus/freemodbus/functions/mbfuncdiag.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/functions/mbfuncdiag.c + * apps/industry/modbus/functions/mbfuncdiag.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/functions/mbfuncdisc.c b/industry/modbus/freemodbus/functions/mbfuncdisc.c similarity index 100% rename from modbus/freemodbus/functions/mbfuncdisc.c rename to industry/modbus/freemodbus/functions/mbfuncdisc.c diff --git a/modbus/freemodbus/functions/mbfuncdisc_m.c b/industry/modbus/freemodbus/functions/mbfuncdisc_m.c similarity index 99% rename from modbus/freemodbus/functions/mbfuncdisc_m.c rename to industry/modbus/freemodbus/functions/mbfuncdisc_m.c index 29386996d..770ab899d 100644 --- a/modbus/freemodbus/functions/mbfuncdisc_m.c +++ b/industry/modbus/freemodbus/functions/mbfuncdisc_m.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/functions/mbfuncdisc_m.c + * apps/industry/modbus/functions/mbfuncdisc_m.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2013 Armink diff --git a/modbus/freemodbus/functions/mbfuncholding.c b/industry/modbus/freemodbus/functions/mbfuncholding.c similarity index 100% rename from modbus/freemodbus/functions/mbfuncholding.c rename to industry/modbus/freemodbus/functions/mbfuncholding.c diff --git a/modbus/freemodbus/functions/mbfuncholding_m.c b/industry/modbus/freemodbus/functions/mbfuncholding_m.c similarity index 99% rename from modbus/freemodbus/functions/mbfuncholding_m.c rename to industry/modbus/freemodbus/functions/mbfuncholding_m.c index b017be715..59be35b26 100644 --- a/modbus/freemodbus/functions/mbfuncholding_m.c +++ b/industry/modbus/freemodbus/functions/mbfuncholding_m.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/functions/mbfuncholding_m.c + * apps/industry/modbus/functions/mbfuncholding_m.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2013 Armink diff --git a/modbus/freemodbus/functions/mbfuncinput.c b/industry/modbus/freemodbus/functions/mbfuncinput.c similarity index 100% rename from modbus/freemodbus/functions/mbfuncinput.c rename to industry/modbus/freemodbus/functions/mbfuncinput.c diff --git a/modbus/freemodbus/functions/mbfuncinput_m.c b/industry/modbus/freemodbus/functions/mbfuncinput_m.c similarity index 99% rename from modbus/freemodbus/functions/mbfuncinput_m.c rename to industry/modbus/freemodbus/functions/mbfuncinput_m.c index 4ca7e8113..2d4799037 100644 --- a/modbus/freemodbus/functions/mbfuncinput_m.c +++ b/industry/modbus/freemodbus/functions/mbfuncinput_m.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/functions/mbfuncinput_m.c + * apps/industry/modbus/functions/mbfuncinput_m.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2013 Armink diff --git a/modbus/freemodbus/functions/mbfuncother.c b/industry/modbus/freemodbus/functions/mbfuncother.c similarity index 100% rename from modbus/freemodbus/functions/mbfuncother.c rename to industry/modbus/freemodbus/functions/mbfuncother.c diff --git a/modbus/freemodbus/functions/mbutils.c b/industry/modbus/freemodbus/functions/mbutils.c similarity index 100% rename from modbus/freemodbus/functions/mbutils.c rename to industry/modbus/freemodbus/functions/mbutils.c diff --git a/modbus/freemodbus/mb.c b/industry/modbus/freemodbus/mb.c similarity index 99% rename from modbus/freemodbus/mb.c rename to industry/modbus/freemodbus/mb.c index 16f5567d8..3d4b9bf5a 100644 --- a/modbus/freemodbus/mb.c +++ b/industry/modbus/freemodbus/mb.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/mb.c + * apps/industry/modbus/mb.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/mb_m.c b/industry/modbus/freemodbus/mb_m.c similarity index 100% rename from modbus/freemodbus/mb_m.c rename to industry/modbus/freemodbus/mb_m.c diff --git a/modbus/freemodbus/nuttx/Make.defs b/industry/modbus/freemodbus/nuttx/Make.defs similarity index 88% rename from modbus/freemodbus/nuttx/Make.defs rename to industry/modbus/freemodbus/nuttx/Make.defs index 723284cc4..1c3413ce3 100644 --- a/modbus/freemodbus/nuttx/Make.defs +++ b/industry/modbus/freemodbus/nuttx/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/freemodbus/nuttx/Make.defs +# apps/industry/modbus/freemodbus/nuttx/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -22,7 +22,7 @@ CSRCS += portother.c -ifeq ($(CONFIG_MODBUS_SLAVE),y) +ifeq ($(CONFIG_INDUSTRY_MODBUS_SLAVE),y) CSRCS += portevent.c portserial.c porttimer.c endif @@ -32,4 +32,4 @@ endif DEPPATH += --dep-path nuttx VPATH += :nuttx -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/nuttx +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/industry/modbus/freemodbus/nuttx diff --git a/modbus/freemodbus/nuttx/port.h b/industry/modbus/freemodbus/nuttx/port.h similarity index 94% rename from modbus/freemodbus/nuttx/port.h rename to industry/modbus/freemodbus/nuttx/port.h index c79dcdd98..149cefad2 100644 --- a/modbus/freemodbus/nuttx/port.h +++ b/industry/modbus/freemodbus/nuttx/port.h @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/nuttx/port.h + * apps/industry/modbus/nuttx/port.h * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter @@ -28,8 +28,8 @@ * ****************************************************************************/ -#ifndef __APPS_MODBUS_NUTTX_PORT_H -#define __APPS_MODBUS_NUTTX_PORT_H +#ifndef __APPS_INDUSTRY_MODBUS_NUTTX_PORT_H +#define __APPS_INDUSTRY_MODBUS_NUTTX_PORT_H /**************************************************************************** * Included Files @@ -79,7 +79,7 @@ typedef enum void vMBPortEnterCritical(void); void vMBPortExitCritical(void); -#ifndef CONFIG_MODBUS_DISABLE_LOG +#ifndef CONFIG_INDUSTRY_MODBUS_DISABLE_LOG void vMBPortLog(eMBPortLogLevel eLevel, const char *szModule, const char *szFmt, ...) printf_like(3, 4); #else @@ -103,4 +103,4 @@ bool xMBPortSerialSetTimeout(uint32_t dwTimeoutMs); } #endif -#endif /* __APPS_MODBUS_NUTTX_PORT_H */ +#endif /* __APPS_INDUSTRY_MODBUS_NUTTX_PORT_H */ diff --git a/modbus/freemodbus/nuttx/portevent.c b/industry/modbus/freemodbus/nuttx/portevent.c similarity index 98% rename from modbus/freemodbus/nuttx/portevent.c rename to industry/modbus/freemodbus/nuttx/portevent.c index bce6e9c54..d9d31072d 100644 --- a/modbus/freemodbus/nuttx/portevent.c +++ b/industry/modbus/freemodbus/nuttx/portevent.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/nuttx/portevent.c + * apps/industry/modbus/nuttx/portevent.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/nuttx/portevent_m.c b/industry/modbus/freemodbus/nuttx/portevent_m.c similarity index 99% rename from modbus/freemodbus/nuttx/portevent_m.c rename to industry/modbus/freemodbus/nuttx/portevent_m.c index fb40f4dee..90d0c0e6e 100644 --- a/modbus/freemodbus/nuttx/portevent_m.c +++ b/industry/modbus/freemodbus/nuttx/portevent_m.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/nuttx/portevent_m.c + * apps/industry/modbus/nuttx/portevent_m.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/nuttx/portother.c b/industry/modbus/freemodbus/nuttx/portother.c similarity index 97% rename from modbus/freemodbus/nuttx/portother.c rename to industry/modbus/freemodbus/nuttx/portother.c index 3de2a38b5..b6c4731d9 100644 --- a/modbus/freemodbus/nuttx/portother.c +++ b/industry/modbus/freemodbus/nuttx/portother.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/nuttx/portother.c + * apps/industry/modbus/nuttx/portother.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter @@ -73,7 +73,7 @@ void vMBPortLogFile(FILE * fNewLogFile) fLogFile = fNewLogFile; } -#ifndef CONFIG_MODBUS_DISABLE_LOG +#ifndef CONFIG_INDUSTRY_MODBUS_DISABLE_LOG void vMBPortLog(eMBPortLogLevel eLevel, const char * szModule, const char * szFmt, ...) { diff --git a/modbus/freemodbus/nuttx/portother_m.c b/industry/modbus/freemodbus/nuttx/portother_m.c similarity index 98% rename from modbus/freemodbus/nuttx/portother_m.c rename to industry/modbus/freemodbus/nuttx/portother_m.c index 1d703c192..9ee337f2a 100644 --- a/modbus/freemodbus/nuttx/portother_m.c +++ b/industry/modbus/freemodbus/nuttx/portother_m.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/nuttx/portother_m.c + * apps/industry/modbus/nuttx/portother_m.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/nuttx/portserial.c b/industry/modbus/freemodbus/nuttx/portserial.c similarity index 99% rename from modbus/freemodbus/nuttx/portserial.c rename to industry/modbus/freemodbus/nuttx/portserial.c index 35155a732..4cb502aa5 100644 --- a/modbus/freemodbus/nuttx/portserial.c +++ b/industry/modbus/freemodbus/nuttx/portserial.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/nuttx/portserial.c + * apps/industry/modbus/nuttx/portserial.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/nuttx/portserial_m.c b/industry/modbus/freemodbus/nuttx/portserial_m.c similarity index 99% rename from modbus/freemodbus/nuttx/portserial_m.c rename to industry/modbus/freemodbus/nuttx/portserial_m.c index 98c11eb28..d7fc25526 100644 --- a/modbus/freemodbus/nuttx/portserial_m.c +++ b/industry/modbus/freemodbus/nuttx/portserial_m.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/nuttx/portserial_m.c + * apps/industry/modbus/nuttx/portserial_m.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/nuttx/porttimer.c b/industry/modbus/freemodbus/nuttx/porttimer.c similarity index 98% rename from modbus/freemodbus/nuttx/porttimer.c rename to industry/modbus/freemodbus/nuttx/porttimer.c index 1685df6ee..d09561f4b 100644 --- a/modbus/freemodbus/nuttx/porttimer.c +++ b/industry/modbus/freemodbus/nuttx/porttimer.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/nuttx/porttimer.c + * apps/industry/modbus/nuttx/porttimer.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/nuttx/porttimer_m.c b/industry/modbus/freemodbus/nuttx/porttimer_m.c similarity index 99% rename from modbus/freemodbus/nuttx/porttimer_m.c rename to industry/modbus/freemodbus/nuttx/porttimer_m.c index 1e878aa00..8d9f3f3af 100644 --- a/modbus/freemodbus/nuttx/porttimer_m.c +++ b/industry/modbus/freemodbus/nuttx/porttimer_m.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/nuttx/porttimer_m.c + * apps/industry/modbus/nuttx/porttimer_m.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/rtu/Make.defs b/industry/modbus/freemodbus/rtu/Make.defs similarity index 91% rename from modbus/freemodbus/rtu/Make.defs rename to industry/modbus/freemodbus/rtu/Make.defs index 43576f993..46656017d 100644 --- a/modbus/freemodbus/rtu/Make.defs +++ b/industry/modbus/freemodbus/rtu/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/freemodbus/rtu/Make.defs +# apps/industry/modbus/freemodbus/rtu/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -40,6 +40,6 @@ endif DEPPATH += --dep-path rtu VPATH += :rtu -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/rtu +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/industry/modbus/freemodbus/rtu endif diff --git a/modbus/freemodbus/rtu/mbcrc.c b/industry/modbus/freemodbus/rtu/mbcrc.c similarity index 99% rename from modbus/freemodbus/rtu/mbcrc.c rename to industry/modbus/freemodbus/rtu/mbcrc.c index dcaddec71..df16f13e0 100644 --- a/modbus/freemodbus/rtu/mbcrc.c +++ b/industry/modbus/freemodbus/rtu/mbcrc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/rtu/mbcrc.c + * apps/industry/modbus/rtu/mbcrc.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/rtu/mbcrc.h b/industry/modbus/freemodbus/rtu/mbcrc.h similarity index 100% rename from modbus/freemodbus/rtu/mbcrc.h rename to industry/modbus/freemodbus/rtu/mbcrc.h diff --git a/modbus/freemodbus/rtu/mbrtu.c b/industry/modbus/freemodbus/rtu/mbrtu.c similarity index 99% rename from modbus/freemodbus/rtu/mbrtu.c rename to industry/modbus/freemodbus/rtu/mbrtu.c index 0f8262d4f..ead36d164 100644 --- a/modbus/freemodbus/rtu/mbrtu.c +++ b/industry/modbus/freemodbus/rtu/mbrtu.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/rtu/mbrtu.c + * apps/industry/modbus/rtu/mbrtu.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/rtu/mbrtu.h b/industry/modbus/freemodbus/rtu/mbrtu.h similarity index 98% rename from modbus/freemodbus/rtu/mbrtu.h rename to industry/modbus/freemodbus/rtu/mbrtu.h index 418311bff..ff31a1844 100644 --- a/modbus/freemodbus/rtu/mbrtu.h +++ b/industry/modbus/freemodbus/rtu/mbrtu.h @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/rtu/mbrtu.h + * apps/industry/modbus/rtu/mbrtu.h * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/rtu/mbrtu_m.c b/industry/modbus/freemodbus/rtu/mbrtu_m.c similarity index 99% rename from modbus/freemodbus/rtu/mbrtu_m.c rename to industry/modbus/freemodbus/rtu/mbrtu_m.c index ed8e62488..4a67a0508 100644 --- a/modbus/freemodbus/rtu/mbrtu_m.c +++ b/industry/modbus/freemodbus/rtu/mbrtu_m.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/rtu/mbrtu_m.c + * apps/industry/modbus/rtu/mbrtu_m.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2013 China Beijing Armink diff --git a/modbus/freemodbus/rtu/mbrtu_m.h b/industry/modbus/freemodbus/rtu/mbrtu_m.h similarity index 98% rename from modbus/freemodbus/rtu/mbrtu_m.h rename to industry/modbus/freemodbus/rtu/mbrtu_m.h index 5fb2eee43..b59652b59 100644 --- a/modbus/freemodbus/rtu/mbrtu_m.h +++ b/industry/modbus/freemodbus/rtu/mbrtu_m.h @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/rtu/mbrtu_m.h + * apps/industry/modbus/rtu/mbrtu_m.h * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2013 China Beijing Armink diff --git a/modbus/freemodbus/tcp/Make.defs b/industry/modbus/freemodbus/tcp/Make.defs similarity index 90% rename from modbus/freemodbus/tcp/Make.defs rename to industry/modbus/freemodbus/tcp/Make.defs index b9f82c6de..281a9a5be 100644 --- a/modbus/freemodbus/tcp/Make.defs +++ b/industry/modbus/freemodbus/tcp/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# apps/modbus/freemodbus/tcp/Make.defs +# apps/industry/modbus/freemodbus/tcp/Make.defs # # SPDX-License-Identifier: Apache-2.0 # @@ -26,6 +26,6 @@ CSRCS += mbtcp.c DEPPATH += --dep-path tcp VPATH += :tcp -CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/modbus/freemodbus/tcp +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/industry/modbus/freemodbus/tcp endif diff --git a/modbus/freemodbus/tcp/mbtcp.c b/industry/modbus/freemodbus/tcp/mbtcp.c similarity index 99% rename from modbus/freemodbus/tcp/mbtcp.c rename to industry/modbus/freemodbus/tcp/mbtcp.c index ca9c41c43..6957effb9 100644 --- a/modbus/freemodbus/tcp/mbtcp.c +++ b/industry/modbus/freemodbus/tcp/mbtcp.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/tcp/mbtcp.c + * apps/industry/modbus/tcp/mbtcp.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter diff --git a/modbus/freemodbus/tcp/mbtcp.h b/industry/modbus/freemodbus/tcp/mbtcp.h similarity index 98% rename from modbus/freemodbus/tcp/mbtcp.h rename to industry/modbus/freemodbus/tcp/mbtcp.h index 39fa9c8ce..26e380cb9 100644 --- a/modbus/freemodbus/tcp/mbtcp.h +++ b/industry/modbus/freemodbus/tcp/mbtcp.h @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/modbus/tcp/mbtcp.h + * apps/industry/modbus/tcp/mbtcp.h * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter From 2016c0b6ae2d2ce590bb4d55895a0c2917f466b2 Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Wed, 15 Apr 2026 09:44:45 -0300 Subject: [PATCH 295/568] apps/modbus: Move modbus to inside industry/ Modbus is a protocol mostly used on industries and since it is a protocol it is not a category to be at root of apps/ Signed-off-by: Alan C. Assis --- CMakeLists.txt | 1 - industry/modbus/Make.defs | 2 +- industry/modbus/freemodbus/Kconfig | 8 ++++---- industry/modbus/freemodbus/ascii/mbascii.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84844e700..3ebffdd94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,6 @@ add_subdirectory(logging) add_subdirectory(lte) add_subdirectory(math) add_subdirectory(mlearning) -add_subdirectory(modbus) add_subdirectory(netutils) add_subdirectory(nshlib) add_subdirectory(platform) diff --git a/industry/modbus/Make.defs b/industry/modbus/Make.defs index fde0dd716..b358e9be4 100644 --- a/industry/modbus/Make.defs +++ b/industry/modbus/Make.defs @@ -20,4 +20,4 @@ # ############################################################################ -include $(wildcard $(APPDIR)/modbus/*/Make.defs) +include $(wildcard $(APPDIR)/industry/modbus/*/Make.defs) diff --git a/industry/modbus/freemodbus/Kconfig b/industry/modbus/freemodbus/Kconfig index dd46bbe3c..7c9e834f3 100644 --- a/industry/modbus/freemodbus/Kconfig +++ b/industry/modbus/freemodbus/Kconfig @@ -153,17 +153,17 @@ config INDUSTRY_MODBUS_MASTER config MB_ASCII_MASTER bool "Modbus ASCII master" default n - depends on MODBUS_MASTER + depends on INDUSTRY_MODBUS_MASTER config MB_RTU_MASTER bool "Modbus RTU master" default n - depends on MODBUS_MASTER + depends on INDUSTRY_MODBUS_MASTER config MB_PORT_HAS_CLOSE bool "Platform close callbacks" default n - depends on MODBUS_MASTER + depends on INDUSTRY_MODBUS_MASTER ---help--- A port which wants to get an callback must select CONFIG_MB_HAS_CLOSE and provide vMBMasterPortClose() as @@ -250,7 +250,7 @@ config MB_MASTER_FUNC_READWRITE_HOLDING_ENABLED If the Read/Write Multiple Registers function should be enabled. endif # MB_ASCII_MASTER || MB_RTU_MASTER -endif # MODBUS +endif # INDUSTRY_MODBUS config INDUSTRY_MODBUS_DISABLE_LOG bool "Disable logging for FreeModBus" diff --git a/industry/modbus/freemodbus/ascii/mbascii.c b/industry/modbus/freemodbus/ascii/mbascii.c index d64505125..1ba55f99c 100644 --- a/industry/modbus/freemodbus/ascii/mbascii.c +++ b/industry/modbus/freemodbus/ascii/mbascii.c @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/industry/modbus/ascii/mbascii.c + * apps/industry/modbus/freemodbus/ascii/mbascii.c * * SPDX-License-Identifier: BSD-3-Clause * SPDX-FileCopyrightText: 2006 Christian Walter From 773f69d5d95d0390d60447a29c2c1b82931932a3 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 13 Apr 2026 14:37:52 +0200 Subject: [PATCH 296/568] modbus: add nxmodbus NxModbus is a lightweight Modbus protocol stack implementation for NuttX RTOS. This commit adds: - nxmodbus stack - nxmbserver - Modbus Server (Slave) example - nxmbclient - Modbus Client (Master) tool Supported Modbus transports: - ASCII - RTU over serial port - TCP - RAW (ADU) for custom transport implementations Signed-off-by: raiden00pl --- examples/nxmbserver/CMakeLists.txt | 35 + examples/nxmbserver/Kconfig | 33 + examples/nxmbserver/Make.defs | 25 + examples/nxmbserver/Makefile | 32 + examples/nxmbserver/nxmbserver_main.c | 543 ++++++++++++ include/nxmodbus/nxmb_client.h | 261 ++++++ include/nxmodbus/nxmb_raw.h | 108 +++ include/nxmodbus/nxmodbus.h | 378 +++++++++ industry/nxmodbus/CMakeLists.txt | 68 ++ industry/nxmodbus/Kconfig | 245 ++++++ industry/nxmodbus/Make.defs | 25 + industry/nxmodbus/Makefile | 76 ++ industry/nxmodbus/core/nxmb_client.c | 739 ++++++++++++++++ industry/nxmodbus/core/nxmb_context.c | 392 +++++++++ industry/nxmodbus/core/nxmb_func.c | 354 ++++++++ industry/nxmodbus/core/nxmb_func_coils.c | 259 ++++++ industry/nxmodbus/core/nxmb_func_diag.c | 83 ++ industry/nxmodbus/core/nxmb_func_discrete.c | 110 +++ industry/nxmodbus/core/nxmb_func_holding.c | 331 ++++++++ industry/nxmodbus/core/nxmb_func_input.c | 115 +++ industry/nxmodbus/core/nxmb_func_other.c | 99 +++ industry/nxmodbus/core/nxmb_server.c | 121 +++ industry/nxmodbus/core/nxmb_utils.c | 127 +++ industry/nxmodbus/nxmb_internal.h | 379 +++++++++ industry/nxmodbus/transport/nxmb_ascii.c | 550 ++++++++++++ industry/nxmodbus/transport/nxmb_crc.c | 108 +++ industry/nxmodbus/transport/nxmb_lrc.c | 70 ++ industry/nxmodbus/transport/nxmb_raw.c | 303 +++++++ industry/nxmodbus/transport/nxmb_serial.c | 423 ++++++++++ .../nxmodbus/transport/nxmb_serial_common.c | 138 +++ industry/nxmodbus/transport/nxmb_tcp.c | 684 +++++++++++++++ system/nxmbclient/CMakeLists.txt | 35 + system/nxmbclient/Kconfig | 32 + system/nxmbclient/Make.defs | 25 + system/nxmbclient/Makefile | 32 + system/nxmbclient/nxmbclient_main.c | 799 ++++++++++++++++++ 36 files changed, 8137 insertions(+) create mode 100644 examples/nxmbserver/CMakeLists.txt create mode 100644 examples/nxmbserver/Kconfig create mode 100644 examples/nxmbserver/Make.defs create mode 100644 examples/nxmbserver/Makefile create mode 100644 examples/nxmbserver/nxmbserver_main.c create mode 100644 include/nxmodbus/nxmb_client.h create mode 100644 include/nxmodbus/nxmb_raw.h create mode 100644 include/nxmodbus/nxmodbus.h create mode 100644 industry/nxmodbus/CMakeLists.txt create mode 100644 industry/nxmodbus/Kconfig create mode 100644 industry/nxmodbus/Make.defs create mode 100644 industry/nxmodbus/Makefile create mode 100644 industry/nxmodbus/core/nxmb_client.c create mode 100644 industry/nxmodbus/core/nxmb_context.c create mode 100644 industry/nxmodbus/core/nxmb_func.c create mode 100644 industry/nxmodbus/core/nxmb_func_coils.c create mode 100644 industry/nxmodbus/core/nxmb_func_diag.c create mode 100644 industry/nxmodbus/core/nxmb_func_discrete.c create mode 100644 industry/nxmodbus/core/nxmb_func_holding.c create mode 100644 industry/nxmodbus/core/nxmb_func_input.c create mode 100644 industry/nxmodbus/core/nxmb_func_other.c create mode 100644 industry/nxmodbus/core/nxmb_server.c create mode 100644 industry/nxmodbus/core/nxmb_utils.c create mode 100644 industry/nxmodbus/nxmb_internal.h create mode 100644 industry/nxmodbus/transport/nxmb_ascii.c create mode 100644 industry/nxmodbus/transport/nxmb_crc.c create mode 100644 industry/nxmodbus/transport/nxmb_lrc.c create mode 100644 industry/nxmodbus/transport/nxmb_raw.c create mode 100644 industry/nxmodbus/transport/nxmb_serial.c create mode 100644 industry/nxmodbus/transport/nxmb_serial_common.c create mode 100644 industry/nxmodbus/transport/nxmb_tcp.c create mode 100644 system/nxmbclient/CMakeLists.txt create mode 100644 system/nxmbclient/Kconfig create mode 100644 system/nxmbclient/Make.defs create mode 100644 system/nxmbclient/Makefile create mode 100644 system/nxmbclient/nxmbclient_main.c diff --git a/examples/nxmbserver/CMakeLists.txt b/examples/nxmbserver/CMakeLists.txt new file mode 100644 index 000000000..d6880be38 --- /dev/null +++ b/examples/nxmbserver/CMakeLists.txt @@ -0,0 +1,35 @@ +# ############################################################################## +# apps/examples/nxmbserver/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_EXAMPLES_NXMBSERVER) + nuttx_add_application( + NAME + ${CONFIG_EXAMPLES_NXMBSERVER_PROGNAME} + PRIORITY + ${CONFIG_EXAMPLES_NXMBSERVER_PRIORITY} + STACKSIZE + ${CONFIG_EXAMPLES_NXMBSERVER_STACKSIZE} + MODULE + ${CONFIG_EXAMPLES_NXMBSERVER} + SRCS + nxmbserver_main.c) +endif() diff --git a/examples/nxmbserver/Kconfig b/examples/nxmbserver/Kconfig new file mode 100644 index 000000000..428f49c5e --- /dev/null +++ b/examples/nxmbserver/Kconfig @@ -0,0 +1,33 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_NXMBSERVER + tristate "NxModbus Server Example" + default n + depends on NXMODBUS_SERVER + ---help--- + Enable the NxModbus server example. This example demonstrates + how to create a Modbus server (slave) that responds to client + requests. Supports RTU, ASCII, and TCP transports with simulated + register data. + +if EXAMPLES_NXMBSERVER + +config EXAMPLES_NXMBSERVER_PROGNAME + string "Program name" + default "nxmbserver" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config EXAMPLES_NXMBSERVER_PRIORITY + int "NxModbus server task priority" + default 100 + +config EXAMPLES_NXMBSERVER_STACKSIZE + int "NxModbus server stack size" + default DEFAULT_TASK_STACKSIZE + +endif # EXAMPLES_NXMBSERVER diff --git a/examples/nxmbserver/Make.defs b/examples/nxmbserver/Make.defs new file mode 100644 index 000000000..57fd777e7 --- /dev/null +++ b/examples/nxmbserver/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/examples/nxmbserver/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_NXMBSERVER),) +CONFIGURED_APPS += $(APPDIR)/examples/nxmbserver +endif diff --git a/examples/nxmbserver/Makefile b/examples/nxmbserver/Makefile new file mode 100644 index 000000000..d3699d90b --- /dev/null +++ b/examples/nxmbserver/Makefile @@ -0,0 +1,32 @@ +############################################################################ +# apps/examples/nxmbserver/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +MAINSRC = nxmbserver_main.c + +PROGNAME = $(CONFIG_EXAMPLES_NXMBSERVER_PROGNAME) +PRIORITY = $(CONFIG_EXAMPLES_NXMBSERVER_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_NXMBSERVER_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_NXMBSERVER) + +include $(APPDIR)/Application.mk diff --git a/examples/nxmbserver/nxmbserver_main.c b/examples/nxmbserver/nxmbserver_main.c new file mode 100644 index 000000000..8e8572dda --- /dev/null +++ b/examples/nxmbserver/nxmbserver_main.c @@ -0,0 +1,543 @@ +/**************************************************************************** + * apps/examples/nxmbserver/nxmbserver_main.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEFAULT_UNIT_ID 1 +#define DEFAULT_TCP_PORT 502 +#define DEFAULT_BAUDRATE 19200 + +#define NUM_COILS 100 +#define NUM_DISCRETE 100 +#define NUM_INPUT_REGS 100 +#define NUM_HOLDING_REGS 100 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Modbus type supported by example */ + +enum transport_type_e +{ + TRANSPORT_RTU = 0, + TRANSPORT_ASCII, + TRANSPORT_TCP +}; + +/* Modbus registers */ + +struct server_data_s +{ + uint8_t coils[NUM_COILS / 8 + 1]; + uint8_t discrete[NUM_DISCRETE / 8 + 1]; + uint16_t input_regs[NUM_INPUT_REGS]; + uint16_t holding_regs[NUM_HOLDING_REGS]; +}; + +/* Modbus server configuration */ + +struct server_config_s +{ + enum transport_type_e transport; + enum nxmb_parity_e parity; + FAR const char *device; + FAR const char *bindaddr; + uint32_t baudrate; + uint16_t port; + uint8_t unit_id; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct server_data_s g_data; +static volatile bool g_running = true; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: signal_handler + ****************************************************************************/ + +static void signal_handler(int signo) +{ + g_running = false; +} + +/**************************************************************************** + * Name: show_usage + ****************************************************************************/ + +static void show_usage(FAR const char *progname) +{ + printf("Usage: %s [OPTIONS]\n\n", progname); + printf("Transport Options:\n"); + printf(" -t TYPE Transport type: rtu, ascii, tcp (required)\n"); + printf(" -d DEVICE Serial device path (for RTU/ASCII)\n"); + printf(" -b BAUD Baud rate (default: %u)\n", DEFAULT_BAUDRATE); + printf(" -p PARITY Parity: none, even, odd (default: even)\n"); + printf(" -a ADDR Bind address (for TCP, default: 0.0.0.0)\n"); + printf(" -P PORT TCP port (default: %u)\n", DEFAULT_TCP_PORT); + printf("\nModbus Options:\n"); + printf(" -u UNIT Unit ID (default: %u)\n", DEFAULT_UNIT_ID); + printf("\nExample:\n"); + printf(" %s -t rtu -d /dev/ttyS1 -b 19200\n", progname); + printf(" %s -t tcp -P 502\n", progname); +} + +/**************************************************************************** + * Name: parse_parity + ****************************************************************************/ + +static int parse_parity(FAR const char *str, FAR enum nxmb_parity_e *parity) +{ + if (strcmp(str, "none") == 0) + { + *parity = NXMB_PAR_NONE; + } + else if (strcmp(str, "even") == 0) + { + *parity = NXMB_PAR_EVEN; + } + else if (strcmp(str, "odd") == 0) + { + *parity = NXMB_PAR_ODD; + } + else + { + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: parse_transport + ****************************************************************************/ + +static int parse_transport(FAR const char *str, + FAR enum transport_type_e *transport) +{ + if (strcmp(str, "rtu") == 0) + { + *transport = TRANSPORT_RTU; + } + else if (strcmp(str, "ascii") == 0) + { + *transport = TRANSPORT_ASCII; + } + else if (strcmp(str, "tcp") == 0) + { + *transport = TRANSPORT_TCP; + } + else + { + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: coils_callback + ****************************************************************************/ + +static int coils_callback(FAR uint8_t *buf, uint16_t addr, uint16_t count, + enum nxmb_regmode_e mode, FAR void *priv) +{ + uint16_t byte_idx; + uint16_t bit_idx; + uint16_t i; + + if (addr + count > NUM_COILS) + { + return -ENOENT; + } + + if (mode == NXMB_REG_READ) + { + for (i = 0; i < count; i++) + { + byte_idx = (addr + i) / 8; + bit_idx = (addr + i) % 8; + + if (g_data.coils[byte_idx] & (1 << bit_idx)) + { + buf[i / 8] |= (1 << (i % 8)); + } + else + { + buf[i / 8] &= ~(1 << (i % 8)); + } + } + } + else + { + for (i = 0; i < count; i++) + { + byte_idx = (addr + i) / 8; + bit_idx = (addr + i) % 8; + + if (buf[i / 8] & (1 << (i % 8))) + { + g_data.coils[byte_idx] |= (1 << bit_idx); + } + else + { + g_data.coils[byte_idx] &= ~(1 << bit_idx); + } + } + } + + return OK; +} + +/**************************************************************************** + * Name: discrete_callback + ****************************************************************************/ + +static int discrete_callback(FAR uint8_t *buf, uint16_t addr, + uint16_t count, FAR void *priv) +{ + uint16_t byte_idx; + uint16_t bit_idx; + uint16_t i; + + if (addr + count > NUM_DISCRETE) + { + return -ENOENT; + } + + for (i = 0; i < count; i++) + { + byte_idx = (addr + i) / 8; + bit_idx = (addr + i) % 8; + + if (g_data.discrete[byte_idx] & (1 << bit_idx)) + { + buf[i / 8] |= (1 << (i % 8)); + } + else + { + buf[i / 8] &= ~(1 << (i % 8)); + } + } + + return OK; +} + +/**************************************************************************** + * Name: input_callback + ****************************************************************************/ + +static int input_callback(FAR uint8_t *buf, uint16_t addr, uint16_t count, + FAR void *priv) +{ + uint16_t i; + + if (addr + count > NUM_INPUT_REGS) + { + return -ENOENT; + } + + for (i = 0; i < count; i++) + { + buf[i * 2] = (uint8_t)(g_data.input_regs[addr + i] >> 8); + buf[i * 2 + 1] = (uint8_t)(g_data.input_regs[addr + i] & 0xff); + } + + return OK; +} + +/**************************************************************************** + * Name: holding_callback + ****************************************************************************/ + +static int holding_callback(FAR uint8_t *buf, uint16_t addr, uint16_t count, + enum nxmb_regmode_e mode, FAR void *priv) +{ + uint16_t i; + + if (addr + count > NUM_HOLDING_REGS) + { + return -ENOENT; + } + + if (mode == NXMB_REG_READ) + { + for (i = 0; i < count; i++) + { + buf[i * 2] = (uint8_t)(g_data.holding_regs[addr + i] >> 8); + buf[i * 2 + 1] = (uint8_t)(g_data.holding_regs[addr + i] & 0xff); + } + } + else + { + for (i = 0; i < count; i++) + { + g_data.holding_regs[addr + i] = + (uint16_t)(buf[i * 2] << 8) | (uint16_t)buf[i * 2 + 1]; + } + } + + return OK; +} + +/**************************************************************************** + * Name: init_data + ****************************************************************************/ + +static void init_data(void) +{ + uint16_t i; + + memset(&g_data, 0, sizeof(g_data)); + + for (i = 0; i < NUM_INPUT_REGS; i++) + { + g_data.input_regs[i] = i * 10; + } + + for (i = 0; i < NUM_HOLDING_REGS; i++) + { + g_data.holding_regs[i] = i * 100; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmbserver_main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + struct server_config_s config; + struct nxmb_config_s mb_config; + struct nxmb_callbacks_s callbacks; + nxmb_handle_t handle; + bool transport_set = false; + int option; + int ret; + + /* Default config */ + + memset(&config, 0, sizeof(config)); + config.baudrate = DEFAULT_BAUDRATE; + config.parity = NXMB_PAR_EVEN; + config.port = DEFAULT_TCP_PORT; + config.unit_id = DEFAULT_UNIT_ID; + + /* Handle CLI */ + + while ((option = getopt(argc, argv, "t:d:b:p:a:P:u:h")) != -1) + { + switch (option) + { + case 't': + if (parse_transport(optarg, &config.transport) < 0) + { + fprintf(stderr, "Error: invalid transport '%s'\n", optarg); + return EXIT_FAILURE; + } + + transport_set = true; + break; + + case 'd': + config.device = optarg; + break; + + case 'b': + config.baudrate = (uint32_t)strtoul(optarg, NULL, 0); + break; + + case 'p': + if (parse_parity(optarg, &config.parity) < 0) + { + fprintf(stderr, "Error: invalid parity '%s'\n", optarg); + return EXIT_FAILURE; + } + + break; + + case 'a': + config.bindaddr = optarg; + break; + + case 'P': + config.port = (uint16_t)strtoul(optarg, NULL, 0); + break; + + case 'u': + config.unit_id = (uint8_t)strtoul(optarg, NULL, 0); + break; + + case 'h': + default: + show_usage(argv[0]); + return (option == 'h') ? EXIT_SUCCESS : EXIT_FAILURE; + } + } + + /* Validate input */ + + if (!transport_set) + { + fprintf(stderr, "Error: transport type (-t) is required\n\n"); + show_usage(argv[0]); + return EXIT_FAILURE; + } + + if ((config.transport == TRANSPORT_RTU || + config.transport == TRANSPORT_ASCII) && + config.device == NULL) + { + fprintf(stderr, "Error: device path (-d) required for RTU/ASCII\n"); + return EXIT_FAILURE; + } + + /* Connect signals */ + + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + + /* Init modbus data */ + + init_data(); + + /* Init modbus stack */ + + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.coil_cb = coils_callback; + callbacks.discrete_cb = discrete_callback; + callbacks.input_cb = input_callback; + callbacks.holding_cb = holding_callback; + + memset(&mb_config, 0, sizeof(mb_config)); + mb_config.unit_id = config.unit_id; + mb_config.is_client = false; + + switch (config.transport) + { + case TRANSPORT_RTU: + mb_config.mode = NXMB_MODE_RTU; + mb_config.transport.serial.devpath = config.device; + mb_config.transport.serial.baudrate = config.baudrate; + mb_config.transport.serial.parity = config.parity; + printf("Starting Modbus RTU server on %s (baud=%" PRId32 + ", unit=%u)\n", config.device, config.baudrate, + config.unit_id); + break; + + case TRANSPORT_ASCII: + mb_config.mode = NXMB_MODE_ASCII; + mb_config.transport.serial.devpath = config.device; + mb_config.transport.serial.baudrate = config.baudrate; + mb_config.transport.serial.parity = config.parity; + printf("Starting Modbus ASCII server on %s (baud=%" PRId32 + ", unit=%u)\n", config.device, config.baudrate, + config.unit_id); + break; + + case TRANSPORT_TCP: + mb_config.mode = NXMB_MODE_TCP; + mb_config.transport.tcp.port = config.port; + mb_config.transport.tcp.bindaddr = config.bindaddr; + printf("Starting Modbus TCP server on port %u (unit=%u)\n", + config.port, config.unit_id); + break; + } + + ret = nxmb_create(&handle, &mb_config); + if (ret < 0) + { + fprintf(stderr, "Error: failed to create Modbus context: %d\n", ret); + return EXIT_FAILURE; + } + + ret = nxmb_set_callbacks(handle, &callbacks); + if (ret < 0) + { + fprintf(stderr, "Error: failed to set callbacks: %d\n", ret); + nxmb_destroy(handle); + return EXIT_FAILURE; + } + + ret = nxmb_enable(handle); + if (ret < 0) + { + fprintf(stderr, "Error: failed to enable context: %d\n", ret); + nxmb_destroy(handle); + return EXIT_FAILURE; + } + + printf("Server running. Press Ctrl+C to stop.\n"); + printf("Register map:\n"); + printf(" Coils: 1-%d (read/write)\n", NUM_COILS); + printf(" Discrete: 1-%d (read-only)\n", NUM_DISCRETE); + printf(" Input regs: 1-%d (read-only, value=addr*10)\n", + NUM_INPUT_REGS); + printf(" Holding regs: 1-%d (read/write, initial=addr*100)\n", + NUM_HOLDING_REGS); + + /* Poll loop */ + + while (g_running) + { + ret = nxmb_poll(handle); + if (ret < 0 && ret != -EAGAIN) + { + fprintf(stderr, "Error: poll failed: %d\n", ret); + break; + } + } + + printf("\nShutting down...\n"); + nxmb_disable(handle); + nxmb_destroy(handle); + + return EXIT_SUCCESS; +} diff --git a/include/nxmodbus/nxmb_client.h b/include/nxmodbus/nxmb_client.h new file mode 100644 index 000000000..49c10e542 --- /dev/null +++ b/include/nxmodbus/nxmb_client.h @@ -0,0 +1,261 @@ +/**************************************************************************** + * apps/include/nxmodbus/nxmb_client.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_NXMODBUS_NXMB_CLIENT_H +#define __APPS_INCLUDE_NXMODBUS_NXMB_CLIENT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Name: nxmb_read_coils + * + * Description: + * Read coil values from a remote unit. + * + * Input Parameters: + * h - The NxModbus client instance. + * uid - The remote unit identifier. + * addr - The first coil address to read. + * count - The number of coils to read. + * buf - The destination buffer for the returned coil values. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_read_coils(nxmb_handle_t h, uint8_t uid, uint16_t addr, + uint16_t count, FAR uint8_t *buf); + +/**************************************************************************** + * Name: nxmb_read_discrete + * + * Description: + * Read discrete input values from a remote unit. + * + * Input Parameters: + * h - The NxModbus client instance. + * uid - The remote unit identifier. + * addr - The first discrete input address to read. + * count - The number of discrete inputs to read. + * buf - The destination buffer for the returned values. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_read_discrete(nxmb_handle_t h, uint8_t uid, uint16_t addr, + uint16_t count, FAR uint8_t *buf); + +/**************************************************************************** + * Name: nxmb_read_input + * + * Description: + * Read input registers from a remote unit. + * + * Input Parameters: + * h - The NxModbus client instance. + * uid - The remote unit identifier. + * addr - The first input register address to read. + * count - The number of registers to read. + * buf - The destination buffer for the returned register values. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_read_input(nxmb_handle_t h, uint8_t uid, uint16_t addr, + uint16_t count, FAR uint16_t *buf); + +/**************************************************************************** + * Name: nxmb_read_holding + * + * Description: + * Read holding registers from a remote unit. + * + * Input Parameters: + * h - The NxModbus client instance. + * uid - The remote unit identifier. + * addr - The first holding register address to read. + * count - The number of registers to read. + * buf - The destination buffer for the returned register values. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_read_holding(nxmb_handle_t h, uint8_t uid, uint16_t addr, + uint16_t count, FAR uint16_t *buf); + +/**************************************************************************** + * Name: nxmb_write_coil + * + * Description: + * Write a single coil on a remote unit. + * + * Input Parameters: + * h - The NxModbus client instance. + * uid - The remote unit identifier. + * addr - The coil address to update. + * value - The coil state to write. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_write_coil(nxmb_handle_t h, uint8_t uid, uint16_t addr, bool value); + +/**************************************************************************** + * Name: nxmb_write_holding + * + * Description: + * Write a single holding register on a remote unit. + * + * Input Parameters: + * h - The NxModbus client instance. + * uid - The remote unit identifier. + * addr - The holding register address to update. + * value - The register value to write. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_write_holding(nxmb_handle_t h, uint8_t uid, uint16_t addr, + uint16_t value); + +/**************************************************************************** + * Name: nxmb_write_coils + * + * Description: + * Write multiple coils on a remote unit. + * + * Input Parameters: + * h - The NxModbus client instance. + * uid - The remote unit identifier. + * addr - The first coil address to update. + * count - The number of coils to write. + * buf - The source buffer containing coil values. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_write_coils(nxmb_handle_t h, uint8_t uid, uint16_t addr, + uint16_t count, FAR const uint8_t *buf); + +/**************************************************************************** + * Name: nxmb_write_holdings + * + * Description: + * Write multiple holding registers on a remote unit. + * + * Input Parameters: + * h - The NxModbus client instance. + * uid - The remote unit identifier. + * addr - The first holding register address to update. + * count - The number of registers to write. + * buf - The source buffer containing register values. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_write_holdings(nxmb_handle_t h, uint8_t uid, uint16_t addr, + uint16_t count, FAR const uint16_t *buf); + +/**************************************************************************** + * Name: nxmb_readwrite_holdings + * + * Description: + * Perform a combined read/write of holding registers on a remote unit + * using FC23 (0x17). The write is performed before the read on the + * server side. + * + * Input Parameters: + * h - The NxModbus client instance. + * uid - The remote unit identifier. + * rd_addr - The first holding register address to read. + * rd_count - The number of registers to read (1-125). + * rd_buf - The destination buffer for the returned register values. + * wr_addr - The first holding register address to write. + * wr_count - The number of registers to write (1-121). + * wr_buf - The source buffer containing register values to write. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_readwrite_holdings(nxmb_handle_t h, uint8_t uid, uint16_t rd_addr, + uint16_t rd_count, FAR uint16_t *rd_buf, + uint16_t wr_addr, uint16_t wr_count, + FAR const uint16_t *wr_buf); + +/**************************************************************************** + * Name: nxmb_set_timeout + * + * Description: + * Set the client-side response timeout. + * + * Input Parameters: + * h - The NxModbus client instance. + * timeout_ms - The timeout in milliseconds. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_set_timeout(nxmb_handle_t h, uint32_t timeout_ms); + +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_NXMODBUS_NXMB_CLIENT_H */ diff --git a/include/nxmodbus/nxmb_raw.h b/include/nxmodbus/nxmb_raw.h new file mode 100644 index 000000000..e01f42598 --- /dev/null +++ b/include/nxmodbus/nxmb_raw.h @@ -0,0 +1,108 @@ +/**************************************************************************** + * apps/include/nxmodbus/nxmb_raw.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_NXMODBUS_NXMB_RAW_H +#define __APPS_INCLUDE_NXMODBUS_NXMB_RAW_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXMB_RAW_HDR_SIZE 8 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Name: nxmb_raw_submit_rx + * + * Description: + * Submit a received raw ADU into the NxModbus protocol core. + * + * Input Parameters: + * h - The NxModbus instance receiving the frame. + * adu - The received raw ADU container. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_raw_submit_rx(nxmb_handle_t h, FAR const struct nxmb_adu_s *adu); + +/**************************************************************************** + * Name: nxmb_raw_put_header + * + * Description: + * Serialize the 8-byte MBAP+FC header for an ADU. + * + * Input Parameters: + * adu - The ADU providing the header fields. + * hdr - The destination buffer for the serialized header. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void nxmb_raw_put_header(FAR const struct nxmb_adu_s *adu, FAR uint8_t *hdr); + +/**************************************************************************** + * Name: nxmb_raw_get_header + * + * Description: + * Parse the 8-byte MBAP+FC header into an ADU structure. + * + * Input Parameters: + * adu - The destination ADU structure. + * hdr - The source buffer containing the serialized header. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void nxmb_raw_get_header(FAR struct nxmb_adu_s *adu, FAR const uint8_t *hdr); + +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_NXMODBUS_NXMB_RAW_H */ diff --git a/include/nxmodbus/nxmodbus.h b/include/nxmodbus/nxmodbus.h new file mode 100644 index 000000000..f5307989b --- /dev/null +++ b/include/nxmodbus/nxmodbus.h @@ -0,0 +1,378 @@ +/**************************************************************************** + * apps/include/nxmodbus/nxmodbus.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_NXMODBUS_NXMODBUS_H +#define __APPS_INCLUDE_NXMODBUS_NXMODBUS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXMB_TCP_PORT_DEFAULT 502 + +/* Maximum number of PDU data bytes (everything after the FC byte). + * Configured via Kconfig (CONFIG_NXMODBUS_ADU_DATA_MAX). + */ + +#define NXMB_ADU_DATA_MAX CONFIG_NXMODBUS_ADU_DATA_MAX + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Opaque handle to an NxModbus instance. */ + +typedef FAR struct nxmb_context_s *nxmb_handle_t; + +/* Custom frame handler */ + +typedef CODE int (*nxmb_custom_fc_handler_t)(nxmb_handle_t ctx); + +/* Modbus Application Data Unit container. + * + * Single canonical ADU representation shared by the protocol core and all + * transports. Transports parse incoming wire frames into this struct and + * serialize this struct back out on transmit. + * + * trans_id, proto_id, length - MBAP header fields (TCP-only). + * unit_id - Modbus address byte. + * fc - Modbus function code byte. + * data[] - PDU payload after the function code. + * crc - RTU/ASCII checksum (serial-only). + * + * The MBAP `length` field counts the bytes following it: unit_id + fc + + * data_count. Transports that don't carry MBAP still populate this field + * with the same value so that consumers can derive data_count uniformly: + * data_count = adu.length - 2 + */ + +struct nxmb_adu_s +{ + uint16_t trans_id; + uint16_t proto_id; + uint16_t length; + uint8_t unit_id; + uint8_t fc; + uint8_t data[NXMB_ADU_DATA_MAX]; + uint16_t crc; +}; + +/* Callback used by raw ADU mode to emit a fully-formed frame. */ + +typedef int (*nxmb_raw_tx_cb_t)(FAR const struct nxmb_adu_s *adu, + FAR void *user_data); + +/* Supported transport modes. */ + +enum nxmb_mode_e +{ + NXMB_MODE_INVAL = 0, + NXMB_MODE_RTU, /* Modbus RTU */ + NXMB_MODE_ASCII, /* Modbus ASCII */ + NXMB_MODE_TCP, /* Modbus TCP */ + NXMB_MODE_RAW /* Custom ADU transport */ +}; + +/* Serial parity configuration. */ + +enum nxmb_parity_e +{ + NXMB_PAR_NONE = 0, + NXMB_PAR_EVEN, + NXMB_PAR_ODD +}; + +/* Register access direction passed to callbacks. */ + +enum nxmb_regmode_e +{ + NXMB_REG_READ = 0, + NXMB_REG_WRITE +}; + +/* Standard Modbus exception codes. */ + +enum nxmb_exception_e +{ + NXMB_EX_NONE = 0x00, + NXMB_EX_ILLEGAL_FUNCTION = 0x01, + NXMB_EX_ILLEGAL_DATA_ADDRESS = 0x02, + NXMB_EX_ILLEGAL_DATA_VALUE = 0x03, + NXMB_EX_DEVICE_FAILURE = 0x04, + NXMB_EX_ACKNOWLEDGE = 0x05, + NXMB_EX_DEVICE_BUSY = 0x06, + NXMB_EX_MEMORY_PARITY_ERROR = 0x08, + NXMB_EX_GATEWAY_PATH_FAILED = 0x0a, + NXMB_EX_GATEWAY_TGT_FAILED = 0x0b +}; + +/* Serial transport configuration. */ + +struct nxmb_serial_config_s +{ + FAR const char *devpath; + enum nxmb_parity_e parity; + uint32_t baudrate; +}; + +/* TCP transport configuration. + * + * For slave mode, bindaddr selects the local address and port selects the + * listening port. For client mode, host selects the remote endpoint and + * port selects the remote port. + */ + +struct nxmb_tcp_config_s +{ + FAR const char *host; + FAR const char *bindaddr; + uint16_t port; +}; + +/* Raw ADU transport configuration. */ + +struct nxmb_raw_config_s +{ + FAR void *user_data; + nxmb_raw_tx_cb_t tx_cb; +}; + +union nxmb_transport_config_u +{ + struct nxmb_serial_config_s serial; + struct nxmb_tcp_config_s tcp; + struct nxmb_raw_config_s raw; +}; + +/* Generic NxModbus instance configuration. */ + +struct nxmb_config_s +{ + union nxmb_transport_config_u transport; + enum nxmb_mode_e mode; + uint8_t unit_id; + bool is_client; +}; + +/* Application callback table for Modbus data model access. + * + * The protocol stack passes buffers covering a contiguous address range and + * the application fills or consumes them depending on the register mode. + */ + +struct nxmb_callbacks_s +{ + CODE int (*coil_cb)(FAR uint8_t *buf, uint16_t addr, uint16_t ncoils, + enum nxmb_regmode_e mode, FAR void *priv); + CODE int (*discrete_cb)(FAR uint8_t *buf, uint16_t addr, + uint16_t ndiscrete, FAR void *priv); + CODE int (*input_cb)(FAR uint8_t *buf, uint16_t addr, uint16_t nregs, + FAR void *priv); + CODE int (*holding_cb)(FAR uint8_t *buf, uint16_t addr, uint16_t nregs, + enum nxmb_regmode_e mode, FAR void *priv); + FAR void *priv; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Name: nxmb_create + * + * Description: + * Create and initialize an NxModbus instance. This function allocates one + * entry from the static NxModbus instance pool and initializes it for the + * selected transport mode. + * + * Input Parameters: + * handle - A location to receive the opaque NxModbus handle. + * config - The transport and role configuration for the new instance. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_create(FAR nxmb_handle_t *handle, + FAR const struct nxmb_config_s *config); + +/**************************************************************************** + * Name: nxmb_destroy + * + * Description: + * Destroy a previously created NxModbus instance. This function releases + * a handle previously obtained from nxmb_create(). + * + * Input Parameters: + * handle - The NxModbus instance to destroy. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_destroy(nxmb_handle_t handle); + +/**************************************************************************** + * Name: nxmb_set_callbacks + * + * Description: + * Register the application callback table for an instance. The registered + * callback table defines how the application exposes coils, discrete + * inputs, input registers, and holding registers to the protocol stack. + * + * Input Parameters: + * handle - The NxModbus instance to update. + * cbs - The callback table to associate with the instance. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_set_callbacks(nxmb_handle_t handle, + FAR const struct nxmb_callbacks_s *cbs); + +/**************************************************************************** + * Name: nxmb_enable + * + * Description: + * Enable the configured transport and protocol handling. This function + * prepares the configured transport backend so the instance can start + * sending or receiving Modbus ADUs. + * + * Input Parameters: + * handle - The NxModbus instance to enable. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_enable(nxmb_handle_t handle); + +/**************************************************************************** + * Name: nxmb_disable + * + * Description: + * Disable an active NxModbus instance. This function stops frame + * processing and releases any transport state held by an enabled instance. + * + * Input Parameters: + * handle - The NxModbus instance to disable. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_disable(nxmb_handle_t handle); + +/**************************************************************************** + * Name: nxmb_poll + * + * Description: + * Execute one server-side polling iteration. This function performs a + * single poll of the transport backend and processes one server-side + * Modbus transaction when data is available. + * + * Input Parameters: + * handle - The NxModbus instance to poll. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_poll(nxmb_handle_t handle); + +/**************************************************************************** + * Name: nxmb_set_server_id + * + * Description: + * Configure the data returned by FC17 (Report Server ID). The response + * contains the server ID byte, a run indicator, and optional additional + * data supplied by the application. + * + * Input Parameters: + * handle - The NxModbus instance to update. + * id - The server ID byte. + * is_running - True if the device is in a running state. + * additional - Optional additional data bytes (may be NULL). + * addlen - Length of additional data. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_set_server_id(nxmb_handle_t handle, uint8_t id, bool is_running, + FAR const uint8_t *additional, uint16_t addlen); + +#ifdef CONFIG_NXMODBUS_CUSTOM_FC +/**************************************************************************** + * Name: nxmb_register_custom_fc + * + * Description: + * Register a custom Modbus function code handler for an instance. + * Custom handlers are checked after standard handlers, so standard + * function codes cannot be overridden. + * + * Input Parameters: + * h - The NxModbus instance handle. + * fc - The custom function code to register. + * handler - The handler function. Receives the instance handle and + * operates on ctx->adu in place: the request fields + * (adu.fc, adu.data[], adu.length) are overwritten with the + * response. Returns zero on success or a negated errno value + * on failure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int nxmb_register_custom_fc(nxmb_handle_t h, uint8_t fc, + nxmb_custom_fc_handler_t handler); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_NXMODBUS_NXMODBUS_H */ diff --git a/industry/nxmodbus/CMakeLists.txt b/industry/nxmodbus/CMakeLists.txt new file mode 100644 index 000000000..35be513e4 --- /dev/null +++ b/industry/nxmodbus/CMakeLists.txt @@ -0,0 +1,68 @@ +# ############################################################################## +# apps/industry/nxmodbus/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_INDUSTRY_NXMODBUS) + + set(CSRCS) + + # Core sources + list(APPEND CSRCS core/nxmb_context.c core/nxmb_utils.c) + + if(CONFIG_NXMODBUS_SERVER) + list(APPEND CSRCS core/nxmb_server.c) + list(APPEND CSRCS core/nxmb_func.c) + list(APPEND CSRCS core/nxmb_func_coils.c core/nxmb_func_discrete.c) + list(APPEND CSRCS core/nxmb_func_holding.c core/nxmb_func_input.c) + list(APPEND CSRCS core/nxmb_func_diag.c core/nxmb_func_other.c) + endif() + + if(CONFIG_NXMODBUS_CLIENT) + list(APPEND CSRCS core/nxmb_client.c) + endif() + + # Transport layer sources + if(CONFIG_NXMODBUS_RTU OR CONFIG_NXMODBUS_ASCII) + list(APPEND CSRCS transport/nxmb_serial_common.c) + endif() + + if(CONFIG_NXMODBUS_RTU) + list(APPEND CSRCS transport/nxmb_crc.c transport/nxmb_serial.c) + endif() + + if(CONFIG_NXMODBUS_ASCII) + list(APPEND CSRCS transport/nxmb_lrc.c transport/nxmb_ascii.c) + endif() + + if(CONFIG_NXMODBUS_RAW_ADU) + list(APPEND CSRCS transport/nxmb_raw.c) + endif() + + if(CONFIG_NXMODBUS_TCP) + list(APPEND CSRCS transport/nxmb_tcp.c) + endif() + + if(CSRCS) + target_include_directories(apps PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_sources(apps PRIVATE ${CSRCS}) + endif() + +endif() diff --git a/industry/nxmodbus/Kconfig b/industry/nxmodbus/Kconfig new file mode 100644 index 000000000..31f555fe7 --- /dev/null +++ b/industry/nxmodbus/Kconfig @@ -0,0 +1,245 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig INDUSTRY_NXMODBUS + bool "NxModbus - New Modbus Stack" + default n + ---help--- + NxModbus is a modern Modbus stack for NuttX with multi-instance + support, per-instance register callbacks, and pluggable transport + backends (RTU, ASCII, TCP, Raw ADU). + + This implementation follows NuttX coding standards and is + designed for upstream contribution to nuttx-apps. + +if INDUSTRY_NXMODBUS + +config NXMODBUS_SERVER + bool "Server (slave) support" + default y + ---help--- + Enable Modbus server (slave) support. The server processes + incoming Modbus requests and calls registered register + callbacks. + +config NXMODBUS_CLIENT + bool "Client (master) support" + default n + ---help--- + Enable Modbus client (master) support. The client sends + Modbus requests to a server and receives responses. + +config NXMODBUS_RTU + bool "Modbus RTU mode" + default y + ---help--- + Enable Modbus RTU (Remote Terminal Unit) serial transmission + mode. Uses binary encoding with CRC16 error checking. + +config NXMODBUS_ASCII + bool "Modbus ASCII mode" + default n + ---help--- + Enable Modbus ASCII serial transmission mode. Uses + hex-encoded text with LRC error checking. Slower but + more human-readable than RTU. + +config NXMODBUS_TCP + bool "Modbus TCP mode" + default n + depends on NET_TCP + ---help--- + Enable Modbus TCP support. Modbus frames are encapsulated + in TCP/IP using the MBAP header format. Requires network + stack with TCP support. + +config NXMODBUS_RAW_ADU + bool "Raw ADU transport support" + default n + ---help--- + Enable raw ADU (Application Data Unit) transport mode. + The application provides callbacks for transmitting and + receiving raw Modbus frames. This enables custom transports + such as TLS, CAN, BLE, or MQTT. + +config NXMODBUS_MAX_INSTANCES + int "Maximum number of NxModbus instances" + default 1 + range 1 16 + ---help--- + Maximum number of simultaneous NxModbus instances. Each + instance can use a different transport (RTU, TCP, etc.) + and configuration. Instances are allocated from a static + pool at compile time. + +config NXMODBUS_ADU_DATA_MAX + int "ADU data buffer size in bytes" + default 252 + range 4 252 + ---help--- + Size of the data[] payload in struct nxmb_adu_s, in bytes. + This is the PDU body after the function code. The Modbus + specification allows up to 252 data bytes (1 fc + 252 data = + 253-byte PDU max). Reduce this value to save RAM on + resource-constrained systems. + +config NXMODBUS_REP_SERVER_ID_BUF + int "Report Server ID buffer size" + default 32 + range 4 253 + ---help--- + Size of the buffer used by FC17 (Report Server ID). + This buffer holds the server ID byte, run indicator, and + optional additional data configured via nxmb_set_server_id(). + +config NXMODBUS_ASCII_TIMEOUT_SEC + int "ASCII character timeout (seconds)" + default 1 + range 1 60 + depends on NXMODBUS_ASCII + ---help--- + Character timeout for Modbus ASCII mode in seconds. If no + character is received within this period, the current frame + is discarded. Default is 1 second per the Modbus specification. + +config NXMODBUS_CLIENT_TIMEOUT_MS + int "Client default response timeout (ms)" + default 1000 + range 100 60000 + depends on NXMODBUS_CLIENT + ---help--- + Default response timeout for client (master) mode in + milliseconds. If no response is received from the server + within this period, the request fails with ETIMEDOUT. + Can be overridden at runtime via nxmb_set_timeout(). + +config NXMODBUS_TCP_MAX_CLIENTS + int "Maximum simultaneous TCP client connections" + default 1 + range 1 8 + depends on NXMODBUS_TCP + ---help--- + Maximum number of simultaneous TCP client connections + accepted by a Modbus TCP server instance. Each connection + uses one file descriptor. Set to 1 for minimal resource + usage. + +config NXMODBUS_TCP_TIMEOUT_SEC + int "TCP idle connection timeout (seconds)" + default 60 + range 1 3600 + depends on NXMODBUS_TCP + ---help--- + Idle timeout for TCP connections in seconds. If no data is + received on a client connection within this period, the + connection is closed. Set to a higher value for slow networks. + +config NXMODBUS_RTU_IDLE_TIMEOUT_MS + int "RTU inter-frame idle timeout (ms)" + default 50 + range 1 1000 + depends on NXMODBUS_RTU + ---help--- + Fallback idle timeout in milliseconds used by the RTU + transport when waiting for a new frame via select(). This + is the maximum time to block waiting for data when no + frame is in progress. The T3.5 character timing is still + used for frame delimiting within an active reception. + +menu "Function Code Selection" + +config NXMODBUS_FUNC_READ_COILS + bool "FC01 Read Coils" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC01 Read Coils function code handler. + +config NXMODBUS_FUNC_READ_DISCRETE + bool "FC02 Read Discrete Inputs" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC02 Read Discrete Inputs function code handler. + +config NXMODBUS_FUNC_READ_HOLDING + bool "FC03 Read Holding Registers" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC03 Read Holding Registers function code handler. + +config NXMODBUS_FUNC_READ_INPUT + bool "FC04 Read Input Registers" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC04 Read Input Registers function code handler. + +config NXMODBUS_FUNC_WRITE_COIL + bool "FC05 Write Single Coil" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC05 Write Single Coil function code handler. + +config NXMODBUS_FUNC_WRITE_HOLDING + bool "FC06 Write Single Holding Register" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC06 Write Single Holding Register function + code handler. + +config NXMODBUS_FUNC_DIAGNOSTICS + bool "FC08 Diagnostics" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC08 Diagnostics function code handler. + Only sub-function 0x0000 (Return Query Data) is supported. + +config NXMODBUS_FUNC_WRITE_COILS + bool "FC15 Write Multiple Coils" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC15 Write Multiple Coils function code handler. + +config NXMODBUS_FUNC_WRITE_HOLDINGS + bool "FC16 Write Multiple Holding Registers" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC16 Write Multiple Holding Registers function + code handler. + +config NXMODBUS_FUNC_REPORT_SERVER_ID + bool "FC17 Report Server ID" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC17 Report Server ID function code handler. + +config NXMODBUS_FUNC_READWRITE_HOLDINGS + bool "FC23 Read/Write Multiple Holding Registers" + default y + depends on NXMODBUS_SERVER + ---help--- + Enable FC23 Read/Write Multiple Holding Registers + function code handler. + +endmenu # Function Code Selection + +config NXMODBUS_CUSTOM_FC + bool "Custom function code extension support" + default y + depends on NXMODBUS + ---help--- + Enable support for registering custom Modbus function + code handlers. Applications can extend the Modbus + function code set via nxmb_register_custom_fc(). + +endif # INDUSTRY_NXMODBUS diff --git a/industry/nxmodbus/Make.defs b/industry/nxmodbus/Make.defs new file mode 100644 index 000000000..539b48d64 --- /dev/null +++ b/industry/nxmodbus/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/modbus/nxmodbus/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_INDUSTRY_NXMODBUS),) +CONFIGURED_APPS += $(APPDIR)/industry/nxmodbus +endif diff --git a/industry/nxmodbus/Makefile b/industry/nxmodbus/Makefile new file mode 100644 index 000000000..64caacdba --- /dev/null +++ b/industry/nxmodbus/Makefile @@ -0,0 +1,76 @@ +############################################################################ +# apps/industry/nxmodbus/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# NxModbus Library + +ifeq ($(CONFIG_INDUSTRY_NXMODBUS),y) + +# Core sources +CSRCS := core/nxmb_context.c +CSRCS += core/nxmb_utils.c + +ifeq ($(CONFIG_NXMODBUS_SERVER),y) +CSRCS += core/nxmb_server.c +CSRCS += core/nxmb_func.c +CSRCS += core/nxmb_func_coils.c +CSRCS += core/nxmb_func_discrete.c +CSRCS += core/nxmb_func_holding.c +CSRCS += core/nxmb_func_input.c +CSRCS += core/nxmb_func_diag.c +CSRCS += core/nxmb_func_other.c +endif + +ifeq ($(CONFIG_NXMODBUS_CLIENT),y) +CSRCS += core/nxmb_client.c +endif + +# Transport layer sources +ifneq (,$(filter y,$(CONFIG_NXMODBUS_RTU) $(CONFIG_NXMODBUS_ASCII))) +CSRCS += transport/nxmb_serial_common.c +endif + +ifeq ($(CONFIG_NXMODBUS_RTU),y) +CSRCS += transport/nxmb_crc.c +CSRCS += transport/nxmb_serial.c +endif + +ifeq ($(CONFIG_NXMODBUS_ASCII),y) +CSRCS += transport/nxmb_lrc.c +CSRCS += transport/nxmb_ascii.c +endif + +ifeq ($(CONFIG_NXMODBUS_RAW_ADU),y) +CSRCS += transport/nxmb_raw.c +endif + +ifeq ($(CONFIG_NXMODBUS_TCP),y) +CSRCS += transport/nxmb_tcp.c +endif + +# Include private headers +CFLAGS += ${INCDIR_PREFIX}$(CURDIR) + +endif + +include $(APPDIR)/Application.mk diff --git a/industry/nxmodbus/core/nxmb_client.c b/industry/nxmodbus/core/nxmb_client.c new file mode 100644 index 000000000..24b264f92 --- /dev/null +++ b/industry/nxmodbus/core/nxmb_client.c @@ -0,0 +1,739 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_client.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct nxmb_client_state_s +{ + uint32_t timeout_ms; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int nxmb_client_tx_wait_rx(nxmb_handle_t ctx, + uint8_t expected_uid, uint8_t expected_fc); +static int nxmb_client_validate_response(nxmb_handle_t ctx, + uint8_t expected_uid, + uint8_t expected_fc); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_exception_to_errno + ****************************************************************************/ + +static int nxmb_exception_to_errno(uint8_t exception) +{ + switch (exception) + { + case NXMB_EX_ILLEGAL_FUNCTION: + return -ENXIO; + + case NXMB_EX_ILLEGAL_DATA_ADDRESS: + return -EFAULT; + + case NXMB_EX_ILLEGAL_DATA_VALUE: + return -EINVAL; + + case NXMB_EX_DEVICE_FAILURE: + return -EIO; + + case NXMB_EX_ACKNOWLEDGE: + return -EBUSY; + + case NXMB_EX_DEVICE_BUSY: + return -EBUSY; + + default: + return -EPROTO; + } +} + +/**************************************************************************** + * Name: nxmb_client_validate_response + ****************************************************************************/ + +static int nxmb_client_validate_response(nxmb_handle_t ctx, + uint8_t expected_uid, + uint8_t expected_fc) +{ + uint8_t rx_uid; + uint8_t rx_fc; + + if (ctx->adu.length < 2) + { + return -EPROTO; + } + + rx_uid = ctx->adu.unit_id; + rx_fc = ctx->adu.fc; + + if (rx_uid != expected_uid) + { + return -EPROTO; + } + + if (rx_fc == (expected_fc | 0x80)) + { + if (ctx->adu.length < 3) + { + return -EPROTO; + } + + return nxmb_exception_to_errno(ctx->adu.data[0]); + } + + if (rx_fc != expected_fc) + { + return -EPROTO; + } + + return OK; +} + +/**************************************************************************** + * Name: nxmb_client_tx_wait_rx + ****************************************************************************/ + +static int nxmb_client_tx_wait_rx(nxmb_handle_t ctx, uint8_t expected_uid, + uint8_t expected_fc) +{ + FAR struct nxmb_client_state_s *state; + uint64_t deadline; + int ret; + + if (ctx == NULL || ctx->client_state == NULL) + { + return -EINVAL; + } + + state = (FAR struct nxmb_client_state_s *)ctx->client_state; + + ret = ctx->transport_ops->send(ctx); + if (ret < 0) + { + return ret; + } + + /* Broadcast frames do not receive a response */ + + if (expected_uid == NXMB_ADDRESS_BROADCAST) + { + return OK; + } + + deadline = nxmb_util_clock_ms() + state->timeout_ms; + + for (; ; ) + { + if (nxmb_util_clock_ms() >= deadline) + { + return -ETIMEDOUT; + } + + ret = ctx->transport_ops->receive(ctx); + if (ret > 0) + { + return nxmb_client_validate_response(ctx, expected_uid, + expected_fc); + } + else if (ret < 0 && ret != -EAGAIN) + { + return ret; + } + } +} + +/**************************************************************************** + * Name: nxmb_client_read_bits + * + * Description: + * Common helper for FC01 (Read Coils) and FC02 (Read Discrete Inputs). + * + ****************************************************************************/ + +static int nxmb_client_read_bits(nxmb_handle_t ctx, uint8_t uid, uint8_t fc, + uint16_t addr, uint16_t count, + FAR uint8_t *buf) +{ + uint16_t nbytes; + int ret; + + nbytes = (count + 7) / 8; + + pthread_mutex_lock(&ctx->lock); + + ctx->adu.unit_id = uid; + ctx->adu.fc = fc; + nxmb_util_put_u16_be(&ctx->adu.data[0], addr); + nxmb_util_put_u16_be(&ctx->adu.data[2], count); + ctx->adu.length = 6; + + ret = nxmb_client_tx_wait_rx(ctx, uid, fc); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + + if (ctx->adu.length < (3 + nbytes) || ctx->adu.data[0] != nbytes) + { + pthread_mutex_unlock(&ctx->lock); + return -EPROTO; + } + + memcpy(buf, &ctx->adu.data[1], nbytes); + + pthread_mutex_unlock(&ctx->lock); + + return OK; +} + +/**************************************************************************** + * Name: nxmb_client_read_regs + * + * Description: + * Common helper for FC03 (Read Holding) and FC04 (Read Input) registers. + * + ****************************************************************************/ + +static int nxmb_client_read_regs(nxmb_handle_t ctx, uint8_t uid, uint8_t fc, + uint16_t addr, uint16_t count, + FAR uint16_t *buf) +{ + uint16_t nbytes; + int ret; + int i; + + nbytes = count * 2; + + pthread_mutex_lock(&ctx->lock); + + ctx->adu.unit_id = uid; + ctx->adu.fc = fc; + nxmb_util_put_u16_be(&ctx->adu.data[0], addr); + nxmb_util_put_u16_be(&ctx->adu.data[2], count); + ctx->adu.length = 6; + + ret = nxmb_client_tx_wait_rx(ctx, uid, fc); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + + if (ctx->adu.length < (3 + nbytes) || ctx->adu.data[0] != nbytes) + { + pthread_mutex_unlock(&ctx->lock); + return -EPROTO; + } + + for (i = 0; i < count; i++) + { + buf[i] = nxmb_util_get_u16_be(&ctx->adu.data[1 + i * 2]); + } + + pthread_mutex_unlock(&ctx->lock); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_read_coils + ****************************************************************************/ + +int nxmb_read_coils(nxmb_handle_t ctx, uint8_t uid, uint16_t addr, + uint16_t count, FAR uint8_t *buf) +{ + DEBUGASSERT(ctx && buf); + + if (uid == NXMB_ADDRESS_BROADCAST || count == 0 || count > 2000) + { + return -EINVAL; + } + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + return nxmb_client_read_bits(ctx, uid, NXMB_FC_READ_COILS, addr, + count, buf); +} + +/**************************************************************************** + * Name: nxmb_read_discrete + ****************************************************************************/ + +int nxmb_read_discrete(nxmb_handle_t ctx, uint8_t uid, uint16_t addr, + uint16_t count, FAR uint8_t *buf) +{ + DEBUGASSERT(ctx && buf); + + if (uid == NXMB_ADDRESS_BROADCAST || count == 0 || count > 2000) + { + return -EINVAL; + } + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + return nxmb_client_read_bits(ctx, uid, NXMB_FC_READ_DISCRETE, addr, + count, buf); +} + +/**************************************************************************** + * Name: nxmb_read_input + ****************************************************************************/ + +int nxmb_read_input(nxmb_handle_t ctx, uint8_t uid, uint16_t addr, + uint16_t count, FAR uint16_t *buf) +{ + DEBUGASSERT(ctx && buf); + + if (uid == NXMB_ADDRESS_BROADCAST || count == 0 || count > 125) + { + return -EINVAL; + } + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + return nxmb_client_read_regs(ctx, uid, NXMB_FC_READ_INPUT, addr, + count, buf); +} + +/**************************************************************************** + * Name: nxmb_read_holding + ****************************************************************************/ + +int nxmb_read_holding(nxmb_handle_t ctx, uint8_t uid, uint16_t addr, + uint16_t count, FAR uint16_t *buf) +{ + DEBUGASSERT(ctx && buf); + + if (uid == NXMB_ADDRESS_BROADCAST || count == 0 || count > 125) + { + return -EINVAL; + } + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + return nxmb_client_read_regs(ctx, uid, NXMB_FC_READ_HOLDING, addr, + count, buf); +} + +/**************************************************************************** + * Name: nxmb_write_coil + ****************************************************************************/ + +int nxmb_write_coil(nxmb_handle_t ctx, uint8_t uid, uint16_t addr, + bool value) +{ + uint16_t coil_value; + int ret; + + DEBUGASSERT(ctx); + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + coil_value = value ? 0xff00 : 0x0000; + + pthread_mutex_lock(&ctx->lock); + + ctx->adu.unit_id = uid; + ctx->adu.fc = NXMB_FC_WRITE_COIL; + nxmb_util_put_u16_be(&ctx->adu.data[0], addr); + nxmb_util_put_u16_be(&ctx->adu.data[2], coil_value); + ctx->adu.length = 6; + + ret = nxmb_client_tx_wait_rx(ctx, uid, NXMB_FC_WRITE_COIL); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + + if (uid != NXMB_ADDRESS_BROADCAST && ctx->adu.length < 6) + { + pthread_mutex_unlock(&ctx->lock); + return -EPROTO; + } + + pthread_mutex_unlock(&ctx->lock); + + return OK; +} + +/**************************************************************************** + * Name: nxmb_write_holding + ****************************************************************************/ + +int nxmb_write_holding(nxmb_handle_t ctx, uint8_t uid, uint16_t addr, + uint16_t value) +{ + int ret; + + DEBUGASSERT(ctx); + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + pthread_mutex_lock(&ctx->lock); + + ctx->adu.unit_id = uid; + ctx->adu.fc = NXMB_FC_WRITE_HOLDING; + nxmb_util_put_u16_be(&ctx->adu.data[0], addr); + nxmb_util_put_u16_be(&ctx->adu.data[2], value); + ctx->adu.length = 6; + + ret = nxmb_client_tx_wait_rx(ctx, uid, NXMB_FC_WRITE_HOLDING); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + + if (uid != NXMB_ADDRESS_BROADCAST && ctx->adu.length < 6) + { + pthread_mutex_unlock(&ctx->lock); + return -EPROTO; + } + + pthread_mutex_unlock(&ctx->lock); + + return OK; +} + +/**************************************************************************** + * Name: nxmb_write_coils + ****************************************************************************/ + +int nxmb_write_coils(nxmb_handle_t ctx, uint8_t uid, uint16_t addr, + uint16_t count, FAR const uint8_t *buf) +{ + uint16_t nbytes; + int ret; + + DEBUGASSERT(ctx && buf); + + if (count == 0 || count > 1968) + { + return -EINVAL; + } + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + nbytes = (count + 7) / 8; + + /* Request layout in adu.data[]: addr(2) + count(2) + bcnt(1) + nbytes */ + + if (5 + nbytes > NXMB_ADU_DATA_MAX) + { + return -EMSGSIZE; + } + + pthread_mutex_lock(&ctx->lock); + + ctx->adu.unit_id = uid; + ctx->adu.fc = NXMB_FC_WRITE_COILS; + nxmb_util_put_u16_be(&ctx->adu.data[0], addr); + nxmb_util_put_u16_be(&ctx->adu.data[2], count); + ctx->adu.data[4] = nbytes; + memcpy(&ctx->adu.data[5], buf, nbytes); + ctx->adu.length = 7 + nbytes; + + ret = nxmb_client_tx_wait_rx(ctx, uid, NXMB_FC_WRITE_COILS); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + + if (uid != NXMB_ADDRESS_BROADCAST && ctx->adu.length < 6) + { + pthread_mutex_unlock(&ctx->lock); + return -EPROTO; + } + + pthread_mutex_unlock(&ctx->lock); + + return OK; +} + +/**************************************************************************** + * Name: nxmb_write_holdings + ****************************************************************************/ + +int nxmb_write_holdings(nxmb_handle_t ctx, uint8_t uid, uint16_t addr, + uint16_t count, FAR const uint16_t *buf) +{ + uint16_t nbytes; + int ret; + int i; + + DEBUGASSERT(ctx && buf); + + if (count == 0 || count > 123) + { + return -EINVAL; + } + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + nbytes = count * 2; + + /* Request layout in adu.data[]: addr(2) + count(2) + bcnt(1) + nbytes */ + + if (5 + nbytes > NXMB_ADU_DATA_MAX) + { + return -EMSGSIZE; + } + + pthread_mutex_lock(&ctx->lock); + + ctx->adu.unit_id = uid; + ctx->adu.fc = NXMB_FC_WRITE_HOLDINGS; + nxmb_util_put_u16_be(&ctx->adu.data[0], addr); + nxmb_util_put_u16_be(&ctx->adu.data[2], count); + ctx->adu.data[4] = nbytes; + + for (i = 0; i < count; i++) + { + nxmb_util_put_u16_be(&ctx->adu.data[5 + i * 2], buf[i]); + } + + ctx->adu.length = 7 + nbytes; + + ret = nxmb_client_tx_wait_rx(ctx, uid, NXMB_FC_WRITE_HOLDINGS); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + + if (uid != NXMB_ADDRESS_BROADCAST && ctx->adu.length < 6) + { + pthread_mutex_unlock(&ctx->lock); + return -EPROTO; + } + + pthread_mutex_unlock(&ctx->lock); + + return OK; +} + +/**************************************************************************** + * Name: nxmb_readwrite_holdings + ****************************************************************************/ + +int nxmb_readwrite_holdings(nxmb_handle_t ctx, uint8_t uid, uint16_t rd_addr, + uint16_t rd_count, FAR uint16_t *rd_buf, + uint16_t wr_addr, uint16_t wr_count, + FAR const uint16_t *wr_buf) +{ + uint16_t rd_nbytes; + uint16_t wr_nbytes; + int ret; + int i; + + DEBUGASSERT(ctx && rd_buf && wr_buf); + + if (uid == NXMB_ADDRESS_BROADCAST || rd_count == 0 || rd_count > 125 || + wr_count == 0 || wr_count > 121) + { + return -EINVAL; + } + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + rd_nbytes = rd_count * 2; + wr_nbytes = wr_count * 2; + + /* Request layout: rd_addr(2) + rd_qty(2) + wr_addr(2) + wr_qty(2) + + * wr_bcnt(1) + wr_nbytes + */ + + if (9 + wr_nbytes > NXMB_ADU_DATA_MAX) + { + return -EMSGSIZE; + } + + pthread_mutex_lock(&ctx->lock); + + ctx->adu.unit_id = uid; + ctx->adu.fc = NXMB_FC_READWRITE_HOLDINGS; + nxmb_util_put_u16_be(&ctx->adu.data[0], rd_addr); + nxmb_util_put_u16_be(&ctx->adu.data[2], rd_count); + nxmb_util_put_u16_be(&ctx->adu.data[4], wr_addr); + nxmb_util_put_u16_be(&ctx->adu.data[6], wr_count); + ctx->adu.data[8] = (uint8_t)wr_nbytes; + + for (i = 0; i < wr_count; i++) + { + nxmb_util_put_u16_be(&ctx->adu.data[9 + i * 2], wr_buf[i]); + } + + ctx->adu.length = 11 + wr_nbytes; + + ret = nxmb_client_tx_wait_rx(ctx, uid, NXMB_FC_READWRITE_HOLDINGS); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + + if (ctx->adu.length < (3 + rd_nbytes)) + { + pthread_mutex_unlock(&ctx->lock); + return -EPROTO; + } + + if (ctx->adu.data[0] != rd_nbytes) + { + pthread_mutex_unlock(&ctx->lock); + return -EPROTO; + } + + for (i = 0; i < rd_count; i++) + { + rd_buf[i] = nxmb_util_get_u16_be(&ctx->adu.data[1 + i * 2]); + } + + pthread_mutex_unlock(&ctx->lock); + + return OK; +} + +/**************************************************************************** + * Name: nxmb_set_timeout + ****************************************************************************/ + +int nxmb_set_timeout(nxmb_handle_t ctx, uint32_t timeout_ms) +{ + FAR struct nxmb_client_state_s *state; + + DEBUGASSERT(ctx && ctx->client_state); + + if (!ctx->is_client) + { + return -ENOTSUP; + } + + state = (FAR struct nxmb_client_state_s *)ctx->client_state; + + pthread_mutex_lock(&ctx->lock); + state->timeout_ms = timeout_ms; + pthread_mutex_unlock(&ctx->lock); + + return OK; +} + +/**************************************************************************** + * Name: nxmb_client_init + ****************************************************************************/ + +int nxmb_client_init(nxmb_handle_t ctx) +{ + FAR struct nxmb_client_state_s *state; + + DEBUGASSERT(ctx && ctx->is_client); + + state = calloc(1, sizeof(struct nxmb_client_state_s)); + if (state == NULL) + { + return -ENOMEM; + } + + state->timeout_ms = CONFIG_NXMODBUS_CLIENT_TIMEOUT_MS; + + ctx->client_state = state; + + return OK; +} + +/**************************************************************************** + * Name: nxmb_client_deinit + ****************************************************************************/ + +int nxmb_client_deinit(nxmb_handle_t ctx) +{ + FAR struct nxmb_client_state_s *state; + + DEBUGASSERT(ctx && ctx->client_state); + + state = (FAR struct nxmb_client_state_s *)ctx->client_state; + + free(state); + + ctx->client_state = NULL; + + return OK; +} diff --git a/industry/nxmodbus/core/nxmb_context.c b/industry/nxmodbus/core/nxmb_context.c new file mode 100644 index 000000000..e6a76c581 --- /dev/null +++ b/industry/nxmodbus/core/nxmb_context.c @@ -0,0 +1,392 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_context.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct nxmb_context_s g_nxmb_pool[CONFIG_NXMODBUS_MAX_INSTANCES]; +static pthread_mutex_t g_pool_lock = PTHREAD_MUTEX_INITIALIZER; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_create + * + * Description: + * Create a new NxModbus instance. + * + * Input Parameters: + * handle - Pointer to receive the instance handle + * config - Instance configuration + * + * Returned Value: + * 0 on success, negative errno on failure + * + ****************************************************************************/ + +int nxmb_create(FAR nxmb_handle_t *handle, + FAR const struct nxmb_config_s *config) +{ + nxmb_handle_t ctx = NULL; + int ret = -ENOMEM; + int i; + + DEBUGASSERT(handle && config); + +#ifndef CONFIG_NXMODBUS_CLIENT + if (config->is_client) + { + /* Master not supported */ + + return -EINVAL; + } +#endif + + pthread_mutex_lock(&g_pool_lock); + + for (i = 0; i < CONFIG_NXMODBUS_MAX_INSTANCES; i++) + { + if (g_nxmb_pool[i].mode == NXMB_MODE_INVAL) + { + ctx = &g_nxmb_pool[i]; + break; + } + } + + if (ctx != NULL) + { + memset(ctx, 0, sizeof(struct nxmb_context_s)); + + ret = pthread_mutex_init(&ctx->lock, NULL); + if (ret == 0) + { + ctx->mode = config->mode; + ctx->unit_id = config->unit_id; + ctx->is_client = config->is_client; + + switch (config->mode) + { +#ifdef CONFIG_NXMODBUS_RTU + case NXMB_MODE_RTU: + ctx->transport_cfg.serial = config->transport.serial; + ctx->transport_ops = &g_nxmb_serial_ops; + break; +#endif + +#ifdef CONFIG_NXMODBUS_ASCII + case NXMB_MODE_ASCII: + ctx->transport_cfg.serial = config->transport.serial; + ctx->transport_ops = &g_nxmb_ascii_ops; + break; +#endif + +#ifdef CONFIG_NXMODBUS_TCP + case NXMB_MODE_TCP: + ctx->transport_cfg.tcp = config->transport.tcp; + ctx->transport_ops = &g_nxmb_tcp_ops; + break; +#endif + +#ifdef CONFIG_NXMODBUS_RAW_ADU + case NXMB_MODE_RAW: + ctx->transport_cfg.raw = config->transport.raw; + ctx->transport_ops = &g_nxmb_raw_ops; + break; +#endif + + default: + pthread_mutex_destroy(&ctx->lock); + memset(ctx, 0, sizeof(struct nxmb_context_s)); + ret = -EINVAL; + goto out; + } + + *handle = ctx; + ret = 0; + } + else + { + memset(ctx, 0, sizeof(struct nxmb_context_s)); + ret = -ret; + } + } + +out: + pthread_mutex_unlock(&g_pool_lock); + return ret; +} + +/**************************************************************************** + * Name: nxmb_destroy + * + * Description: + * Destroy an NxModbus instance. + * + * Input Parameters: + * handle - Instance handle + * + * Returned Value: + * 0 on success, negative errno on failure + * + ****************************************************************************/ + +int nxmb_destroy(nxmb_handle_t ctx) +{ +#ifdef CONFIG_NXMODBUS_CUSTOM_FC + FAR struct nxmb_custom_fc_s *entry; + FAR struct nxmb_custom_fc_s *next; +#endif + + DEBUGASSERT(ctx); + + pthread_mutex_lock(&g_pool_lock); + pthread_mutex_lock(&ctx->lock); + + if (ctx->enabled) + { + pthread_mutex_unlock(&ctx->lock); + pthread_mutex_unlock(&g_pool_lock); + return -EBUSY; + } + + pthread_mutex_unlock(&ctx->lock); + pthread_mutex_destroy(&ctx->lock); + +#ifdef CONFIG_NXMODBUS_CUSTOM_FC + entry = ctx->custom_fc_list; + while (entry != NULL) + { + next = entry->next; + free(entry); + entry = next; + } +#endif + + memset(ctx, 0, sizeof(struct nxmb_context_s)); + pthread_mutex_unlock(&g_pool_lock); + + return 0; +} + +/**************************************************************************** + * Name: nxmb_set_callbacks + * + * Description: + * Set application callbacks for register access. + * + * Input Parameters: + * handle - Instance handle + * callbacks - Pointer to callback structure + * + * Returned Value: + * 0 on success, negative errno on failure + * + ****************************************************************************/ + +int nxmb_set_callbacks(nxmb_handle_t ctx, + FAR const struct nxmb_callbacks_s *callbacks) +{ + DEBUGASSERT(ctx); + + pthread_mutex_lock(&ctx->lock); + ctx->callbacks = callbacks; + pthread_mutex_unlock(&ctx->lock); + + return 0; +} + +/**************************************************************************** + * Name: nxmb_enable + * + * Description: + * Enable an NxModbus instance and initialize transport. + * + * Input Parameters: + * handle - Instance handle + * + * Returned Value: + * 0 on success, negative errno on failure + * + ****************************************************************************/ + +int nxmb_enable(nxmb_handle_t ctx) +{ + int ret; + + DEBUGASSERT(ctx && ctx->transport_ops && ctx->transport_ops->init); + + pthread_mutex_lock(&ctx->lock); + + if (ctx->enabled) + { + pthread_mutex_unlock(&ctx->lock); + return -EBUSY; + } + +#ifdef CONFIG_NXMODBUS_CLIENT + if (ctx->is_client) + { + ret = nxmb_client_init(ctx); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + } +#endif + + /* Initialize transport */ + + ret = ctx->transport_ops->init(ctx); + if (ret < 0) + { +#ifdef CONFIG_NXMODBUS_CLIENT + if (ctx->is_client) + { + nxmb_client_deinit(ctx); + } +#endif + + pthread_mutex_unlock(&ctx->lock); + return ret; + } + + ctx->enabled = true; + pthread_mutex_unlock(&ctx->lock); + + return 0; +} + +/**************************************************************************** + * Name: nxmb_set_server_id + * + * Description: + * Configure the data returned by FC17 (Report Server ID). + * + * Input Parameters: + * handle - Instance handle + * id - Server ID byte + * is_running - True if device is running + * additional - Optional additional data (may be NULL) + * addlen - Length of additional data + * + * Returned Value: + * 0 on success, negative errno on failure + * + ****************************************************************************/ + +int nxmb_set_server_id(nxmb_handle_t ctx, uint8_t id, bool is_running, + FAR const uint8_t *additional, uint16_t addlen) +{ + DEBUGASSERT(ctx); + + /* The first two bytes are server ID and run indicator. + * The rest is optional additional data. + */ + + if (addlen + 2 > CONFIG_NXMODBUS_REP_SERVER_ID_BUF) + { + return -ENOMEM; + } + + pthread_mutex_lock(&ctx->lock); + + ctx->server_id_len = 0; + ctx->server_id_buf[ctx->server_id_len++] = id; + ctx->server_id_buf[ctx->server_id_len++] = + (uint8_t)(is_running ? 0xff : 0x00); + + if (addlen > 0 && additional != NULL) + { + memcpy(&ctx->server_id_buf[ctx->server_id_len], additional, + (size_t)addlen); + ctx->server_id_len += addlen; + } + + pthread_mutex_unlock(&ctx->lock); + + return 0; +} + +/**************************************************************************** + * Name: nxmb_disable + * + * Description: + * Disable an NxModbus instance and deinitialize transport. + * + * Input Parameters: + * handle - Instance handle + * + * Returned Value: + * 0 on success, negative errno on failure + * + ****************************************************************************/ + +int nxmb_disable(nxmb_handle_t ctx) +{ + DEBUGASSERT(ctx && ctx->transport_ops && ctx->transport_ops->deinit); + + pthread_mutex_lock(&ctx->lock); + + if (!ctx->enabled) + { + pthread_mutex_unlock(&ctx->lock); + return 0; + } + + ctx->transport_ops->deinit(ctx); + +#ifdef CONFIG_NXMODBUS_CLIENT + if (ctx->is_client) + { + nxmb_client_deinit(ctx); + } +#endif + + ctx->enabled = false; + pthread_mutex_unlock(&ctx->lock); + + return 0; +} diff --git a/industry/nxmodbus/core/nxmb_func.c b/industry/nxmodbus/core/nxmb_func.c new file mode 100644 index 000000000..13b595b4f --- /dev/null +++ b/industry/nxmodbus/core/nxmb_func.c @@ -0,0 +1,354 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_func.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXMB_EXCEPTION_FLAG 0x80 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Function code handler signature */ + +typedef enum nxmb_exception_e (*nxmb_fc_handler_t)(nxmb_handle_t ctx); + +/* Dispatch table entry */ + +struct nxmb_fc_entry_s +{ + uint8_t fc; + nxmb_fc_handler_t handler; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Standard function code dispatch table */ + +static const struct nxmb_fc_entry_s g_nxmb_fc_table[] = +{ +#ifdef CONFIG_NXMODBUS_FUNC_READ_COILS + { NXMB_FC_READ_COILS, nxmb_fc01_read_coils }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_READ_DISCRETE + { NXMB_FC_READ_DISCRETE, nxmb_fc02_read_discrete }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_READ_HOLDING + { NXMB_FC_READ_HOLDING, nxmb_fc03_read_holding }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_READ_INPUT + { NXMB_FC_READ_INPUT, nxmb_fc04_read_input }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_WRITE_COIL + { NXMB_FC_WRITE_COIL, nxmb_fc05_write_coil }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_WRITE_HOLDING + { NXMB_FC_WRITE_HOLDING, nxmb_fc06_write_holding }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_DIAGNOSTICS + { NXMB_FC_DIAGNOSTICS, nxmb_fc08_diagnostics }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_WRITE_COILS + { NXMB_FC_WRITE_COILS, nxmb_fc15_write_coils }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_WRITE_HOLDINGS + { NXMB_FC_WRITE_HOLDINGS, nxmb_fc16_write_holdings }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_REPORT_SERVER_ID + { NXMB_FC_REPORT_SERVER_ID, nxmb_fc17_report_server_id }, +#endif +#ifdef CONFIG_NXMODBUS_FUNC_READWRITE_HOLDINGS + { NXMB_FC_READWRITE_HOLDINGS, nxmb_fc23_readwrite_holding } +#endif +}; + +#define NXMB_FC_TABLE_SIZE \ + (sizeof(g_nxmb_fc_table) / sizeof(g_nxmb_fc_table[0])) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_build_exception + * + * Description: + * Build a Modbus exception response in ctx->adu in place. + * + * Input Parameters: + * ctx - Instance context + * fc - Function code + * exception - NxModbus exception code + * + ****************************************************************************/ + +static void nxmb_build_exception(nxmb_handle_t ctx, uint8_t fc, + enum nxmb_exception_e exception) +{ + ctx->adu.fc = fc | NXMB_EXCEPTION_FLAG; + ctx->adu.data[0] = (uint8_t)exception; + + /* unit_id + fc + 1 exception byte */ + + ctx->adu.length = 3; +} + +/**************************************************************************** + * Name: nxmb_lookup_standard_fc + * + * Description: + * Look up a standard function code handler in the dispatch table. + * + * Input Parameters: + * fc - Function code to look up + * + * Returned Value: + * Handler function pointer, or NULL if not found + * + ****************************************************************************/ + +static nxmb_fc_handler_t nxmb_lookup_standard_fc(uint8_t fc) +{ + int i; + + for (i = 0; i < NXMB_FC_TABLE_SIZE; i++) + { + if (g_nxmb_fc_table[i].fc == fc) + { + return g_nxmb_fc_table[i].handler; + } + } + + return NULL; +} + +#ifdef CONFIG_NXMODBUS_CUSTOM_FC + +/**************************************************************************** + * Name: nxmb_lookup_custom_fc + * + * Description: + * Look up a custom function code handler in the instance list. + * + * Input Parameters: + * ctx - Instance context + * fc - Function code to look up + * + * Returned Value: + * Handler function pointer, or NULL if not found + * + ****************************************************************************/ + +static nxmb_custom_fc_handler_t nxmb_lookup_custom_fc( + nxmb_handle_t ctx, uint8_t fc) +{ + FAR struct nxmb_custom_fc_s *entry; + + for (entry = ctx->custom_fc_list; entry != NULL; entry = entry->next) + { + if (entry->fc == fc) + { + return entry->handler; + } + } + + return NULL; +} + +#endif /* CONFIG_NXMODBUS_CUSTOM_FC */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_dispatch_function + * + * Description: + * Dispatch a Modbus function code to the appropriate handler. Operates in + * place on ctx->adu. Checks standard handlers first, then custom handlers + * if enabled. Builds an exception response if no handler is found or the + * handler fails. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +int nxmb_dispatch_function(nxmb_handle_t ctx) +{ + nxmb_fc_handler_t handler; + enum nxmb_exception_e exception; + uint8_t fc; +#ifdef CONFIG_NXMODBUS_CUSTOM_FC + nxmb_custom_fc_handler_t custom_handler; + int ret; +#endif + + DEBUGASSERT(ctx); + + if (ctx->adu.length < 2) + { + return -EINVAL; + } + + fc = ctx->adu.fc; + + /* Look up standard handler first */ + + handler = nxmb_lookup_standard_fc(fc); + +#ifdef CONFIG_NXMODBUS_CUSTOM_FC + + /* If not found, check custom handlers */ + + if (handler == NULL) + { + custom_handler = nxmb_lookup_custom_fc(ctx, fc); + if (custom_handler != NULL) + { + ret = custom_handler(ctx); + if (ret < 0) + { + nxmb_build_exception(ctx, fc, NXMB_EX_DEVICE_FAILURE); + } + + return 0; + } + } +#endif + + /* If no handler found, return illegal function exception */ + + if (handler == NULL) + { + nxmb_build_exception(ctx, fc, NXMB_EX_ILLEGAL_FUNCTION); + return 0; + } + + /* Call the handler */ + + exception = handler(ctx); + + /* If handler returned exception, build exception response */ + + if (exception != NXMB_EX_NONE) + { + nxmb_build_exception(ctx, fc, exception); + } + + return 0; +} + +#ifdef CONFIG_NXMODBUS_CUSTOM_FC +/**************************************************************************** + * Name: nxmb_register_custom_fc + * + * Description: + * Register a custom Modbus function code handler for an instance. + * + * Custom handlers are checked after standard handlers, so standard + * function codes (FC01-FC16) cannot be overridden. + * + * Input Parameters: + * h - The NxModbus instance handle + * fc - The custom function code to register + * handler - The handler function + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +int nxmb_register_custom_fc(nxmb_handle_t ctx, uint8_t fc, + nxmb_custom_fc_handler_t handler) +{ + FAR struct nxmb_custom_fc_s *entry; + FAR struct nxmb_custom_fc_s *new_entry; + + DEBUGASSERT(ctx && handler); + + /* Check if FC is already a standard handler */ + + if (nxmb_lookup_standard_fc(fc) != NULL) + { + return -EEXIST; + } + + pthread_mutex_lock(&ctx->lock); + + /* Check if FC is already registered as custom */ + + for (entry = ctx->custom_fc_list; entry != NULL; entry = entry->next) + { + if (entry->fc == fc) + { + pthread_mutex_unlock(&ctx->lock); + return -EEXIST; + } + } + + /* Allocate new entry */ + + new_entry = malloc(sizeof(struct nxmb_custom_fc_s)); + if (new_entry == NULL) + { + pthread_mutex_unlock(&ctx->lock); + return -ENOMEM; + } + + /* Initialize and prepend to list */ + + new_entry->fc = fc; + new_entry->handler = handler; + new_entry->next = ctx->custom_fc_list; + ctx->custom_fc_list = new_entry; + + pthread_mutex_unlock(&ctx->lock); + return 0; +} + +#endif /* CONFIG_NXMODBUS_CUSTOM_FC */ diff --git a/industry/nxmodbus/core/nxmb_func_coils.c b/industry/nxmodbus/core/nxmb_func_coils.c new file mode 100644 index 000000000..3235fcc9e --- /dev/null +++ b/industry/nxmodbus/core/nxmb_func_coils.c @@ -0,0 +1,259 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_func_coils.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Offsets are in adu.data[]; lengths refer to data only. */ + +/* FC01 Read Coils */ + +#define NXMB_FC01_ADDR_OFF 0 +#define NXMB_FC01_QTY_OFF 2 +#define NXMB_FC01_REQ_DATA_LEN 4 + +/* FC05 Write Single Coil */ + +#define NXMB_FC05_ADDR_OFF 0 +#define NXMB_FC05_VALUE_OFF 2 +#define NXMB_FC05_REQ_DATA_LEN 4 + +/* FC15 Write Multiple Coils */ + +#define NXMB_FC15_ADDR_OFF 0 +#define NXMB_FC15_QTY_OFF 2 +#define NXMB_FC15_BCNT_OFF 4 +#define NXMB_FC15_DATA_OFF 5 +#define NXMB_FC15_RESP_DATA_LEN 4 + +/* Maximum coil quantity per Modbus specification. + * FC01/FC02 read max is 2000 (0x07D0). + * FC15 write max is 1968 (0x07B0). + */ + +#define NXMB_COIL_READ_QTY_MAX 2000 +#define NXMB_COIL_WRITE_QTY_MAX 1968 + +/* Coil ON/OFF wire values for FC05 */ + +#define NXMB_COIL_ON 0xff00 +#define NXMB_COIL_OFF 0x0000 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_fc01_read_coils + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc01_read_coils(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t addr; + uint16_t qty; + uint8_t nbytes; + int ret; + + if (data_len != NXMB_FC01_REQ_DATA_LEN) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if (ctx->callbacks == NULL || ctx->callbacks->coil_cb == NULL) + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + + addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC01_ADDR_OFF]); + qty = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC01_QTY_OFF]); + + if (qty < 1 || qty > NXMB_COIL_READ_QTY_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if ((uint32_t)addr + qty > 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + nbytes = (uint8_t)((qty + 7) / 8); + + /* Response is byte_count + coil data */ + + if (1 + nbytes > NXMB_ADU_DATA_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + /* Build response: byte_count + coil data */ + + ctx->adu.fc = NXMB_FC_READ_COILS; + ctx->adu.data[0] = nbytes; + + /* Zero data area so unused trailing bits are clear */ + + memset(&ctx->adu.data[1], 0, nbytes); + + ret = ctx->callbacks->coil_cb(&ctx->adu.data[1], addr, qty, NXMB_REG_READ, + ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + ctx->adu.length = (uint16_t)(2 + 1 + nbytes); + return NXMB_EX_NONE; +} + +/**************************************************************************** + * Name: nxmb_fc05_write_coil + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc05_write_coil(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t addr; + uint16_t value; + uint8_t coil_buf[2]; + int ret; + + if (data_len != NXMB_FC05_REQ_DATA_LEN) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if (ctx->callbacks == NULL || ctx->callbacks->coil_cb == NULL) + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + + addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC05_ADDR_OFF]); + value = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC05_VALUE_OFF]); + + if (addr == 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + if (value != NXMB_COIL_ON && value != NXMB_COIL_OFF) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + /* Convert wire value to single-bit buffer for callback */ + + coil_buf[0] = (value == NXMB_COIL_ON) ? 1 : 0; + coil_buf[1] = 0; + + ret = ctx->callbacks->coil_cb(coil_buf, addr, 1, NXMB_REG_WRITE, + ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + /* Response echoes the request — adu.length is already correct */ + + return NXMB_EX_NONE; +} + +/**************************************************************************** + * Name: nxmb_fc15_write_coils + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc15_write_coils(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t addr; + uint16_t qty; + uint8_t byte_count; + uint8_t byte_count_exp; + int ret; + + if (data_len < NXMB_FC15_DATA_OFF) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if (ctx->callbacks == NULL || ctx->callbacks->coil_cb == NULL) + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + + addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC15_ADDR_OFF]); + qty = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC15_QTY_OFF]); + byte_count = ctx->adu.data[NXMB_FC15_BCNT_OFF]; + + if (qty < 1 || qty > NXMB_COIL_WRITE_QTY_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if ((uint32_t)addr + qty > 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + byte_count_exp = (uint8_t)((qty + 7) / 8); + + if (byte_count != byte_count_exp) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + /* Verify total data length matches header + payload */ + + if (data_len != (uint16_t)(NXMB_FC15_DATA_OFF + byte_count)) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + ret = ctx->callbacks->coil_cb(&ctx->adu.data[NXMB_FC15_DATA_OFF], addr, + qty, NXMB_REG_WRITE, ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + /* Response: addr(2) + qty(2) — already in data[0..3] from request */ + + ctx->adu.length = (uint16_t)(2 + NXMB_FC15_RESP_DATA_LEN); + return NXMB_EX_NONE; +} diff --git a/industry/nxmodbus/core/nxmb_func_diag.c b/industry/nxmodbus/core/nxmb_func_diag.c new file mode 100644 index 000000000..8575c610d --- /dev/null +++ b/industry/nxmodbus/core/nxmb_func_diag.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_func_diag.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXMB_DIAG_SUBFUNC_OFF 0 +#define NXMB_DIAG_DATA_OFF 2 +#define NXMB_DIAG_REQ_MIN_DATA_LEN 4 + +/* Sub-function codes */ + +#define NXMB_DIAG_RETURN_QUERY 0x0000 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_fc08_diagnostics + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc08_diagnostics(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t subfunc; + + if (data_len < NXMB_DIAG_REQ_MIN_DATA_LEN) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + subfunc = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_DIAG_SUBFUNC_OFF]); + + switch (subfunc) + { + case NXMB_DIAG_RETURN_QUERY: + { + /* Response echoes the request — adu is already correct */ + + return NXMB_EX_NONE; + } + + default: + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + } +} diff --git a/industry/nxmodbus/core/nxmb_func_discrete.c b/industry/nxmodbus/core/nxmb_func_discrete.c new file mode 100644 index 000000000..b30a0a720 --- /dev/null +++ b/industry/nxmodbus/core/nxmb_func_discrete.c @@ -0,0 +1,110 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_func_discrete.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXMB_FC02_ADDR_OFF 0 +#define NXMB_FC02_QTY_OFF 2 +#define NXMB_FC02_REQ_DATA_LEN 4 + +#define NXMB_DISCRETE_QTY_MAX 2000 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_fc02_read_discrete + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc02_read_discrete(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t addr; + uint16_t qty; + uint8_t nbytes; + int ret; + + if (data_len != NXMB_FC02_REQ_DATA_LEN) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if (ctx->callbacks == NULL || ctx->callbacks->discrete_cb == NULL) + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + + addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC02_ADDR_OFF]); + qty = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC02_QTY_OFF]); + + if (qty < 1 || qty > NXMB_DISCRETE_QTY_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if ((uint32_t)addr + qty > 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + nbytes = (uint8_t)((qty + 7) / 8); + + /* Response is byte_count + discrete data */ + + if (1 + nbytes > NXMB_ADU_DATA_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + ctx->adu.fc = NXMB_FC_READ_DISCRETE; + ctx->adu.data[0] = nbytes; + + memset(&ctx->adu.data[1], 0, nbytes); + + ret = ctx->callbacks->discrete_cb(&ctx->adu.data[1], addr, qty, + ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + ctx->adu.length = (uint16_t)(2 + 1 + nbytes); + return NXMB_EX_NONE; +} diff --git a/industry/nxmodbus/core/nxmb_func_holding.c b/industry/nxmodbus/core/nxmb_func_holding.c new file mode 100644 index 000000000..a4fe74cc5 --- /dev/null +++ b/industry/nxmodbus/core/nxmb_func_holding.c @@ -0,0 +1,331 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_func_holding.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* PDU data offsets are relative to ctx->adu.data[] (after unit_id + fc). + * Lengths refer to the data payload only — adu.length = 2 + data_len. + */ + +/* FC03 Read Holding Registers */ + +#define NXMB_FC03_ADDR_OFF 0 +#define NXMB_FC03_QTY_OFF 2 +#define NXMB_FC03_REQ_DATA_LEN 4 + +/* FC06 Write Single Holding Register */ + +#define NXMB_FC06_ADDR_OFF 0 +#define NXMB_FC06_VALUE_OFF 2 +#define NXMB_FC06_REQ_DATA_LEN 4 + +/* FC16 Write Multiple Holding Registers */ + +#define NXMB_FC16_ADDR_OFF 0 +#define NXMB_FC16_QTY_OFF 2 +#define NXMB_FC16_BCNT_OFF 4 +#define NXMB_FC16_DATA_OFF 5 +#define NXMB_FC16_RESP_DATA_LEN 4 + +/* FC23 Read/Write Multiple Holding Registers */ + +#define NXMB_FC23_RD_ADDR_OFF 0 +#define NXMB_FC23_RD_QTY_OFF 2 +#define NXMB_FC23_WR_ADDR_OFF 4 +#define NXMB_FC23_WR_QTY_OFF 6 +#define NXMB_FC23_WR_BCNT_OFF 8 +#define NXMB_FC23_WR_DATA_OFF 9 +#define NXMB_FC23_REQ_MIN_DATA_LEN 9 + +/* Quantity limits per Modbus Application Protocol Specification */ + +#define NXMB_REG_READ_QTY_MAX 125 /* 0x007D */ +#define NXMB_REG_WRITE_MUL_QTY_MAX 123 /* 0x007B */ +#define NXMB_REG_READWRITE_RD_QTY_MAX 125 /* 0x007D */ +#define NXMB_REG_READWRITE_WR_QTY_MAX 121 /* 0x0079 */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_fc03_read_holding + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc03_read_holding(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t addr; + uint16_t qty; + uint8_t nbytes; + int ret; + + if (data_len != NXMB_FC03_REQ_DATA_LEN) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if (ctx->callbacks == NULL || ctx->callbacks->holding_cb == NULL) + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + + addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC03_ADDR_OFF]); + qty = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC03_QTY_OFF]); + + if (qty < 1 || qty > NXMB_REG_READ_QTY_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if ((uint32_t)addr + qty > 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + nbytes = (uint8_t)(qty * 2); + + /* Response is byte_count + register data */ + + if (1 + nbytes > NXMB_ADU_DATA_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + /* Build response: byte_count + register data (big-endian) */ + + ctx->adu.fc = NXMB_FC_READ_HOLDING; + ctx->adu.data[0] = nbytes; + + ret = ctx->callbacks->holding_cb(&ctx->adu.data[1], addr, qty, + NXMB_REG_READ, ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + ctx->adu.length = (uint16_t)(2 + 1 + nbytes); + return NXMB_EX_NONE; +} + +/**************************************************************************** + * Name: nxmb_fc06_write_holding + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc06_write_holding(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t addr; + int ret; + + if (data_len != NXMB_FC06_REQ_DATA_LEN) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if (ctx->callbacks == NULL || ctx->callbacks->holding_cb == NULL) + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + + addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC06_ADDR_OFF]); + + if (addr == 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + ret = ctx->callbacks->holding_cb(&ctx->adu.data[NXMB_FC06_VALUE_OFF], addr, + 1, NXMB_REG_WRITE, ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + /* Response echoes the request — adu.length is already correct */ + + return NXMB_EX_NONE; +} + +/**************************************************************************** + * Name: nxmb_fc16_write_holdings + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc16_write_holdings(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t addr; + uint16_t qty; + uint8_t byte_count; + int ret; + + if (data_len < NXMB_FC16_DATA_OFF) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if (ctx->callbacks == NULL || ctx->callbacks->holding_cb == NULL) + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + + addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC16_ADDR_OFF]); + qty = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC16_QTY_OFF]); + byte_count = ctx->adu.data[NXMB_FC16_BCNT_OFF]; + + if (qty < 1 || qty > NXMB_REG_WRITE_MUL_QTY_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if ((uint32_t)addr + qty > 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + if (byte_count != (uint8_t)(qty * 2)) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + /* Verify total data length matches header + payload */ + + if (data_len != (uint16_t)(NXMB_FC16_DATA_OFF + byte_count)) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + ret = ctx->callbacks->holding_cb(&ctx->adu.data[NXMB_FC16_DATA_OFF], addr, + qty, NXMB_REG_WRITE, + ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + /* Response: addr(2) + qty(2) — already in data[0..3] from request */ + + ctx->adu.length = (uint16_t)(2 + NXMB_FC16_RESP_DATA_LEN); + return NXMB_EX_NONE; +} + +/**************************************************************************** + * Name: nxmb_fc23_readwrite_holding + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc23_readwrite_holding(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t rd_addr; + uint16_t rd_qty; + uint16_t wr_addr; + uint16_t wr_qty; + uint8_t wr_bcnt; + uint16_t rd_bcnt; + int ret; + + if (data_len < NXMB_FC23_REQ_MIN_DATA_LEN) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if (ctx->callbacks == NULL || ctx->callbacks->holding_cb == NULL) + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + + rd_addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC23_RD_ADDR_OFF]); + rd_qty = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC23_RD_QTY_OFF]); + wr_addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC23_WR_ADDR_OFF]); + wr_qty = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC23_WR_QTY_OFF]); + wr_bcnt = ctx->adu.data[NXMB_FC23_WR_BCNT_OFF]; + + if (rd_qty < 1 || rd_qty > NXMB_REG_READWRITE_RD_QTY_MAX || wr_qty < 1 || + wr_qty > NXMB_REG_READWRITE_WR_QTY_MAX || wr_bcnt != (wr_qty * 2)) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if ((uint32_t)rd_addr + rd_qty > 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + if ((uint32_t)wr_addr + wr_qty > 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + /* Verify total request data length matches header + write payload */ + + if (data_len != (uint16_t)(NXMB_FC23_WR_DATA_OFF + wr_bcnt)) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + /* Response is byte_count + read register data — must fit in adu.data[] */ + + if (1 + rd_qty * 2 > NXMB_ADU_DATA_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + ret = ctx->callbacks->holding_cb(&ctx->adu.data[NXMB_FC23_WR_DATA_OFF], + wr_addr, wr_qty, NXMB_REG_WRITE, + ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + /* Build response: byte_count + read register data, overwriting request */ + + ctx->adu.fc = NXMB_FC_READWRITE_HOLDINGS; + rd_bcnt = rd_qty * 2; + ctx->adu.data[0] = (uint8_t)rd_bcnt; + + ret = ctx->callbacks->holding_cb(&ctx->adu.data[1], rd_addr, rd_qty, + NXMB_REG_READ, ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + ctx->adu.length = (uint16_t)(2 + 1 + rd_bcnt); + return NXMB_EX_NONE; +} diff --git a/industry/nxmodbus/core/nxmb_func_input.c b/industry/nxmodbus/core/nxmb_func_input.c new file mode 100644 index 000000000..151d2510b --- /dev/null +++ b/industry/nxmodbus/core/nxmb_func_input.c @@ -0,0 +1,115 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_func_input.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* FC04 Read Input Registers — offsets in adu.data[], lengths are data + * only + */ + +#define NXMB_FC04_ADDR_OFF 0 +#define NXMB_FC04_QTY_OFF 2 +#define NXMB_FC04_REQ_DATA_LEN 4 + +/* Maximum register quantity per Modbus specification */ + +#define NXMB_REG_READ_QTY_MAX 125 /* 0x007D */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_fc04_read_input + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc04_read_input(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + uint16_t addr; + uint16_t qty; + uint8_t nbytes; + int ret; + + if (data_len != NXMB_FC04_REQ_DATA_LEN) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if (ctx->callbacks == NULL || ctx->callbacks->input_cb == NULL) + { + return NXMB_EX_ILLEGAL_FUNCTION; + } + + addr = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC04_ADDR_OFF]); + qty = nxmb_util_get_u16_be(&ctx->adu.data[NXMB_FC04_QTY_OFF]); + + if (qty < 1 || qty > NXMB_REG_READ_QTY_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + if ((uint32_t)addr + qty > 0xffffu) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + nbytes = (uint8_t)(qty * 2); + + /* Response is byte_count + register data */ + + if (1 + nbytes > NXMB_ADU_DATA_MAX) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + /* Build response: byte_count + register data (big-endian) */ + + ctx->adu.fc = NXMB_FC_READ_INPUT; + ctx->adu.data[0] = nbytes; + + ret = ctx->callbacks->input_cb(&ctx->adu.data[1], addr, qty, + ctx->callbacks->priv); + if (ret != 0) + { + return nxmb_cb_ret_to_exception(ret); + } + + ctx->adu.length = (uint16_t)(2 + 1 + nbytes); + return NXMB_EX_NONE; +} diff --git a/industry/nxmodbus/core/nxmb_func_other.c b/industry/nxmodbus/core/nxmb_func_other.c new file mode 100644 index 000000000..5827026df --- /dev/null +++ b/industry/nxmodbus/core/nxmb_func_other.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_func_other.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXMB_REPORT_ID_REQ_DATA_LEN 0 + +/* Run indicator status */ + +#define NXMB_RUN_STATUS_ON 0xff +#define NXMB_RUN_STATUS_OFF 0x00 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_fc17_report_server_id + * + * Description: + * Handle FC17 (0x11) Report Server ID request. Returns the configured + * unit ID and a run indicator byte (0xFF = ON). + * + ****************************************************************************/ + +enum nxmb_exception_e nxmb_fc17_report_server_id(nxmb_handle_t ctx) +{ + uint16_t data_len = ctx->adu.length - 2; + + if (data_len != NXMB_REPORT_ID_REQ_DATA_LEN) + { + return NXMB_EX_ILLEGAL_DATA_VALUE; + } + + /* If the application configured server ID data via nxmb_set_server_id(), + * use that; otherwise fall back to unit_id + run status ON. + */ + + ctx->adu.fc = NXMB_FC_REPORT_SERVER_ID; + + if (ctx->server_id_len > 0) + { + /* Response is byte_count + server_id_buf */ + + if (1 + ctx->server_id_len > NXMB_ADU_DATA_MAX) + { + return NXMB_EX_DEVICE_FAILURE; + } + + ctx->adu.data[0] = (uint8_t)ctx->server_id_len; + memcpy(&ctx->adu.data[1], ctx->server_id_buf, ctx->server_id_len); + ctx->adu.length = (uint16_t)(2 + 1 + ctx->server_id_len); + } + else + { + ctx->adu.data[0] = 2; /* byte count */ + ctx->adu.data[1] = ctx->unit_id; /* server ID */ + ctx->adu.data[2] = NXMB_RUN_STATUS_ON; /* run indicator */ + ctx->adu.length = (uint16_t)(2 + 3); + } + + return NXMB_EX_NONE; +} diff --git a/industry/nxmodbus/core/nxmb_server.c b/industry/nxmodbus/core/nxmb_server.c new file mode 100644 index 000000000..4168b53f2 --- /dev/null +++ b/industry/nxmodbus/core/nxmb_server.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_server.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXMB_FUNC_ERROR 0x80 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_poll + * + * Description: + * Poll for Modbus events and process received frames. + * + * Input Parameters: + * handle - Instance handle + * + * Returned Value: + * 0 on success, negative errno on failure + * + ****************************************************************************/ + +int nxmb_poll(nxmb_handle_t ctx) +{ + uint8_t rcv_address; + int ret; + + DEBUGASSERT(ctx && ctx->transport_ops && ctx->transport_ops->receive); + + pthread_mutex_lock(&ctx->lock); + + if (!ctx->enabled) + { + pthread_mutex_unlock(&ctx->lock); + return -EAGAIN; + } + + ret = ctx->transport_ops->receive(ctx); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + + if (ret == 0 || ctx->adu.length == 0) + { + pthread_mutex_unlock(&ctx->lock); + return 0; + } + + rcv_address = ctx->adu.unit_id; + + if (rcv_address != NXMB_ADDRESS_BROADCAST && rcv_address != ctx->unit_id) + { + pthread_mutex_unlock(&ctx->lock); + return 0; + } + + /* Dispatch to function code handler. Handlers mutate ctx->adu in place, + * turning the request into the response. + */ + + ret = nxmb_dispatch_function(ctx); + + if (rcv_address != NXMB_ADDRESS_BROADCAST) + { + if (ctx->transport_ops->send != NULL) + { + ret = ctx->transport_ops->send(ctx); + if (ret < 0) + { + pthread_mutex_unlock(&ctx->lock); + return ret; + } + } + } + + pthread_mutex_unlock(&ctx->lock); + return 0; +} diff --git a/industry/nxmodbus/core/nxmb_utils.c b/industry/nxmodbus/core/nxmb_utils.c new file mode 100644 index 000000000..016d370c5 --- /dev/null +++ b/industry/nxmodbus/core/nxmb_utils.c @@ -0,0 +1,127 @@ +/**************************************************************************** + * apps/industry/nxmodbus/core/nxmb_utils.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_util_set_bits + * + * Description: + * Set bits in a byte buffer. + * + * Input Parameters: + * buf - Byte buffer + * bit_offset - Bit offset from start of buffer + * nbits - Number of bits to set (max 8) + * value - Value to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +void nxmb_util_set_bits(FAR uint8_t *buf, uint16_t bit_offset, uint8_t nbits, + uint8_t value) +{ + uint16_t word_buf; + uint16_t mask; + uint16_t byte_offset; + uint16_t pre_bits; + uint16_t val = value; + + byte_offset = bit_offset / 8; + pre_bits = bit_offset - (byte_offset * 8); + + val <<= pre_bits; + mask = (uint16_t)((1 << nbits) - 1); + mask <<= pre_bits; + + word_buf = buf[byte_offset]; + if (pre_bits + nbits > 8) + { + word_buf |= buf[byte_offset + 1] << 8; + } + + word_buf = (word_buf & (~mask)) | val; + + buf[byte_offset] = (uint8_t)(word_buf & 0xff); + if (pre_bits + nbits > 8) + { + buf[byte_offset + 1] = (uint8_t)(word_buf >> 8); + } +} + +/**************************************************************************** + * Name: nxmb_util_get_bits + * + * Description: + * Get bits from a byte buffer. + * + * Input Parameters: + * buf - Byte buffer + * bit_offset - Bit offset from start of buffer + * nbits - Number of bits to get (max 8) + * + * Returned Value: + * Bit value + * + ****************************************************************************/ + +uint8_t nxmb_util_get_bits(FAR const uint8_t *buf, uint16_t bit_offset, + uint8_t nbits) +{ + uint16_t word_buf; + uint16_t mask; + uint16_t byte_offset; + uint16_t pre_bits; + + byte_offset = bit_offset / 8; + pre_bits = bit_offset - (byte_offset * 8); + + mask = (uint16_t)((1 << nbits) - 1); + + word_buf = buf[byte_offset]; + if (pre_bits + nbits > 8) + { + word_buf |= buf[byte_offset + 1] << 8; + } + + word_buf >>= pre_bits; + word_buf &= mask; + + return (uint8_t)word_buf; +} + diff --git a/industry/nxmodbus/nxmb_internal.h b/industry/nxmodbus/nxmb_internal.h new file mode 100644 index 000000000..0ec3db5c9 --- /dev/null +++ b/industry/nxmodbus/nxmb_internal.h @@ -0,0 +1,379 @@ +/**************************************************************************** + * apps/industry/nxmodbus/nxmb_internal.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INDUSTRY_NXMODBUS_NXMB_INTERNAL_H +#define __APPS_INDUSTRY_NXMODBUS_NXMB_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Pre-processor Definitions */ + +#define NXMB_ADDRESS_BROADCAST 0 + +/* Modbus function codes */ + +#define NXMB_FC_READ_COILS 0x01 +#define NXMB_FC_READ_DISCRETE 0x02 +#define NXMB_FC_READ_HOLDING 0x03 +#define NXMB_FC_READ_INPUT 0x04 +#define NXMB_FC_WRITE_COIL 0x05 +#define NXMB_FC_WRITE_HOLDING 0x06 +#define NXMB_FC_DIAGNOSTICS 0x08 +#define NXMB_FC_WRITE_COILS 0x0f +#define NXMB_FC_WRITE_HOLDINGS 0x10 +#define NXMB_FC_REPORT_SERVER_ID 0x11 +#define NXMB_FC_READWRITE_HOLDINGS 0x17 + +/* Transport operations interface. + * + * receive() must not block indefinitely. Implementations should use an + * internal timeout (e.g. select()) and return 0 or -EAGAIN when no + * complete frame is available yet. The client polling loop relies on + * this to enforce its own response timeout. + */ + +struct nxmb_transport_ops_s +{ + CODE int (*init)(nxmb_handle_t ctx); + CODE int (*deinit)(nxmb_handle_t ctx); + CODE int (*send)(nxmb_handle_t ctx); + CODE int (*receive)(nxmb_handle_t ctx); +}; + +/* Custom function code handler */ + +struct nxmb_custom_fc_s +{ + FAR struct nxmb_custom_fc_s *next; + nxmb_custom_fc_handler_t handler; + uint8_t fc; +}; + +/* NxModbus instance context */ + +struct nxmb_context_s +{ + FAR const struct nxmb_callbacks_s *callbacks; + FAR const struct nxmb_transport_ops_s *transport_ops; + enum nxmb_mode_e mode; + pthread_mutex_t lock; + uint8_t unit_id; + bool is_client; + bool enabled; + + /* Transport configuration */ + + union nxmb_transport_config_u transport_cfg; + + /* Single ADU container reused for both RX and TX. Modbus is half-duplex, + * so request and response never coexist: handlers mutate the request + * in place to form the response. + */ + + struct nxmb_adu_s adu; + + /* Report Server ID (FC17) data */ + + uint8_t server_id_buf[CONFIG_NXMODBUS_REP_SERVER_ID_BUF]; + uint16_t server_id_len; + + /* Custom handlers */ + + FAR struct nxmb_custom_fc_s *custom_fc_list; + FAR void *transport_state; + FAR void *client_state; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef CONFIG_NXMODBUS_RTU +extern const struct nxmb_transport_ops_s g_nxmb_serial_ops; +#endif + +#ifdef CONFIG_NXMODBUS_ASCII +extern const struct nxmb_transport_ops_s g_nxmb_ascii_ops; +#endif + +#ifdef CONFIG_NXMODBUS_RAW_ADU +extern const struct nxmb_transport_ops_s g_nxmb_raw_ops; +#endif + +#ifdef CONFIG_NXMODBUS_TCP +extern const struct nxmb_transport_ops_s g_nxmb_tcp_ops; +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_cb_ret_to_exception + * + * Description: + * Map a callback return value to a Modbus exception code. + * + * -ENOENT -> address not supported by the application + * anything else -> generic device failure + * + ****************************************************************************/ + +static inline enum nxmb_exception_e nxmb_cb_ret_to_exception(int ret) +{ + if (ret == -ENOENT) + { + return NXMB_EX_ILLEGAL_DATA_ADDRESS; + } + + return NXMB_EX_DEVICE_FAILURE; +} + +/**************************************************************************** + * Name: nxmb_util_get_u16_be + * + * Description: + * Extract a big-endian 16-bit value from a buffer. + * + ****************************************************************************/ + +static inline uint16_t nxmb_util_get_u16_be(FAR const uint8_t *buf) +{ + return (uint16_t)((buf[0] << 8) | buf[1]); +} + +/**************************************************************************** + * Name: nxmb_util_put_u16_be + * + * Description: + * Store a 16-bit value as big-endian in a buffer. + * + ****************************************************************************/ + +static inline void nxmb_util_put_u16_be(FAR uint8_t *buf, uint16_t value) +{ + buf[0] = (uint8_t)(value >> 8); + buf[1] = (uint8_t)(value & 0xff); +} + +/**************************************************************************** + * Name: nxmb_util_clock_ms + * + * Description: + * Return the current monotonic clock value in milliseconds. + * + ****************************************************************************/ + +static inline uint64_t nxmb_util_clock_ms(void) +{ + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; +} + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_TERMIOS +/**************************************************************************** + * Name: nxmb_serial_configure + * + * Description: + * Configure serial port with termios settings for Modbus communication. + * Shared by RTU and ASCII transports. + * + * Input Parameters: + * fd - File descriptor + * baudrate - Baud rate + * parity - Parity setting + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +int nxmb_serial_configure(int fd, uint32_t baudrate, + enum nxmb_parity_e parity); +#endif + +/**************************************************************************** + * Name: nxmb_util_set_bits + * + * Description: + * Set up to 8 bits in a byte buffer at the given bit offset. + * + * Input Parameters: + * buf - Byte buffer + * bit_offset - Bit offset from start of buffer + * nbits - Number of bits to set (max 8) + * value - Bit values to write + * + ****************************************************************************/ + +void nxmb_util_set_bits(FAR uint8_t *buf, uint16_t bit_offset, uint8_t nbits, + uint8_t value); + +/**************************************************************************** + * Name: nxmb_util_get_bits + * + * Description: + * Extract up to 8 bits from a byte buffer at the given bit offset. + * + * Input Parameters: + * buf - Byte buffer + * bit_offset - Bit offset from start of buffer + * nbits - Number of bits to extract (max 8) + * + * Returned Value: + * Extracted bit values + * + ****************************************************************************/ + +uint8_t nxmb_util_get_bits(FAR const uint8_t *buf, uint16_t bit_offset, + uint8_t nbits); + +#ifdef CONFIG_NXMODBUS_RTU +/**************************************************************************** + * Name: nxmb_crc16 + * + * Description: + * Calculate Modbus RTU CRC16 checksum. + * + * Input Parameters: + * buf - Pointer to data buffer + * len - Length of data in bytes + * + * Returned Value: + * CRC16 value + * + ****************************************************************************/ + +uint16_t nxmb_crc16(FAR const uint8_t *buf, uint16_t len); +#endif + +#ifdef CONFIG_NXMODBUS_ASCII +/**************************************************************************** + * Name: nxmb_lrc + * + * Description: + * Calculate Modbus ASCII LRC checksum. + * + * Input Parameters: + * buf - Pointer to data buffer + * len - Length of data in bytes + * + * Returned Value: + * LRC value (8-bit) + * + ****************************************************************************/ + +uint8_t nxmb_lrc(FAR const uint8_t *buf, uint16_t len); +#endif + +#ifdef CONFIG_NXMODBUS_CLIENT +/**************************************************************************** + * Name: nxmb_client_init + * + * Description: + * Initialize client state for master mode. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +int nxmb_client_init(nxmb_handle_t ctx); + +/**************************************************************************** + * Name: nxmb_client_deinit + * + * Description: + * Deinitialize client state. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +int nxmb_client_deinit(nxmb_handle_t ctx); +#endif + +/**************************************************************************** + * Name: nxmb_dispatch_function + * + * Description: + * Dispatch a Modbus function code to the appropriate handler. Operates + * in place on ctx->adu. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +int nxmb_dispatch_function(nxmb_handle_t ctx); + +/* Function-code handlers operate on ctx->adu in place: they read the + * request from adu.fc/adu.data[]/adu.length and overwrite those fields + * with the response. + */ + +enum nxmb_exception_e nxmb_fc01_read_coils(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc02_read_discrete(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc05_write_coil(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc15_write_coils(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc03_read_holding(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc04_read_input(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc06_write_holding(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc16_write_holdings(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc23_readwrite_holding(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc08_diagnostics(nxmb_handle_t ctx); +enum nxmb_exception_e nxmb_fc17_report_server_id(nxmb_handle_t ctx); + +#endif /* __APPS_INDUSTRY_NXMODBUS_NXMB_INTERNAL_H */ diff --git a/industry/nxmodbus/transport/nxmb_ascii.c b/industry/nxmodbus/transport/nxmb_ascii.c new file mode 100644 index 000000000..668a89821 --- /dev/null +++ b/industry/nxmodbus/transport/nxmb_ascii.c @@ -0,0 +1,550 @@ +/**************************************************************************** + * apps/industry/nxmodbus/transport/nxmb_ascii.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXMB_ASCII_START_CHAR ':' +#define NXMB_ASCII_CR '\r' +#define NXMB_ASCII_LF '\n' + +/* Serialized binary frame: unit_id(1) + fc(1) + data + LRC(1) */ + +#define NXMB_ASCII_BIN_MAX (NXMB_ADU_DATA_MAX + 3) + +/* Hex-encoded ASCII frame: ':' + 2*bin + CR + LF */ + +#define NXMB_ASCII_BUFLEN (NXMB_ASCII_BIN_MAX * 2 + 4) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct nxmb_ascii_state_s +{ + int fd; + uint8_t rx_buf[NXMB_ASCII_BUFLEN]; + uint16_t rx_pos; + bool in_frame; +#ifdef CONFIG_SERIAL_TERMIOS + struct termios old_tio; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int nxmb_ascii_char_to_hex(char c); +static char nxmb_ascii_hex_to_char(uint8_t nibble); +static uint16_t nxmb_ascii_encode(FAR const uint8_t *bin, uint16_t bin_len, + FAR char *ascii); +static int nxmb_ascii_decode(FAR const char *ascii, uint16_t ascii_len, + FAR uint8_t *bin); +static int nxmb_ascii_init(nxmb_handle_t ctx); +static int nxmb_ascii_deinit(nxmb_handle_t ctx); +static int nxmb_ascii_send(nxmb_handle_t ctx); +static int nxmb_ascii_receive(nxmb_handle_t ctx); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct nxmb_transport_ops_s g_nxmb_ascii_ops = +{ + .init = nxmb_ascii_init, + .deinit = nxmb_ascii_deinit, + .send = nxmb_ascii_send, + .receive = nxmb_ascii_receive +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_ascii_char_to_hex + * + * Description: + * Convert ASCII hex character to binary nibble. + * + * Input Parameters: + * c - ASCII hex character + * + * Returned Value: + * Binary value 0-15, or -1 on error + * + ****************************************************************************/ + +static int nxmb_ascii_char_to_hex(char c) +{ + if (c >= '0' && c <= '9') + { + return c - '0'; + } + else if (c >= 'A' && c <= 'F') + { + return c - 'A' + 10; + } + else if (c >= 'a' && c <= 'f') + { + return c - 'a' + 10; + } + + return -1; +} + +/**************************************************************************** + * Name: nxmb_ascii_hex_to_char + * + * Description: + * Convert binary nibble to ASCII hex character. + * + * Input Parameters: + * nibble - Binary value 0-15 + * + * Returned Value: + * ASCII hex character + * + ****************************************************************************/ + +static char nxmb_ascii_hex_to_char(uint8_t nibble) +{ + if (nibble < 10) + { + return '0' + nibble; + } + else + { + return 'A' + (nibble - 10); + } +} + +/**************************************************************************** + * Name: nxmb_ascii_encode + * + * Description: + * Encode binary data to ASCII hex string. + * + * Input Parameters: + * bin - Binary data + * bin_len - Binary data length + * ascii - Output ASCII buffer + * + * Returned Value: + * ASCII string length + * + ****************************************************************************/ + +static uint16_t nxmb_ascii_encode(FAR const uint8_t *bin, uint16_t bin_len, + FAR char *ascii) +{ + uint16_t pos = 0; + uint16_t i; + + for (i = 0; i < bin_len; i++) + { + ascii[pos++] = nxmb_ascii_hex_to_char(bin[i] >> 4); + ascii[pos++] = nxmb_ascii_hex_to_char(bin[i] & 0x0f); + } + + return pos; +} + +/**************************************************************************** + * Name: nxmb_ascii_decode + * + * Description: + * Decode ASCII hex string to binary data. + * + * Input Parameters: + * ascii - ASCII hex string + * ascii_len - ASCII string length (must be even) + * bin - Output binary buffer + * + * Returned Value: + * Binary data length, or negative errno on error + * + ****************************************************************************/ + +static int nxmb_ascii_decode(FAR const char *ascii, uint16_t ascii_len, + FAR uint8_t *bin) +{ + uint16_t i; + int high; + int low; + + if (ascii_len % 2 != 0) + { + return -EINVAL; + } + + for (i = 0; i < ascii_len; i += 2) + { + high = nxmb_ascii_char_to_hex(ascii[i]); + low = nxmb_ascii_char_to_hex(ascii[i + 1]); + + if (high < 0 || low < 0) + { + return -EINVAL; + } + + bin[i / 2] = (high << 4) | low; + } + + return ascii_len / 2; +} + +/**************************************************************************** + * Name: nxmb_ascii_init + * + * Description: + * Initialize serial ASCII transport. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_ascii_init(nxmb_handle_t ctx) +{ + FAR struct nxmb_ascii_state_s *state; + FAR const struct nxmb_serial_config_s *cfg; + int ret; + + DEBUGASSERT(ctx); + + cfg = &ctx->transport_cfg.serial; + + if (cfg->devpath == NULL) + { + return -EINVAL; + } + + state = calloc(1, sizeof(struct nxmb_ascii_state_s)); + if (state == NULL) + { + return -ENOMEM; + } + + state->fd = open(cfg->devpath, O_RDWR | O_NOCTTY); + if (state->fd < 0) + { + ret = -errno; + free(state); + return ret; + } + +#ifdef CONFIG_SERIAL_TERMIOS + if (tcgetattr(state->fd, &state->old_tio) < 0) + { + ret = -errno; + close(state->fd); + free(state); + return ret; + } + + ret = nxmb_serial_configure(state->fd, cfg->baudrate, cfg->parity); + if (ret < 0) + { + close(state->fd); + free(state); + return ret; + } +#endif + + state->rx_pos = 0; + state->in_frame = false; + + ctx->transport_state = state; + + return 0; +} + +/**************************************************************************** + * Name: nxmb_ascii_deinit + * + * Description: + * Deinitialize serial ASCII transport. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_ascii_deinit(nxmb_handle_t ctx) +{ + FAR struct nxmb_ascii_state_s *state; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + +#ifdef CONFIG_SERIAL_TERMIOS + tcsetattr(state->fd, TCSANOW, &state->old_tio); +#endif + close(state->fd); + free(state); + + ctx->transport_state = NULL; + + return 0; +} + +/**************************************************************************** + * Name: nxmb_ascii_send + * + * Description: + * Send ASCII frame over serial port. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_ascii_send(nxmb_handle_t ctx) +{ + FAR struct nxmb_ascii_state_s *state; + uint8_t bin[NXMB_ASCII_BIN_MAX]; + char tx_buf[NXMB_ASCII_BUFLEN]; + uint16_t data_len; + uint16_t pos = 0; + uint8_t lrc; + ssize_t written; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + + if (ctx->adu.length < 2) + { + return -EINVAL; + } + + data_len = ctx->adu.length - 2; + + /* Linearize the ADU into the wire byte order: unit_id, fc, data... */ + + bin[0] = ctx->adu.unit_id; + bin[1] = ctx->adu.fc; + memcpy(&bin[2], ctx->adu.data, data_len); + + lrc = nxmb_lrc(bin, ctx->adu.length); + ctx->adu.crc = lrc; + + tx_buf[pos++] = NXMB_ASCII_START_CHAR; + pos += nxmb_ascii_encode(bin, ctx->adu.length, &tx_buf[pos]); + tx_buf[pos++] = nxmb_ascii_hex_to_char(lrc >> 4); + tx_buf[pos++] = nxmb_ascii_hex_to_char(lrc & 0x0f); + tx_buf[pos++] = NXMB_ASCII_CR; + tx_buf[pos++] = NXMB_ASCII_LF; + + written = write(state->fd, tx_buf, pos); + + if (written < 0) + { + return -errno; + } + + if (written != pos) + { + return -EIO; + } + + return 0; +} + +/**************************************************************************** + * Name: nxmb_ascii_receive + * + * Description: + * Receive ASCII frame from serial port. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_ascii_receive(nxmb_handle_t ctx) +{ + FAR struct nxmb_ascii_state_s *state; + uint8_t bin[NXMB_ASCII_BIN_MAX]; + struct timeval timeout; + fd_set readfds; + ssize_t nread; + uint8_t c; + uint8_t lrc_calc; + uint8_t lrc_recv; + int ret; + int bin_len; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + + FD_ZERO(&readfds); + FD_SET(state->fd, &readfds); + + timeout.tv_sec = CONFIG_NXMODBUS_ASCII_TIMEOUT_SEC; + timeout.tv_usec = 0; + + ret = select(state->fd + 1, &readfds, NULL, NULL, &timeout); + + if (ret < 0) + { + return -errno; + } + + if (ret == 0) + { + return 0; + } + + if (!FD_ISSET(state->fd, &readfds)) + { + return 0; + } + + nread = read(state->fd, &c, 1); + if (nread < 0) + { + return -errno; + } + + if (nread == 0) + { + return 0; + } + + if (c == NXMB_ASCII_START_CHAR) + { + state->rx_pos = 0; + state->in_frame = true; + return 0; + } + + if (!state->in_frame) + { + return 0; + } + + if (c == NXMB_ASCII_LF) + { + state->in_frame = false; + + /* Minimum valid frame: addr(2) + func(2) + lrc(2) + CR = 7 chars. + * Maximum valid frame: NXMB_ASCII_BIN_MAX hex pairs + CR. Reject + * anything larger so the decoded length fits bin[]. + */ + + if (state->rx_pos < 7 || + state->rx_pos > NXMB_ASCII_BIN_MAX * 2 + 1 || + state->rx_buf[state->rx_pos - 1] != NXMB_ASCII_CR) + { + state->rx_pos = 0; + return 0; + } + + /* Decode all hex chars (exclude CR) into a temp binary buffer. + * Layout: unit_id + fc + data... + LRC. + */ + + bin_len = nxmb_ascii_decode((FAR const char *)state->rx_buf, + state->rx_pos - 1, bin); + + if (bin_len < 3) + { + state->rx_pos = 0; + return 0; + } + + lrc_calc = nxmb_lrc(bin, bin_len - 1); + lrc_recv = bin[bin_len - 1]; + + if (lrc_calc != lrc_recv) + { + state->rx_pos = 0; + return 0; + } + + /* Unpack into ctx->adu. Length excludes LRC. */ + + ctx->adu.unit_id = bin[0]; + ctx->adu.fc = bin[1]; + memcpy(ctx->adu.data, &bin[2], (bin_len - 3)); + ctx->adu.crc = lrc_recv; + ctx->adu.length = (bin_len - 1); + + state->rx_pos = 0; + + return 1; + } + + if (state->rx_pos < sizeof(state->rx_buf)) + { + state->rx_buf[state->rx_pos++] = c; + } + else + { + state->in_frame = false; + state->rx_pos = 0; + } + + return 0; +} diff --git a/industry/nxmodbus/transport/nxmb_crc.c b/industry/nxmodbus/transport/nxmb_crc.c new file mode 100644 index 000000000..abfffffb4 --- /dev/null +++ b/industry/nxmodbus/transport/nxmb_crc.c @@ -0,0 +1,108 @@ +/**************************************************************************** + * apps/industry/nxmodbus/transport/nxmb_crc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint16_t g_crc16_table[256] = +{ + 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, + 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, + 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, + 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, + 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, + 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, + 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, + 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, + 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00, + 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, + 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981, + 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, + 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, + 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, + 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, + 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, + 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, + 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, + 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, + 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, + 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, + 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, + 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, + 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, + 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, + 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, + 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, + 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, + 0x4100, 0x81c1, 0x8081, 0x4040 +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_crc16 + * + * Description: + * Calculate Modbus RTU CRC16 checksum. + * + * Input Parameters: + * buf - Pointer to data buffer + * len - Length of data in bytes + * + * Returned Value: + * CRC16 value + * + ****************************************************************************/ + +uint16_t nxmb_crc16(FAR const uint8_t *buf, uint16_t len) +{ + uint16_t crc = 0xffff; + uint8_t index; + + if (buf == NULL || len == 0) + { + return crc; + } + + while (len--) + { + index = (crc ^ *buf++); + crc = (crc >> 8) ^ g_crc16_table[index]; + } + + return crc; +} diff --git a/industry/nxmodbus/transport/nxmb_lrc.c b/industry/nxmodbus/transport/nxmb_lrc.c new file mode 100644 index 000000000..7768c9cb5 --- /dev/null +++ b/industry/nxmodbus/transport/nxmb_lrc.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * apps/industry/nxmodbus/transport/nxmb_lrc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_lrc + * + * Description: + * Calculate Modbus ASCII LRC checksum. + * + * Input Parameters: + * buf - Pointer to data buffer + * len - Length of data in bytes + * + * Returned Value: + * LRC value (8-bit) + * + ****************************************************************************/ + +uint8_t nxmb_lrc(FAR const uint8_t *buf, uint16_t len) +{ + uint8_t lrc = 0; + uint16_t i; + + if (buf == NULL || len == 0) + { + return lrc; + } + + for (i = 0; i < len; i++) + { + lrc += buf[i]; + } + + return (uint8_t)(-((int8_t)lrc)); +} diff --git a/industry/nxmodbus/transport/nxmb_raw.c b/industry/nxmodbus/transport/nxmb_raw.c new file mode 100644 index 000000000..8352581fe --- /dev/null +++ b/industry/nxmodbus/transport/nxmb_raw.c @@ -0,0 +1,303 @@ +/**************************************************************************** + * apps/industry/nxmodbus/transport/nxmb_raw.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MBAP_PROTO_ID 0x0000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Raw ADU transport state */ + +struct nxmb_raw_state_s +{ + FAR void *user_data; + nxmb_raw_tx_cb_t tx_callback; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int nxmb_raw_init(nxmb_handle_t ctx); +static int nxmb_raw_deinit(nxmb_handle_t ctx); +static int nxmb_raw_send(nxmb_handle_t ctx); +static int nxmb_raw_receive(nxmb_handle_t ctx); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct nxmb_transport_ops_s g_nxmb_raw_ops = +{ + .init = nxmb_raw_init, + .deinit = nxmb_raw_deinit, + .send = nxmb_raw_send, + .receive = nxmb_raw_receive, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_raw_init + * + * Description: + * Initialize raw ADU transport. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_raw_init(nxmb_handle_t ctx) +{ + FAR const struct nxmb_raw_config_s *cfg; + FAR struct nxmb_raw_state_s *state; + + DEBUGASSERT(ctx); + + cfg = &ctx->transport_cfg.raw; + + if (cfg->tx_cb == NULL) + { + return -EINVAL; + } + + state = malloc(sizeof(struct nxmb_raw_state_s)); + if (state == NULL) + { + return -ENOMEM; + } + + state->tx_callback = cfg->tx_cb; + state->user_data = cfg->user_data; + + ctx->transport_state = state; + + return OK; +} + +/**************************************************************************** + * Name: nxmb_raw_deinit + * + * Description: + * Deinitialize raw ADU transport. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_raw_deinit(nxmb_handle_t ctx) +{ + DEBUGASSERT(ctx && ctx->transport_state); + + free(ctx->transport_state); + ctx->transport_state = NULL; + + return OK; +} + +/**************************************************************************** + * Name: nxmb_raw_send + * + * Description: + * Send raw ADU via user callback. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_raw_send(nxmb_handle_t ctx) +{ + FAR struct nxmb_raw_state_s *state; + int ret; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + + if (state->tx_callback == NULL) + { + return -EINVAL; + } + + ctx->adu.proto_id = MBAP_PROTO_ID; + + ret = state->tx_callback(&ctx->adu, state->user_data); + if (ret < 0) + { + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: nxmb_raw_receive + * + * Description: + * Receive raw ADU (not used in raw mode, frames are submitted via + * nxmb_raw_submit_rx). + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * -ENOTSUP (raw mode uses submit pattern, not polling) + * + ****************************************************************************/ + +static int nxmb_raw_receive(nxmb_handle_t ctx) +{ + return -ENOTSUP; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_raw_submit_rx + * + * Description: + * Submit a received raw ADU into the NxModbus protocol core. + * + * Input Parameters: + * h - The NxModbus instance receiving the frame + * adu - The received raw ADU container + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +int nxmb_raw_submit_rx(nxmb_handle_t ctx, FAR const struct nxmb_adu_s *adu) +{ + DEBUGASSERT(ctx && adu); + + if (adu->proto_id != MBAP_PROTO_ID) + { + return -EPROTO; + } + + if (adu->length < 2) + { + return -EINVAL; + } + + if ((adu->length - 2) > NXMB_ADU_DATA_MAX) + { + return -EMSGSIZE; + } + + pthread_mutex_lock(&ctx->lock); + ctx->adu = *adu; + pthread_mutex_unlock(&ctx->lock); + + return OK; +} + +/**************************************************************************** + * Name: nxmb_raw_put_header + * + * Description: + * Serialize the 8-byte MBAP+FC header for an ADU. + * + * Input Parameters: + * adu - The ADU providing the header fields + * hdr - The destination buffer for the serialized header + * + * Returned Value: + * None + * + ****************************************************************************/ + +void nxmb_raw_put_header(FAR const struct nxmb_adu_s *adu, FAR uint8_t *hdr) +{ + DEBUGASSERT(adu && hdr); + + nxmb_util_put_u16_be(&hdr[0], adu->trans_id); + nxmb_util_put_u16_be(&hdr[2], adu->proto_id); + nxmb_util_put_u16_be(&hdr[4], adu->length); + hdr[6] = adu->unit_id; + hdr[7] = adu->fc; +} + +/**************************************************************************** + * Name: nxmb_raw_get_header + * + * Description: + * Parse the 8-byte MBAP+FC header into an ADU structure. + * + * Input Parameters: + * adu - The destination ADU structure + * hdr - The source buffer containing the serialized header + * + * Returned Value: + * None + * + ****************************************************************************/ + +void nxmb_raw_get_header(FAR struct nxmb_adu_s *adu, FAR const uint8_t *hdr) +{ + DEBUGASSERT(adu && hdr); + + adu->trans_id = nxmb_util_get_u16_be(&hdr[0]); + adu->proto_id = nxmb_util_get_u16_be(&hdr[2]); + adu->length = nxmb_util_get_u16_be(&hdr[4]); + adu->unit_id = hdr[6]; + adu->fc = hdr[7]; +} diff --git a/industry/nxmodbus/transport/nxmb_serial.c b/industry/nxmodbus/transport/nxmb_serial.c new file mode 100644 index 000000000..679e0d597 --- /dev/null +++ b/industry/nxmodbus/transport/nxmb_serial.c @@ -0,0 +1,423 @@ +/**************************************************************************** + * apps/industry/nxmodbus/transport/nxmb_serial.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXMB_RTU_MIN_FRAME_SIZE 5 + +/* Wire frame: unit_id + fc + data + 2 CRC bytes */ + +#define NXMB_RTU_FRAME_MAX (NXMB_ADU_DATA_MAX + 4) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct nxmb_serial_state_s +{ + int fd; + uint32_t t35_usec; + bool rx_frame_now; + uint16_t rx_pos; + uint8_t rx_buf[NXMB_RTU_FRAME_MAX]; +#ifdef CONFIG_SERIAL_TERMIOS + struct termios old_tio; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static uint32_t nxmb_serial_calculate_t35(uint32_t baudrate); +static int nxmb_serial_init(nxmb_handle_t ctx); +static int nxmb_serial_deinit(nxmb_handle_t ctx); +static int nxmb_serial_send(nxmb_handle_t ctx); +static int nxmb_serial_receive(nxmb_handle_t ctx); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct nxmb_transport_ops_s g_nxmb_serial_ops = +{ + .init = nxmb_serial_init, + .deinit = nxmb_serial_deinit, + .send = nxmb_serial_send, + .receive = nxmb_serial_receive +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_serial_calculate_t35 + * + * Description: + * Calculate T3.5 character timeout in microseconds based on baud rate. + * + * Input Parameters: + * baudrate - Serial baud rate + * + * Returned Value: + * T3.5 timeout in microseconds + * + ****************************************************************************/ + +static uint32_t nxmb_serial_calculate_t35(uint32_t baudrate) +{ + if (baudrate <= 19200) + { + /* T3.5 = 3.5 * 11 bits/char * 1e6 us/s / baudrate + * = 38500000 / baudrate (in microseconds). + * Use integer arithmetic to avoid floating-point, which may + * require FPU context save/restore on embedded targets. + */ + + return 38500000u / baudrate; + } + else + { + /* Per Modbus spec, fixed 1750 us for baud rates above 19200 */ + + return 1750; + } +} + +/**************************************************************************** + * Name: nxmb_serial_init + * + * Description: + * Initialize serial RTU transport. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_serial_init(nxmb_handle_t ctx) +{ + FAR struct nxmb_serial_state_s *state; + FAR const struct nxmb_serial_config_s *cfg; + int ret; + + DEBUGASSERT(ctx); + + cfg = &ctx->transport_cfg.serial; + + if (cfg->devpath == NULL) + { + return -EINVAL; + } + + state = calloc(1, sizeof(struct nxmb_serial_state_s)); + if (state == NULL) + { + return -ENOMEM; + } + + state->fd = open(cfg->devpath, O_RDWR | O_NOCTTY); + if (state->fd < 0) + { + ret = -errno; + free(state); + return ret; + } + +#ifdef CONFIG_SERIAL_TERMIOS + if (tcgetattr(state->fd, &state->old_tio) < 0) + { + ret = -errno; + close(state->fd); + free(state); + return ret; + } + + ret = nxmb_serial_configure(state->fd, cfg->baudrate, cfg->parity); + + if (ret < 0) + { + close(state->fd); + free(state); + return ret; + } + + tcflush(state->fd, TCIOFLUSH); +#endif + + state->t35_usec = nxmb_serial_calculate_t35(cfg->baudrate); + state->rx_frame_now = false; + + ctx->transport_state = state; + + return 0; +} + +/**************************************************************************** + * Name: nxmb_serial_deinit + * + * Description: + * Deinitialize serial RTU transport. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_serial_deinit(nxmb_handle_t ctx) +{ + FAR struct nxmb_serial_state_s *state; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + +#ifdef CONFIG_SERIAL_TERMIOS + tcsetattr(state->fd, TCSANOW, &state->old_tio); +#endif + close(state->fd); + free(state); + + ctx->transport_state = NULL; + + return 0; +} + +/**************************************************************************** + * Name: nxmb_serial_send + * + * Description: + * Send RTU frame over serial port. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_serial_send(nxmb_handle_t ctx) +{ + FAR struct nxmb_serial_state_s *state; + uint8_t frame[NXMB_RTU_FRAME_MAX]; + uint16_t data_len; + uint16_t total; + uint16_t crc; + ssize_t written; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + + if (ctx->adu.length < 2) + { + return -EINVAL; + } + + data_len = ctx->adu.length - 2; + + /* Linearize the ADU and append CRC: unit_id, fc, data..., crc_lo, crc_hi */ + + frame[0] = ctx->adu.unit_id; + frame[1] = ctx->adu.fc; + memcpy(&frame[2], ctx->adu.data, data_len); + + crc = nxmb_crc16(frame, ctx->adu.length); + + frame[ctx->adu.length] = (crc & 0xff); + frame[ctx->adu.length + 1] = (crc >> 8); + + ctx->adu.crc = crc; + + total = ctx->adu.length + 2; + written = write(state->fd, frame, total); + + if (written < 0) + { + return -errno; + } + + if (written != total) + { + return -EIO; + } + + return 0; +} + +/**************************************************************************** + * Name: nxmb_serial_receive + * + * Description: + * Receive RTU frame from serial port with dynamic timeout. + * + * Input Parameters: + * ctx - Instance context + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int nxmb_serial_receive(nxmb_handle_t ctx) +{ + FAR struct nxmb_serial_state_s *state; + struct timeval timeout; + fd_set readfds; + ssize_t nread; + uint16_t crc_calc; + uint16_t crc_recv; + uint16_t data_len; + int ret; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + + FD_ZERO(&readfds); + FD_SET(state->fd, &readfds); + + if (state->rx_frame_now) + { + timeout.tv_sec = 0; + timeout.tv_usec = state->t35_usec; + } + else + { + timeout.tv_sec = 0; + timeout.tv_usec = CONFIG_NXMODBUS_RTU_IDLE_TIMEOUT_MS * 1000; + } + + ret = select(state->fd + 1, &readfds, NULL, NULL, &timeout); + + if (ret < 0) + { + return -errno; + } + + if (ret == 0) + { + if (state->rx_frame_now) + { + state->rx_frame_now = false; + + if (state->rx_pos < NXMB_RTU_MIN_FRAME_SIZE) + { + state->rx_pos = 0; + return 0; + } + + crc_calc = nxmb_crc16(state->rx_buf, state->rx_pos - 2); + crc_recv = state->rx_buf[state->rx_pos - 2] | + (state->rx_buf[state->rx_pos - 1] << 8); + + if (crc_calc != crc_recv) + { + state->rx_pos = 0; + return 0; + } + + /* Unpack frame into ctx->adu (excluding the trailing CRC). */ + + data_len = (state->rx_pos - 4); + ctx->adu.unit_id = state->rx_buf[0]; + ctx->adu.fc = state->rx_buf[1]; + memcpy(ctx->adu.data, &state->rx_buf[2], data_len); + ctx->adu.crc = crc_recv; + ctx->adu.length = (state->rx_pos - 2); + + state->rx_pos = 0; + return 1; + } + + return 0; + } + + if (!FD_ISSET(state->fd, &readfds)) + { + return 0; + } + + if (!state->rx_frame_now) + { + state->rx_pos = 0; + state->rx_frame_now = true; + } + + nread = read(state->fd, + &state->rx_buf[state->rx_pos], + sizeof(state->rx_buf) - state->rx_pos); + if (nread < 0) + { + return -errno; + } + + if (nread == 0) + { + return 0; + } + + state->rx_pos += nread; + + if (state->rx_pos >= sizeof(state->rx_buf)) + { + state->rx_pos = 0; + state->rx_frame_now = false; + return 0; + } + + return 0; +} diff --git a/industry/nxmodbus/transport/nxmb_serial_common.c b/industry/nxmodbus/transport/nxmb_serial_common.c new file mode 100644 index 000000000..72b2d1a87 --- /dev/null +++ b/industry/nxmodbus/transport/nxmb_serial_common.c @@ -0,0 +1,138 @@ +/**************************************************************************** + * apps/industry/nxmodbus/transport/nxmb_serial_common.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_TERMIOS + +/**************************************************************************** + * Name: nxmb_serial_configure + * + * Description: + * Configure serial port with termios settings for Modbus communication. + * + * Input Parameters: + * fd - File descriptor + * baudrate - Baud rate + * parity - Parity setting + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +int nxmb_serial_configure(int fd, uint32_t baudrate, + enum nxmb_parity_e parity) +{ + struct termios tio; + speed_t speed; + + if (tcgetattr(fd, &tio) < 0) + { + return -errno; + } + + switch (baudrate) + { + case 9600: + speed = B9600; + break; + case 19200: + speed = B19200; + break; + case 38400: + speed = B38400; + break; + case 57600: + speed = B57600; + break; + case 115200: + speed = B115200; + break; + default: + return -EINVAL; + } + + cfsetispeed(&tio, speed); + cfsetospeed(&tio, speed); + + tio.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); + tio.c_cflag |= CS8 | CLOCAL | CREAD; + + switch (parity) + { + case NXMB_PAR_NONE: + + /* Modbus spec: no parity requires 2 stop bits so the + * character frame remains 11 bits. + */ + + tio.c_cflag |= CSTOPB; + break; + case NXMB_PAR_EVEN: + tio.c_cflag |= PARENB; + break; + case NXMB_PAR_ODD: + tio.c_cflag |= PARENB | PARODD; + break; + default: + return -EINVAL; + } + + tio.c_iflag &= + ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + tio.c_oflag &= ~OPOST; + tio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + + tio.c_cc[VMIN] = 0; + tio.c_cc[VTIME] = 0; + + if (tcsetattr(fd, TCSANOW, &tio) < 0) + { + return -errno; + } + + return 0; +} + +#endif /* CONFIG_SERIAL_TERMIOS */ diff --git a/industry/nxmodbus/transport/nxmb_tcp.c b/industry/nxmodbus/transport/nxmb_tcp.c new file mode 100644 index 000000000..f4b2dc940 --- /dev/null +++ b/industry/nxmodbus/transport/nxmb_tcp.c @@ -0,0 +1,684 @@ +/**************************************************************************** + * apps/industry/nxmodbus/transport/nxmb_tcp.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "nxmb_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MBAP_HEADER_SIZE 7 +#define MBAP_FC_SIZE 8 +#define NXMB_TCP_RECV_MS 1000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct nxmb_tcp_client_s +{ + int fd; + uint16_t trans_id; + time_t last_activity; +}; + +struct nxmb_tcp_state_s +{ + struct nxmb_tcp_client_s clients[CONFIG_NXMODBUS_TCP_MAX_CLIENTS]; + int listen_fd; + int active_idx; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int nxmb_tcp_init(nxmb_handle_t ctx); +static int nxmb_tcp_deinit(nxmb_handle_t ctx); +static int nxmb_tcp_send(nxmb_handle_t ctx); +static int nxmb_tcp_receive(nxmb_handle_t ctx); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct nxmb_transport_ops_s g_nxmb_tcp_ops = +{ + .init = nxmb_tcp_init, + .deinit = nxmb_tcp_deinit, + .send = nxmb_tcp_send, + .receive = nxmb_tcp_receive, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmb_tcp_put_header + ****************************************************************************/ + +static void nxmb_tcp_put_header(FAR const struct nxmb_adu_s *adu, + FAR uint8_t *hdr) +{ + nxmb_util_put_u16_be(&hdr[0], adu->trans_id); + nxmb_util_put_u16_be(&hdr[2], adu->proto_id); + nxmb_util_put_u16_be(&hdr[4], adu->length); + hdr[6] = adu->unit_id; + hdr[7] = adu->fc; +} + +/**************************************************************************** + * Name: nxmb_tcp_get_header + ****************************************************************************/ + +static void nxmb_tcp_get_header(FAR struct nxmb_adu_s *adu, + FAR const uint8_t *hdr) +{ + adu->trans_id = nxmb_util_get_u16_be(&hdr[0]); + adu->proto_id = nxmb_util_get_u16_be(&hdr[2]); + adu->length = nxmb_util_get_u16_be(&hdr[4]); + adu->unit_id = hdr[6]; + adu->fc = hdr[7]; +} + +/**************************************************************************** + * Name: nxmb_tcp_create_server + ****************************************************************************/ + +static int nxmb_tcp_create_server(FAR const struct nxmb_tcp_config_s *cfg) +{ + struct sockaddr_in addr; + int listen_fd; + int ret; +#ifdef CONFIG_NET_SOCKOPTS + int opt = 1; +#endif + + listen_fd = socket(AF_INET, SOCK_STREAM, 0); + if (listen_fd < 0) + { + return -errno; + } + +#ifdef CONFIG_NET_SOCKOPTS + setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); +#endif + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(cfg->port); + + if (cfg->bindaddr != NULL) + { + ret = inet_pton(AF_INET, cfg->bindaddr, &addr.sin_addr); + if (ret != 1) + { + close(listen_fd); + return -EINVAL; + } + } + else + { + addr.sin_addr.s_addr = htonl(INADDR_ANY); + } + + ret = bind(listen_fd, (FAR struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) + { + close(listen_fd); + return -errno; + } + + ret = listen(listen_fd, CONFIG_NXMODBUS_TCP_MAX_CLIENTS); + if (ret < 0) + { + close(listen_fd); + return -errno; + } + + return listen_fd; +} + +/**************************************************************************** + * Name: nxmb_tcp_connect_client + ****************************************************************************/ + +static int nxmb_tcp_connect_client(FAR const struct nxmb_tcp_config_s *cfg) +{ + struct sockaddr_in addr; + int client_fd; + int ret; + + if (cfg->host == NULL) + { + return -EINVAL; + } + + client_fd = socket(AF_INET, SOCK_STREAM, 0); + if (client_fd < 0) + { + return -errno; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(cfg->port); + + ret = inet_pton(AF_INET, cfg->host, &addr.sin_addr); + if (ret != 1) + { + close(client_fd); + return -EINVAL; + } + + ret = connect(client_fd, (FAR struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) + { + close(client_fd); + return -errno; + } + + return client_fd; +} + +/**************************************************************************** + * Name: nxmb_tcp_recv_full + ****************************************************************************/ + +static int nxmb_tcp_recv_full(int fd, FAR uint8_t *buf, size_t len, + int timeout_ms) +{ + struct timeval tv; + fd_set readfds; + size_t received; + int ret; + + received = 0; + + while (received < len) + { + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + + tv.tv_sec = timeout_ms / 1000; + tv.tv_usec = (timeout_ms % 1000) * 1000; + + ret = select(fd + 1, &readfds, NULL, NULL, &tv); + if (ret < 0) + { + return -errno; + } + else if (ret == 0) + { + return -ETIMEDOUT; + } + + ret = recv(fd, &buf[received], len - received, 0); + if (ret < 0) + { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + { + continue; + } + + return -errno; + } + else if (ret == 0) + { + return -ECONNRESET; + } + + received += ret; + } + + return received; +} + +/**************************************************************************** + * Name: nxmb_tcp_init + ****************************************************************************/ + +static int nxmb_tcp_init(nxmb_handle_t ctx) +{ + FAR const struct nxmb_tcp_config_s *cfg; + FAR struct nxmb_tcp_state_s *state; + int fd; + int i; + + DEBUGASSERT(ctx); + + cfg = &ctx->transport_cfg.tcp; + + state = calloc(1, sizeof(struct nxmb_tcp_state_s)); + if (state == NULL) + { + return -ENOMEM; + } + + state->listen_fd = -1; + state->active_idx = -1; + + for (i = 0; i < CONFIG_NXMODBUS_TCP_MAX_CLIENTS; i++) + { + state->clients[i].fd = -1; + } + + if (ctx->is_client) + { + fd = nxmb_tcp_connect_client(cfg); + if (fd < 0) + { + free(state); + return fd; + } + + state->clients[0].fd = fd; + state->clients[0].last_activity = time(NULL); + } + else + { + fd = nxmb_tcp_create_server(cfg); + if (fd < 0) + { + free(state); + return fd; + } + + state->listen_fd = fd; + } + + ctx->transport_state = state; + + return OK; +} + +/**************************************************************************** + * Name: nxmb_tcp_deinit + ****************************************************************************/ + +static int nxmb_tcp_deinit(nxmb_handle_t ctx) +{ + FAR struct nxmb_tcp_state_s *state; + int i; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + + for (i = 0; i < CONFIG_NXMODBUS_TCP_MAX_CLIENTS; i++) + { + if (state->clients[i].fd >= 0) + { + close(state->clients[i].fd); + } + } + + if (state->listen_fd >= 0) + { + close(state->listen_fd); + } + + free(state); + ctx->transport_state = NULL; + + return OK; +} + +/**************************************************************************** + * Name: nxmb_tcp_send + ****************************************************************************/ + +static int nxmb_tcp_send(nxmb_handle_t ctx) +{ + FAR struct nxmb_tcp_state_s *state; + FAR struct nxmb_tcp_client_s *client; + uint8_t header[MBAP_FC_SIZE]; + struct iovec iov[2]; + uint16_t data_len; + uint16_t total; + ssize_t sent; + int fd; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + + /* For server mode, respond to the client that sent the request. + * For client mode, use the single connection (index 0). + */ + + if (ctx->is_client) + { + client = &state->clients[0]; + } + else + { + if (state->active_idx < 0) + { + return -ENOTCONN; + } + + client = &state->clients[state->active_idx]; + } + + fd = client->fd; + if (fd < 0) + { + return -ENOTCONN; + } + + if (ctx->adu.length < 2) + { + return -EINVAL; + } + + /* Populate the MBAP fields before serializing the header */ + + ctx->adu.trans_id = client->trans_id; + ctx->adu.proto_id = 0x0000; + + data_len = ctx->adu.length - 2; + + /* Emit MBAP header + PDU data via writev() to avoid a stack-side + * copy. The kernel gathers both iovecs into a single TCP segment. + */ + + nxmb_tcp_put_header(&ctx->adu, header); + + iov[0].iov_base = header; + iov[0].iov_len = MBAP_FC_SIZE; + iov[1].iov_base = ctx->adu.data; + iov[1].iov_len = data_len; + + total = MBAP_FC_SIZE + data_len; + sent = writev(fd, iov, (data_len > 0) ? 2 : 1); + if (sent != total) + { + return (sent < 0) ? -errno : -EIO; + } + + client->last_activity = time(NULL); + + return OK; +} + +/**************************************************************************** + * Name: nxmb_tcp_evict_idle + * + * Description: + * Close idle client connections that exceed the configured timeout. + * + ****************************************************************************/ + +static void nxmb_tcp_evict_idle(FAR struct nxmb_tcp_state_s *state, + time_t now) +{ + int i; + + for (i = 0; i < CONFIG_NXMODBUS_TCP_MAX_CLIENTS; i++) + { + if (state->clients[i].fd >= 0 && + (now - state->clients[i].last_activity) > + CONFIG_NXMODBUS_TCP_TIMEOUT_SEC) + { + close(state->clients[i].fd); + state->clients[i].fd = -1; + } + } +} + +/**************************************************************************** + * Name: nxmb_tcp_accept_new + * + * Description: + * Accept a pending connection into the first free client slot. + * + ****************************************************************************/ + +static void nxmb_tcp_accept_new(FAR struct nxmb_tcp_state_s *state) +{ + int fd; + int i; + + fd = accept(state->listen_fd, NULL, NULL); + if (fd < 0) + { + return; + } + + for (i = 0; i < CONFIG_NXMODBUS_TCP_MAX_CLIENTS; i++) + { + if (state->clients[i].fd < 0) + { + state->clients[i].fd = fd; + state->clients[i].last_activity = time(NULL); + return; + } + } + + /* No free slot -- reject the connection */ + + close(fd); +} + +/**************************************************************************** + * Name: nxmb_tcp_read_frame + * + * Description: + * Read a complete Modbus TCP frame from a client connection. + * On error (except timeout), the connection is closed. + * + ****************************************************************************/ + +static int nxmb_tcp_read_frame(nxmb_handle_t ctx, + FAR struct nxmb_tcp_client_s *client) +{ + uint8_t header[MBAP_FC_SIZE]; + uint16_t data_len; + int ret; + + ret = nxmb_tcp_recv_full(client->fd, header, MBAP_FC_SIZE, + NXMB_TCP_RECV_MS); + if (ret < 0) + { + if (ret == -ETIMEDOUT || ret == -EAGAIN) + { + return -EAGAIN; + } + + close(client->fd); + client->fd = -1; + return ret; + } + + nxmb_tcp_get_header(&ctx->adu, header); + + if (ctx->adu.proto_id != 0x0000) + { + close(client->fd); + client->fd = -1; + return -EPROTO; + } + + if (ctx->adu.length < 2) + { + close(client->fd); + client->fd = -1; + return -EINVAL; + } + + data_len = ctx->adu.length - 2; + + if (data_len > NXMB_ADU_DATA_MAX) + { + close(client->fd); + client->fd = -1; + return -EMSGSIZE; + } + + if (data_len > 0) + { + ret = nxmb_tcp_recv_full(client->fd, ctx->adu.data, data_len, + NXMB_TCP_RECV_MS); + if (ret < 0) + { + close(client->fd); + client->fd = -1; + return ret; + } + } + + client->trans_id = ctx->adu.trans_id; + client->last_activity = time(NULL); + + return ctx->adu.length; +} + +static int nxmb_tcp_receive(nxmb_handle_t ctx) +{ + FAR struct nxmb_tcp_state_s *state; + struct timeval tv; + fd_set readfds; + time_t now; + int maxfd; + int ret; + int i; + + DEBUGASSERT(ctx && ctx->transport_state); + + state = ctx->transport_state; + state->active_idx = -1; + + /* Client mode: single connection, read directly */ + + if (ctx->is_client) + { + if (state->clients[0].fd < 0) + { + return -ENOTCONN; + } + + state->active_idx = 0; + return nxmb_tcp_read_frame(ctx, &state->clients[0]); + } + + /* Server mode: multiplex listen socket + all client connections */ + + now = time(NULL); + nxmb_tcp_evict_idle(state, now); + + FD_ZERO(&readfds); + maxfd = -1; + + if (state->listen_fd >= 0) + { + FD_SET(state->listen_fd, &readfds); + maxfd = state->listen_fd; + } + + for (i = 0; i < CONFIG_NXMODBUS_TCP_MAX_CLIENTS; i++) + { + if (state->clients[i].fd >= 0) + { + FD_SET(state->clients[i].fd, &readfds); + if (state->clients[i].fd > maxfd) + { + maxfd = state->clients[i].fd; + } + } + } + + if (maxfd < 0) + { + return -EAGAIN; + } + + tv.tv_sec = 0; + tv.tv_usec = 50000; + + ret = select(maxfd + 1, &readfds, NULL, NULL, &tv); + if (ret < 0) + { + return -errno; + } + + if (ret == 0) + { + return -EAGAIN; + } + + /* Accept new connections if listen socket is ready */ + + if (state->listen_fd >= 0 && FD_ISSET(state->listen_fd, &readfds)) + { + nxmb_tcp_accept_new(state); + } + + /* Check each client for incoming data (first ready wins). + * In server mode, a per-client read failure (disconnect, protocol + * error, etc.) must not be fatal - nxmb_tcp_read_frame has already + * closed the offending fd, and the listen socket remains open for new + * connections. Translate any such error to -EAGAIN so the caller + * keeps polling. + */ + + for (i = 0; i < CONFIG_NXMODBUS_TCP_MAX_CLIENTS; i++) + { + if (state->clients[i].fd >= 0 && + FD_ISSET(state->clients[i].fd, &readfds)) + { + state->active_idx = i; + ret = nxmb_tcp_read_frame(ctx, &state->clients[i]); + if (ret < 0 && ret != -EAGAIN) + { + state->active_idx = -1; + return -EAGAIN; + } + + return ret; + } + } + + return -EAGAIN; +} diff --git a/system/nxmbclient/CMakeLists.txt b/system/nxmbclient/CMakeLists.txt new file mode 100644 index 000000000..fa463ae85 --- /dev/null +++ b/system/nxmbclient/CMakeLists.txt @@ -0,0 +1,35 @@ +# ############################################################################## +# apps/system/nxmbclient/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_SYSTEM_NXMBCLIENT) + nuttx_add_application( + NAME + ${CONFIG_NXMBCLIENT_PROGNAME} + PRIORITY + ${CONFIG_NXMBCLIENT_PRIORITY} + STACKSIZE + ${CONFIG_NXMBCLIENT_STACKSIZE} + MODULE + ${CONFIG_SYSTEM_NXMBCLIENT} + SRCS + nxmbclient_main.c) +endif() diff --git a/system/nxmbclient/Kconfig b/system/nxmbclient/Kconfig new file mode 100644 index 000000000..8768d601c --- /dev/null +++ b/system/nxmbclient/Kconfig @@ -0,0 +1,32 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config SYSTEM_NXMBCLIENT + tristate "NxModbus Client Tool" + default n + depends on NXMODBUS_CLIENT + ---help--- + Enable the NxModbus client command-line tool. This utility allows + you to perform Modbus client operations from the command line, + supporting RTU, ASCII, and TCP transports. + +if SYSTEM_NXMBCLIENT + +config NXMBCLIENT_PROGNAME + string "Program name" + default "nxmbclient" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config NXMBCLIENT_PRIORITY + int "NxModbus client task priority" + default 100 + +config NXMBCLIENT_STACKSIZE + int "NxModbus client stack size" + default DEFAULT_TASK_STACKSIZE + +endif # SYSTEM_NXMBCLIENT diff --git a/system/nxmbclient/Make.defs b/system/nxmbclient/Make.defs new file mode 100644 index 000000000..e171ba4d4 --- /dev/null +++ b/system/nxmbclient/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/system/nxmbclient/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_SYSTEM_NXMBCLIENT),) +CONFIGURED_APPS += $(APPDIR)/system/nxmbclient +endif diff --git a/system/nxmbclient/Makefile b/system/nxmbclient/Makefile new file mode 100644 index 000000000..f4e1a7cc0 --- /dev/null +++ b/system/nxmbclient/Makefile @@ -0,0 +1,32 @@ +############################################################################ +# apps/system/nxmbclient/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +MAINSRC = nxmbclient_main.c + +PROGNAME = $(CONFIG_NXMBCLIENT_PROGNAME) +PRIORITY = $(CONFIG_NXMBCLIENT_PRIORITY) +STACKSIZE = $(CONFIG_NXMBCLIENT_STACKSIZE) +MODULE = $(CONFIG_SYSTEM_NXMBCLIENT) + +include $(APPDIR)/Application.mk diff --git a/system/nxmbclient/nxmbclient_main.c b/system/nxmbclient/nxmbclient_main.c new file mode 100644 index 000000000..eb550d07c --- /dev/null +++ b/system/nxmbclient/nxmbclient_main.c @@ -0,0 +1,799 @@ +/**************************************************************************** + * apps/system/nxmbclient/nxmbclient_main.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEFAULT_TIMEOUT_MS 1000 +#define DEFAULT_UNIT_ID 1 +#define DEFAULT_TCP_PORT 502 +#define DEFAULT_BAUDRATE 115200 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Modbus client type */ + +enum transport_type_e +{ + TRANSPORT_RTU = 0, + TRANSPORT_ASCII, + TRANSPORT_TCP +}; + +/* Modbus client configuration */ + +struct nxmbclient_config_s +{ + enum transport_type_e transport; + enum nxmb_parity_e parity; + FAR const char *device; + FAR const char *host; + uint32_t baudrate; + uint16_t port; + uint8_t unit_id; + uint32_t timeout_ms; + uint32_t poll_ms; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static volatile bool g_running = true; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: signal_handler + ****************************************************************************/ + +static void signal_handler(int signo) +{ + g_running = false; +} + +/**************************************************************************** + * Name: show_usage + ****************************************************************************/ + +static void show_usage(FAR const char *progname) +{ + printf("Usage: %s [OPTIONS] COMMAND [ARGS...]\n\n", progname); + printf("Transport Options:\n"); + printf(" -t TYPE Transport type: rtu, ascii, tcp (required)\n"); + printf(" -d DEVICE Serial device path (for RTU/ASCII)\n"); + printf(" -b BAUD Baud rate (default: %u)\n", DEFAULT_BAUDRATE); + printf(" -p PARITY Parity: none, even, odd (default: none)\n"); + printf(" -h HOST TCP host address (for TCP)\n"); + printf(" -P PORT TCP port (default: %u)\n", DEFAULT_TCP_PORT); + printf("\nModbus Options:\n"); + printf(" -u UNIT Unit ID (default: %u)\n", DEFAULT_UNIT_ID); + printf(" -T TIMEOUT Timeout in ms (default: %u)\n", DEFAULT_TIMEOUT_MS); + printf(" --poll MS Polling interval in ms (0 = one-shot)\n"); + printf("\nCommands:\n"); + printf(" read-coils ADDR COUNT\n"); + printf(" read-discrete ADDR COUNT\n"); + printf(" read-input ADDR COUNT\n"); + printf(" read-holding ADDR COUNT\n"); + printf(" write-coil ADDR VALUE\n"); + printf(" write-holding ADDR VALUE\n"); + printf(" write-coils ADDR VALUE...\n"); + printf(" write-holdings ADDR VALUE...\n"); +} + +/**************************************************************************** + * Name: parse_parity + ****************************************************************************/ + +static int parse_parity(FAR const char *str, FAR enum nxmb_parity_e *parity) +{ + if (strcmp(str, "none") == 0) + { + *parity = NXMB_PAR_NONE; + } + else if (strcmp(str, "even") == 0) + { + *parity = NXMB_PAR_EVEN; + } + else if (strcmp(str, "odd") == 0) + { + *parity = NXMB_PAR_ODD; + } + else + { + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: parse_transport + ****************************************************************************/ + +static int parse_transport(FAR const char *str, + FAR enum transport_type_e *transport) +{ + if (strcmp(str, "rtu") == 0) + { + *transport = TRANSPORT_RTU; + } + else if (strcmp(str, "ascii") == 0) + { + *transport = TRANSPORT_ASCII; + } + else if (strcmp(str, "tcp") == 0) + { + *transport = TRANSPORT_TCP; + } + else + { + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: cmd_read_coils + ****************************************************************************/ + +static int cmd_read_coils(nxmb_handle_t handle, uint8_t unit_id, + int argc, FAR char **argv) +{ + FAR uint8_t *values; + uint16_t addr; + uint16_t count; + uint16_t nbytes; + int ret; + int i; + + if (argc < 2) + { + fprintf(stderr, "Error: read-coils requires ADDR COUNT\n"); + return -EINVAL; + } + + addr = (uint16_t)strtoul(argv[0], NULL, 0); + count = (uint16_t)strtoul(argv[1], NULL, 0); + nbytes = (count + 7) / 8; + + values = malloc(nbytes); + if (values == NULL) + { + return -ENOMEM; + } + + memset(values, 0, nbytes); + + ret = nxmb_read_coils(handle, unit_id, addr, count, values); + if (ret < 0) + { + fprintf(stderr, "Error: read-coils failed: %d\n", ret); + free(values); + return ret; + } + + for (i = 0; i < count; i++) + { + printf("%u\t%u\n", addr + i, + (values[i / 8] >> (i % 8)) & 1); + } + + free(values); + return OK; +} + +/**************************************************************************** + * Name: cmd_read_discrete + ****************************************************************************/ + +static int cmd_read_discrete(nxmb_handle_t handle, uint8_t unit_id, + int argc, FAR char **argv) +{ + FAR uint8_t *values; + uint16_t addr; + uint16_t count; + uint16_t nbytes; + int ret; + int i; + + if (argc < 2) + { + fprintf(stderr, "Error: read-discrete requires ADDR COUNT\n"); + return -EINVAL; + } + + addr = (uint16_t)strtoul(argv[0], NULL, 0); + count = (uint16_t)strtoul(argv[1], NULL, 0); + nbytes = (count + 7) / 8; + + values = malloc(nbytes); + if (values == NULL) + { + return -ENOMEM; + } + + memset(values, 0, nbytes); + + ret = nxmb_read_discrete(handle, unit_id, addr, count, values); + if (ret < 0) + { + fprintf(stderr, "Error: read-discrete failed: %d\n", ret); + free(values); + return ret; + } + + for (i = 0; i < count; i++) + { + printf("%u\t%u\n", addr + i, + (values[i / 8] >> (i % 8)) & 1); + } + + free(values); + return OK; +} + +/**************************************************************************** + * Name: cmd_read_input + ****************************************************************************/ + +static int cmd_read_input(nxmb_handle_t handle, uint8_t unit_id, + int argc, FAR char **argv) +{ + FAR uint16_t *values; + uint16_t addr; + uint16_t count; + int ret; + int i; + + if (argc < 2) + { + fprintf(stderr, "Error: read-input requires ADDR COUNT\n"); + return -EINVAL; + } + + addr = (uint16_t)strtoul(argv[0], NULL, 0); + count = (uint16_t)strtoul(argv[1], NULL, 0); + + values = malloc(count * sizeof(uint16_t)); + if (values == NULL) + { + return -ENOMEM; + } + + ret = nxmb_read_input(handle, unit_id, addr, count, values); + if (ret < 0) + { + fprintf(stderr, "Error: read-input failed: %d\n", ret); + free(values); + return ret; + } + + for (i = 0; i < count; i++) + { + printf("%u\t%u\n", addr + i, values[i]); + } + + free(values); + return OK; +} + +/**************************************************************************** + * Name: cmd_read_holding + ****************************************************************************/ + +static int cmd_read_holding(nxmb_handle_t handle, uint8_t unit_id, + int argc, FAR char **argv) +{ + FAR uint16_t *values; + uint16_t addr; + uint16_t count; + int ret; + int i; + + if (argc < 2) + { + fprintf(stderr, "Error: read-holding requires ADDR COUNT\n"); + return -EINVAL; + } + + addr = (uint16_t)strtoul(argv[0], NULL, 0); + count = (uint16_t)strtoul(argv[1], NULL, 0); + + values = malloc(count * sizeof(uint16_t)); + if (values == NULL) + { + return -ENOMEM; + } + + ret = nxmb_read_holding(handle, unit_id, addr, count, values); + if (ret < 0) + { + fprintf(stderr, "Error: read-holding failed: %d\n", ret); + free(values); + return ret; + } + + for (i = 0; i < count; i++) + { + printf("%u\t%u\n", addr + i, values[i]); + } + + free(values); + return OK; +} + +/**************************************************************************** + * Name: cmd_write_coil + ****************************************************************************/ + +static int cmd_write_coil(nxmb_handle_t handle, uint8_t unit_id, + int argc, FAR char **argv) +{ + uint16_t addr; + uint8_t value; + int ret; + + if (argc < 2) + { + fprintf(stderr, "Error: write-coil requires ADDR VALUE\n"); + return -EINVAL; + } + + addr = (uint16_t)strtoul(argv[0], NULL, 0); + value = (uint8_t)strtoul(argv[1], NULL, 0); + + ret = nxmb_write_coil(handle, unit_id, addr, value); + if (ret < 0) + { + fprintf(stderr, "Error: write-coil failed: %d\n", ret); + return ret; + } + + printf("OK\n"); + return OK; +} + +/**************************************************************************** + * Name: cmd_write_holding + ****************************************************************************/ + +static int cmd_write_holding(nxmb_handle_t handle, uint8_t unit_id, + int argc, FAR char **argv) +{ + uint16_t addr; + uint16_t value; + int ret; + + if (argc < 2) + { + fprintf(stderr, "Error: write-holding requires ADDR VALUE\n"); + return -EINVAL; + } + + addr = (uint16_t)strtoul(argv[0], NULL, 0); + value = (uint16_t)strtoul(argv[1], NULL, 0); + + ret = nxmb_write_holding(handle, unit_id, addr, value); + if (ret < 0) + { + fprintf(stderr, "Error: write-holding failed: %d\n", ret); + return ret; + } + + printf("OK\n"); + return OK; +} + +/**************************************************************************** + * Name: cmd_write_coils + ****************************************************************************/ + +static int cmd_write_coils(nxmb_handle_t handle, uint8_t unit_id, + int argc, FAR char **argv) +{ + FAR uint8_t *values; + uint16_t addr; + uint16_t count; + int ret; + int i; + + if (argc < 2) + { + fprintf(stderr, "Error: write-coils requires ADDR VALUE...\n"); + return -EINVAL; + } + + addr = (uint16_t)strtoul(argv[0], NULL, 0); + count = argc - 1; + + values = malloc(count); + if (values == NULL) + { + return -ENOMEM; + } + + for (i = 0; i < count; i++) + { + values[i] = (uint8_t)strtoul(argv[i + 1], NULL, 0); + } + + ret = nxmb_write_coils(handle, unit_id, addr, count, values); + if (ret < 0) + { + fprintf(stderr, "Error: write-coils failed: %d\n", ret); + free(values); + return ret; + } + + free(values); + printf("OK\n"); + return OK; +} + +/**************************************************************************** + * Name: cmd_write_holdings + ****************************************************************************/ + +static int cmd_write_holdings(nxmb_handle_t handle, uint8_t unit_id, + int argc, FAR char **argv) +{ + FAR uint16_t *values; + uint16_t addr; + uint16_t count; + int ret; + int i; + + if (argc < 2) + { + fprintf(stderr, "Error: write-holdings requires ADDR VALUE...\n"); + return -EINVAL; + } + + addr = (uint16_t)strtoul(argv[0], NULL, 0); + count = argc - 1; + + values = malloc(count * sizeof(uint16_t)); + if (values == NULL) + { + return -ENOMEM; + } + + for (i = 0; i < count; i++) + { + values[i] = (uint16_t)strtoul(argv[i + 1], NULL, 0); + } + + ret = nxmb_write_holdings(handle, unit_id, addr, count, values); + if (ret < 0) + { + fprintf(stderr, "Error: write-holdings failed: %d\n", ret); + free(values); + return ret; + } + + free(values); + printf("OK\n"); + return OK; +} + +/**************************************************************************** + * Name: execute_command + ****************************************************************************/ + +static int execute_command(nxmb_handle_t handle, + uint8_t unit_id, + FAR const char *cmd, + int argc, + FAR char **argv) +{ + if (strcmp(cmd, "read-coils") == 0) + { + return cmd_read_coils(handle, unit_id, argc, argv); + } + else if (strcmp(cmd, "read-discrete") == 0) + { + return cmd_read_discrete(handle, unit_id, argc, argv); + } + else if (strcmp(cmd, "read-input") == 0) + { + return cmd_read_input(handle, unit_id, argc, argv); + } + else if (strcmp(cmd, "read-holding") == 0) + { + return cmd_read_holding(handle, unit_id, argc, argv); + } + else if (strcmp(cmd, "write-coil") == 0) + { + return cmd_write_coil(handle, unit_id, argc, argv); + } + else if (strcmp(cmd, "write-holding") == 0) + { + return cmd_write_holding(handle, unit_id, argc, argv); + } + else if (strcmp(cmd, "write-coils") == 0) + { + return cmd_write_coils(handle, unit_id, argc, argv); + } + else if (strcmp(cmd, "write-holdings") == 0) + { + return cmd_write_holdings(handle, unit_id, argc, argv); + } + else + { + fprintf(stderr, "Error: unknown command '%s'\n", cmd); + return -EINVAL; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmbclient_main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + struct nxmbclient_config_s config; + struct nxmb_config_s mb_config; + nxmb_handle_t handle = NULL; + struct sigaction sa; + FAR const char *cmd; + int option; + int ret; + int cmd_argc; + FAR char **cmd_argv; + + /* Initialize config with defaults */ + + memset(&config, 0, sizeof(config)); + config.baudrate = DEFAULT_BAUDRATE; + config.parity = NXMB_PAR_NONE; + config.port = DEFAULT_TCP_PORT; + config.unit_id = DEFAULT_UNIT_ID; + config.timeout_ms = DEFAULT_TIMEOUT_MS; + config.poll_ms = 0; + + /* Parse options */ + + while ((option = getopt(argc, argv, "t:d:b:p:h:P:u:T:-:")) != -1) + { + switch (option) + { + case 't': + if (parse_transport(optarg, &config.transport) < 0) + { + fprintf(stderr, "Error: invalid transport '%s'\n", optarg); + return EXIT_FAILURE; + } + break; + + case 'd': + config.device = optarg; + break; + + case 'b': + config.baudrate = strtoul(optarg, NULL, 0); + break; + + case 'p': + if (parse_parity(optarg, &config.parity) < 0) + { + fprintf(stderr, "Error: invalid parity '%s'\n", optarg); + return EXIT_FAILURE; + } + break; + + case 'h': + config.host = optarg; + break; + + case 'P': + config.port = (uint16_t)strtoul(optarg, NULL, 0); + break; + + case 'u': + config.unit_id = (uint8_t)strtoul(optarg, NULL, 0); + break; + + case 'T': + config.timeout_ms = strtoul(optarg, NULL, 0); + break; + + case '-': + if (strcmp(optarg, "poll") == 0) + { + if (optind < argc) + { + config.poll_ms = strtoul(argv[optind++], NULL, 0); + } + else + { + fprintf(stderr, "Error: --poll requires argument\n"); + return EXIT_FAILURE; + } + } + else + { + fprintf(stderr, "Error: unknown option --%s\n", optarg); + return EXIT_FAILURE; + } + break; + + default: + show_usage(argv[0]); + return EXIT_FAILURE; + } + } + + /* Check for command */ + + if (optind >= argc) + { + fprintf(stderr, "Error: no command specified\n"); + show_usage(argv[0]); + return EXIT_FAILURE; + } + + cmd = argv[optind]; + cmd_argc = argc - optind - 1; + cmd_argv = &argv[optind + 1]; + + /* Validate transport-specific options */ + + if (config.transport == TRANSPORT_RTU || + config.transport == TRANSPORT_ASCII) + { + if (config.device == NULL) + { + fprintf(stderr, "Error: -d DEVICE required for RTU/ASCII\n"); + return EXIT_FAILURE; + } + } + else if (config.transport == TRANSPORT_TCP) + { + if (config.host == NULL) + { + fprintf(stderr, "Error: -h HOST required for TCP\n"); + return EXIT_FAILURE; + } + } + + /* Setup signal handler for clean shutdown */ + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = signal_handler; + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + + /* Create Modbus context */ + + memset(&mb_config, 0, sizeof(mb_config)); + mb_config.unit_id = config.unit_id; + mb_config.is_client = true; + + if (config.transport == TRANSPORT_RTU) + { + mb_config.mode = NXMB_MODE_RTU; + mb_config.transport.serial.devpath = config.device; + mb_config.transport.serial.baudrate = config.baudrate; + mb_config.transport.serial.parity = config.parity; + } + else if (config.transport == TRANSPORT_ASCII) + { + mb_config.mode = NXMB_MODE_ASCII; + mb_config.transport.serial.devpath = config.device; + mb_config.transport.serial.baudrate = config.baudrate; + mb_config.transport.serial.parity = config.parity; + } + else if (config.transport == TRANSPORT_TCP) + { + mb_config.mode = NXMB_MODE_TCP; + mb_config.transport.tcp.host = config.host; + mb_config.transport.tcp.port = config.port; + } + + ret = nxmb_create(&handle, &mb_config); + if (ret < 0) + { + fprintf(stderr, "Error: failed to create Modbus context: %d\n", ret); + return EXIT_FAILURE; + } + + /* Enable context */ + + ret = nxmb_enable(handle); + if (ret < 0) + { + fprintf(stderr, "Error: failed to enable context: %d\n", ret); + nxmb_destroy(handle); + return EXIT_FAILURE; + } + + /* Set timeout */ + + ret = nxmb_set_timeout(handle, config.timeout_ms); + if (ret < 0) + { + fprintf(stderr, "Error: failed to set timeout: %d\n", ret); + nxmb_disable(handle); + nxmb_destroy(handle); + return EXIT_FAILURE; + } + + /* Execute command (with optional polling) */ + + if (config.poll_ms > 0) + { + /* Polling mode */ + + while (g_running) + { + ret = execute_command(handle, config.unit_id, cmd, cmd_argc, + cmd_argv); + if (ret < 0) + { + break; + } + + usleep(config.poll_ms * 1000); + } + } + else + { + /* One-shot mode */ + + ret = execute_command(handle, config.unit_id, cmd, cmd_argc, + cmd_argv); + } + + /* Cleanup */ + + nxmb_disable(handle); + nxmb_destroy(handle); + + return (ret < 0) ? EXIT_FAILURE : EXIT_SUCCESS; +} From 180607372a12b26d1c312c7ef2f3774f235e3695 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Fri, 24 Apr 2026 09:19:23 +0200 Subject: [PATCH 297/568] .github/build.yml: improve ntfc installation increase retries and timeout for pip install and try again in case of failure Signed-off-by: raiden00pl --- .github/workflows/build.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 740d6f81d..a8aba0de8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -183,7 +183,15 @@ jobs: run: | export ARTIFACTDIR=`pwd`/buildartifacts - pip install ntfc==0.0.1 + for i in 1 2 3; do + python -m pip install \ + --default-timeout=100 \ + --retries 10 \ + ntfc==0.0.1 && break + echo "Retry $i failed..." + sleep 5 + done + mkdir /github/workspace/nuttx-ntfc mkdir /github/workspace/nuttx-ntfc/external cd /github/workspace/nuttx-ntfc From eccfba4776808ad1a705d9da25793bdd8d227afe Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Fri, 24 Apr 2026 09:30:59 +0200 Subject: [PATCH 298/568] .github: use ntfc test cases from Apache repo use ntfc test cases from Apache repo Signed-off-by: raiden00pl --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a8aba0de8..05735c18d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -197,7 +197,8 @@ jobs: cd /github/workspace/nuttx-ntfc # get NTFC test cases cd external - git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-testing + git clone -b release-0.0.1 https://github.com/apache/nuttx-ntfc-testing + mv nuttx-ntfc-testing nuttx-testing export NTFCDIR=/github/workspace/nuttx-ntfc echo "::add-matcher::sources/nuttx/.github/gcc.json" From 901278a4bab1ef503de1569096ff01f95b25c3d3 Mon Sep 17 00:00:00 2001 From: Tiago Medicci Date: Mon, 20 Apr 2026 17:04:51 -0300 Subject: [PATCH 299/568] examples: Remove deprecated `rmtchar` example application The upper-half RMT driver is no longer available on NuttX. Instead, Espressif's RMT peripheral was bound directly to the lirc driver. For testing purposes, use the `irtest` application. NuttX OS PR https://github.com/apache/nuttx/pull/18654 removed the upper-half driver interface used by this application, so removing it does not break any existing feature on NuttX. Signed-off-by: Tiago Medicci --- examples/rmtchar/CMakeLists.txt | 40 --- examples/rmtchar/Kconfig | 68 ----- examples/rmtchar/Make.defs | 25 -- examples/rmtchar/Makefile | 43 --- examples/rmtchar/rmtchar.h | 129 --------- examples/rmtchar/rmtchar_common.c | 93 ------- examples/rmtchar/rmtchar_main.c | 362 ------------------------- examples/rmtchar/rmtchar_receiver.c | 140 ---------- examples/rmtchar/rmtchar_transmitter.c | 158 ----------- 9 files changed, 1058 deletions(-) delete mode 100644 examples/rmtchar/CMakeLists.txt delete mode 100644 examples/rmtchar/Kconfig delete mode 100644 examples/rmtchar/Make.defs delete mode 100644 examples/rmtchar/Makefile delete mode 100644 examples/rmtchar/rmtchar.h delete mode 100644 examples/rmtchar/rmtchar_common.c delete mode 100644 examples/rmtchar/rmtchar_main.c delete mode 100644 examples/rmtchar/rmtchar_receiver.c delete mode 100644 examples/rmtchar/rmtchar_transmitter.c diff --git a/examples/rmtchar/CMakeLists.txt b/examples/rmtchar/CMakeLists.txt deleted file mode 100644 index a01ebe080..000000000 --- a/examples/rmtchar/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -# ############################################################################## -# apps/examples/rmtchar/CMakeLists.txt -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed to the Apache Software Foundation (ASF) under one or more contributor -# license agreements. See the NOTICE file distributed with this work for -# additional information regarding copyright ownership. The ASF licenses this -# file to you under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. -# -# ############################################################################## - -if(CONFIG_EXAMPLES_RMTCHAR) - nuttx_add_application( - NAME - rmtchar - STACKSIZE - ${CONFIG_DEFAULT_TASK_STACKSIZE} - MODULE - ${CONFIG_EXAMPLES_RMTCHAR} - SRCS - rmtchar_main.c) - target_sources(apps PRIVATE rmtchar_common.c) - if(CONFIG_EXAMPLES_RMTCHAR_TX) - target_sources(apps PRIVATE rmtchar_transmitter.c) - endif() - if(CONFIG_EXAMPLES_RMTCHAR_RX) - target_sources(apps PRIVATE rmtchar_receiver.c) - endif() -endif() diff --git a/examples/rmtchar/Kconfig b/examples/rmtchar/Kconfig deleted file mode 100644 index e88da638a..000000000 --- a/examples/rmtchar/Kconfig +++ /dev/null @@ -1,68 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see the file kconfig-language.txt in the NuttX tools repository. -# - -config EXAMPLES_RMTCHAR - tristate "RMT character driver test" - default n - depends on RMT - ---help--- - Enable the RMT character driver test - -if EXAMPLES_RMTCHAR - -config EXAMPLES_RMTCHAR_TX - bool "Use RMT transmitter" - default n - ---help--- - This should be set if the RMT device supports a transmitter. - -if EXAMPLES_RMTCHAR_TX - -config EXAMPLES_RMTCHAR_TX_DEVPATH - string "RMT transmitter character device path" - default "/dev/rmt0" - ---help--- - The default path to the RMT transmitter character device. - Default: /dev/rmt0 - -config EXAMPLES_RMTCHAR_TXSTACKSIZE - int "Transmitter thread stack size" - default DEFAULT_TASK_STACKSIZE - ---help--- - This is the stack size to use when starting the transmitter thread. - -endif # EXAMPLES_RMTCHAR_TX - -config EXAMPLES_RMTCHAR_RX - bool "Use RMT receiver" - default n - ---help--- - This should be set if the RMT device supports a receiver. - -if EXAMPLES_RMTCHAR_RX - -config EXAMPLES_RMTCHAR_RX_DEVPATH - string "RMT receiver character device path" - default "/dev/rmt1" - ---help--- - The default path to the RMT receiver character device. - Default: /dev/rmt1 - -config EXAMPLES_RMTCHAR_RXSTACKSIZE - int "Receiver thread stack size" - default DEFAULT_TASK_STACKSIZE - ---help--- - This is the stack size to use when starting the receiver thread. - -endif # EXAMPLES_RMTCHAR_RX - -config EXAMPLES_RMTCHAR_ITEMS - int "Number of words to transmit or receive" - default 64 - ---help--- - This is the total amount of words to be transmitted or - received by the RMT RX device. - -endif diff --git a/examples/rmtchar/Make.defs b/examples/rmtchar/Make.defs deleted file mode 100644 index 0b14b2487..000000000 --- a/examples/rmtchar/Make.defs +++ /dev/null @@ -1,25 +0,0 @@ -############################################################################ -# apps/examples/rmtchar/Make.defs -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. The -# ASF licenses this file to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance with the -# License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -############################################################################ - -ifneq ($(CONFIG_EXAMPLES_RMTCHAR),) -CONFIGURED_APPS += $(APPDIR)/examples/rmtchar -endif diff --git a/examples/rmtchar/Makefile b/examples/rmtchar/Makefile deleted file mode 100644 index 2c6d454dd..000000000 --- a/examples/rmtchar/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################ -# apps/examples/rmtchar/Makefile -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. The -# ASF licenses this file to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance with the -# License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -############################################################################ - -include $(APPDIR)/Make.defs - -# rmt character driver test - -ifeq ($(CONFIG_EXAMPLES_RMTCHAR_TX),y) -CSRCS += rmtchar_transmitter.c -endif -ifeq ($(CONFIG_EXAMPLES_RMTCHAR_RX),y) -CSRCS += rmtchar_receiver.c -endif -CSRCS += rmtchar_common.c -MAINSRC = rmtchar_main.c - -# Touchscreen built-in application info - -PROGNAME = rmtchar -PRIORITY = SCHED_PRIORITY_DEFAULT -STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) -MODULE = $(CONFIG_EXAMPLES_RMTCHAR) - -include $(APPDIR)/Application.mk diff --git a/examples/rmtchar/rmtchar.h b/examples/rmtchar/rmtchar.h deleted file mode 100644 index 832b80a4c..000000000 --- a/examples/rmtchar/rmtchar.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** - * apps/examples/rmtchar/rmtchar.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __APPS_EXAMPLES_RMTCHAR_RMTCHAR_H -#define __APPS_EXAMPLES_RMTCHAR_RMTCHAR_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Configuration */ - -#ifndef CONFIG_EXAMPLES_RMTCHAR_TX_DEVPATH -# define CONFIG_EXAMPLES_RMTCHAR_TX_DEVPATH "/dev/rmt0" -#endif - -#ifndef CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH -# define CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH "/dev/rmt1" -#endif - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -struct rmtchar_state_s -{ - bool initialized; - int rmtchar_items; -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX - FAR char *txdevpath; -#endif -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX - FAR char *rxdevpath; -#endif -}; - -struct rmt_item32_s -{ - union - { - struct - { - uint32_t duration0 : 15; /* Duration of level0 */ - uint32_t level0 : 1; /* Level of the first part */ - uint32_t duration1 : 15; /* Duration of level1 */ - uint32_t level1 : 1; /* Level of the second part */ - }; - uint32_t val; /* Equivalent unsigned value for the RMT item */ - }; -}; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Name: rmtchar_transmitter() - * - * Description: - * This is the entry point for the transmitter thread. - * - ****************************************************************************/ - -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX -pthread_addr_t rmtchar_transmitter(pthread_addr_t arg); -#endif - -/**************************************************************************** - * Name: rmtchar_receiver() - * - * Description: - * This is the entry point for the receiver thread. - * - ****************************************************************************/ - -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX -pthread_addr_t rmtchar_receiver(pthread_addr_t arg); -#endif - -/**************************************************************************** - * Name: print_items - * - * Description: - * This function prints the level and duration of RMT items stored in a - * buffer. It iterates over the buffer, printing the level and duration of - * each item in a formatted manner. - * - * Input Parameters: - * buf - Pointer to the buffer containing the RMT items. - * len - The number of RMT items in the buffer. - * - * Returned Value: - * None. - * - ****************************************************************************/ - -void print_items(struct rmt_item32_s *buf, int len); - -#endif /* __APPS_EXAMPLES_RMTCHAR_RMTCHAR_H */ diff --git a/examples/rmtchar/rmtchar_common.c b/examples/rmtchar/rmtchar_common.c deleted file mode 100644 index 098e5363a..000000000 --- a/examples/rmtchar/rmtchar_common.c +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** - * apps/examples/rmtchar/rmtchar_common.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "rmtchar.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: print_items - * - * Description: - * This function prints the level and duration of RMT items stored in a - * buffer. It iterates over the buffer, printing the level and duration of - * each item in a formatted manner. - * - * Input Parameters: - * buf - Pointer to the buffer containing the RMT items. - * len - The number of RMT items in the buffer. - * - * Returned Value: - * None. - * - ****************************************************************************/ - -void print_items(struct rmt_item32_s *buf, int len) -{ - int i; - - for (i = 0; i < len; i++, buf++) - { - printf("\t[%d]:\tL %d\tD %d\t", i, buf->level0, buf->duration0); - printf("L %d\t D %d\n", buf->level1, buf->duration1); - } -} diff --git a/examples/rmtchar/rmtchar_main.c b/examples/rmtchar/rmtchar_main.c deleted file mode 100644 index 63a8ced85..000000000 --- a/examples/rmtchar/rmtchar_main.c +++ /dev/null @@ -1,362 +0,0 @@ -/**************************************************************************** - * apps/examples/rmtchar/rmtchar_main.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include "rmtchar.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#if !defined(CONFIG_EXAMPLES_RMTCHAR_RX) && \ - !defined(CONFIG_EXAMPLES_RMTCHAR_TX) -# error "At least one of CONFIG_EXAMPLES_RMTCHAR_RX or \ - CONFIG_EXAMPLES_RMTCHAR_TX must be defined" -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static struct rmtchar_state_s g_rmtchar; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: rmtchar_devpath - ****************************************************************************/ - -static void rmtchar_devpath(FAR struct rmtchar_state_s *rmtchar, - FAR const char *devpath, - bool is_tx) -{ - /* Get rid of any old device path */ - - if (is_tx) - { - if (rmtchar->txdevpath) - { - free(rmtchar->txdevpath); - } - - /* Then set-up the new device path by copying the string */ - - rmtchar->txdevpath = strdup(devpath); - } - else - { - if (rmtchar->rxdevpath) - { - free(rmtchar->rxdevpath); - } - - /* Then set-up the new device path by copying the string */ - - rmtchar->rxdevpath = strdup(devpath); - } -} - -/**************************************************************************** - * Name: rmtchar_help - ****************************************************************************/ - -static void rmtchar_help(FAR struct rmtchar_state_s *rmtchar) -{ - printf("Usage: rmtchar [OPTIONS]\n"); - printf("\nArguments are \"sticky\".\n"); - printf("For example, once the RMT character device is\n"); - printf("specified, that device will be reused until it is changed.\n"); - printf("\n\"sticky\" OPTIONS include:\n"); - printf(" [-i items] selects the number of words (items) to be transmitted" - " or received by the RMT character device. " - "Default: %d Current: %d\n", - CONFIG_EXAMPLES_RMTCHAR_ITEMS, - rmtchar->rmtchar_items ? rmtchar->rmtchar_items : - CONFIG_EXAMPLES_RMTCHAR_ITEMS); -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX - printf(" [-t devpath] selects the RMT transmitter character device path. " - "Default: %s Current: %s\n", - CONFIG_EXAMPLES_RMTCHAR_TX_DEVPATH, - rmtchar->txdevpath ? rmtchar->txdevpath : "NONE"); -#endif -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX - printf(" [-r devpath] selects the RMT receiver character device path. " - "Default: %s Current: %s\n", - CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH, - rmtchar->rxdevpath ? rmtchar->rxdevpath : "NONE"); -#endif - printf(" [-h] shows this message and exits\n"); -} - -/**************************************************************************** - * Name: arg_string - ****************************************************************************/ - -static int arg_string(FAR char **arg, FAR char **value) -{ - FAR char *ptr = *arg; - - if (ptr[2] == '\0') - { - *value = arg[1]; - return 2; - } - else - { - *value = &ptr[2]; - return 1; - } -} - -/**************************************************************************** - * Name: arg_decimal - ****************************************************************************/ - -static int arg_decimal(FAR char **arg, FAR int *value) -{ - FAR char *string; - int ret; - - ret = arg_string(arg, &string); - *value = strtol(string, NULL, 10); - return ret; -} - -/**************************************************************************** - * Name: parse_args - ****************************************************************************/ - -static void parse_args(FAR struct rmtchar_state_s *rmtchar, - int argc, - FAR char **argv) -{ - FAR char *ptr; - FAR char *str; - int value; - int index; - int nargs; - - for (index = 1; index < argc; ) - { - ptr = argv[index]; - if (ptr[0] != '-') - { - printf("Invalid options format: %s\n", ptr); - exit(0); - } - - switch (ptr[1]) - { - case 'i': - nargs = arg_decimal(&argv[index], &value); - if (value < 0) - { - printf("Count must be non-negative: %d\n", value); - exit(1); - } - - rmtchar->rmtchar_items = value; - index += nargs; - break; -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX - case 't': - nargs = arg_string(&argv[index], &str); - rmtchar_devpath(rmtchar, str, true); - index += nargs; - break; -#endif - -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX - case 'r': - nargs = arg_string(&argv[index], &str); - rmtchar_devpath(rmtchar, str, false); - index += nargs; - break; -#endif - case 'h': - rmtchar_help(rmtchar); - exit(0); - - default: - printf("Unsupported option: %s\n", ptr); - rmtchar_help(rmtchar); - exit(1); - } - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: rmtchar_main - ****************************************************************************/ - -int main(int argc, FAR char *argv[]) -{ - pthread_attr_t attr; - pthread_addr_t result; -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX - pthread_t transmitter; -#endif -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX - pthread_t receiver; -#endif -#if defined(CONFIG_EXAMPLES_RMTCHAR_RX) && defined(CONFIG_EXAMPLES_RMTCHAR_TX) - struct sched_param param; -#endif - int ret; - - UNUSED(ret); - - /* Check if we have initialized */ - - if (!g_rmtchar.initialized) - { - /* Set the default values */ - - g_rmtchar.rmtchar_items = CONFIG_EXAMPLES_RMTCHAR_ITEMS; - -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX - rmtchar_devpath(&g_rmtchar, CONFIG_EXAMPLES_RMTCHAR_TX_DEVPATH, true); -#endif -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX - rmtchar_devpath(&g_rmtchar, CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH, false); -#endif - - g_rmtchar.initialized = true; - } - - /* Parse the command line */ - - parse_args(&g_rmtchar, argc, argv); - -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX - /* Start the receiver thread */ - - printf("rmtchar_main: Start receiver thread\n"); - pthread_attr_init(&attr); - -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX - /* Bump the receiver priority from the default so that it will be above - * the priority of transmitter. This is important if a loopback test is - * being performed. - */ - - pthread_attr_getschedparam(&attr, ¶m); - param.sched_priority++; - pthread_attr_setschedparam(&attr, ¶m); -#endif - - /* Set the receiver stack size */ - - pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_RMTCHAR_RXSTACKSIZE); - - /* Start the receiver */ - - ret = pthread_create(&receiver, &attr, rmtchar_receiver, &g_rmtchar); - if (ret != OK) - { - printf("rmtchar_main: ERROR: failed to Start receiver thread: %d\n", - ret); - return EXIT_FAILURE; - } - - pthread_setname_np(receiver, "receiver"); -#endif - -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX - /* Start the transmitter thread */ - - printf("rmtchar_main: Start transmitter thread\n"); - pthread_attr_init(&attr); - - /* Set the transmitter stack size */ - - pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_RMTCHAR_TXSTACKSIZE); - - /* Start the transmitter */ - - ret = pthread_create(&transmitter, &attr, rmtchar_transmitter, &g_rmtchar); - if (ret != OK) - { - printf("rmtchar_main: ERROR: failed to Start transmitter thread: %d\n", - ret); -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX - printf("rmtchar_main: Waiting for the receiver thread\n"); - pthread_join(receiver, &result); -#endif - return EXIT_FAILURE; - } - - pthread_setname_np(transmitter, "transmitter"); -#endif - -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX - printf("rmtchar_main: Waiting for the transmitter thread\n"); - ret = pthread_join(transmitter, &result); - if (ret != OK) - { - printf("rmtchar_main: ERROR: pthread_join failed: %d\n", ret); - } -#endif - -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX - printf("rmtchar_main: Waiting for the receiver thread\n"); - ret = pthread_join(receiver, &result); - if (ret != OK) - { - printf("rmtchar_main: ERROR: pthread_join failed: %d\n", ret); - } -#endif - - return EXIT_SUCCESS; -} diff --git a/examples/rmtchar/rmtchar_receiver.c b/examples/rmtchar/rmtchar_receiver.c deleted file mode 100644 index 2e1b20e36..000000000 --- a/examples/rmtchar/rmtchar_receiver.c +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** - * apps/examples/rmtchar/rmtchar_receiver.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "rmtchar.h" - -#ifdef CONFIG_EXAMPLES_RMTCHAR_RX - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: rmtchar_receiver() - * - * Description: - * This is the entry point for the receiver thread. - * - ****************************************************************************/ - -pthread_addr_t rmtchar_receiver(pthread_addr_t arg) -{ - FAR struct rmtchar_state_s *rmtchar = (FAR struct rmtchar_state_s *)arg; - struct rmt_item32_s buf[rmtchar->rmtchar_items]; - int nread; - int fd; - - /* Open the RMT character device */ - - fd = open(rmtchar->rxdevpath, O_RDONLY); - if (fd < 0) - { - int errcode = errno; - printf("rmtchar_receiver: ERROR: failed to open %s: %d\n", - rmtchar->rxdevpath, errcode); - pthread_exit(NULL); - } - - /* Flush any output before reading */ - - fflush(stdout); - - /* Read the buffer to the RMT character driver */ - - nread = read(fd, (char *)buf, rmtchar->rmtchar_items * - sizeof(struct rmt_item32_s)); - if (nread < 0) - { - int errcode = errno; - if (errcode != EINTR) - { - printf("rmtchar_receiver: ERROR: read failed: %d\n", - errcode); - close(fd); - pthread_exit(NULL); - } - } - else - { - if (nread != (rmtchar->rmtchar_items * sizeof(struct rmt_item32_s))) - { - printf("rmtchar_receiver: ERROR: partial read: %d\n", - nread); - printf("rmtchar_receiver: Received buffer:\n"); - print_items(buf, nread / sizeof(struct rmt_item32_s)); - close(fd); - pthread_exit(NULL); - } - else - { - printf("rmtchar_receiver: Received buffer:\n"); - print_items(buf, nread / sizeof(struct rmt_item32_s)); - } - } - - /* Make sure that the transmitter thread has a chance to run */ - - pthread_yield(); - - close(fd); - return NULL; -} - -#endif /* CONFIG_EXAMPLES_RMTCHAR_RX */ diff --git a/examples/rmtchar/rmtchar_transmitter.c b/examples/rmtchar/rmtchar_transmitter.c deleted file mode 100644 index 75fc0103b..000000000 --- a/examples/rmtchar/rmtchar_transmitter.c +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** - * apps/examples/rmtchar/rmtchar_transmitter.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "rmtchar.h" - -#ifdef CONFIG_EXAMPLES_RMTCHAR_TX - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: rmtchar_transmitter() - * - * Description: - * This is the entry point for the transmitter thread. - * - ****************************************************************************/ - -pthread_addr_t rmtchar_transmitter(pthread_addr_t arg) -{ - FAR struct rmtchar_state_s *rmtchar = (FAR struct rmtchar_state_s *)arg; - struct rmt_item32_s buf[rmtchar->rmtchar_items]; - int duration = 1000; - int nwritten; - int fd; - int i; - - /* Open the RMT character device */ - - fd = open(rmtchar->txdevpath, O_WRONLY); - if (fd < 0) - { - int errcode = errno; - printf("rmtchar_transmitter: ERROR: failed to open %s: %d\n", - rmtchar->txdevpath, errcode); - pthread_exit(NULL); - } - - /* Fill the transmitter buffer with known items */ - - for (i = 0; i < rmtchar->rmtchar_items; i++) - { - buf[i].level0 = 1; - buf[i].duration0 = duration; - buf[i].level1 = 0; - buf[i].duration1 = duration; - - duration += 10; - } - - /* Flush any output before writing */ - - fflush(stdout); - - /* Print the buffer to be sent */ - - print_items(buf, rmtchar->rmtchar_items); - - /* Then send the buffer */ - - /* Write the buffer to the RMT character driver */ - - nwritten = write(fd, (char *)buf, rmtchar->rmtchar_items * - sizeof(struct rmt_item32_s)); - if (nwritten < 0) - { - int errcode = errno; - if (errcode != EINTR) - { - printf("rmtchar_transmitter: ERROR: write failed: %d\n", - errcode); - close(fd); - pthread_exit(NULL); - } - } - else if (nwritten != (rmtchar->rmtchar_items * - sizeof(struct rmt_item32_s))) - { - printf("rmtchar_transmitter: ERROR: partial write: %d\n", - nwritten); - close(fd); - pthread_exit(NULL); - } - else - { - printf("rmtchar_transmitter: Send buffer with %d bytes\n", - rmtchar->rmtchar_items * sizeof(struct rmt_item32_s)); - } - - /* Make sure that the receiver thread has a chance to run */ - - pthread_yield(); - - close(fd); - return NULL; -} - -#endif /* CONFIG_EXAMPLES_RMTCHAR_TX */ From 6cb1a04fe7e53a25893d5c0aa2155e214daf230a Mon Sep 17 00:00:00 2001 From: Tiago Medicci Date: Mon, 20 Apr 2026 17:15:00 -0300 Subject: [PATCH 300/568] system/irtest: Fix issues regarding portability and buffer size This commit fixes issues regarding portability by using variables with fixed width (and their format macro constants). Signed-off-by: Tiago Medicci --- system/irtest/Kconfig | 2 +- system/irtest/cmd.cxx | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/system/irtest/Kconfig b/system/irtest/Kconfig index 34743bb87..e77bea6aa 100644 --- a/system/irtest/Kconfig +++ b/system/irtest/Kconfig @@ -32,7 +32,7 @@ config SYSTEM_IRTEST_MAX_NIRDEV default 2 config SYSTEM_IRTEST_MAX_SIRDATA - int "The Maximum size of sending data in unsigned int" + int "The Maximum size of sending data in nwords (4 bytes)" default 64 endif diff --git a/system/irtest/cmd.cxx b/system/irtest/cmd.cxx index d61527df7..8dde00437 100644 --- a/system/irtest/cmd.cxx +++ b/system/irtest/cmd.cxx @@ -226,7 +226,8 @@ CMD1(close_device, size_t, index) CMD1(write_data, size_t, index) { - unsigned int data[CONFIG_SYSTEM_IRTEST_MAX_SIRDATA]; + uint32_t data[CONFIG_SYSTEM_IRTEST_MAX_SIRDATA]; + uint32_t tmp; if (index >= CONFIG_SYSTEM_IRTEST_MAX_NIRDEV) { @@ -236,7 +237,7 @@ CMD1(write_data, size_t, index) int size = 0; for (; size < CONFIG_SYSTEM_IRTEST_MAX_SIRDATA; size++) { - unsigned int tmp = get_next_arg < unsigned int > (); + tmp = get_next_arg < uint32_t > (); if (tmp == 0) { break; @@ -250,14 +251,14 @@ CMD1(write_data, size_t, index) if (size % 2 == 0) { int result = write(g_irdevs[index], data, - sizeof(unsigned int) * (size - 1)); + sizeof(uint32_t) * (size - 1)); usleep(data[size - 1]); return result; } else { return write(g_irdevs[index], data, - sizeof(unsigned int) * size); + sizeof(uint32_t) * size); } } @@ -268,20 +269,20 @@ CMD2(read_data, size_t, index, size_t, size) return ERROR; } - unsigned int data[size]; + uint32_t data[size]; int result = read(g_irdevs[index], data, sizeof(data)); if (result > 0) { - result /= sizeof(unsigned int); + result /= sizeof(uint32_t); for (int i = 0; i < result; i++) { if (i + 1 == result) { - printf("%d\n", data[i]); + printf("%" PRIu32 "\n", data[i]); } else { - printf("%d, ", data[i]); + printf("%" PRIu32 ", ", data[i]); } } } From 9b6b7607f20d2ce119d14ee56da084e1ff582ac7 Mon Sep 17 00:00:00 2001 From: Tiago Medicci Date: Mon, 20 Apr 2026 17:26:17 -0300 Subject: [PATCH 301/568] system/irtest: Avoids silently truncating long write_data commands Long write_data commands can be truncated without any check due to the maximum size of CONFIG_SYSTEM_IRTEST_MAX_SIRDATA. This commit adds a check to avoid a silent fail. Signed-off-by: Tiago Medicci --- system/irtest/cmd.cxx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/system/irtest/cmd.cxx b/system/irtest/cmd.cxx index 8dde00437..c8673c9b1 100644 --- a/system/irtest/cmd.cxx +++ b/system/irtest/cmd.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "enum.hpp" @@ -246,6 +247,17 @@ CMD1(write_data, size_t, index) data[size] = tmp; } + /* Avoid silently truncating long write_data commands. */ + + if (size == CONFIG_SYSTEM_IRTEST_MAX_SIRDATA) + { + tmp = get_next_arg < uint32_t > (); + if (tmp != 0) + { + return -E2BIG; + } + } + /* lirc require the odd length */ if (size % 2 == 0) From 6379e531de0d73549a5242de1cc6c9ee7839db9b Mon Sep 17 00:00:00 2001 From: Tiago Medicci Date: Mon, 20 Apr 2026 17:22:26 -0300 Subject: [PATCH 302/568] system/irtest: Set `irtest` command line size to CONFIG_LINE_MAX Let `irtest` command line size be equal to CONFIG_LINE_MAX so that bigger (or smaller) commands can be set. Signed-off-by: Tiago Medicci --- system/irtest/main.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/system/irtest/main.cxx b/system/irtest/main.cxx index d8534aae6..a50976666 100644 --- a/system/irtest/main.cxx +++ b/system/irtest/main.cxx @@ -24,11 +24,17 @@ * Included Files ****************************************************************************/ +#include + #include #include "system/readline.h" #include "cmd.hpp" +#ifndef CONFIG_LINE_MAX +# define CONFIG_LINE_MAX 512 +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -48,7 +54,7 @@ extern "C" { int main(int argc, char *argv[]) { - char cmdline[512]; + char cmdline[CONFIG_LINE_MAX]; init_device(); From 62f3d37041f3a72dc71cec50187c656d89fed4e5 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Thu, 23 Apr 2026 23:16:47 +0800 Subject: [PATCH 303/568] examples/vncviewer: add VNC viewer for LCD display Add a minimal VNC viewer application that connects to a VNC server and renders the remote desktop on a local LCD. Features: - RFB 3.8 protocol with VNC Authentication (DES, pure software) - Raw encoding with pixel format auto-detected from LCD driver - Row-by-row rendering via LCDDEVIO_PUTAREA (minimal RAM usage) - LCD resolution and format queried at runtime via LCDDEVIO_GETVIDEOINFO - Auto-reconnect on connection loss with 2-second retry Usage: vncviewer [port] vncviewer -p [port] vncviewer -p -d [port] Assisted-by: GitHubCopilot:claude-4.6-opus Signed-off-by: wangjianyu3 --- system/vncviewer/CMakeLists.txt | 35 + system/vncviewer/Kconfig | 32 + system/vncviewer/Make.defs | 25 + system/vncviewer/Makefile | 37 + system/vncviewer/lcd_render.c | 177 +++++ system/vncviewer/lcd_render.h | 106 +++ system/vncviewer/rfb_protocol.c | 1051 +++++++++++++++++++++++++++++ system/vncviewer/rfb_protocol.h | 220 ++++++ system/vncviewer/vncviewer_main.c | 306 +++++++++ 9 files changed, 1989 insertions(+) create mode 100644 system/vncviewer/CMakeLists.txt create mode 100644 system/vncviewer/Kconfig create mode 100644 system/vncviewer/Make.defs create mode 100644 system/vncviewer/Makefile create mode 100644 system/vncviewer/lcd_render.c create mode 100644 system/vncviewer/lcd_render.h create mode 100644 system/vncviewer/rfb_protocol.c create mode 100644 system/vncviewer/rfb_protocol.h create mode 100644 system/vncviewer/vncviewer_main.c diff --git a/system/vncviewer/CMakeLists.txt b/system/vncviewer/CMakeLists.txt new file mode 100644 index 000000000..06fc69463 --- /dev/null +++ b/system/vncviewer/CMakeLists.txt @@ -0,0 +1,35 @@ +# ############################################################################## +# apps/system/vncviewer/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_SYSTEM_VNCVIEWER) + nuttx_add_application( + NAME + ${CONFIG_SYSTEM_VNCVIEWER_PROGNAME} + SRCS + vncviewer_main.c + rfb_protocol.c + lcd_render.c + STACKSIZE + ${CONFIG_SYSTEM_VNCVIEWER_STACKSIZE} + PRIORITY + ${CONFIG_SYSTEM_VNCVIEWER_PRIORITY}) +endif() diff --git a/system/vncviewer/Kconfig b/system/vncviewer/Kconfig new file mode 100644 index 000000000..49af6c94a --- /dev/null +++ b/system/vncviewer/Kconfig @@ -0,0 +1,32 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config SYSTEM_VNCVIEWER + tristate "VNC Viewer" + default n + depends on NET_TCP && LCD + ---help--- + Enable the VNC Viewer example application. + Connects to a VNC server and displays the remote + framebuffer on a local LCD. + +if SYSTEM_VNCVIEWER + +config SYSTEM_VNCVIEWER_PROGNAME + string "Program name" + default "vncviewer" + ---help--- + This is the name of the program that will be used when the + NSH ELF program is installed. + +config SYSTEM_VNCVIEWER_PRIORITY + int "VNC Viewer task priority" + default 100 + +config SYSTEM_VNCVIEWER_STACKSIZE + int "VNC Viewer stack size" + default 4096 + +endif diff --git a/system/vncviewer/Make.defs b/system/vncviewer/Make.defs new file mode 100644 index 000000000..eca552f64 --- /dev/null +++ b/system/vncviewer/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/system/vncviewer/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_SYSTEM_VNCVIEWER),) +CONFIGURED_APPS += $(APPDIR)/system/vncviewer +endif diff --git a/system/vncviewer/Makefile b/system/vncviewer/Makefile new file mode 100644 index 000000000..90fa66590 --- /dev/null +++ b/system/vncviewer/Makefile @@ -0,0 +1,37 @@ +############################################################################ +# apps/system/vncviewer/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# VNC Viewer built-in application info + +PROGNAME = $(CONFIG_SYSTEM_VNCVIEWER_PROGNAME) +PRIORITY = $(CONFIG_SYSTEM_VNCVIEWER_PRIORITY) +STACKSIZE = $(CONFIG_SYSTEM_VNCVIEWER_STACKSIZE) +MODULE = $(CONFIG_SYSTEM_VNCVIEWER) + +# VNC Viewer sources + +MAINSRC = vncviewer_main.c +CSRCS = rfb_protocol.c lcd_render.c + +include $(APPDIR)/Application.mk diff --git a/system/vncviewer/lcd_render.c b/system/vncviewer/lcd_render.c new file mode 100644 index 000000000..9e940474e --- /dev/null +++ b/system/vncviewer/lcd_render.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * apps/system/vncviewer/lcd_render.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "lcd_render.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lcd_init + ****************************************************************************/ + +int lcd_init(struct lcd_ctx_s *ctx, int devno) +{ + char devpath[16]; + int ret; + + snprintf(devpath, sizeof(devpath), "/dev/lcd%d", devno); + + ctx->fd = open(devpath, O_RDWR); + if (ctx->fd < 0) + { + printf("vncviewer: failed to open %s: %d\n", devpath, errno); + return -errno; + } + + /* Query LCD resolution */ + + struct fb_videoinfo_s vinfo; + ret = ioctl(ctx->fd, LCDDEVIO_GETVIDEOINFO, + (unsigned long)(uintptr_t)&vinfo); + if (ret < 0) + { + printf("vncviewer: GETVIDEOINFO failed: %d\n", errno); + close(ctx->fd); + ctx->fd = -1; + return -errno; + } + else + { + ctx->xres = vinfo.xres; + ctx->yres = vinfo.yres; + ctx->fmt = vinfo.fmt; + } + + printf("vncviewer: LCD %s opened (%ux%u)\n", + devpath, ctx->xres, ctx->yres); + + /* Set power on */ + + ret = ioctl(ctx->fd, LCDDEVIO_SETPOWER, 1); + if (ret < 0) + { + printf("vncviewer: WARNING: SETPOWER failed: %d\n", errno); + } + + return OK; +} + +/**************************************************************************** + * Name: lcd_put_row + ****************************************************************************/ + +int lcd_put_row(struct lcd_ctx_s *ctx, uint16_t x, uint16_t y, + uint16_t w, const uint16_t *pixels) +{ + struct lcddev_area_s area; + int ret; + + /* Clip to LCD bounds */ + + if (x >= ctx->xres || y >= ctx->yres) + { + return OK; + } + + if (x + w > ctx->xres) + { + w = ctx->xres - x; + } + + area.row_start = y; + area.row_end = y; + area.col_start = x; + area.col_end = x + w - 1; + area.data = (uint8_t *)pixels; + + ret = ioctl(ctx->fd, LCDDEVIO_PUTAREA, (unsigned long)(uintptr_t)&area); + if (ret < 0) + { + return -errno; + } + + return OK; +} + +/**************************************************************************** + * Name: lcd_fill + ****************************************************************************/ + +int lcd_fill(struct lcd_ctx_s *ctx, uint16_t color) +{ + uint16_t y; + uint16_t i; + uint16_t w = ctx->xres; + FAR uint16_t *rowbuf; + + rowbuf = (FAR uint16_t *)malloc(w * sizeof(uint16_t)); + if (rowbuf == NULL) + { + return -ENOMEM; + } + + for (i = 0; i < w; i++) + { + rowbuf[i] = color; + } + + for (y = 0; y < ctx->yres; y++) + { + lcd_put_row(ctx, 0, y, w, rowbuf); + } + + free(rowbuf); + + return OK; +} + +/**************************************************************************** + * Name: lcd_uninit + ****************************************************************************/ + +void lcd_uninit(struct lcd_ctx_s *ctx) +{ + if (ctx->fd >= 0) + { + close(ctx->fd); + ctx->fd = -1; + } +} diff --git a/system/vncviewer/lcd_render.h b/system/vncviewer/lcd_render.h new file mode 100644 index 000000000..5940b8f87 --- /dev/null +++ b/system/vncviewer/lcd_render.h @@ -0,0 +1,106 @@ +/**************************************************************************** + * apps/system/vncviewer/lcd_render.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_SYSTEM_VNCVIEWER_LCD_RENDER_H +#define __APPS_SYSTEM_VNCVIEWER_LCD_RENDER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct lcd_ctx_s +{ + int fd; /* File descriptor for /dev/lcdN */ + uint16_t xres; /* LCD horizontal resolution */ + uint16_t yres; /* LCD vertical resolution */ + uint8_t fmt; /* Pixel format (FB_FMT_*) */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: lcd_init + * + * Description: + * Open and initialize the LCD device. + * + * Input Parameters: + * ctx - LCD context to initialize + * devno - LCD device number (0 for /dev/lcd0) + * + * Returned Value: + * OK on success, negative errno on failure. + * + ****************************************************************************/ + +int lcd_init(struct lcd_ctx_s *ctx, int devno); + +/**************************************************************************** + * Name: lcd_put_row + * + * Description: + * Write a single row of pixels to the LCD. + * + * Input Parameters: + * ctx - LCD context + * x - Starting X coordinate + * y - Y coordinate (row) + * w - Width in pixels + * pixels - Pixel data matching LCD native format + * + * Returned Value: + * OK on success, negative errno on failure. + * + ****************************************************************************/ + +int lcd_put_row(struct lcd_ctx_s *ctx, uint16_t x, uint16_t y, + uint16_t w, const uint16_t *pixels); + +/**************************************************************************** + * Name: lcd_fill + * + * Description: + * Fill the entire LCD with a solid color. + * + ****************************************************************************/ + +int lcd_fill(struct lcd_ctx_s *ctx, uint16_t color); + +/**************************************************************************** + * Name: lcd_uninit + * + * Description: + * Close the LCD device. + * + ****************************************************************************/ + +void lcd_uninit(struct lcd_ctx_s *ctx); + +#endif /* __APPS_SYSTEM_VNCVIEWER_LCD_RENDER_H */ diff --git a/system/vncviewer/rfb_protocol.c b/system/vncviewer/rfb_protocol.c new file mode 100644 index 000000000..ef324af83 --- /dev/null +++ b/system/vncviewer/rfb_protocol.c @@ -0,0 +1,1051 @@ +/**************************************************************************** + * apps/system/vncviewer/rfb_protocol.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rfb_protocol.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data - DES tables for VNC authentication + ****************************************************************************/ + +/* Initial permutation */ + +static const uint8_t g_ip[64] = +{ + 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 +}; + +/* Final permutation (IP inverse) */ + +static const uint8_t g_fp[64] = +{ + 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 +}; + +/* Expansion permutation */ + +static const uint8_t g_expand[48] = +{ + 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 +}; + +/* Permuted choice 1 */ + +static const uint8_t g_pc1[56] = +{ + 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 +}; + +/* Permuted choice 2 */ + +static const uint8_t g_pc2[48] = +{ + 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 +}; + +/* P-box permutation */ + +static const uint8_t g_pbox[32] = +{ + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, + 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, + 19, 13, 30, 6, 22, 11, 4, 25 +}; + +/* S-boxes */ + +static const uint8_t g_sbox[8][64] = +{ + { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 + }, + { + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 + }, + { + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 + }, + { + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 + }, + { + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 + }, + { + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 + }, + { + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 + }, + { + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 + } +}; + +/* Key schedule left shifts */ + +static const uint8_t g_shifts[] = +{ + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: des_getbit / des_setbit + * + * Description: + * Get/set a single bit in a byte array (1-indexed, MSB first). + * + ****************************************************************************/ + +static int des_getbit(const uint8_t *data, int bitnum) +{ + return (data[(bitnum - 1) / 8] >> (7 - ((bitnum - 1) % 8))) & 1; +} + +static void des_setbit(uint8_t *data, int bitnum, int val) +{ + int byte_idx = (bitnum - 1) / 8; + int bit_idx = 7 - ((bitnum - 1) % 8); + + if (val) + { + data[byte_idx] |= (uint8_t)(1 << bit_idx); + } + else + { + data[byte_idx] &= (uint8_t)~(1 << bit_idx); + } +} + +/**************************************************************************** + * Name: des_permute + * + * Description: + * Apply a permutation table to a bit array. + * + ****************************************************************************/ + +static void des_permute(const uint8_t *in, uint8_t *out, + const uint8_t *table, int n) +{ + int i; + + memset(out, 0, (n + 7) / 8); + for (i = 0; i < n; i++) + { + des_setbit(out, i + 1, des_getbit(in, table[i])); + } +} + +/**************************************************************************** + * Name: des_encrypt_block + * + * Description: + * DES ECB encrypt a single 8-byte block in place. + * Straightforward implementation using standard tables. + * + ****************************************************************************/ + +static void des_encrypt_block(uint8_t *block, const uint8_t *key) +{ + uint8_t state[8]; + uint8_t cd[7]; + uint8_t l[4]; + uint8_t r[4]; + uint8_t er[6]; + uint8_t subkey[6]; + uint8_t sout[4]; + uint8_t f[4]; + uint8_t newl[4]; + uint8_t combined[8]; + uint8_t result[8]; + uint32_t c; + uint32_t d; + int round; + int i; + int s; + + /* Initial permutation */ + + des_permute(block, state, g_ip, 64); + memcpy(l, state, 4); + memcpy(r, state + 4, 4); + + /* Key schedule: apply PC1 to key */ + + des_permute(key, cd, g_pc1, 56); + + /* Extract C (bits 1-28) and D (bits 29-56) as 28-bit values */ + + for (round = 0; round < 16; round++) + { + int shift = g_shifts[round]; + + c = ((uint32_t)cd[0] << 20) | ((uint32_t)cd[1] << 12) | + ((uint32_t)cd[2] << 4) | ((uint32_t)cd[3] >> 4); + d = (((uint32_t)cd[3] & 0x0f) << 24) | ((uint32_t)cd[4] << 16) | + ((uint32_t)cd[5] << 8) | (uint32_t)cd[6]; + + /* Left rotate C and D by shift positions */ + + c = ((c << shift) | (c >> (28 - shift))) & 0x0fffffff; + d = ((d << shift) | (d >> (28 - shift))) & 0x0fffffff; + + /* Pack back into cd[] */ + + cd[0] = (uint8_t)(c >> 20); + cd[1] = (uint8_t)(c >> 12); + cd[2] = (uint8_t)(c >> 4); + cd[3] = (uint8_t)((c << 4) | (d >> 24)); + cd[4] = (uint8_t)(d >> 16); + cd[5] = (uint8_t)(d >> 8); + cd[6] = (uint8_t)d; + + /* Apply PC2 to get 48-bit subkey */ + + des_permute(cd, subkey, g_pc2, 48); + + /* Expand R from 32 to 48 bits */ + + des_permute(r, er, g_expand, 48); + + /* XOR with subkey */ + + for (i = 0; i < 6; i++) + { + er[i] ^= subkey[i]; + } + + /* S-box substitution: 48 bits -> 32 bits */ + + memset(sout, 0, 4); + for (s = 0; s < 8; s++) + { + int off = s * 6; + int b0 = des_getbit(er, off + 1); + int b1 = des_getbit(er, off + 2); + int b2 = des_getbit(er, off + 3); + int b3 = des_getbit(er, off + 4); + int b4 = des_getbit(er, off + 5); + int b5 = des_getbit(er, off + 6); + int row = (b0 << 1) | b5; + int col = (b1 << 3) | (b2 << 2) | (b3 << 1) | b4; + int val = g_sbox[s][row * 16 + col]; + + sout[s / 2] |= (uint8_t)(val << (((s & 1) == 0) ? 4 : 0)); + } + + /* P-box permutation */ + + des_permute(sout, f, g_pbox, 32); + + /* newR = L XOR f(R, K); L = old R */ + + for (i = 0; i < 4; i++) + { + newl[i] = l[i] ^ f[i]; + } + + memcpy(l, r, 4); + memcpy(r, newl, 4); + } + + /* Final: combine R16 | L16 (note the swap) and apply FP */ + + memcpy(combined, r, 4); + memcpy(combined + 4, l, 4); + des_permute(combined, result, g_fp, 64); + memcpy(block, result, 8); +} + +/**************************************************************************** + * Name: vnc_encrypt_challenge + * + * Description: + * Encrypt 16-byte VNC challenge using password as DES key. + * VNC reverses bits in each byte of the password. + * + ****************************************************************************/ + +static void vnc_encrypt_challenge(uint8_t *challenge, + const char *password) +{ + uint8_t key[8]; + int i; + + memset(key, 0, 8); + for (i = 0; i < 8 && password[i] != '\0'; i++) + { + uint8_t c = (uint8_t)password[i]; + + /* Reverse bits in byte (VNC quirk) */ + + key[i] = (uint8_t)(((c & 0x01) << 7) | ((c & 0x02) << 5) | + ((c & 0x04) << 3) | ((c & 0x08) << 1) | + ((c & 0x10) >> 1) | ((c & 0x20) >> 3) | + ((c & 0x40) >> 5) | ((c & 0x80) >> 7)); + } + + /* Encrypt two 8-byte blocks */ + + des_encrypt_block(challenge, key); + des_encrypt_block(challenge + 8, key); +} + +/**************************************************************************** + * Name: rfb_recv_exact + * + * Description: + * Receive exactly 'len' bytes from socket. + * + ****************************************************************************/ + +static int rfb_recv_exact(int sockfd, void *buf, size_t len) +{ + uint8_t *p = (uint8_t *)buf; + ssize_t n; + + while (len > 0) + { + n = recv(sockfd, p, len, 0); + if (n <= 0) + { + if (n == 0) + { + return -ECONNRESET; + } + + if (errno == EINTR) + { + continue; + } + + return -errno; + } + + p += n; + len -= n; + } + + return OK; +} + +/**************************************************************************** + * Name: rfb_send_exact + * + * Description: + * Send exactly 'len' bytes to socket. + * + ****************************************************************************/ + +static int rfb_send_exact(int sockfd, const void *buf, size_t len) +{ + const uint8_t *p = (const uint8_t *)buf; + ssize_t n; + + while (len > 0) + { + n = send(sockfd, p, len, 0); + if (n <= 0) + { + if (errno == EINTR) + { + continue; + } + + return -errno; + } + + p += n; + len -= n; + } + + return OK; +} + +/**************************************************************************** + * Name: rfb_negotiate_version + * + * Description: + * Exchange RFB protocol version strings. + * + ****************************************************************************/ + +static int rfb_negotiate_version(int sockfd) +{ + char buf[RFB_VERSION_LEN + 1]; + int ret; + + /* Receive server version */ + + ret = rfb_recv_exact(sockfd, buf, RFB_VERSION_LEN); + if (ret < 0) + { + printf("vncviewer: failed to receive server version\n"); + return ret; + } + + buf[RFB_VERSION_LEN] = '\0'; + printf("vncviewer: server version: %s", buf); + + /* Send our version (3.8) */ + + ret = rfb_send_exact(sockfd, RFB_VERSION_STRING, RFB_VERSION_LEN); + if (ret < 0) + { + printf("vncviewer: failed to send client version\n"); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: rfb_negotiate_security + * + * Description: + * Negotiate security type. Supports None and VNC Authentication. + * + ****************************************************************************/ + +static int rfb_negotiate_security(int sockfd, const char *password) +{ + uint8_t num_types; + uint8_t types[16]; + uint8_t chosen; + uint32_t result; + int ret; + int i; + + /* Receive number of security types */ + + ret = rfb_recv_exact(sockfd, &num_types, 1); + if (ret < 0) + { + return ret; + } + + if (num_types == 0) + { + /* Connection failed - read reason string */ + + uint32_t reason_len; + rfb_recv_exact(sockfd, &reason_len, 4); + reason_len = ntohl(reason_len); + printf("vncviewer: connection refused by server\n"); + return -ECONNREFUSED; + } + + /* Receive security type list */ + + ret = rfb_recv_exact(sockfd, types, num_types); + if (ret < 0) + { + return ret; + } + + /* Choose security type: prefer None, fallback to VNC Auth */ + + chosen = RFB_SEC_INVALID; + for (i = 0; i < num_types; i++) + { + if (types[i] == RFB_SEC_NONE) + { + chosen = RFB_SEC_NONE; + break; + } + + if (types[i] == RFB_SEC_VNC_AUTH) + { + chosen = RFB_SEC_VNC_AUTH; + } + } + + if (chosen == RFB_SEC_INVALID) + { + printf("vncviewer: no supported security type\n"); + return -ENOTSUP; + } + + /* Send chosen type */ + + ret = rfb_send_exact(sockfd, &chosen, 1); + if (ret < 0) + { + return ret; + } + + printf("vncviewer: security type: %s\n", + chosen == RFB_SEC_NONE ? "None" : "VNC Auth"); + + if (chosen == RFB_SEC_VNC_AUTH) + { + /* VNC Authentication: receive 16-byte challenge */ + + uint8_t challenge[16]; + + ret = rfb_recv_exact(sockfd, challenge, 16); + if (ret < 0) + { + return ret; + } + + /* Encrypt challenge with password using DES */ + + if (password == NULL || password[0] == '\0') + { + printf("vncviewer: WARNING: VNC Auth required but no password\n"); + } + else + { + vnc_encrypt_challenge(challenge, password); + } + + ret = rfb_send_exact(sockfd, challenge, 16); + if (ret < 0) + { + return ret; + } + } + + /* Receive SecurityResult (for both None and VNC Auth in RFB 3.8) */ + + ret = rfb_recv_exact(sockfd, &result, 4); + if (ret < 0) + { + return ret; + } + + result = ntohl(result); + if (result != 0) + { + printf("vncviewer: authentication failed (result=%u)\n", + (unsigned)result); + return -EACCES; + } + + printf("vncviewer: authentication OK\n"); + return OK; +} + +/**************************************************************************** + * Name: rfb_client_init + * + * Description: + * Send ClientInit and receive ServerInit. + * + ****************************************************************************/ + +static int rfb_client_init(int sockfd, struct rfb_conn_s *conn) +{ + uint8_t shared = 1; /* shared session */ + uint8_t buf[24]; + uint32_t name_len; + int ret; + + /* Send ClientInit */ + + ret = rfb_send_exact(sockfd, &shared, 1); + if (ret < 0) + { + return ret; + } + + /* Receive ServerInit: 2+2+16+4 = 24 bytes header + name */ + + ret = rfb_recv_exact(sockfd, buf, 24); + if (ret < 0) + { + return ret; + } + + conn->fb_width = ntohs(*(uint16_t *)&buf[0]); + conn->fb_height = ntohs(*(uint16_t *)&buf[2]); + + /* bytes 4..19 = server pixel format (we'll override it) */ + + name_len = ntohl(*(uint32_t *)&buf[20]); + if (name_len > sizeof(conn->name) - 1) + { + name_len = sizeof(conn->name) - 1; + } + + if (name_len > 0) + { + ret = rfb_recv_exact(sockfd, conn->name, name_len); + if (ret < 0) + { + return ret; + } + } + + conn->name[name_len] = '\0'; + + printf("vncviewer: server desktop: \"%s\" %ux%u\n", + conn->name, conn->fb_width, conn->fb_height); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rfb_connect + ****************************************************************************/ + +int rfb_connect(const char *host, uint16_t port) +{ + struct sockaddr_in addr; + int sockfd; + int ret; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + { + printf("vncviewer: socket() failed: %d\n", errno); + return -errno; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + + ret = inet_pton(AF_INET, host, &addr.sin_addr); + if (ret <= 0) + { + printf("vncviewer: invalid address: %s\n", host); + close(sockfd); + return -EINVAL; + } + + printf("vncviewer: connecting to %s:%u...\n", host, port); + + ret = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) + { + printf("vncviewer: connect() failed: %d\n", errno); + close(sockfd); + return -errno; + } + + printf("vncviewer: connected\n"); + return sockfd; +} + +/**************************************************************************** + * Name: rfb_handshake + ****************************************************************************/ + +int rfb_handshake(struct rfb_conn_s *conn, const char *password) +{ + int ret; + + ret = rfb_negotiate_version(conn->sockfd); + if (ret < 0) + { + return ret; + } + + ret = rfb_negotiate_security(conn->sockfd, password); + if (ret < 0) + { + return ret; + } + + ret = rfb_client_init(conn->sockfd, conn); + if (ret < 0) + { + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: rfb_set_pixel_format + ****************************************************************************/ + +int rfb_set_pixel_format(struct rfb_conn_s *conn, uint8_t fmt) +{ + uint8_t msg[20]; + uint8_t bits; + uint8_t depth; + uint16_t rmax; + uint16_t gmax; + uint16_t bmax; + uint8_t rshift; + uint8_t gshift; + uint8_t bshift; + + switch (fmt) + { + case 11: /* FB_FMT_RGB16_565 */ + bits = 16; depth = 16; + rmax = 31; gmax = 63; bmax = 31; + rshift = 11; gshift = 5; bshift = 0; + conn->bpp = 2; + break; + + case 10: /* FB_FMT_RGB16_555 */ + bits = 16; depth = 15; + rmax = 31; gmax = 31; bmax = 31; + rshift = 10; gshift = 5; bshift = 0; + conn->bpp = 2; + break; + + case 12: /* FB_FMT_RGB24 */ + bits = 32; depth = 24; + rmax = 255; gmax = 255; bmax = 255; + rshift = 16; gshift = 8; bshift = 0; + conn->bpp = 4; + break; + + case 13: /* FB_FMT_RGB32 */ + bits = 32; depth = 24; + rmax = 255; gmax = 255; bmax = 255; + rshift = 16; gshift = 8; bshift = 0; + conn->bpp = 4; + break; + + default: + printf("vncviewer: unsupported LCD format %d\n", fmt); + return -ENOTSUP; + } + + memset(msg, 0, sizeof(msg)); + + /* Message type + 3 bytes padding */ + + msg[0] = RFB_SET_PIXEL_FORMAT; + + /* Pixel format at offset 4 */ + + msg[4] = bits; /* bits-per-pixel */ + msg[5] = depth; /* depth */ + msg[6] = 0; /* big-endian = false */ + msg[7] = 1; /* true-color = true */ + + msg[8] = (rmax >> 8) & 0xff; + msg[9] = rmax & 0xff; + msg[10] = (gmax >> 8) & 0xff; + msg[11] = gmax & 0xff; + msg[12] = (bmax >> 8) & 0xff; + msg[13] = bmax & 0xff; + + msg[14] = rshift; + msg[15] = gshift; + msg[16] = bshift; + + return rfb_send_exact(conn->sockfd, msg, sizeof(msg)); +} + +/**************************************************************************** + * Name: rfb_set_encodings + ****************************************************************************/ + +int rfb_set_encodings(struct rfb_conn_s *conn) +{ + uint8_t msg[8]; + + msg[0] = RFB_SET_ENCODINGS; + msg[1] = 0; /* padding */ + + /* number-of-encodings = 1 */ + + msg[2] = 0; + msg[3] = 1; + + /* encoding: Raw = 0 */ + + msg[4] = 0; + msg[5] = 0; + msg[6] = 0; + msg[7] = 0; + + return rfb_send_exact(conn->sockfd, msg, sizeof(msg)); +} + +/**************************************************************************** + * Name: rfb_request_update + ****************************************************************************/ + +int rfb_request_update(struct rfb_conn_s *conn, bool incremental, + uint16_t x, uint16_t y, uint16_t w, uint16_t h) +{ + uint8_t msg[10]; + + msg[0] = RFB_FB_UPDATE_REQUEST; + msg[1] = incremental ? 1 : 0; + *(uint16_t *)&msg[2] = htons(x); + *(uint16_t *)&msg[4] = htons(y); + *(uint16_t *)&msg[6] = htons(w); + *(uint16_t *)&msg[8] = htons(h); + + return rfb_send_exact(conn->sockfd, msg, sizeof(msg)); +} + +/**************************************************************************** + * Name: rfb_recv_update + ****************************************************************************/ + +int rfb_recv_update(struct rfb_conn_s *conn, rfb_rect_cb_t rect_cb, + void *arg) +{ + uint8_t msg_type; + int ret; + + /* Read message type */ + + ret = rfb_recv_exact(conn->sockfd, &msg_type, 1); + if (ret < 0) + { + return ret; + } + + switch (msg_type) + { + case RFB_FB_UPDATE: + { + uint8_t hdr[3]; + uint16_t num_rects; + uint16_t i; + + /* Read padding(1) + number-of-rectangles(2) */ + + ret = rfb_recv_exact(conn->sockfd, hdr, 3); + if (ret < 0) + { + return ret; + } + + num_rects = ntohs(*(uint16_t *)&hdr[1]); + + for (i = 0; i < num_rects; i++) + { + struct rfb_rect_hdr_s rect; + uint8_t rect_buf[12]; + uint32_t row_bytes; + uint32_t row; + + /* Read rectangle header: x(2)+y(2)+w(2)+h(2)+encoding(4) */ + + ret = rfb_recv_exact(conn->sockfd, rect_buf, 12); + if (ret < 0) + { + return ret; + } + + rect.x = ntohs(*(uint16_t *)&rect_buf[0]); + rect.y = ntohs(*(uint16_t *)&rect_buf[2]); + rect.w = ntohs(*(uint16_t *)&rect_buf[4]); + rect.h = ntohs(*(uint16_t *)&rect_buf[6]); + rect.encoding = (int32_t)ntohl(*(uint32_t *)&rect_buf[8]); + + if (rect.encoding != RFB_ENCODING_RAW) + { + printf("vncviewer: unsupported encoding %d\n", + (int)rect.encoding); + return -ENOTSUP; + } + + /* Read pixel data row by row to limit memory usage */ + + row_bytes = rect.w * conn->bpp; + + FAR uint8_t *rowbuf = malloc(row_bytes); + if (rowbuf == NULL) + { + return -ENOMEM; + } + + for (row = 0; row < rect.h; row++) + { + struct rfb_rect_hdr_s row_rect; + + ret = rfb_recv_exact(conn->sockfd, rowbuf, row_bytes); + if (ret < 0) + { + free(rowbuf); + return ret; + } + + /* Callback with single-row rectangle */ + + row_rect.x = rect.x; + row_rect.y = rect.y + row; + row_rect.w = rect.w; + row_rect.h = 1; + row_rect.encoding = RFB_ENCODING_RAW; + + if (rect_cb) + { + rect_cb(&row_rect, rowbuf, arg); + } + } + + free(rowbuf); + } + } + break; + + case RFB_SET_COLORMAP: + { + /* Skip: padding(1) + first-color(2) + num-colors(2) */ + + uint8_t cm_hdr[5]; + uint16_t num_colors; + + ret = rfb_recv_exact(conn->sockfd, cm_hdr, 5); + if (ret < 0) + { + return ret; + } + + num_colors = ntohs(*(uint16_t *)&cm_hdr[3]); + + /* Skip color entries: num_colors * 6 bytes (R+G+B each 2B) */ + + uint32_t skip = num_colors * 6; + uint8_t tmp[256]; + + while (skip > 0) + { + uint32_t chunk = skip > sizeof(tmp) ? sizeof(tmp) : skip; + ret = rfb_recv_exact(conn->sockfd, tmp, chunk); + if (ret < 0) + { + return ret; + } + + skip -= chunk; + } + } + break; + + case RFB_BELL: + + /* No payload */ + + break; + + case RFB_SERVER_CUT_TEXT: + { + uint8_t ct_hdr[7]; + uint32_t text_len; + + ret = rfb_recv_exact(conn->sockfd, ct_hdr, 7); + if (ret < 0) + { + return ret; + } + + text_len = ntohl(*(uint32_t *)&ct_hdr[3]); + + /* Skip text content */ + + uint8_t tmp[256]; + + while (text_len > 0) + { + uint32_t chunk = text_len > sizeof(tmp) + ? sizeof(tmp) : text_len; + ret = rfb_recv_exact(conn->sockfd, tmp, chunk); + if (ret < 0) + { + return ret; + } + + text_len -= chunk; + } + } + break; + + default: + printf("vncviewer: unknown message type %u\n", msg_type); + return -EPROTO; + } + + return OK; +} diff --git a/system/vncviewer/rfb_protocol.h b/system/vncviewer/rfb_protocol.h new file mode 100644 index 000000000..b5b4c1e78 --- /dev/null +++ b/system/vncviewer/rfb_protocol.h @@ -0,0 +1,220 @@ +/**************************************************************************** + * apps/system/vncviewer/rfb_protocol.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_SYSTEM_VNCVIEWER_RFB_PROTOCOL_H +#define __APPS_SYSTEM_VNCVIEWER_RFB_PROTOCOL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* RFB Protocol Version */ + +#define RFB_VERSION_STRING "RFB 003.008\n" +#define RFB_VERSION_LEN 12 + +/* Security Types */ + +#define RFB_SEC_INVALID 0 +#define RFB_SEC_NONE 1 +#define RFB_SEC_VNC_AUTH 2 + +/* Client-to-Server Message Types */ + +#define RFB_SET_PIXEL_FORMAT 0 +#define RFB_SET_ENCODINGS 2 +#define RFB_FB_UPDATE_REQUEST 3 +#define RFB_KEY_EVENT 4 +#define RFB_POINTER_EVENT 5 +#define RFB_CLIENT_CUT_TEXT 6 + +/* Server-to-Client Message Types */ + +#define RFB_FB_UPDATE 0 +#define RFB_SET_COLORMAP 1 +#define RFB_BELL 2 +#define RFB_SERVER_CUT_TEXT 3 + +/* Encoding Types */ + +#define RFB_ENCODING_RAW 0 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Pixel format (negotiated with server based on LCD) */ + +struct rfb_pixel_format_s +{ + uint8_t bits_per_pixel; /* 16 */ + uint8_t depth; /* 16 */ + uint8_t big_endian; /* 0 = little-endian */ + uint8_t true_color; /* 1 */ + uint16_t red_max; /* 31 (5 bits) */ + uint16_t green_max; /* 63 (6 bits) */ + uint16_t blue_max; /* 31 (5 bits) */ + uint8_t red_shift; /* 11 */ + uint8_t green_shift; /* 5 */ + uint8_t blue_shift; /* 0 */ + uint8_t padding[3]; +}; + +/* Server init message (parsed) */ + +struct rfb_server_init_s +{ + uint16_t fb_width; + uint16_t fb_height; + struct rfb_pixel_format_s pixel_format; + char name[256]; +}; + +/* Framebuffer update rectangle header */ + +struct rfb_rect_hdr_s +{ + uint16_t x; + uint16_t y; + uint16_t w; + uint16_t h; + int32_t encoding; +}; + +/* RFB connection context */ + +struct rfb_conn_s +{ + int sockfd; + uint16_t fb_width; + uint16_t fb_height; + uint16_t view_width; + uint16_t view_height; + uint8_t bpp; /* Bytes per pixel */ + char name[256]; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: rfb_connect + * + * Description: + * Establish TCP connection to VNC server. + * + * Input Parameters: + * host - Server IP address string + * port - Server port number + * + * Returned Value: + * Socket fd on success, negative errno on failure. + * + ****************************************************************************/ + +int rfb_connect(const char *host, uint16_t port); + +/**************************************************************************** + * Name: rfb_handshake + * + * Description: + * Perform RFB protocol handshake: version, security, init. + * + * Input Parameters: + * conn - RFB connection context (sockfd must be set) + * password - VNC password (NULL or empty for no auth) + * + * Returned Value: + * OK on success, negative errno on failure. + * + ****************************************************************************/ + +int rfb_handshake(struct rfb_conn_s *conn, const char *password); + +/**************************************************************************** + * Name: rfb_set_pixel_format + * + * Description: + * Send SetPixelFormat message based on LCD pixel format. + * + ****************************************************************************/ + +int rfb_set_pixel_format(struct rfb_conn_s *conn, uint8_t fmt); + +/**************************************************************************** + * Name: rfb_set_encodings + * + * Description: + * Send SetEncodings message (Raw only). + * + ****************************************************************************/ + +int rfb_set_encodings(struct rfb_conn_s *conn); + +/**************************************************************************** + * Name: rfb_request_update + * + * Description: + * Send FramebufferUpdateRequest. + * + * Input Parameters: + * conn - RFB connection + * incremental - true for incremental update + * x, y, w, h - Region to request + * + ****************************************************************************/ + +int rfb_request_update(struct rfb_conn_s *conn, bool incremental, + uint16_t x, uint16_t y, uint16_t w, uint16_t h); + +/**************************************************************************** + * Name: rfb_recv_update + * + * Description: + * Receive and process one server message. For FramebufferUpdate, + * calls the provided callback for each rectangle. + * + * Input Parameters: + * conn - RFB connection + * rect_cb - Callback for each received rectangle + * arg - User argument passed to callback + * + * Returned Value: + * OK on success, negative errno on failure. + * + ****************************************************************************/ + +typedef void (*rfb_rect_cb_t)(const struct rfb_rect_hdr_s *rect, + const uint8_t *pixels, void *arg); + +int rfb_recv_update(struct rfb_conn_s *conn, rfb_rect_cb_t rect_cb, + void *arg); + +#endif /* __APPS_SYSTEM_VNCVIEWER_RFB_PROTOCOL_H */ diff --git a/system/vncviewer/vncviewer_main.c b/system/vncviewer/vncviewer_main.c new file mode 100644 index 000000000..654740ccb --- /dev/null +++ b/system/vncviewer/vncviewer_main.c @@ -0,0 +1,306 @@ +/**************************************************************************** + * apps/system/vncviewer/vncviewer_main.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "rfb_protocol.h" +#include "lcd_render.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define VNCVIEWER_DEFAULT_PORT 5900 +#define VNCVIEWER_DEFAULT_LCD 0 + +#define COLOR_BLACK 0x0000 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct lcd_ctx_s g_lcd; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rect_callback + * + * Description: + * Called for each row of pixel data received from VNC server. + * Writes directly to LCD, clipping to screen bounds. + * + ****************************************************************************/ + +static void rect_callback(const struct rfb_rect_hdr_s *rect, + const uint8_t *pixels, void *arg) +{ + /* rect->h is always 1 (row-by-row from rfb_recv_update) */ + + if (rect->y < g_lcd.yres && rect->x < g_lcd.xres) + { + uint16_t w = rect->w; + + if (rect->x + w > g_lcd.xres) + { + w = g_lcd.xres - rect->x; + } + + lcd_put_row(&g_lcd, rect->x, rect->y, w, (const uint16_t *)pixels); + } +} + +/**************************************************************************** + * Name: show_usage + ****************************************************************************/ + +static void show_usage(const char *progname) +{ + printf("Usage: %s [options] [port]\n", progname); + printf("Options:\n"); + printf(" -p VNC password\n"); + printf(" -d LCD device number (default: %d)\n", + VNCVIEWER_DEFAULT_LCD); + printf(" -h Show this help\n"); + printf("Default port: %d\n", VNCVIEWER_DEFAULT_PORT); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vncviewer_main + * + * Description: + * VNC Viewer entry point. Connects to a VNC server and displays + * the remote framebuffer on the local LCD. + * + ****************************************************************************/ + +int main(int argc, char *argv[]) +{ + const char *host = NULL; + const char *password = ""; + uint16_t port = VNCVIEWER_DEFAULT_PORT; + int lcd_devno = VNCVIEWER_DEFAULT_LCD; + struct rfb_conn_s conn; + int opt; + int ret; + + /* Parse command line arguments */ + + while ((opt = getopt(argc, argv, "p:d:h")) != -1) + { + switch (opt) + { + case 'p': + password = optarg; + break; + + case 'd': + lcd_devno = atoi(optarg); + break; + + case 'h': + show_usage(argv[0]); + return EXIT_SUCCESS; + + default: + show_usage(argv[0]); + return EXIT_FAILURE; + } + } + + if (optind < argc) + { + host = argv[optind++]; + } + + if (optind < argc) + { + port = atoi(argv[optind]); + } + + if (host == NULL) + { + printf("vncviewer: host is required\n"); + show_usage(argv[0]); + return EXIT_FAILURE; + } + + /* Initialize LCD */ + + printf("vncviewer: initializing LCD...\n"); + + ret = lcd_init(&g_lcd, lcd_devno); + if (ret < 0) + { + printf("vncviewer: LCD init failed: %d\n", ret); + return EXIT_FAILURE; + } + + /* Fill screen black */ + + lcd_fill(&g_lcd, COLOR_BLACK); + + /* Connect to VNC server */ + + memset(&conn, 0, sizeof(conn)); + + /* Connection loop with retry */ + + for (; ; ) + { + int rcvbuf; + + conn.sockfd = rfb_connect(host, port); + if (conn.sockfd < 0) + { + printf("vncviewer: connection failed: %d, retrying...\n", + conn.sockfd); + sleep(2); + continue; + } + + /* Increase TCP receive buffer to handle bursts */ + + rcvbuf = 32768; + setsockopt(conn.sockfd, SOL_SOCKET, SO_RCVBUF, + &rcvbuf, sizeof(rcvbuf)); + + /* RFB handshake */ + + ret = rfb_handshake(&conn, password); + if (ret < 0) + { + printf("vncviewer: handshake failed: %d, retrying...\n", ret); + close(conn.sockfd); + sleep(2); + continue; + } + + /* Configure pixel format based on LCD */ + + ret = rfb_set_pixel_format(&conn, g_lcd.fmt); + if (ret < 0) + { + printf("vncviewer: set pixel format failed: %d, retrying...\n", + ret); + close(conn.sockfd); + sleep(2); + continue; + } + + /* Set encodings: Raw only */ + + ret = rfb_set_encodings(&conn); + if (ret < 0) + { + printf("vncviewer: set encodings failed: %d, retrying...\n", ret); + close(conn.sockfd); + sleep(2); + continue; + } + + /* Determine view size: min of server desktop and LCD */ + + conn.view_width = conn.fb_width < g_lcd.xres + ? conn.fb_width : g_lcd.xres; + conn.view_height = conn.fb_height < g_lcd.yres + ? conn.fb_height : g_lcd.yres; + + printf("vncviewer: view area: %ux%u (server: %ux%u, lcd: %ux%u)\n", + conn.view_width, conn.view_height, + conn.fb_width, conn.fb_height, + g_lcd.xres, g_lcd.yres); + + /* Request initial full framebuffer update */ + + ret = rfb_request_update(&conn, false, + 0, 0, conn.view_width, conn.view_height); + if (ret < 0) + { + printf("vncviewer: initial update request failed: %d, " + "retrying...\n", ret); + close(conn.sockfd); + sleep(2); + continue; + } + + /* Main loop: receive updates and render to LCD */ + + printf("vncviewer: entering main loop\n"); + + while (true) + { + /* Receive and process server message */ + + ret = rfb_recv_update(&conn, rect_callback, NULL); + if (ret < 0) + { + printf("vncviewer: recv error: %d\n", ret); + break; + } + + /* Request next incremental update */ + + ret = rfb_request_update(&conn, true, + 0, 0, + conn.view_width, conn.view_height); + if (ret < 0) + { + printf("vncviewer: update request failed: %d\n", ret); + break; + } + } + + /* Connection lost - retry */ + + printf("vncviewer: reconnecting in 2 seconds...\n"); + close(conn.sockfd); + sleep(2); + } + + /* Cleanup */ + + printf("vncviewer: disconnecting\n"); + close(conn.sockfd); + lcd_uninit(&g_lcd); + + return EXIT_SUCCESS; +} From 4b705721cae4d029b93ac9cd5df42fa81940b535 Mon Sep 17 00:00:00 2001 From: shichunma Date: Sat, 11 Apr 2026 18:26:39 +0800 Subject: [PATCH 304/568] netutils/dhcpc: parse DHCP NTP server option Request DHCP option 42 and store the returned IPv4 NTP server addresses in struct dhcpc_state for later consumers. Signed-off-by: Jerry Ma --- include/netutils/dhcpc.h | 6 +++++ netutils/dhcpc/dhcpc.c | 52 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/include/netutils/dhcpc.h b/include/netutils/dhcpc.h index 0cf16907b..b17d6f368 100644 --- a/include/netutils/dhcpc.h +++ b/include/netutils/dhcpc.h @@ -55,6 +55,10 @@ # define CONFIG_NETDB_DNSSERVER_NAMESERVERS 1 #endif +#if !defined(CONFIG_NETUTILS_DHCPC_NTP_SERVERS) +# define CONFIG_NETUTILS_DHCPC_NTP_SERVERS 1 +#endif + /**************************************************************************** * Public Types ****************************************************************************/ @@ -66,6 +70,8 @@ struct dhcpc_state struct in_addr netmask; struct in_addr dnsaddr[CONFIG_NETDB_DNSSERVER_NAMESERVERS]; uint8_t num_dnsaddr; /* Number of DNS addresses received */ + struct in_addr ntpaddr[CONFIG_NETUTILS_DHCPC_NTP_SERVERS]; + uint8_t num_ntpaddr; /* Number of NTP addresses received */ struct in_addr default_router; uint32_t lease_time; /* Lease expires in this number of seconds */ uint32_t renewal_time; /* Seconds to transition to RENEW state(T1) */ diff --git a/netutils/dhcpc/dhcpc.c b/netutils/dhcpc/dhcpc.c index e899b6930..a449c96ca 100644 --- a/netutils/dhcpc/dhcpc.c +++ b/netutils/dhcpc/dhcpc.c @@ -91,6 +91,7 @@ #define DHCP_OPTION_ROUTER 3 #define DHCP_OPTION_DNS_SERVER 6 #define DHCP_OPTION_HOST_NAME 12 +#define DHCP_OPTION_NTP_SERVER 42 #define DHCP_OPTION_REQ_IPADDR 50 #define DHCP_OPTION_LEASE_TIME 51 #define DHCP_OPTION_MSG_TYPE 53 @@ -210,10 +211,11 @@ static FAR uint8_t *dhcpc_addclientid(FAR uint8_t *clientid, static FAR uint8_t *dhcpc_addreqoptions(FAR uint8_t *optptr) { *optptr++ = DHCP_OPTION_REQ_LIST; - *optptr++ = 3; + *optptr++ = 4; *optptr++ = DHCP_OPTION_SUBNET_MASK; *optptr++ = DHCP_OPTION_ROUTER; *optptr++ = DHCP_OPTION_DNS_SERVER; + *optptr++ = DHCP_OPTION_NTP_SERVER; return optptr; } @@ -411,6 +413,39 @@ static uint8_t dhcpc_parseoptions(FAR struct dhcpc_state *presult, } break; + case DHCP_OPTION_NTP_SERVER: + + /* Get the NTP server addresses in network order. + * DHCP option 42 can contain multiple IPv4 addresses, + * each 4 bytes long. + */ + + if (optptr + 2 <= end) + { + uint8_t optlen = *(optptr + 1); + uint8_t num_ntp = optlen / 4; + uint8_t i; + + if (num_ntp > CONFIG_NETUTILS_DHCPC_NTP_SERVERS) + { + num_ntp = CONFIG_NETUTILS_DHCPC_NTP_SERVERS; + } + + presult->num_ntpaddr = 0; + for (i = 0; i < num_ntp && (optptr + 2 + i * 4 + 4) <= end; + i++) + { + memcpy(&presult->ntpaddr[i].s_addr, optptr + 2 + i * 4, + 4); + presult->num_ntpaddr++; + } + } + else + { + nerr("Packet too short (NTP address missing)\n"); + } + break; + case DHCP_OPTION_MSG_TYPE: /* Get message type */ @@ -999,6 +1034,21 @@ int dhcpc_request(FAR void *handle, FAR struct dhcpc_state *presult) } } + /* Print all NTP servers received */ + + if (presult->num_ntpaddr > 0) + { + uint8_t i; + for (i = 0; i < presult->num_ntpaddr; i++) + { + ninfo("Got NTP server %d: %u.%u.%u.%u\n", i, + ip4_addr1(presult->ntpaddr[i].s_addr), + ip4_addr2(presult->ntpaddr[i].s_addr), + ip4_addr3(presult->ntpaddr[i].s_addr), + ip4_addr4(presult->ntpaddr[i].s_addr)); + } + } + ninfo("Got default router %u.%u.%u.%u\n", ip4_addr1(presult->default_router.s_addr), ip4_addr2(presult->default_router.s_addr), From c82957109fc14fe552c8f32a8f93bc7330c41cd3 Mon Sep 17 00:00:00 2001 From: shichunma Date: Sat, 11 Apr 2026 18:41:05 +0800 Subject: [PATCH 305/568] netutils: prefer DHCP-provided NTP servers for ntpc Use the DHCP-learned NTP server list as the default ntpc server source when DHCP option 42 is available. Fall back to CONFIG_NETUTILS_NTPCLIENT_SERVER only when DHCP does not provide any NTP servers, and restart ntpc when the DHCP-provided server list changes. Signed-off-by: Jerry Ma --- include/netutils/netlib.h | 43 ++++ netutils/netlib/CMakeLists.txt | 1 + netutils/netlib/Makefile | 1 + netutils/netlib/netlib_dhcp_ntp.c | 182 ++++++++++++++++ netutils/netlib/netlib_obtainipv4addr.c | 78 +++++++ netutils/ntpclient/ntpclient.c | 263 +++++++++++++++++++++--- 6 files changed, 535 insertions(+), 33 deletions(-) create mode 100644 netutils/netlib/netlib_dhcp_ntp.c diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 2b3146e91..eb3933fe9 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -203,6 +203,11 @@ struct url_s }; #endif +#ifdef CONFIG_NETUTILS_DHCPC +typedef CODE void (*netlib_dhcp_ntp_callback_t) + (FAR const char *ntp_server_list, FAR void *arg); +#endif + /**************************************************************************** * Public Data ****************************************************************************/ @@ -247,6 +252,44 @@ ssize_t netlib_get_devices(FAR struct netlib_device_s *devlist, bool netlib_ipv4addrconv(FAR const char *addrstr, FAR uint8_t *addr); bool netlib_ethaddrconv(FAR const char *hwstr, FAR uint8_t *hw); +#ifdef CONFIG_NETUTILS_DHCPC +/**************************************************************************** + * Name: netlib_set_ntp_servers_from_dhcp + * + * Description: + * Update the currently active DHCP option 42 NTP server list. The list + * contains semicolon-separated hostnames or addresses. Passing NULL or + * an empty string clears the DHCP-provided list. + * + ****************************************************************************/ + +int netlib_set_ntp_servers_from_dhcp(FAR const char *ntp_server_list); + +/**************************************************************************** + * Name: netlib_register_dhcp_ntp_callback + * + * Description: + * Register a callback to receive DHCP option 42 NTP server list updates. + * The current list, if any, is replayed immediately after registration. + * Only one callback may be registered at a time. + * + ****************************************************************************/ + +int netlib_register_dhcp_ntp_callback(netlib_dhcp_ntp_callback_t callback, + FAR void *arg); + +/**************************************************************************** + * Name: netlib_unregister_dhcp_ntp_callback + * + * Description: + * Unregister a previously registered DHCP option 42 NTP update callback. + * + ****************************************************************************/ + +int netlib_unregister_dhcp_ntp_callback(netlib_dhcp_ntp_callback_t callback, + FAR void *arg); +#endif + #ifdef CONFIG_NET_ETHERNET /* Get and set IP/MAC addresses (Ethernet L2 only) */ diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt index 49e8aa81e..2f0f11e0f 100644 --- a/netutils/netlib/CMakeLists.txt +++ b/netutils/netlib/CMakeLists.txt @@ -57,6 +57,7 @@ if(CONFIG_NETUTILS_NETLIB) endif() if(CONFIG_NETUTILS_DHCPC) list(APPEND SRCS netlib_obtainipv4addr.c) + list(APPEND SRCS netlib_dhcp_ntp.c) endif() endif() diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index 4bfc8d9d4..7bba856b7 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -57,6 +57,7 @@ CSRCS += netlib_iptables.c endif ifeq ($(CONFIG_NETUTILS_DHCPC),y) CSRCS += netlib_obtainipv4addr.c +CSRCS += netlib_dhcp_ntp.c endif endif diff --git a/netutils/netlib/netlib_dhcp_ntp.c b/netutils/netlib/netlib_dhcp_ntp.c new file mode 100644 index 000000000..b1d608db0 --- /dev/null +++ b/netutils/netlib/netlib_dhcp_ntp.c @@ -0,0 +1,182 @@ +/**************************************************************************** + * apps/netutils/netlib/netlib_dhcp_ntp.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_NETUTILS_DHCPC + +#include +#include +#include +#include + +#include "netutils/netlib.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static pthread_mutex_t g_dhcp_ntp_lock = PTHREAD_MUTEX_INITIALIZER; +static FAR char *g_dhcp_ntp_servers; +static netlib_dhcp_ntp_callback_t g_dhcp_ntp_callback; +static FAR void *g_dhcp_ntp_callback_arg; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static FAR char *netlib_dhcp_ntp_dup(FAR const char *ntp_server_list) +{ + if (ntp_server_list == NULL || ntp_server_list[0] == '\0') + { + return NULL; + } + + return strdup(ntp_server_list); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int netlib_set_ntp_servers_from_dhcp(FAR const char *ntp_server_list) +{ + FAR char *new_servers; + FAR char *notify_servers = NULL; + FAR char *old_servers; + netlib_dhcp_ntp_callback_t callback; + FAR void *arg; + int ret = OK; + + new_servers = netlib_dhcp_ntp_dup(ntp_server_list); + if (ntp_server_list != NULL && ntp_server_list[0] != '\0' && + new_servers == NULL) + { + return -ENOMEM; + } + + pthread_mutex_lock(&g_dhcp_ntp_lock); + + if ((g_dhcp_ntp_servers == NULL && new_servers == NULL) || + (g_dhcp_ntp_servers != NULL && new_servers != NULL && + strcmp(g_dhcp_ntp_servers, new_servers) == 0)) + { + pthread_mutex_unlock(&g_dhcp_ntp_lock); + free(new_servers); + return OK; + } + + callback = g_dhcp_ntp_callback; + arg = g_dhcp_ntp_callback_arg; + + if (callback != NULL && new_servers != NULL) + { + notify_servers = strdup(new_servers); + if (notify_servers == NULL) + { + ret = -ENOMEM; + goto errout_with_lock; + } + } + + old_servers = g_dhcp_ntp_servers; + g_dhcp_ntp_servers = new_servers; + pthread_mutex_unlock(&g_dhcp_ntp_lock); + + free(old_servers); + + if (callback != NULL) + { + callback(notify_servers, arg); + } + + free(notify_servers); + return OK; + +errout_with_lock: + pthread_mutex_unlock(&g_dhcp_ntp_lock); + free(new_servers); + return ret; +} + +int netlib_register_dhcp_ntp_callback(netlib_dhcp_ntp_callback_t callback, + FAR void *arg) +{ + FAR char *notify_servers = NULL; + + if (callback == NULL) + { + return -EINVAL; + } + + pthread_mutex_lock(&g_dhcp_ntp_lock); + + if (g_dhcp_ntp_callback != NULL && + (g_dhcp_ntp_callback != callback || g_dhcp_ntp_callback_arg != arg)) + { + pthread_mutex_unlock(&g_dhcp_ntp_lock); + return -EBUSY; + } + + if (g_dhcp_ntp_servers != NULL) + { + notify_servers = strdup(g_dhcp_ntp_servers); + if (notify_servers == NULL) + { + pthread_mutex_unlock(&g_dhcp_ntp_lock); + return -ENOMEM; + } + } + + g_dhcp_ntp_callback = callback; + g_dhcp_ntp_callback_arg = arg; + + pthread_mutex_unlock(&g_dhcp_ntp_lock); + + callback(notify_servers, arg); + free(notify_servers); + return OK; +} + +int netlib_unregister_dhcp_ntp_callback(netlib_dhcp_ntp_callback_t callback, + FAR void *arg) +{ + int ret = -ENOENT; + + pthread_mutex_lock(&g_dhcp_ntp_lock); + + if (g_dhcp_ntp_callback == callback && g_dhcp_ntp_callback_arg == arg) + { + g_dhcp_ntp_callback = NULL; + g_dhcp_ntp_callback_arg = NULL; + ret = OK; + } + + pthread_mutex_unlock(&g_dhcp_ntp_lock); + return ret; +} + +#endif /* CONFIG_NETUTILS_DHCPC */ diff --git a/netutils/netlib/netlib_obtainipv4addr.c b/netutils/netlib/netlib_obtainipv4addr.c index cab55b74c..df07fef59 100644 --- a/netutils/netlib/netlib_obtainipv4addr.c +++ b/netutils/netlib/netlib_obtainipv4addr.c @@ -25,6 +25,10 @@ ****************************************************************************/ #include +#include +#include +#include +#include #include #include "netutils/dhcpc.h" @@ -105,6 +109,68 @@ static int dhcp_setup_result(FAR const char *ifname, return OK; } +#ifdef CONFIG_NETUTILS_NTPCLIENT +static int dhcp_set_ntp_servers(FAR const struct dhcpc_state *ds) +{ + char ntp_server_list[CONFIG_NETUTILS_DHCPC_NTP_SERVERS * + (INET_ADDRSTRLEN + 1)]; + size_t offset = 0; + uint8_t i; + + /* Clear the DHCP-provided NTP server list, + * consider case: that device has joined another dhcp domain, + * it need refresh related settings. + */ + + if (ds->num_ntpaddr == 0) + { + return netlib_set_ntp_servers_from_dhcp(NULL); + } + + ntp_server_list[0] = '\0'; + + for (i = 0; i < ds->num_ntpaddr; i++) + { + char addrbuf[INET_ADDRSTRLEN]; + int ret; + + /* Skip empty entries */ + + if (ds->ntpaddr[i].s_addr == 0) + { + continue; + } + + if (inet_ntop(AF_INET, &ds->ntpaddr[i], addrbuf, sizeof(addrbuf)) == + NULL) + { + return -EINVAL; + } + + /* Append the server to the list */ + + ret = snprintf(ntp_server_list + offset, + sizeof(ntp_server_list) - offset, + "%s%s", offset == 0 ? "" : ";", addrbuf); + if (ret < 0 || (size_t)ret >= sizeof(ntp_server_list) - offset) + { + return -E2BIG; + } + + offset += (size_t)ret; + } + + /* Clear the list if all entries were empty */ + + if (offset == 0) + { + return netlib_set_ntp_servers_from_dhcp(NULL); + } + + return netlib_set_ntp_servers_from_dhcp(ntp_server_list); +} +#endif + /**************************************************************************** * Name: dhcp_obtain_statefuladdr * @@ -156,6 +222,18 @@ static int dhcp_obtain_statefuladdr(FAR const char *ifname) if (ret == OK) { ret = dhcp_setup_result(ifname, &ds); +#ifdef CONFIG_NETUTILS_NTPCLIENT + if (ret == OK) + { + ret = dhcp_set_ntp_servers(&ds); + if (ret < 0) + { + nwarn("WARNING: failed to update DHCP NTP server list: %d\n", + ret); + ret = OK; + } + } +#endif } else { diff --git a/netutils/ntpclient/ntpclient.c b/netutils/ntpclient/ntpclient.c index ce7d2f0d9..ec002a7f1 100644 --- a/netutils/ntpclient/ntpclient.c +++ b/netutils/ntpclient/ntpclient.c @@ -126,6 +126,14 @@ enum ntpc_daemon_e NTP_STOPPED }; +enum ntpc_server_source_e +{ + NTP_SERVER_SOURCE_NONE = 0, + NTP_SERVER_SOURCE_CONFIG, + NTP_SERVER_SOURCE_DHCP, + NTP_SERVER_SOURCE_EXPLICIT +}; + /* This type describes the state of the NTP client daemon. Only one * instance of the NTP daemon is permitted in this implementation. */ @@ -133,11 +141,17 @@ enum ntpc_daemon_e struct ntpc_daemon_s { uint8_t state; /* See enum ntpc_daemon_e */ + uint8_t source; /* See enum ntpc_server_source_e */ + bool dhcp_registered; sem_t lock; /* Used to protect the whole structure */ sem_t sync; /* Used to synchronize start and stop events */ pid_t pid; /* Task ID of the NTP daemon */ sq_queue_t kod_list; /* KoD excluded server addresses */ int family; /* Allowed address family */ + + /* DHCP-provided server list */ + + FAR char *dhcp_servers; }; union ntp_addr_u @@ -194,11 +208,14 @@ struct ntp_kod_exclude_s static struct ntpc_daemon_s g_ntpc_daemon = { NTP_NOT_RUNNING, + NTP_SERVER_SOURCE_NONE, + false, SEM_INITIALIZER(1), SEM_INITIALIZER(0), -1, { NULL, NULL }, AF_UNSPEC, /* Default is both IPv4 and IPv6 */ + NULL, }; static struct ntp_sample_s g_last_samples @@ -209,6 +226,115 @@ unsigned int g_last_nsamples = 0; * Private Functions ****************************************************************************/ +static int ntpc_daemon(int argc, FAR char **argv); +static int ntpc_set_servers_from_dhcp(FAR const char *ntp_server_list); + +static FAR char *ntpc_dup_server_list(FAR const char *ntp_server_list) +{ + if (ntp_server_list == NULL || ntp_server_list[0] == '\0') + { + return NULL; + } + + return strdup(ntp_server_list); +} + +static FAR const char *ntpc_select_server_list(FAR uint8_t *source) +{ + if (g_ntpc_daemon.dhcp_servers != NULL && + g_ntpc_daemon.dhcp_servers[0] != '\0') + { + *source = NTP_SERVER_SOURCE_DHCP; + return g_ntpc_daemon.dhcp_servers; + } + + if (CONFIG_NETUTILS_NTPCLIENT_SERVER[0] != '\0') + { + *source = NTP_SERVER_SOURCE_CONFIG; + return CONFIG_NETUTILS_NTPCLIENT_SERVER; + } + + *source = NTP_SERVER_SOURCE_NONE; + return NULL; +} + +#ifdef CONFIG_NETUTILS_DHCPC +static void ntpc_dhcp_notify(FAR const char *ntp_server_list, FAR void *arg) +{ + int ret; + + UNUSED(arg); + + ret = ntpc_set_servers_from_dhcp(ntp_server_list); + if (ret < 0) + { + nwarn("WARNING: failed to update DHCP NTP server list: %d\n", ret); + } +} + +static int ntpc_register_dhcp(void) +{ + int ret; + + sem_wait(&g_ntpc_daemon.lock); + if (g_ntpc_daemon.dhcp_registered) + { + sem_post(&g_ntpc_daemon.lock); + return OK; + } + + g_ntpc_daemon.dhcp_registered = true; + sem_post(&g_ntpc_daemon.lock); + + ret = netlib_register_dhcp_ntp_callback(ntpc_dhcp_notify, NULL); + if (ret < 0) + { + sem_wait(&g_ntpc_daemon.lock); + g_ntpc_daemon.dhcp_registered = false; + sem_post(&g_ntpc_daemon.lock); + return ret; + } + + return OK; +} +#endif + +static int ntpc_start_selected(FAR const char *ntp_server_list, + uint8_t source) +{ + FAR char *task_argv[] = + { + (FAR char *)ntp_server_list, + NULL + }; + + g_ntpc_daemon.state = NTP_STARTED; + g_ntpc_daemon.source = source; + g_ntpc_daemon.pid = + task_create("NTP daemon", CONFIG_NETUTILS_NTPCLIENT_SERVERPRIO, + CONFIG_NETUTILS_NTPCLIENT_STACKSIZE, ntpc_daemon, + task_argv); + + if (g_ntpc_daemon.pid < 0) + { + int errval = errno; + DEBUGASSERT(errval > 0); + + g_ntpc_daemon.state = NTP_STOPPED; + g_ntpc_daemon.source = NTP_SERVER_SOURCE_NONE; + nerr("ERROR: Failed to start the NTP daemon: %d\n", errval); + return -errval; + } + + do + { + sem_wait(&g_ntpc_daemon.sync); + } + while (g_ntpc_daemon.state == NTP_STARTED); + + return g_ntpc_daemon.pid; +} + /**************************************************************************** * Name: sample_cmp ****************************************************************************/ @@ -1490,11 +1616,12 @@ void ntpc_dualstack_family(int family) int ntpc_start_with_list(FAR const char *ntp_server_list) { - FAR char *task_argv[] = + int ret; + + if (ntp_server_list == NULL || ntp_server_list[0] == '\0') { - (FAR char *)ntp_server_list, - NULL - }; + return -EINVAL; + } /* Is the NTP in a non-running state? */ @@ -1502,34 +1629,10 @@ int ntpc_start_with_list(FAR const char *ntp_server_list) if (g_ntpc_daemon.state == NTP_NOT_RUNNING || g_ntpc_daemon.state == NTP_STOPPED) { - /* Start the NTP daemon */ - - g_ntpc_daemon.state = NTP_STARTED; - g_ntpc_daemon.pid = - task_create("NTP daemon", CONFIG_NETUTILS_NTPCLIENT_SERVERPRIO, - CONFIG_NETUTILS_NTPCLIENT_STACKSIZE, ntpc_daemon, - task_argv); - - /* Handle failures to start the NTP daemon */ - - if (g_ntpc_daemon.pid < 0) - { - int errval = errno; - DEBUGASSERT(errval > 0); - - g_ntpc_daemon.state = NTP_STOPPED; - nerr("ERROR: Failed to start the NTP daemon: %d\n", errval); - sem_post(&g_ntpc_daemon.lock); - return -errval; - } - - /* Wait for any daemon state change */ - - do - { - sem_wait(&g_ntpc_daemon.sync); - } - while (g_ntpc_daemon.state == NTP_STARTED); + ret = ntpc_start_selected(ntp_server_list, + NTP_SERVER_SOURCE_EXPLICIT); + sem_post(&g_ntpc_daemon.lock); + return ret; } sem_post(&g_ntpc_daemon.lock); @@ -1550,7 +1653,101 @@ int ntpc_start_with_list(FAR const char *ntp_server_list) int ntpc_start(void) { - return ntpc_start_with_list(CONFIG_NETUTILS_NTPCLIENT_SERVER); + FAR const char *ntp_server_list; + uint8_t source; + int ret; + +#ifdef CONFIG_NETUTILS_DHCPC + ret = ntpc_register_dhcp(); + if (ret < 0) + { + return ret; + } +#endif + + sem_wait(&g_ntpc_daemon.lock); + if (g_ntpc_daemon.state != NTP_NOT_RUNNING && + g_ntpc_daemon.state != NTP_STOPPED) + { + ret = g_ntpc_daemon.pid; + sem_post(&g_ntpc_daemon.lock); + return ret; + } + + ntp_server_list = ntpc_select_server_list(&source); + if (ntp_server_list == NULL) + { + g_ntpc_daemon.source = NTP_SERVER_SOURCE_NONE; + sem_post(&g_ntpc_daemon.lock); + return -ENOENT; + } + + ret = ntpc_start_selected(ntp_server_list, source); + sem_post(&g_ntpc_daemon.lock); + return ret; +} + +static int ntpc_set_servers_from_dhcp(FAR const char *ntp_server_list) +{ + FAR char *new_servers; + FAR char *old_servers; + bool start = false; + bool restart = false; + int ret = OK; + + new_servers = ntpc_dup_server_list(ntp_server_list); + if (ntp_server_list != NULL && ntp_server_list[0] != '\0' && + new_servers == NULL) + { + return -ENOMEM; + } + + sem_wait(&g_ntpc_daemon.lock); + + if ((g_ntpc_daemon.dhcp_servers == NULL && new_servers == NULL) || + (g_ntpc_daemon.dhcp_servers != NULL && new_servers != NULL && + strcmp(g_ntpc_daemon.dhcp_servers, new_servers) == 0)) + { + sem_post(&g_ntpc_daemon.lock); + free(new_servers); + return OK; + } + + old_servers = g_ntpc_daemon.dhcp_servers; + g_ntpc_daemon.dhcp_servers = new_servers; + + if ((g_ntpc_daemon.source == NTP_SERVER_SOURCE_DHCP || + g_ntpc_daemon.source == NTP_SERVER_SOURCE_CONFIG) && + (g_ntpc_daemon.state == NTP_STARTED || + g_ntpc_daemon.state == NTP_RUNNING)) + { + restart = true; + } + else if (g_ntpc_daemon.source == NTP_SERVER_SOURCE_NONE && + new_servers != NULL && + (g_ntpc_daemon.state == NTP_NOT_RUNNING || + g_ntpc_daemon.state == NTP_STOPPED)) + { + start = true; + } + + sem_post(&g_ntpc_daemon.lock); + free(old_servers); + + if (restart) + { + ret = ntpc_stop(); + if (ret >= 0 && new_servers != NULL) + { + ret = ntpc_start(); + } + } + else if (start) + { + ret = ntpc_start(); + } + + return ret; } /**************************************************************************** From 0105a9b23879666fc323e36d4896c3333679bba3 Mon Sep 17 00:00:00 2001 From: shichunma Date: Mon, 27 Apr 2026 21:40:58 +0800 Subject: [PATCH 306/568] netutils/ntpclient: guard DHCP-only helpers fix a warning that static function defined by not used Signed-off-by: Jerry Ma --- netutils/ntpclient/ntpclient.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/netutils/ntpclient/ntpclient.c b/netutils/ntpclient/ntpclient.c index ec002a7f1..304c02a3c 100644 --- a/netutils/ntpclient/ntpclient.c +++ b/netutils/ntpclient/ntpclient.c @@ -227,6 +227,7 @@ unsigned int g_last_nsamples = 0; ****************************************************************************/ static int ntpc_daemon(int argc, FAR char **argv); +#ifdef CONFIG_NETUTILS_DHCPC static int ntpc_set_servers_from_dhcp(FAR const char *ntp_server_list); static FAR char *ntpc_dup_server_list(FAR const char *ntp_server_list) @@ -238,6 +239,7 @@ static FAR char *ntpc_dup_server_list(FAR const char *ntp_server_list) return strdup(ntp_server_list); } +#endif static FAR const char *ntpc_select_server_list(FAR uint8_t *source) { @@ -1687,6 +1689,7 @@ int ntpc_start(void) return ret; } +#ifdef CONFIG_NETUTILS_DHCPC static int ntpc_set_servers_from_dhcp(FAR const char *ntp_server_list) { FAR char *new_servers; @@ -1749,6 +1752,7 @@ static int ntpc_set_servers_from_dhcp(FAR const char *ntp_server_list) return ret; } +#endif /**************************************************************************** * Name: ntpc_stop From ded0a17514954cf8230b2e0a0f1fce63a5c69080 Mon Sep 17 00:00:00 2001 From: Serg Podtynnyi Date: Wed, 22 Apr 2026 22:13:59 +0700 Subject: [PATCH 307/568] graphics/lvgl: bump version to 9.2.2 Update lvlg version to 9.2.2, includes fix for nuttx lcd release Get version from config in Makefile Get version from config in cmake file Signed-off-by: Serg Podtynnyi --- graphics/lvgl/CMakeLists.txt | 15 ++++++++++++--- graphics/lvgl/Kconfig | 4 ++-- graphics/lvgl/Makefile | 7 +++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/graphics/lvgl/CMakeLists.txt b/graphics/lvgl/CMakeLists.txt index 352b5da59..ba5af28e2 100644 --- a/graphics/lvgl/CMakeLists.txt +++ b/graphics/lvgl/CMakeLists.txt @@ -27,12 +27,21 @@ if(CONFIG_GRAPHICS_LVGL) # ############################################################################ set(LVGL_DIR ${CMAKE_CURRENT_LIST_DIR}/lvgl) + set(LVGL_VERSION + "${CONFIG_LVGL_VERSION_MAJOR}.${CONFIG_LVGL_VERSION_MINOR}.${CONFIG_LVGL_VERSION_PATCH}" + ) + if(NOT EXISTS ${LVGL_DIR}) + set(LVGL_URL + "https://github.com/lvgl/lvgl/archive/refs/tags/v${LVGL_VERSION}.zip") FetchContent_Declare( lvgl_fetch - DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR} - URL "https://github.com/lvgl/lvgl/archive/refs/tags/v9.2.1.zip" SOURCE_DIR - ${CMAKE_CURRENT_LIST_DIR}/lvgl BINARY_DIR + URL ${LVGL_URL} + DOWNLOAD_DIR + ${CMAKE_CURRENT_LIST_DIR} + SOURCE_DIR + ${CMAKE_CURRENT_LIST_DIR}/lvgl + BINARY_DIR ${CMAKE_BINARY_DIR}/apps/graphics/lvgl/lvgl DOWNLOAD_NO_PROGRESS true TIMEOUT 120) diff --git a/graphics/lvgl/Kconfig b/graphics/lvgl/Kconfig index 4daf467f3..2d9ad2f8e 100644 --- a/graphics/lvgl/Kconfig +++ b/graphics/lvgl/Kconfig @@ -11,7 +11,7 @@ menuconfig GRAPHICS_LVGL if GRAPHICS_LVGL -# Kconfig file for LVGL v9.2.1 +# Kconfig file for LVGL v9.2.2 menu "LVGL configuration" @@ -1495,7 +1495,7 @@ menu "LVGL configuration" default 2 # LVGL_VERSION_MINOR config LVGL_VERSION_PATCH int - default 1 # LVGL_VERSION_PATCH + default 2 # LVGL_VERSION_PATCH endmenu menu "Devices" diff --git a/graphics/lvgl/Makefile b/graphics/lvgl/Makefile index a81fac1eb..ce9ad6b7f 100644 --- a/graphics/lvgl/Makefile +++ b/graphics/lvgl/Makefile @@ -58,8 +58,11 @@ WD := ${shell echo $(CURDIR) | sed -e 's/ /\\ /g'} CONFIG_GRAPH_LVGL_URL ?= "https://github.com/lvgl/lvgl/archive/refs/tags" -LVGL_VERSION = 9.2.1 -LVGL_TARBALL = v$(LVGL_VERSION).zip +_MAJ := $(CONFIG_LVGL_VERSION_MAJOR) +_MIN := $(CONFIG_LVGL_VERSION_MINOR) +_PAT := $(CONFIG_LVGL_VERSION_PATCH) +LVGL_VERSION := $(_MAJ).$(_MIN).$(_PAT) +LVGL_TARBALL := v$(LVGL_VERSION).zip LVGL_UNPACKNAME = lvgl UNPACK ?= unzip -o $(if $(V),,-q) From a9881037ea8f37c99cad6c31eb3ba8af2ebc3cec Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Tue, 27 Aug 2024 17:53:44 +0200 Subject: [PATCH 308/568] nimble: remove -Wno-pointer-to-int-cast from CFLAGS it's not needed and cause warnings for C++ builds: cc1plus: warning: command-line option '-Wno-pointer-to-int-cast' is valid for C/ObjC but not for C++ Signed-off-by: raiden00pl --- wireless/bluetooth/nimble/CMakeLists.txt | 5 +++-- wireless/bluetooth/nimble/Makefile.nimble | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/wireless/bluetooth/nimble/CMakeLists.txt b/wireless/bluetooth/nimble/CMakeLists.txt index 1abf4a576..f6fda14ec 100644 --- a/wireless/bluetooth/nimble/CMakeLists.txt +++ b/wireless/bluetooth/nimble/CMakeLists.txt @@ -193,7 +193,8 @@ if(CONFIG_NIMBLE) target_include_directories(nimble PUBLIC include ${INCLUDES}) - target_compile_options(nimble PUBLIC -Wno-pointer-to-int-cast -Wno-undef - -Wno-format -Wno-unused-but-set-variable) + target_compile_options(nimble PUBLIC -Wno-undef -Wno-format + -Wno-unused-but-set-variable) + target_sources(nimble PRIVATE ${SRCS}) endif() diff --git a/wireless/bluetooth/nimble/Makefile.nimble b/wireless/bluetooth/nimble/Makefile.nimble index 8a4281dfa..0b86a8263 100644 --- a/wireless/bluetooth/nimble/Makefile.nimble +++ b/wireless/bluetooth/nimble/Makefile.nimble @@ -64,7 +64,7 @@ CXXFLAGS += $(addprefix ${INCDIR_PREFIX}, $(NIMBLE_ALL_INC)) # NimBLE assumes this flag since it expects undefined macros to be zero value -CFLAGS += -Wno-pointer-to-int-cast -Wno-undef +CFLAGS += -Wno-undef # disable printf format checks From 5b0cae9ab0e8669ad2f6020e1ecb0e855b44c466 Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Mon, 16 Feb 2026 13:41:27 -0500 Subject: [PATCH 309/568] !apps: Simplify NuttX initialization BREAKING: In an effort to simplify board initialization logic for NuttX, NSH will no longer support architecture initialization. This will happen during boot via the BOARD_LATE_INITIALIZE option. The boardctl command BOARDIOC_INIT is also no longer available from user-space. Quick fix: Any application relying on BOARDIOC_INIT should now enable BOARD_LATE_INITIALIZE to have initialization performed by the kernel in advance of the application running. If control over initialization is still necessary, BOARDIOC_FINALINIT should be implemented and used. Boards relying on NSH for initialization should also enable BOARD_LATE_INITIALIZE instead. Signed-off-by: Matteo Golin --- boot/miniboot/miniboot_main.c | 6 +---- boot/nxboot/nxboot_main.c | 6 ----- examples/foc/foc_main.c | 10 ++------ examples/lvgldemo/lvgldemo.c | 24 ------------------- examples/lvglterm/lvglterm.c | 23 ------------------ examples/nimble/nimble_main.c | 6 ----- examples/nimble_blecent/nimble_blecent_main.c | 8 +------ examples/nimble_bleprph/nimble_bleprph_main.c | 8 +------ examples/nxscope/nxscope_main.c | 8 +------ examples/powerled/powerled_main.c | 6 ----- examples/smps/smps_main.c | 6 ----- graphics/nxwm/src/nxwm_main.cxx | 10 -------- graphics/twm4nx/Kconfig | 11 --------- graphics/twm4nx/src/twm4nx_main.cxx | 17 ------------- nshlib/Kconfig | 12 +--------- nshlib/nsh.h | 7 ------ nshlib/nsh_init.c | 12 ---------- system/adb/Kconfig | 9 +------ system/adb/adb_main.c | 7 +----- system/adcscope/adcscope_main.c | 8 +------ system/ofloader/ofloader.c | 10 ++------ system/sensorscope/sensorscope_main.c | 8 +------ 22 files changed, 13 insertions(+), 209 deletions(-) diff --git a/boot/miniboot/miniboot_main.c b/boot/miniboot/miniboot_main.c index 63f47465c..ce490c45b 100644 --- a/boot/miniboot/miniboot_main.c +++ b/boot/miniboot/miniboot_main.c @@ -39,7 +39,7 @@ * Name: miniboot_main * * Description: - * Minimal bootlaoder entry point. + * Minimal bootloader entry point. * ****************************************************************************/ @@ -49,10 +49,6 @@ int main(int argc, FAR char *argv[]) syslog(LOG_INFO, "*** miniboot ***\n"); - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); - #ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ diff --git a/boot/nxboot/nxboot_main.c b/boot/nxboot/nxboot_main.c index 976b03b4c..0682b92c7 100644 --- a/boot/nxboot/nxboot_main.c +++ b/boot/nxboot/nxboot_main.c @@ -264,16 +264,10 @@ int main(int argc, FAR char *argv[]) FAR struct boardioc_reset_cause_s cause; #endif -#if defined(CONFIG_BOARDCTL) && !defined(CONFIG_NSH_ARCHINIT) - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); - #ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ boardctl(BOARDIOC_FINALINIT, 0); -#endif #endif syslog(LOG_INFO, "*** nxboot ***\n"); diff --git a/examples/foc/foc_main.c b/examples/foc/foc_main.c index 4b280e848..2f1b6b0c4 100644 --- a/examples/foc/foc_main.c +++ b/examples/foc/foc_main.c @@ -142,7 +142,7 @@ struct args_s g_args = } }; -/* Start allowed at defaule */ +/* Start allowed at default */ static bool g_start_allowed = true; static pthread_mutex_t g_start_allowed_lock = PTHREAD_MUTEX_INITIALIZER; @@ -294,16 +294,10 @@ int main(int argc, char *argv[]) goto errout_no_nxscope; } -#ifndef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); - -# ifdef CONFIG_BOARDCTL_FINALINIT +#ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ boardctl(BOARDIOC_FINALINIT, 0); -# endif #endif PRINTF("\nStart foc_main application!\n\n"); diff --git a/examples/lvgldemo/lvgldemo.c b/examples/lvgldemo/lvgldemo.c index 55d6620ed..b6ab1e5ab 100644 --- a/examples/lvgldemo/lvgldemo.c +++ b/examples/lvgldemo/lvgldemo.c @@ -38,23 +38,6 @@ * Pre-processor Definitions ****************************************************************************/ -/* Should we perform board-specific driver initialization? There are two - * ways that board initialization can occur: 1) automatically via - * board_late_initialize() during bootupif CONFIG_BOARD_LATE_INITIALIZE - * or 2). - * via a call to boardctl() if the interface is enabled - * (CONFIG_BOARDCTL=y). - * If this task is running as an NSH built-in application, then that - * initialization has probably already been performed otherwise we do it - * here. - */ - -#undef NEED_BOARDINIT - -#if defined(CONFIG_BOARDCTL) && !defined(CONFIG_NSH_ARCHINIT) -# define NEED_BOARDINIT 1 -#endif - /**************************************************************************** * Private Types ****************************************************************************/ @@ -122,13 +105,6 @@ int main(int argc, FAR char *argv[]) return -1; } -#ifdef NEED_BOARDINIT - /* Perform board-specific driver initialization */ - - boardctl(BOARDIOC_INIT, 0); - -#endif - lv_init(); lv_nuttx_dsc_init(&info); diff --git a/examples/lvglterm/lvglterm.c b/examples/lvglterm/lvglterm.c index 71c5e650e..f1ef2259f 100644 --- a/examples/lvglterm/lvglterm.c +++ b/examples/lvglterm/lvglterm.c @@ -63,23 +63,6 @@ * Pre-processor Definitions ****************************************************************************/ -/* Should we perform board-specific driver initialization? There are two - * ways that board initialization can occur: 1) automatically via - * board_late_initialize() during bootupif CONFIG_BOARD_LATE_INITIALIZE - * or 2). - * via a call to boardctl() if the interface is enabled - * (CONFIG_BOARDCTL=y). - * If this task is running as an NSH built-in application, then that - * initialization has probably already been performed otherwise we do it - * here. - */ - -#undef NEED_BOARDINIT - -#if defined(CONFIG_BOARDCTL) && !defined(CONFIG_NSH_ARCHINIT) -# define NEED_BOARDINIT 1 -#endif - /* How often to poll for output from NSH Shell (milliseconds) */ #define TIMER_PERIOD_MS 100 @@ -550,16 +533,10 @@ int main(int argc, FAR char *argv[]) uv_loop_t ui_loop; #endif -#ifdef NEED_BOARDINIT - /* Perform board-specific driver initialization */ - - boardctl(BOARDIOC_INIT, 0); - #ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ boardctl(BOARDIOC_FINALINIT, 0); -#endif #endif /* LVGL initialization */ diff --git a/examples/nimble/nimble_main.c b/examples/nimble/nimble_main.c index ba46199f7..68eb2f051 100644 --- a/examples/nimble/nimble_main.c +++ b/examples/nimble/nimble_main.c @@ -255,12 +255,6 @@ int main(int argc, FAR char *argv[]) ble_hci_sock_set_device(atoi(argv[1])); } -#ifndef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization */ - - boardctl(BOARDIOC_INIT, 0); -#endif - #ifndef CONFIG_NSH_NETINIT /* Bring up the network */ diff --git a/examples/nimble_blecent/nimble_blecent_main.c b/examples/nimble_blecent/nimble_blecent_main.c index a20dd282d..5af9d2b03 100644 --- a/examples/nimble_blecent/nimble_blecent_main.c +++ b/examples/nimble_blecent/nimble_blecent_main.c @@ -412,7 +412,7 @@ static int blecent_gap_event(FAR struct ble_gap_event *event, FAR void *arg) return 0; } - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ print_adv_fields(&fields); @@ -632,12 +632,6 @@ int main(int argc, FAR char **argv) ble_hci_sock_set_device(atoi(argv[1])); } -#ifndef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization */ - - boardctl(BOARDIOC_INIT, 0); -#endif - #ifndef CONFIG_NSH_NETINIT /* Bring up the network */ diff --git a/examples/nimble_bleprph/nimble_bleprph_main.c b/examples/nimble_bleprph/nimble_bleprph_main.c index 9dea4d226..9c41f72b2 100644 --- a/examples/nimble_bleprph/nimble_bleprph_main.c +++ b/examples/nimble_bleprph/nimble_bleprph_main.c @@ -140,7 +140,7 @@ static void bleprph_advertise(void) BLE_HS_ADV_F_BREDR_UNSUP; /* Indicate that the TX power level field should be included; have the - * stack fill this value automatically. This is done by assiging the + * stack fill this value automatically. This is done by assigning the * special value BLE_HS_ADV_TX_PWR_LVL_AUTO. */ @@ -372,12 +372,6 @@ int main(int argc, FAR char *argv[]) ble_hci_sock_set_device(atoi(argv[1])); } -#ifndef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization */ - - boardctl(BOARDIOC_INIT, 0); -#endif - #ifndef CONFIG_NSH_NETINIT /* Bring up the network */ diff --git a/examples/nxscope/nxscope_main.c b/examples/nxscope/nxscope_main.c index afad9052b..1f4c9fff4 100644 --- a/examples/nxscope/nxscope_main.c +++ b/examples/nxscope/nxscope_main.c @@ -527,16 +527,10 @@ int main(int argc, FAR char *argv[]) printf("stream interval = %d\n", env.interval); printf("main interval = %d\n", interval); -#ifndef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); - -# ifdef CONFIG_BOARDCTL_FINALINIT +#ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ boardctl(BOARDIOC_FINALINIT, 0); -# endif #endif #ifdef CONFIG_EXAMPLES_NXSCOPE_CDCACM diff --git a/examples/powerled/powerled_main.c b/examples/powerled/powerled_main.c index b949aadfa..6743b5e23 100644 --- a/examples/powerled/powerled_main.c +++ b/examples/powerled/powerled_main.c @@ -439,16 +439,10 @@ int main(int argc, char *argv[]) goto errout; } -#ifndef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); - #ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ boardctl(BOARDIOC_FINALINIT, 0); -#endif #endif /* Set LED current limit */ diff --git a/examples/smps/smps_main.c b/examples/smps/smps_main.c index 852696855..b9ddbd827 100644 --- a/examples/smps/smps_main.c +++ b/examples/smps/smps_main.c @@ -476,16 +476,10 @@ int main(int argc, char *argv[]) goto errout; } -#ifndef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); - #ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ boardctl(BOARDIOC_FINALINIT, 0); -#endif #endif /* Set SMPS mode */ diff --git a/graphics/nxwm/src/nxwm_main.cxx b/graphics/nxwm/src/nxwm_main.cxx index 98feabbf6..6b6a3ca1d 100644 --- a/graphics/nxwm/src/nxwm_main.cxx +++ b/graphics/nxwm/src/nxwm_main.cxx @@ -485,16 +485,6 @@ static bool createMediaPlayer(void) int main(int argc, char *argv[]) { -#if defined(CONFIG_BOARDCTL) && !defined(CONFIG_BOARD_LATE_INITIALIZE) - // Should we perform board-specific initialization? There are two ways - // that board initialization can occur: 1) automatically via - // board_late_initialize() during bootup if CONFIG_BOARD_LATE_INITIALIZE, or - // 2) here via a call to boardctl() if the interface is enabled - // (CONFIG_BOARDCTL=y). - - boardctl(BOARDIOC_INIT, 0); -#endif - #ifdef CONFIG_NXWM_NXTERM // Initialize the NSH library diff --git a/graphics/twm4nx/Kconfig b/graphics/twm4nx/Kconfig index 3f9600f68..3b114df88 100644 --- a/graphics/twm4nx/Kconfig +++ b/graphics/twm4nx/Kconfig @@ -42,17 +42,6 @@ config TWM4NX_REVMINOR string "Twm4Nx minor version number" default "0" -config TWM4NX_ARCHINIT - bool "Have architecture-specific initialization" - default n - select BOARDCTL - depends on !NSH_ARCHINIT - ---help--- - Set if your board provides architecture specific initialization - via the board-interface function boardctl(). The boardctl() - function will be called early in Twm4Nx initialization to allow - board logic to do such things as configure MMC/SD slots. - config TWM4NX_NETINIT bool "Network initialization" default y diff --git a/graphics/twm4nx/src/twm4nx_main.cxx b/graphics/twm4nx/src/twm4nx_main.cxx index 30185ad07..3cfb3a6b5 100644 --- a/graphics/twm4nx/src/twm4nx_main.cxx +++ b/graphics/twm4nx/src/twm4nx_main.cxx @@ -98,23 +98,6 @@ int main(int argc, FAR char *argv[]) int ret; -#if defined(CONFIG_TWM4NX_ARCHINIT) && defined(CONFIG_BOARDCTL) && \ - !defined(CONFIG_BOARD_LATE_INITIALIZE) - // Should we perform board-specific initialization? There are two ways - // that board initialization can occur: 1) automatically via - // board_late_initialize() during bootup if CONFIG_BOARD_LATE_INITIALIZE, or - // 2) here via a call to boardctl() if the interface is enabled - // (CONFIG_BOARDCTL=y). board_early_initialize() is also possibility, - // although less likely. - - ret = boardctl(BOARDIOC_INIT, 0); - if (ret < 0) - { - twmerr("ERROR: boardctl(BOARDIOC_INIT) failed: %d\n", errno); - return EXIT_FAILURE; - } -#endif - #ifdef CONFIG_TWM4NX_NETINIT /* Bring up the network */ diff --git a/nshlib/Kconfig b/nshlib/Kconfig index b9a510383..1fc34cb21 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -9,7 +9,7 @@ config NSH_LIBRARY bool "NSH Library" default n select NETUTILS_NETLIB if NET - select BOARDCTL if (!NSH_DISABLE_MKRD && !DISABLE_MOUNTPOINT) || NSH_ARCHINIT + select BOARDCTL if (!NSH_DISABLE_MKRD && !DISABLE_MOUNTPOINT) select BOARDCTL_MKRD if !NSH_DISABLE_MKRD && !DISABLE_MOUNTPOINT ---help--- Build the NSH support library. This is used, for example, by @@ -1116,16 +1116,6 @@ config NSH_USBDEV_TRACEINTERRUPTS endif # NSH_USBDEV_TRACE endmenu # USB Device Trace Support -config NSH_ARCHINIT - bool "Have architecture-specific initialization" - default n - select BOARDCTL - ---help--- - Set if your board provides architecture specific initialization - via the board-interface function boardctl(). The boardctl() - function will be called early in NSH initialization to allow - board logic to do such things as configure MMC/SD slots. - menu "Networking Configuration" depends on NET diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 8ea334d07..2fb3cf867 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -807,13 +807,6 @@ int nsh_loginscript(FAR struct nsh_vtbl_s *vtbl); * available: */ -/* Architecture-specific initialization depends on boardctl(BOARDIOC_INIT) */ - -#if defined(CONFIG_NSH_ARCHINIT) && !defined(CONFIG_BOARDCTL) -# warning CONFIG_NSH_ARCHINIT is set, but CONFIG_BOARDCTL is not -# undef CONFIG_NSH_ARCHINIT -#endif - /* The mkrd command depends on boardctl(BOARDIOC_MKRD) */ #if !defined(CONFIG_BOARDCTL) || !defined(CONFIG_BOARDCTL_MKRD) diff --git a/nshlib/nsh_init.c b/nshlib/nsh_init.c index 4846ff15b..aea095e34 100644 --- a/nshlib/nsh_init.c +++ b/nshlib/nsh_init.c @@ -143,12 +143,6 @@ void nsh_initialize(void) boardctl(BOARDIOC_APP_SYMTAB, (uintptr_t)&symdesc); #endif -#ifdef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); -#endif - #if defined(CONFIG_ETC_ROMFS) && !defined(CONFIG_NSH_DISABLESCRIPT) pstate = nsh_newconsole(false); @@ -163,12 +157,6 @@ void nsh_initialize(void) netinit_bringup(); #endif -#if defined(CONFIG_NSH_ARCHINIT) && defined(CONFIG_BOARDCTL_FINALINIT) - /* Perform architecture-specific final-initialization (if configured) */ - - boardctl(BOARDIOC_FINALINIT, 0); -#endif - #if defined(CONFIG_ETC_ROMFS) && !defined(CONFIG_NSH_DISABLESCRIPT) /* Execute the start-up script */ diff --git a/system/adb/Kconfig b/system/adb/Kconfig index 05296cca7..a97ac5a9f 100644 --- a/system/adb/Kconfig +++ b/system/adb/Kconfig @@ -200,19 +200,12 @@ config ADBD_SOCKET_SERVICE ---help--- Enable "adb forward|reverse" feature. -config ADBD_BOARD_INIT - bool "Board initialization" - depends on BOARDCTL - default n - ---help--- - Setup board before running adb daemon. - config ADBD_USB_BOARDCTL bool "USB Board Control" depends on BOARDCTL depends on ADBD_USB_SERVER select BOARDCTL_USBDEVCTRL - default ADBD_BOARD_INIT + default y ---help--- Connect usbdev before running adb daemon. diff --git a/system/adb/adb_main.c b/system/adb/adb_main.c index 3895001d5..8703337c6 100644 --- a/system/adb/adb_main.c +++ b/system/adb/adb_main.c @@ -32,8 +32,7 @@ #include #include -#if defined(CONFIG_ADBD_BOARD_INIT) || defined (CONFIG_BOARDCTL_RESET) || \ - defined(CONFIG_ADBD_USB_BOARDCTL) +#if defined (CONFIG_BOARDCTL_RESET) || defined(CONFIG_ADBD_USB_BOARDCTL) # include #endif @@ -120,10 +119,6 @@ int main(int argc, FAR char **argv) int ret; #endif -#ifdef CONFIG_ADBD_BOARD_INIT - boardctl(BOARDIOC_INIT, 0); -#endif /* CONFIG_ADBD_BOARD_INIT */ - #ifdef CONFIG_ADBD_USB_BOARDCTL /* Setup USBADB device */ diff --git a/system/adcscope/adcscope_main.c b/system/adcscope/adcscope_main.c index 3413c6b52..991a756ca 100644 --- a/system/adcscope/adcscope_main.c +++ b/system/adcscope/adcscope_main.c @@ -382,16 +382,10 @@ int main(int argc, FAR char *argv[]) pthread_t thread; int ret; -#ifndef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); - -# ifdef CONFIG_BOARDCTL_FINALINIT +#ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ boardctl(BOARDIOC_FINALINIT, 0); -# endif #endif #ifdef CONFIG_SYSTEM_ADCSCOPE_CDCACM diff --git a/system/ofloader/ofloader.c b/system/ofloader/ofloader.c index 8200262fe..6648a66b0 100644 --- a/system/ofloader/ofloader.c +++ b/system/ofloader/ofloader.c @@ -35,7 +35,7 @@ #include "ofloader.h" /**************************************************************************** - * Private Typess + * Private Types ****************************************************************************/ struct devinfo_s @@ -320,16 +320,10 @@ int main(int argc, FAR char *argv[]) size_t i; mqd_t mq; -#if defined(CONFIG_BOARDCTL) && !defined(CONFIG_NSH_ARCHINIT) - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); - -# ifdef CONFIG_BOARDCTL_FINALINIT +#ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ boardctl(BOARDIOC_FINALINIT, 0); -# endif #endif memset(&mqattr, 0, sizeof(struct mq_attr)); diff --git a/system/sensorscope/sensorscope_main.c b/system/sensorscope/sensorscope_main.c index 2c8f2ecbe..1bb5e044d 100644 --- a/system/sensorscope/sensorscope_main.c +++ b/system/sensorscope/sensorscope_main.c @@ -412,16 +412,10 @@ int main(int argc, FAR char *argv[]) pthread_t thread; int ret; -#ifndef CONFIG_NSH_ARCHINIT - /* Perform architecture-specific initialization (if configured) */ - - boardctl(BOARDIOC_INIT, 0); - -# ifdef CONFIG_BOARDCTL_FINALINIT +#ifdef CONFIG_BOARDCTL_FINALINIT /* Perform architecture-specific final-initialization (if configured) */ boardctl(BOARDIOC_FINALINIT, 0); -# endif #endif #ifdef CONFIG_SYSTEM_SENSORSCOPE_CDCACM From dca76ccb7853f2e96aa4add40dbe924209d2259c Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Thu, 19 Feb 2026 00:07:07 -0500 Subject: [PATCH 310/568] codespell: Ignore lines without typos Ignore some new lines with incorrect spelling error detection. Signed-off-by: Matteo Golin --- .codespell-ignore-lines | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.codespell-ignore-lines b/.codespell-ignore-lines index 4b6f55c66..45628423d 100644 --- a/.codespell-ignore-lines +++ b/.codespell-ignore-lines @@ -1,6 +1,8 @@ mynewt-nimble/nimble/host/services/ans/src/ble_svc_ans.c mynewt-nimble/nimble/host/services/ans/include +#include "services/ans/ble_svc_ans.h" #include "crypto/controlse/ccertificate.hxx" + * notifications for the ANS Unread Alert Status characteristic object = new Controlse::CCertificate( Controlse::CCertificate cert(se, settings->key_id); auto certificate = Controlse::CCertificate( From b3cf222836bea1a97fc2c5d49596850459c99b9d Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sun, 29 Mar 2026 17:46:22 +0200 Subject: [PATCH 311/568] system/sensorscope: support for fixe16 data system/sensorscope: support for fixe16 data Signed-off-by: raiden00pl --- system/sensorscope/sensorscope_main.c | 57 ++++++++++++++++++--------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/system/sensorscope/sensorscope_main.c b/system/sensorscope/sensorscope_main.c index 1bb5e044d..9430ab08c 100644 --- a/system/sensorscope/sensorscope_main.c +++ b/system/sensorscope/sensorscope_main.c @@ -50,6 +50,12 @@ #define SENSOR_PATH_MAX 62 #define SENSOR_CHNAME_MAX 16 +#ifdef CONFIG_SENSORS_USE_B16 +# define NXSCOPE_DATA_TYPE NXSCOPE_TYPE_B16 +#else +# define NXSCOPE_DATA_TYPE NXSCOPE_TYPE_FLOAT +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -98,24 +104,41 @@ struct nxscope_thr_env_s struct nxsensor_info_s g_nxsensor[] = { - {"accel", sizeof(struct sensor_accel), 0, 3, NXSCOPE_TYPE_FLOAT}, - {"mag", sizeof(struct sensor_mag), 0, 3, NXSCOPE_TYPE_FLOAT}, - {"gyro", sizeof(struct sensor_gyro), 0, 3, NXSCOPE_TYPE_FLOAT}, - {"light", sizeof(struct sensor_light), 0, 2, NXSCOPE_TYPE_FLOAT}, - {"baro", sizeof(struct sensor_baro), 0, 2, NXSCOPE_TYPE_FLOAT}, - {"prox", sizeof(struct sensor_prox), 0, 1, NXSCOPE_TYPE_FLOAT}, - {"humi", sizeof(struct sensor_humi), 0, 1, NXSCOPE_TYPE_FLOAT}, - {"temp", sizeof(struct sensor_temp), 0, 1, NXSCOPE_TYPE_FLOAT}, - {"rgb", sizeof(struct sensor_rgb), 0, 3, NXSCOPE_TYPE_FLOAT}, + {"accel", sizeof(struct sensor_accel), 0, 3, NXSCOPE_DATA_TYPE}, + {"mag", sizeof(struct sensor_mag), 0, 3, NXSCOPE_DATA_TYPE}, + {"gyro", sizeof(struct sensor_gyro), 0, 3, NXSCOPE_DATA_TYPE}, + {"light", sizeof(struct sensor_light), 0, 2, NXSCOPE_DATA_TYPE}, + {"baro", sizeof(struct sensor_baro), 0, 2, NXSCOPE_DATA_TYPE}, + {"prox", sizeof(struct sensor_prox), 0, 1, NXSCOPE_DATA_TYPE}, + {"humi", sizeof(struct sensor_humi), 0, 1, NXSCOPE_DATA_TYPE}, + {"temp", sizeof(struct sensor_temp), 0, 1, NXSCOPE_DATA_TYPE}, + {"rgb", sizeof(struct sensor_rgb), 0, 3, NXSCOPE_DATA_TYPE}, {"hall", sizeof(struct sensor_hall), 0, 1, NXSCOPE_TYPE_INT32}, - {"ir", sizeof(struct sensor_ir), 0, 1, NXSCOPE_TYPE_FLOAT}, - {"gas", sizeof(struct sensor_gas), 0, 1, NXSCOPE_TYPE_FLOAT}, + {"ir", sizeof(struct sensor_ir), 0, 1, NXSCOPE_DATA_TYPE}, + {"gas", sizeof(struct sensor_gas), 0, 1, NXSCOPE_DATA_TYPE}, }; /**************************************************************************** * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: nxscope_samples_put + ****************************************************************************/ + +static void nxscope_samples_put(FAR struct nxscope_thr_env_s *envp, + FAR struct listen_object_s *tmp, + size_t offset) +{ +#ifdef CONFIG_SENSORS_USE_B16 + FAR b16_t *data = (b16_t *)&tmp->data[offset]; + nxscope_put_vb16(&envp->nxs, tmp->chanid, data, tmp->info->dim); +#else + FAR float *data = (float *)&tmp->data[offset]; + nxscope_put_vfloat(&envp->nxs, tmp->chanid, data, tmp->info->dim); +#endif +} + /**************************************************************************** * Name: nxscope_samples_thr ****************************************************************************/ @@ -124,9 +147,7 @@ static FAR void *nxscope_samples_thr(FAR void *arg) { FAR struct nxscope_thr_env_s *envp = arg; FAR struct listen_object_s *tmp; - FAR float *data; int ret; - size_t offset; DEBUGASSERT(envp); @@ -147,11 +168,9 @@ static FAR void *nxscope_samples_thr(FAR void *arg) { /* Get vector from a given offset */ - offset = tmp->info->data_offset + sizeof(uint64_t); - data = (float *)&tmp->data[offset]; - - nxscope_put_vfloat(&envp->nxs, tmp->chanid, data, - tmp->info->dim); + nxscope_samples_put(envp, tmp, + tmp->info->data_offset + + sizeof(uint64_t)); } } @@ -363,7 +382,7 @@ static int nxscope_channels(FAR struct nxscope_thr_env_s *envp) /* Register nxscope channel */ - u.s.dtype = NXSCOPE_TYPE_FLOAT; + u.s.dtype = NXSCOPE_DATA_TYPE; u.s._res = 0; u.s.cri = 0; From 783957da07a39f0de7d6337b853d3516483a60da Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sun, 29 Mar 2026 17:48:36 +0200 Subject: [PATCH 312/568] system/uorb: DEBUG_UORB depends on float data DEBUG_UORB depends on float data, FIXED16 not supported Signed-off-by: raiden00pl --- system/uorb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/uorb/Kconfig b/system/uorb/Kconfig index 4e8103d2e..674317a38 100644 --- a/system/uorb/Kconfig +++ b/system/uorb/Kconfig @@ -46,7 +46,7 @@ endif # UORB_TESTS config DEBUG_UORB bool "uorb debug output" select LIBC_PRINT_EXTENSION - depends on LIBC_FLOATINGPOINT + depends on LIBC_FLOATINGPOINT && SENSORS_USE_FLOAT default n if DEBUG_UORB From 3adb14f12d66b833d21a18c4f94a260c96d28a5d Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 3 May 2026 16:25:03 +0800 Subject: [PATCH 313/568] !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support The matching nuttx commit removes CONFIG_HAVE_LONG_LONG; clean up the remaining users in nuttx-apps so that "long long" is always assumed: - examples/noteprintf, examples/nxscope: unconditionally exercise the %lld / long long branch. - fsutils/mkfatfs/configfat.c: drop the 32-bit fall-back paths in mkfatfs_nfatsect12/16/32; always use uint64_t for the FAT-size arithmetic. - logging/nxscope/nxscope_chan.c: drop the CONFIG_HAVE_LONG_LONG guard around the 64-bit sample helpers. - netutils/ftpd, netutils/ntpclient: always emit the 64-bit format strings. - testing/fs/fstest/fstest_main.c: drop the parallel 32-bit verification path; keep only the 64-bit (long long) random pattern generator. - system/zmodem/host/nuttx/compiler.h: remove the host-side CONFIG_HAVE_LONG_LONG stub macro. Signed-off-by: Xiang Xiao --- examples/noteprintf/noteprintf_main.c | 4 --- examples/nxscope/nxscope_main.c | 4 --- fsutils/mkfatfs/configfat.c | 40 ++++----------------------- logging/nxscope/nxscope_chan.c | 2 -- netutils/ftpd/ftpd.c | 4 --- netutils/ntpclient/ntpclient.c | 4 --- system/zmodem/host/nuttx/compiler.h | 4 --- testing/fs/fstest/fstest_main.c | 34 ++--------------------- 8 files changed, 8 insertions(+), 88 deletions(-) diff --git a/examples/noteprintf/noteprintf_main.c b/examples/noteprintf/noteprintf_main.c index dbc81ee8f..2717d7a1b 100644 --- a/examples/noteprintf/noteprintf_main.c +++ b/examples/noteprintf/noteprintf_main.c @@ -53,9 +53,7 @@ int main(int argc, FAR char *argv[]) short s = 2; int i = 3; long l = 4; -#ifdef CONFIG_HAVE_LONG_LONG long long ll = 5; -#endif intmax_t im = 6; size_t sz = 7; ptrdiff_t ptr = 8; @@ -78,9 +76,7 @@ int main(int argc, FAR char *argv[]) sched_note_printf(NOTE_TAG_ALWAYS, "%hd", s); sched_note_printf(NOTE_TAG_ALWAYS, "%d", i); sched_note_printf(NOTE_TAG_ALWAYS, "%ld", l); -#ifdef CONFIG_HAVE_LONG_LONG sched_note_printf(NOTE_TAG_ALWAYS, "%lld", ll); -#endif sched_note_printf(NOTE_TAG_ALWAYS, "%jd", im); sched_note_printf(NOTE_TAG_ALWAYS, "%zd", sz); sched_note_printf(NOTE_TAG_ALWAYS, "%td", ptr); diff --git a/examples/nxscope/nxscope_main.c b/examples/nxscope/nxscope_main.c index 1f4c9fff4..ba0a3c226 100644 --- a/examples/nxscope/nxscope_main.c +++ b/examples/nxscope/nxscope_main.c @@ -341,7 +341,6 @@ static FAR void *nxscope_samples_thr(FAR void *arg) nxscope_put_b16(envp->nxs, 13, ftob16(-1.0f)); -#ifdef CONFIG_HAVE_LONG_LONG /* Channel 14 */ nxscope_put_ub32(envp->nxs, 14, dtob32(1.0)); @@ -349,7 +348,6 @@ static FAR void *nxscope_samples_thr(FAR void *arg) /* Channel 15 */ nxscope_put_b32(envp->nxs, 15, dtob32(-1.0)); -#endif /* Channel 16 */ @@ -705,7 +703,6 @@ int main(int argc, FAR char *argv[]) u.s.cri = 0; nxscope_chan_init(&nxs, 13, "chan13", u.u8, 1, 0); -#ifdef CONFIG_HAVE_LONG_LONG u.s.dtype = NXSCOPE_TYPE_UB32; u.s._res = 0; u.s.cri = 0; @@ -715,7 +712,6 @@ int main(int argc, FAR char *argv[]) u.s._res = 0; u.s.cri = 0; nxscope_chan_init(&nxs, 15, "chan15", u.u8, 1, 0); -#endif /* Vector data channel */ diff --git a/fsutils/mkfatfs/configfat.c b/fsutils/mkfatfs/configfat.c index a3550cf7a..20f54d5af 100644 --- a/fsutils/mkfatfs/configfat.c +++ b/fsutils/mkfatfs/configfat.c @@ -121,13 +121,8 @@ static inline uint32_t mkfatfs_nfatsect12(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var, uint32_t navailsects) { -#ifdef CONFIG_HAVE_LONG_LONG uint64_t denom; uint64_t number; -#else - uint32_t denom; - uint32_t number; -#endif /* For FAT12, the cluster number is held in a 12-bit number or 1.5 bytes * per cluster reference. So each FAT sector will hold sectorsize/1.5 @@ -156,25 +151,12 @@ mkfatfs_nfatsect12(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var, * navailsects > 0x55555555 - 2 * clustersize */ -#ifndef CONFIG_HAVE_LONG_LONG - if (navailsects <= (0x55555555 - (1 << (fmt->ff_clustshift + 1)))) - { -#endif - - denom = (fmt->ff_nfats << 1) + fmt->ff_nfats - + (var->fv_sectorsize << (fmt->ff_clustshift + 1)); - number = (navailsects << 1) + navailsects - + (1 << (fmt->ff_clustshift + 2)) - + (1 << (fmt->ff_clustshift + 1)); - return (uint32_t)((number + denom - 1) / denom); - -#ifndef CONFIG_HAVE_LONG_LONG - } - else - { - return 0; - } -#endif + denom = (fmt->ff_nfats << 1) + fmt->ff_nfats + + (var->fv_sectorsize << (fmt->ff_clustshift + 1)); + number = (navailsects << 1) + navailsects + + (1 << (fmt->ff_clustshift + 2)) + + (1 << (fmt->ff_clustshift + 1)); + return (uint32_t)((number + denom - 1) / denom); } /**************************************************************************** @@ -201,13 +183,8 @@ static inline uint32_t mkfatfs_nfatsect16(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var, uint32_t navailsects) { -#ifdef CONFIG_HAVE_LONG_LONG uint64_t denom; uint64_t number; -#else - uint32_t denom; - uint32_t number; -#endif /* For FAT16, the cluster number is held in a 16-bit number or 2 bytes per * cluster reference. So each FAT sector will hold sectorsize/2 cluster @@ -270,13 +247,8 @@ static inline uint32_t mkfatfs_nfatsect32(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var, uint32_t navailsects) { -#ifdef CONFIG_HAVE_LONG_LONG uint64_t denom; uint64_t number; -#else - uint32_t denom; - uint32_t number; -#endif /* For FAT32, the cluster number is held in a 32-bit number or 4 bytes per * cluster reference. So each FAT sector will hold sectorsize/4 cluster diff --git a/logging/nxscope/nxscope_chan.c b/logging/nxscope/nxscope_chan.c index a68451f47..5fb9e9b92 100644 --- a/logging/nxscope/nxscope_chan.c +++ b/logging/nxscope/nxscope_chan.c @@ -332,7 +332,6 @@ static int nxscope_put_vector(FAR uint8_t *buff, uint8_t type, FAR void *val, break; } -#ifdef CONFIG_HAVE_LONG_LONG case NXSCOPE_TYPE_UINT64: case NXSCOPE_TYPE_INT64: case NXSCOPE_TYPE_DOUBLE: @@ -358,7 +357,6 @@ static int nxscope_put_vector(FAR uint8_t *buff, uint8_t type, FAR void *val, break; } -#endif case NXSCOPE_TYPE_CHAR: { diff --git a/netutils/ftpd/ftpd.c b/netutils/ftpd/ftpd.c index a6ed75324..fa5eb9284 100644 --- a/netutils/ftpd/ftpd.c +++ b/netutils/ftpd/ftpd.c @@ -3735,11 +3735,7 @@ static int ftpd_command_appe(FAR struct ftpd_session_s *session) static int ftpd_command_rest(FAR struct ftpd_session_s *session) { -#ifdef CONFIG_HAVE_LONG_LONG session->restartpos = (off_t)atoll(session->param); -#else - session->restartpos = (off_t)atoi(session->param); -#endif session->flags |= FTPD_SESSIONFLAG_RESTARTPOS; return ftpd_response(session->cmd.sd, session->txtimeout, diff --git a/netutils/ntpclient/ntpclient.c b/netutils/ntpclient/ntpclient.c index 304c02a3c..3d2b50e02 100644 --- a/netutils/ntpclient/ntpclient.c +++ b/netutils/ntpclient/ntpclient.c @@ -63,10 +63,6 @@ /* Configuration ************************************************************/ -#ifndef CONFIG_HAVE_LONG_LONG -# error "64-bit integer support required for NTP client" -#endif - #if defined(CONFIG_LIBC_NETDB) && !defined(CONFIG_NETUTILS_NTPCLIENT_SERVER) # error "CONFIG_NETUTILS_NTPCLIENT_SERVER must be provided" #endif diff --git a/system/zmodem/host/nuttx/compiler.h b/system/zmodem/host/nuttx/compiler.h index d2a4ff0f9..5376baee0 100644 --- a/system/zmodem/host/nuttx/compiler.h +++ b/system/zmodem/host/nuttx/compiler.h @@ -219,7 +219,6 @@ /* GCC supports both types double and long long */ -# define CONFIG_HAVE_LONG_LONG 1 # define CONFIG_HAVE_FLOAT 1 # define CONFIG_HAVE_DOUBLE 1 # define CONFIG_HAVE_LONG_DOUBLE 1 @@ -323,7 +322,6 @@ /* SDCC does not support type long long or type double */ -# undef CONFIG_HAVE_LONG_LONG # define CONFIG_HAVE_FLOAT 1 # undef CONFIG_HAVE_DOUBLE # undef CONFIG_HAVE_LONG_DOUBLE @@ -431,7 +429,6 @@ * and simply do not support long long or double. */ -# undef CONFIG_HAVE_LONG_LONG # define CONFIG_HAVE_FLOAT 1 # undef CONFIG_HAVE_DOUBLE # undef CONFIG_HAVE_LONG_DOUBLE @@ -507,7 +504,6 @@ # undef CONFIG_SMALL_MEMORY # undef CONFIG_LONG_IS_NOT_INT # undef CONFIG_PTR_IS_NOT_INT -# undef CONFIG_HAVE_LONG_LONG # define CONFIG_HAVE_FLOAT 1 # undef CONFIG_HAVE_DOUBLE # undef CONFIG_HAVE_LONG_DOUBLE diff --git a/testing/fs/fstest/fstest_main.c b/testing/fs/fstest/fstest_main.c index 68ea1f719..a0d8f8978 100644 --- a/testing/fs/fstest/fstest_main.c +++ b/testing/fs/fstest/fstest_main.c @@ -218,7 +218,7 @@ static inline void fstest_randname(FAR struct fstest_ctx_s *ctx, dirlen = strlen(ctx->mountdir); - /* Force the max filename lengh and also the min name len = 4 */ + /* Force the max filename length and also the min name len = 4 */ maxname = CONFIG_TESTING_FSTEST_MAXNAME - dirlen - 3; namelen = (rand() % maxname) + 4; @@ -668,7 +668,6 @@ static inline int fstest_rdfile(FAR struct fstest_ctx_s *ctx, * Name: fstest_filesize ****************************************************************************/ -#ifdef CONFIG_HAVE_LONG_LONG static unsigned long long fstest_filesize(FAR struct fstest_ctx_s *ctx) { unsigned long long bytes_used; @@ -688,27 +687,6 @@ static unsigned long long fstest_filesize(FAR struct fstest_ctx_s *ctx) return bytes_used; } -#else -static unsigned long fstest_filesize(FAR struct fstest_ctx_s *ctx) -{ - unsigned long bytes_used; - FAR struct fstest_filedesc_s *file; - int i; - - bytes_used = 0; - - for (i = 0; i < ctx->max_open; i++) - { - file = &ctx->files[i]; - if (file->name != NULL && !file->deleted) - { - bytes_used += file->len; - } - } - - return bytes_used; -} -#endif /**************************************************************************** * Name: fstest_verifyfs @@ -983,7 +961,7 @@ int main(int argc, FAR char *argv[]) ctx = malloc(sizeof(struct fstest_ctx_s)); if (ctx == NULL) { - printf("malloc ctx feild,exit!\n"); + printf("malloc ctx field,exit!\n"); exit(1); } @@ -1081,11 +1059,7 @@ int main(int argc, FAR char *argv[]) /* Directory listing */ fstest_directory(ctx); -#ifdef CONFIG_HAVE_LONG_LONG printf("Total file size: %llu\n", fstest_filesize(ctx)); -#else - printf("Total file size: %lu\n", fstest_filesize(ctx)); -#endif /* Verify all files written to FLASH */ @@ -1131,11 +1105,7 @@ int main(int argc, FAR char *argv[]) /* Directory listing */ fstest_directory(ctx); -#ifdef CONFIG_HAVE_LONG_LONG printf("Total file size: %llu\n", fstest_filesize(ctx)); -#else - printf("Total file size: %lu\n", fstest_filesize(ctx)); -#endif /* Verify all files written to FLASH */ From ed746548ca857ad149433a90e7eb8ec44ad84522 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 3 May 2026 20:52:13 +0800 Subject: [PATCH 314/568] !testing/libc/scanftest: drop CONFIG_LIBC_LONG_LONG from help text CONFIG_LIBC_LONG_LONG has been removed; long long support is now unconditional. Signed-off-by: Xiang Xiao --- testing/libc/scanftest/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testing/libc/scanftest/Kconfig b/testing/libc/scanftest/Kconfig index 33426dc97..92cc1c81b 100644 --- a/testing/libc/scanftest/Kconfig +++ b/testing/libc/scanftest/Kconfig @@ -11,8 +11,7 @@ config TESTING_SCANFTEST Enable sscanf() test For all tests to be successful, you need to enable - CONFIG_LIBC_FLOATINGPOINT, CONFIG_LIBC_LONG_LONG and - CONFIG_LIBC_SCANSET in addition. + CONFIG_LIBC_FLOATINGPOINT and CONFIG_LIBC_SCANSET in addition. if TESTING_SCANFTEST From 72837c8d2698fcb6a9750ad8aa8103831fc2273b Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 3 May 2026 15:54:26 +0800 Subject: [PATCH 315/568] !apps: drop CONFIG_SYSTEM_TIME64 conditionals NuttX always uses a 64-bit system clock now (time_t/clock_t are always 64-bit). Remove the obsolete CONFIG_SYSTEM_TIME64 #ifdef branches and Kconfig dependency. - examples/dronecan: drop SYSTEM_TIME64 dependency - examples/netlink_route: always use PRIx64 - netutils/netinit: always use the 1-hour LONG_TIME_SEC - netutils/ptpd: always pack the 48-bit seconds field and apply the 64-bit overflow guard in timespec_delta_ns() - testing/ostest/semtimed: always validate tv_sec >= 0 Signed-off-by: Xiang Xiao --- examples/dronecan/Kconfig | 2 +- examples/netlink_route/netlink_route_main.c | 4 ---- netutils/netinit/netinit.c | 6 +----- netutils/ptpd/ptpd.c | 7 ------- testing/ostest/semtimed.c | 4 ---- 5 files changed, 2 insertions(+), 21 deletions(-) diff --git a/examples/dronecan/Kconfig b/examples/dronecan/Kconfig index f005a37f2..4ad761eb1 100644 --- a/examples/dronecan/Kconfig +++ b/examples/dronecan/Kconfig @@ -6,7 +6,7 @@ config EXAMPLES_DRONECAN tristate "DroneCAN example" default n - depends on CANUTILS_LIBDRONECAN && SYSTEM_TIME64 + depends on CANUTILS_LIBDRONECAN ---help--- Enable the LIBDRONECAN example diff --git a/examples/netlink_route/netlink_route_main.c b/examples/netlink_route/netlink_route_main.c index c69f4dd12..896a9796e 100644 --- a/examples/netlink_route/netlink_route_main.c +++ b/examples/netlink_route/netlink_route_main.c @@ -168,11 +168,7 @@ static void dump_neighbor(void) printf(" "); } -#ifdef CONFIG_SYSTEM_TIME64 printf("Time 0x%" PRIx64 "\n", nb->ne_time); -#else - printf("Time 0x%" PRIx32 "\n", nb->ne_time); -#endif } free(nbtab); diff --git a/netutils/netinit/netinit.c b/netutils/netinit/netinit.c index 24feea642..6120f4a67 100644 --- a/netutils/netinit/netinit.c +++ b/netutils/netinit/netinit.c @@ -204,11 +204,7 @@ * signal indicating a change in network status. */ -#ifdef CONFIG_SYSTEM_TIME64 -# define LONG_TIME_SEC (60*60) /* One hour in seconds */ -#else -# define LONG_TIME_SEC (5*60) /* Five minutes in seconds */ -#endif +#define LONG_TIME_SEC (60*60) /* One hour in seconds */ #define SHORT_TIME_SEC (2) /* 2 seconds */ diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 74b43084d..430693cc9 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -184,13 +184,8 @@ static void timespec_to_ptp_format(FAR const struct timespec *ts, * both fields big-endian. */ -#ifdef CONFIG_SYSTEM_TIME64 timestamp[0] = (uint8_t)(ts->tv_sec >> 40); timestamp[1] = (uint8_t)(ts->tv_sec >> 32); -#else - timestamp[0] = 0; - timestamp[1] = 0; -#endif timestamp[2] = (uint8_t)(ts->tv_sec >> 24); timestamp[3] = (uint8_t)(ts->tv_sec >> 16); timestamp[4] = (uint8_t)(ts->tv_sec >> 8); @@ -320,7 +315,6 @@ static int64_t timespec_delta_ns(FAR const struct timespec *ts1, delta_s = ts1->tv_sec - ts2->tv_sec; -#ifdef CONFIG_SYSTEM_TIME64 /* Conversion to nanoseconds could overflow if the system time is 64-bit */ if (delta_s >= INT64_MAX / NSEC_PER_SEC) @@ -331,7 +325,6 @@ static int64_t timespec_delta_ns(FAR const struct timespec *ts1, { return INT64_MIN; } -#endif return delta_s * NSEC_PER_SEC + (ts1->tv_nsec - ts2->tv_nsec); } diff --git a/testing/ostest/semtimed.c b/testing/ostest/semtimed.c index ce3f163c1..2b8fc6648 100644 --- a/testing/ostest/semtimed.c +++ b/testing/ostest/semtimed.c @@ -79,11 +79,7 @@ static void ostest_gettime(struct timespec *tp) printf("ostest_gettime: ERROR: clock_gettime failed\n"); ASSERT(false); } -#ifdef CONFIG_SYSTEM_TIME64 else if (tp->tv_sec < 0 || tp->tv_nsec < 0 || -#else - else if (tp->tv_nsec < 0 || -#endif tp->tv_nsec >= 1000 * 1000 * 1000) { printf("ostest_gettime: ERROR: clock_gettime returned bogus time\n"); From a6477ec8dc38f92e16c2b6632cdcf3320259042f Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 3 May 2026 17:17:05 +0800 Subject: [PATCH 316/568] !apps: replace sclock_t with clock_t and drop redundant time_t/off_t casts Align with the upstream nuttx change that drops the sclock_t alias now that clock_t is itself a signed 64-bit type (int64_t). Beyond the pure sclock_t -> clock_t rename, this commit also removes the now-unnecessary (time_t)-1 / (time_t)0 / (off_t)-1 casts that were papering over the previously-unsigned time_t. Files touched: - examples/alarm/alarm_main.c: sclock_t -> clock_t - netutils/dhcpd/dhcpd.c: sclock_t -> clock_t - netutils/ftpd/ftpd.c: sclock_t -> clock_t - netutils/thttpd/libhttpd.c, netutils/thttpd/tdate_parse.c: drop (time_t)-1 / (time_t)0 / (off_t)-1 sentinel casts - system/resmonitor/filldisk.c, system/zmodem/zm_receive.c: sclock_t -> clock_t - testing/ostest/wdog.c: sclock_t -> clock_t (the bulk of the rename, 30 sites) - testing/testsuites/kernel/syscall/cases/{clock_nanosleep_test, fsync_test,time_test}.c: drop (time_t)-1 casts in the new signed-time_t world No behavioural change. Signed-off-by: Xiang Xiao --- examples/alarm/alarm_main.c | 2 +- netutils/dhcpd/dhcpd.c | 2 +- netutils/ftpd/ftpd.c | 4 +-- netutils/thttpd/libhttpd.c | 16 +++++----- netutils/thttpd/tdate_parse.c | 2 +- system/resmonitor/filldisk.c | 2 +- system/zmodem/zm_receive.c | 2 +- testing/ostest/wdog.c | 30 +++++++++---------- .../syscall/cases/clock_nanosleep_test.c | 2 +- .../kernel/syscall/cases/fsync_test.c | 2 +- .../kernel/syscall/cases/time_test.c | 2 +- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/examples/alarm/alarm_main.c b/examples/alarm/alarm_main.c index d4ab70a80..4b5296f73 100644 --- a/examples/alarm/alarm_main.c +++ b/examples/alarm/alarm_main.c @@ -393,7 +393,7 @@ int main(int argc, FAR char *argv[]) setrel.id = alarmid; setrel.pid = g_alarm_daemon_pid; - setrel.reltime = (time_t)seconds; + setrel.reltime = seconds; setrel.event.sigev_notify = SIGEV_SIGNAL; setrel.event.sigev_signo = CONFIG_EXAMPLES_ALARM_SIGNO; diff --git a/netutils/dhcpd/dhcpd.c b/netutils/dhcpd/dhcpd.c index a166e9123..5d909a2e6 100644 --- a/netutils/dhcpd/dhcpd.c +++ b/netutils/dhcpd/dhcpd.c @@ -661,7 +661,7 @@ static inline bool dhcpd_parseoptions(void) if (optlen >= 6 && optlen < remaining) { memcpy(&tmp, &ptr[DHCPD_OPTION_DATA], 4); - g_state.ds_optleasetime = (time_t)ntohl(tmp); + g_state.ds_optleasetime = ntohl(tmp); } break; diff --git a/netutils/ftpd/ftpd.c b/netutils/ftpd/ftpd.c index fa5eb9284..ded7484d7 100644 --- a/netutils/ftpd/ftpd.c +++ b/netutils/ftpd/ftpd.c @@ -2305,11 +2305,11 @@ static int ftpd_listbuffer(FAR struct ftpd_session_s *session, /* time */ - memcpy(&tm, localtime((FAR const time_t *)&st->st_mtime), sizeof(tm)); + memcpy(&tm, localtime(&st->st_mtime), sizeof(tm)); offset += snprintf(&buffer[offset], buflen - offset, " %s %2u", g_monthtab[tm.tm_mon], tm.tm_mday); now = time(0); - if ((now - st->st_mtime) > (time_t)(60 * 60 * 24 * 180)) + if (now - st->st_mtime > 60 * 60 * 24 * 180) { offset += snprintf(&buffer[offset], buflen - offset, " %5u", tm.tm_year + 1900); diff --git a/netutils/thttpd/libhttpd.c b/netutils/thttpd/libhttpd.c index 19acb562c..1a7d46c13 100644 --- a/netutils/thttpd/libhttpd.c +++ b/netutils/thttpd/libhttpd.c @@ -327,7 +327,7 @@ static void send_mime(httpd_conn *hc, int status, const char *title, (hc->range_end >= hc->range_start) && ((hc->range_end != length - 1) || (hc->range_start != 0)) && - (hc->range_if == (time_t) - 1 || hc->range_if == hc->sb.st_mtime)) + (hc->range_if == -1 || hc->range_if == hc->sb.st_mtime)) { partial_content = 1; status = 206; @@ -340,7 +340,7 @@ static void send_mime(httpd_conn *hc, int status, const char *title, } gettimeofday(&now, NULL); - if (mod == (time_t)0) + if (mod == 0) { mod = now.tv_sec; } @@ -510,7 +510,7 @@ static int send_err_file(httpd_conn *hc, int status, char *title, } send_mime(hc, status, title, "", extraheads, "text/html; charset=%s", - (off_t)-1, (time_t)0); + -1, 0); for (; ; ) { nread = fread(buf, 1, sizeof(buf) - 1, fp); @@ -2421,8 +2421,8 @@ int httpd_get_conn(httpd_server *hs, int listen_fd, httpd_conn *hc) hc->altdir[0] = '\0'; #endif hc->buflen = 0; - hc->if_modified_since = (time_t) - 1; - hc->range_if = (time_t)-1; + hc->if_modified_since = -1; + hc->range_if = -1; hc->contentlength = -1; hc->type = ""; #ifdef CONFIG_THTTPD_VHOST @@ -2926,7 +2926,7 @@ int httpd_parse_request(httpd_conn *hc) { cp = &buf[18]; hc->if_modified_since = tdate_parse(cp); - if (hc->if_modified_since == (time_t) - 1) + if (hc->if_modified_since == -1) { nerr("ERROR: unparsable time: %s\n", cp); } @@ -2973,7 +2973,7 @@ int httpd_parse_request(httpd_conn *hc) { cp = &buf[9]; hc->range_if = tdate_parse(cp); - if (hc->range_if == (time_t) - 1) + if (hc->range_if == -1) { nerr("ERROR: unparsable time: %s\n", cp); } @@ -3521,7 +3521,7 @@ int httpd_start_request(httpd_conn *hc, struct timeval *nowp) send_mime(hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size, hc->sb.st_mtime); } - else if (hc->if_modified_since != (time_t) - 1 && + else if (hc->if_modified_since != -1 && hc->if_modified_since >= hc->sb.st_mtime) { send_mime(hc, 304, err304title, hc->encodings, "", diff --git a/netutils/thttpd/tdate_parse.c b/netutils/thttpd/tdate_parse.c index 2b49d3995..82b55846a 100644 --- a/netutils/thttpd/tdate_parse.c +++ b/netutils/thttpd/tdate_parse.c @@ -348,7 +348,7 @@ time_t tdate_parse(char *str) #endif /* Day of week not yet supported by NuttX */ else { - return (time_t) - 1; + return -1; } if (tm.tm_year > 1900) diff --git a/system/resmonitor/filldisk.c b/system/resmonitor/filldisk.c index de550b47e..6670048b0 100644 --- a/system/resmonitor/filldisk.c +++ b/system/resmonitor/filldisk.c @@ -304,7 +304,7 @@ int main(int argc, FAR char *argv[]) mode = 1; break; case 'i': - interval = (time_t)bytes(optarg); + interval = bytes(optarg); break; case 'b': bufsize = bytes(optarg); diff --git a/system/zmodem/zm_receive.c b/system/zmodem/zm_receive.c index 6818a1fab..19fe6ef18 100644 --- a/system/zmodem/zm_receive.c +++ b/system/zmodem/zm_receive.c @@ -675,7 +675,7 @@ static int zmr_filename(FAR struct zm_state_s *pzm) pzmr->filesize = (off_t)filesize; #ifdef CONFIG_SYSTEM_ZMODEM_TIMESTAMPS - pzmr->timestamp = (time_t)timestamp; + pzmr->timestamp = timestamp; #endif /* Check if we need to send the CRC */ diff --git a/testing/ostest/wdog.c b/testing/ostest/wdog.c index e64f1246f..69e4b1386 100644 --- a/testing/ostest/wdog.c +++ b/testing/ostest/wdog.c @@ -56,7 +56,7 @@ typedef struct wdtest_param_s { FAR struct wdog_s *wdog; - sclock_t interval; + clock_t interval; uint64_t callback_cnt; clock_t triggered_tick; } wdtest_param_t; @@ -79,7 +79,7 @@ static void wdtest_callback(wdparm_t param) wdtest_param->callback_cnt += 1; } -static void wdtest_checkdelay(sclock_t diff, sclock_t delay_tick) +static void wdtest_checkdelay(clock_t diff, clock_t delay_tick) { /* Ensure the watchdog trigger time is not earlier than expected. */ @@ -97,13 +97,13 @@ static void wdtest_checkdelay(sclock_t diff, sclock_t delay_tick) } static void wdtest_once(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, - sclock_t delay_ns) + clock_t delay_ns) { uint64_t cnt; - sclock_t diff; + clock_t diff; clock_t wdset_tick; irqstate_t flags; - sclock_t delay_tick = (sclock_t)NSEC2TICK((clock_t)delay_ns); + clock_t delay_tick = NSEC2TICK(delay_ns); wdtest_printf("wdtest_once %lld ns\n", (long long)delay_ns); @@ -133,20 +133,20 @@ static void wdtest_once(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, /* Check if the delay is within the acceptable tolerance. */ - diff = (sclock_t)(param->triggered_tick - wdset_tick); + diff = param->triggered_tick - wdset_tick; wdtest_checkdelay(diff, delay_tick); } static void wdtest_rand(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, - sclock_t rand_ns) + clock_t rand_ns) { uint64_t cnt; int idx; - sclock_t delay_ns; + clock_t delay_ns; clock_t wdset_tick; - sclock_t delay_tick; - sclock_t diff; + clock_t delay_tick; + clock_t diff; irqstate_t flags = 0; /* Perform multiple iterations with random delays. */ @@ -190,7 +190,7 @@ static void wdtest_rand(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, if (cnt % 2) { - diff = (sclock_t)(param->triggered_tick - wdset_tick); + diff = param->triggered_tick - wdset_tick; wdtest_checkdelay(diff, delay_tick); } } @@ -204,7 +204,7 @@ static void wdtest_rand(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, static void wdtest_callback_recursive(wdparm_t param) { FAR wdtest_param_t *wdtest_param = (FAR wdtest_param_t *)param; - sclock_t interval = wdtest_param->interval; + clock_t interval = wdtest_param->interval; wdtest_param->callback_cnt += 1; wdtest_param->triggered_tick = clock_systime_ticks(); @@ -215,7 +215,7 @@ static void wdtest_callback_recursive(wdparm_t param) static void wdtest_recursive(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, - sclock_t delay_ns, + clock_t delay_ns, unsigned int times) { uint64_t cnt; @@ -227,7 +227,7 @@ static void wdtest_recursive(FAR struct wdog_s *wdog, cnt = param->callback_cnt; param->wdog = wdog; - param->interval = (sclock_t)NSEC2TICK((clock_t)delay_ns); + param->interval = NSEC2TICK(delay_ns); wdtest_assert(param->interval >= 0); @@ -253,7 +253,7 @@ static void wdtest_recursive(FAR struct wdog_s *wdog, static void wdog_test_run(FAR wdtest_param_t *param) { uint64_t cnt; - sclock_t rest; + clock_t rest; clock_t delay; struct wdog_s test_wdog = { diff --git a/testing/testsuites/kernel/syscall/cases/clock_nanosleep_test.c b/testing/testsuites/kernel/syscall/cases/clock_nanosleep_test.c index 6ae37f7da..dacb6076b 100644 --- a/testing/testsuites/kernel/syscall/cases/clock_nanosleep_test.c +++ b/testing/testsuites/kernel/syscall/cases/clock_nanosleep_test.c @@ -55,7 +55,7 @@ void test_nuttx_syscall_clocknanosleep01(FAR void **state) ret = clock_nanosleep(type, 0, &t, NULL); assert_int_equal(ret, 0); end_time = clock(); - assert_int_equal((time_t)(end_time - start_time) / CLOCKS_PER_SEC, + assert_int_equal((end_time - start_time) / CLOCKS_PER_SEC, t.tv_sec); } diff --git a/testing/testsuites/kernel/syscall/cases/fsync_test.c b/testing/testsuites/kernel/syscall/cases/fsync_test.c index e2834f861..d84f17937 100644 --- a/testing/testsuites/kernel/syscall/cases/fsync_test.c +++ b/testing/testsuites/kernel/syscall/cases/fsync_test.c @@ -238,7 +238,7 @@ void test_nuttx_syscall_fsync03(FAR void **state) ret = fsync(fd); time_end = time(0); - assert_true(time_end != (time_t)-1); + assert_true(time_end != -1); assert_int_not_equal(ret, -1); assert_int_equal(ret, 0); assert_false(time_end < time_start); diff --git a/testing/testsuites/kernel/syscall/cases/time_test.c b/testing/testsuites/kernel/syscall/cases/time_test.c index a5aea7653..1d9b35119 100644 --- a/testing/testsuites/kernel/syscall/cases/time_test.c +++ b/testing/testsuites/kernel/syscall/cases/time_test.c @@ -57,7 +57,7 @@ void test_nuttx_syscall_time01(FAR void **state) /* check return code */ - assert_int_not_equal(ret, (time_t)-1); + assert_int_not_equal(ret, -1); } } From 275a083464fd08209fd54e7372954977dfd45fbd Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Tue, 12 May 2026 09:22:51 +0200 Subject: [PATCH 317/568] ci: retry git clone for nuttx-ntfc-testing github infra is not stable so even "git clone" from github repos can fail with error: 500. With this commit we try to clone repo few more times. Signed-off-by: raiden00pl --- .github/workflows/build.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 05735c18d..4fe967a7e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -197,7 +197,18 @@ jobs: cd /github/workspace/nuttx-ntfc # get NTFC test cases cd external - git clone -b release-0.0.1 https://github.com/apache/nuttx-ntfc-testing + for i in 1 2 3 4 5; do + git clone -b release-0.0.1 https://github.com/apache/nuttx-ntfc-testing && break + if [ "$i" -eq 5 ]; then + echo "Failed to clone nuttx-ntfc-testing after $i attempts" + exit 1 + fi + + delay=$((i * 10)) + echo "Clone attempt $i failed; retrying in ${delay}s..." + rm -rf nuttx-ntfc-testing + sleep "$delay" + done mv nuttx-ntfc-testing nuttx-testing export NTFCDIR=/github/workspace/nuttx-ntfc From 97485342aa2e983ab566c0731caea59c4dc0df04 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Thu, 23 Apr 2026 21:59:12 +0800 Subject: [PATCH 318/568] netlib_ipv6route.c: fix the issue of parsing IPv6 routing entries Update the column ruler and field labels in route_ipv6_entry comment to match the actual output: lowercase to uppercase, remove colons. Consistent with Nuttx definition Signed-off-by: zhanghongyu --- netutils/netlib/netlib_ipv6route.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/netutils/netlib/netlib_ipv6route.c b/netutils/netlib/netlib_ipv6route.c index a0e10fa7c..14bcc2e9f 100644 --- a/netutils/netlib/netlib_ipv6route.c +++ b/netutils/netlib/netlib_ipv6route.c @@ -49,14 +49,14 @@ /* The form of the entry from the routing table file: * - * 11111111112222222222333333333344444444445555 - * 12345678901234567890123456789012345678901234567890123 - * nnnn. target: xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx - * netmask: xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx - * router: xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx + * 1111111111222222222233333333334444444444555 + * 1234567890123456789012345678901234567890123456789012 + * nnnn. TARGET xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx + * NETMASK xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx + * ROUTER xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx */ -#define ADDR_OFFSET 15 +#define ADDR_OFFSET 14 /**************************************************************************** * Private Functions From 5d15d9741814dd198fa9902bdcb18f5f2b8fb839 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Thu, 23 Apr 2026 11:50:53 +0800 Subject: [PATCH 319/568] netlib: replace DNS ping with gateway ping for connectivity check Refactor netlib_check_ipconnectivity() to use gateway/router ping instead of DNS server ping for network connectivity checks. Add IPv6 support. Signed-off-by: zhanghongyu --- include/netutils/netlib.h | 41 ++- netutils/netlib/CMakeLists.txt | 4 +- netutils/netlib/Makefile | 4 +- netutils/netlib/netlib_checkifconnectivity.c | 7 +- netutils/netlib/netlib_checkipconnectivity.c | 345 +++++++++++++++++-- 5 files changed, 365 insertions(+), 36 deletions(-) diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index eb3933fe9..d76c93e96 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -561,12 +561,49 @@ int netlib_getifstatistics(FAR const char *ifname, int netlib_check_ifconflict(FAR const char *ifname); #endif -#ifdef CONFIG_NETUTILS_PING +/**************************************************************************** + * Name: netlib_check_ipconnectivity + * + * Description: + * Check network connectivity by pinging a remote IP address. + * If ip is NULL, ping the gateway of each network interface, + * and optionally the routers from the routing table. If ping + * is disabled, just check the status of the IP network card. + * + * Parameters: + * ip The ipv4 address to check, or NULL to ping gateways + * timeout The max timeout of each ping + * retry The retry times of ping + * + * Return: + * nums of remote reply of ping; a negative or ZERO on failure + * + ****************************************************************************/ + int netlib_check_ipconnectivity(FAR const char *ip, int timeout, int retry); + +#ifdef CONFIG_NETUTILS_PING + +/**************************************************************************** + * Name: netlib_check_ifconnectivity + * + * Description: + * Check network connectivity by pinging the default gateway + * of the specified network interface. + * + * Parameters: + * ifname The name of the interface to use + * timeout The timeout of ping + * retry The retry times of ping + * + * Return: + * nums of gateway reply of ping; a negative on failure. + * + ****************************************************************************/ + int netlib_check_ifconnectivity(FAR const char *ifname, int timeout, int retry); #else -#define netlib_check_ipconnectivity(i, t, r) 1 #define netlib_check_ifconnectivity(i, t, r) 1 #endif diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt index 2f0f11e0f..0a6735121 100644 --- a/netutils/netlib/CMakeLists.txt +++ b/netutils/netlib/CMakeLists.txt @@ -158,8 +158,10 @@ if(CONFIG_NETUTILS_NETLIB) list(APPEND SRCS netlib_getiobinfo.c) endif() + list(APPEND SRCS netlib_checkipconnectivity.c) + if(CONFIG_NETUTILS_PING) - list(APPEND SRCS netlib_checkipconnectivity.c netlib_checkifconnectivity.c) + list(APPEND SRCS netlib_checkifconnectivity.c) endif() list(APPEND SRCS netlib_checkhttpconnectivity.c) diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile index 7bba856b7..5867d9190 100644 --- a/netutils/netlib/Makefile +++ b/netutils/netlib/Makefile @@ -157,8 +157,10 @@ ifeq ($(CONFIG_MM_IOB),y) CSRCS += netlib_getiobinfo.c endif +CSRCS += netlib_checkipconnectivity.c + ifeq ($(CONFIG_NETUTILS_PING),y) -CSRCS += netlib_checkipconnectivity.c netlib_checkifconnectivity.c +CSRCS += netlib_checkifconnectivity.c endif CSRCS += netlib_checkhttpconnectivity.c diff --git a/netutils/netlib/netlib_checkifconnectivity.c b/netutils/netlib/netlib_checkifconnectivity.c index bfc06001a..d0bc8c3e3 100644 --- a/netutils/netlib/netlib_checkifconnectivity.c +++ b/netutils/netlib/netlib_checkifconnectivity.c @@ -48,7 +48,8 @@ * Name: netlib_check_ifconnectivity * * Description: - * Check network interface connectivity by pinging the gateway + * Check network connectivity by pinging the default gateway + * of the specified network interface. * * Parameters: * ifname The name of the interface to use @@ -56,7 +57,7 @@ * retry The retry times of ping * * Return: - * nums of gateway reply of ping; a nagtive on failure. + * nums of gateway reply of ping; a negative on failure. * ****************************************************************************/ @@ -86,4 +87,4 @@ int netlib_check_ifconnectivity(FAR const char *ifname, return netlib_check_ipconnectivity(destip, timeout, retry); } -#endif /* CONFIG_NETUTILS_PING */ \ No newline at end of file +#endif /* CONFIG_NETUTILS_PING */ diff --git a/netutils/netlib/netlib_checkipconnectivity.c b/netutils/netlib/netlib_checkipconnectivity.c index 04b3c3c0b..ce1a334b8 100644 --- a/netutils/netlib/netlib_checkipconnectivity.c +++ b/netutils/netlib/netlib_checkipconnectivity.c @@ -32,20 +32,22 @@ #include #include #include +#include #include #include -#include "netutils/icmp_ping.h" #include "netutils/netlib.h" - -#ifdef CONFIG_NETUTILS_PING +#include "netutils/icmp_ping.h" +#include "netutils/icmpv6_ping.h" /**************************************************************************** * Private Data ****************************************************************************/ -#define PING_IPADDR_DATALEN 80 +#define PING_IPADDR_DATALEN 56 + +#ifdef CONFIG_NETUTILS_PING /**************************************************************************** * Private Functions @@ -72,6 +74,243 @@ static void ping_ipaddr_callback(FAR const struct ping_result_s *result) } } +#endif /* CONFIG_NETUTILS_PING */ + +#ifdef CONFIG_NETUTILS_PING6 + +/**************************************************************************** + * Name: ping6_ipaddr_callback + * + * Description: + * ping6 ipaddr callback + * + * Parameters: + * result The result of ping6 + * + ****************************************************************************/ + +static void ping6_ipaddr_callback(FAR const struct ping6_result_s *result) +{ + FAR int *count = result->info->priv; + + if (result->code == ICMPv6_I_FINISH) + { + *count = result->nreplies; + } +} + +#endif /* CONFIG_NETUTILS_PING6 */ + +/**************************************************************************** + * Name: ping_gateway + * + * Description: + * Ping the default gateway of each network interface (IPv4 and IPv6). + * + * Parameters: + * info Pointer to the IPv4 ping info structure + * info6 Pointer to the IPv6 ping info structure + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_IFINDEX +static void ping_gateway(FAR struct ping_info_s *info, + FAR struct ping6_info_s *info6) +{ + FAR int *replies = info->priv; + FAR struct ifaddrs *ifap; + FAR struct ifaddrs *ifa; + + if (getifaddrs(&ifap) < 0) + { + return; + } + + for (ifa = ifap; ifa != NULL && *replies == 0; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == NULL) + { + continue; + } + + /* Skip interfaces that are not up and running */ + + if ((ifa->ifa_flags & (IFF_UP | IFF_RUNNING)) != + (IFF_UP | IFF_RUNNING) || (ifa->ifa_flags & IFF_LOOPBACK) != 0) + { + continue; + } + + if (ifa->ifa_addr->sa_family == AF_INET) + { + FAR struct sockaddr_in *sin; + char destip[INET_ADDRSTRLEN]; + + /* Skip interfaces with INADDR_ANY address and loopback flag */ + + sin = (FAR struct sockaddr_in *)ifa->ifa_addr; + if (sin->sin_addr.s_addr == INADDR_ANY) + { + continue; + } + + /* No ARP means point-to-point or tunnel, treat as reachable */ + + if ((ifa->ifa_flags & IFF_NOARP) != 0) + { + (*replies)++; + break; + } + + sin = (FAR struct sockaddr_in *)ifa->ifa_dstaddr; + if (sin == NULL || + sin->sin_family != AF_INET || + sin->sin_addr.s_addr == INADDR_ANY) + { + continue; + } + + inet_ntop(AF_INET, &sin->sin_addr, destip, sizeof(destip)); + ninfo("ping gateway %s on %s\n", destip, ifa->ifa_name); + info->hostname = destip; +#ifdef CONFIG_NETUTILS_PING + icmp_ping(info); +#else + (*replies)++; +#endif + } + else if (ifa->ifa_addr->sa_family == AF_INET6) + { + FAR struct sockaddr_in6 *sin6; + char destip[INET6_ADDRSTRLEN]; + + /* Skip interfaces with unspecified address and loopback flag */ + + sin6 = (FAR struct sockaddr_in6 *)ifa->ifa_addr; + if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) + { + continue; + } + + /* No ARP means point-to-point or tunnel, treat as reachable */ + + if ((ifa->ifa_flags & IFF_NOARP) != 0) + { + (*replies)++; + break; + } + + sin6 = (FAR struct sockaddr_in6 *)ifa->ifa_dstaddr; + if (sin6 == NULL || + sin6->sin6_family != AF_INET6 || + IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) + { + continue; + } + + inet_ntop(AF_INET6, &sin6->sin6_addr, destip, sizeof(destip)); + ninfo("ping6 gateway %s on %s\n", destip, ifa->ifa_name); + info6->hostname = destip; +#ifdef CONFIG_NETUTILS_PING6 + icmp6_ping(info6); +#else + (*replies)++; +#endif + } + } + + freeifaddrs(ifap); +} +#endif /* CONFIG_NETDEV_IFINDEX */ + +/**************************************************************************** + * Name: ping_route + * + * Description: + * Ping the router addresses from the IPv4 routing table. + * + * Parameters: + * info Pointer to the ping info structure + * + ****************************************************************************/ + +#if defined(HAVE_ROUTE_PROCFS) && defined(CONFIG_NETUTILS_PING) +static void ping_route(FAR struct ping_info_s *info) +{ + FAR int *replies = info->priv; + FAR FILE *stream; + struct netlib_ipv4_route_s route; + + stream = netlib_open_ipv4route(); + if (stream == NULL) + { + return; + } + + while (*replies == 0 && netlib_read_ipv4route(stream, &route) > 0) + { + char destip[INET_ADDRSTRLEN]; + + if (route.router == INADDR_ANY) + { + continue; + } + + inet_ntop(AF_INET, &route.router, destip, sizeof(destip)); + ninfo("ping route gateway %s\n", destip); + info->hostname = destip; + icmp_ping(info); + } + + netlib_close_ipv4route(stream); +} +#endif /* HAVE_ROUTE_PROCFS && CONFIG_NETUTILS_PING */ + +/**************************************************************************** + * Name: ping6_route + * + * Description: + * Ping the router addresses from the IPv6 routing table. + * + * Parameters: + * info6 Pointer to the ping6 info structure + * + ****************************************************************************/ + +#if defined(HAVE_ROUTE_PROCFS) && defined(CONFIG_NETUTILS_PING6) +static void ping6_route(FAR struct ping6_info_s *info6) +{ + FAR int *replies = info6->priv; + FAR FILE *stream; + struct netlib_ipv6_route_s route; + + stream = netlib_open_ipv6route(); + if (stream == NULL) + { + return; + } + + while (*replies == 0 && netlib_read_ipv6route(stream, &route) > 0) + { + char destip[INET6_ADDRSTRLEN]; + struct in6_addr router; + + memcpy(&router, route.router, sizeof(router)); + if (IN6_IS_ADDR_UNSPECIFIED(&router)) + { + continue; + } + + inet_ntop(AF_INET6, &router, destip, sizeof(destip)); + ninfo("ping6 route gateway %s\n", destip); + info6->hostname = destip; + icmp6_ping(info6); + } + + netlib_close_ipv6route(stream); +} +#endif /* HAVE_ROUTE_PROCFS && CONFIG_NETUTILS_PING6 */ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -80,59 +319,107 @@ static void ping_ipaddr_callback(FAR const struct ping_result_s *result) * Name: netlib_check_ipconnectivity * * Description: - * Get the network dns status + * Check network connectivity by pinging a remote IP address. + * If ip is NULL, ping the gateway of each network interface, + * and optionally the routers from the routing table. If ping + * is disabled, just check the status of the IP network card. * * Parameters: - * ip The ipv4 address to check + * ip The ipv4 address to check, or NULL to ping gateways * timeout The max timeout of each ping * retry The retry times of ping * * Return: - * nums of remote reply of ping; a nagtive on failure + * nums of remote reply of ping; a negative or ZERO on failure * ****************************************************************************/ int netlib_check_ipconnectivity(FAR const char *ip, int timeout, int retry) { int replies = 0; -#ifdef CONFIG_NETDB_DNSSERVER_IPv4ADDR - char ip_str[INET_ADDRSTRLEN]; - struct in_addr addr; -#endif +#if defined(CONFIG_NETDEV_IFINDEX) || defined(CONFIG_NETUTILS_PING) struct ping_info_s info; +#endif +#if defined(CONFIG_NETDEV_IFINDEX) || defined(CONFIG_NETUTILS_PING6) + struct ping6_info_s info6; +#endif +#ifdef CONFIG_NETUTILS_PING info.count = retry; info.datalen = PING_IPADDR_DATALEN; info.delay = 0; info.timeout = timeout; info.callback = ping_ipaddr_callback; - info.priv = &replies; -#ifdef CONFIG_NET_BINDTODEVICE + info.hostname = ip; +# ifdef CONFIG_NET_BINDTODEVICE info.devname = NULL; +# endif +#endif +#if defined(CONFIG_NETDEV_IFINDEX) || defined(CONFIG_NETUTILS_PING) + info.priv = &replies; #endif - /* if ip is NULL we use default DNS server */ +#ifdef CONFIG_NETUTILS_PING6 + info6.count = retry; + info6.datalen = PING_IPADDR_DATALEN; + info6.delay = 0; + info6.timeout = timeout; + info6.hostname = ip; + info6.callback = ping6_ipaddr_callback; +# ifdef CONFIG_NET_BINDTODEVICE + info6.devname = NULL; +# endif +#endif +#if defined(CONFIG_NETDEV_IFINDEX) || defined(CONFIG_NETUTILS_PING6) + info6.priv = &replies; +#endif - if (ip == NULL) + if (ip != NULL) { -#ifdef CONFIG_NETDB_DNSSERVER_IPv4ADDR - addr.s_addr = HTONL(CONFIG_NETDB_DNSSERVER_IPv4ADDR); - inet_ntop(AF_INET, &addr, ip_str, INET_ADDRSTRLEN); - info.hostname = ip_str; + struct in6_addr addr6; + + ninfo("ping ipaddr test %s\n", ip); + if (inet_pton(AF_INET6, ip, &addr6) == 1) + { +#ifdef CONFIG_NETUTILS_PING6 + icmp6_ping(&info6); + return replies; #else - nerr("ERROR: IP is NULL and no DNS server configured\n"); - return -EINVAL; + /* Fallback to network card status check */ #endif - } - else - { - info.hostname = ip; + } + else + { +#ifdef CONFIG_NETUTILS_PING + icmp_ping(&info); + return replies; +#else + /* Fallback to network card status check */ +#endif + } } - ninfo("ping ipaddr test %s \n", info.hostname); - icmp_ping(&info); +#ifdef CONFIG_NETDEV_IFINDEX + ping_gateway(&info, &info6); +#endif + +#if defined(HAVE_ROUTE_PROCFS) && defined(CONFIG_NETUTILS_PING) + if (replies == 0) + { + ping_route(&info); + } +#endif + +#if defined(HAVE_ROUTE_PROCFS) && defined(CONFIG_NETUTILS_PING6) + if (replies == 0) + { + ping6_route(&info6); + } +#endif + +#if !defined(CONFIG_NETDEV_IFINDEX) && !defined(HAVE_ROUTE_PROCFS) + replies = 1; +#endif return replies; } - -#endif /* CONFIG_NETUTILS_PING */ \ No newline at end of file From 21b28a4126ac1268c9f4d4f41b60247837e1158f Mon Sep 17 00:00:00 2001 From: xiaoxiang781216 Date: Wed, 13 May 2026 18:36:26 +0800 Subject: [PATCH 320/568] testing/ltp: silence -Wshift-count-overflow on -Werror builds The LTP open_posix_testsuite header timespec.h has, since 2019: #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) When time_t is 64 bits (the default after sched/remove-system-time64), the shift reaches the sign bit of the underlying type and toolchains emit -Wshift-count-overflow, which the LTP build promotes to a hard error via -Werror. This breaks rv-virt/citest and rv-virt/citest64 on CI. The diagnostic is benign here (TIME_T_MAX itself is correct) and the defect is in upstream LTP, so disable the warning alongside the other 'should be removed in the future' relaxations until upstream is fixed. Signed-off-by: xiaoxiang781216 --- testing/ltp/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/ltp/Makefile b/testing/ltp/Makefile index c6f712614..39a7d931b 100644 --- a/testing/ltp/Makefile +++ b/testing/ltp/Makefile @@ -238,6 +238,7 @@ CFLAGS += -Wno-int-conversion -Wno-shadow # Should be removed if possible in the future CFLAGS += -Wno-incompatible-pointer-types -Wno-overflow -Wno-int-to-pointer-cast +CFLAGS += -Wno-shift-count-overflow # Specific compilation errors ignored in MacOS platform ifneq ($(CONFIG_HOST_MACOS),) From c10ce6aa4f2578f3fee49f3731eb53b446d02a27 Mon Sep 17 00:00:00 2001 From: Shoji Tokunaga Date: Wed, 13 May 2026 14:08:11 +0900 Subject: [PATCH 321/568] apps/cmake: Make hello_rust_cargo buildable with cmake * Resolve APPDIR. * Remove "debug" from RUST_PROFILE_FLAG. * Add JSON specification compatibility flag. * Correct the directory structure for RUST_LIB_PATH. Signed-off-by: Shoji Tokunaga --- cmake/nuttx_add_rust.cmake | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/cmake/nuttx_add_rust.cmake b/cmake/nuttx_add_rust.cmake index 0d1f09839..3a26bfd16 100644 --- a/cmake/nuttx_add_rust.cmake +++ b/cmake/nuttx_add_rust.cmake @@ -47,6 +47,8 @@ include(nuttx_parse_function_args) # ~~~ function(nuttx_rust_target_triple ARCHTYPE ABITYPE CPUTYPE OUTPUT) + get_filename_component(APPDIR "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/.." + ABSOLUTE) if(ARCHTYPE STREQUAL "x86_64") set(TARGET_TRIPLE "${APPDIR}/tools/x86_64-unknown-nuttx.json") elseif(ARCHTYPE STREQUAL "x86") @@ -127,9 +129,11 @@ function(nuttx_add_rust) # Determine build profile based on CONFIG_DEBUG_FULLOPT if(CONFIG_DEBUG_FULLOPT) + set(RUST_PROFILE_FLAG "--release") set(RUST_PROFILE "release") set(RUST_PANIC_FLAGS "-Zunstable-options -Cpanic=immediate-abort") else() + set(RUST_PROFILE_FLAG "") set(RUST_PROFILE "debug") set(RUST_PANIC_FLAGS "") endif() @@ -145,9 +149,9 @@ function(nuttx_add_rust) set(TARGET_BASE ${RUST_TARGET}) endif() - set(RUST_BUILD_DIR - ${CMAKE_CURRENT_BINARY_DIR}/${CRATE_NAME}/target/${TARGET_BASE}) - set(RUST_LIB_PATH ${RUST_BUILD_DIR}/${RUST_PROFILE}/lib${CRATE_NAME}.a) + set(RUST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CRATE_NAME}/target) + set(RUST_LIB_PATH + ${RUST_BUILD_DIR}/${TARGET_BASE}/${RUST_PROFILE}/lib${CRATE_NAME}.a) # Create build directory file(MAKE_DIRECTORY ${RUST_BUILD_DIR}) @@ -158,9 +162,10 @@ function(nuttx_add_rust) COMMAND ${CMAKE_COMMAND} -E env NUTTX_INCLUDE_DIR=${PROJECT_SOURCE_DIR}/include:${CMAKE_BINARY_DIR}/include:${CMAKE_BINARY_DIR}/include/arch - RUSTFLAGS=${RUST_PANIC_FLAGS} cargo build --${RUST_PROFILE} - -Zbuild-std=std,panic_abort --manifest-path ${CRATE_PATH}/Cargo.toml - --target ${RUST_TARGET} --target-dir ${RUST_BUILD_DIR} + RUSTFLAGS=${RUST_PANIC_FLAGS} cargo build ${RUST_PROFILE_FLAG} + -Zbuild-std=std,panic_abort -Zjson-target-spec --manifest-path + ${CRATE_PATH}/Cargo.toml --target ${RUST_TARGET} --target-dir + ${RUST_BUILD_DIR} COMMENT "Building Rust crate ${CRATE_NAME}" VERBATIM) From bb7c83b01cf7c48d8f4850b9074e3478e62ca08e Mon Sep 17 00:00:00 2001 From: Shoji Tokunaga Date: Sat, 16 May 2026 14:55:38 +0900 Subject: [PATCH 322/568] apps:cmake: Add APPLE to a build target for sim's configuration using CMake. * Add Rust target conversion support for `aarch64` on acOS/Linux (and Linux `arm`). * When a Rust target is unsupported and results in an empty configuration, trigger a CMake `FATAL_ERROR`. Signed-off-by: Shoji Tokunaga --- cmake/nuttx_add_rust.cmake | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cmake/nuttx_add_rust.cmake b/cmake/nuttx_add_rust.cmake index 3a26bfd16..55fce1a8e 100644 --- a/cmake/nuttx_add_rust.cmake +++ b/cmake/nuttx_add_rust.cmake @@ -35,6 +35,7 @@ include(nuttx_parse_function_args) # - riscv64: riscv64imac/imafdc-unknown-nuttx-elf # - x86: i686-unknown-nuttx # - x86_64: x86_64-unknown-nuttx +# - aarch64: aarch64-apple-darwin # # Inputs: # ARCHTYPE - Architecture type (e.g. thumbv7m, riscv32) @@ -53,6 +54,10 @@ function(nuttx_rust_target_triple ARCHTYPE ABITYPE CPUTYPE OUTPUT) set(TARGET_TRIPLE "${APPDIR}/tools/x86_64-unknown-nuttx.json") elseif(ARCHTYPE STREQUAL "x86") set(TARGET_TRIPLE "${APPDIR}/tools/i486-unknown-nuttx.json") + elseif(ARCHTYPE STREQUAL "aarch64") + if(APPLE) + set(TARGET_TRIPLE "aarch64-apple-darwin") + endif() elseif(ARCHTYPE MATCHES "thumb") if(ARCHTYPE MATCHES "thumbv8m") # Extract just the base architecture type (thumbv8m.main or thumbv8m.base) @@ -92,6 +97,13 @@ function(nuttx_rust_target_triple ARCHTYPE ABITYPE CPUTYPE OUTPUT) set(TARGET_TRIPLE "riscv64imac-unknown-nuttx-elf") endif() endif() + + if(NOT TARGET_TRIPLE) + message( + FATAL_ERROR + "Unsupported Rust target: LLVM_ARCHTYPE=${ARCHTYPE}, LLVM_ABITYPE=${ABITYPE}, LLVM_CPUTYPE=${CPUTYPE}" + ) + endif() set(${OUTPUT} ${TARGET_TRIPLE} PARENT_SCOPE) From 86fb38fbe42899dd9ccca99a03f9dfcbca36269f Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Sun, 17 May 2026 15:16:15 -0400 Subject: [PATCH 323/568] boot/mcuboot: Update commit version This updates the version of mcuboot used by NuttX now that BOARDIOC_INIT is removed. Signed-off-by: Matteo Golin --- boot/mcuboot/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/mcuboot/Kconfig b/boot/mcuboot/Kconfig index 271c986e7..656861d73 100644 --- a/boot/mcuboot/Kconfig +++ b/boot/mcuboot/Kconfig @@ -22,7 +22,7 @@ config MCUBOOT_REPOSITORY config MCUBOOT_VERSION string "MCUboot version" - default "457be0cf3fb03e9e09938728dece8f03309db973" + default "e36d3c8d6ca5e0ed1f510f2a7d110f405a7c396b" ---help--- Defines MCUboot version to be downloaded. Either release tag or commit hash should be specified. Using newer MCUboot version From 8bd66150344846b3d28112690ac9d381e6327406 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 11 May 2026 11:15:18 +0200 Subject: [PATCH 324/568] examples/pwm: remove references to CONFIG_PWM_MULTICHAN remove references to CONFIG_PWM_MULTICHAN Signed-off-by: raiden00pl --- examples/pwm/Kconfig | 18 +---- examples/pwm/pwm.h | 10 ++- examples/pwm/pwm_main.c | 151 +++++++++++++++------------------------- 3 files changed, 63 insertions(+), 116 deletions(-) diff --git a/examples/pwm/Kconfig b/examples/pwm/Kconfig index 9378003f2..b6e0a3d82 100644 --- a/examples/pwm/Kconfig +++ b/examples/pwm/Kconfig @@ -29,10 +29,7 @@ config EXAMPLES_PWM_DURATION default 5 ---help--- The default PWM pulse train duration in seconds. Used only if the current - pulse count is zero (pulse count is only supported if PWM_PULSECOUNT - is not defined). Default: 5 seconds - -if PWM_MULTICHAN + pulse count is zero. Default: 5 seconds config EXAMPLES_PWM_DUTYPCT1 int "First PWM duty percentage" @@ -138,17 +135,6 @@ config EXAMPLES_PWM_CHANNEL6 endif -endif - -if !PWM_MULTICHAN - -config EXAMPLES_PWM_DUTYPCT - int "Default PWM duty percentage" - default 50 - range 1 99 - ---help--- - The default PWM duty as a percentage. Default: 50% - config EXAMPLES_PWM_PULSECOUNT int "Default pulse count" default 0 @@ -159,5 +145,3 @@ config EXAMPLES_PWM_PULSECOUNT the count). endif - -endif diff --git a/examples/pwm/pwm.h b/examples/pwm/pwm.h index e0447b9b3..d5c15aed9 100644 --- a/examples/pwm/pwm.h +++ b/examples/pwm/pwm.h @@ -40,8 +40,10 @@ * Default: /dev/pwm0 * CONFIG_EXAMPLES_PWM_FREQUENCY - The initial PWM frequency. * Default: 100 Hz - * CONFIG_EXAMPLES_PWM_DUTYPCT - The initial PWM duty as a percentage. - * Default: 50% + * CONFIG_EXAMPLES_PWM_DUTYPCTn - The initial PWM duty as a percentage for + * channel n. Default: 50% + * CONFIG_EXAMPLES_PWM_CHANNELn - The PWM channel number for channel n. + * Default: n * CONFIG_EXAMPLES_PWM_DURATION - The initial PWM pulse train duration * in seconds. Used only if the current pulse count is zero * (pulse count is only supported if CONFIG_PWM_PULSECOUNT is defined). @@ -63,10 +65,6 @@ # define CONFIG_EXAMPLES_PWM_FREQUENCY 100 #endif -#ifndef CONFIG_EXAMPLES_PWM_DUTYPCT -# define CONFIG_EXAMPLES_PWM_DUTYPCT 50 -#endif - #ifndef CONFIG_EXAMPLES_PWM_DURATION # define CONFIG_EXAMPLES_PWM_DURATION 5 #endif diff --git a/examples/pwm/pwm_main.c b/examples/pwm/pwm_main.c index 683587f08..085a36b9e 100644 --- a/examples/pwm/pwm_main.c +++ b/examples/pwm/pwm_main.c @@ -48,46 +48,44 @@ /* Configuration ************************************************************/ -#ifdef CONFIG_PWM_MULTICHAN -# if CONFIG_PWM_NCHANNELS > 1 -# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL2 -# error "Channel numbers must be unique" -# endif +#if CONFIG_PWM_NCHANNELS > 1 +# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL2 +# error "Channel numbers must be unique" # endif -# if CONFIG_PWM_NCHANNELS > 2 -# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL3 || \ +#endif +#if CONFIG_PWM_NCHANNELS > 2 +# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL3 || \ CONFIG_EXAMPLES_PWM_CHANNEL2 == CONFIG_EXAMPLES_PWM_CHANNEL3 -# error "Channel numbers must be unique" -# endif +# error "Channel numbers must be unique" # endif -# if CONFIG_PWM_NCHANNELS > 3 -# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL4 || \ +#endif +#if CONFIG_PWM_NCHANNELS > 3 +# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL4 || \ CONFIG_EXAMPLES_PWM_CHANNEL2 == CONFIG_EXAMPLES_PWM_CHANNEL4 || \ CONFIG_EXAMPLES_PWM_CHANNEL3 == CONFIG_EXAMPLES_PWM_CHANNEL4 -# error "Channel numbers must be unique" -# endif +# error "Channel numbers must be unique" # endif -# if CONFIG_PWM_NCHANNELS > 4 -# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL5 || \ +#endif +#if CONFIG_PWM_NCHANNELS > 4 +# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL5 || \ CONFIG_EXAMPLES_PWM_CHANNEL2 == CONFIG_EXAMPLES_PWM_CHANNEL5 || \ CONFIG_EXAMPLES_PWM_CHANNEL3 == CONFIG_EXAMPLES_PWM_CHANNEL5 || \ CONFIG_EXAMPLES_PWM_CHANNEL4 == CONFIG_EXAMPLES_PWM_CHANNEL5 -# error "Channel numbers must be unique" -# endif +# error "Channel numbers must be unique" # endif -# if CONFIG_PWM_NCHANNELS > 5 -# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL6 || \ +#endif +#if CONFIG_PWM_NCHANNELS > 5 +# if CONFIG_EXAMPLES_PWM_CHANNEL1 == CONFIG_EXAMPLES_PWM_CHANNEL6 || \ CONFIG_EXAMPLES_PWM_CHANNEL2 == CONFIG_EXAMPLES_PWM_CHANNEL6 || \ CONFIG_EXAMPLES_PWM_CHANNEL3 == CONFIG_EXAMPLES_PWM_CHANNEL6 || \ CONFIG_EXAMPLES_PWM_CHANNEL4 == CONFIG_EXAMPLES_PWM_CHANNEL6 || \ CONFIG_EXAMPLES_PWM_CHANNEL5 == CONFIG_EXAMPLES_PWM_CHANNEL6 -# error "Channel numbers must be unique" -# endif -# endif -# if CONFIG_PWM_NCHANNELS > 6 -# error "Too many PWM channels" +# error "Channel numbers must be unique" # endif #endif +#if CONFIG_PWM_NCHANNELS > 6 +# error "Too many PWM channels" +#endif /**************************************************************************** * Private Types @@ -97,12 +95,8 @@ struct pwm_state_s { bool initialized; FAR char *devpath; -#ifdef CONFIG_PWM_MULTICHAN - uint8_t channels[CONFIG_PWM_NCHANNELS]; + int8_t channels[CONFIG_PWM_NCHANNELS]; uint8_t duties[CONFIG_PWM_NCHANNELS]; -#else - uint8_t duty; -#endif uint32_t freq; #ifdef CONFIG_PWM_PULSECOUNT uint32_t count; @@ -152,49 +146,47 @@ static void pwm_devpath(FAR struct pwm_state_s *pwm, FAR const char *devpath) static void pwm_help(FAR struct pwm_state_s *pwm) { -#ifdef CONFIG_PWM_MULTICHAN - uint8_t channels[CONFIG_PWM_NCHANNELS] = - { - CONFIG_EXAMPLES_PWM_CHANNEL1, + int8_t channels[CONFIG_PWM_NCHANNELS] = + { + CONFIG_EXAMPLES_PWM_CHANNEL1, #if CONFIG_PWM_NCHANNELS > 1 - CONFIG_EXAMPLES_PWM_CHANNEL2, + CONFIG_EXAMPLES_PWM_CHANNEL2, #endif #if CONFIG_PWM_NCHANNELS > 2 - CONFIG_EXAMPLES_PWM_CHANNEL3, + CONFIG_EXAMPLES_PWM_CHANNEL3, #endif #if CONFIG_PWM_NCHANNELS > 3 - CONFIG_EXAMPLES_PWM_CHANNEL4, + CONFIG_EXAMPLES_PWM_CHANNEL4, #endif #if CONFIG_PWM_NCHANNELS > 4 - CONFIG_EXAMPLES_PWM_CHANNEL5, + CONFIG_EXAMPLES_PWM_CHANNEL5, #endif #if CONFIG_PWM_NCHANNELS > 5 - CONFIG_EXAMPLES_PWM_CHANNEL6, + CONFIG_EXAMPLES_PWM_CHANNEL6, #endif - }; + }; uint8_t duties[CONFIG_PWM_NCHANNELS] = - { - CONFIG_EXAMPLES_PWM_DUTYPCT1, + { + CONFIG_EXAMPLES_PWM_DUTYPCT1, #if CONFIG_PWM_NCHANNELS > 1 - CONFIG_EXAMPLES_PWM_DUTYPCT2, + CONFIG_EXAMPLES_PWM_DUTYPCT2, #endif #if CONFIG_PWM_NCHANNELS > 2 - CONFIG_EXAMPLES_PWM_DUTYPCT3, + CONFIG_EXAMPLES_PWM_DUTYPCT3, #endif #if CONFIG_PWM_NCHANNELS > 3 - CONFIG_EXAMPLES_PWM_DUTYPCT4, + CONFIG_EXAMPLES_PWM_DUTYPCT4, #endif #if CONFIG_PWM_NCHANNELS > 4 - CONFIG_EXAMPLES_PWM_DUTYPCT5, + CONFIG_EXAMPLES_PWM_DUTYPCT5, #endif #if CONFIG_PWM_NCHANNELS > 5 - CONFIG_EXAMPLES_PWM_DUTYPCT6, + CONFIG_EXAMPLES_PWM_DUTYPCT6, #endif - }; + }; int i; -#endif printf("Usage: pwm [OPTIONS]\n"); printf("\nArguments are \"sticky\". " @@ -207,7 +199,6 @@ static void pwm_help(FAR struct pwm_state_s *pwm) printf(" [-f frequency] selects the pulse frequency. " "Default: %d Hz Current: %" PRIu32 " Hz\n", CONFIG_EXAMPLES_PWM_FREQUENCY, pwm->freq); -#ifdef CONFIG_PWM_MULTICHAN printf(" [[-c channel1] [[-c channel2] ...]] " "selects the channel number for each channel. "); printf("Default:"); @@ -239,11 +230,6 @@ static void pwm_help(FAR struct pwm_state_s *pwm) } printf("\n"); -#else - printf(" [-d duty] selects the pulse duty as a percentage. " - "Default: %d %% Current: %d %%\n", - CONFIG_EXAMPLES_PWM_DUTYPCT, pwm->duty); -#endif #ifdef CONFIG_PWM_PULSECOUNT printf(" [-n count] selects the pulse count. " "Default: %d Current: %" PRIx32 "\n", @@ -301,10 +287,10 @@ static void parse_args(FAR struct pwm_state_s *pwm, int argc, long value; int index; int nargs; -#ifdef CONFIG_PWM_MULTICHAN +#if CONFIG_PWM_NCHANNELS > 1 int nchannels = 0; - int nduties = 0; #endif + int nduties = 0; for (index = 1; index < argc; ) { @@ -329,7 +315,7 @@ static void parse_args(FAR struct pwm_state_s *pwm, int argc, index += nargs; break; -#ifdef CONFIG_PWM_MULTICHAN +#if CONFIG_PWM_NCHANNELS > 1 case 'c': nargs = arg_decimal(&argv[index], &value); if (value < -1 || value > CONFIG_PWM_NCHANNELS) @@ -361,7 +347,6 @@ static void parse_args(FAR struct pwm_state_s *pwm, int argc, exit(1); } -#ifdef CONFIG_PWM_MULTICHAN if (nduties < CONFIG_PWM_NCHANNELS) { nduties++; @@ -373,9 +358,6 @@ static void parse_args(FAR struct pwm_state_s *pwm, int argc, } pwm->duties[nduties - 1] = (uint8_t)value; -#else - pwm->duty = (uint8_t)value; -#endif index += nargs; break; @@ -436,16 +418,13 @@ int main(int argc, FAR char *argv[]) struct pwm_info_s info; int fd; int ret; -#ifdef CONFIG_PWM_MULTICHAN int i; int j; -#endif /* Initialize the state data */ if (!g_pwmstate.initialized) { -#ifdef CONFIG_PWM_MULTICHAN g_pwmstate.channels[0] = CONFIG_EXAMPLES_PWM_CHANNEL1; g_pwmstate.duties[0] = CONFIG_EXAMPLES_PWM_DUTYPCT1; #if CONFIG_PWM_NCHANNELS > 1 @@ -467,9 +446,6 @@ int main(int argc, FAR char *argv[]) #if CONFIG_PWM_NCHANNELS > 5 g_pwmstate.channels[5] = CONFIG_EXAMPLES_PWM_CHANNEL6; g_pwmstate.duties[5] = CONFIG_EXAMPLES_PWM_DUTYPCT6; -#endif -#else - g_pwmstate.duty = CONFIG_EXAMPLES_PWM_DUTYPCT; #endif g_pwmstate.freq = CONFIG_EXAMPLES_PWM_FREQUENCY; g_pwmstate.duration = CONFIG_EXAMPLES_PWM_DURATION; @@ -483,19 +459,23 @@ int main(int argc, FAR char *argv[]) parse_args(&g_pwmstate, argc, argv); -#ifdef CONFIG_PWM_MULTICHAN - for (i = 0; i < CONFIG_PWM_MULTICHAN; i++) + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) { - for (j = i + 1; j < CONFIG_PWM_MULTICHAN; j++) + if (g_pwmstate.channels[i] < 1) { - if (g_pwmstate.channels[j] == g_pwmstate.channels[i]) + continue; + } + + for (j = i + 1; j < CONFIG_PWM_NCHANNELS; j++) + { + if (g_pwmstate.channels[j] > 0 && + g_pwmstate.channels[j] == g_pwmstate.channels[i]) { printf("pwm_main: channel numbers must be unique\n"); goto errout; } } } -#endif /* Has a device been assigned? */ @@ -517,8 +497,8 @@ int main(int argc, FAR char *argv[]) /* Configure the characteristics of the pulse train */ + memset(&info, 0, sizeof(info)); info.frequency = g_pwmstate.freq; -#ifdef CONFIG_PWM_MULTICHAN printf("pwm_main: starting output with frequency: %" PRIu32, info.frequency); @@ -531,26 +511,11 @@ int main(int argc, FAR char *argv[]) info.channels[i].channel, info.channels[i].duty); } - printf("\n"); - -#else - info.duty = g_pwmstate.duty ? \ - b16divi(uitoub16(g_pwmstate.duty) - 1, 100) : 0; -# ifdef CONFIG_PWM_PULSECOUNT - info.count = g_pwmstate.count; - - printf("pwm_main: starting output " - "with frequency: %" PRIu32 " duty: %08" PRIx32 - " count: %" PRIx32 "\n", - info.frequency, (uint32_t)info.duty, info.count); - -# else - printf("pwm_main: starting output " - "with frequency: %" PRIu32 " duty: %08" PRIx32 "\n", - info.frequency, (uint32_t)info.duty); - -# endif +#ifdef CONFIG_PWM_PULSECOUNT + info.channels[0].count = g_pwmstate.count; + printf(" count: %" PRIx32, info.channels[0].count); #endif + printf("\n"); ret = ioctl(fd, PWMIOC_SETCHARACTERISTICS, (unsigned long)((uintptr_t)&info)); @@ -577,7 +542,7 @@ int main(int argc, FAR char *argv[]) */ #ifdef CONFIG_PWM_PULSECOUNT - if (info.count == 0) + if (info.channels[0].count == 0) #endif { /* Wait for the specified duration */ From 2fce07fe1ccc295ffeec3d63dee2de8dcc9d4b89 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 11 May 2026 11:15:41 +0200 Subject: [PATCH 325/568] testing/drivertest_pwm: remove references to CONFIG_PWM_MULTICHAN remove references to CONFIG_PWM_MULTICHAN Signed-off-by: raiden00pl --- testing/drivers/drivertest/drivertest_pwm.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/testing/drivers/drivertest/drivertest_pwm.c b/testing/drivers/drivertest/drivertest_pwm.c index 3dd3bae64..7b08f9a24 100644 --- a/testing/drivers/drivertest/drivertest_pwm.c +++ b/testing/drivers/drivertest/drivertest_pwm.c @@ -164,11 +164,11 @@ static void parse_commandline(FAR struct pwm_state_s *pwm_state, int argc, OPTARG_TO_VALUE(converted, uint32_t, 10); if (converted < 0) { - printf("Count must be non-negative: %ld\n", converted); + printf("Count must be non-negative: %d\n", converted); pwm_help(argv[0], pwm_state, EXIT_FAILURE); } - pwm_state->count = (uint32_t)value; + pwm_state->count = (uint32_t)converted; break; #endif case 'f': @@ -223,9 +223,7 @@ static void drivertest_pwm(FAR void **state) { int fd; int ret; -#ifdef CONFIG_PWM_MULTICHAN int i; -#endif struct pwm_info_s info; FAR struct pwm_state_s *pwm_state; pwm_state = (FAR struct pwm_state_s *)*state; @@ -241,18 +239,14 @@ static void drivertest_pwm(FAR void **state) info.frequency = pwm_state->freq; -#ifdef CONFIG_PWM_MULTICHAN for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) { info.channels[i].channel = i + 1; info.channels[i].duty = b16divi(uitoub16(pwm_state->duty), 100); } -#else - info.duty = b16divi(uitoub16(pwm_state->duty), 100); -#endif #ifdef CONFIG_PWM_PULSECOUNT - info.count = pwm_state.count; + info.channels[0].count = pwm_state->count; #endif ret = ioctl(fd, PWMIOC_SETCHARACTERISTICS, @@ -271,7 +265,7 @@ static void drivertest_pwm(FAR void **state) */ #ifdef CONFIG_PWM_PULSECOUNT - if (info.count == 0) + if (info.channels[0].count == 0) #endif { /* Wait for the specified duration */ From 8ba84edb0ac6772ac67e4c78d14044435dd90d75 Mon Sep 17 00:00:00 2001 From: Tiago Medicci Date: Fri, 8 May 2026 13:54:17 -0300 Subject: [PATCH 326/568] interpreters/python: Enable using `pip` to install Python packages This commit enables using `pip` as a pre-compiled (pyc) built-in distributed along with cpython. Signed-off-by: Tiago Medicci --- interpreters/python/Kconfig | 17 +++ interpreters/python/Make.defs | 2 + interpreters/python/Makefile | 38 ++++- interpreters/python/Setup.local.in | 10 -- interpreters/python/config.site.in | 11 +- ...015-keep-ensurepip-in-stdlib-archive.patch | 25 ++++ ...offset-check-when-time-t-is-unsigned.patch | 21 +++ ...ep-pydecimal-and-trim-tooling-extras.patch | 35 +++++ ...0018-ignore-chmod-on-nuttx-like-wasi.patch | 25 ++++ interpreters/python/python_wrapper.c | 2 + interpreters/python/repack_wheel_add_pyc.py | 139 ++++++++++++++++++ 11 files changed, 313 insertions(+), 12 deletions(-) create mode 100644 interpreters/python/patch/0015-keep-ensurepip-in-stdlib-archive.patch create mode 100644 interpreters/python/patch/0016-fix-timezone-offset-check-when-time-t-is-unsigned.patch create mode 100644 interpreters/python/patch/0017-stdlib-zip-keep-pydecimal-and-trim-tooling-extras.patch create mode 100644 interpreters/python/patch/0018-ignore-chmod-on-nuttx-like-wasi.patch create mode 100644 interpreters/python/repack_wheel_add_pyc.py diff --git a/interpreters/python/Kconfig b/interpreters/python/Kconfig index dfc3f5ee8..dfc5fd4cc 100644 --- a/interpreters/python/Kconfig +++ b/interpreters/python/Kconfig @@ -37,4 +37,21 @@ config INTERPRETERS_CPYTHON_PROGNAME ---help--- This is the name of the program that will be used from the nsh. +config INTERPRETERS_CPYTHON_ENABLE_PIP + bool "Enable bundled pip" + default n + ---help--- + Enable bundling pip into the CPython module image. When enabled, the + build downloads the pip wheel and pre-installs it through a + site-packages .pth entry that points to ensurepip's bundled wheel. + Disable this to skip pip wheel download/integration entirely. + + +config INTERPRETERS_CPYTHON_PYTHONPATH + string "CPython Python path" + default "/tmp" + ---help--- + This is the Python default search path for modules files. This is + required to be a writable path. + endif diff --git a/interpreters/python/Make.defs b/interpreters/python/Make.defs index c02973e5a..dceeb5267 100644 --- a/interpreters/python/Make.defs +++ b/interpreters/python/Make.defs @@ -27,6 +27,8 @@ CPYTHON_VERSION_MINOR=$(basename $(CPYTHON_VERSION)) EXTRA_LIBPATHS += -L$(APPDIR)/interpreters/python/install/target EXTRA_LIBS += -lpython$(CPYTHON_VERSION_MINOR) +EXTRA_LIBS += $(APPDIR)/interpreters/python/build/target/Modules/_hacl/libHacl_Hash_SHA2.a +EXTRA_LIBS += $(APPDIR)/interpreters/python/build/target/Modules/expat/libexpat.a CONFIGURED_APPS += $(APPDIR)/interpreters/python endif diff --git a/interpreters/python/Makefile b/interpreters/python/Makefile index 954f07b30..a339bbe02 100644 --- a/interpreters/python/Makefile +++ b/interpreters/python/Makefile @@ -84,6 +84,10 @@ $(CPYTHON_UNPACKNAME): $(CPYTHON_ZIP) $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0012-hack-place-_PyRuntime-structure-into-PSRAM-bss-regio.patch $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0013-transform-functions-used-by-NuttX-to-lowercase.patch $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0014-insert-prefix-to-list_length-to-avoid-symbol-collisi.patch + $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0015-keep-ensurepip-in-stdlib-archive.patch + $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0016-fix-timezone-offset-check-when-time-t-is-unsigned.patch + $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0017-stdlib-zip-keep-pydecimal-and-trim-tooling-extras.patch + $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0018-ignore-chmod-on-nuttx-like-wasi.patch $(HOSTPYTHON): mkdir -p $(HOSTBUILD) @@ -92,6 +96,7 @@ $(HOSTPYTHON): cd $(HOSTBUILD) && $(CPYTHON_PATH)/configure \ --with-pydebug \ --prefix=$(HOSTINSTALL) \ + --disable-test-modules \ ) $(MAKE) -C $(HOSTBUILD) install @@ -152,7 +157,7 @@ $(TARGETBUILD)/Makefile: $(HOSTPYTHON) $(CONFIG_SITE) $(SETUP_LOCAL) AR="$(AR)" \ ARFLAGS=" " \ MACHDEP="$(MACHDEP)" \ - OPT="-g -O0 -Wall" \ + OPT="-O3" \ CONFIG_SITE="$(CONFIG_SITE)" \ $(CPYTHON_PATH)/configure \ --prefix=${TARGETINSTALL} \ @@ -163,13 +168,44 @@ $(TARGETBUILD)/Makefile: $(HOSTPYTHON) $(CONFIG_SITE) $(SETUP_LOCAL) --without-mimalloc \ --without-pymalloc \ --disable-test-modules \ + --with-ensurepip=no \ ) + $(Q) sed -i 's/^#define HAVE_LIBB2 1/\/* #undef HAVE_LIBB2 *\//' $(TARGETBUILD)/pyconfig.h + $(Q) sed -i 's/-lb2//g' $(TARGETBUILD)/Makefile $(TARGETLIBPYTHON): $(TARGETBUILD)/Makefile +ifeq ($(CONFIG_INTERPRETERS_CPYTHON_ENABLE_PIP),y) + $(Q) mkdir -p $(CPYTHON_PATH)/Lib/ensurepip/_bundled + $(Q) ( \ + PIP_WHEEL_VERSION=$$($(HOSTPYTHON) -c "import ensurepip; print(ensurepip._PIP_VERSION)"); \ + PIP_WHEEL=$(CPYTHON_PATH)/Lib/ensurepip/_bundled/pip-$${PIP_WHEEL_VERSION}-py3-none-any.whl; \ + if [ ! -f "$${PIP_WHEEL}" ]; then \ + echo "Fetching pip wheel $${PIP_WHEEL_VERSION} for ensurepip bundle"; \ + $(HOSTPYTHON) -m pip download --only-binary=:all: --no-deps --dest $(CPYTHON_PATH)/Lib/ensurepip/_bundled pip==$${PIP_WHEEL_VERSION}; \ + fi; \ + echo "Pre-compiling pip wheel with build Python (must match embedded CPython version)"; \ + $(HOSTPYTHON) $(CURDIR)/repack_wheel_add_pyc.py "$${PIP_WHEEL}"; \ + ) +endif $(MAKE) -C $(TARGETBUILD) regen-frozen $(MAKE) -C $(TARGETBUILD) libpython$(CPYTHON_VERSION_MINOR).a wasm_stdlib $(Q) ( cp $(TARGETBUILD)/libpython$(CPYTHON_VERSION_MINOR).a $(TARGETLIBPYTHON) ) $(Q) $(UNPACK) $(TARGETMODULESPACK) -d $(TARGETMODULES)/python$(CPYTHON_VERSION_MINOR) +ifeq ($(CONFIG_INTERPRETERS_CPYTHON_ENABLE_PIP),y) + $(Q) mkdir -p $(TARGETMODULES)/python$(CPYTHON_VERSION_MINOR)/site-packages + $(Q) ( \ + set -e; \ + BUNDLED_DIR=$(TARGETMODULES)/python$(CPYTHON_VERSION_MINOR)/ensurepip/_bundled; \ + SITE_PACKAGES=$(TARGETMODULES)/python$(CPYTHON_VERSION_MINOR)/site-packages; \ + : > "$${SITE_PACKAGES}/bundled_wheels.pth"; \ + for wheel in $${BUNDLED_DIR}/*.whl; do \ + [ -f "$${wheel}" ] || continue; \ + whl_name=$$(basename "$${wheel}"); \ + echo "Pre-installing wheel via zipimport into target sys.path: $${whl_name}"; \ + echo "../ensurepip/_bundled/$${whl_name}" >> "$${SITE_PACKAGES}/bundled_wheels.pth"; \ + done; \ + ) +endif MODULE = $(CONFIG_INTERPRETERS_CPYTHON) diff --git a/interpreters/python/Setup.local.in b/interpreters/python/Setup.local.in index 5ff7cd3fa..0bd116574 100644 --- a/interpreters/python/Setup.local.in +++ b/interpreters/python/Setup.local.in @@ -4,7 +4,6 @@ *disabled* _asyncio -_blake2 _bz2 _codecs_cn _codecs_hk @@ -15,19 +14,12 @@ _codecs_tw _ctypes _decimal _elementtree -_hashlib _heapq _interpchannels _interpqueues _lsprof _lzma -_md5 _multibytecodec -_sha1 -_sha2 -_sha2 -_sha3 -_sha3 _sqlite3 _ssl _statistics @@ -41,9 +33,7 @@ _testlimitedcapi _uuid _xxtestfuzz _zoneinfo -mmap pwd -pyexpat readline resource xxsubtype diff --git a/interpreters/python/config.site.in b/interpreters/python/config.site.in index eb37e5a88..52c04725a 100644 --- a/interpreters/python/config.site.in +++ b/interpreters/python/config.site.in @@ -21,4 +21,13 @@ export ac_cv_func_pipe="yes" export ac_cv_enable_strict_prototypes_warning="no" export ac_cv_func_getnameinfo="yes" export ac_cv_func_poll="yes" -export ac_cv_func_gethostname="yes" \ No newline at end of file +export ac_cv_func_gethostname="yes" +export ac_cv_func_lstat="yes" +export ac_cv_func_readlink="yes" +export ac_cv_func_realpath="yes" +export ac_cv_func_getpid="yes" +export ac_cv_func_utime="yes" +export ac_cv_func_utimes="yes" +export ac_cv_func_getuid="yes" +export ac_cv_func_sysconf="yes" +export ac_cv_func_umask="yes" diff --git a/interpreters/python/patch/0015-keep-ensurepip-in-stdlib-archive.patch b/interpreters/python/patch/0015-keep-ensurepip-in-stdlib-archive.patch new file mode 100644 index 000000000..a74e892ef --- /dev/null +++ b/interpreters/python/patch/0015-keep-ensurepip-in-stdlib-archive.patch @@ -0,0 +1,25 @@ +--- a/Tools/wasm/wasm_assets.py ++++ b/Tools/wasm/wasm_assets.py +@@ -40,7 +40,6 @@ OMIT_FILES = ( + # regression tests + "test/", + # package management +- "ensurepip/", + "venv/", + # other platforms + "_aix_support.py", +@@ -148,6 +147,13 @@ def create_stdlib_zip( + if entry.name.endswith(".py") or entry.is_dir(): + # writepy() writes .pyc files (bytecode). + pzf.writepy(entry, filterfunc=filterfunc) ++ ++ # Preserve ensurepip wheel payloads so `python -m ensurepip` can ++ # bootstrap pip on targets that consume this stdlib zip archive. ++ bundled_wheels = args.srcdir_lib / "ensurepip" / "_bundled" ++ if bundled_wheels.is_dir(): ++ for wheel in sorted(bundled_wheels.glob("*.whl")): ++ pzf.write(wheel, arcname=f"ensurepip/_bundled/{wheel.name}") + + + def detect_extension_modules(args: argparse.Namespace) -> Dict[str, bool]: + diff --git a/interpreters/python/patch/0016-fix-timezone-offset-check-when-time-t-is-unsigned.patch b/interpreters/python/patch/0016-fix-timezone-offset-check-when-time-t-is-unsigned.patch new file mode 100644 index 000000000..81924297b --- /dev/null +++ b/interpreters/python/patch/0016-fix-timezone-offset-check-when-time-t-is-unsigned.patch @@ -0,0 +1,21 @@ +--- a/Modules/timemodule.c ++++ b/Modules/timemodule.c +@@ -1800,15 +1800,15 @@ static int + static const time_t YEAR = (365 * 24 + 6) * 3600; + time_t t; + struct tm p; +- time_t janzone_t, julyzone_t; ++ long long janzone_t, julyzone_t; + char janname[10], julyname[10]; + t = (time((time_t *)0) / YEAR) * YEAR; + _PyTime_localtime(t, &p); + get_zone(janname, 9, &p); +- janzone_t = -get_gmtoff(t, &p); ++ janzone_t = -(long long)get_gmtoff(t, &p); + janname[9] = '\0'; + t += YEAR/2; + _PyTime_localtime(t, &p); + get_zone(julyname, 9, &p); +- julyzone_t = -get_gmtoff(t, &p); ++ julyzone_t = -(long long)get_gmtoff(t, &p); + julyname[9] = '\0'; diff --git a/interpreters/python/patch/0017-stdlib-zip-keep-pydecimal-and-trim-tooling-extras.patch b/interpreters/python/patch/0017-stdlib-zip-keep-pydecimal-and-trim-tooling-extras.patch new file mode 100644 index 000000000..333bb983a --- /dev/null +++ b/interpreters/python/patch/0017-stdlib-zip-keep-pydecimal-and-trim-tooling-extras.patch @@ -0,0 +1,35 @@ +--- a/Tools/wasm/wasm_assets.py ++++ b/Tools/wasm/wasm_assets.py +@@ -47,13 +47,20 @@ + # webbrowser + "antigravity.py", + "webbrowser.py", +- # Pure Python implementations of C extensions +- "_pydecimal.py", ++ # Pure Python implementations of C extensions. ++ # NOTE: keep "_pydecimal.py" so decimal.py can fall back to it when the ++ # _decimal C extension is not built (NuttX targets do not link libmpdec). + "_pyio.py", + # concurrent threading + "concurrent/futures/thread.py", + # Misc unused or large files + "pydoc_data/", ++ # Tooling/REPL extras not needed on a constrained embedded target. ++ "unittest/", ++ "_pyrepl/", ++ "idlelib/", ++ "turtledemo/", ++ "wsgiref/", + ) + + # Synchronous network I/O and protocols are not supported; for example, +@@ -80,7 +87,8 @@ + "_asyncio": ["asyncio/"], + "_curses": ["curses/"], + "_ctypes": ["ctypes/"], +- "_decimal": ["decimal.py"], ++ # decimal.py is intentionally NOT omitted here: it ships a pure-Python ++ # fallback (_pydecimal) used when the _decimal C ext is unavailable. + "_dbm": ["dbm/ndbm.py"], + "_gdbm": ["dbm/gnu.py"], + "_json": ["json/"], diff --git a/interpreters/python/patch/0018-ignore-chmod-on-nuttx-like-wasi.patch b/interpreters/python/patch/0018-ignore-chmod-on-nuttx-like-wasi.patch new file mode 100644 index 000000000..4e2afb410 --- /dev/null +++ b/interpreters/python/patch/0018-ignore-chmod-on-nuttx-like-wasi.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tiago Medicci +Date: Thu, 7 May 2026 14:00:00 -0300 +Subject: [PATCH] posixmodule: ignore chmod on NuttX like WASI + +NuttX's tmpfs does not implement chstat, so chmod fails with ENOSYS. +Apply the same workaround already used for WASI: silently succeed +when HAVE_CHMOD is not defined. + +--- + Modules/posixmodule.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/Modules/posixmodule.c ++++ b/Modules/posixmodule.c +@@ -3608,8 +3608,8 @@ + #ifdef HAVE_CHMOD + result = chmod(path->narrow, mode); +-#elif defined(__wasi__) +- // WASI SDK 15.0 does not support chmod. ++#elif defined(__wasi__) || defined(__NuttX__) ++ // WASI SDK 15.0 and NuttX do not fully support chmod. + // Ignore missing syscall for now. + result = 0; + #else diff --git a/interpreters/python/python_wrapper.c b/interpreters/python/python_wrapper.c index 6617bae98..be7454514 100644 --- a/interpreters/python/python_wrapper.c +++ b/interpreters/python/python_wrapper.c @@ -198,5 +198,7 @@ int main(int argc, FAR char *argv[]) setenv("PYTHON_BASIC_REPL", "1", 1); + setenv("PYTHONPATH", CONFIG_INTERPRETERS_CPYTHON_PYTHONPATH, 1); + return py_bytesmain(argc, argv); } diff --git a/interpreters/python/repack_wheel_add_pyc.py b/interpreters/python/repack_wheel_add_pyc.py new file mode 100644 index 000000000..fc2d913f7 --- /dev/null +++ b/interpreters/python/repack_wheel_add_pyc.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +# +# Repack a wheel in-place: compile pip/*.py to legacy sibling *.pyc (compileall +# -b: required for zipimport, which does not read PEP 3147 __pycache__/ names), +# remove the .py sources, and rewrite *.dist-info/RECORD. + +from __future__ import annotations + +import argparse +import base64 +import hashlib +import shutil +import subprocess +import sys +import tempfile +import zipfile +from pathlib import Path + + +def wheel_record_hash(data: bytes) -> str: + digest = hashlib.sha256(data).digest() + return base64.urlsafe_b64encode(digest).decode("ascii").rstrip("=") + + +def wheel_has_pip_py_sources(zf: zipfile.ZipFile) -> bool: + return any(n.startswith("pip/") and n.endswith(".py") for n in zf.namelist()) + + +def wheel_has_legacy_pip_bytecode(zf: zipfile.ZipFile) -> bool: + return "pip/__init__.pyc" in zf.namelist() + + +def strip_pip_py_sources(pip_dir: Path) -> int: + """Remove pip/**/*.py after sibling legacy *.pyc exists (compileall -b output).""" + removed = 0 + for path in sorted(pip_dir.rglob("*.py")): + if not path.is_file(): + continue + pyc = path.with_suffix(".pyc") + if not pyc.is_file(): + rel = path.relative_to(pip_dir) + raise SystemExit( + f"missing legacy .pyc for pip/{rel.as_posix()}, refusing to delete source" + ) + path.unlink() + removed += 1 + return removed + + +def rebuild_record(root: Path) -> None: + dist_infos = sorted(root.glob("*.dist-info")) + if len(dist_infos) != 1: + raise SystemExit( + f"expected one *.dist-info, got {[p.name for p in dist_infos]}" + ) + di = dist_infos[0] + record_path = di / "RECORD" + record_rel = f"{di.name}/RECORD" + lines: list[str] = [] + for path in sorted(root.rglob("*")): + if not path.is_file(): + continue + rel = path.relative_to(root).as_posix() + if rel == record_rel: + continue + body = path.read_bytes() + lines.append(f"{rel},sha256={wheel_record_hash(body)},{len(body)}") + lines.append(f"{record_rel},,") + record_path.write_text("\n".join(lines) + "\n", encoding="utf-8") + + +def repack(whl_path: Path, *, force: bool) -> None: + whl_path = whl_path.resolve() + if not whl_path.is_file(): + raise SystemExit(f"missing wheel: {whl_path}") + + with zipfile.ZipFile(whl_path) as zf: + has_py = wheel_has_pip_py_sources(zf) + if not has_py: + if not wheel_has_legacy_pip_bytecode(zf): + raise SystemExit( + "repack_wheel_add_pyc: wheel has no pip/*.py and no pip/__init__.pyc " + "(corrupt or old tool output). Delete the bundled pip-*.whl and rebuild." + ) + if not force: + print( + f"repack_wheel_add_pyc: skip (pip already bytecode-only): {whl_path.name}" + ) + return + + tmpdir = tempfile.mkdtemp(prefix="pip-whl-pyc-") + try: + root = Path(tmpdir) + with zipfile.ZipFile(whl_path) as zf: + zf.extractall(root) + + pip_dir = root / "pip" + if not pip_dir.is_dir(): + raise SystemExit("wheel has no pip/ top-level package") + + subprocess.run( + [sys.executable, "-m", "compileall", "-q", "-f", "-b", str(pip_dir)], + cwd=str(root), + check=True, + ) + n_py = strip_pip_py_sources(pip_dir) + rebuild_record(root) + + out_path = whl_path.with_suffix(whl_path.suffix + ".tmp") + with zipfile.ZipFile(out_path, "w", compression=zipfile.ZIP_DEFLATED) as out: + for path in sorted(root.rglob("*")): + if path.is_file(): + arcname = path.relative_to(root).as_posix() + out.write(path, arcname) + + out_path.replace(whl_path) + print( + f"repack_wheel_add_pyc: bytecode-only pip ({n_py} .py removed) -> {whl_path.name}" + ) + finally: + shutil.rmtree(tmpdir, ignore_errors=True) + + +def main() -> None: + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("wheel", type=Path, help="path to .whl (updated in place)") + ap.add_argument( + "-f", + "--force", + action="store_true", + help="repack even if pip is already .pyc-only", + ) + args = ap.parse_args() + repack(args.wheel, force=args.force) + + +if __name__ == "__main__": + main() From f0f7c5ada9f4c92c73acab75c4ef21a38722d689 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 18 May 2026 12:30:05 +0200 Subject: [PATCH 327/568] wakaama: add support for TLV add support for LWM2M TLV Signed-off-by: raiden00pl --- netutils/wakaama/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/netutils/wakaama/CMakeLists.txt b/netutils/wakaama/CMakeLists.txt index df3c32c2c..6e5e4f094 100644 --- a/netutils/wakaama/CMakeLists.txt +++ b/netutils/wakaama/CMakeLists.txt @@ -78,6 +78,10 @@ if(CONFIG_NETUTILS_WAKAAMA) list(APPEND WAKAAMA_DEFINITIONS LWM2M_SUPPORT_SENML_JSON) endif() + if(CONFIG_WAKAAMA_TLV) + list(APPEND WAKAAMA_DEFINITIONS LWM2M_SUPPORT_TLV) + endif() + list(APPEND WAKAAMA_DEFINITIONS LWM2M_COAP_DEFAULT_BLOCK_SIZE=${CONFIG_WAKAAMA_COAP_DEFAULT_BLOCK_SIZE}) From ecfc1b5b61ad505aeb0f75a399ed2738d200c459 Mon Sep 17 00:00:00 2001 From: Abhishek Mishra Date: Wed, 13 May 2026 21:40:51 +0000 Subject: [PATCH 328/568] nshlib: add chmod and chown builtins Add minimal chmod/chown support to NSH using the existing libc/VFS syscall interfaces. Supported forms: - chmod - chown [:gid] The chown implementation supports the numeric ownership forms already handled by the underlying NuttX chown() implementation, including unchanged uid/gid semantics via omitted fields. Only numeric permission modes and numeric uid/gid forms are supported in this initial implementation. This adds interactive filesystem permission and ownership management support to NSH and aligns the shell more closely with standard POSIX environments. Signed-off-by: Abhishek Mishra --- nshlib/Kconfig | 10 ++++ nshlib/nsh.h | 6 +++ nshlib/nsh_command.c | 8 +++ nshlib/nsh_fscmds.c | 123 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+) diff --git a/nshlib/Kconfig b/nshlib/Kconfig index 1fc34cb21..2d1570b87 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -341,6 +341,16 @@ config NSH_DISABLE_CD bool "Disable cd" default DEFAULT_SMALL +config NSH_DISABLE_CHMOD + bool "Disable chmod" + default DEFAULT_SMALL + depends on FS_PERMISSION + +config NSH_DISABLE_CHOWN + bool "Disable chown" + default DEFAULT_SMALL + depends on FS_PERMISSION + config NSH_DISABLE_CP bool "Disable cp" default DEFAULT_SMALL diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 2fb3cf867..7abb7c38f 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -963,6 +963,12 @@ int cmd_irqinfo(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #ifndef CONFIG_NSH_DISABLE_CAT int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #endif +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD) + int cmd_chmod(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); +#endif +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHOWN) + int cmd_chown(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); +#endif #ifndef CONFIG_NSH_DISABLE_CP int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #endif diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index ec3f8a385..23534fbe5 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -168,6 +168,14 @@ static const struct cmdmap_s g_cmdmap[] = CMD_MAP("cd", cmd_cd, 1, 2, "[|-|~|..]"), #endif +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD) + CMD_MAP("chmod", cmd_chmod, 3, 3, " "), +#endif + +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHOWN) + CMD_MAP("chown", cmd_chown, 3, 3, "[][:] "), +#endif + #ifndef CONFIG_NSH_DISABLE_CP CMD_MAP("cp", cmd_cp, 3, 4, "[-r] "), #endif diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index a88c1a20d..13daa8258 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -843,6 +843,129 @@ int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) } #endif +/**************************************************************************** + * Name: cmd_chmod + * + * Description: + * chmod + * + * Only numeric (octal) modes are supported. + * + ****************************************************************************/ + +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD) +int cmd_chmod(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) +{ + FAR char *fullpath; + FAR char *endptr; + long mode; + int ret = ERROR; + + UNUSED(argc); + + mode = strtol(argv[1], &endptr, 8); + if (endptr == argv[1] || *endptr != '\0' || mode < 0 || mode > 0777) + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + fullpath = nsh_getfullpath(vtbl, argv[2]); + if (fullpath != NULL) + { + ret = chmod(fullpath, (mode_t)mode); + if (ret < 0) + { + nsh_error(vtbl, g_fmtcmdfailed, argv[0], "chmod", NSH_ERRNO); + } + + nsh_freefullpath(fullpath); + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: cmd_chown + * + * Description: + * chown [:] + * chown []: + * + * Only numeric uid/gid forms are supported. Empty uid or gid fields + * leave that side unchanged. + * + ****************************************************************************/ + +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHOWN) +int cmd_chown(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) +{ + FAR const char *spec = argv[1]; + FAR char *endptr; + FAR char *fullpath; + long value; + uid_t uid = (uid_t)-1; + gid_t gid = (gid_t)-1; + int ret = ERROR; + + UNUSED(argc); + + value = strtol(spec, &endptr, 10); + if (endptr != spec) + { + if (value < 0) + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + uid = (uid_t)value; + } + + if (*endptr == ':') + { + FAR const char *gidstr = endptr + 1; + if (*gidstr != '\0') + { + value = strtol(gidstr, &endptr, 10); + if (*endptr != '\0' || value < 0) + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + gid = (gid_t)value; + } + } + else if (*endptr != '\0') + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + if (uid == (uid_t)-1 && gid == (gid_t)-1) + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + fullpath = nsh_getfullpath(vtbl, argv[2]); + if (fullpath != NULL) + { + ret = lchown(fullpath, uid, gid); + if (ret < 0) + { + nsh_error(vtbl, g_fmtcmdfailed, argv[0], "chown", NSH_ERRNO); + } + + nsh_freefullpath(fullpath); + } + + return ret; +} +#endif + /**************************************************************************** * Name: cmd_dmesg ****************************************************************************/ From e536adaabc92f77ad652a4b1f45986d7ebceb75c Mon Sep 17 00:00:00 2001 From: Shoji Tokunaga Date: Sun, 17 May 2026 14:07:13 +0900 Subject: [PATCH 329/568] apps/cmake: Add DEPENDS for Rust-related files. * Add `DEPENDS` to ensure staticlib rebuilds when Rust-related files change. * Uses `GLOB_RECURSE` to search for Rust-related files. Signed-off-by: Shoji Tokunaga --- cmake/nuttx_add_rust.cmake | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cmake/nuttx_add_rust.cmake b/cmake/nuttx_add_rust.cmake index 55fce1a8e..c8546f0fa 100644 --- a/cmake/nuttx_add_rust.cmake +++ b/cmake/nuttx_add_rust.cmake @@ -168,6 +168,18 @@ function(nuttx_add_rust) # Create build directory file(MAKE_DIRECTORY ${RUST_BUILD_DIR}) + # Collect Rust source files and manifests as dependencies so that changes in + # the crate trigger a rebuild via CMake/Ninja. + file( + GLOB_RECURSE + RUST_CRATE_SOURCES + CONFIGURE_DEPENDS + "${CRATE_PATH}/Cargo.toml" + "${CRATE_PATH}/Cargo.lock" + "${CRATE_PATH}/build.rs" + "${CRATE_PATH}/src/*.rs" + "${CRATE_PATH}/src/**/*.rs") + # Add a custom command to build the Rust crate add_custom_command( OUTPUT ${RUST_LIB_PATH} @@ -178,6 +190,7 @@ function(nuttx_add_rust) -Zbuild-std=std,panic_abort -Zjson-target-spec --manifest-path ${CRATE_PATH}/Cargo.toml --target ${RUST_TARGET} --target-dir ${RUST_BUILD_DIR} + DEPENDS ${RUST_CRATE_SOURCES} COMMENT "Building Rust crate ${CRATE_NAME}" VERBATIM) From 02153debae607b6b7b2b1f093ba7db7d6e3b06e9 Mon Sep 17 00:00:00 2001 From: Shunchao Hu Date: Sun, 12 Apr 2026 09:54:32 +0800 Subject: [PATCH 330/568] system/ping: Fallback to ping6 for gethost error handling. When ping only receives an IPv6 DNS response, the current command reports "ping_gethostip" and exits even though ping6 can still handle the target. Keep the existing ping and ping6 netutils interfaces unchanged and add a one-way fallback in the ping command. If IPv4 name resolution fails, ping will spawn ping6 with the same arguments and let ping6 report the final result. Signed-off-by: Shunchao Hu --- system/ping/ping.c | 64 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/system/ping/ping.c b/system/ping/ping.c index f294983a1..4588393ab 100644 --- a/system/ping/ping.c +++ b/system/ping/ping.c @@ -35,6 +35,15 @@ #include #include +#if defined(CONFIG_SYSTEM_PING6) && defined(CONFIG_LIBC_EXECFUNCS) +#define PING_ENABLE_PING6_FALLBACK +#endif + +#ifdef PING_ENABLE_PING6_FALLBACK +#include +#include +#endif + #include #include "netutils/icmp_ping.h" @@ -121,8 +130,10 @@ static void ping_result(FAR const struct ping_result_s *result) switch (result->code) { case ICMP_E_HOSTIP: +#ifndef PING_ENABLE_PING6_FALLBACK fprintf(stderr, "ERROR: ping_gethostip(%s) failed\n", result->info->hostname); +#endif break; case ICMP_E_MEMORY: @@ -279,6 +290,49 @@ static void ping_result(FAR const struct ping_result_s *result) } } +#ifdef PING_ENABLE_PING6_FALLBACK +/**************************************************************************** + * Name: ping6_fallback + ****************************************************************************/ + +static int ping6_fallback(int argc, FAR char *argv[]) +{ + pid_t pid; + int ret; + int status; + + if (argc <= 0) + { + return EXIT_FAILURE; + } + + argv[0] = CONFIG_SYSTEM_PING6_PROGNAME; + + ret = posix_spawnp(&pid, CONFIG_SYSTEM_PING6_PROGNAME, NULL, NULL, + argv, NULL); + if (ret != 0) + { + fprintf(stderr, "ERROR: posix_spawnp(%s) failed: %d\n", + CONFIG_SYSTEM_PING6_PROGNAME, ret); + return EXIT_FAILURE; + } + + ret = waitpid(pid, &status, 0); + if (ret < 0) + { + fprintf(stderr, "ERROR: waitpid() failed: %d\n", errno); + return EXIT_FAILURE; + } + + if (WIFEXITED(status)) + { + return WEXITSTATUS(status); + } + + return EXIT_FAILURE; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -403,7 +457,15 @@ int main(int argc, FAR char *argv[]) info.hostname = argv[optind]; icmp_ping(&info); - return priv.code < 0 ? EXIT_FAILURE: EXIT_SUCCESS; + +#ifdef PING_ENABLE_PING6_FALLBACK + if (priv.code == ICMP_E_HOSTIP) + { + return ping6_fallback(argc, argv); + } +#endif + + return priv.code < 0 ? EXIT_FAILURE : EXIT_SUCCESS; errout_with_usage: optind = 0; From 173e19cde118546c5d3180e1a4b5c3c53a765142 Mon Sep 17 00:00:00 2001 From: Eren Terzioglu Date: Wed, 29 Apr 2026 10:27:12 +0200 Subject: [PATCH 331/568] apps/examples: Add path option to SPI Slave test Add path option to spislv_test example Signed-off-by: Eren Terzioglu --- examples/spislv_test/Kconfig | 6 +++ examples/spislv_test/spislv_test.c | 84 ++++++++++++++++++------------ 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/examples/spislv_test/Kconfig b/examples/spislv_test/Kconfig index ab273e0aa..54dd827c5 100644 --- a/examples/spislv_test/Kconfig +++ b/examples/spislv_test/Kconfig @@ -12,6 +12,12 @@ config EXAMPLES_SPISLV if EXAMPLES_SPISLV +config EXAMPLES_SPISLV_DEFAULT_PATH + string "Default SPI Slave device path" + default "/dev/spislv0" + ---help--- + Default path for SPI Slave device + config EXAMPLES_SPISLV_PROGNAME string "Program name" default "spislv" diff --git a/examples/spislv_test/spislv_test.c b/examples/spislv_test/spislv_test.c index 2ad13c236..dcde9fe3a 100644 --- a/examples/spislv_test/spislv_test.c +++ b/examples/spislv_test/spislv_test.c @@ -40,7 +40,7 @@ /* Define buffer sizes */ #define RX_BUFFER_SIZE 64 #define TX_BUFFER_SIZE 64 -#define SOURCE_FILE "dev/spislv2" /* SPI device path */ +#define DEFAULT_SPI_PATH CONFIG_EXAMPLES_SPISLV_DEFAULT_PATH /* Enumeration for operation modes */ @@ -61,6 +61,7 @@ typedef struct operation_mode_t mode; int num_bytes; /* Applicable for write mode */ int timeout_seconds; /* Applicable for all modes */ + const char *spi_path; /* SPI slave device path */ unsigned char tx_buffer[TX_BUFFER_SIZE]; } program_config_t; @@ -68,6 +69,33 @@ typedef struct * Private Functions ****************************************************************************/ +static void print_usage(const char *progname) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s -x [-p ] [-t ] \n", + progname); + fprintf(stderr, " %s -l [-p ] [-t ]\n", progname); + fprintf(stderr, " %s -e [-p ] [-t ]\n", progname); + fprintf(stderr, "\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -p SPI slave device path [default: %s]\n", + DEFAULT_SPI_PATH); + fprintf(stderr, + " -t Timeout in seconds [default: 10]\n"); + fprintf(stderr, + " -x Number of bytes to queue \n"); + fprintf(stderr, + " -l Only listen for data from the master\n"); + fprintf(stderr, + " -e Echo received data back to the master\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Examples:\n"); + fprintf(stderr, " %s -x 2 abba\n", progname); + fprintf(stderr, " %s -l -t 5\n", progname); + fprintf(stderr, " %s -e -t 10\n", progname); + fprintf(stderr, " %s -p /dev/spislv2 -l\n", progname); +} + /** * @brief Converts a single hexadecimal character to its byte value. * @@ -148,13 +176,25 @@ static int parse_arguments(int argc, char *argv[], config->mode = MODE_INVALID; config->num_bytes = 0; config->timeout_seconds = 10; /* Default timeout */ + config->spi_path = DEFAULT_SPI_PATH; /* Parse command-line options */ - while ((opt = getopt(argc, argv, "x:t:le")) != -1) + while ((opt = getopt(argc, argv, "p:x:t:le")) != -1) { switch (opt) { + case 'p': + if (optarg[0] == '\0') + { + fprintf(stderr, + "Error: SPI device path (-p) must not be empty.\n"); + return -1; + } + + config->spi_path = optarg; + break; + case 'x': if (config->mode != MODE_INVALID) { @@ -208,18 +248,7 @@ static int parse_arguments(int argc, char *argv[], break; default: - fprintf(stderr, "Usage:\n"); - fprintf(stderr, - " %s -x [-t ] \n", - argv[0]); - fprintf(stderr, - " %s -l [-t ]\n", argv[0]); - fprintf(stderr, - " %s -e [-t ]\n", argv[0]); - printf("Examples:\n"); - printf(" spislv -x 2 abba\n"); - printf(" spislv -l -t 5\n"); - printf(" spislv -e -t 10\n\n"); + print_usage(argv[0]); return -1; } } @@ -232,9 +261,7 @@ static int parse_arguments(int argc, char *argv[], { fprintf(stderr, "Error: Missing hexadecimal bytes to send.\n"); - fprintf(stderr, - "Usage: %s -x [-t ] \n", - argv[0]); + print_usage(argv[0]); return -1; } @@ -265,18 +292,7 @@ static int parse_arguments(int argc, char *argv[], else if (config->mode == MODE_INVALID) { fprintf(stderr, "Error: No operation mode specified.\n"); - fprintf(stderr, "Usage:\n"); - fprintf(stderr, - " %s -x [-t ] \n", - argv[0]); - fprintf(stderr, - " %s -l [-t ]\n", argv[0]); - fprintf(stderr, - " %s -e [-t ]\n", argv[0]); - printf("Examples:\n"); - printf(" spislv -x 2 abba\n"); - printf(" spislv -l -t 5\n"); - printf(" spislv -e -t 10\n"); + print_usage(argv[0]); return -1; } @@ -320,7 +336,7 @@ static int write_mode(program_config_t *config, int fd) if (bytes_written < 0) { fprintf(stderr, "Error: Failed to write to %s: %s\n", - SOURCE_FILE, strerror(errno)); + config->spi_path, strerror(errno)); return -1; } @@ -426,7 +442,7 @@ static int read_with_timeout(program_config_t *config, int fd) if (bytes_read < 0) { fprintf(stderr, "Error: Failed to read from %s: %s\n", - SOURCE_FILE, strerror(errno)); + config->spi_path, strerror(errno)); return -1; } @@ -453,7 +469,7 @@ static int read_with_timeout(program_config_t *config, int fd) { fprintf(stderr, "Error: Failed to write to %s: %s\n", - SOURCE_FILE, strerror(errno)); + config->spi_path, strerror(errno)); return -1; } else if (bytes_written != bytes_read) @@ -503,11 +519,11 @@ int main(int argc, char *argv[]) return -1; } - fd = open(SOURCE_FILE, O_RDWR); + fd = open(config.spi_path, O_RDWR); if (fd < 0) { fprintf(stderr, "Error: Failed to open %s: %s\n", - SOURCE_FILE, strerror(errno)); + config.spi_path, strerror(errno)); return -1; } From 43bc7e99d6453cdd0e925ae5128574012f5198e0 Mon Sep 17 00:00:00 2001 From: Filipe Cavalcanti Date: Wed, 20 May 2026 13:22:49 +0200 Subject: [PATCH 332/568] system/nxdiag: add CMake support for NXDiag tool Supports building NXDiag with CMake. Signed-off-by: Filipe Cavalcanti --- system/nxdiag/CMakeLists.txt | 102 +++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 system/nxdiag/CMakeLists.txt diff --git a/system/nxdiag/CMakeLists.txt b/system/nxdiag/CMakeLists.txt new file mode 100644 index 000000000..ec0cd116c --- /dev/null +++ b/system/nxdiag/CMakeLists.txt @@ -0,0 +1,102 @@ +# ############################################################################## +# apps/system/nxdiag/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_SYSTEM_NXDIAG) + + find_program(PYTHON3 python3) + if(NOT PYTHON3) + message(FATAL_ERROR "python3 not found in PATH (required for nxdiag)") + endif() + + set(NXDIAG_TOOLSDIR ${NUTTX_DIR}/tools) + set(NXDIAG_SYSINFO ${CMAKE_CURRENT_SOURCE_DIR}/sysinfo.h) + + # Build host_info_dump.py argument list + + set(NXDIAG_FLAGS ${NUTTX_DIR}) + + if(CONFIG_SYSTEM_NXDIAG_CONF) + list(APPEND NXDIAG_FLAGS --config) + endif() + + if(CONFIG_SYSTEM_NXDIAG_COMP_FLAGS) + list(APPEND NXDIAG_FLAGS --flags "${CMAKE_C_FLAGS}" "${CMAKE_CXX_FLAGS}" + "${CMAKE_EXE_LINKER_FLAGS}") + endif() + + if(CONFIG_SYSTEM_NXDIAG_HOST_PACKAGES) + list(APPEND NXDIAG_FLAGS --packages) + endif() + + if(CONFIG_SYSTEM_NXDIAG_HOST_MODULES) + list(APPEND NXDIAG_FLAGS --modules) + endif() + + if(CONFIG_SYSTEM_NXDIAG_HOST_PATH) + list(APPEND NXDIAG_FLAGS --path) + endif() + + if(CONFIG_SYSTEM_NXDIAG_VERBOSE) + list(APPEND NXDIAG_FLAGS --verbose) + endif() + + set(NXDIAG_PY_FLAGS "") + + # Vendor-specific checks + + if(CONFIG_SYSTEM_NXDIAG_ESPRESSIF) + list(APPEND NXDIAG_FLAGS --target_info) + list(APPEND NXDIAG_PY_FLAGS -B) + endif() + + # Generate sysinfo.h + + add_custom_command( + OUTPUT ${NXDIAG_SYSINFO} + COMMAND ${PYTHON3} ${NXDIAG_PY_FLAGS} ${NXDIAG_TOOLSDIR}/host_info_dump.py + ${NXDIAG_FLAGS} -b ${CMAKE_BINARY_DIR} > ${NXDIAG_SYSINFO} + DEPENDS ${NXDIAG_TOOLSDIR}/host_info_dump.py + COMMENT "Generating nxdiag sysinfo.h" + VERBATIM) + + add_custom_target(nxdiag_sysinfo_gen DEPENDS ${NXDIAG_SYSINFO}) + + nuttx_add_application( + NAME + nxdiag + SRCS + nxdiag.c + PRIORITY + ${CONFIG_SYSTEM_NXDIAG_PRIORITY} + STACKSIZE + ${CONFIG_SYSTEM_NXDIAG_STACKSIZE} + INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS + nxdiag_sysinfo_gen) + + set_property( + DIRECTORY ${CMAKE_SOURCE_DIR} + APPEND + PROPERTY ADDITIONAL_CLEAN_FILES ${NXDIAG_SYSINFO}) + +endif() From bda34481067a3d27508cd0edcd837e931d97bb3e Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Thu, 21 May 2026 10:40:34 +0530 Subject: [PATCH 333/568] apps/system/microros: Create empty library skeleton. Add Make.defs with copyright header for the micro-ROS library build system. This establishes the directory structure for Phase 2, with actual build logic to follow in subsequent steps. Signed-off-by: Arjav Patel --- system/microros/Make.defs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 system/microros/Make.defs diff --git a/system/microros/Make.defs b/system/microros/Make.defs new file mode 100644 index 000000000..5ec456770 --- /dev/null +++ b/system/microros/Make.defs @@ -0,0 +1,21 @@ +############################################################################ +# apps/system/microros/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ From 2a3a41d53af6cefcd357954839c110703347e214 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Thu, 21 May 2026 10:40:38 +0530 Subject: [PATCH 334/568] apps/system/microros: Add Kconfig with configuration options. Add Kconfig file defining CONFIG_SYSTEM_MICROROS and related options: - MICROROS_DISTRO: ROS 2 distribution selection (default jazzy) - MICROROS_TRANSPORT_UDP/SERIAL: Transport method selection - MICROROS_AGENT_IP/PORT: UDP agent address configuration - MICROROS_SERIAL_DEVICE/BAUD: Serial transport configuration - Resource limits: MAX_NODES, MAX_PUBLISHERS, MAX_SUBSCRIPTIONS, MAX_SERVICES, MAX_CLIENTS Allows menuconfig integration for micro-ROS library configuration. Signed-off-by: Arjav Patel --- system/microros/Kconfig | 102 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 system/microros/Kconfig diff --git a/system/microros/Kconfig b/system/microros/Kconfig new file mode 100644 index 000000000..d1d7d562a --- /dev/null +++ b/system/microros/Kconfig @@ -0,0 +1,102 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig SYSTEM_MICROROS + bool "micro-ROS Integration" + default n + depends on NET_UDP || SERIAL_TERMIOS + ---help--- + Enable micro-ROS integration for NuttX RTOS. Provides a ROS 2 + client library for embedded and real-time systems. + +if SYSTEM_MICROROS + +config MICROROS_DISTRO + string "ROS 2 Distribution" + default "jazzy" + ---help--- + Specifies the ROS 2 distribution branch (e.g., humble, jazzy, kilted). + This determines which versions of micro-ROS packages are fetched. + +choice + prompt "Transport Method" + default MICROROS_TRANSPORT_UDP + +config MICROROS_TRANSPORT_UDP + bool "UDP Transport" + ---help--- + Use UDP socket for communication with micro-ROS agent. + +config MICROROS_TRANSPORT_SERIAL + bool "Serial Transport" + depends on SERIAL_TERMIOS + ---help--- + Use serial (UART/USB-CDC) for communication with micro-ROS agent. + +endchoice + +if MICROROS_TRANSPORT_UDP + +config MICROROS_AGENT_IP + string "Agent IP Address" + default "10.42.0.214" + ---help--- + IP address of the micro-ROS agent. + +config MICROROS_AGENT_PORT + int "Agent Port" + default 8888 + ---help--- + UDP port of the micro-ROS agent. + +endif + +if MICROROS_TRANSPORT_SERIAL + +config MICROROS_SERIAL_DEVICE + string "Serial Device Path" + default "/dev/ttyS0" + ---help--- + Serial device to use for transport (e.g., /dev/ttyS0, /dev/ttyACM0). + +config MICROROS_SERIAL_BAUD + int "Serial Baud Rate" + default 115200 + ---help--- + Baud rate for serial communication. + +endif + +config MICROROS_MAX_NODES + int "Maximum Nodes" + default 1 + ---help--- + Maximum number of ROS nodes that can be created. + +config MICROROS_MAX_PUBLISHERS + int "Maximum Publishers" + default 5 + ---help--- + Maximum number of publishers per node. + +config MICROROS_MAX_SUBSCRIPTIONS + int "Maximum Subscriptions" + default 5 + ---help--- + Maximum number of subscriptions per node. + +config MICROROS_MAX_SERVICES + int "Maximum Services" + default 1 + ---help--- + Maximum number of services per node. + +config MICROROS_MAX_CLIENTS + int "Maximum Clients" + default 1 + ---help--- + Maximum number of service clients per node. + +endif From 0be492889355a88c8885588ec71aabc8e06cc668 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Thu, 21 May 2026 10:40:41 +0530 Subject: [PATCH 335/568] apps/system/microros: Add Makefile skeleton. Add Makefile with standard NuttX build system integration. Follows the MENUDESC + Directory.mk pattern used throughout nuttx-apps. Enables the system/microros module to be built as part of the apps directory build process. Signed-off-by: Arjav Patel --- system/microros/Makefile | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 system/microros/Makefile diff --git a/system/microros/Makefile b/system/microros/Makefile new file mode 100644 index 000000000..b907087ee --- /dev/null +++ b/system/microros/Makefile @@ -0,0 +1,25 @@ +############################################################################ +# apps/system/microros/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +MENUDESC = "micro-ROS Library" + +include $(APPDIR)/Directory.mk From faf07ed3b07ed2e10e2aae8d93f1bfddfec37c6f Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Thu, 21 May 2026 10:40:44 +0530 Subject: [PATCH 336/568] apps/system/microros: Add .gitignore for library build artifacts. Ignore build outputs and generated files: - Directories: micro_ros_src/, micro_ros_dev/, build/, install/ - Build outputs: libmicroros.a, toolchain.cmake, colcon.meta - Archives: *.tar.gz Prevents build artifacts and downloaded sources from being committed. Signed-off-by: Arjav Patel --- system/microros/.gitignore | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 system/microros/.gitignore diff --git a/system/microros/.gitignore b/system/microros/.gitignore new file mode 100644 index 000000000..878b0e80a --- /dev/null +++ b/system/microros/.gitignore @@ -0,0 +1,13 @@ +# Build artifacts +/build/ +/install/ +/micro_ros_dev/ +/micro_ros_src/ + +# Generated files +/libmicroros.a +/toolchain.cmake +/colcon.meta + +# Archives +*.tar.gz From e9d1141f7c12220a8577feccbd22ba6e78ec70f8 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Thu, 21 May 2026 10:43:35 +0530 Subject: [PATCH 337/568] apps/system/microros: Add CMakeLists.txt for CMake support. Add CMakeLists.txt file for CMake build system integration. Enables the micro-ROS library module to be built using NuttX CMake build system alongside traditional Make-based builds. Signed-off-by: Arjav Patel --- system/microros/CMakeLists.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 system/microros/CMakeLists.txt diff --git a/system/microros/CMakeLists.txt b/system/microros/CMakeLists.txt new file mode 100644 index 000000000..9edae8cef --- /dev/null +++ b/system/microros/CMakeLists.txt @@ -0,0 +1,25 @@ +# ############################################################################## +# apps/system/microros/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_SYSTEM_MICROROS) + nuttx_add_library(microros) +endif() From f9f59bd0f86a97f873496736e942f594b0c546c1 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Mon, 11 May 2026 17:51:35 +0800 Subject: [PATCH 338/568] !apps: drop redundant casts on tv_sec/tv_nsec and fix printf formats Now that time_t is unconditionally 64-bit (signed int64_t) and the struct timespec fields tv_sec / tv_nsec are wide enough on their own, the explicit (uint64_t)/(int64_t)/(int) casts that used to guard the multiplications and subtractions in *_us / *_ms / *_ns helpers are no longer needed. Drop them to keep the timekeeping math readable. In the same spirit, this commit also normalises the printf-style format specifiers and casts used to print tv_sec / tv_nsec / tv_usec values. The prior code was a mix of "%d"/"%u"/"%ld"/"%lu"/"%lld" with matching (int)/(unsigned long)/(long long) casts; some formats truncated time_t on 32-bit hosts, others mismatched signedness or width. Replace all such cases with the portable POSIX-recommended forms: - tv_sec (time_t, signed, impl-defined width) -> %jd + (intmax_t) - tv_nsec (long, signed) -> %ld (no cast) - tv_usec (suseconds_t / long) -> %ld (no cast) Also drop two stale `(FAR const time_t *)&ts.tv_sec` casts that are unnecessary now that ts.tv_sec is plain time_t. Arithmetic-cleanup files (existing scope): - benchmarks/cyclictest/cyclictest.c: timediff_us() - benchmarks/sd_bench/sd_bench_main.c: get_time_delta_us() - examples/oneshot/oneshot_main.c: maxus computation - examples/watchdog/watchdog_main.c: current_time_ms (x2) - industry/nxmodbus/nxmb_internal.h: nxmb_util_clock_ms() - netutils/ntpclient/ntpclient.c: timespec2ntp() - netutils/ptpd/ptpd.c: ptp_adjtime() - system/dd/dd_main.c: elapsed accounting - testing/drivers/drivertest/drivertest_posix_timer.c: get_timestamp() - testing/drivers/sd_stress/sd_stress_main.c:get_time_delta() - testing/sched/getprime/getprime_main.c: elapsed accounting - testing/sched/pthread_mutex_perf/pthread_mutex_perf.c: timespec_avg() Printf-format-fix files (new in this revision): - examples/adjtime/adjtime_main.c - examples/charger/charger_main.c - examples/netpkt/netpkt_ethercat.c - fsutils/mkfatfs/mkfatfs.c - graphics/tiff/tiff_initialize.c - netutils/ptpd/ptpd.c - nshlib/nsh_timcmds.c - system/coredump/coredump.c - system/ptpd/ptpd_main.c - testing/drivers/drivertest/drivertest_oneshot.c - testing/mm/kasantest/kasantest.c - testing/ostest/semtimed.c - testing/sched/pthread_mutex_perf/pthread_mutex_perf.c - testing/sched/timerjitter/timerjitter.c - testing/testsuites/kernel/time/cases/clock_test_clock01.c - testing/testsuites/kernel/time/cases/clock_test_smoke.c No behavioural change. Signed-off-by: Xiang Xiao --- benchmarks/cyclictest/cyclictest.c | 8 ++--- benchmarks/sd_bench/sd_bench_main.c | 4 +-- examples/adjtime/adjtime_main.c | 9 +++--- examples/charger/charger_main.c | 4 +-- examples/netpkt/netpkt_ethercat.c | 7 +++-- examples/oneshot/oneshot_main.c | 4 +-- examples/watchdog/watchdog_main.c | 6 ++-- fsutils/mkfatfs/mkfatfs.c | 2 +- graphics/nxwm/src/chexcalculator.cxx | 6 ++-- graphics/tiff/tiff_initialize.c | 2 +- industry/nxmodbus/nxmb_internal.h | 2 +- .../usock_handlers/alt1250_ioctl_lwm2m.c | 2 +- netutils/ntpclient/ntpclient.c | 20 ++++++------ netutils/ptpd/ptpd.c | 20 ++++++------ nshlib/nsh_timcmds.c | 13 ++++---- system/coredump/coredump.c | 4 +-- system/dd/dd_main.c | 4 +-- system/ptpd/ptpd_main.c | 31 ++++++++++--------- system/resmonitor/filldisk.c | 20 ++++++------ .../drivers/drivertest/drivertest_oneshot.c | 2 +- .../drivertest/drivertest_posix_timer.c | 2 +- testing/drivers/sd_stress/sd_stress_main.c | 6 ++-- testing/mm/kasantest/kasantest.c | 6 ++-- testing/ostest/semtimed.c | 17 +++++----- testing/sched/getprime/getprime_main.c | 4 +-- .../pthread_mutex_perf/pthread_mutex_perf.c | 17 +++++----- testing/sched/timerjitter/timerjitter.c | 5 +-- .../kernel/syscall/cases/pread_test.c | 8 ++--- .../kernel/syscall/cases/truncate_test.c | 4 +-- .../kernel/syscall/cases/write_test.c | 8 ++--- .../kernel/time/cases/clock_test_clock01.c | 12 +++---- .../kernel/time/cases/clock_test_smoke.c | 24 +++++++------- 32 files changed, 144 insertions(+), 139 deletions(-) diff --git a/benchmarks/cyclictest/cyclictest.c b/benchmarks/cyclictest/cyclictest.c index 1727c54f1..fb9382dd5 100644 --- a/benchmarks/cyclictest/cyclictest.c +++ b/benchmarks/cyclictest/cyclictest.c @@ -443,8 +443,8 @@ static inline void tsnorm(struct timespec *ts) static inline int64_t timediff_us(struct timespec t1, struct timespec t2) { int64_t ret; - ret = 1000000 * (int64_t) ((int) t1.tv_sec - (int) t2.tv_sec); - ret += (int64_t) ((int) t1.tv_nsec - (int) t2.tv_nsec) / 1000; + ret = 1000000 * (t1.tv_sec - t2.tv_sec); + ret += (t1.tv_nsec - t2.tv_nsec) / 1000; return ret; } @@ -458,11 +458,11 @@ static inline int64_t timediff_us_timer(struct timer_status_s after, t2 = after.timeleft; if (t2 < t1) { - ret = (int64_t) (t1 - t2); + ret = t1 - t2; } else { - ret = (int64_t) (after.timeout - (t2 - t1)); + ret = after.timeout - (t2 - t1); } return ret; diff --git a/benchmarks/sd_bench/sd_bench_main.c b/benchmarks/sd_bench/sd_bench_main.c index 8a48a9128..44d30fa63 100644 --- a/benchmarks/sd_bench/sd_bench_main.c +++ b/benchmarks/sd_bench/sd_bench_main.c @@ -130,8 +130,8 @@ static uint64_t get_time_delta_us(const struct timespec *start, const struct timespec *end) { uint64_t elapsed; - elapsed = (((uint64_t)end->tv_sec * NSEC_PER_SEC) + end->tv_nsec); - elapsed -= (((uint64_t)start->tv_sec * NSEC_PER_SEC) + start->tv_nsec); + elapsed = (end->tv_sec * NSEC_PER_SEC) + end->tv_nsec; + elapsed -= (start->tv_sec * NSEC_PER_SEC) + start->tv_nsec; return elapsed / 1000.; } diff --git a/examples/adjtime/adjtime_main.c b/examples/adjtime/adjtime_main.c index 17eda10f5..fefe80567 100644 --- a/examples/adjtime/adjtime_main.c +++ b/examples/adjtime/adjtime_main.c @@ -25,6 +25,7 @@ ****************************************************************************/ #include +#include #include #include @@ -149,8 +150,8 @@ int main(int argc, FAR char *argv[]) parse_args(&delta, argc, argv); - printf("Delta time is %ld seconds and %ld micro seconds.\n", - (long)delta.tv_sec, delta.tv_usec); + printf("Delta time is %jd seconds and %ld micro seconds.\n", + (intmax_t)delta.tv_sec, delta.tv_usec); /* Call adjtime function. */ @@ -161,8 +162,8 @@ int main(int argc, FAR char *argv[]) } else { - printf("Returned olddelta is %ld seconds and %ld micro seconds.\n", - (long)olddelta.tv_sec, olddelta.tv_usec); + printf("Returned olddelta is %jd seconds and %ld micro seconds.\n", + (intmax_t)olddelta.tv_sec, olddelta.tv_usec); } return ret; diff --git a/examples/charger/charger_main.c b/examples/charger/charger_main.c index baac2f27e..2184ea9d5 100644 --- a/examples/charger/charger_main.c +++ b/examples/charger/charger_main.c @@ -231,8 +231,8 @@ int main(int argc, FAR char *argv[]) } gettimeofday(&tv, NULL); - printf("%ju.%06ld: %d mV, %d mA\n", - (uintmax_t)tv.tv_sec, tv.tv_usec, voltage, current); + printf("%jd.%06ld: %d mV, %d mA\n", + (intmax_t)tv.tv_sec, tv.tv_usec, voltage, current); close(fd); diff --git a/examples/netpkt/netpkt_ethercat.c b/examples/netpkt/netpkt_ethercat.c index 6ed6ae8d9..ea24791a7 100644 --- a/examples/netpkt/netpkt_ethercat.c +++ b/examples/netpkt/netpkt_ethercat.c @@ -26,6 +26,7 @@ #include +#include #include #include @@ -118,9 +119,9 @@ int main(int argc, FAR const char *argv[]) len = recvfrom(sockfd, recvbuff, 100, 0, NULL, NULL); clock_gettime(CLOCK_REALTIME, &recv_time); - printf("Data recv: %d bytes, spent time %ld ns\n", len, - (recv_time.tv_sec - send_time.tv_sec) * NSEC_PER_SEC + - recv_time.tv_nsec - send_time.tv_nsec); + printf("Data recv: %d bytes, spent time %jd ns\n", len, + (intmax_t)(recv_time.tv_sec - send_time.tv_sec) * + NSEC_PER_SEC + recv_time.tv_nsec - send_time.tv_nsec); usleep(1000); } diff --git a/examples/oneshot/oneshot_main.c b/examples/oneshot/oneshot_main.c index 50760e360..00fac3f2d 100644 --- a/examples/oneshot/oneshot_main.c +++ b/examples/oneshot/oneshot_main.c @@ -167,8 +167,8 @@ int main(int argc, FAR char *argv[]) return EXIT_FAILURE; } - maxus = (uint64_t)ts.tv_sec * USEC_PER_SEC + - (uint64_t)ts.tv_nsec / NSEC_PER_USEC; + maxus = ts.tv_sec * USEC_PER_SEC + + ts.tv_nsec / NSEC_PER_USEC; printf("Maximum delay is %" PRIu64 "\n", maxus); diff --git a/examples/watchdog/watchdog_main.c b/examples/watchdog/watchdog_main.c index 4e22001a1..1167f3116 100644 --- a/examples/watchdog/watchdog_main.c +++ b/examples/watchdog/watchdog_main.c @@ -308,8 +308,7 @@ int main(int argc, FAR char *argv[]) /* Get current time to calculate the elapsed time */ clock_gettime(CLOCK_REALTIME, &tnow); - current_time_ms = (uint64_t)((tnow.tv_sec * 1000) - + (tnow.tv_nsec / 1000000)); + current_time_ms = (tnow.tv_sec * 1000) + (tnow.tv_nsec / 1000000); } /* Then stop pinging */ @@ -345,8 +344,7 @@ int main(int argc, FAR char *argv[]) /* Get current time to calculate the elapsed time */ clock_gettime(CLOCK_REALTIME, &tnow); - current_time_ms = (uint64_t)((tnow.tv_sec * 1000) - + (tnow.tv_nsec / 1000000)); + current_time_ms = (tnow.tv_sec * 1000) + (tnow.tv_nsec / 1000000); } /* We should not get here */ diff --git a/fsutils/mkfatfs/mkfatfs.c b/fsutils/mkfatfs/mkfatfs.c index 8b2227e02..629d6bb76 100644 --- a/fsutils/mkfatfs/mkfatfs.c +++ b/fsutils/mkfatfs/mkfatfs.c @@ -92,7 +92,7 @@ static uint32_t fat_systime2fattime(void) { /* Break done the seconds in date and time units */ - if (gmtime_r((FAR const time_t *)&ts.tv_sec, &tm) != NULL) + if (gmtime_r(&ts.tv_sec, &tm) != NULL) { /* FAT can only represent dates since 1980. struct tm can * represent dates since 1900. diff --git a/graphics/nxwm/src/chexcalculator.cxx b/graphics/nxwm/src/chexcalculator.cxx index f2cf62018..3ba68eac3 100644 --- a/graphics/nxwm/src/chexcalculator.cxx +++ b/graphics/nxwm/src/chexcalculator.cxx @@ -734,7 +734,7 @@ void CHexCalculator::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) if (m_result) { - m_accum = (uint64_t)g_keyDesc[index].value; + m_accum = g_keyDesc[index].value; } // Otherwise, add the new value to the accumulator. The way @@ -743,12 +743,12 @@ void CHexCalculator::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) else if (m_hexMode) { m_accum <<= 4; - m_accum |= (uint64_t)g_keyDesc[index].value; + m_accum |= g_keyDesc[index].value; } else { m_accum *= 10; - m_accum += (uint64_t)g_keyDesc[index].value; + m_accum += g_keyDesc[index].value; } updateText(); } diff --git a/graphics/tiff/tiff_initialize.c b/graphics/tiff/tiff_initialize.c index 2c4f5921a..5ce27cac4 100644 --- a/graphics/tiff/tiff_initialize.c +++ b/graphics/tiff/tiff_initialize.c @@ -434,7 +434,7 @@ static int tiff_datetime(FAR char *timbuf, unsigned int buflen) /* Break the current time up into the format needed by strftime */ - gmtime_r((FAR const time_t *)&ts.tv_sec, &tm); + gmtime_r(&ts.tv_sec, &tm); /* Convert the current time to TIFF format */ diff --git a/industry/nxmodbus/nxmb_internal.h b/industry/nxmodbus/nxmb_internal.h index 0ec3db5c9..6e781bd04 100644 --- a/industry/nxmodbus/nxmb_internal.h +++ b/industry/nxmodbus/nxmb_internal.h @@ -205,7 +205,7 @@ static inline uint64_t nxmb_util_clock_ms(void) struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; } /**************************************************************************** diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_lwm2m.c b/lte/alt1250/usock_handlers/alt1250_ioctl_lwm2m.c index e68704a87..3e76e43bd 100644 --- a/lte/alt1250/usock_handlers/alt1250_ioctl_lwm2m.c +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_lwm2m.c @@ -610,7 +610,7 @@ static int perform_m2m_applysetting(FAR struct alt1250_s *dev, } *usock_result = OK; - dev->lwm2m_apply_xid = (int64_t)xid; + dev->lwm2m_apply_xid = xid; MODEM_STATE_INTENTRST(dev); altdevice_reset(dev->altfd); diff --git a/netutils/ntpclient/ntpclient.c b/netutils/ntpclient/ntpclient.c index 3d2b50e02..5a48b0586 100644 --- a/netutils/ntpclient/ntpclient.c +++ b/netutils/ntpclient/ntpclient.c @@ -567,7 +567,7 @@ static int32_t ntp_nsecpart(int64_t time) { /* Get fraction part converted to nanoseconds. */ - return (((int64_t)((uint64_t)time << 32) >> 32) * NSEC_PER_SEC) >> 32; + return (((time << 32) >> 32) * NSEC_PER_SEC) >> 32; } /**************************************************************************** @@ -589,7 +589,7 @@ static uint64_t timespec2ntp(FAR const struct timespec *ts) /* Set seconds part. */ - ntp_time += (uint64_t)(ts->tv_sec) << 32; + ntp_time += ts->tv_sec << 32; return ntp_time; } @@ -647,8 +647,8 @@ static void ntpc_calculate_offset(FAR int64_t *offset, FAR int64_t *delay, * http://nicolas.aimon.fr/2014/12/05/timesync/ */ - *offset = (int64_t)((remote_recvtime / 2 - local_xmittime / 2) + - (remote_xmittime / 2 - local_recvtime / 2)); + *offset = (remote_recvtime / 2 - local_xmittime / 2) + + (remote_xmittime / 2 - local_recvtime / 2); /* Calculate roundtrip delay. */ @@ -707,13 +707,13 @@ static void ntpc_settime(int64_t offset, FAR struct timespec *start_realtime, diffms_real = curr_realtime.tv_sec - start_realtime->tv_sec; diffms_real *= 1000; - diffms_real += (int64_t)(curr_realtime.tv_nsec - - start_realtime->tv_nsec) / (1000 * 1000); + diffms_real += (curr_realtime.tv_nsec - + start_realtime->tv_nsec) / (1000 * 1000); diffms_mono = curr_monotonic.tv_sec - start_monotonic->tv_sec; diffms_mono *= 1000; - diffms_mono += (int64_t)(curr_monotonic.tv_nsec - - start_monotonic->tv_nsec) / (1000 * 1000); + diffms_mono += (curr_monotonic.tv_nsec - + start_monotonic->tv_nsec) / (1000 * 1000); /* Detect if real-time has been altered by other task. */ @@ -1489,14 +1489,14 @@ static int ntpc_daemon(int argc, FAR char **argv) if (offset1 > 0 && offset2 > 0) { - offset = ((uint64_t)offset1 + (uint64_t)offset2) / 2; + offset = (offset1 + offset2) / 2; } else if (offset1 < 0 && offset2 < 0) { offset1 = -offset1; offset2 = -offset2; - offset = ((uint64_t)offset1 + (uint64_t)offset2) / 2; + offset = (offset1 + offset2) / 2; offset = -offset; } diff --git a/netutils/ptpd/ptpd.c b/netutils/ptpd/ptpd.c index 430693cc9..49c608210 100644 --- a/netutils/ptpd/ptpd.c +++ b/netutils/ptpd/ptpd.c @@ -425,7 +425,7 @@ static int ptp_adjtime(FAR struct ptp_state_s *state, int64_t delta_ns, struct timeval delta; delta.tv_sec = delta_ns / NSEC_PER_SEC; - delta_ns -= (int64_t)delta.tv_sec * NSEC_PER_SEC; + delta_ns -= delta.tv_sec * NSEC_PER_SEC; delta.tv_usec = delta_ns / NSEC_PER_USEC; return adjtime(&delta, NULL); } @@ -1030,11 +1030,11 @@ static int ptp_update_local_clock(FAR struct ptp_state_s *state, const int64_t adj_limit_ns = CONFIG_NETUTILS_PTPD_SETTIME_THRESHOLD_MS * (int64_t)NSEC_PER_MSEC; - ptpinfo("Local time: %lld.%09ld, remote time %lld.%09ld\n", - (long long)local_timestamp->tv_sec, - (long)local_timestamp->tv_nsec, - (long long)remote_timestamp->tv_sec, - (long)remote_timestamp->tv_nsec); + ptpinfo("Local time: %jd.%09ld, remote time %jd.%09ld\n", + (intmax_t)local_timestamp->tv_sec, + local_timestamp->tv_nsec, + (intmax_t)remote_timestamp->tv_sec, + remote_timestamp->tv_nsec); delta_ns = timespec_delta_ns(remote_timestamp, local_timestamp); delta_ns += state->path_delay_ns; @@ -1062,8 +1062,8 @@ static int ptp_update_local_clock(FAR struct ptp_state_s *state, if (ret == OK) { - ptpinfo("Jumped to timestamp %lld.%09ld s\n", - (long long)new_time.tv_sec, (long)new_time.tv_nsec); + ptpinfo("Jumped to timestamp %jd.%09ld s\n", + (intmax_t)new_time.tv_sec, new_time.tv_nsec); } else { @@ -1241,7 +1241,7 @@ static void ptp_add_correction_time(FAR const uint8_t *correction, | (((uint64_t)correction[4]) << 8) | (((uint64_t)correction[5]) << 0); - ptpinfo("correction before: %lld.%09ld\n", (long long)ts->tv_sec, + ptpinfo("correction before: %jd.%09ld\n", (intmax_t)ts->tv_sec, ts->tv_nsec); ts->tv_sec += correction_time / NSEC_PER_SEC; @@ -1252,7 +1252,7 @@ static void ptp_add_correction_time(FAR const uint8_t *correction, ts->tv_sec += 1; } - ptpinfo("correction after: %lld.%09ld\n", (long long)ts->tv_sec, + ptpinfo("correction after: %jd.%09ld\n", (intmax_t)ts->tv_sec, ts->tv_nsec); } diff --git a/nshlib/nsh_timcmds.c b/nshlib/nsh_timcmds.c index de5dd8adf..9a812d461 100644 --- a/nshlib/nsh_timcmds.c +++ b/nshlib/nsh_timcmds.c @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -120,7 +121,7 @@ static inline int date_showtime(FAR struct nsh_vtbl_s *vtbl, if (utc) { - if (gmtime_r((FAR const time_t *)&ts.tv_sec, &tm) == NULL) + if (gmtime_r(&ts.tv_sec, &tm) == NULL) { nsh_error(vtbl, g_fmtcmdfailed, name, "gmtime_r", NSH_ERRNO); return ERROR; @@ -128,7 +129,7 @@ static inline int date_showtime(FAR struct nsh_vtbl_s *vtbl, } else { - if (localtime_r((FAR const time_t *)&ts.tv_sec, &tm) == NULL) + if (localtime_r(&ts.tv_sec, &tm) == NULL) { nsh_error(vtbl, g_fmtcmdfailed, name, "localtime_r", NSH_ERRNO); return ERROR; @@ -354,8 +355,8 @@ int cmd_time(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) } diff.tv_nsec = end.tv_nsec - start.tv_nsec; - nsh_output(vtbl, "\n%lu.%04lu sec\n", (unsigned long)diff.tv_sec, - (unsigned long)diff.tv_nsec / 100000); + nsh_output(vtbl, "\n%jd.%04ld sec\n", (intmax_t)diff.tv_sec, + diff.tv_nsec / 100000); } } @@ -489,7 +490,7 @@ int cmd_timedatectl(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) return ERROR; } - if (localtime_r((FAR const time_t *)&ts.tv_sec, &tm) == NULL) + if (localtime_r(&ts.tv_sec, &tm) == NULL) { nsh_error(vtbl, g_fmtcmdfailed, argv[0], "localtime_r", NSH_ERRNO); return ERROR; @@ -508,7 +509,7 @@ int cmd_timedatectl(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) tm.tm_gmtoff); nsh_output(vtbl, " Local time: %s %s\n", timbuf, tm.tm_zone); - if (gmtime_r((FAR const time_t *)&ts.tv_sec, &tm) == NULL) + if (gmtime_r(&ts.tv_sec, &tm) == NULL) { nsh_error(vtbl, g_fmtcmdfailed, argv[0], "gmtime_r", NSH_ERRNO); return ERROR; diff --git a/system/coredump/coredump.c b/system/coredump/coredump.c index 6a742f479..2787ee3d0 100644 --- a/system/coredump/coredump.c +++ b/system/coredump/coredump.c @@ -264,9 +264,9 @@ static void coredump_restore(FAR char *savepath, size_t maxfile) /* 'date -d @$(printf "%d" 0x6720C67E)' restore utc to date */ ret = snprintf(dumppath, sizeof(dumppath), - "%s/%.16s-%llx"COREDUMP_FILE_SUFFIX, + "%s/%.16s-%jx"COREDUMP_FILE_SUFFIX, savepath, info.name.version, - (unsigned long long)info.time.tv_sec); + (intmax_t)info.time.tv_sec); while (ret--) { diff --git a/system/dd/dd_main.c b/system/dd/dd_main.c index a240ae3fe..17138371b 100644 --- a/system/dd/dd_main.c +++ b/system/dd/dd_main.c @@ -508,8 +508,8 @@ int main(int argc, FAR char **argv) #ifdef CONFIG_SYSTEM_DD_STATS clock_gettime(CLOCK_MONOTONIC, &ts1); - elapsed = (((uint64_t)ts1.tv_sec * NSEC_PER_SEC) + ts1.tv_nsec); - elapsed -= (((uint64_t)ts0.tv_sec * NSEC_PER_SEC) + ts0.tv_nsec); + elapsed = (ts1.tv_sec * NSEC_PER_SEC) + ts1.tv_nsec; + elapsed -= (ts0.tv_sec * NSEC_PER_SEC) + ts0.tv_nsec; elapsed /= NSEC_PER_USEC; /* usec */ fprintf(stderr, "%" PRIu64 " bytes (%" PRIu32 " blocks) copied, %u usec, ", diff --git a/system/ptpd/ptpd_main.c b/system/ptpd/ptpd_main.c index 4a87ce472..6b1720689 100644 --- a/system/ptpd/ptpd_main.c +++ b/system/ptpd/ptpd_main.c @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -97,7 +98,7 @@ static int do_ptpd_status(int pid) gmtime_r(&status.last_clock_update.tv_sec, &time_tm); strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &time_tm); printf("- last_clock_update: %s.%09ld\n", - buf, (long)status.last_clock_update.tv_nsec); + buf, status.last_clock_update.tv_nsec); printf("- last_delta_ns: %lld\n", (long long)status.last_delta_ns); printf("- last_adjtime_ns: %lld\n", (long long)status.last_adjtime_ns); @@ -106,20 +107,20 @@ static int do_ptpd_status(int pid) clock_gettime(CLOCK_MONOTONIC, &time_now); - printf("- last_received_multicast: %d s ago\n", - (int)(time_now.tv_sec - status.last_received_multicast.tv_sec)); - printf("- last_received_announce: %d s ago\n", - (int)(time_now.tv_sec - status.last_received_announce.tv_sec)); - printf("- last_received_sync: %d s ago\n", - (int)(time_now.tv_sec - status.last_received_sync.tv_sec)); - printf("- last_transmitted_sync: %d s ago\n", - (int)(time_now.tv_sec - status.last_transmitted_sync.tv_sec)); - printf("- last_transmitted_announce: %d s ago\n", - (int)(time_now.tv_sec - status.last_transmitted_announce.tv_sec)); - printf("- last_transmitted_delayresp: %d s ago\n", - (int)(time_now.tv_sec - status.last_transmitted_delayresp.tv_sec)); - printf("- last_transmitted_delayreq: %d s ago\n", - (int)(time_now.tv_sec - status.last_transmitted_delayreq.tv_sec)); + printf("- last_received_multicast: %jd s ago\n", + (intmax_t)(time_now.tv_sec - status.last_received_multicast.tv_sec)); + printf("- last_received_announce: %jd s ago\n", + (intmax_t)(time_now.tv_sec - status.last_received_announce.tv_sec)); + printf("- last_received_sync: %jd s ago\n", + (intmax_t)(time_now.tv_sec - status.last_received_sync.tv_sec)); + printf("- last_transmitted_sync: %jd s ago\n", + (intmax_t)(time_now.tv_sec - status.last_transmitted_sync.tv_sec)); + printf("- last_transmitted_announce: %jd s ago\n", + (intmax_t)(time_now.tv_sec - status.last_transmitted_announce.tv_sec)); + printf("- last_transmitted_delayresp: %jd s ago\n", + (intmax_t)(time_now.tv_sec - status.last_transmitted_delayresp.tv_sec)); + printf("- last_transmitted_delayreq: %jd s ago\n", + (intmax_t)(time_now.tv_sec - status.last_transmitted_delayreq.tv_sec)); return EXIT_SUCCESS; } diff --git a/system/resmonitor/filldisk.c b/system/resmonitor/filldisk.c index 6670048b0..35f1289da 100644 --- a/system/resmonitor/filldisk.c +++ b/system/resmonitor/filldisk.c @@ -234,20 +234,20 @@ static void print_disk_info(struct statfs *diskinfo) { syslog(LOG_INFO, "\tfs block size : %zu\n", diskinfo->f_bsize); syslog(LOG_INFO, - "\tfs block nums : %" PRIu64 "\n", - (uint64_t)diskinfo->f_blocks); + "\tfs block nums : %ju\n", + (uintmax_t)diskinfo->f_blocks); syslog(LOG_INFO, - "\tfs free blocks : %" PRIu64 "\n", - (uint64_t)diskinfo->f_bfree); + "\tfs free blocks : %ju\n", + (uintmax_t)diskinfo->f_bfree); syslog(LOG_INFO, - "\tfs free blocks available : %" PRIu64 "\n", - (uint64_t)diskinfo->f_bavail); + "\tfs free blocks available : %ju\n", + (uintmax_t)diskinfo->f_bavail); syslog(LOG_INFO, - "\tfs total file nodes : %" PRIu64 "\n", - (uint64_t)diskinfo->f_files); + "\tfs total file nodes : %ju\n", + (uintmax_t)diskinfo->f_files); syslog(LOG_INFO, - "\tfs free file nodes : %" PRIu64 "\n", - (uint64_t)diskinfo->f_ffree); + "\tfs free file nodes : %ju\n", + (uintmax_t)diskinfo->f_ffree); } int main(int argc, FAR char *argv[]) diff --git a/testing/drivers/drivertest/drivertest_oneshot.c b/testing/drivers/drivertest/drivertest_oneshot.c index a8b18cc6d..2538112b5 100644 --- a/testing/drivers/drivertest/drivertest_oneshot.c +++ b/testing/drivers/drivertest/drivertest_oneshot.c @@ -167,7 +167,7 @@ static void drivertest_oneshot(FAR void **state) ret = ioctl(fd, OSIOC_MAXDELAY, &ts); assert_return_code(ret, OK); - syslog(LOG_DEBUG, "maxdelay sec:%lld\n", (long long)ts.tv_sec); + syslog(LOG_DEBUG, "maxdelay sec:%jd\n", (intmax_t)ts.tv_sec); syslog(LOG_DEBUG, "maxdelay nsec:%ld\n", ts.tv_nsec); for (i = 0; i < ONESHOT_DEFAULT_NSAMPLES; i++) diff --git a/testing/drivers/drivertest/drivertest_posix_timer.c b/testing/drivers/drivertest/drivertest_posix_timer.c index 65b95ee24..727eeb7ec 100644 --- a/testing/drivers/drivertest/drivertest_posix_timer.c +++ b/testing/drivers/drivertest/drivertest_posix_timer.c @@ -146,7 +146,7 @@ static uint64_t get_timestamp(void) struct timespec ts; uint64_t ms; clock_gettime(CLOCK_MONOTONIC, &ts); - ms = (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; return ms; } diff --git a/testing/drivers/sd_stress/sd_stress_main.c b/testing/drivers/sd_stress/sd_stress_main.c index afcf528a0..da6e4f5c7 100644 --- a/testing/drivers/sd_stress/sd_stress_main.c +++ b/testing/drivers/sd_stress/sd_stress_main.c @@ -134,7 +134,7 @@ static bool create_files(const char *dir, const char *name, if (!read_bytes) { - printf("malloc failed for read bytes bufffer\n"); + printf("malloc failed for read bytes buffer\n"); return false; } @@ -282,8 +282,8 @@ static uint64_t get_time_delta(const struct timespec *start, const struct timespec *end) { uint64_t elapsed; - elapsed = (((uint64_t)end->tv_sec * NSEC_PER_SEC) + end->tv_nsec); - elapsed -= (((uint64_t)start->tv_sec * NSEC_PER_SEC) + start->tv_nsec); + elapsed = (end->tv_sec * NSEC_PER_SEC) + end->tv_nsec; + elapsed -= (start->tv_sec * NSEC_PER_SEC) + start->tv_nsec; return elapsed / 1000; } diff --git a/testing/mm/kasantest/kasantest.c b/testing/mm/kasantest/kasantest.c index 72f1353a1..bf8317b54 100644 --- a/testing/mm/kasantest/kasantest.c +++ b/testing/mm/kasantest/kasantest.c @@ -666,9 +666,9 @@ static int run_testcase(int argc, FAR char *argv[]) clock_gettime(CLOCK_MONOTONIC, &end); timespec_sub(&result, &end, &start); - printf("%s spending %ld.%lds\n", run->testcase->name, - result.tv_sec, - result.tv_nsec); + printf("%s spending %jd.%09lds\n", run->testcase->name, + (intmax_t)result.tv_sec, + result.tv_nsec); return ret; } diff --git a/testing/ostest/semtimed.c b/testing/ostest/semtimed.c index 2b8fc6648..231da93c3 100644 --- a/testing/ostest/semtimed.c +++ b/testing/ostest/semtimed.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -150,10 +151,10 @@ void semtimed_test(void) } } - printf("BEFORE: (%lu sec, %lu nsec)\n", - (unsigned long)before.tv_sec, (unsigned long)before.tv_nsec); - printf("AFTER: (%lu sec, %lu nsec)\n", - (unsigned long)after.tv_sec, (unsigned long)after.tv_nsec); + printf("BEFORE: (%jd sec, %ld nsec)\n", + (intmax_t)before.tv_sec, before.tv_nsec); + printf("AFTER: (%jd sec, %ld nsec)\n", + (intmax_t)after.tv_sec, after.tv_nsec); /* Now make sure that the time wait returns successfully if the semaphore * is posted @@ -246,10 +247,10 @@ void semtimed_test(void) printf("semtimed_test: PASS: sem_timedwait succeeded\n"); } - printf("BEFORE: (%lu sec, %lu nsec)\n", - (unsigned long)before.tv_sec, (unsigned long)before.tv_nsec); - printf("AFTER: (%lu sec, %lu nsec)\n", - (unsigned long)after.tv_sec, (unsigned long)after.tv_nsec); + printf("BEFORE: (%jd sec, %ld nsec)\n", + (intmax_t)before.tv_sec, before.tv_nsec); + printf("AFTER: (%jd sec, %ld nsec)\n", + (intmax_t)after.tv_sec, after.tv_nsec); /* Clean up detritus left by the pthread */ diff --git a/testing/sched/getprime/getprime_main.c b/testing/sched/getprime/getprime_main.c index bee2509be..2670963a2 100644 --- a/testing/sched/getprime/getprime_main.c +++ b/testing/sched/getprime/getprime_main.c @@ -217,8 +217,8 @@ int main(int argc, FAR char *argv[]) get_prime_in_parallel(n); clock_gettime(CLOCK_REALTIME, &ts1); - elapsed = (((uint64_t)ts1.tv_sec * NSEC_PER_SEC) + ts1.tv_nsec); - elapsed -= (((uint64_t)ts0.tv_sec * NSEC_PER_SEC) + ts0.tv_nsec); + elapsed = (ts1.tv_sec * NSEC_PER_SEC) + ts1.tv_nsec; + elapsed -= (ts0.tv_sec * NSEC_PER_SEC) + ts0.tv_nsec; elapsed /= NSEC_PER_MSEC; /* msec */ printf("%s took %" PRIu64 " msec\n", argv[0], elapsed); diff --git a/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c b/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c index f958f0fcb..12128e394 100644 --- a/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c +++ b/testing/sched/pthread_mutex_perf/pthread_mutex_perf.c @@ -25,6 +25,7 @@ ****************************************************************************/ #include +#include #include #include @@ -63,7 +64,7 @@ static void timespec_add(struct timespec *total, const struct timespec *diff) static void timespec_avg(const struct timespec *total, int count, struct timespec *avg) { - uint64_t total_ns = (uint64_t)total->tv_sec * 1000000000 + total->tv_nsec; + uint64_t total_ns = total->tv_sec * 1000000000 + total->tv_nsec; uint64_t avg_ns = total_ns / count; avg->tv_sec = avg_ns / 1000000000; @@ -129,17 +130,17 @@ int main(int argc, char *argv[]) timespec_avg(&total, j, &avg); - printf("%d: diff = %lu.%09lu s | avg = %lu.%09lu s\n", j, - (unsigned long)diff.tv_sec, (unsigned long)diff.tv_nsec, - (unsigned long)avg.tv_sec, (unsigned long)avg.tv_nsec); + printf("%d: diff = %jd.%09ld s | avg = %jd.%09ld s\n", j, + (intmax_t)diff.tv_sec, diff.tv_nsec, + (intmax_t)avg.tv_sec, avg.tv_nsec); } printf("\n===== result =====\n"); printf("count: %d\n", loop_count); - printf("total: %lu.%09lu s\n", (unsigned long)total.tv_sec, - (unsigned long)total.tv_nsec); - printf("avg: %lu.%09lu s\n", (unsigned long)avg.tv_sec, - (unsigned long)avg.tv_nsec); + printf("total: %jd.%09ld s\n", (intmax_t)total.tv_sec, + total.tv_nsec); + printf("avg: %jd.%09ld s\n", (intmax_t)avg.tv_sec, + avg.tv_nsec); return 0; } diff --git a/testing/sched/timerjitter/timerjitter.c b/testing/sched/timerjitter/timerjitter.c index 01eed10d5..6811a3f19 100644 --- a/testing/sched/timerjitter/timerjitter.c +++ b/testing/sched/timerjitter/timerjitter.c @@ -25,6 +25,7 @@ ****************************************************************************/ #include +#include #include #include #include @@ -213,8 +214,8 @@ static FAR void *timerjitter(FAR void *arg) diff = calc_diff(&now, &next); if (param->print) { - printf("diff %"PRId64", now %"PRId64".%09lu\n", diff, now.tv_sec, - now.tv_nsec); + printf("diff %"PRId64", now %jd.%09ld\n", diff, + (intmax_t)now.tv_sec, now.tv_nsec); } if (diff > param->max) diff --git a/testing/testsuites/kernel/syscall/cases/pread_test.c b/testing/testsuites/kernel/syscall/cases/pread_test.c index 8877e5b99..ed1eb419e 100644 --- a/testing/testsuites/kernel/syscall/cases/pread_test.c +++ b/testing/testsuites/kernel/syscall/cases/pread_test.c @@ -224,8 +224,8 @@ void pread01_l_seek(int fdesc, off_t offset, int whence, off_t checkoff) if ((offloc = lseek(fdesc, offset, whence)) != checkoff) { syslog(LOG_WARNING, - "return = %" PRId64 " , expected %" PRId64 "\n", - (int64_t)offloc, (int64_t)checkoff); + "return = %jd, expected %jd\n", + (intmax_t)offloc, (intmax_t)checkoff); syslog(LOG_ERR, "lseek() on %s failed\n", pread01_filename); } } @@ -234,7 +234,7 @@ void pread01_l_seek(int fdesc, off_t offset, int whence, off_t checkoff) * Name: pread01_compare_bufers ****************************************************************************/ -/* compare_bufers() - Compare the contents of read buffer aganist the +/* compare_bufers() - Compare the contents of read buffer against the * write buffer contents. * * The contents of the index of each buffer should be as follows: @@ -259,7 +259,7 @@ int pread01_compare_bufers(void) } } - /* If no erros, Test successful */ + /* If no errors, Test successful */ if (!err_flg) { diff --git a/testing/testsuites/kernel/syscall/cases/truncate_test.c b/testing/testsuites/kernel/syscall/cases/truncate_test.c index 3162bcfd0..48a141ba5 100644 --- a/testing/testsuites/kernel/syscall/cases/truncate_test.c +++ b/testing/testsuites/kernel/syscall/cases/truncate_test.c @@ -140,8 +140,8 @@ void test_nuttx_syscall_truncate01(FAR void **state) { syslog(LOG_ERR, "FAIL, %s: Incorrect file " - "size %" PRId64 " , Expected %d\n", - truncate01_fileneme, (int64_t)file_length, + "size %jd, Expected %d\n", + truncate01_fileneme, (intmax_t)file_length, TRUNC_LEN); fail_msg("test fail !"); } diff --git a/testing/testsuites/kernel/syscall/cases/write_test.c b/testing/testsuites/kernel/syscall/cases/write_test.c index 8b274f66c..c994c9e91 100644 --- a/testing/testsuites/kernel/syscall/cases/write_test.c +++ b/testing/testsuites/kernel/syscall/cases/write_test.c @@ -79,8 +79,8 @@ void test_nuttx_syscall_write01(FAR void **state) { badcount++; syslog(LOG_INFO, - "INFO, write() returned %" PRId64 ", expected %d\n", - (int64_t)ret, i); + "INFO, write() returned %zd, expected %d\n", + ret, i); } } @@ -160,8 +160,8 @@ void test_nuttx_syscall_write03(FAR void **state) { badcount++; syslog(LOG_INFO, - "INFO, write() returned %" PRId64 ", expected %d\n", - (int64_t)ret, i); + "INFO, write() returned %zd, expected %d\n", + ret, i); } } diff --git a/testing/testsuites/kernel/time/cases/clock_test_clock01.c b/testing/testsuites/kernel/time/cases/clock_test_clock01.c index 6443495e2..7d79dd8c7 100644 --- a/testing/testsuites/kernel/time/cases/clock_test_clock01.c +++ b/testing/testsuites/kernel/time/cases/clock_test_clock01.c @@ -61,8 +61,8 @@ void test_nuttx_clock_test_clock01(FAR void **state) /* get current real time */ ret = clock_gettime(clk, &oldtp); - syslog(LOG_INFO, "The current real time: sec is %lld, nsec is %ld\n", - (long long)oldtp.tv_sec, oldtp.tv_nsec); + syslog(LOG_INFO, "The current real time: sec is %jd, nsec is %ld\n", + (intmax_t)oldtp.tv_sec, oldtp.tv_nsec); assert_int_equal(ret, 0); syslog(LOG_INFO, "sleep 2 seconds\n"); @@ -76,8 +76,8 @@ void test_nuttx_clock_test_clock01(FAR void **state) /* set real time */ ret = clock_settime(clk, &tp); - syslog(LOG_INFO, "Setting time: sec is %lld, nsec is %ld\n", - (long long)tp.tv_sec, tp.tv_nsec); + syslog(LOG_INFO, "Setting time: sec is %jd, nsec is %ld\n", + (intmax_t)tp.tv_sec, tp.tv_nsec); assert_int_equal(ret, 0); syslog(LOG_INFO, "get real time clock again\n"); @@ -86,9 +86,9 @@ void test_nuttx_clock_test_clock01(FAR void **state) ret = clock_gettime(clk, &tp); syslog(LOG_INFO, - "Obtaining the current time after setting: sec = %lld, nsec = " + "Obtaining the current time after setting: sec = %jd, nsec = " "%ld\n", - (long long)tp.tv_sec, tp.tv_nsec); + (intmax_t)tp.tv_sec, tp.tv_nsec); passflag = (tp.tv_sec >= 2 + oldtp.tv_sec) && (tp.tv_sec <= 2 + oldtp.tv_sec + 1); /* 2, use for testing clock setting */ diff --git a/testing/testsuites/kernel/time/cases/clock_test_smoke.c b/testing/testsuites/kernel/time/cases/clock_test_smoke.c index 3b8948958..035b6ad41 100644 --- a/testing/testsuites/kernel/time/cases/clock_test_smoke.c +++ b/testing/testsuites/kernel/time/cases/clock_test_smoke.c @@ -52,7 +52,7 @@ void test_nuttx_clock_test_smoke01(FAR void **state) 0, 0 }; - struct timespec setts = + struct timespec tp = { 0, 0 }; @@ -79,30 +79,30 @@ void test_nuttx_clock_test_smoke01(FAR void **state) ret = clock_gettime(clk, &oldtp); syslog(LOG_INFO, - "the clock current time: %lld second, %ld nanosecond\n", - (long long)oldtp.tv_sec, oldtp.tv_nsec); + "the clock current time: %jd second, %ld nanosecond\n", + (intmax_t)oldtp.tv_sec, oldtp.tv_nsec); assert_int_equal(ret, 0); /* set clock realtime */ - setts.tv_sec = oldtp.tv_sec + 1; - setts.tv_nsec = oldtp.tv_nsec; + tp.tv_sec = oldtp.tv_sec + 1; + tp.tv_nsec = oldtp.tv_nsec; syslog(LOG_INFO, - "the clock setting time: %lld second, %ld nanosecond\n", - (long long)setts.tv_sec, setts.tv_nsec); - ret = clock_settime(CLOCK_REALTIME, &setts); + "the clock setting time: %jd second, %ld nanosecond\n", + (intmax_t)tp.tv_sec, tp.tv_nsec); + ret = clock_settime(CLOCK_REALTIME, &tp); assert_int_equal(ret, 0); ret = clock_gettime(clk, &ts); syslog(LOG_INFO, - "obtaining the current time after setting: %lld second, %ld " + "obtaining the current time after setting: %jd second, %ld " "nanosecond\n", - (long long)ts.tv_sec, ts.tv_nsec); + (intmax_t)ts.tv_sec, ts.tv_nsec); passflag = - (ts.tv_sec >= setts.tv_sec) && + (ts.tv_sec >= tp.tv_sec) && (ts.tv_sec <= - setts.tv_sec + 1); /* 1, means obtaining time's errno is 1 second. */ + tp.tv_sec + 1); /* 1, means obtaining time's errno is 1 second. */ assert_int_equal(ret, 0); assert_int_equal(passflag, 1); } From 5c703f5603f3cea92c82a46c650435f430b03e33 Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Tue, 19 May 2026 17:43:05 +0800 Subject: [PATCH 339/568] nshlib/testing: Fix open() arguments. Pass explicit open flags for the NSH script redirect file so the mode argument is used as file creation permissions. Add the missing mode argument to AIO ostest open() calls that create the test file. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- nshlib/nsh_script.c | 3 ++- testing/ostest/aio.c | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/nshlib/nsh_script.c b/nshlib/nsh_script.c index 21bef19e4..d1f1d369e 100644 --- a/nshlib/nsh_script.c +++ b/nshlib/nsh_script.c @@ -61,7 +61,8 @@ static int nsh_script_redirect(FAR struct nsh_vtbl_s *vtbl, if (CONFIG_NSH_SCRIPT_REDIRECT_PATH[0]) { - fd = open(CONFIG_NSH_SCRIPT_REDIRECT_PATH, 0666); + fd = open(CONFIG_NSH_SCRIPT_REDIRECT_PATH, + O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd > 0) { nsh_redirect(vtbl, 0, fd, fd, save); diff --git a/testing/ostest/aio.c b/testing/ostest/aio.c index 8a6fe9637..e69d3a5e7 100644 --- a/testing/ostest/aio.c +++ b/testing/ostest/aio.c @@ -299,7 +299,7 @@ void aio_test(void) /* Case 1: Poll for transfer complete */ printf("AIO test case 1: Poll for transfer complete\n"); - g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC); + g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC, 0666); if (g_fildes < 0) { printf("aio_test: ERROR: Failed to open %s: %d\n", @@ -336,7 +336,7 @@ void aio_test(void) usleep(500 * 1000); printf("AIO test case 2: Use LIO_WAIT for transfer complete\n"); - g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC); + g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC, 0666); if (g_fildes < 0) { printf("aio_test: ERROR: Failed to open %s: %d\n", @@ -374,7 +374,7 @@ void aio_test(void) usleep(500 * 1000); printf("AIO test case 3: Use aio_suspend for transfer complete\n"); - g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC); + g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC, 0666); if (g_fildes < 0) { printf("aio_test: ERROR: Failed to open %s: %d\n", @@ -442,7 +442,7 @@ void aio_test(void) usleep(500 * 1000); printf("AIO test case 4: Use individual signals for transfer complete\n"); - g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC); + g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC, 0666); if (g_fildes < 0) { printf("aio_test: ERROR: Failed to open %s: %d\n", @@ -506,7 +506,7 @@ void aio_test(void) printf("AIO test case 5:" " Use list complete signal for transfer complete\n"); - g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC); + g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC, 0666); if (g_fildes < 0) { printf("aio_test: ERROR: Failed to open %s: %d\n", @@ -569,7 +569,7 @@ void aio_test(void) usleep(500 * 1000); printf("AIO test case 6: Cancel I/O by AIO control block\n"); - g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC); + g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC, 0666); if (g_fildes < 0) { printf("aio_test: ERROR: Failed to open %s: %d\n", @@ -616,7 +616,7 @@ void aio_test(void) usleep(500 * 1000); printf("AIO test case 7:Cancel I/O by file descriptor\n"); - g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC); + g_fildes = open(AIO_FILEPATH, O_RDWR | O_CREAT | O_TRUNC, 0666); if (g_fildes < 0) { printf("aio_test: ERROR: Failed to open %s: %d\n", From b4f1e2949462a6e3c8ba7233e48649757906a2aa Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Tue, 19 May 2026 17:56:09 +0800 Subject: [PATCH 340/568] apps: Fix additional open() arguments. Add missing mode arguments to direct open() calls that use O_CREAT. Also open the lp503x device with explicit read-only flags instead of O_CREAT, matching the device-node usage. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- benchmarks/sd_bench/sd_bench_main.c | 2 +- examples/lp503x/lp503x_main.c | 2 +- examples/settings/settings_main.c | 4 ++-- system/nxcamera/nxcamera.c | 2 +- testing/drivers/drivertest/drivertest_audio.c | 3 ++- testing/drivers/sd_stress/sd_stress_main.c | 2 +- testing/fs/smart_test/smart_test.c | 2 +- testing/testsuites/kernel/fs/cases/fs_poll_test.c | 4 ++-- testing/testsuites/kernel/syscall/cases/fcntl_test.c | 2 +- testing/testsuites/kernel/syscall/cases/lseek_test.c | 2 +- testing/testsuites/kernel/syscall/cases/rmdir_test.c | 2 +- testing/testsuites/kernel/syscall/cases/unlink_test.c | 2 +- 12 files changed, 15 insertions(+), 14 deletions(-) diff --git a/benchmarks/sd_bench/sd_bench_main.c b/benchmarks/sd_bench/sd_bench_main.c index 44d30fa63..9822ac748 100644 --- a/benchmarks/sd_bench/sd_bench_main.c +++ b/benchmarks/sd_bench/sd_bench_main.c @@ -451,7 +451,7 @@ int main(int argc, char *argv[]) cfg.run_duration *= 1000; bench_fd = open(BENCHMARK_FILE, - O_CREAT | (verify ? O_RDWR : O_WRONLY) | O_TRUNC); + O_CREAT | (verify ? O_RDWR : O_WRONLY) | O_TRUNC, 0666); if (bench_fd < 0) { diff --git a/examples/lp503x/lp503x_main.c b/examples/lp503x/lp503x_main.c index 5a43da39c..0eba5c1b3 100644 --- a/examples/lp503x/lp503x_main.c +++ b/examples/lp503x/lp503x_main.c @@ -632,7 +632,7 @@ int main(int argc, FAR char *argv[]) int len; int x; - fd = open(CONFIG_EXAMPLES_LP503X_DEVPATH, O_CREAT); + fd = open(CONFIG_EXAMPLES_LP503X_DEVPATH, O_RDONLY); if (fd < 0) { fprintf(stderr, "ERROR: Failed to open %s: %d\n", diff --git a/examples/settings/settings_main.c b/examples/settings/settings_main.c index b284a4843..3f718aa7c 100644 --- a/examples/settings/settings_main.c +++ b/examples/settings/settings_main.c @@ -115,7 +115,7 @@ int settings_main(int argc, FAR char *argv[]) if (ret == -ENOENT) { printf("No existing binary storage file found. Creating it.\n"); - fd = open(bin_path, O_CREAT); + fd = open(bin_path, O_CREAT, 0666); if (fd < 0) { printf("Failed to create settings file\n"); @@ -138,7 +138,7 @@ int settings_main(int argc, FAR char *argv[]) if (ret == -ENOENT) { printf("No existing text storage file found. Creating it.\n"); - fd = open(text_path, O_CREAT); + fd = open(text_path, O_CREAT, 0666); if (fd < 0) { printf("Failed to create settings file\n"); diff --git a/system/nxcamera/nxcamera.c b/system/nxcamera/nxcamera.c index b8f5d41aa..331ff6214 100644 --- a/system/nxcamera/nxcamera.c +++ b/system/nxcamera/nxcamera.c @@ -575,7 +575,7 @@ int nxcamera_setfile(FAR struct nxcamera_s *pcam, FAR const char *pfile, /* Try to open the file */ - temp_fd = open(pfile, O_CREAT | O_RDWR); + temp_fd = open(pfile, O_CREAT | O_RDWR, 0666); if (temp_fd == -1) { /* Error opening the file */ diff --git a/testing/drivers/drivertest/drivertest_audio.c b/testing/drivers/drivertest/drivertest_audio.c index de12da3d1..0232d32b7 100644 --- a/testing/drivers/drivertest/drivertest_audio.c +++ b/testing/drivers/drivertest/drivertest_audio.c @@ -382,7 +382,8 @@ static int audio_test_prepare(FAR struct audio_state_s *state, } else { - state->out_fd = open(state->outfile, O_WRONLY | O_CREAT | O_TRUNC); + state->out_fd = open(state->outfile, + O_WRONLY | O_CREAT | O_TRUNC, 0666); } if (state->out_fd == -1) diff --git a/testing/drivers/sd_stress/sd_stress_main.c b/testing/drivers/sd_stress/sd_stress_main.c index da6e4f5c7..39c3e563e 100644 --- a/testing/drivers/sd_stress/sd_stress_main.c +++ b/testing/drivers/sd_stress/sd_stress_main.c @@ -160,7 +160,7 @@ static bool create_files(const char *dir, const char *name, bytes[j] = (bytes[j] + i) & 0xff; } - int fd = open(path, O_CREAT | O_RDWR); + int fd = open(path, O_CREAT | O_RDWR, 0666); if (fd < 0) { diff --git a/testing/fs/smart_test/smart_test.c b/testing/fs/smart_test/smart_test.c index 13bd393c8..f439cdfda 100644 --- a/testing/fs/smart_test/smart_test.c +++ b/testing/fs/smart_test/smart_test.c @@ -393,7 +393,7 @@ static int smart_circular_log_test(char *filename) /* Open the circular log file */ - fd = open(filename, O_RDWR | O_CREAT); + fd = open(filename, O_RDWR | O_CREAT, 0666); if (fd == -1) { printf("Unable to create file %s\n", filename); diff --git a/testing/testsuites/kernel/fs/cases/fs_poll_test.c b/testing/testsuites/kernel/fs/cases/fs_poll_test.c index e51ae9ee9..fcbcaf246 100644 --- a/testing/testsuites/kernel/fs/cases/fs_poll_test.c +++ b/testing/testsuites/kernel/fs/cases/fs_poll_test.c @@ -59,13 +59,13 @@ void test_nuttx_fs_poll01(FAR void **state) int poll01_ret; struct pollfd poll01_fds[5]; - poll01_fd1 = open(I_FILE1, O_RDONLY | O_CREAT); + poll01_fd1 = open(I_FILE1, O_RDONLY | O_CREAT, 0666); assert_true(poll01_fd1 >= 0); poll01_fds[0].fd = poll01_fd1; poll01_fds[0].events = POLLOUT; - poll01_fd2 = open(I_FILE2, O_RDWR | O_CREAT); + poll01_fd2 = open(I_FILE2, O_RDWR | O_CREAT, 0666); assert_true(poll01_fd2 >= 0); poll01_fds[1].fd = poll01_fd2; diff --git a/testing/testsuites/kernel/syscall/cases/fcntl_test.c b/testing/testsuites/kernel/syscall/cases/fcntl_test.c index 0897f65b4..2dfdcc370 100644 --- a/testing/testsuites/kernel/syscall/cases/fcntl_test.c +++ b/testing/testsuites/kernel/syscall/cases/fcntl_test.c @@ -306,7 +306,7 @@ void test_nuttx_syscall_fcntl06(FAR void **state) sprintf(fname, "fcntl06_%d", gettid()); - fd = open(fname, O_RDWR | O_CREAT); + fd = open(fname, O_RDWR | O_CREAT, 0700); assert_true(fd > 0); for (lc = 0; lc < 10; lc++) diff --git a/testing/testsuites/kernel/syscall/cases/lseek_test.c b/testing/testsuites/kernel/syscall/cases/lseek_test.c index cef521915..619f61a72 100644 --- a/testing/testsuites/kernel/syscall/cases/lseek_test.c +++ b/testing/testsuites/kernel/syscall/cases/lseek_test.c @@ -91,7 +91,7 @@ void test_nuttx_syscall_lseek01(FAR void **state) snprintf(filename, sizeof(filename), "%s_file", __func__); - fd = open(filename, O_RDWR | O_CREAT); + fd = open(filename, O_RDWR | O_CREAT, 0644); if (fd > 0) { diff --git a/testing/testsuites/kernel/syscall/cases/rmdir_test.c b/testing/testsuites/kernel/syscall/cases/rmdir_test.c index 8068a2253..20c74a9c6 100644 --- a/testing/testsuites/kernel/syscall/cases/rmdir_test.c +++ b/testing/testsuites/kernel/syscall/cases/rmdir_test.c @@ -103,7 +103,7 @@ void test_nuttx_syscall_rmdir02(FAR void **state) assert_int_equal(ret, 0); ret = mkdir("Rmdir02_testdir/test1", (S_IRWXU | S_IRWXG | S_IRWXO)); assert_int_equal(ret, 0); - fd = open("Rmdir02_testfile2", O_CREAT | O_RDWR); + fd = open("Rmdir02_testfile2", O_CREAT | O_RDWR, 0700); if (fd > 0) close(fd); diff --git a/testing/testsuites/kernel/syscall/cases/unlink_test.c b/testing/testsuites/kernel/syscall/cases/unlink_test.c index f3a7e1697..e5b771786 100644 --- a/testing/testsuites/kernel/syscall/cases/unlink_test.c +++ b/testing/testsuites/kernel/syscall/cases/unlink_test.c @@ -55,7 +55,7 @@ void test_nuttx_syscall_unlink01(FAR void **state) sprintf(fname, "%s_file", __func__); - fd = open(fname, O_RDWR | O_CREAT); + fd = open(fname, O_RDWR | O_CREAT, 0700); if (fd > 0) { close(fd); From fcd10aa7259e5e80eb9aed98477e407d827cceb4 Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Wed, 20 May 2026 09:46:12 +0800 Subject: [PATCH 341/568] examples/lp503x: Open device write-only. Open the LP503X device with O_WRONLY because the driver registers the device node with write-only permissions and the example controls it through ioctl(). Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- examples/lp503x/lp503x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lp503x/lp503x_main.c b/examples/lp503x/lp503x_main.c index 0eba5c1b3..9cc99d3b7 100644 --- a/examples/lp503x/lp503x_main.c +++ b/examples/lp503x/lp503x_main.c @@ -632,7 +632,7 @@ int main(int argc, FAR char *argv[]) int len; int x; - fd = open(CONFIG_EXAMPLES_LP503X_DEVPATH, O_RDONLY); + fd = open(CONFIG_EXAMPLES_LP503X_DEVPATH, O_WRONLY); if (fd < 0) { fprintf(stderr, "ERROR: Failed to open %s: %d\n", From 5355adb9cf789340b89b948b6a35b6aafb4c5a47 Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Wed, 20 May 2026 21:36:08 +0800 Subject: [PATCH 342/568] apps: Fix codespell warnings. Fix the reported typo warnings and ignore the V4L2 parm field name in apps codespell configuration, matching the main NuttX repository. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- .codespellrc | 2 +- system/nxcamera/nxcamera.c | 12 ++++++------ testing/testsuites/kernel/syscall/cases/fcntl_test.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.codespellrc b/.codespellrc index c2a1ecdfc..8bcdf2bc7 100644 --- a/.codespellrc +++ b/.codespellrc @@ -10,4 +10,4 @@ skip = LICENSE, # Ignore words list (FTP protocol commands and technical terms) -ignore-words-list = ALLO, ARCHTYPE +ignore-words-list = ALLO, ARCHTYPE, parm diff --git a/system/nxcamera/nxcamera.c b/system/nxcamera/nxcamera.c index 331ff6214..0f74b418a 100644 --- a/system/nxcamera/nxcamera.c +++ b/system/nxcamera/nxcamera.c @@ -676,7 +676,7 @@ int nxcamera_stream(FAR struct nxcamera_s *pcam, int i; struct v4l2_buffer buf; struct v4l2_requestbuffers req; - struct v4l2_streamparm parm; + struct v4l2_streamparm param; DEBUGASSERT(pcam != NULL); @@ -720,11 +720,11 @@ int nxcamera_stream(FAR struct nxcamera_s *pcam, return ret; } - memset(&parm, 0, sizeof(parm)); - parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - parm.parm.capture.timeperframe.denominator = framerate; - parm.parm.capture.timeperframe.numerator = 1; - ret = ioctl(pcam->capture_fd, VIDIOC_S_PARM, (uintptr_t)&parm); + memset(¶m, 0, sizeof(param)); + param.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + param.parm.capture.timeperframe.denominator = framerate; + param.parm.capture.timeperframe.numerator = 1; + ret = ioctl(pcam->capture_fd, VIDIOC_S_PARM, (uintptr_t)¶m); if (ret < 0) { ret = -errno; diff --git a/testing/testsuites/kernel/syscall/cases/fcntl_test.c b/testing/testsuites/kernel/syscall/cases/fcntl_test.c index 2dfdcc370..2737621ce 100644 --- a/testing/testsuites/kernel/syscall/cases/fcntl_test.c +++ b/testing/testsuites/kernel/syscall/cases/fcntl_test.c @@ -113,7 +113,7 @@ void test_nuttx_syscall_fcntl01(FAR void **state) flags = fcntl(fd[2], F_GETFL, 0); assert_false((flags & (O_NDELAY | O_APPEND | O_WRONLY)) == 0); - /* Check that flags are not cummulative */ + /* Check that flags are not cumulative */ assert_false(fcntl(fd[2], F_SETFL, 0) == -1); From 2ad3e4e17be61f6f98acfc6bba2c19fe3f753f11 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Wed, 20 May 2026 09:25:25 +0200 Subject: [PATCH 343/568] examples/pwm: remove refenrences to PULSECOUNT Remove refenrences to PULSECOUNT from PWM example. Pulse count driver will be handled by separate application. Signed-off-by: raiden00pl --- examples/pwm/Kconfig | 12 +------- examples/pwm/pwm.h | 10 +------ examples/pwm/pwm_main.c | 64 ++++++++--------------------------------- 3 files changed, 14 insertions(+), 72 deletions(-) diff --git a/examples/pwm/Kconfig b/examples/pwm/Kconfig index b6e0a3d82..facd1b6dd 100644 --- a/examples/pwm/Kconfig +++ b/examples/pwm/Kconfig @@ -28,8 +28,7 @@ config EXAMPLES_PWM_DURATION int "Default PWM duration" default 5 ---help--- - The default PWM pulse train duration in seconds. Used only if the current - pulse count is zero. Default: 5 seconds + The default PWM pulse train duration in seconds. Default: 5 seconds config EXAMPLES_PWM_DUTYPCT1 int "First PWM duty percentage" @@ -135,13 +134,4 @@ config EXAMPLES_PWM_CHANNEL6 endif -config EXAMPLES_PWM_PULSECOUNT - int "Default pulse count" - default 0 - depends on PWM_PULSECOUNT - ---help--- - The initial PWM pulse count. This option is only available if - PWM_PULSECOUNT is defined. Default: 0 (i.e., use the duration, not - the count). - endif diff --git a/examples/pwm/pwm.h b/examples/pwm/pwm.h index d5c15aed9..389241626 100644 --- a/examples/pwm/pwm.h +++ b/examples/pwm/pwm.h @@ -45,12 +45,8 @@ * CONFIG_EXAMPLES_PWM_CHANNELn - The PWM channel number for channel n. * Default: n * CONFIG_EXAMPLES_PWM_DURATION - The initial PWM pulse train duration - * in seconds. Used only if the current pulse count is zero - * (pulse count is only supported if CONFIG_PWM_PULSECOUNT is defined). + * in seconds. * Default: 5 seconds - * CONFIG_EXAMPLES_PWM_PULSECOUNT - The initial PWM pulse count. - * This option is only available if CONFIG_PWM_PULSECOUNT is defined. - * Default: 0 (i.e., use the duration, not the count). */ #ifndef CONFIG_PWM @@ -69,10 +65,6 @@ # define CONFIG_EXAMPLES_PWM_DURATION 5 #endif -#ifndef CONFIG_EXAMPLES_PWM_PULSECOUNT -# define CONFIG_EXAMPLES_PWM_PULSECOUNT 0 -#endif - /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/examples/pwm/pwm_main.c b/examples/pwm/pwm_main.c index 085a36b9e..e373a5bb0 100644 --- a/examples/pwm/pwm_main.c +++ b/examples/pwm/pwm_main.c @@ -98,9 +98,6 @@ struct pwm_state_s int8_t channels[CONFIG_PWM_NCHANNELS]; uint8_t duties[CONFIG_PWM_NCHANNELS]; uint32_t freq; -#ifdef CONFIG_PWM_PULSECOUNT - uint32_t count; -#endif int duration; }; @@ -230,11 +227,6 @@ static void pwm_help(FAR struct pwm_state_s *pwm) } printf("\n"); -#ifdef CONFIG_PWM_PULSECOUNT - printf(" [-n count] selects the pulse count. " - "Default: %d Current: %" PRIx32 "\n", - CONFIG_EXAMPLES_PWM_PULSECOUNT, pwm->count); -#endif printf(" [-t duration] is the duration of the pulse train in seconds. " "Default: %d Current: %d\n", CONFIG_EXAMPLES_PWM_DURATION, pwm->duration); @@ -361,20 +353,6 @@ static void parse_args(FAR struct pwm_state_s *pwm, int argc, index += nargs; break; -#ifdef CONFIG_PWM_PULSECOUNT - case 'n': - nargs = arg_decimal(&argv[index], &value); - if (value < 0) - { - printf("Count must be non-negative: %ld\n", value); - exit(1); - } - - pwm->count = (uint32_t)value; - index += nargs; - break; -#endif - case 'p': nargs = arg_string(&argv[index], &str); pwm_devpath(pwm, str); @@ -449,9 +427,6 @@ int main(int argc, FAR char *argv[]) #endif g_pwmstate.freq = CONFIG_EXAMPLES_PWM_FREQUENCY; g_pwmstate.duration = CONFIG_EXAMPLES_PWM_DURATION; -#ifdef CONFIG_PWM_PULSECOUNT - g_pwmstate.count = CONFIG_EXAMPLES_PWM_PULSECOUNT; -#endif g_pwmstate.initialized = true; } @@ -511,10 +486,6 @@ int main(int argc, FAR char *argv[]) info.channels[i].channel, info.channels[i].duty); } -#ifdef CONFIG_PWM_PULSECOUNT - info.channels[0].count = g_pwmstate.count; - printf(" count: %" PRIx32, info.channels[0].count); -#endif printf("\n"); ret = ioctl(fd, PWMIOC_SETCHARACTERISTICS, @@ -526,9 +497,7 @@ int main(int argc, FAR char *argv[]) goto errout_with_dev; } - /* Then start the pulse train. Since the driver was opened in blocking - * mode, this call will block if the count value is greater than zero. - */ + /* Then start the pulse train. */ ret = ioctl(fd, PWMIOC_START, 0); if (ret < 0) @@ -537,28 +506,19 @@ int main(int argc, FAR char *argv[]) goto errout_with_dev; } - /* It a non-zero count was not specified, then wait for the selected - * duration, then stop the PWM output. - */ + /* Wait for the specified duration, then stop the PWM output. */ -#ifdef CONFIG_PWM_PULSECOUNT - if (info.channels[0].count == 0) -#endif + sleep(g_pwmstate.duration); + + /* Then stop the pulse train */ + + printf("pwm_main: stopping output\n"); + + ret = ioctl(fd, PWMIOC_STOP, 0); + if (ret < 0) { - /* Wait for the specified duration */ - - sleep(g_pwmstate.duration); - - /* Then stop the pulse train */ - - printf("pwm_main: stopping output\n"); - - ret = ioctl(fd, PWMIOC_STOP, 0); - if (ret < 0) - { - printf("pwm_main: ioctl(PWMIOC_STOP) failed: %d\n", errno); - goto errout_with_dev; - } + printf("pwm_main: ioctl(PWMIOC_STOP) failed: %d\n", errno); + goto errout_with_dev; } close(fd); From 5cce60aa9afe7631a86aa2cbe61492bbf27b172a Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Wed, 20 May 2026 09:26:55 +0200 Subject: [PATCH 344/568] examples: add pulse count example add pulse count driver example. Previously it was mixed with PWM example. Signed-off-by: raiden00pl --- examples/pulsecount/CMakeLists.txt | 33 ++++ examples/pulsecount/Kconfig | 42 +++++ examples/pulsecount/Make.defs | 25 +++ examples/pulsecount/Makefile | 32 ++++ examples/pulsecount/pulsecount_main.c | 247 ++++++++++++++++++++++++++ 5 files changed, 379 insertions(+) create mode 100644 examples/pulsecount/CMakeLists.txt create mode 100644 examples/pulsecount/Kconfig create mode 100644 examples/pulsecount/Make.defs create mode 100644 examples/pulsecount/Makefile create mode 100644 examples/pulsecount/pulsecount_main.c diff --git a/examples/pulsecount/CMakeLists.txt b/examples/pulsecount/CMakeLists.txt new file mode 100644 index 000000000..356b1b982 --- /dev/null +++ b/examples/pulsecount/CMakeLists.txt @@ -0,0 +1,33 @@ +# ############################################################################## +# apps/examples/pulsecount/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_EXAMPLES_PULSECOUNT) + nuttx_add_application( + NAME + pulsecount + STACKSIZE + ${CONFIG_DEFAULT_TASK_STACKSIZE} + MODULE + ${CONFIG_EXAMPLES_PULSECOUNT} + SRCS + pulsecount_main.c) +endif() diff --git a/examples/pulsecount/Kconfig b/examples/pulsecount/Kconfig new file mode 100644 index 000000000..4f4526868 --- /dev/null +++ b/examples/pulsecount/Kconfig @@ -0,0 +1,42 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_PULSECOUNT + tristate "pulsecount example" + default n + depends on PULSECOUNT + ---help--- + Enable the finite pulsecount example + +if EXAMPLES_PULSECOUNT + +config EXAMPLES_PULSECOUNT_DEVPATH + string "pulsecount device path" + default "/dev/pulsecount0" + ---help--- + The path to the pulsecount device. Default: /dev/pulsecount0 + +config EXAMPLES_PULSECOUNT_HIGH_NS + int "Default pulsecount high time" + default 5000000 + ---help--- + The default pulsecount high time in nanoseconds. + Default: 5000000 ns + +config EXAMPLES_PULSECOUNT_LOW_NS + int "Default pulsecount low time" + default 5000000 + ---help--- + The default pulsecount low time in nanoseconds. + Default: 5000000 ns + +config EXAMPLES_PULSECOUNT_COUNT + int "Default pulsecount count" + default 100 + range 1 2147483647 + ---help--- + The default number of pulses to generate. + +endif diff --git a/examples/pulsecount/Make.defs b/examples/pulsecount/Make.defs new file mode 100644 index 000000000..db46b5478 --- /dev/null +++ b/examples/pulsecount/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/examples/pulsecount/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_PULSECOUNT),) +CONFIGURED_APPS += $(APPDIR)/examples/pulsecount +endif diff --git a/examples/pulsecount/Makefile b/examples/pulsecount/Makefile new file mode 100644 index 000000000..b03e07503 --- /dev/null +++ b/examples/pulsecount/Makefile @@ -0,0 +1,32 @@ +############################################################################ +# apps/examples/pulsecount/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +MAINSRC = pulsecount_main.c + +PROGNAME = pulsecount +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_PULSECOUNT) + +include $(APPDIR)/Application.mk diff --git a/examples/pulsecount/pulsecount_main.c b/examples/pulsecount/pulsecount_main.c new file mode 100644 index 000000000..82678be08 --- /dev/null +++ b/examples/pulsecount/pulsecount_main.c @@ -0,0 +1,247 @@ +/**************************************************************************** + * apps/examples/pulsecount/pulsecount_main.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct pulsecount_state_s +{ + FAR char *devpath; + uint32_t high_ns; + uint32_t low_ns; + uint32_t count; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void pulsecount_devpath(FAR struct pulsecount_state_s *state, + FAR const char *devpath) +{ + if (state->devpath != NULL) + { + free(state->devpath); + } + + state->devpath = strdup(devpath); +} + +static int arg_string(FAR char **arg, FAR char **value) +{ + FAR char *ptr = *arg; + + if (ptr[2] == '\0') + { + *value = arg[1]; + return 2; + } + + *value = &ptr[2]; + return 1; +} + +static int arg_decimal(FAR char **arg, FAR long *value) +{ + FAR char *string; + int ret; + + ret = arg_string(arg, &string); + *value = strtol(string, NULL, 10); + return ret; +} + +static void pulsecount_help(FAR struct pulsecount_state_s *state) +{ + printf("Usage: pulsecount [OPTIONS]\n"); + printf(" [-p devpath] Default: %s Current: %s\n", + CONFIG_EXAMPLES_PULSECOUNT_DEVPATH, + state->devpath != NULL ? state->devpath : "NONE"); + printf(" [-H high-ns] Default: %d ns Current: %" PRIu32 " ns\n", + CONFIG_EXAMPLES_PULSECOUNT_HIGH_NS, state->high_ns); + printf(" [-L low-ns] Default: %d ns Current: %" PRIu32 " ns\n", + CONFIG_EXAMPLES_PULSECOUNT_LOW_NS, state->low_ns); + printf(" [-n count] Default: %d Current: %" PRIu32 "\n", + CONFIG_EXAMPLES_PULSECOUNT_COUNT, state->count); + printf(" [-h] shows this message and exits\n"); +} + +static void parse_args(FAR struct pulsecount_state_s *state, int argc, + FAR char **argv) +{ + FAR char *str; + long value; + int index; + int nargs; + + for (index = 1; index < argc; ) + { + if (argv[index][0] != '-') + { + printf("Invalid options format: %s\n", argv[index]); + exit(1); + } + + switch (argv[index][1]) + { + case 'p': + nargs = arg_string(&argv[index], &str); + pulsecount_devpath(state, str); + index += nargs; + break; + + case 'H': + nargs = arg_decimal(&argv[index], &value); + if (value < 1) + { + printf("High time out of range: %ld\n", value); + exit(1); + } + + state->high_ns = (uint32_t)value; + index += nargs; + break; + + case 'L': + nargs = arg_decimal(&argv[index], &value); + if (value < 1) + { + printf("Low time out of range: %ld\n", value); + exit(1); + } + + state->low_ns = (uint32_t)value; + index += nargs; + break; + + case 'n': + nargs = arg_decimal(&argv[index], &value); + if (value < 1) + { + printf("Count out of range: %ld\n", value); + exit(1); + } + + state->count = (uint32_t)value; + index += nargs; + break; + + case 'h': + pulsecount_help(state); + exit(0); + + default: + printf("Unsupported option: %s\n", argv[index]); + pulsecount_help(state); + exit(1); + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + struct pulsecount_state_s state; + struct pulsecount_info_s info; + int fd; + int ret; + + /* Defaults */ + + memset(&state, 0, sizeof(state)); + state.high_ns = CONFIG_EXAMPLES_PULSECOUNT_HIGH_NS; + state.low_ns = CONFIG_EXAMPLES_PULSECOUNT_LOW_NS; + state.count = CONFIG_EXAMPLES_PULSECOUNT_COUNT; + + /* Parse args */ + + parse_args(&state, argc, argv); + + if (state.devpath == NULL) + { + pulsecount_devpath(&state, CONFIG_EXAMPLES_PULSECOUNT_DEVPATH); + } + + fd = open(state.devpath, O_RDONLY); + if (fd < 0) + { + printf("pulsecount: open %s failed: %d\n", state.devpath, errno); + goto errout; + } + + memset(&info, 0, sizeof(info)); + info.high_ns = state.high_ns; + info.low_ns = state.low_ns; + info.count = state.count; + + printf("pulsecount: high: %" PRIu32 " ns low: %" PRIu32 + " ns count: %" PRIu32 "\n", + info.high_ns, info.low_ns, info.count); + + ret = ioctl(fd, PULSECOUNTIOC_SETCHARACTERISTICS, + (unsigned long)((uintptr_t)&info)); + if (ret < 0) + { + printf("pulsecount: ioctl(PULSECOUNTIOC_SETCHARACTERISTICS) " + "failed: %d\n", errno); + goto errout_with_dev; + } + + ret = ioctl(fd, PULSECOUNTIOC_START, 0); + if (ret < 0) + { + printf("pulsecount: ioctl(PULSECOUNTIOC_START) failed: %d\n", errno); + goto errout_with_dev; + } + + close(fd); + fflush(stdout); + return OK; + +errout_with_dev: + close(fd); +errout: + fflush(stdout); + return ERROR; +} From c9c5c75d08828aca7fb695a2a0a65a57063641f1 Mon Sep 17 00:00:00 2001 From: Shoji Tokunaga Date: Fri, 22 May 2026 09:04:14 +0900 Subject: [PATCH 345/568] examples/rust: Fix hello_rust_cargo CMake settings Use the hello_rust_cargo-specific Kconfig symbols for the built-in application stack size and priority. Previously, CMake referenced the generic hello example symbols, so the configured hello_rust_cargo stack size could be ignored. Signed-off-by: Shoji Tokunaga --- examples/rust/hello/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/rust/hello/CMakeLists.txt b/examples/rust/hello/CMakeLists.txt index c0daea419..2a83be84e 100644 --- a/examples/rust/hello/CMakeLists.txt +++ b/examples/rust/hello/CMakeLists.txt @@ -25,7 +25,7 @@ if(CONFIG_EXAMPLES_HELLO_RUST_CARGO) nuttx_add_application( NAME ${CONFIG_EXAMPLES_HELLO_RUST_CARGO_PROGNAME} STACKSIZE - ${CONFIG_EXAMPLES_HELLO_STACKSIZE} PRIORITY - ${CONFIG_EXAMPLES_HELLO_PRIORITY}) + ${CONFIG_EXAMPLES_HELLO_RUST_CARGO_STACKSIZE} PRIORITY + ${CONFIG_EXAMPLES_HELLO_RUST_CARGO_PRIORITY}) endif() # CONFIG_EXAMPLES_HELLO_RUST_CARGO From 965cddfa365f261c3c8ace3dbe35a0a1cca70c4e Mon Sep 17 00:00:00 2001 From: Tiago Medicci Date: Thu, 21 May 2026 14:29:22 +0200 Subject: [PATCH 346/568] system/libffi: Add libffi package integration Add Kconfig, build rules, and ignore entries required to build and package libffi as a standalone system component. Signed-off-by: Tiago Medicci --- system/libffi/.gitignore | 4 ++ system/libffi/Kconfig | 24 +++++++ system/libffi/Make.defs | 28 ++++++++ system/libffi/Makefile | 135 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 system/libffi/.gitignore create mode 100644 system/libffi/Kconfig create mode 100644 system/libffi/Make.defs create mode 100644 system/libffi/Makefile diff --git a/system/libffi/.gitignore b/system/libffi/.gitignore new file mode 100644 index 000000000..26d13e2cd --- /dev/null +++ b/system/libffi/.gitignore @@ -0,0 +1,4 @@ +/*.zip +/build/ +/install/ +/libffi/ diff --git a/system/libffi/Kconfig b/system/libffi/Kconfig new file mode 100644 index 000000000..0b11516ef --- /dev/null +++ b/system/libffi/Kconfig @@ -0,0 +1,24 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LIB_LIBFFI + bool "libffi" + default n + ---help--- + Enable the libffi Foreign Function Interface library. libffi + provides a portable way to call C functions with arguments + determined at runtime. It is required by CPython's _ctypes module. + +if LIB_LIBFFI + +config LIB_LIBFFI_VERSION + string "libffi commit hash" + default "9760868682cc9a33008761f158d86481d56738aa" + ---help--- + Git commit hash of the libffi repository to download and build. + The source is fetched from https://github.com/libffi/libffi at + the specified commit. + +endif # LIB_LIBFFI diff --git a/system/libffi/Make.defs b/system/libffi/Make.defs new file mode 100644 index 000000000..5949ff04f --- /dev/null +++ b/system/libffi/Make.defs @@ -0,0 +1,28 @@ +############################################################################ +# apps/system/libffi/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_LIB_LIBFFI),) +CONFIGURED_APPS += $(APPDIR)/system/libffi + +EXTRA_LIBPATHS += -L$(APPDIR)/system/libffi/install/lib +EXTRA_LIBS += -lffi +endif diff --git a/system/libffi/Makefile b/system/libffi/Makefile new file mode 100644 index 000000000..c2b4810ed --- /dev/null +++ b/system/libffi/Makefile @@ -0,0 +1,135 @@ +############################################################################ +# apps/system/libffi/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +LIBFFI_URL = https://github.com/libffi/libffi/archive +LIBFFI_COMMIT = $(patsubst "%",%,$(strip $(CONFIG_LIB_LIBFFI_VERSION))) +LIBFFI_ZIP = libffi-$(LIBFFI_COMMIT).zip +LIBFFI_SRC = libffi +LIBFFI_BUILDDIR = $(CURDIR)/build +LIBFFI_INSTALLDIR = $(CURDIR)/install +APPS_INCDIR = $(APPDIR)$(DELIM)include + +UNPACK ?= unzip -q -o + +# --------------------------------------------------------------------------- +# Derive the autotools --host triplet from the NuttX configuration. +# +# libffi's configure.host matches on patterns such as: +# riscv*-*-* arm*-*-* aarch64*-*-* xtensa*-*-* +# mips*-*-* i?86-*-* x86_64-*-* +# +# We map CONFIG_ARCH (and, for RISC-V, the word-size selectors) to the +# CPU part that libffi expects, then append "-nuttx-elf" as vendor-os. +# --------------------------------------------------------------------------- + +ifeq ($(CONFIG_ARCH),risc-v) + ifeq ($(CONFIG_ARCH_RV64),y) + LIBFFI_CPU = riscv64 + else + LIBFFI_CPU = riscv32 + endif +else ifeq ($(CONFIG_ARCH),arm64) + LIBFFI_CPU = aarch64 +else ifeq ($(CONFIG_ARCH),arm) + LIBFFI_CPU = arm +else ifeq ($(CONFIG_ARCH),xtensa) + LIBFFI_CPU = xtensa +else ifeq ($(CONFIG_ARCH),mips) + LIBFFI_CPU = mips +else ifeq ($(CONFIG_ARCH),x86_64) + LIBFFI_CPU = x86_64 +else ifeq ($(CONFIG_ARCH),x86) + LIBFFI_CPU = i686 +else + LIBFFI_CPU = $(subst -,,$(CONFIG_ARCH)) +endif + +LIBFFI_HOST = $(LIBFFI_CPU)-nuttx-elf + +# --------------------------------------------------------------------------- +# CFLAGS for the libffi build itself. +# +# We start from the NuttX-provided CFLAGS (which already carry -march, +# -mabi, -isystem paths, -D__NuttX__, etc.) and add a few flags that the +# library needs. We deliberately strip -nostdlib because autoconf link +# checks need the default startfiles/libs to succeed. +# --------------------------------------------------------------------------- + +LIBFFI_CFLAGS = $(filter-out -nostdlib -Werror -Werror=% -Wno-cpp,$(CFLAGS)) +LIBFFI_CFLAGS += -ffunction-sections -fdata-sections -O2 + +# --------------------------------------------------------------------------- +# Download, autoreconf, configure, build, install +# --------------------------------------------------------------------------- + +ifeq ($(wildcard $(LIBFFI_SRC)/.git),) + +$(LIBFFI_ZIP): + @echo "Downloading: $(LIBFFI_URL)/$(LIBFFI_COMMIT).zip" + $(Q) curl -L $(LIBFFI_URL)/$(LIBFFI_COMMIT).zip -o $(LIBFFI_ZIP) + +$(LIBFFI_SRC): $(LIBFFI_ZIP) + @echo "Unpacking: $(LIBFFI_ZIP) -> $(LIBFFI_SRC)" + $(Q) $(UNPACK) $(LIBFFI_ZIP) + $(Q) mv libffi-$(LIBFFI_COMMIT) $(LIBFFI_SRC) + +endif + +$(LIBFFI_SRC)/configure: $(LIBFFI_SRC) + @echo "Generating libffi configure script (autoreconf)" + $(Q) (cd $(LIBFFI_SRC) && autoreconf -v -i) + +$(LIBFFI_INSTALLDIR)/lib/libffi.a: $(LIBFFI_SRC)/configure + $(Q) mkdir -p $(LIBFFI_BUILDDIR) + $(Q) ( \ + cd $(LIBFFI_BUILDDIR) && \ + $(CURDIR)/$(LIBFFI_SRC)/configure \ + --host=$(LIBFFI_HOST) \ + --prefix=$(LIBFFI_INSTALLDIR) \ + --disable-shared \ + --enable-static \ + --disable-docs \ + --disable-exec-static-tramp \ + --disable-multi-os-directory \ + CC="$(CC)" \ + CFLAGS="$(LIBFFI_CFLAGS)" \ + AR="$(CROSSDEV)ar" \ + RANLIB="$(CROSSDEV)ranlib" \ + ) + $(MAKE) -C $(LIBFFI_BUILDDIR) -j$(shell nproc) + $(MAKE) -C $(LIBFFI_BUILDDIR) install + +context:: $(LIBFFI_INSTALLDIR)/lib/libffi.a + $(Q) mkdir -p $(APPS_INCDIR) + $(Q) cp $(LIBFFI_INSTALLDIR)/include/*.h $(APPS_INCDIR) + +distclean:: + $(call DELDIR, $(LIBFFI_BUILDDIR)) + $(call DELDIR, $(LIBFFI_INSTALLDIR)) + $(call DELDIR, $(LIBFFI_SRC)) + $(call DELFILE, $(LIBFFI_ZIP)) + $(call DELFILE, $(APPS_INCDIR)/ffi.h) + $(call DELFILE, $(APPS_INCDIR)/ffitarget.h) + +include $(APPDIR)/Application.mk From 58b780c280f3bab89d947be17c5c398e6556711a Mon Sep 17 00:00:00 2001 From: Tiago Medicci Date: Thu, 21 May 2026 14:29:12 +0200 Subject: [PATCH 347/568] interpreters/python: Add ctypes prototype patches for NuttX Integrate NuttX-specific ctypes and posixmodule updates. Signed-off-by: Tiago Medicci --- interpreters/python/Kconfig | 1 + interpreters/python/Makefile | 6 ++++++ interpreters/python/Setup.local.in | 1 - interpreters/python/config.site.in | 4 ++++ ...no-set_errno-to-avoid-nuttx-macro-coll.patch | 17 +++++++++++++++++ .../0020-ctypes-skip-pythonapi-on-nuttx.patch | 11 +++++++++++ ...sixmodule-ignore-utime-enosys-on-nuttx.patch | 16 ++++++++++++++++ 7 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 interpreters/python/patch/0019-undef-get_errno-set_errno-to-avoid-nuttx-macro-coll.patch create mode 100644 interpreters/python/patch/0020-ctypes-skip-pythonapi-on-nuttx.patch create mode 100644 interpreters/python/patch/0021-posixmodule-ignore-utime-enosys-on-nuttx.patch diff --git a/interpreters/python/Kconfig b/interpreters/python/Kconfig index dfc5fd4cc..a0582835f 100644 --- a/interpreters/python/Kconfig +++ b/interpreters/python/Kconfig @@ -6,6 +6,7 @@ config INTERPRETERS_CPYTHON tristate "CPython" depends on LIB_ZLIB + depends on !LIBC_DLFCN || LIB_LIBFFI depends on EXPERIMENTAL default n ---help--- diff --git a/interpreters/python/Makefile b/interpreters/python/Makefile index a339bbe02..1b1392cac 100644 --- a/interpreters/python/Makefile +++ b/interpreters/python/Makefile @@ -88,6 +88,9 @@ $(CPYTHON_UNPACKNAME): $(CPYTHON_ZIP) $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0016-fix-timezone-offset-check-when-time-t-is-unsigned.patch $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0017-stdlib-zip-keep-pydecimal-and-trim-tooling-extras.patch $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0018-ignore-chmod-on-nuttx-like-wasi.patch + $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0019-undef-get_errno-set_errno-to-avoid-nuttx-macro-coll.patch + $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0020-ctypes-skip-pythonapi-on-nuttx.patch + $(Q) patch -p1 -d $(CPYTHON_UNPACKNAME) < patch$(DELIM)0021-posixmodule-ignore-utime-enosys-on-nuttx.patch $(HOSTPYTHON): mkdir -p $(HOSTBUILD) @@ -128,6 +131,9 @@ $(SETUP_LOCAL): ifneq ($(CONFIG_ARCH_HAVE_FORK),y) @echo "_posixsubprocess" >> $@ endif +ifneq ($(CONFIG_LIBC_DLFCN),y) + @echo "_ctypes" >> $@ +endif # For the Python's `configure` script, please consider the following # when building for NuttX: diff --git a/interpreters/python/Setup.local.in b/interpreters/python/Setup.local.in index 0bd116574..d8c27292b 100644 --- a/interpreters/python/Setup.local.in +++ b/interpreters/python/Setup.local.in @@ -11,7 +11,6 @@ _codecs_iso2022 _codecs_jp _codecs_kr _codecs_tw -_ctypes _decimal _elementtree _heapq diff --git a/interpreters/python/config.site.in b/interpreters/python/config.site.in index 52c04725a..d19337ea6 100644 --- a/interpreters/python/config.site.in +++ b/interpreters/python/config.site.in @@ -31,3 +31,7 @@ export ac_cv_func_utimes="yes" export ac_cv_func_getuid="yes" export ac_cv_func_sysconf="yes" export ac_cv_func_umask="yes" +export ac_cv_func_ffi_prep_cif_var="yes" +export ac_cv_func_ffi_prep_closure_loc="yes" +export ac_cv_func_ffi_closure_alloc="yes" +export ac_cv_func_utimes="no" diff --git a/interpreters/python/patch/0019-undef-get_errno-set_errno-to-avoid-nuttx-macro-coll.patch b/interpreters/python/patch/0019-undef-get_errno-set_errno-to-avoid-nuttx-macro-coll.patch new file mode 100644 index 000000000..905827466 --- /dev/null +++ b/interpreters/python/patch/0019-undef-get_errno-set_errno-to-avoid-nuttx-macro-coll.patch @@ -0,0 +1,17 @@ +--- a/Modules/_ctypes/callproc.c ++++ b/Modules/_ctypes/callproc.c +@@ -91,6 +91,14 @@ + #include + #endif + ++/* NuttX errno.h defines get_errno() and set_errno(e) as macros. ++ Undef them so that CPython's static functions of the same name ++ in this file compile without conflict. */ ++#ifdef __NuttX__ ++#undef get_errno ++#undef set_errno ++#endif ++ + #ifdef _Py_MEMORY_SANITIZER + #include + #endif diff --git a/interpreters/python/patch/0020-ctypes-skip-pythonapi-on-nuttx.patch b/interpreters/python/patch/0020-ctypes-skip-pythonapi-on-nuttx.patch new file mode 100644 index 000000000..99ca460d9 --- /dev/null +++ b/interpreters/python/patch/0020-ctypes-skip-pythonapi-on-nuttx.patch @@ -0,0 +1,11 @@ +--- a/Lib/ctypes/__init__.py ++++ b/Lib/ctypes/__init__.py +@@ -481,6 +481,8 @@ + pythonapi = PyDLL("libpython%d.%d.so" % _sys.version_info[:2]) + elif _sys.platform == "cygwin": + pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) ++elif _sys.platform == "nuttx": ++ pythonapi = None + else: + pythonapi = PyDLL(None) + diff --git a/interpreters/python/patch/0021-posixmodule-ignore-utime-enosys-on-nuttx.patch b/interpreters/python/patch/0021-posixmodule-ignore-utime-enosys-on-nuttx.patch new file mode 100644 index 000000000..664d0f174 --- /dev/null +++ b/interpreters/python/patch/0021-posixmodule-ignore-utime-enosys-on-nuttx.patch @@ -0,0 +1,16 @@ +--- a/Modules/posixmodule.c ++++ b/Modules/posixmodule.c +@@ -6666,6 +6666,13 @@ + } + #endif + ++#if defined(__NuttX__) ++ if (result == -1 && errno == ENOSYS) { ++ /* SmartFS and other NuttX fs do not implement chstat. */ ++ Py_RETURN_NONE; ++ } ++#endif ++ + if (result < 0) { + path_error(path); + return NULL; From c44f9a0556aef8cc7d9e50c5e4a86a41b26e143f Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Sat, 23 May 2026 10:23:47 +0800 Subject: [PATCH 348/568] apps: Fix unchecked strdup()/asprintf() as requested in #1727 Add missing failure handling for direct strdup() and asprintf() calls where the allocated result is consumed locally before any NULL/error check. This keeps the scope to the functions named in #1727 and avoids changing pass-through return sites where callers already receive NULL on allocation failure. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- .codespell-ignore-lines | 2 ++ examples/mount/mount_main.c | 7 +++++ examples/romfs/romfs_main.c | 6 +++++ netutils/chat/chat.c | 42 +++++++++++++++++------------- netutils/ftpc/ftpc_connect.c | 5 ++++ netutils/ftpc/ftpc_listdir.c | 12 +++++++++ netutils/ftpc/ftpc_login.c | 4 +++ netutils/ftpd/ftpd.c | 33 +++++++++++++++++++++++ netutils/webserver/httpd_dirlist.c | 6 ++++- nshlib/nsh_envcmds.c | 22 ++++++++++++++++ nshlib/nsh_netcmds.c | 6 +++++ system/telnet/telnet_chatd.c | 9 ++++++- 12 files changed, 134 insertions(+), 20 deletions(-) diff --git a/.codespell-ignore-lines b/.codespell-ignore-lines index 45628423d..b001b6343 100644 --- a/.codespell-ignore-lines +++ b/.codespell-ignore-lines @@ -6,3 +6,5 @@ object = new Controlse::CCertificate( Controlse::CCertificate cert(se, settings->key_id); auto certificate = Controlse::CCertificate( + * |---------- [-rw-r--r-- 15] afile.txt + g_afile.name = "afile.txt"; diff --git a/examples/mount/mount_main.c b/examples/mount/mount_main.c index c2b4e45b4..e42f0d88b 100644 --- a/examples/mount/mount_main.c +++ b/examples/mount/mount_main.c @@ -217,6 +217,13 @@ static void show_directories(const char *path, int indent) snprintf(g_namebuffer, sizeof(g_namebuffer), "%s/%s", path, direntry->d_name); subdir = strdup(g_namebuffer); + if (subdir == NULL) + { + printf("show_directories: ERROR out of memory\n"); + g_nerrors++; + continue; + } + show_directories(subdir, indent + 1); free(subdir); } diff --git a/examples/romfs/romfs_main.c b/examples/romfs/romfs_main.c index fa957bbd7..7a7395503 100644 --- a/examples/romfs/romfs_main.c +++ b/examples/romfs/romfs_main.c @@ -394,6 +394,12 @@ static void readdirectories(const char *path, struct node_s *entry) snprintf(g_scratchbuffer, sizeof(g_scratchbuffer), "%s/%s", path, direntry->d_name); fullpath = strdup(g_scratchbuffer); + if (fullpath == NULL) + { + printf(" ERROR: Out of memory\n"); + g_nerrors++; + continue; + } if (DIRENT_ISDIRECTORY(direntry->d_type)) { diff --git a/netutils/chat/chat.c b/netutils/chat/chat.c index c1af84ae8..94f79c500 100644 --- a/netutils/chat/chat.c +++ b/netutils/chat/chat.c @@ -108,6 +108,8 @@ static int chat_tokenise(FAR struct chat *priv, int tok_on_delimiter(void) { + FAR struct chat_token *newtok; + if (!tok_pos && !quoted && !no_termin) { /* a) the first character in the script is a delimiter or @@ -122,9 +124,29 @@ static int chat_tokenise(FAR struct chat *priv, /* Terminate the temporary */ tok_str[tok_pos] = '\0'; + newtok = malloc(sizeof(struct chat_token)); + if (newtok == NULL) + { + /* out of memory */ + + return -ENOMEM; + } + + /* Copy the temporary */ + + newtok->string = strdup(tok_str); + if (newtok->string == NULL) + { + free(newtok); + return -ENOMEM; + } + + newtok->no_termin = no_termin; + newtok->next = NULL; + if (tok) { - tok->next = malloc(sizeof(struct chat_token)); + tok->next = newtok; /* The terminated token becomes previous */ @@ -134,26 +156,10 @@ static int chat_tokenise(FAR struct chat *priv, { /* There was no previous token */ - *first_tok = malloc(sizeof(struct chat_token)); + *first_tok = newtok; tok = *first_tok; } - if (!tok) - { - /* out of memory */ - - return -ENOMEM; - } - - /* Copy the temporary */ - - tok->string = strdup(tok_str); - tok->no_termin = no_termin; - - /* Initialize the next token */ - - tok->next = NULL; - /* Reset the buffer position */ tok_pos = 0; diff --git a/netutils/ftpc/ftpc_connect.c b/netutils/ftpc/ftpc_connect.c index 61defa614..f28c40b61 100644 --- a/netutils/ftpc/ftpc_connect.c +++ b/netutils/ftpc/ftpc_connect.c @@ -108,6 +108,11 @@ SESSION ftpc_connect(FAR union ftpc_sockaddr_u *server) */ session->homeldir = strdup(ftpc_lpwd()); + if (session->homeldir == NULL) + { + nerr("ERROR: Failed to allocate local home directory\n"); + goto errout_with_alloc; + } /* And (Re-)connect to the server */ diff --git a/netutils/ftpc/ftpc_listdir.c b/netutils/ftpc/ftpc_listdir.c index 02947ad5c..01ef7dd3a 100644 --- a/netutils/ftpc/ftpc_listdir.c +++ b/netutils/ftpc/ftpc_listdir.c @@ -257,6 +257,7 @@ FAR struct ftpc_dirlist_s *ftpc_listdir(SESSION handle, FAR char *tmpfname; bool iscurrdir; unsigned int nnames; + unsigned int i; int allocsize; int ret; @@ -365,6 +366,17 @@ FAR struct ftpc_dirlist_s *ftpc_listdir(SESSION handle, ftpc_nlstparse(filestream, ftpc_addname, dirlist); DEBUGASSERT(nnames == dirlist->nnames); + + for (i = 0; i < dirlist->nnames; i++) + { + if (dirlist->name[i] == NULL) + { + nerr("ERROR: Failed to allocate directory name\n"); + ftpc_dirfree(dirlist); + dirlist = NULL; + break; + } + } } errout: diff --git a/netutils/ftpc/ftpc_login.c b/netutils/ftpc/ftpc_login.c index 4ee477e00..80a97044a 100644 --- a/netutils/ftpc/ftpc_login.c +++ b/netutils/ftpc/ftpc_login.c @@ -172,6 +172,10 @@ int ftpc_relogin(FAR struct ftpc_session_s *session) if (session->homerdir != NULL) { session->currdir = strdup(session->homerdir); + if (session->currdir == NULL) + { + return -ENOMEM; + } } /* If the user has requested a special start up directory, then change to diff --git a/netutils/ftpd/ftpd.c b/netutils/ftpd/ftpd.c index ded7484d7..c62d9ca73 100644 --- a/netutils/ftpd/ftpd.c +++ b/netutils/ftpd/ftpd.c @@ -627,6 +627,11 @@ static bool ftpd_account_login(FAR struct ftpd_session_s *session, if (account->home != NULL) { home = strdup(account->home); + if (home == NULL) + { + ftpd_account_free(account); + return false; + } } flags = account->flags; @@ -645,6 +650,11 @@ static bool ftpd_account_login(FAR struct ftpd_session_s *session, { home = strdup(home); } + + if (home == NULL) + { + return false; + } } if ((flags & FTPD_ACCOUNTFLAG_ADMIN) != 0) @@ -652,6 +662,12 @@ static bool ftpd_account_login(FAR struct ftpd_session_s *session, /* admin user */ session->home = strdup("/"); + if (session->home == NULL) + { + free(home); + return false; + } + session->work = home; } else @@ -660,6 +676,12 @@ static bool ftpd_account_login(FAR struct ftpd_session_s *session, session->home = home; session->work = strdup("/"); + if (session->work == NULL) + { + free(home); + session->home = NULL; + return false; + } } return true; @@ -2517,6 +2539,17 @@ static int ftpd_command_user(FAR struct ftpd_session_s *session) session->loggedin = false; session->home = strdup(home == NULL ? "/" : home); session->work = strdup("/"); + if (session->home == NULL || session->work == NULL) + { + free(session->home); + free(session->work); + session->home = NULL; + session->work = NULL; + + return ftpd_response(session->cmd.sd, session->txtimeout, + g_respfmt1, 451, ' ', + "Memory exhausted !"); + } return ftpd_response(session->cmd.sd, session->txtimeout, g_respfmt1, 230, ' ', "Login successful."); diff --git a/netutils/webserver/httpd_dirlist.c b/netutils/webserver/httpd_dirlist.c index 6dda65286..b77d68e4e 100644 --- a/netutils/webserver/httpd_dirlist.c +++ b/netutils/webserver/httpd_dirlist.c @@ -196,7 +196,11 @@ ssize_t httpd_dirlist(int outfd, FAR struct httpd_fs_file *file) } ret = asprintf(&path, "%s/%s", file->path, dent->d_name); - ASSERT(ret > 0 && path); + if (ret < 0 || path == NULL) + { + nerr("ERROR: asprintf failed\n"); + break; + } /* call stat() to obtain modified time and size */ diff --git a/nshlib/nsh_envcmds.c b/nshlib/nsh_envcmds.c index d2378bb38..442d6b2ba 100644 --- a/nshlib/nsh_envcmds.c +++ b/nshlib/nsh_envcmds.c @@ -257,17 +257,38 @@ int cmd_cd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) else if (strcmp(path, "-") == 0) { alloc = strdup(nsh_getwd(g_oldpwd)); + if (alloc == NULL) + { + nsh_error(vtbl, g_fmtcmdoutofmemory, argv[0]); + ret = ERROR; + goto errout; + } + path = alloc; } #endif else if (strcmp(path, "..") == 0) { alloc = strdup(nsh_getcwd(vtbl)); + if (alloc == NULL) + { + nsh_error(vtbl, g_fmtcmdoutofmemory, argv[0]); + ret = ERROR; + goto errout; + } + path = dirname(alloc); } else { fullpath = nsh_getfullpath(vtbl, path); + if (fullpath == NULL) + { + nsh_error(vtbl, g_fmtcmdoutofmemory, argv[0]); + ret = ERROR; + goto errout; + } + path = fullpath; } @@ -288,6 +309,7 @@ int cmd_cd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) /* Free any memory that was allocated */ +errout: if (alloc) { free(alloc); diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 3171bdfbb..8e25c69a2 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -1555,6 +1555,12 @@ int cmd_wget(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) if (localfile == NULL) { allocfile = strdup(url); + if (allocfile == NULL) + { + fmt = g_fmtcmdoutofmemory; + goto errout; + } + localfile = basename(allocfile); } diff --git a/system/telnet/telnet_chatd.c b/system/telnet/telnet_chatd.c index 5ab503092..582bda725 100644 --- a/system/telnet/telnet_chatd.c +++ b/system/telnet/telnet_chatd.c @@ -40,7 +40,7 @@ /* Leveraged from libtelnet, https://github.com/seanmiddleditch/libtelnet. * Modified and re-released under the BSD license. * - * The original authors of libtelnet are listed below. Per their licesne, + * The original authors of libtelnet are listed below. Per their license, * "The author or authors of this code dedicate any and all copyright * interest in this code to the public domain. We make this dedication for * the benefit of the public at large and to the detriment of our heirs and @@ -52,6 +52,7 @@ * (Also listed in the AUTHORS file are Jack Kelly * and Katherine Flavel ) */ + /**************************************************************************** * Included Files ****************************************************************************/ @@ -254,6 +255,12 @@ static void _online(const char *line, int overflow, void *ud) /* Keep name */ user->name = strdup(line); + if (user->name == NULL) + { + telnet_printf(user->telnet, "Out of memory.\nEnter name: "); + return; + } + telnet_printf(user->telnet, "Welcome, %s!\n", line); return; } From 85680134366118955daa7c00fffada10c9ef3208 Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Sat, 23 May 2026 10:24:19 +0800 Subject: [PATCH 349/568] netutils/thttpd: Apply the same check to related allocation sites Extend the allocation-failure check to httpd_strdup(), the thttpd-local wrapper that has the same failure contract as strdup(). This is logically separable from the direct strdup()/asprintf() fixes: it prevents using hs->hostname before checking whether the wrapped string allocation succeeded, and releases the partially allocated server state on failure. The scope intentionally does not extend to malloc(), calloc(), or other raw allocators because #1727 specifically calls out strdup()/asprintf(), and covering all allocation APIs would make this PR much broader. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- netutils/thttpd/libhttpd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/netutils/thttpd/libhttpd.c b/netutils/thttpd/libhttpd.c index 1a7d46c13..8be1c6ec9 100644 --- a/netutils/thttpd/libhttpd.c +++ b/netutils/thttpd/libhttpd.c @@ -2163,14 +2163,15 @@ FAR httpd_server *httpd_initialize(FAR httpd_sockaddr *sa) #else hs->hostname = httpd_strdup(httpd_ntoa(sa)); #endif - ninfo("hostname: %s\n", hs->hostname); - if (!hs->hostname) { nerr("ERROR: out of memory copying hostname\n"); + free_httpd_server(hs); return NULL; } + ninfo("hostname: %s\n", hs->hostname); + hs->cgi_count = 0; /* Initialize listen sockets */ From 2d6cd7421554a8c040f33b8bc421167f58f055fb Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Sun, 24 May 2026 10:30:11 +0800 Subject: [PATCH 350/568] testing/sd_stress: Handle stale temporary directories Fix #3205 by removing stale sdstress work directories left by previous interrupted or failed runs before starting a new test. The cleanup only removes entries matching the generated tmpNNN file pattern. If the directory contains any unexpected entry, the test fails instead of deleting user data. Also make create_dir() and remove_dir() use their path argument instead of the fixed temporary directory names. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- testing/drivers/sd_stress/sd_stress_main.c | 100 ++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/testing/drivers/sd_stress/sd_stress_main.c b/testing/drivers/sd_stress/sd_stress_main.c index 39c3e563e..882bec362 100644 --- a/testing/drivers/sd_stress/sd_stress_main.c +++ b/testing/drivers/sd_stress/sd_stress_main.c @@ -47,12 +47,14 @@ * Included Files ****************************************************************************/ +#include #include #include #include #include #include #include +#include #include #include @@ -94,7 +96,7 @@ static void usage(void) static bool create_dir(const char *path) { - int ret = mkdir(TEMPDIR, S_IRWXU | S_IRWXG | S_IRWXO); + int ret = mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO); if (ret < 0) { @@ -108,7 +110,7 @@ static bool create_dir(const char *path) static bool remove_dir(const char *path) { - int ret = rmdir(TEMPDIR2); + int ret = rmdir(path); if (ret < 0) { @@ -120,6 +122,94 @@ static bool remove_dir(const char *path) return true; } +static bool is_temp_file(const char *name, const char *prefix) +{ + size_t prefix_len = strlen(prefix); + int i; + + if (strncmp(name, prefix, prefix_len) != 0) + { + return false; + } + + for (i = 0; i < 3; i++) + { + char ch = name[prefix_len + i]; + + if (ch < '0' || ch > '9') + { + return false; + } + } + + return name[prefix_len + i] == '\0'; +} + +static bool cleanup_dir(const char *path, const char *name) +{ + FAR DIR *dir; + FAR struct dirent *entry; + char filepath[MAX_PATH_LEN]; + int ret; + + dir = opendir(path); + if (dir == NULL) + { + if (errno == ENOENT) + { + return true; + } + + printf("opendir %s failed, errno: %d -> %s\n", + path, errno, strerror(errno)); + return false; + } + + while ((entry = readdir(dir)) != NULL) + { + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) + { + continue; + } + + if (!is_temp_file(entry->d_name, name)) + { + printf("%s contains unexpected entry %s\n", path, entry->d_name); + closedir(dir); + return false; + } + + ret = snprintf(filepath, sizeof(filepath), "%s/%s", + path, entry->d_name); + if (ret < 0 || (size_t)ret >= sizeof(filepath)) + { + printf("path name too long\n"); + closedir(dir); + return false; + } + + ret = unlink(filepath); + if (ret < 0) + { + printf("unlink %s failed, ret: %d, errno %d -> %s\n", + filepath, ret, errno, strerror(errno)); + closedir(dir); + return false; + } + } + + ret = closedir(dir); + if (ret < 0) + { + printf("closedir %s failed, ret: %d, errno %d -> %s\n", + path, ret, errno, strerror(errno)); + return false; + } + + return remove_dir(path); +} + static bool create_files(const char *dir, const char *name, size_t num_files, char *bytes, size_t num_bytes) { @@ -372,6 +462,12 @@ int main(int argc, char *argv[]) total_time = 0; + if (!cleanup_dir(TEMPDIR, TEMPFILE) || !cleanup_dir(TEMPDIR2, TEMPFILE)) + { + free(bytes); + return -1; + } + for (size_t i = 0; i < num_runs; ++i) { start = get_abs_time(); From f8a48fa5f35f5d6aaceb66859dac578d6fdaff13 Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Sun, 24 May 2026 10:30:56 +0800 Subject: [PATCH 351/568] testing/sd_stress: Harden file creation cleanup Close the temporary file descriptor when create_files() fails after open(), and release the read buffer before returning from the path-length failure branch. This is logically separable from the #3205 stale-directory fix: it does not change how existing /sd/stress is handled, but keeps the same failure paths from leaking resources while the stress test exits after an error. The scope intentionally stays within sd_stress failure cleanup and does not touch SD/MMC transfer behavior or other testing drivers. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- testing/drivers/sd_stress/sd_stress_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/testing/drivers/sd_stress/sd_stress_main.c b/testing/drivers/sd_stress/sd_stress_main.c index 882bec362..dffdd16c5 100644 --- a/testing/drivers/sd_stress/sd_stress_main.c +++ b/testing/drivers/sd_stress/sd_stress_main.c @@ -233,6 +233,7 @@ static bool create_files(const char *dir, const char *name, if (path_len + 5 >= MAX_PATH_LEN) { printf("path name too long\n"); + free(read_bytes); return false; } @@ -267,7 +268,7 @@ static bool create_files(const char *dir, const char *name, printf("write %s failed, ret: %d, errno %d -> %s\n", path, ret, errno, strerror(errno)); passed = false; - break; + goto close_file; } ret = lseek(fd, 0, SEEK_SET); @@ -277,7 +278,7 @@ static bool create_files(const char *dir, const char *name, printf("lseek %s failed, ret: %d, errno %d -> %s\n", path, ret, errno, strerror(errno)); passed = false; - break; + goto close_file; } ret = read(fd, read_bytes, num_bytes); @@ -287,16 +288,17 @@ static bool create_files(const char *dir, const char *name, printf("read %s failed, ret: %d, errno %d -> %s\n", path, ret, errno, strerror(errno)); passed = false; - break; + goto close_file; } if (memcmp(read_bytes, bytes, num_bytes) != 0) { printf("read and write buffers are not the same\n"); passed = false; - break; + goto close_file; } +close_file: ret = close(fd); if (ret < 0) @@ -306,6 +308,11 @@ static bool create_files(const char *dir, const char *name, passed = false; break; } + + if (!passed) + { + break; + } } free(read_bytes); From 2d949fa7c57b1a836f1217d8093787a63c9c04a1 Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Mon, 25 May 2026 10:46:59 +0800 Subject: [PATCH 352/568] system/settings: Avoid recursive save locking Fix #3105 by making the immediate save path write pending settings while the caller still owns g_settings.mtx instead of calling the timer callback, which locks the same mutex again. The cached-save timer callback still takes the mutex before using the same locked helper, so asynchronous saves keep their existing synchronization while non-cached saves no longer depend on a recursive mutex. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- system/settings/settings.c | 70 ++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/system/settings/settings.c b/system/settings/settings.c index 105c093dd..c478e96f8 100644 --- a/system/settings/settings.c +++ b/system/settings/settings.c @@ -82,7 +82,10 @@ static int set_ip(FAR setting_t *setting, FAR struct in_addr *ip); static int load(void); static void save(void); static void signotify(void); +static void dump_cache_locked(FAR bool *wrpend); +#ifdef CONFIG_SYSTEM_SETTINGS_CACHED_SAVES static void dump_cache(union sigval ptr); +#endif /**************************************************************************** * Private Data @@ -623,12 +626,7 @@ static void save(void) #ifdef CONFIG_SYSTEM_SETTINGS_CACHED_SAVES timer_settime(g_settings.timerid, 0, &g_settings.trigger, NULL); #else - union sigval value = - { - .sival_ptr = &g_settings.wrpend, - }; - - dump_cache(value); + dump_cache_locked(&g_settings.wrpend); #endif } @@ -661,6 +659,38 @@ static void signotify(void) } } +/**************************************************************************** + * Name: dump_cache_locked + * + * Description: + * Writes out the cached data to the appropriate storage. The caller + * must hold g_settings.mtx. + * + * Input Parameters: + * wrpend - pending write flag to clear after dumping + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void dump_cache_locked(FAR bool *wrpend) +{ + int i; + + for (i = 0; i < CONFIG_SYSTEM_SETTINGS_MAX_STORAGES; i++) + { + if ((g_settings.store[i].file[0] != '\0') && + g_settings.store[i].save_fn) + { + (void)g_settings.store[i].save_fn(g_settings.store[i].file); + } + } + + *wrpend = false; +} + +#ifdef CONFIG_SYSTEM_SETTINGS_CACHED_SAVES /**************************************************************************** * Name: dump_cache * @@ -677,36 +707,16 @@ static void signotify(void) static void dump_cache(union sigval ptr) { - int ret = OK; - FAR bool *wrpend = (bool *)ptr.sival_ptr; - - int i; + FAR bool *wrpend = (FAR bool *)ptr.sival_ptr; + int ret; ret = pthread_mutex_lock(&g_settings.mtx); assert(ret >= 0); - for (i = 0; i < CONFIG_SYSTEM_SETTINGS_MAX_STORAGES; i++) - { - if ((g_settings.store[i].file[0] != '\0') && - g_settings.store[i].save_fn) - { - ret = g_settings.store[i].save_fn(g_settings.store[i].file); -#if 0 - if (ret < 0) - { - /* What to do? We can't return anything from a void function. - * - * MIGHT BE A FUTURE REVISIT NEEDED - */ - } -#endif - } - } - - *wrpend = false; - + dump_cache_locked(wrpend); pthread_mutex_unlock(&g_settings.mtx); } +#endif /**************************************************************************** * Name: sanity_check From 0dd221cc763a6b41198868f245593126741d6ba5 Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Mon, 25 May 2026 10:47:43 +0800 Subject: [PATCH 353/568] system/settings: Drop unused recursive mutex type The settings save path no longer re-enters g_settings.mtx, so the mutex does not need to be initialized as PTHREAD_MUTEX_RECURSIVE. This keeps the #3105 fix independent of CONFIG_PTHREAD_MUTEX_TYPES and destroys the temporary mutex attribute object after initialization. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com> --- system/settings/settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/settings/settings.c b/system/settings/settings.c index c478e96f8..1625c3f5a 100644 --- a/system/settings/settings.c +++ b/system/settings/settings.c @@ -772,9 +772,9 @@ void settings_init(void) pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); pthread_mutex_init(&g_settings.mtx, &attr); + pthread_mutexattr_destroy(&attr); memset(map, 0, sizeof(map)); memset(g_settings.store, 0, sizeof(g_settings.store)); From 0f8f9125f08bbe68bfcedd21e7c1b88a88037b09 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 05:00:00 +0000 Subject: [PATCH 354/568] apps/system/microros: add micro_ros_lib directory skeleton. Add micro_ros_lib/ subdirectory with a .keep sentinel so the directory is tracked by git before any generated build artifacts appear. All colcon/fetch outputs land here and are gitignored by the parent .gitignore. Signed-off-by: Arjav Patel --- system/microros/micro_ros_lib/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 system/microros/micro_ros_lib/.keep diff --git a/system/microros/micro_ros_lib/.keep b/system/microros/micro_ros_lib/.keep new file mode 100644 index 000000000..e69de29bb From 98d3a0bcb051e04c22f880fe5292ec7e89dbf991 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 05:43:58 +0000 Subject: [PATCH 355/568] apps/system/microros: add colcon.meta.in resource-limit template. Add a colcon.meta.in template that is substituted at build time with Kconfig values. Key settings: - Custom transport only (UCLIENT_PROFILE_CUSTOM_TRANSPORT=ON, UCLIENT_PROFILE_STREAM_FRAMING=ON) -- actual UDP/serial callbacks are wired in Phase 4. - RCL_MICROROS=ON (Jazzy/Kilted renamed flag replacing the old RCL_COMMAND_LINE_ENABLED/RCL_LOGGING_ENABLED pair). - RCUTILS_NO_FILESYSTEM=OFF -- NuttX provides POSIX filesystem. - Resource limits use @MAX_NODES@/@MAX_PUBLISHERS@ etc. placeholders substituted from CONFIG_MICROROS_MAX_* Kconfig values. Signed-off-by: Arjav Patel --- system/microros/micro_ros_lib/colcon.meta.in | 52 ++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 system/microros/micro_ros_lib/colcon.meta.in diff --git a/system/microros/micro_ros_lib/colcon.meta.in b/system/microros/micro_ros_lib/colcon.meta.in new file mode 100644 index 000000000..00468545b --- /dev/null +++ b/system/microros/micro_ros_lib/colcon.meta.in @@ -0,0 +1,52 @@ +{ + "names": { + "microxrcedds_client": { + "cmake-args": [ + "-DUCLIENT_PIC=OFF", + "-DUCLIENT_PROFILE_DISCOVERY=OFF", + "-DUCLIENT_PROFILE_UDP=OFF", + "-DUCLIENT_PROFILE_TCP=OFF", + "-DUCLIENT_PROFILE_SERIAL=OFF", + "-DUCLIENT_PROFILE_CUSTOM_TRANSPORT=ON", + "-DUCLIENT_PROFILE_STREAM_FRAMING=ON", + "-DUCLIENT_EXTERNAL_SERIAL=ON" + ] + }, + "rmw_microxrcedds": { + "cmake-args": [ + "-DRMW_UXRCE_TRANSPORT=custom", + "-DRMW_UXRCE_MAX_NODES=@MAX_NODES@", + "-DRMW_UXRCE_MAX_PUBLISHERS=@MAX_PUBLISHERS@", + "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=@MAX_SUBSCRIPTIONS@", + "-DRMW_UXRCE_MAX_SERVICES=@MAX_SERVICES@", + "-DRMW_UXRCE_MAX_CLIENTS=@MAX_CLIENTS@", + "-DRMW_UXRCE_MAX_HISTORY=4" + ] + }, + "rcl": { + "cmake-args": [ + "-DRCL_MICROROS=ON" + ] + }, + "rcutils": { + "cmake-args": [ + "-DRCUTILS_NO_FILESYSTEM=OFF", + "-DRCUTILS_NO_THREAD_SUPPORT=ON", + "-DRCUTILS_NO_64_ATOMIC=ON", + "-DRCUTILS_AVOID_DYNAMIC_ALLOCATION=ON", + "-DENABLE_TESTING=OFF" + ] + }, + "rosidl_typesupport": { + "cmake-args": [ + "-DROSIDL_TYPESUPPORT_SINGLE_TYPESUPPORT=ON" + ] + }, + "tracetools": { + "cmake-args": [ + "-DTRACETOOLS_DISABLED=ON", + "-DTRACETOOLS_STATUS_CHECKING_TOOL=OFF" + ] + } + } +} From e764594d2607b0a4cb680935240ea1655a8db889 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 06:23:38 +0000 Subject: [PATCH 356/568] apps/system/microros: add CMake cross-compile toolchain template. Add toolchain.cmake.in and include_override/assert.h for the colcon cross-build. Key differences from the old robertobucher port: - Drop -DCLOCK_MONOTONIC=0: NuttX defines CLOCK_MONOTONIC=1 and the override broke nanosleep() on newer kernels. - CMAKE_SYSTEM_PROCESSOR is a placeholder substituted per-arch. - include_override/assert.h works around the rosidl NDEBUG issue (https://github.com/ros2/rosidl/pull/739). Signed-off-by: Arjav Patel --- .../micro_ros_lib/include_override/assert.h | 41 +++++++++++++++++++ .../microros/micro_ros_lib/toolchain.cmake.in | 29 +++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 system/microros/micro_ros_lib/include_override/assert.h create mode 100644 system/microros/micro_ros_lib/toolchain.cmake.in diff --git a/system/microros/micro_ros_lib/include_override/assert.h b/system/microros/micro_ros_lib/include_override/assert.h new file mode 100644 index 000000000..1874aa304 --- /dev/null +++ b/system/microros/micro_ros_lib/include_override/assert.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * apps/system/microros/micro_ros_lib/include_override/assert.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __MICROROS_INCLUDE_OVERRIDE_ASSERT_H +#define __MICROROS_INCLUDE_OVERRIDE_ASSERT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Pull the system assert.h, then redefine assert to a no-op when NDEBUG is + * set. Avoids an assert redefinition conflict in rosidl typesupport. + */ + +#include_next + +#ifdef NDEBUG +# undef assert +# define assert(x) ((void)(0)) +#endif + +#endif /* __MICROROS_INCLUDE_OVERRIDE_ASSERT_H */ diff --git a/system/microros/micro_ros_lib/toolchain.cmake.in b/system/microros/micro_ros_lib/toolchain.cmake.in new file mode 100644 index 000000000..dbdc290e2 --- /dev/null +++ b/system/microros/micro_ros_lib/toolchain.cmake.in @@ -0,0 +1,29 @@ +include(CMakeForceCompiler) + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR @CMAKE_SYSTEM_PROCESSOR@) +set(CMAKE_CROSSCOMPILING 1) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +set(PLATFORM_NAME "nuttx") + +set(CMAKE_C_COMPILER @CMAKE_C_COMPILER@) +set(CMAKE_CXX_COMPILER @CMAKE_CXX_COMPILER@) + +set(CMAKE_C_FLAGS_INIT "-std=c11 @ARCH_C_FLAGS@ -D'__attribute__(x)='" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_INIT "-std=c++14 @ARCH_CPP_FLAGS@ -fno-rtti -D'__attribute__(x)='" CACHE STRING "" FORCE) + +set(NUTTX_TOPDIR @NUTTX_TOPDIR@) +set(NUTTX_APPDIR @NUTTX_APPDIR@) +set(INCLUDE_OVR_DIR @INCLUDE_OVR_DIR@) + +include_directories(SYSTEM + ${NUTTX_TOPDIR}/include + ${NUTTX_TOPDIR}/include/cxx + ${NUTTX_APPDIR}/include +) + +include_directories(AFTER SYSTEM + ${INCLUDE_OVR_DIR}/include_override +) + +set(__BIG_ENDIAN__ 0) From b1a4d3fcd5f35a4b82aaadb9158356b2313433d3 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 07:04:05 +0000 Subject: [PATCH 357/568] apps/system/microros: add libmicroros.a colcon build pipeline. Replace the Directory.mk stub with a full Application.mk-based Makefile that builds libmicroros.a from upstream micro-ROS sources via colcon. Build pipeline (six steps, each a Make target): 1. micro_ros_dev/install -- clone + build ament/colcon host tools 2. micro_ros_src/src -- git clone all Jazzy micro-ROS packages with --depth 1; apply DIR-typedef guard patch; mark unused packages COLCON_IGNORE 3. toolchain.cmake -- sed-substitute CC/CXX/CFLAGS into template 4. colcon.meta -- sed-substitute Kconfig resource limits 5. micro_ros_src/install -- colcon cross-build (merge-install, packages-ignore-regex=.*_cpp) 6. libmicroros.a -- ar-merge all install/lib/*.a into one archive; copy include/ tree clean:: removes generated files; distclean:: removes all fetched dirs. Signed-off-by: Arjav Patel --- system/microros/Makefile | 223 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 222 insertions(+), 1 deletion(-) diff --git a/system/microros/Makefile b/system/microros/Makefile index b907087ee..6d34e3cc3 100644 --- a/system/microros/Makefile +++ b/system/microros/Makefile @@ -20,6 +20,227 @@ # ############################################################################ +include $(APPDIR)/Make.defs + +MICROROS_DIR := $(APPDIR)/system/microros +MICROROS_LIB_DIR := $(MICROROS_DIR)/micro_ros_lib +MICROROS_DISTRO := $(patsubst "%",%,$(CONFIG_MICROROS_DISTRO)) +MICROROS_AR := $(CROSSDEV)ar + +MAX_NODES := $(CONFIG_MICROROS_MAX_NODES) +MAX_PUB := $(CONFIG_MICROROS_MAX_PUBLISHERS) +MAX_SUB := $(CONFIG_MICROROS_MAX_SUBSCRIPTIONS) +MAX_SVC := $(CONFIG_MICROROS_MAX_SERVICES) +MAX_CLIENTS := $(CONFIG_MICROROS_MAX_CLIENTS) + +# Escape for sed: forward slashes and strip quotes +ESCAPED_CC := $(subst /,\/,$(CC)) +ESCAPED_CXX := $(subst /,\/,$(CXX)) +ESCAPED_TOPDIR := $(subst /,\/,$(TOPDIR)) +ESCAPED_APPDIR := $(subst /,\/,$(APPDIR)) +ESCAPED_LIBDIR := $(subst /,\/,$(MICROROS_LIB_DIR)) +ESCAPED_CFLAGS := $(subst /,\/,$(subst ",,$(CFLAGS))) +ESCAPED_CXXFLAGS := $(subst /,\/,$(subst ",,$(CXXFLAGS))) + MENUDESC = "micro-ROS Library" -include $(APPDIR)/Directory.mk +# Architecture for CMake toolchain +ifeq ($(CONFIG_ARCH_ARM),y) +MICROROS_ARCH := arm +else ifeq ($(CONFIG_ARCH_ARM64),y) +MICROROS_ARCH := arm64 +else ifeq ($(CONFIG_ARCH_RISCV),y) +MICROROS_ARCH := riscv +else ifeq ($(CONFIG_ARCH_XTENSA),y) +MICROROS_ARCH := xtensa +else +MICROROS_ARCH := generic +endif + +# Wire libmicroros.a into the build when the context target fires +context:: $(MICROROS_DIR)/libmicroros.a + +# --------------------------------------------------------------------------- +# Step 1 – Build the ament/colcon dev tools (host-side) +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/micro_ros_dev/install: + rm -rf $(MICROROS_LIB_DIR)/micro_ros_dev + mkdir -p $(MICROROS_LIB_DIR)/micro_ros_dev/src + cd $(MICROROS_LIB_DIR)/micro_ros_dev && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/ament_cmake src/ament_cmake && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/ament_lint src/ament_lint && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/ament_package src/ament_package && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/googletest src/googletest && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/ament_cmake_ros src/ament_cmake_ros && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ament/ament_index src/ament_index && \ + touch src/ament_cmake_ros/rmw_test_fixture_implementation/COLCON_IGNORE 2>/dev/null || true && \ + touch src/ament_cmake_ros/rmw_test_fixture/COLCON_IGNORE 2>/dev/null || true && \ + colcon build --cmake-args -DBUILD_TESTING=OFF + +# --------------------------------------------------------------------------- +# Step 2 – Clone all micro-ROS source packages +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/micro_ros_src/src: $(MICROROS_LIB_DIR)/micro_ros_dev/install + rm -rf $(MICROROS_LIB_DIR)/micro_ros_src + mkdir -p $(MICROROS_LIB_DIR)/micro_ros_src/src + cd $(MICROROS_LIB_DIR)/micro_ros_src && \ + git clone -b ros2 --depth 1 \ + https://github.com/eProsima/micro-CDR src/micro-CDR && \ + git clone -b ros2 --depth 1 \ + https://github.com/eProsima/Micro-XRCE-DDS-Client src/Micro-XRCE-DDS-Client && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rmw-microxrcedds src/rmw_microxrcedds && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rcl src/rcl && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rclc src/rclc && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rcutils src/rcutils && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rosidl src/rosidl && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rosidl_defaults src/rosidl_defaults && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rosidl_dynamic_typesupport src/rosidl_dynamic_typesupport && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rosidl_core src/rosidl_core && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rmw src/rmw && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rmw_implementation src/rmw_implementation && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rcl_interfaces src/rcl_interfaces && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/common_interfaces src/common_interfaces && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/rcl_logging src/rcl_logging && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/micro_ros_msgs src/micro_ros_msgs && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rosidl_typesupport src/rosidl_typesupport && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/rosidl_typesupport_microxrcedds src/rosidl_typesupport_microxrcedds && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/micro-ROS/micro_ros_utilities src/micro_ros_utilities && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/unique_identifier_msgs src/unique_identifier_msgs && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/test_interface_files src/test_interface_files && \ + git clone -b $(MICROROS_DISTRO) --depth 1 \ + https://github.com/ros2/ros2_tracing src/ros2_tracing && \ + touch src/ros2_tracing/test_tracetools/COLCON_IGNORE && \ + touch src/ros2_tracing/lttngpy/COLCON_IGNORE && \ + touch src/rmw/rmw_security_common/COLCON_IGNORE && \ + touch src/rcl_logging/rcl_logging_spdlog/COLCON_IGNORE && \ + touch src/rclc/rclc_examples/COLCON_IGNORE && \ + touch src/rcl/rcl_yaml_param_parser/COLCON_IGNORE && \ + touch src/rosidl/rosidl_typesupport_introspection_cpp/COLCON_IGNORE && \ + touch src/rcl_interfaces/test_msgs/COLCON_IGNORE && \ + touch src/common_interfaces/actionlib_msgs/COLCON_IGNORE && \ + touch src/common_interfaces/std_srvs/COLCON_IGNORE && \ + patch -p1 --forward --ignore-whitespace \ + -d src < $(MICROROS_LIB_DIR)/patches/0001-dir-typedef-nuttx-guard.patch || true && \ + patch -p1 --forward --ignore-whitespace \ + -d src < $(MICROROS_LIB_DIR)/patches/0002-rcutils-process-nuttx-compat.patch || true && \ + patch -p1 --forward --ignore-whitespace \ + -d src < $(MICROROS_LIB_DIR)/patches/0003-rcutils-strcasecmp-include-strings-h.patch || true + +# --------------------------------------------------------------------------- +# Step 3 – Generate toolchain.cmake from template +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/toolchain.cmake: $(MICROROS_LIB_DIR)/toolchain.cmake.in + sed \ + -e 's/@CMAKE_C_COMPILER@/$(ESCAPED_CC)/g' \ + -e 's/@CMAKE_CXX_COMPILER@/$(ESCAPED_CXX)/g' \ + -e 's/@ARCH_C_FLAGS@/$(ESCAPED_CFLAGS)/g' \ + -e 's/@ARCH_CPP_FLAGS@/$(ESCAPED_CXXFLAGS)/g' \ + -e 's/@NUTTX_TOPDIR@/$(ESCAPED_TOPDIR)/g' \ + -e 's/@NUTTX_APPDIR@/$(ESCAPED_APPDIR)/g' \ + -e 's/@INCLUDE_OVR_DIR@/$(ESCAPED_LIBDIR)/g' \ + -e 's/@CMAKE_SYSTEM_PROCESSOR@/$(MICROROS_ARCH)/g' \ + $< > $@ + +# --------------------------------------------------------------------------- +# Step 4 – Generate colcon.meta from template +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/colcon.meta: $(MICROROS_LIB_DIR)/colcon.meta.in + sed \ + -e 's/@MAX_NODES@/$(MAX_NODES)/g' \ + -e 's/@MAX_PUBLISHERS@/$(MAX_PUB)/g' \ + -e 's/@MAX_SUBSCRIPTIONS@/$(MAX_SUB)/g' \ + -e 's/@MAX_SERVICES@/$(MAX_SVC)/g' \ + -e 's/@MAX_CLIENTS@/$(MAX_CLIENTS)/g' \ + $< > $@ + +# --------------------------------------------------------------------------- +# Step 5 – Cross-build micro-ROS packages with colcon +# --------------------------------------------------------------------------- + +$(MICROROS_LIB_DIR)/micro_ros_src/install: \ + $(MICROROS_LIB_DIR)/toolchain.cmake \ + $(MICROROS_LIB_DIR)/colcon.meta \ + $(MICROROS_LIB_DIR)/micro_ros_src/src + cd $(MICROROS_LIB_DIR)/micro_ros_src && \ + unset AMENT_PREFIX_PATH && \ + . ../micro_ros_dev/install/local_setup.sh && \ + colcon build \ + --merge-install \ + "--packages-ignore-regex=(.*_cpp$$|.*_py$$|test_rmw_implementation|rclc_examples)" \ + --metas $(MICROROS_LIB_DIR)/colcon.meta \ + --cmake-args \ + --no-warn-unused-cli \ + -DCMAKE_POSITION_INDEPENDENT_CODE=OFF \ + -DTHIRDPARTY=ON \ + -DBUILD_SHARED_LIBS=OFF \ + -DBUILD_TESTING=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + "-DCMAKE_TOOLCHAIN_FILE=$(MICROROS_LIB_DIR)/toolchain.cmake" \ + -DCMAKE_VERBOSE_MAKEFILE=OFF + +# --------------------------------------------------------------------------- +# Step 6 – Merge all .a files into a single libmicroros.a +# --------------------------------------------------------------------------- + +$(MICROROS_DIR)/libmicroros.a: $(MICROROS_LIB_DIR)/micro_ros_src/install + mkdir -p $(MICROROS_LIB_DIR)/libmicroros_obj + cd $(MICROROS_LIB_DIR)/libmicroros_obj && \ + for file in $$(find $(MICROROS_LIB_DIR)/micro_ros_src/install/lib/ -name '*.a'); do \ + folder=$$(basename $$file .a); \ + mkdir -p $$folder && cd $$folder; \ + $(MICROROS_AR) x $$file; \ + for f in *; do \ + [ -f "$$f" ] && mv "$$f" "../$${folder}-$${f}" 2>/dev/null || true; \ + done; \ + cd ..; \ + rm -rf $$folder; \ + done && \ + $(MICROROS_AR) rc libmicroros.a $$(find . -maxdepth 1 -type f ! -name 'libmicroros.a') && \ + cp libmicroros.a $(MICROROS_DIR)/ + cd $(MICROROS_LIB_DIR) && rm -rf libmicroros_obj + cp -R $(MICROROS_LIB_DIR)/micro_ros_src/install/include $(MICROROS_DIR)/include + +# --------------------------------------------------------------------------- +# Cleanup targets +# --------------------------------------------------------------------------- + +clean:: + $(call DELFILE,$(MICROROS_DIR)/libmicroros.a) + $(call DELDIR,$(MICROROS_DIR)/include) + $(call DELFILE,$(MICROROS_LIB_DIR)/toolchain.cmake) + $(call DELFILE,$(MICROROS_LIB_DIR)/colcon.meta) + +distclean:: clean + $(call DELDIR,$(MICROROS_LIB_DIR)/micro_ros_src) + $(call DELDIR,$(MICROROS_LIB_DIR)/micro_ros_dev) + +include $(APPDIR)/Application.mk From cb316ec1659542e6ae8024cfe1d3aed76bb224c6 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 07:44:01 +0000 Subject: [PATCH 358/568] apps/system/microros: wire libmicroros.a into LDLIBS and CFLAGS. When CONFIG_SYSTEM_MICROROS=y, add the prebuilt libmicroros.a to LDLIBS and the colcon-installed include/ tree to CFLAGS/CXXFLAGS so that any application in nuttx-apps can include micro-ROS headers and link against the library without extra flags. Signed-off-by: Arjav Patel --- system/microros/Make.defs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/system/microros/Make.defs b/system/microros/Make.defs index 5ec456770..ae95e997d 100644 --- a/system/microros/Make.defs +++ b/system/microros/Make.defs @@ -19,3 +19,12 @@ # under the License. # ############################################################################ + +ifneq ($(CONFIG_SYSTEM_MICROROS),) +CONFIGURED_APPS += $(APPDIR)/system/microros + +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/include +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/include + +LDLIBS += $(APPDIR)/system/microros/libmicroros.a +endif From 7dbebe1673afc25228c3da82be9cfb7e3d10c5ec Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 08:29:50 +0000 Subject: [PATCH 359/568] apps/system/microros: add DIR-typedef NuttX guard patch. NuttX defines DIR as a struct type in dirent.h. The rcutils filesystem source has a bare typedef int DIR that triggers a redefinition error when NuttX system headers are on the include path. Guard it with #ifndef DIR so the typedef is skipped when the type is already defined. Applied automatically during the micro_ros_src/src fetch step with patch -p1 --forward --ignore-whitespace ... || true so the build is idempotent if the upstream ever merges a fix. Signed-off-by: Arjav Patel --- .../0001-dir-typedef-nuttx-guard.patch | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 system/microros/patches/0001-dir-typedef-nuttx-guard.patch diff --git a/system/microros/patches/0001-dir-typedef-nuttx-guard.patch b/system/microros/patches/0001-dir-typedef-nuttx-guard.patch new file mode 100644 index 000000000..75e4f91d9 --- /dev/null +++ b/system/microros/patches/0001-dir-typedef-nuttx-guard.patch @@ -0,0 +1,31 @@ +From: micro-ROS NuttX Port +Subject: [PATCH] rcutils: guard bare DIR typedef to avoid conflict with NuttX dirent.h + +NuttX defines DIR as a struct type in dirent.h. The bare + typedef int DIR; +in rcutils/src/filesystem.c causes a redefinition error when the +NuttX system headers are on the include path. Guard it so it is +only emitted when DIR has not already been defined. + +--- a/rcutils/src/filesystem.c ++++ b/rcutils/src/filesystem.c +@@ -1,6 +1,8 @@ + // Copyright 2017 Open Source Robotics Foundation, Inc. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + #if !defined _WIN32 && !defined __QNXTO__ ++#ifndef DIR + typedef int DIR; ++#endif + #endif From 9a0c249c79dd81551aa2d71bba846e82f9c48876 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 09:10:51 +0000 Subject: [PATCH 360/568] apps/system/microros: add CMake ExternalProject build support. Mirror the Makefile build pipeline into CMakeLists.txt using ExternalProject_Add so that CMake-based NuttX builds (cmake --build) can also produce libmicroros.a. The external project delegates to the existing Makefile targets, then exposes the result via an IMPORTED STATIC library target with correct INTERFACE_INCLUDE_DIRECTORIES. Signed-off-by: Arjav Patel --- system/microros/CMakeLists.txt | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/system/microros/CMakeLists.txt b/system/microros/CMakeLists.txt index 9edae8cef..44cd0d25b 100644 --- a/system/microros/CMakeLists.txt +++ b/system/microros/CMakeLists.txt @@ -21,5 +21,27 @@ # ############################################################################## if(CONFIG_SYSTEM_MICROROS) - nuttx_add_library(microros) + set(MICROROS_DIR ${CMAKE_CURRENT_LIST_DIR}) + set(MICROROS_LIB_DIR ${MICROROS_DIR}/micro_ros_lib) + set(MICROROS_DISTRO ${CONFIG_MICROROS_DISTRO}) + + include(ExternalProject) + + ExternalProject_Add( + microros_build + SOURCE_DIR ${MICROROS_LIB_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND + ${CMAKE_COMMAND} -E env CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} + AR=${CMAKE_AR} CFLAGS=${CMAKE_C_FLAGS} CXXFLAGS=${CMAKE_CXX_FLAGS} make -C + ${MICROROS_DIR} libmicroros.a + INSTALL_COMMAND "" + BUILD_IN_SOURCE TRUE + BUILD_BYPRODUCTS ${MICROROS_DIR}/libmicroros.a) + + nuttx_add_library(microros STATIC IMPORTED GLOBAL) + set_target_properties( + microros PROPERTIES IMPORTED_LOCATION ${MICROROS_DIR}/libmicroros.a + INTERFACE_INCLUDE_DIRECTORIES ${MICROROS_DIR}/include) + add_dependencies(microros microros_build) endif() From 55a7d4d2df0b95cda489afa3ad5c48d0ca3d4e5d Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 09:52:17 +0000 Subject: [PATCH 361/568] apps/system/microros: define __NuttX__ in cross-compile toolchain flags. Add -D__NuttX__ to CMAKE_C_FLAGS_INIT and CMAKE_CXX_FLAGS_INIT in toolchain.cmake.in so that all cross-compiled micro-ROS packages see the NuttX target macro. Without this, rcutils/src/process.c follows the __linux__ branch and references program_invocation_name, a glibc-only extension absent from the NuttX C library. Pair with 0002-rcutils-process-nuttx-compat.patch which additionally guards the linux branch with !defined(__NuttX__), ensuring the embedded fallback path is taken on NuttX even if the host compiler defines any linux-flavoured macros. Signed-off-by: Arjav Patel --- .../microros/micro_ros_lib/toolchain.cmake.in | 4 ++-- .../0002-rcutils-process-nuttx-compat.patch | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 system/microros/patches/0002-rcutils-process-nuttx-compat.patch diff --git a/system/microros/micro_ros_lib/toolchain.cmake.in b/system/microros/micro_ros_lib/toolchain.cmake.in index dbdc290e2..8d3aabe3c 100644 --- a/system/microros/micro_ros_lib/toolchain.cmake.in +++ b/system/microros/micro_ros_lib/toolchain.cmake.in @@ -9,8 +9,8 @@ set(PLATFORM_NAME "nuttx") set(CMAKE_C_COMPILER @CMAKE_C_COMPILER@) set(CMAKE_CXX_COMPILER @CMAKE_CXX_COMPILER@) -set(CMAKE_C_FLAGS_INIT "-std=c11 @ARCH_C_FLAGS@ -D'__attribute__(x)='" CACHE STRING "" FORCE) -set(CMAKE_CXX_FLAGS_INIT "-std=c++14 @ARCH_CPP_FLAGS@ -fno-rtti -D'__attribute__(x)='" CACHE STRING "" FORCE) +set(CMAKE_C_FLAGS_INIT "-std=c11 @ARCH_C_FLAGS@ -D__NuttX__ -D'__attribute__(x)='" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_INIT "-std=c++14 @ARCH_CPP_FLAGS@ -fno-rtti -D__NuttX__ -D'__attribute__(x)='" CACHE STRING "" FORCE) set(NUTTX_TOPDIR @NUTTX_TOPDIR@) set(NUTTX_APPDIR @NUTTX_APPDIR@) diff --git a/system/microros/patches/0002-rcutils-process-nuttx-compat.patch b/system/microros/patches/0002-rcutils-process-nuttx-compat.patch new file mode 100644 index 000000000..ca8b6c56a --- /dev/null +++ b/system/microros/patches/0002-rcutils-process-nuttx-compat.patch @@ -0,0 +1,20 @@ +From: micro-ROS NuttX Port +Subject: [PATCH] rcutils: skip program_invocation_name on NuttX + +When cross-compiling for NuttX on a Linux host the compiler still +defines __linux__, causing rcutils_get_executable_name() to reference +program_invocation_name which is a glibc extension absent from the +NuttX C library. Guard the Linux branch with !defined(__NuttX__) so +the "embedded OS" fallback (empty string) is taken instead. + +--- a/rcutils/src/process.c ++++ b/rcutils/src/process.c +@@ -61,7 +61,7 @@ int rcutils_get_pid() + #if defined __APPLE__ || defined __FreeBSD__ || (defined __ANDROID__ && __ANDROID_API__ >= 21) + const char * appname = getprogname(); + #elif defined __GNUC__ && !defined(__QNXNTO__) && !defined(__OHOS__) +- #if defined __linux__ || defined __linux || defined __gnu_linux__ || defined linux ++ #if (defined __linux__ || defined __linux || defined __gnu_linux__ || defined linux) && !defined(__NuttX__) + const char * appname = program_invocation_name; + #else + // Some embedded OS compile with __GNUC__ but are not quite conformant with GNU-specific extensions. From 939ed0ca2a7b593949973be5d09aefea1b659418 Mon Sep 17 00:00:00 2001 From: Arjav Patel Date: Sat, 23 May 2026 15:40:17 +0000 Subject: [PATCH 362/568] apps/system/microros: add rcutils strcasecmp strings.h include patch. POSIX specifies strcasecmp/strncasecmp in , not . On NuttX (and other strict POSIX environments) rcutils/src/strcasecmp.c only includes , causing an implicit-declaration error for strcasecmp when cross-compiling. Patch 0003 adds #include guarded by !_WIN32, matching the existing Windows/POSIX split in the file. Signed-off-by: Arjav Patel --- ...rcutils-strcasecmp-include-strings-h.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 system/microros/patches/0003-rcutils-strcasecmp-include-strings-h.patch diff --git a/system/microros/patches/0003-rcutils-strcasecmp-include-strings-h.patch b/system/microros/patches/0003-rcutils-strcasecmp-include-strings-h.patch new file mode 100644 index 000000000..7392f2828 --- /dev/null +++ b/system/microros/patches/0003-rcutils-strcasecmp-include-strings-h.patch @@ -0,0 +1,19 @@ +From: micro-ROS NuttX Port +Subject: [PATCH] rcutils: include for strcasecmp on NuttX + +POSIX specifies strcasecmp/strncasecmp in , not . +NuttX follows the standard strictly so omitting this header causes an +"implicit declaration" error. Guard the include with __NuttX__ so it +only applies where needed and does not affect Linux or other platforms +that already expose strcasecmp through . + +--- a/rcutils/src/strcasecmp.c ++++ b/rcutils/src/strcasecmp.c +@@ -17,6 +17,9 @@ extern "C" + #include + #include ++#ifdef __NuttX__ ++#include ++#endif + + #include "rcutils/strcasecmp.h" From 84022eaa8130fcc1cb09a01caaa4299bf5ee57c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 May 2026 03:48:08 +0000 Subject: [PATCH 363/568] build(deps): bump docker/login-action from 4.0.0 to 4.2.0 Bumps [docker/login-action](https://github.com/docker/login-action) from 4.0.0 to 4.2.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/b45d80f862d83dbcd57f89517bcf500b2ab88fb2...650006c6eb7dba73a995cc03b0b2d7f5ca915bee) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4fe967a7e..c159fe7ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -163,7 +163,7 @@ jobs: run: tar zxf sources.tar.gz - name: Docker Login - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -251,7 +251,7 @@ jobs: run: tar zxf sources.tar.gz - name: Docker Login - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: registry: ghcr.io username: ${{ github.actor }} From d0fa5af39b8eaab9067db0dec45fbbf6f996e120 Mon Sep 17 00:00:00 2001 From: Jiri Vlasak Date: Mon, 11 May 2026 09:09:12 +0200 Subject: [PATCH 364/568] audioutils: Add RTTTL parsing library Add a simple library for parsing Ring Tone Text Transfer Language (RTTTL). Signed-off-by: Jiri Vlasak --- audioutils/rtttl-c/.gitignore | 1 + audioutils/rtttl-c/Kconfig | 21 +++++++++++++++ audioutils/rtttl-c/Make.defs | 25 ++++++++++++++++++ audioutils/rtttl-c/Makefile | 50 +++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 audioutils/rtttl-c/.gitignore create mode 100644 audioutils/rtttl-c/Kconfig create mode 100644 audioutils/rtttl-c/Make.defs create mode 100644 audioutils/rtttl-c/Makefile diff --git a/audioutils/rtttl-c/.gitignore b/audioutils/rtttl-c/.gitignore new file mode 100644 index 000000000..554f93513 --- /dev/null +++ b/audioutils/rtttl-c/.gitignore @@ -0,0 +1 @@ +/rtttl-c diff --git a/audioutils/rtttl-c/Kconfig b/audioutils/rtttl-c/Kconfig new file mode 100644 index 000000000..8ea3355d5 --- /dev/null +++ b/audioutils/rtttl-c/Kconfig @@ -0,0 +1,21 @@ +config AUDIOUTILS_RTTTL_C + bool "RTTTL parsing library" + default n + ---help--- + Simple library for parsing Ring Tone Text Transfer Language (RTTTL) + + Define how to make a sound: + + void + play_tone(struct rtttl_tone tone) + { + /* TODO: Make a sound with + * tone.frequency_100hz + * tone.period_us + * tone.duration_us + */ + } + + and then play RTTTL string: + + rtttl_play("...", play_tone); diff --git a/audioutils/rtttl-c/Make.defs b/audioutils/rtttl-c/Make.defs new file mode 100644 index 000000000..fa9aa98f8 --- /dev/null +++ b/audioutils/rtttl-c/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/audioutils/rtttl-c/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_AUDIOUTILS_RTTTL_C),) +CONFIGURED_APPS += $(APPDIR)/audioutils/rtttl-c +endif diff --git a/audioutils/rtttl-c/Makefile b/audioutils/rtttl-c/Makefile new file mode 100644 index 000000000..aa290169d --- /dev/null +++ b/audioutils/rtttl-c/Makefile @@ -0,0 +1,50 @@ +############################################################################ +# apps/audioutils/rtttl-c/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +CSRCS = $(RTTTL_C_DIR)/rtttl.c + +RTTTL_C_DIR = rtttl-c +RTTTL_C_VERSION = v0.1.0 +RTTTL_C_RTTTL_H_SHA256 = 6331174ae34a419ad427d9755f8ba9d3b6a92c09ecc4f36bbe07ec5e4d0cc007 +RTTTL_C_RTTTL_C_SHA256 = f0db64ef0b68136bac24616a3d62508bcc54ccdd68265d6447d99b264653b7b9 + +$(RTTTL_C_DIR): + $(Q) echo "Cloning rtttl-c repo..." + $(Q) git clone --depth=1 --branch=$(RTTTL_C_VERSION) https://git.sr.ht/~qeef/rtttl-c + $(Q) touch $(RTTTL_C_DIR) + $(Q) echo "Checking rtttl-c hashes..." + $(Q) $(APPDIR)/tools/check-hash.sh sha256 $(RTTTL_C_RTTTL_H_SHA256) $@/rtttl.h + $(Q) $(APPDIR)/tools/check-hash.sh sha256 $(RTTTL_C_RTTTL_C_SHA256) $@/rtttl.c + +create_includes: $(RTTTL_C_DIR)/rtttl.h + $(Q) cp $< $(APPDIR)/include/audioutils + +context:: $(RTTTL_C_DIR) + $(Q) $(MAKE) create_includes + +distclean:: + $(call DELFILE, $(APPDIR)/include/audioutils/rtttl.h) + $(call DELDIR, rtttl-c) + +include $(APPDIR)/Application.mk From 72bedd5c5df72f85daa65f4ddeac54efcf84c080 Mon Sep 17 00:00:00 2001 From: Shoji Tokunaga Date: Tue, 26 May 2026 10:06:13 +0900 Subject: [PATCH 365/568] apps/tools: Make hello_rust_cargo buildable with make * Add JSON specification compatibility flag. * Add Rust target conversion support for `aarch64` on macOS. Signed-off-by: Shoji Tokunaga --- tools/Rust.mk | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/Rust.mk b/tools/Rust.mk index 8e037aef6..3a5f72806 100644 --- a/tools/Rust.mk +++ b/tools/Rust.mk @@ -52,6 +52,9 @@ $(or \ $(and $(filter x86,$(LLVM_ARCHTYPE)), \ $(APPDIR)/tools/i486-unknown-nuttx.json \ ), \ + $(and $(filter aarch64,$(LLVM_ARCHTYPE)), \ + $(if $(filter y,$(CONFIG_HOST_MACOS)),aarch64-apple-darwin) \ + ), \ $(and $(filter thumb%,$(LLVM_ARCHTYPE)), \ $(if $(filter thumbv8m%,$(LLVM_ARCHTYPE)), \ $(if $(filter cortex-m23,$(LLVM_CPUTYPE)),thumbv8m.base,thumbv8m.main)-nuttx-$(LLVM_ABITYPE), \ @@ -91,7 +94,7 @@ ifeq ($(CONFIG_DEBUG_FULLOPT),y) define RUST_CARGO_BUILD NUTTX_INCLUDE_DIR=$(TOPDIR)/include:$(TOPDIR)/include/arch \ RUSTFLAGS="-Zunstable-options -Cpanic=immediate-abort" \ - cargo build --release -Zbuild-std=std,panic_abort \ + cargo build --release -Zbuild-std=std,panic_abort -Zjson-target-spec \ --manifest-path $(2)/$(1)/Cargo.toml \ --target $(call RUST_TARGET_TRIPLE) endef @@ -99,7 +102,7 @@ else define RUST_CARGO_BUILD @echo "Building Rust code with cargo..." NUTTX_INCLUDE_DIR=$(TOPDIR)/include:$(TOPDIR)/include/arch \ - cargo build -Zbuild-std=std,panic_abort \ + cargo build -Zbuild-std=std,panic_abort -Zjson-target-spec \ --manifest-path $(2)/$(1)/Cargo.toml \ --target $(call RUST_TARGET_TRIPLE) endef From ed063a0981f97949c1294745eb5602bfa8170d36 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Tue, 19 May 2026 16:42:47 +0800 Subject: [PATCH 366/568] nshlib: fix infinite loop on broken stdout in nsh_catfile When stdout is broken (e.g. PTY master closed), nsh_catfile could spin forever: write() fails, error logging generates syslog output to /dev/log, next read() picks it up, write() fails again, ad infinitum. Two fixes: - nsh_console: drop the _err() in nsh_consolewrite entirely. The risk is errno-agnostic (EPIPE / EIO / ENOSPC / ...): any failure logged here can be re-injected by the syslog backend when OUTFD is bound to /dev/log. Callers already see the failure via the negative return value and errno, so on-failure logging at this layer is redundant. - nsh_fsutils: jump straight from the inner write-failure path to a single errout: cleanup label instead of using a two-level break + flag check, so a failed write cannot fall through to another read(). Assisted-by: GitHubCopilot:claude-4.7-opus Signed-off-by: wangjianyu3 --- nshlib/nsh_console.c | 21 +++++++++++---------- nshlib/nsh_fsutils.c | 9 ++++++++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/nshlib/nsh_console.c b/nshlib/nsh_console.c index ebcbe6fb2..0e4284222 100644 --- a/nshlib/nsh_console.c +++ b/nshlib/nsh_console.c @@ -131,18 +131,19 @@ static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes) { FAR struct console_stdio_s *pstate = (FAR struct console_stdio_s *)vtbl; - ssize_t ret; - /* Write the data to the output stream */ + /* Write the data to the output stream. + * + * Errors are reported to the caller via the negative return value and + * errno; do NOT _err() here. OUTFD may itself be wired to the syslog + * backend (e.g. nsh_catfile dumping /dev/log on dmesg), in which case + * logging on write failure would produce new bytes, get picked up by + * the next read(), and lock the shell into an infinite loop at the + * highest priority — independent of which errno (EPIPE/EIO/ENOSPC/...) + * the underlying device returns. + */ - ret = write(OUTFD(pstate), buffer, nbytes); - if (ret < 0) - { - _err("ERROR: [%d] Failed to send buffer: %d\n", - OUTFD(pstate), errno); - } - - return ret; + return write(OUTFD(pstate), buffer, nbytes); } /**************************************************************************** diff --git a/nshlib/nsh_fsutils.c b/nshlib/nsh_fsutils.c index 878c1d18e..7044d8d54 100644 --- a/nshlib/nsh_fsutils.c +++ b/nshlib/nsh_fsutils.c @@ -228,8 +228,14 @@ int nsh_catfile(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, NSH_ERRNO_OF(errcode)); } + /* Jump straight to cleanup. On a broken stdout (e.g. + * closed PTY master) we must not keep reading: the + * outer loop would otherwise drain /dev/log forever + * when cat is dumping it on dmesg. + */ + ret = ERROR; - break; + goto errout; } else { @@ -255,6 +261,7 @@ int nsh_catfile(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, /* Close the input file and return the result */ +errout: close(fd); free(buffer); return ret; From 492a86691d5b25a2de8510c15db8eaf73fe550f2 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Thu, 14 Aug 2025 21:45:53 +0800 Subject: [PATCH 367/568] system/nxinit: Add NuttX Init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This component (abbreviated as "NxInit") is specifically developed for NuttX and intended for system initialization. While we have adopted the Android Init Language among various syntax options, this is a brand-new implementation—it is not a port or variant of Android Init. Refer to the implementation of Android Init Language, consists of five broad classes of statements: Actions, Commands, Services, Options, and Imports. Actions support two types of triggers: event and action. Action triggers also support runtime triggering. Services support lifecycle management, including automatic restart (at specified intervals), and starting/stopping individually or by class. Import supports files or directories, and we may add a static method in the future. The following are some differences: 1. The Android Init Language treats lines starting with `#` as comments, while we use a preprocessor to handle comments. 2. For action commands, we can omit "exec" and directly execute built-in apps or nsh builtins. 3. Regarding the property service, users can either adapt it by self or directly use the preset NVS-based properties. 4. Only part of standard action commands and service options are implemented currlently. To enable system/nxinit: ```diff -CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_ENTRYPOINT="init_main" +CONFIG_SYSTEM_NXINIT=y ``` For format and additional details, refer to: https://android.googlesource.com/platform/system/core/+/ master/init/README.md Signed-off-by: wangjianyu3 --- system/nxinit/CMakeLists.txt | 39 +++ system/nxinit/Kconfig | 118 +++++++ system/nxinit/Make.defs | 25 ++ system/nxinit/Makefile | 39 +++ system/nxinit/action.c | 320 ++++++++++++++++++ system/nxinit/action.h | 85 +++++ system/nxinit/builtin.c | 184 +++++++++++ system/nxinit/builtin.h | 38 +++ system/nxinit/import.c | 60 ++++ system/nxinit/import.h | 38 +++ system/nxinit/init.c | 252 ++++++++++++++ system/nxinit/init.h | 91 +++++ system/nxinit/parser.c | 288 ++++++++++++++++ system/nxinit/parser.h | 60 ++++ system/nxinit/service.c | 622 +++++++++++++++++++++++++++++++++++ system/nxinit/service.h | 138 ++++++++ 16 files changed, 2397 insertions(+) create mode 100644 system/nxinit/CMakeLists.txt create mode 100644 system/nxinit/Kconfig create mode 100644 system/nxinit/Make.defs create mode 100644 system/nxinit/Makefile create mode 100644 system/nxinit/action.c create mode 100644 system/nxinit/action.h create mode 100644 system/nxinit/builtin.c create mode 100644 system/nxinit/builtin.h create mode 100644 system/nxinit/import.c create mode 100644 system/nxinit/import.h create mode 100644 system/nxinit/init.c create mode 100644 system/nxinit/init.h create mode 100644 system/nxinit/parser.c create mode 100644 system/nxinit/parser.h create mode 100644 system/nxinit/service.c create mode 100644 system/nxinit/service.h diff --git a/system/nxinit/CMakeLists.txt b/system/nxinit/CMakeLists.txt new file mode 100644 index 000000000..5aef892e9 --- /dev/null +++ b/system/nxinit/CMakeLists.txt @@ -0,0 +1,39 @@ +# ############################################################################## +# apps/system/nxinit/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_SYSTEM_NXINIT) + + set(CSRCS init.c action.c builtin.c import.c parser.c service.c) + + nuttx_add_application( + MODULE + ${CONFIG_SYSTEM_NXINIT} + NAME + ${CONFIG_SYSTEM_NXINIT_PROGNAME} + STACKSIZE + ${CONFIG_SYSTEM_NXINIT_STACKSIZE} + PRIORITY + ${CONFIG_SYSTEM_NXINIT_PRIORITY} + SRCS + ${CSRCS}) + +endif() diff --git a/system/nxinit/Kconfig b/system/nxinit/Kconfig new file mode 100644 index 000000000..8b1bb6b22 --- /dev/null +++ b/system/nxinit/Kconfig @@ -0,0 +1,118 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config SYSTEM_NXINIT + tristate "NuttX Init" + default n + depends on LIBC_EXECFUNCS + depends on SCHED_CHILD_STATUS + ---help--- + Enable NxInit(NuttX Init) component for system initialization. + The script of NxInit(init.rc) is compatible with the Android Init Language syntax. + +if SYSTEM_NXINIT + +# +# Basic +# + +config SYSTEM_NXINIT_PRIORITY + int "Thread priority" + default 100 + +config SYSTEM_NXINIT_STACKSIZE + int "Stack size" + default DEFAULT_TASK_STACKSIZE + +config SYSTEM_NXINIT_PROGNAME + string "Program name" + default "init" + +# +# RC +# + +config SYSTEM_NXINIT_RC_LINE_MAX + int "Max line length of RC file" + default 128 + ---help--- + Maximum line length of RC file. + More details: https://android.googlesource.com/platform/system/core/+/master/init/README.md + +# +# Action +# + +config SYSTEM_NXINIT_ACTION_CMD_ARGS_MAX + int "Max number of command arguments" + default 8 + ---help--- + Maximum number of command arguments. + Form: + ``` + on + + + + ... + ``` + +config SYSTEM_NXINIT_ACTION_MANAGER_EVENT_MAX + int "Max number of action manager events" + default 32 + ---help--- + Maximum number of action manager events. + ``` + struct action_manager_s + { + ... + FAR char *events[CONFIG_SYSTEM_NXINIT_ACTION_MANAGER_EVENT_MAX]; + ... + }; + ``` + +# +# Service +# + +config SYSTEM_NXINIT_SERVICE_ARGS_MAX + int "Max number of service arguments" + default 8 + range 3 64 + ---help--- + Maximum number of service arguments, + including "name", "pathname" and key word "service"(at least 3). Form: + ``` + service [ ]* +