From fb27cba23f93b1160272bd36420baf38a922ce0d Mon Sep 17 00:00:00 2001 From: kurisaw <2053731441@qq.com> Date: Mon, 28 Jul 2025 09:23:32 +0800 Subject: [PATCH 1/3] fix(kernel)/improve(utest):fix the legacy issue related to the length of the object name version --- examples/utest/testcases/kernel/Kconfig | 10 +- examples/utest/testcases/kernel/object_tc.c | 367 +++++++++++++++++++- src/klibc/utest/TC_rt_memcmp.c | 2 +- src/object.c | 18 +- 4 files changed, 372 insertions(+), 25 deletions(-) diff --git a/examples/utest/testcases/kernel/Kconfig b/examples/utest/testcases/kernel/Kconfig index ec1054fae86..278de61a293 100644 --- a/examples/utest/testcases/kernel/Kconfig +++ b/examples/utest/testcases/kernel/Kconfig @@ -1,9 +1,5 @@ menu "Kernel Testcase" -config UTEST_OBJECT_TC - bool "object test" - default y - config UTEST_MEMHEAP_TC bool "memheap stability test" default y @@ -14,6 +10,12 @@ config UTEST_SMALL_MEM_TC default y depends on RT_USING_SMALL_MEM +config UTEST_OBJECT_TC + select RT_USING_DEVICE + select RT_USING_SEMAPHORE + bool "object test" + default n + config UTEST_SLAB_TC bool "slab test" default n diff --git a/examples/utest/testcases/kernel/object_tc.c b/examples/utest/testcases/kernel/object_tc.c index 156fd8e7307..239366f0e2c 100644 --- a/examples/utest/testcases/kernel/object_tc.c +++ b/examples/utest/testcases/kernel/object_tc.c @@ -13,51 +13,89 @@ #include /** - * @brief Test case for verifying object name handling functionality + * @brief Comprehensive test suite for RT-Thread object system * * @note This test suite validates: - * 1. Proper truncation of long object names - * 2. Correct NULL name handling - * 3. Exact length name preservation - * 4. Both static and dynamic object initialization - * 5. Memory safety and boundary conditions + * 1. Object name handling (truncation, NULL, exact length, long names) + * 2. Static and dynamic object initialization + * 3. Object finding functionality (rt_object_find, rt_thread_find, rt_device_find) + * 4. Object information and enumeration + * 5. Type checking and system object detection + * 6. Memory safety and boundary conditions */ +/* Global counter for unique object names */ +static rt_uint32_t name_counter = 0; + +/* Generate unique name to avoid conflicts, considering RT_NAME_MAX truncation */ +static void generate_unique_name(char *buf, rt_size_t size, const char *prefix) +{ + rt_snprintf(buf, size, "%s%d", prefix, name_counter++); + rt_size_t len = rt_strlen(buf); + if (len > RT_NAME_MAX - 1) + { + len = RT_NAME_MAX - 1; + buf[len] = '\0'; + } + /* Check if name (or truncated name) exists */ + while (rt_object_find(buf, RT_Object_Class_Unknown) != RT_NULL || + rt_thread_find(buf) != RT_NULL || + rt_device_find(buf) != RT_NULL) + { + name_counter++; + rt_snprintf(buf, size, "%s%d", prefix, name_counter); + len = rt_strlen(buf); + if (len > RT_NAME_MAX - 1) + { + len = RT_NAME_MAX - 1; + buf[len] = '\0'; + } + } + rt_kprintf("Generated unique name: %s\n", buf); +} + static void test_object_name_handling(void) { - struct rt_object static_obj1; - struct rt_object static_obj2; - struct rt_object static_obj3; + struct rt_object static_obj1, static_obj2, static_obj3; rt_object_t dyn_obj = RT_NULL; char test_name[RT_NAME_MAX + 5]; + char unique_name[RT_NAME_MAX]; + /* Prepare a long test name */ for (int i = 0; i < sizeof(test_name) - 1; i++) { test_name[i] = 'A' + (i % 26); } test_name[sizeof(test_name) - 1] = '\0'; - /* Test 1: Static Object Initialization - Extra Long Name */ + /* Test 1: Static Object with Extra Long Name */ + generate_unique_name(unique_name, RT_NAME_MAX, "long"); rt_object_init(&static_obj1, RT_Object_Class_Thread, test_name); uassert_true(rt_strlen(static_obj1.name) <= RT_NAME_MAX - 1); uassert_true(static_obj1.name[RT_NAME_MAX - 1] == '\0'); + uassert_true(rt_strncmp(static_obj1.name, test_name, RT_NAME_MAX - 1) == 0); + uassert_true(rt_object_is_systemobject(&static_obj1)); - /* Test 2: Dynamic Object Allocation */ + /* Test 2: Dynamic Object with Long Name */ + generate_unique_name(unique_name, RT_NAME_MAX, "dynlong"); dyn_obj = rt_object_allocate(RT_Object_Class_Thread, test_name); uassert_not_null(dyn_obj); if (dyn_obj) { uassert_true(rt_strlen(dyn_obj->name) <= RT_NAME_MAX - 1); uassert_true(dyn_obj->name[RT_NAME_MAX - 1] == '\0'); + uassert_true(rt_strncmp(dyn_obj->name, test_name, RT_NAME_MAX - 1) == 0); + uassert_false(rt_object_is_systemobject(dyn_obj)); rt_object_delete(dyn_obj); dyn_obj = RT_NULL; } - /* Test 3: NULL Name Handling - Using New Static Object */ + /* Test 3: NULL Name Handling */ + generate_unique_name(unique_name, RT_NAME_MAX, "null"); rt_object_init(&static_obj2, RT_Object_Class_Thread, NULL); uassert_true(static_obj2.name[0] == '\0'); - /* Test 4: Dynamic Object with NULL Name */ + generate_unique_name(unique_name, RT_NAME_MAX, "dynull"); dyn_obj = rt_object_allocate(RT_Object_Class_Thread, NULL); uassert_not_null(dyn_obj); if (dyn_obj) @@ -67,31 +105,328 @@ static void test_object_name_handling(void) dyn_obj = RT_NULL; } - /* Test 5: Fixed-Length Name - Using Third Static Object */ + /* Test 4: Exact Length Name */ char exact_name[RT_NAME_MAX]; rt_memset(exact_name, 'B', RT_NAME_MAX - 1); exact_name[RT_NAME_MAX - 1] = '\0'; - + generate_unique_name(unique_name, RT_NAME_MAX, "exact"); rt_object_init(&static_obj3, RT_Object_Class_Thread, exact_name); uassert_str_equal(static_obj3.name, exact_name); + /* Cleanup */ rt_object_detach(&static_obj1); rt_object_detach(&static_obj2); rt_object_detach(&static_obj3); } +static void test_object_find_operations(void) +{ + rt_object_t found; + char name[RT_NAME_MAX]; + char long_name[16]; /* Longer than typical RT_NAME_MAX=8 */ + const char *nonexist_name = "nonexistent_obj"; + + /* Test 1: Find static thread object with rt_object_find */ + struct rt_object static_obj; + generate_unique_name(name, RT_NAME_MAX, "sobj"); + rt_object_init(&static_obj, RT_Object_Class_Thread, name); + found = rt_object_find(name, RT_Object_Class_Thread); + if (found == RT_NULL) + { + rt_kprintf("Failed to find static thread object: %s\n", name); + } + uassert_not_null(found); + uassert_ptr_equal(found, &static_obj); + uassert_str_equal(found->name, name); + rt_object_detach(&static_obj); + + /* Test 2: Find dynamic thread object with rt_object_find */ + generate_unique_name(name, RT_NAME_MAX, "dobj"); + rt_object_t dyn_obj = rt_object_allocate(RT_Object_Class_Thread, name); + uassert_not_null(dyn_obj); + if (dyn_obj) + { + found = rt_object_find(name, RT_Object_Class_Thread); + if (found == RT_NULL) + { + rt_kprintf("Failed to find dynamic thread object: %s\n", name); + } + uassert_not_null(found); + uassert_ptr_equal(found, dyn_obj); + uassert_str_equal(found->name, name); + rt_object_delete(dyn_obj); + } + + /* Test 3: Find thread object with rt_thread_find */ + generate_unique_name(name, RT_NAME_MAX, "thr"); + rt_thread_t thread = rt_thread_create(name, RT_NULL, RT_NULL, 1024, 20, 10); + uassert_not_null(thread); + if (thread) + { + rt_thread_t found_thread = rt_thread_find(name); + if (found_thread == RT_NULL) + { + rt_kprintf("Failed to find thread with rt_thread_find: %s\n", name); + } + uassert_not_null(found_thread); + uassert_ptr_equal(found_thread, thread); + uassert_str_equal(found_thread->parent.name, name); + rt_thread_delete(thread); + } + +#ifdef RT_USING_DEVICE + /* Test 4: Find device object with rt_device_find */ + struct rt_device device; + generate_unique_name(name, RT_NAME_MAX, "dev"); + rt_err_t ret = rt_device_register(&device, name, RT_DEVICE_FLAG_RDONLY); + uassert_int_equal(ret, RT_EOK); + rt_device_t found_device = rt_device_find(name); + if (found_device == RT_NULL) + { + rt_kprintf("Failed to find device with rt_device_find: %s\n", name); + } + uassert_not_null(found_device); + uassert_ptr_equal(found_device, &device); + uassert_str_equal(found_device->parent.name, name); + rt_device_unregister(&device); +#endif + + /* Test 5: Find thread with long name (exceeding RT_NAME_MAX) */ + rt_snprintf(long_name, sizeof(long_name), "longthreadname%d", name_counter++); + rt_thread_t long_thread = rt_thread_create(long_name, RT_NULL, RT_NULL, 1024, 20, 10); + uassert_not_null(long_thread); + if (long_thread) + { + char truncated_name[RT_NAME_MAX]; + rt_strncpy(truncated_name, long_name, RT_NAME_MAX - 1); + truncated_name[RT_NAME_MAX - 1] = '\0'; + rt_kprintf("Testing long thread name: %s, truncated to: %s\n", long_name, truncated_name); + rt_thread_t found_thread = rt_thread_find(truncated_name); + if (found_thread == RT_NULL) + { + rt_kprintf("Failed to find thread with rt_thread_find: %s\n", truncated_name); + } + uassert_not_null(found_thread); + uassert_ptr_equal(found_thread, long_thread); + uassert_str_equal(found_thread->parent.name, truncated_name); + rt_thread_delete(long_thread); + } + + /* Test 6: Find thread with long name directly (no manual truncation) */ + rt_snprintf(long_name, sizeof(long_name), "longthreadname%d", name_counter++); + rt_thread_t long_thread_direct = rt_thread_create(long_name, RT_NULL, RT_NULL, 1024, 20, 10); + uassert_not_null(long_thread_direct); + if (long_thread_direct) + { + rt_kprintf("Testing direct long name: %s\n", long_name); + rt_thread_t found_thread = rt_thread_find(long_name); + if (found_thread == RT_NULL) + { + rt_kprintf("Failed to find thread with rt_thread_find: %s\n", long_name); + } + uassert_not_null(found_thread); + uassert_ptr_equal(found_thread, long_thread_direct); + char truncated_name[RT_NAME_MAX]; + rt_strncpy(truncated_name, long_name, RT_NAME_MAX - 1); + truncated_name[RT_NAME_MAX - 1] = '\0'; + uassert_str_equal(found_thread->parent.name, truncated_name); + rt_thread_delete(long_thread_direct); + } + +#ifdef RT_USING_DEVICE + /* Test 7: Find device with long name (exceeding RT_NAME_MAX) */ + rt_snprintf(long_name, sizeof(long_name), "longdevicename%d", name_counter++); + struct rt_device long_device; + ret = rt_device_register(&long_device, long_name, RT_DEVICE_FLAG_RDONLY); + uassert_int_equal(ret, RT_EOK); + if (ret == RT_EOK) + { + char truncated_name[RT_NAME_MAX]; + rt_strncpy(truncated_name, long_name, RT_NAME_MAX - 1); + truncated_name[RT_NAME_MAX - 1] = '\0'; + rt_kprintf("Testing long device name: %s, truncated to: %s\n", long_name, truncated_name); + rt_device_t found_device = rt_device_find(truncated_name); + if (found_device == RT_NULL) + { + rt_kprintf("Failed to find device with rt_device_find: %s\n", truncated_name); + } + uassert_not_null(found_device); + uassert_ptr_equal(found_device, &long_device); + uassert_str_equal(found_device->parent.name, truncated_name); + rt_device_unregister(&long_device); + } +#endif + + /* Test 8: Find non-existent object with rt_object_find */ + found = rt_object_find(nonexist_name, RT_Object_Class_Thread); + uassert_null(found); + + /* Test 9: Find with NULL name with rt_object_find */ + found = rt_object_find(NULL, RT_Object_Class_Thread); + uassert_null(found); + + /* Test 10: Find with NULL name with rt_thread_find */ + rt_thread_t found_thread = rt_thread_find(NULL); + uassert_null(found_thread); + +#ifdef RT_USING_DEVICE + /* Test 11: Find with NULL name with rt_device_find */ + rt_device_t found_device_null = rt_device_find(NULL); + uassert_null(found_device_null); +#endif +} + +static void test_object_info_enumeration(void) +{ + struct rt_object static_objs[3]; + rt_object_t dyn_objs[2] = {RT_NULL, RT_NULL}; + char names[5][RT_NAME_MAX]; + + /* Generate unique names */ + for (int i = 0; i < 5; i++) + { + generate_unique_name(names[i], RT_NAME_MAX, "enum"); + } + + /* Create test objects */ + for (int i = 0; i < 3; i++) + { + rt_object_init(&static_objs[i], RT_Object_Class_Thread, names[i]); + } + + for (int i = 0; i < 2; i++) + { + dyn_objs[i] = rt_object_allocate(RT_Object_Class_Thread, names[i + 3]); + uassert_not_null(dyn_objs[i]); + } + + /* Test 1: Get object information */ + struct rt_object_information *info = rt_object_get_information(RT_Object_Class_Thread); + uassert_not_null(info); + uassert_int_equal(info->type, RT_Object_Class_Thread); + + /* Test 2: Get object count */ + int count = rt_object_get_length(RT_Object_Class_Thread); + uassert_true(count >= 5); /* At least our 5 objects */ + + /* Test 3: Get object pointers with sufficient buffer */ + rt_object_t *objects = (rt_object_t *)rt_malloc((count + 2) * sizeof(rt_object_t)); + uassert_not_null(objects); + if (objects) + { + int ret = rt_object_get_pointers(RT_Object_Class_Thread, objects, count + 2); + uassert_int_equal(ret, count); + + /* Verify our objects are in the list */ + int found_count = 0; + for (int i = 0; i < ret; i++) + { + for (int j = 0; j < 3; j++) + { + if (objects[i] == &static_objs[j]) found_count++; + } + + for (int j = 0; j < 2; j++) + { + if (objects[i] == dyn_objs[j]) found_count++; + } + } + uassert_int_equal(found_count, 5); + + rt_free(objects); + } + + /* Test 4: Get object pointers with small buffer */ + rt_object_t one_object[1]; + int ret = rt_object_get_pointers(RT_Object_Class_Thread, one_object, 1); + uassert_true(ret <= 1); + + /* Test 5: Empty container (use Semaphore as it may be empty) */ +#ifdef RT_USING_SEMAPHORE + int empty_count = rt_object_get_length(RT_Object_Class_Semaphore); + uassert_true(empty_count >= 0); /* Cannot assume empty, but verify non-negative */ +#endif + + /* Cleanup */ + for (int i = 0; i < 3; i++) + { + rt_object_detach(&static_objs[i]); + } + + for (int i = 0; i < 2; i++) + { + if (dyn_objs[i]) + { + rt_object_delete(dyn_objs[i]); + } + } +} + +static void test_object_type_handling(void) +{ + struct rt_object obj; + char name[RT_NAME_MAX]; + generate_unique_name(name, RT_NAME_MAX, "typ"); /* Use short prefix */ + rt_kprintf("Object name for test: %s\n", name); + rt_object_init(&obj, RT_Object_Class_Thread, name); + + /* Test 1: Get object type */ + uassert_int_equal(rt_object_get_type(&obj), RT_Object_Class_Thread); + + /* Test 2: Check system object */ + uassert_true(rt_object_is_systemobject(&obj)); + + /* Test 3: Get name with sufficient buffer */ + char name_buf[RT_NAME_MAX]; + rt_err_t ret = rt_object_get_name(&obj, name_buf, sizeof(name_buf)); + uassert_int_equal(ret, RT_EOK); + uassert_str_equal(name_buf, name); + + /* Test 4: Get name with small buffer */ + char small_buf[4] = {0}; /* Initialize to avoid undefined behavior */ + ret = rt_object_get_name(&obj, small_buf, sizeof(small_buf)); + uassert_int_equal(ret, RT_EOK); + rt_kprintf("small_buf after rt_object_get_name: %s (bytes: %02x %02x %02x %02x)\n", + small_buf, small_buf[0], small_buf[1], small_buf[2], small_buf[3]); + uassert_true(rt_strncmp(small_buf, name, sizeof(small_buf) - 1) == 0); + uassert_true(small_buf[sizeof(small_buf) - 1] == '\0'); /* Expect null-termination (assuming kernel fix) */ + + /* Test 5: Get name with invalid parameters */ + ret = rt_object_get_name(RT_NULL, name_buf, sizeof(name_buf)); + uassert_int_equal(ret, -RT_EINVAL); + ret = rt_object_get_name(&obj, NULL, sizeof(name_buf)); + uassert_int_equal(ret, -RT_EINVAL); + ret = rt_object_get_name(&obj, name_buf, 0); + uassert_int_equal(ret, -RT_EINVAL); + + rt_object_detach(&obj); +} + static rt_err_t testcase_init(void) { + /* Ensure scheduler is available */ + if (!rt_scheduler_is_available()) + { + rt_kprintf("Scheduler is not available, test may fail\n"); + return -RT_ERROR; + } + /* Reset name counter for each test suite run */ + name_counter = 0; + rt_kprintf("RT_NAME_MAX = %d\n", RT_NAME_MAX); return RT_EOK; } static rt_err_t testcase_cleanup(void) { + /* No dynamic cleanup needed, as each test case handles its own cleanup */ return RT_EOK; } static void test_object_suite(void) { UTEST_UNIT_RUN(test_object_name_handling); + UTEST_UNIT_RUN(test_object_find_operations); + UTEST_UNIT_RUN(test_object_info_enumeration); + UTEST_UNIT_RUN(test_object_type_handling); } -UTEST_TC_EXPORT(test_object_suite, "testcases.kernel.object_test", testcase_init, testcase_cleanup, 10); +UTEST_TC_EXPORT(test_object_suite, "testcases.kernel.object_test", testcase_init, testcase_cleanup, 20); diff --git a/src/klibc/utest/TC_rt_memcmp.c b/src/klibc/utest/TC_rt_memcmp.c index e8baf556ace..45d4d756ccc 100644 --- a/src/klibc/utest/TC_rt_memcmp.c +++ b/src/klibc/utest/TC_rt_memcmp.c @@ -121,7 +121,7 @@ static void TC_rt_memcmp_partial_match(void) uassert_int_not_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0); } -#define LARGE_ARRAY_SIZE 1000 +#define LARGE_ARRAY_SIZE 500 static void TC_rt_memcmp_large_array(void) { diff --git a/src/object.c b/src/object.c index 2452001f342..c21fcb6c0ac 100644 --- a/src/object.c +++ b/src/object.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2025, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -672,7 +672,13 @@ static rt_err_t _match_name(struct rt_object *obj, void *data) { struct _obj_find_param *param = data; const char *name = param->match_name; - if (rt_strncmp(obj->name, name, RT_NAME_MAX) == 0) + char truncated_name[RT_NAME_MAX]; + + /* Truncate input name to RT_NAME_MAX - 1 to match object name storage */ + rt_strncpy(truncated_name, name, RT_NAME_MAX - 1); + truncated_name[RT_NAME_MAX - 1] = '\0'; + + if (rt_strcmp(obj->name, truncated_name) == 0) { param->matched_obj = obj; @@ -705,7 +711,8 @@ rt_object_t rt_object_find(const char *name, rt_uint8_t type) }; /* parameter check */ - if (name == RT_NULL) return RT_NULL; + if (name == RT_NULL || rt_object_get_information(type) == RT_NULL) + return RT_NULL; /* which is invoke in interrupt status */ RT_DEBUG_NOT_IN_INTERRUPT; @@ -731,7 +738,9 @@ rt_err_t rt_object_get_name(rt_object_t object, char *name, rt_uint8_t name_size if ((object != RT_NULL) && (name != RT_NULL) && (name_size != 0U)) { const char *obj_name = object->name; - (void) rt_strncpy(name, obj_name, (rt_size_t)name_size); + rt_strncpy(name, obj_name, (rt_size_t)name_size); + /* Ensure null-termination */ + name[name_size - 1] = '\0'; result = RT_EOK; } @@ -794,3 +803,4 @@ rt_err_t rt_custom_object_destroy(rt_object_t obj) #endif /**@}*/ + From 95fb77dc388bd6d5999ee8b45c578f417fa232f9 Mon Sep 17 00:00:00 2001 From: kurisaw <2053731441@qq.com> Date: Mon, 28 Jul 2025 09:23:48 +0800 Subject: [PATCH 2/3] add object testcase for auto ci --- .github/utest/kernel/object.cfg | 6 ++++++ .github/workflows/utest_auto_run.yml | 3 +++ 2 files changed, 9 insertions(+) create mode 100644 .github/utest/kernel/object.cfg diff --git a/.github/utest/kernel/object.cfg b/.github/utest/kernel/object.cfg new file mode 100644 index 00000000000..d522d6a637d --- /dev/null +++ b/.github/utest/kernel/object.cfg @@ -0,0 +1,6 @@ +CONFIG_UTEST_OBJECT_TC=y + +# dependencies +CONFIG_RT_USING_CI_ACTION=y +CONFIG_RT_USING_DEVICE=y +CONFIG_RT_USING_SEMAPHORE=y diff --git a/.github/workflows/utest_auto_run.yml b/.github/workflows/utest_auto_run.yml index 1a3660f8d0a..d8827b8ecfa 100644 --- a/.github/workflows/utest_auto_run.yml +++ b/.github/workflows/utest_auto_run.yml @@ -47,6 +47,9 @@ jobs: config_file: - "default.cfg" + # kernel + # - "kernel/object.cfg" + # cpp11 # - "cpp11/cpp11.cfg" From 427952b47c6058e174eaae061b9d5d1941ba7644 Mon Sep 17 00:00:00 2001 From: kurisaw <2053731441@qq.com> Date: Wed, 30 Jul 2025 10:36:42 +0800 Subject: [PATCH 3/3] limit the size of the object name --- bsp/qemu-vexpress-a9/.config | 22 +- bsp/qemu-vexpress-a9/rtconfig.h | 10 +- examples/utest/testcases/kernel/object_tc.c | 350 +++++++------------- src/object.c | 32 +- 4 files changed, 172 insertions(+), 242 deletions(-) diff --git a/bsp/qemu-vexpress-a9/.config b/bsp/qemu-vexpress-a9/.config index 8953cba090c..ffc470a12c2 100644 --- a/bsp/qemu-vexpress-a9/.config +++ b/bsp/qemu-vexpress-a9/.config @@ -108,7 +108,7 @@ # CONFIG_RT_UTEST_TC_USING_KLIBC is not set # end of klibc options -CONFIG_RT_NAME_MAX=8 +CONFIG_RT_NAME_MAX=16 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_NANO is not set # CONFIG_RT_USING_SMART is not set @@ -496,6 +496,7 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # CONFIG_PKG_USING_FREEMODBUS is not set # CONFIG_PKG_USING_NANOPB is not set # CONFIG_PKG_USING_WIFI_HOST_DRIVER is not set +# CONFIG_PKG_USING_ESP_HOSTED is not set # # Wi-Fi @@ -603,6 +604,7 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # CONFIG_PKG_USING_QMODBUS is not set # CONFIG_PKG_USING_PNET is not set # CONFIG_PKG_USING_OPENER is not set +# CONFIG_PKG_USING_FREEMQTT is not set # end of IoT - internet of things # @@ -831,6 +833,7 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # CONFIG_PKG_USING_RMP is not set # CONFIG_PKG_USING_R_RHEALSTONE is not set # CONFIG_PKG_USING_HEARTBEAT is not set +# CONFIG_PKG_USING_MICRO_ROS_RTTHREAD_PACKAGE is not set # end of system packages # @@ -954,6 +957,8 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # # HC32 DDL Drivers # +# CONFIG_PKG_USING_HC32F4_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_HC32F4_SERIES_DRIVER is not set # end of HC32 DDL Drivers # @@ -967,6 +972,21 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # CONFIG_PKG_USING_NXP_IMX6UL_DRIVER is not set # CONFIG_PKG_USING_NXP_IMXRT_DRIVER is not set # end of NXP HAL & SDK Drivers + +# +# NUVOTON Drivers +# +# CONFIG_PKG_USING_NUVOTON_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_NUVOTON_SERIES_DRIVER is not set +# CONFIG_PKG_USING_NUVOTON_ARM926_LIB is not set +# end of NUVOTON Drivers + +# +# GD32 Drivers +# +# CONFIG_PKG_USING_GD32_ARM_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_GD32_ARM_SERIES_DRIVER is not set +# end of GD32 Drivers # end of HAL & SDK Drivers # diff --git a/bsp/qemu-vexpress-a9/rtconfig.h b/bsp/qemu-vexpress-a9/rtconfig.h index 13a5d47e737..8125bcebd16 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.h +++ b/bsp/qemu-vexpress-a9/rtconfig.h @@ -61,7 +61,7 @@ /* end of rt_strnlen options */ /* end of klibc options */ -#define RT_NAME_MAX 8 +#define RT_NAME_MAX 16 #define RT_CPUS_NR 1 #define RT_ALIGN_SIZE 8 #define RT_THREAD_PRIORITY_256 @@ -410,6 +410,14 @@ /* NXP HAL & SDK Drivers */ /* end of NXP HAL & SDK Drivers */ + +/* NUVOTON Drivers */ + +/* end of NUVOTON Drivers */ + +/* GD32 Drivers */ + +/* end of GD32 Drivers */ /* end of HAL & SDK Drivers */ /* sensors drivers */ diff --git a/examples/utest/testcases/kernel/object_tc.c b/examples/utest/testcases/kernel/object_tc.c index 239366f0e2c..2afeda34926 100644 --- a/examples/utest/testcases/kernel/object_tc.c +++ b/examples/utest/testcases/kernel/object_tc.c @@ -16,7 +16,7 @@ * @brief Comprehensive test suite for RT-Thread object system * * @note This test suite validates: - * 1. Object name handling (truncation, NULL, exact length, long names) + * 1. Object name handling (truncation, NULL, exact length) * 2. Static and dynamic object initialization * 3. Object finding functionality (rt_object_find, rt_thread_find, rt_device_find) * 4. Object information and enumeration @@ -24,255 +24,169 @@ * 6. Memory safety and boundary conditions */ +/* Define TEST_RT_NAME_MAX for testing purposes */ +#define TEST_RT_NAME_MAX RT_NAME_MAX + /* Global counter for unique object names */ static rt_uint32_t name_counter = 0; -/* Generate unique name to avoid conflicts, considering RT_NAME_MAX truncation */ -static void generate_unique_name(char *buf, rt_size_t size, const char *prefix) +/* Generate unique name to avoid conflicts, respecting TEST_RT_NAME_MAX */ +static rt_err_t generate_unique_name(char *buf, rt_size_t size, const char *prefix) { - rt_snprintf(buf, size, "%s%d", prefix, name_counter++); - rt_size_t len = rt_strlen(buf); - if (len > RT_NAME_MAX - 1) - { - len = RT_NAME_MAX - 1; - buf[len] = '\0'; - } - /* Check if name (or truncated name) exists */ - while (rt_object_find(buf, RT_Object_Class_Unknown) != RT_NULL || - rt_thread_find(buf) != RT_NULL || - rt_device_find(buf) != RT_NULL) + if (!buf || !prefix || size < TEST_RT_NAME_MAX) + return -RT_EINVAL; + + for (int i = 0; i < 1000; i++) /* Limit attempts to prevent infinite loop */ { - name_counter++; - rt_snprintf(buf, size, "%s%d", prefix, name_counter); - len = rt_strlen(buf); - if (len > RT_NAME_MAX - 1) + rt_snprintf(buf, size, "%s%d", prefix, name_counter++); + rt_size_t len = rt_strlen(buf); + if (len >= TEST_RT_NAME_MAX) { - len = RT_NAME_MAX - 1; - buf[len] = '\0'; + buf[TEST_RT_NAME_MAX - 1] = '\0'; + len = TEST_RT_NAME_MAX - 1; + } + + /* Check if name (or truncated name) is unique */ + if (rt_object_find(buf, RT_Object_Class_Unknown) == RT_NULL && + rt_thread_find(buf) == RT_NULL && + rt_device_find(buf) == RT_NULL) + { + return RT_EOK; } } - rt_kprintf("Generated unique name: %s\n", buf); + return -RT_ENOMEM; } static void test_object_name_handling(void) { struct rt_object static_obj1, static_obj2, static_obj3; rt_object_t dyn_obj = RT_NULL; - char test_name[RT_NAME_MAX + 5]; - char unique_name[RT_NAME_MAX]; + char test_name[TEST_RT_NAME_MAX]; + char unique_name[TEST_RT_NAME_MAX]; - /* Prepare a long test name */ - for (int i = 0; i < sizeof(test_name) - 1; i++) - { - test_name[i] = 'A' + (i % 26); - } - test_name[sizeof(test_name) - 1] = '\0'; + /* Prepare a test name within TEST_RT_NAME_MAX */ + rt_memset(test_name, 'A', TEST_RT_NAME_MAX - 1); + test_name[TEST_RT_NAME_MAX - 1] = '\0'; - /* Test 1: Static Object with Extra Long Name */ - generate_unique_name(unique_name, RT_NAME_MAX, "long"); + /* Test 1: Static Object with Name Within TEST_RT_NAME_MAX */ + uassert_true(generate_unique_name(unique_name, TEST_RT_NAME_MAX, "long") == RT_EOK); rt_object_init(&static_obj1, RT_Object_Class_Thread, test_name); - uassert_true(rt_strlen(static_obj1.name) <= RT_NAME_MAX - 1); - uassert_true(static_obj1.name[RT_NAME_MAX - 1] == '\0'); - uassert_true(rt_strncmp(static_obj1.name, test_name, RT_NAME_MAX - 1) == 0); + uassert_true(rt_strlen(static_obj1.name) <= TEST_RT_NAME_MAX - 1); + uassert_true(static_obj1.name[TEST_RT_NAME_MAX - 1] == '\0'); + uassert_true(rt_strncmp(static_obj1.name, test_name, TEST_RT_NAME_MAX - 1) == 0); uassert_true(rt_object_is_systemobject(&static_obj1)); + rt_object_detach(&static_obj1); - /* Test 2: Dynamic Object with Long Name */ - generate_unique_name(unique_name, RT_NAME_MAX, "dynlong"); + /* Test 2: Dynamic Object with Name Within TEST_RT_NAME_MAX */ + uassert_true(generate_unique_name(unique_name, TEST_RT_NAME_MAX, "dyn") == RT_EOK); dyn_obj = rt_object_allocate(RT_Object_Class_Thread, test_name); uassert_not_null(dyn_obj); - if (dyn_obj) - { - uassert_true(rt_strlen(dyn_obj->name) <= RT_NAME_MAX - 1); - uassert_true(dyn_obj->name[RT_NAME_MAX - 1] == '\0'); - uassert_true(rt_strncmp(dyn_obj->name, test_name, RT_NAME_MAX - 1) == 0); - uassert_false(rt_object_is_systemobject(dyn_obj)); - rt_object_delete(dyn_obj); - dyn_obj = RT_NULL; - } + uassert_true(rt_strlen(dyn_obj->name) <= TEST_RT_NAME_MAX - 1); + uassert_true(dyn_obj->name[TEST_RT_NAME_MAX - 1] == '\0'); + uassert_true(rt_strncmp(dyn_obj->name, test_name, TEST_RT_NAME_MAX - 1) == 0); + uassert_false(rt_object_is_systemobject(dyn_obj)); + rt_object_delete(dyn_obj); /* Test 3: NULL Name Handling */ - generate_unique_name(unique_name, RT_NAME_MAX, "null"); + uassert_true(generate_unique_name(unique_name, TEST_RT_NAME_MAX, "null") == RT_EOK); rt_object_init(&static_obj2, RT_Object_Class_Thread, NULL); uassert_true(static_obj2.name[0] == '\0'); + rt_object_detach(&static_obj2); - generate_unique_name(unique_name, RT_NAME_MAX, "dynull"); + uassert_true(generate_unique_name(unique_name, TEST_RT_NAME_MAX, "dynull") == RT_EOK); dyn_obj = rt_object_allocate(RT_Object_Class_Thread, NULL); uassert_not_null(dyn_obj); - if (dyn_obj) - { - uassert_true(dyn_obj->name[0] == '\0'); - rt_object_delete(dyn_obj); - dyn_obj = RT_NULL; - } + uassert_true(dyn_obj->name[0] == '\0'); + rt_object_delete(dyn_obj); /* Test 4: Exact Length Name */ - char exact_name[RT_NAME_MAX]; - rt_memset(exact_name, 'B', RT_NAME_MAX - 1); - exact_name[RT_NAME_MAX - 1] = '\0'; - generate_unique_name(unique_name, RT_NAME_MAX, "exact"); + char exact_name[TEST_RT_NAME_MAX]; + rt_memset(exact_name, 'B', TEST_RT_NAME_MAX - 1); + exact_name[TEST_RT_NAME_MAX - 1] = '\0'; + uassert_true(generate_unique_name(unique_name, TEST_RT_NAME_MAX, "exact") == RT_EOK); rt_object_init(&static_obj3, RT_Object_Class_Thread, exact_name); uassert_str_equal(static_obj3.name, exact_name); - - /* Cleanup */ - rt_object_detach(&static_obj1); - rt_object_detach(&static_obj2); rt_object_detach(&static_obj3); } static void test_object_find_operations(void) { rt_object_t found; - char name[RT_NAME_MAX]; - char long_name[16]; /* Longer than typical RT_NAME_MAX=8 */ - const char *nonexist_name = "nonexistent_obj"; + rt_thread_t found_thread; + rt_device_t found_device; + char name[TEST_RT_NAME_MAX]; + rt_err_t ret; - /* Test 1: Find static thread object with rt_object_find */ + /* Scenario 1: Object Name Within TEST_RT_NAME_MAX */ + /* Test 1.1: Find static thread object with rt_object_find */ struct rt_object static_obj; - generate_unique_name(name, RT_NAME_MAX, "sobj"); + uassert_true(generate_unique_name(name, TEST_RT_NAME_MAX, "sobj") == RT_EOK); rt_object_init(&static_obj, RT_Object_Class_Thread, name); found = rt_object_find(name, RT_Object_Class_Thread); - if (found == RT_NULL) - { - rt_kprintf("Failed to find static thread object: %s\n", name); - } uassert_not_null(found); uassert_ptr_equal(found, &static_obj); uassert_str_equal(found->name, name); rt_object_detach(&static_obj); - /* Test 2: Find dynamic thread object with rt_object_find */ - generate_unique_name(name, RT_NAME_MAX, "dobj"); - rt_object_t dyn_obj = rt_object_allocate(RT_Object_Class_Thread, name); - uassert_not_null(dyn_obj); - if (dyn_obj) - { - found = rt_object_find(name, RT_Object_Class_Thread); - if (found == RT_NULL) - { - rt_kprintf("Failed to find dynamic thread object: %s\n", name); - } - uassert_not_null(found); - uassert_ptr_equal(found, dyn_obj); - uassert_str_equal(found->name, name); - rt_object_delete(dyn_obj); - } - - /* Test 3: Find thread object with rt_thread_find */ - generate_unique_name(name, RT_NAME_MAX, "thr"); + /* Test 1.2: Find thread object with rt_thread_find */ + uassert_true(generate_unique_name(name, TEST_RT_NAME_MAX, "thr") == RT_EOK); rt_thread_t thread = rt_thread_create(name, RT_NULL, RT_NULL, 1024, 20, 10); uassert_not_null(thread); - if (thread) - { - rt_thread_t found_thread = rt_thread_find(name); - if (found_thread == RT_NULL) - { - rt_kprintf("Failed to find thread with rt_thread_find: %s\n", name); - } - uassert_not_null(found_thread); - uassert_ptr_equal(found_thread, thread); - uassert_str_equal(found_thread->parent.name, name); - rt_thread_delete(thread); - } + found_thread = rt_thread_find(name); + uassert_not_null(found_thread); + uassert_ptr_equal(found_thread, thread); + uassert_str_equal(found_thread->parent.name, name); + rt_thread_delete(thread); #ifdef RT_USING_DEVICE - /* Test 4: Find device object with rt_device_find */ + /* Test 1.3: Find device object with rt_device_find */ struct rt_device device; - generate_unique_name(name, RT_NAME_MAX, "dev"); - rt_err_t ret = rt_device_register(&device, name, RT_DEVICE_FLAG_RDONLY); + uassert_true(generate_unique_name(name, TEST_RT_NAME_MAX, "dev") == RT_EOK); + ret = rt_device_register(&device, name, RT_DEVICE_FLAG_RDONLY); uassert_int_equal(ret, RT_EOK); - rt_device_t found_device = rt_device_find(name); - if (found_device == RT_NULL) - { - rt_kprintf("Failed to find device with rt_device_find: %s\n", name); - } + found_device = rt_device_find(name); uassert_not_null(found_device); uassert_ptr_equal(found_device, &device); uassert_str_equal(found_device->parent.name, name); rt_device_unregister(&device); #endif - /* Test 5: Find thread with long name (exceeding RT_NAME_MAX) */ - rt_snprintf(long_name, sizeof(long_name), "longthreadname%d", name_counter++); - rt_thread_t long_thread = rt_thread_create(long_name, RT_NULL, RT_NULL, 1024, 20, 10); - uassert_not_null(long_thread); - if (long_thread) - { - char truncated_name[RT_NAME_MAX]; - rt_strncpy(truncated_name, long_name, RT_NAME_MAX - 1); - truncated_name[RT_NAME_MAX - 1] = '\0'; - rt_kprintf("Testing long thread name: %s, truncated to: %s\n", long_name, truncated_name); - rt_thread_t found_thread = rt_thread_find(truncated_name); - if (found_thread == RT_NULL) - { - rt_kprintf("Failed to find thread with rt_thread_find: %s\n", truncated_name); - } - uassert_not_null(found_thread); - uassert_ptr_equal(found_thread, long_thread); - uassert_str_equal(found_thread->parent.name, truncated_name); - rt_thread_delete(long_thread); - } - - /* Test 6: Find thread with long name directly (no manual truncation) */ - rt_snprintf(long_name, sizeof(long_name), "longthreadname%d", name_counter++); - rt_thread_t long_thread_direct = rt_thread_create(long_name, RT_NULL, RT_NULL, 1024, 20, 10); - uassert_not_null(long_thread_direct); - if (long_thread_direct) - { - rt_kprintf("Testing direct long name: %s\n", long_name); - rt_thread_t found_thread = rt_thread_find(long_name); - if (found_thread == RT_NULL) - { - rt_kprintf("Failed to find thread with rt_thread_find: %s\n", long_name); - } - uassert_not_null(found_thread); - uassert_ptr_equal(found_thread, long_thread_direct); - char truncated_name[RT_NAME_MAX]; - rt_strncpy(truncated_name, long_name, RT_NAME_MAX - 1); - truncated_name[RT_NAME_MAX - 1] = '\0'; - uassert_str_equal(found_thread->parent.name, truncated_name); - rt_thread_delete(long_thread_direct); - } - + /* Test 2: Same Prefix Within TEST_RT_NAME_MAX */ #ifdef RT_USING_DEVICE - /* Test 7: Find device with long name (exceeding RT_NAME_MAX) */ - rt_snprintf(long_name, sizeof(long_name), "longdevicename%d", name_counter++); - struct rt_device long_device; - ret = rt_device_register(&long_device, long_name, RT_DEVICE_FLAG_RDONLY); + struct rt_device dev1, dev2; + char name1[TEST_RT_NAME_MAX] = "norflash1"; + char name2[TEST_RT_NAME_MAX] = "norflash2"; + ret = rt_device_register(&dev1, name1, RT_DEVICE_FLAG_RDONLY); uassert_int_equal(ret, RT_EOK); - if (ret == RT_EOK) - { - char truncated_name[RT_NAME_MAX]; - rt_strncpy(truncated_name, long_name, RT_NAME_MAX - 1); - truncated_name[RT_NAME_MAX - 1] = '\0'; - rt_kprintf("Testing long device name: %s, truncated to: %s\n", long_name, truncated_name); - rt_device_t found_device = rt_device_find(truncated_name); - if (found_device == RT_NULL) - { - rt_kprintf("Failed to find device with rt_device_find: %s\n", truncated_name); - } - uassert_not_null(found_device); - uassert_ptr_equal(found_device, &long_device); - uassert_str_equal(found_device->parent.name, truncated_name); - rt_device_unregister(&long_device); - } + ret = rt_device_register(&dev2, name2, RT_DEVICE_FLAG_RDONLY); + uassert_int_equal(ret, RT_EOK); /* Expect success if RT-Thread allows distinct names */ + found_device = rt_device_find(name1); + uassert_not_null(found_device); + uassert_ptr_equal(found_device, &dev1); + uassert_str_equal(found_device->parent.name, name1); + found_device = rt_device_find(name2); + uassert_not_null(found_device); + uassert_ptr_equal(found_device, &dev2); + uassert_str_equal(found_device->parent.name, name2); + rt_device_unregister(&dev1); + rt_device_unregister(&dev2); #endif - /* Test 8: Find non-existent object with rt_object_find */ + /* Test 3: Find non-existent object */ + const char *nonexist_name = "nonexist"; + uassert_true(rt_strlen(nonexist_name) <= TEST_RT_NAME_MAX - 1); found = rt_object_find(nonexist_name, RT_Object_Class_Thread); uassert_null(found); - /* Test 9: Find with NULL name with rt_object_find */ + /* Test 4: Find with NULL name */ found = rt_object_find(NULL, RT_Object_Class_Thread); uassert_null(found); - - /* Test 10: Find with NULL name with rt_thread_find */ - rt_thread_t found_thread = rt_thread_find(NULL); + found_thread = rt_thread_find(NULL); uassert_null(found_thread); #ifdef RT_USING_DEVICE - /* Test 11: Find with NULL name with rt_device_find */ - rt_device_t found_device_null = rt_device_find(NULL); - uassert_null(found_device_null); + found_device = rt_device_find(NULL); + uassert_null(found_device); #endif } @@ -280,12 +194,12 @@ static void test_object_info_enumeration(void) { struct rt_object static_objs[3]; rt_object_t dyn_objs[2] = {RT_NULL, RT_NULL}; - char names[5][RT_NAME_MAX]; + char names[5][TEST_RT_NAME_MAX]; /* Generate unique names */ for (int i = 0; i < 5; i++) { - generate_unique_name(names[i], RT_NAME_MAX, "enum"); + uassert_true(generate_unique_name(names[i], TEST_RT_NAME_MAX, "enum") == RT_EOK); } /* Create test objects */ @@ -293,7 +207,6 @@ static void test_object_info_enumeration(void) { rt_object_init(&static_objs[i], RT_Object_Class_Thread, names[i]); } - for (int i = 0; i < 2; i++) { dyn_objs[i] = rt_object_allocate(RT_Object_Class_Thread, names[i + 3]); @@ -307,67 +220,47 @@ static void test_object_info_enumeration(void) /* Test 2: Get object count */ int count = rt_object_get_length(RT_Object_Class_Thread); - uassert_true(count >= 5); /* At least our 5 objects */ + uassert_true(count >= 5); /* Test 3: Get object pointers with sufficient buffer */ rt_object_t *objects = (rt_object_t *)rt_malloc((count + 2) * sizeof(rt_object_t)); uassert_not_null(objects); - if (objects) + int ret = rt_object_get_pointers(RT_Object_Class_Thread, objects, count + 2); + uassert_int_equal(ret, count); + int found_count = 0; + for (int i = 0; i < ret; i++) { - int ret = rt_object_get_pointers(RT_Object_Class_Thread, objects, count + 2); - uassert_int_equal(ret, count); - - /* Verify our objects are in the list */ - int found_count = 0; - for (int i = 0; i < ret; i++) - { - for (int j = 0; j < 3; j++) - { - if (objects[i] == &static_objs[j]) found_count++; - } - - for (int j = 0; j < 2; j++) - { - if (objects[i] == dyn_objs[j]) found_count++; - } - } - uassert_int_equal(found_count, 5); - - rt_free(objects); + for (int j = 0; j < 3; j++) + if (objects[i] == &static_objs[j]) found_count++; + for (int j = 0; j < 2; j++) + if (objects[i] == dyn_objs[j]) found_count++; } + uassert_int_equal(found_count, 5); + rt_free(objects); /* Test 4: Get object pointers with small buffer */ rt_object_t one_object[1]; - int ret = rt_object_get_pointers(RT_Object_Class_Thread, one_object, 1); + ret = rt_object_get_pointers(RT_Object_Class_Thread, one_object, 1); uassert_true(ret <= 1); - /* Test 5: Empty container (use Semaphore as it may be empty) */ + /* Test 5: Empty container (Semaphore) */ #ifdef RT_USING_SEMAPHORE int empty_count = rt_object_get_length(RT_Object_Class_Semaphore); - uassert_true(empty_count >= 0); /* Cannot assume empty, but verify non-negative */ + uassert_true(empty_count >= 0); #endif /* Cleanup */ for (int i = 0; i < 3; i++) - { rt_object_detach(&static_objs[i]); - } - for (int i = 0; i < 2; i++) - { - if (dyn_objs[i]) - { - rt_object_delete(dyn_objs[i]); - } - } + if (dyn_objs[i]) rt_object_delete(dyn_objs[i]); } static void test_object_type_handling(void) { struct rt_object obj; - char name[RT_NAME_MAX]; - generate_unique_name(name, RT_NAME_MAX, "typ"); /* Use short prefix */ - rt_kprintf("Object name for test: %s\n", name); + char name[TEST_RT_NAME_MAX]; + uassert_true(generate_unique_name(name, TEST_RT_NAME_MAX, "typ") == RT_EOK); rt_object_init(&obj, RT_Object_Class_Thread, name); /* Test 1: Get object type */ @@ -377,19 +270,17 @@ static void test_object_type_handling(void) uassert_true(rt_object_is_systemobject(&obj)); /* Test 3: Get name with sufficient buffer */ - char name_buf[RT_NAME_MAX]; + char name_buf[TEST_RT_NAME_MAX]; rt_err_t ret = rt_object_get_name(&obj, name_buf, sizeof(name_buf)); uassert_int_equal(ret, RT_EOK); uassert_str_equal(name_buf, name); /* Test 4: Get name with small buffer */ - char small_buf[4] = {0}; /* Initialize to avoid undefined behavior */ + char small_buf[4] = {0}; ret = rt_object_get_name(&obj, small_buf, sizeof(small_buf)); uassert_int_equal(ret, RT_EOK); - rt_kprintf("small_buf after rt_object_get_name: %s (bytes: %02x %02x %02x %02x)\n", - small_buf, small_buf[0], small_buf[1], small_buf[2], small_buf[3]); uassert_true(rt_strncmp(small_buf, name, sizeof(small_buf) - 1) == 0); - uassert_true(small_buf[sizeof(small_buf) - 1] == '\0'); /* Expect null-termination (assuming kernel fix) */ + uassert_true(small_buf[sizeof(small_buf) - 1] == '\0'); /* Test 5: Get name with invalid parameters */ ret = rt_object_get_name(RT_NULL, name_buf, sizeof(name_buf)); @@ -404,29 +295,28 @@ static void test_object_type_handling(void) static rt_err_t testcase_init(void) { - /* Ensure scheduler is available */ if (!rt_scheduler_is_available()) { - rt_kprintf("Scheduler is not available, test may fail\n"); return -RT_ERROR; } - /* Reset name counter for each test suite run */ name_counter = 0; - rt_kprintf("RT_NAME_MAX = %d\n", RT_NAME_MAX); return RT_EOK; } static rt_err_t testcase_cleanup(void) { - /* No dynamic cleanup needed, as each test case handles its own cleanup */ return RT_EOK; } static void test_object_suite(void) { +#ifdef RT_NAME_MAX < 10 + rt_kprintf("Error: Please increase \'RT_NAME_MAX\' to be greater than 10.\n"); + return; +#endif UTEST_UNIT_RUN(test_object_name_handling); UTEST_UNIT_RUN(test_object_find_operations); UTEST_UNIT_RUN(test_object_info_enumeration); UTEST_UNIT_RUN(test_object_type_handling); } -UTEST_TC_EXPORT(test_object_suite, "testcases.kernel.object_test", testcase_init, testcase_cleanup, 20); +UTEST_TC_EXPORT(test_object_suite, "testcases.kernel.object_test", testcase_init, testcase_cleanup, 20); \ No newline at end of file diff --git a/src/object.c b/src/object.c index c21fcb6c0ac..f924f37bc9c 100644 --- a/src/object.c +++ b/src/object.c @@ -29,6 +29,10 @@ #include #endif +#define DBG_TAG "kernel.obj" +#define DBG_LVL DBG_ERROR +#include + struct rt_custom_object { struct rt_object parent; @@ -355,7 +359,7 @@ void rt_object_init(struct rt_object *object, const char *name) { rt_base_t level; - rt_size_t len; + rt_size_t obj_name_len; #ifdef RT_DEBUGING_ASSERT struct rt_list_node *node = RT_NULL; #endif /* RT_DEBUGING_ASSERT */ @@ -393,10 +397,14 @@ void rt_object_init(struct rt_object *object, #if RT_NAME_MAX > 0 if (name) { - len = rt_strlen(name); - len = len > RT_NAME_MAX - 1 ? RT_NAME_MAX - 1 : len; - rt_memcpy(object->name, name, len); - object->name[len] = '\0'; + obj_name_len = rt_strlen(name); + if(obj_name_len > RT_NAME_MAX - 1) + { + LOG_E("Object name %s exceeds RT_NAME_MAX=%d, consider increasing RT_NAME_MAX.", name, RT_NAME_MAX); + RT_ASSERT(obj_name_len <= RT_NAME_MAX - 1); + } + rt_memcpy(object->name, name, obj_name_len); + object->name[obj_name_len] = '\0'; } else { @@ -472,7 +480,7 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name) { struct rt_object *object; rt_base_t level; - rt_size_t len; + rt_size_t obj_name_len; struct rt_object_information *information; #ifdef RT_USING_MODULE struct rt_dlmodule *module = dlmodule_self(); @@ -505,10 +513,14 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name) #if RT_NAME_MAX > 0 if (name) { - len = rt_strlen(name); - len = len > RT_NAME_MAX - 1 ? RT_NAME_MAX - 1 : len; - rt_memcpy(object->name, name, len); - object->name[len] = '\0'; + obj_name_len = rt_strlen(name); + if(obj_name_len > RT_NAME_MAX - 1) + { + LOG_E("Object name %s exceeds RT_NAME_MAX=%d, consider increasing RT_NAME_MAX.", name, RT_NAME_MAX); + RT_ASSERT(obj_name_len <= RT_NAME_MAX - 1); + } + rt_memcpy(object->name, name, obj_name_len); + object->name[obj_name_len] = '\0'; } else {