diff options
| author | WBI\nxf44444 <[email protected]> | 2022-01-26 01:43:05 +0800 |
|---|---|---|
| committer | WBI\nxf44444 <[email protected]> | 2022-01-26 01:43:05 +0800 |
| commit | 8b0f50b7e211ee32ab08ba085ecd74588c3a3c63 (patch) | |
| tree | 75440be5ecd30cc1403a9387851c0530ed057981 /examples | |
| parent | 3be35fecae513b07c35bd6f3992bf7824434bdd6 (diff) | |
| parent | 32a5668593c578b85560338c29d76f3a252c8dbc (diff) | |
Update i2c driver, add read ACK and BUS status check
Diffstat (limited to 'examples')
116 files changed, 8221 insertions, 5115 deletions
diff --git a/examples/file/listdir.c b/examples/file/listdir.c index d8ea7af82a..d858a00bff 100644 --- a/examples/file/listdir.c +++ b/examples/file/listdir.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -9,11 +9,15 @@ * 2020-04-12 Jianjia Ma add msh cmd */ #include <rtthread.h> -#include <dfs_posix.h> +#include <dfs_file.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/statfs.h> void list_dir(const char* path) { - char * fullpath; + char * fullpath = RT_NULL; DIR *dir; dir = opendir(path); @@ -57,14 +61,16 @@ void list_dir(const char* path) rt_kprintf("open %s directory failed\n", path); } - rt_free(fullpath); + if (RT_NULL != fullpath) + { + rt_free(fullpath); + } } #ifdef RT_USING_FINSH #include <finsh.h> FINSH_FUNCTION_EXPORT(list_dir, list directory); -#ifdef FINSH_USING_MSH static void cmd_list_dir(int argc, char *argv[]) { char* filename; @@ -80,6 +86,5 @@ static void cmd_list_dir(int argc, char *argv[]) } list_dir(filename); } -FINSH_FUNCTION_EXPORT_ALIAS(cmd_list_dir, __cmd_list_dir, list directory); -#endif /* FINSH_USING_MSH */ +MSH_CMD_EXPORT_ALIAS(cmd_list_dir, list_dir, list directory); #endif /* RT_USING_FINSH */ diff --git a/examples/file/readspeed.c b/examples/file/readspeed.c index e5073856b4..dfa68ceb32 100644 --- a/examples/file/readspeed.c +++ b/examples/file/readspeed.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -10,7 +10,11 @@ */ #include <rtthread.h> -#include <dfs_posix.h> +#include <dfs_file.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/statfs.h> void readspeed(const char* filename, int block_size) { @@ -46,9 +50,9 @@ void readspeed(const char* filename, int block_size) } tick = rt_tick_get() - tick; - /* close file and release memory */ + /* close file and release memory */ close(fd); - rt_free(buff_ptr); + rt_free(buff_ptr); /* calculate read speed */ rt_kprintf("File read speed: %d byte/s\n", total_length /tick * RT_TICK_PER_SECOND); @@ -58,7 +62,6 @@ void readspeed(const char* filename, int block_size) #include <finsh.h> FINSH_FUNCTION_EXPORT(readspeed, perform file read test); -#ifdef FINSH_USING_MSH static void cmd_readspeed(int argc, char *argv[]) { char* filename; @@ -82,6 +85,5 @@ static void cmd_readspeed(int argc, char *argv[]) } readspeed(filename, block_size); } -FINSH_FUNCTION_EXPORT_ALIAS(cmd_readspeed, __cmd_readspeed, test file system read speed); -#endif /* FINSH_USING_MSH */ +MSH_CMD_EXPORT_ALIAS(cmd_readspeed, readspeed, test file system read speed); #endif /* RT_USING_FINSH */ diff --git a/examples/file/readwrite.c b/examples/file/readwrite.c index 5738323805..5d0defeaa9 100644 --- a/examples/file/readwrite.c +++ b/examples/file/readwrite.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -10,28 +10,32 @@ */ #include <rtthread.h> -#include <dfs_posix.h> +#include <dfs_file.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/statfs.h> #define TEST_DATA_LEN 120 /* file read write test */ void readwrite(const char* filename) { - int fd; - int index, length; - char* test_data; - char* buffer; - int block_size = TEST_DATA_LEN; + int fd; + int index, length; + char* test_data; + char* buffer; + int block_size = TEST_DATA_LEN; - /* open with write only & create */ - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0); - if (fd < 0) - { - rt_kprintf("open file for write failed\n"); - return; - } + /* open with write only & create */ + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0); + if (fd < 0) + { + rt_kprintf("open file for write failed\n"); + return; + } - test_data = rt_malloc(block_size); + test_data = rt_malloc(block_size); if (test_data == RT_NULL) { rt_kprintf("no memory\n"); @@ -48,94 +52,94 @@ void readwrite(const char* filename) return; } - /* prepare some data */ - for (index = 0; index < block_size; index ++) - { - test_data[index] = index + 27; - } + /* prepare some data */ + for (index = 0; index < block_size; index ++) + { + test_data[index] = index + 27; + } - /* write to file */ - length = write(fd, test_data, block_size); - if (length != block_size) - { - rt_kprintf("write data failed\n"); - close(fd); - goto __exit; - } + /* write to file */ + length = write(fd, test_data, block_size); + if (length != block_size) + { + rt_kprintf("write data failed\n"); + close(fd); + goto __exit; + } - /* close file */ - close(fd); + /* close file */ + close(fd); - /* reopen the file with append to the end */ - fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0); - if (fd < 0) - { - rt_kprintf("open file for append write failed\n"); - goto __exit;; - } + /* reopen the file with append to the end */ + fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0); + if (fd < 0) + { + rt_kprintf("open file for append write failed\n"); + goto __exit;; + } - length = write(fd, test_data, block_size); - if (length != block_size) - { - rt_kprintf("append write data failed\n"); - close(fd); - goto __exit; - } - /* close the file */ - close(fd); + length = write(fd, test_data, block_size); + if (length != block_size) + { + rt_kprintf("append write data failed\n"); + close(fd); + goto __exit; + } + /* close the file */ + close(fd); - /* open the file for data validation. */ - fd = open(filename, O_RDONLY, 0); - if (fd < 0) - { - rt_kprintf("check: open file for read failed\n"); - goto __exit; - } + /* open the file for data validation. */ + fd = open(filename, O_RDONLY, 0); + if (fd < 0) + { + rt_kprintf("check: open file for read failed\n"); + goto __exit; + } - /* read the data (should be the data written by the first time ) */ - length = read(fd, buffer, block_size); - if (length != block_size) - { - rt_kprintf("check: read file failed\n"); - close(fd); - goto __exit; - } + /* read the data (should be the data written by the first time ) */ + length = read(fd, buffer, block_size); + if (length != block_size) + { + rt_kprintf("check: read file failed\n"); + close(fd); + goto __exit; + } - /* validate */ - for (index = 0; index < block_size; index ++) - { - if (test_data[index] != buffer[index]) - { - rt_kprintf("check: check data failed at %d\n", index); - close(fd); - goto __exit; - } - } + /* validate */ + for (index = 0; index < block_size; index ++) + { + if (test_data[index] != buffer[index]) + { + rt_kprintf("check: check data failed at %d\n", index); + close(fd); + goto __exit; + } + } - /* read the data (should be the second time data) */ - length = read(fd, buffer, block_size); - if (length != block_size) - { - rt_kprintf("check: read file failed\n"); - close(fd); - goto __exit; - } + /* read the data (should be the second time data) */ + length = read(fd, buffer, block_size); + if (length != block_size) + { + rt_kprintf("check: read file failed\n"); + close(fd); + goto __exit; + } - /* validate */ - for (index = 0; index < block_size; index ++) - { - if (test_data[index] != buffer[index]) - { - rt_kprintf("check: check data failed at %d\n", index); - close(fd); - goto __exit; - } - } + /* validate */ + for (index = 0; index < block_size; index ++) + { + if (test_data[index] != buffer[index]) + { + rt_kprintf("check: check data failed at %d\n", index); + close(fd); + goto __exit; + } + } - /* close the file */ - close(fd); - /* print result */ - rt_kprintf("read/write test successful!\n"); + /* close the file */ + close(fd); + /* print result */ + rt_kprintf("read/write test successful!\n"); __exit: rt_free(test_data); @@ -147,7 +151,6 @@ __exit: /* export to finsh */ FINSH_FUNCTION_EXPORT(readwrite, perform file read and write test); -#ifdef FINSH_USING_MSH static void cmd_readwrite(int argc, char *argv[]) { char* filename; @@ -163,6 +166,5 @@ static void cmd_readwrite(int argc, char *argv[]) } readwrite(filename); } -FINSH_FUNCTION_EXPORT_ALIAS(cmd_readwrite, __cmd_readwrite, perform file read and write test); -#endif /* FINSH_USING_MSH */ +MSH_CMD_EXPORT_ALIAS(cmd_readwrite, readwrite, perform file read and write test); #endif /* RT_USING_FINSH */ diff --git a/examples/file/seekdir.c b/examples/file/seekdir.c index d6a33426b4..5198a8056b 100644 --- a/examples/file/seekdir.c +++ b/examples/file/seekdir.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -8,39 +8,43 @@ * 2011-06-02 Bernard first version * 2020-04-12 Jianjia Ma add msh cmd */ -#include <dfs_posix.h> +#include <dfs_file.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/statfs.h> void seekdir_test(void) { - DIR * dirp; - long save3 = 0; - int i = 0; - struct dirent *dp; + DIR * dirp; + long save3 = 0; + int i = 0; + struct dirent *dp; - dirp = opendir ("/"); - save3 = telldir(dirp); - for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp)) - { - rt_kprintf("direntry: %s\n", dp->d_name); + dirp = opendir ("/"); + save3 = telldir(dirp); + for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp)) + { + rt_kprintf("direntry: %s\n", dp->d_name); - /* save the pointer of the third directory */ - if (i++ == 3) - { - save3 = telldir(dirp); - } - } + /* save the pointer of the third directory */ + if (i++ == 3) + { + save3 = telldir(dirp); + } + } - /* get back to the third directory */ - seekdir (dirp, save3); - rt_kprintf("seek dientry to: %d\n", save3); - for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp)) - { - rt_kprintf("direntry: %s\n", dp->d_name); - } + /* get back to the third directory */ + seekdir (dirp, save3); + rt_kprintf("seek dientry to: %d\n", save3); + for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp)) + { + rt_kprintf("direntry: %s\n", dp->d_name); + } - /* close the directory */ - closedir (dirp); -} + /* close the directory */ + closedir (dirp); +} #ifdef RT_USING_FINSH #include <finsh.h> diff --git a/examples/file/writespeed.c b/examples/file/writespeed.c index 60dd900a68..87a4c329bd 100644 --- a/examples/file/writespeed.c +++ b/examples/file/writespeed.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -9,7 +9,11 @@ * 2020-04-12 Jianjia Ma add msh cmd */ #include <rtthread.h> -#include <dfs_posix.h> +#include <dfs_file.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/statfs.h> void writespeed(const char* filename, int total_length, int block_size) { @@ -66,7 +70,6 @@ void writespeed(const char* filename, int total_length, int block_size) #include <finsh.h> FINSH_FUNCTION_EXPORT(writespeed, perform file write test); -#ifdef FINSH_USING_MSH static void cmd_writespeed(int argc, char *argv[]) { char* filename; @@ -93,6 +96,5 @@ static void cmd_writespeed(int argc, char *argv[]) } writespeed(filename, length, block_size); } -FINSH_FUNCTION_EXPORT_ALIAS(cmd_writespeed, __cmd_writespeed, test file system write speed); -#endif /* FINSH_USING_MSH */ +MSH_CMD_EXPORT_ALIAS(cmd_writespeed, writespeed, test file system write speed); #endif /* RT_USING_FINSH */ diff --git a/examples/kernel/SConscript b/examples/kernel/SConscript deleted file mode 100644 index e627d852be..0000000000 --- a/examples/kernel/SConscript +++ /dev/null @@ -1,41 +0,0 @@ -from building import * - -src = Split(""" -tc_comm.c -thread_static.c -thread_dynamic.c -thread_priority.c -thread_same_priority.c -thread_static_simple.c -thread_dynamic_simple.c -thread_delete.c -thread_detach.c -thread_yield.c -thread_suspend.c -thread_resume.c -semaphore_static.c -semaphore_dynamic.c -semaphore_priority.c -semaphore_buffer_worker.c -semaphore_producer_consumer.c -mutex_simple.c -event_simple.c -mbox_simple.c -mbox_send_wait.c -messageq_simple.c -timer_static.c -timer_dynamic.c -timer_stop_self.c -timer_control.c -timer_timeout.c -heap_malloc.c -heap_realloc.c -memp_simple.c -tc_sample.c -""") - -group = DefineGroup('Examples', src, - depend = ['RT_USING_TC'], - CPPPATH=[GetCurrentDir()]) - -Return('group') diff --git a/examples/kernel/cpuusage.c b/examples/kernel/cpuusage.c deleted file mode 100644 index 490061ddb7..0000000000 --- a/examples/kernel/cpuusage.c +++ /dev/null @@ -1,70 +0,0 @@ -#include <rtthread.h> -#include <rthw.h> - -#define CPU_USAGE_CALC_TICK 10 -#define CPU_USAGE_LOOP 100 - -static rt_uint8_t cpu_usage_major = 0, cpu_usage_minor= 0; -static rt_uint32_t total_count = 0; - -static void cpu_usage_idle_hook() -{ - rt_tick_t tick; - rt_uint32_t count; - volatile rt_uint32_t loop; - - if (total_count == 0) - { - /* get total count */ - rt_enter_critical(); - tick = rt_tick_get(); - while(rt_tick_get() - tick < CPU_USAGE_CALC_TICK) - { - total_count ++; - loop = 0; - while (loop < CPU_USAGE_LOOP) loop ++; - } - rt_exit_critical(); - } - - count = 0; - /* get CPU usage */ - tick = rt_tick_get(); - while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK) - { - count ++; - loop = 0; - while (loop < CPU_USAGE_LOOP) loop ++; - } - - /* calculate major and minor */ - if (count < total_count) - { - count = total_count - count; - cpu_usage_major = (count * 100) / total_count; - cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count; - } - else - { - total_count = count; - - /* no CPU usage */ - cpu_usage_major = 0; - cpu_usage_minor = 0; - } -} - -void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor) -{ - RT_ASSERT(major != RT_NULL); - RT_ASSERT(minor != RT_NULL); - - *major = cpu_usage_major; - *minor = cpu_usage_minor; -} - -void cpu_usage_init() -{ - /* set idle thread hook */ - rt_thread_idle_sethook(cpu_usage_idle_hook); -} diff --git a/examples/kernel/event_simple.c b/examples/kernel/event_simple.c deleted file mode 100644 index e377e721bb..0000000000 --- a/examples/kernel/event_simple.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 程序清单:事件例程 - * - * 这个程序会创建3个动态线程及初始化一个静态事件对象 - * 一个线程等于事件对象上以接收事件; - * 一个线程定时发送事件 (事件3) - * 一个线程定时发送事件 (事件5) - */ -#include <rtthread.h> -#include <time.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -static rt_thread_t tid3 = RT_NULL; - -/* 事件控制块 */ -static struct rt_event event; - -/* 线程1入口函数 */ -static void thread1_entry(void *param) -{ - rt_uint32_t e; - - while (1) - { - /* receive first event */ - if (rt_event_recv(&event, ((1 << 3) | (1 << 5)), - RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, - RT_WAITING_FOREVER, &e) == RT_EOK) - { - rt_kprintf("thread1: AND recv event 0x%x\n", e); - } - - rt_kprintf("thread1: delay 1s to prepare second event\n"); - rt_thread_delay(10); - - /* receive second event */ - if (rt_event_recv(&event, ((1 << 3) | (1 << 5)), - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - RT_WAITING_FOREVER, &e) == RT_EOK) - { - rt_kprintf("thread1: OR recv event 0x%x\n", e); - } - - rt_thread_delay(5); - } -} - -/* 线程2入口函数 */ -static void thread2_entry(void *param) -{ - while (1) - { - rt_kprintf("thread2: send event1\n"); - rt_event_send(&event, (1 << 3)); - - rt_thread_delay(10); - } -} - -/* 线程3入口函数 */ -static void thread3_entry(void *param) -{ - while (1) - { - rt_kprintf("thread3: send event2\n"); - rt_event_send(&event, (1 << 5)); - - rt_thread_delay(20); - } -} - -int event_simple_init() -{ - /* 初始化事件对象 */ - rt_event_init(&event, "event", RT_IPC_FLAG_FIFO); - - /* 创建线程1 */ - tid1 = rt_thread_create("t1", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("t2", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程3 */ - tid3 = rt_thread_create("t3", - thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid3 != RT_NULL) - rt_thread_startup(tid3); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid3); - - /* 执行事件对象脱离 */ - rt_event_detach(&event); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_event_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - event_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_event_simple, a simple event example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - event_simple_init(); - - return 0; -} -#endif diff --git a/examples/kernel/heap_malloc.c b/examples/kernel/heap_malloc.c deleted file mode 100644 index 271202ad8f..0000000000 --- a/examples/kernel/heap_malloc.c +++ /dev/null @@ -1,74 +0,0 @@ -#include <rtthread.h> -#include "tc_comm.h" - -/* - * This is an example for heap malloc - */ - -static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) -{ - while (len) - { - if (*ptr != value) - return RT_FALSE; - ptr ++; - len --; - } - - return RT_TRUE; -} - -static void heap_malloc_init() -{ - rt_uint8_t res = TC_STAT_PASSED; - rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; - - ptr1 = rt_malloc(1); - ptr2 = rt_malloc(13); - ptr3 = rt_malloc(31); - ptr4 = rt_malloc(127); - ptr5 = rt_malloc(0); - - memset(ptr1, 1, 1); - memset(ptr2, 2, 13); - memset(ptr3, 3, 31); - memset(ptr4, 4, 127); - - if (mem_check(ptr1, 1, 1) == RT_FALSE) - res = TC_STAT_FAILED; - if (mem_check(ptr2, 2, 13) == RT_FALSE) - res = TC_STAT_FAILED; - if (mem_check(ptr3, 3, 31) == RT_FALSE) - res = TC_STAT_FAILED; - if (mem_check(ptr4, 4, 127) == RT_FALSE) - res = TC_STAT_FAILED; - - rt_free(ptr4); - rt_free(ptr3); - rt_free(ptr2); - rt_free(ptr1); - - if (ptr5 != RT_NULL) - { - rt_free(ptr5); - } - - tc_done(res); -} - -#ifdef RT_USING_TC -int _tc_heap_malloc() -{ - heap_malloc_init(); - - return 0; -} -FINSH_FUNCTION_EXPORT(_tc_heap_malloc, a heap malloc test); -#else -int rt_application_init() -{ - heap_malloc_init(); - - return 0; -} -#endif diff --git a/examples/kernel/heap_realloc.c b/examples/kernel/heap_realloc.c deleted file mode 100644 index bc7b56a999..0000000000 --- a/examples/kernel/heap_realloc.c +++ /dev/null @@ -1,102 +0,0 @@ -#include <rtthread.h> -#include "tc_comm.h" - -/* - * This is an example for heap malloc - */ - -static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) -{ - while (len) - { - if (*ptr != value) return RT_FALSE; - - ptr ++; - len --; - } - - return RT_TRUE; -} - -static void heap_realloc_init() -{ - rt_uint8_t res = TC_STAT_PASSED; - rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; - - ptr1 = rt_malloc(1); - ptr2 = rt_malloc(13); - ptr3 = rt_malloc(31); - ptr4 = rt_malloc(127); - ptr5 = rt_malloc(0); - - memset(ptr1, 1, 1); - memset(ptr2, 2, 13); - memset(ptr3, 3, 31); - memset(ptr4, 4, 127); - - if (mem_check(ptr1, 1, 1) == RT_FALSE) - { - res = TC_STAT_FAILED; - goto _free; - } - if (mem_check(ptr2, 2, 13) == RT_FALSE) - { - res = TC_STAT_FAILED; - goto _free; - } - if (mem_check(ptr3, 3, 31) == RT_FALSE) - { - res = TC_STAT_FAILED; - goto _free; - } - if (mem_check(ptr4, 4, 127) == RT_FALSE) - { - res = TC_STAT_FAILED; - goto _free; - } - - ptr1 = rt_realloc(ptr1, 13); - ptr2 = rt_realloc(ptr2, 31); - ptr3 = rt_realloc(ptr3, 127); - ptr4 = rt_realloc(ptr4, 1); - ptr5 = rt_realloc(ptr5, 0); - if (ptr5) - { - rt_kprintf("realloc(ptr, 0) should return NULL\n"); - res = TC_STAT_FAILED; - } - - if (mem_check(ptr1, 1, 1) == RT_FALSE) - res = TC_STAT_FAILED; - if (mem_check(ptr2, 2, 13) == RT_FALSE) - res = TC_STAT_FAILED; - if (mem_check(ptr3, 3, 31) == RT_FALSE) - res = TC_STAT_FAILED; - if (mem_check(ptr4, 4, 1) == RT_FALSE) - res = TC_STAT_FAILED; - -_free: - rt_free(ptr4); - rt_free(ptr3); - rt_free(ptr2); - rt_free(ptr1); - - tc_done(res); -} - -#ifdef RT_USING_TC -int _tc_heap_realloc() -{ - heap_realloc_init(); - - return 0; -} -FINSH_FUNCTION_EXPORT(_tc_heap_realloc, a heap re-malloc test); -#else -int rt_application_init() -{ - heap_realloc_init(); - - return 0; -} -#endif diff --git a/examples/kernel/mbox_send_wait.c b/examples/kernel/mbox_send_wait.c deleted file mode 100644 index 86513fcb13..0000000000 --- a/examples/kernel/mbox_send_wait.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 程序清单:邮箱例程_发送阻塞 - * - * 这个程序用来测试邮箱发送时候的阻塞情况。 - * - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; - -/* 邮箱控制块 */ -static struct rt_mailbox mb; -/* 用于放邮件的内存池 */ -static char mb_pool[32]; - -static char mb_str1[] = "I'm a mail!"; -static char mb_str2[] = "this is another mail!"; - -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - unsigned char* str; - - while (1) - { - /* 从邮箱中收取邮件 */ - if (rt_mb_recv(&mb, (rt_uint32_t*)&str, RT_WAITING_FOREVER) == RT_EOK) - { - rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str); - - /* 延时20个OS Tick */ - rt_thread_delay(50); - } - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - rt_uint8_t count; - char *str; - - count = 0; - while (1) - { - count ++; - if (count & 0x1) - { - /* 发送mb_str1地址到邮箱中 */ - str = mb_str1; - } - else - { - /* 发送mb_str2地址到邮箱中 */ - str = mb_str2; - } - - /* 不停的发送邮件,如果满了则等待10个tick,然后超时 */ - if( rt_mb_send_wait(&mb, (rt_uint32_t)str,10) == RT_EOK ) - rt_kprintf("thread2: sent a mail to mailbox, the content:%s\n", str); - else - rt_kprintf("thread2: timeout while waiting to send a mail.\n"); - } -} - -int mbox_send_wait_init() -{ - /* 初始化一个mailbox */ - rt_mb_init(&mb, - "mbt", /* 名称是mbt */ - &mb_pool[0], /* 邮箱用到的内存池是mb_pool */ - sizeof(mb_pool)/4, /* 大小是mb_pool大小除以4,因为一封邮件的大小是4字节 */ - RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */ - - /* 创建线程1 */ - tid1 = rt_thread_create("t1", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("t2", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 执行邮箱对象脱离 */ - rt_mb_detach(&mb); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_mbox_send_wait() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - mbox_send_wait_init(); - - /* 返回TestCase运行的最长时间 */ - return 300; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_mbox_send_wait, a example of mailbox send wait); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - mbox_send_wait_init(); - - return 0; -} -#endif - diff --git a/examples/kernel/mbox_simple.c b/examples/kernel/mbox_simple.c deleted file mode 100644 index 5d588decb3..0000000000 --- a/examples/kernel/mbox_simple.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 程序清单:邮箱例程 - * - * 这个程序会创建2个动态线程,一个静态的邮箱对象,其中一个线程往邮箱中发送邮件, - * 一个线程往邮箱中收取邮件。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; - -/* 邮箱控制块 */ -static struct rt_mailbox mb; -/* 用于放邮件的内存池 */ -static char mb_pool[128]; - -static char mb_str1[] = "I'm a mail!"; -static char mb_str2[] = "this is another mail!"; - -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - unsigned char* str; - - while (1) - { - rt_kprintf("thread1: try to recv a mail\n"); - - /* 从邮箱中收取邮件 */ - if (rt_mb_recv(&mb, (rt_uint32_t*)&str, RT_WAITING_FOREVER) == RT_EOK) - { - rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str); - - /* 延时10个OS Tick */ - rt_thread_delay(10); - } - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - rt_uint8_t count; - - count = 0; - while (1) - { - count ++; - if (count & 0x1) - { - /* 发送mb_str1地址到邮箱中 */ - rt_mb_send(&mb, (rt_uint32_t)&mb_str1[0]); - } - else - { - /* 发送mb_str2地址到邮箱中 */ - rt_mb_send(&mb, (rt_uint32_t)&mb_str2[0]); - } - - /* 延时20个OS Tick */ - rt_thread_delay(20); - } -} - -int mbox_simple_init() -{ - /* 初始化一个mailbox */ - rt_mb_init(&mb, - "mbt", /* 名称是mbt */ - &mb_pool[0], /* 邮箱用到的内存池是mb_pool */ - sizeof(mb_pool)/4, /* 大小是mb_pool大小除以4,因为一封邮件的大小是4字节 */ - RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */ - - /* 创建线程1 */ - tid1 = rt_thread_create("t1", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("t2", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 执行邮箱对象脱离 */ - rt_mb_detach(&mb); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_mbox_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - mbox_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_mbox_simple, a simple mailbox example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - mbox_simple_init(); - - return 0; -} -#endif diff --git a/examples/kernel/memp_simple.c b/examples/kernel/memp_simple.c deleted file mode 100644 index ab8f3b94ed..0000000000 --- a/examples/kernel/memp_simple.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 程序清单:内存池例程 - * - * 这个程序会创建一个静态的内存池对象,2个动态线程。两个线程会试图分别从内存池中获得 - * 内存块 - */ -#include <rtthread.h> -#include "tc_comm.h" - -static rt_uint8_t *ptr[48]; -static rt_uint8_t mempool[4096]; -static struct rt_mempool mp; - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; - -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - int i; - char *block; - - while(1) - { - for (i = 0; i < 48; i++) - { - /* 申请内存块 */ - rt_kprintf("allocate No.%d\n", i); - if (ptr[i] == RT_NULL) - { - ptr[i] = rt_mp_alloc(&mp, RT_WAITING_FOREVER); - } - } - - /* 继续申请一个内存块,因为已经没有内存块,线程应该被挂起 */ - block = rt_mp_alloc(&mp, RT_WAITING_FOREVER); - rt_kprintf("allocate the block mem\n"); - /* 释放这个内存块 */ - rt_mp_free(block); - block = RT_NULL; - } -} - -/* 线程2入口,线程2的优先级比线程1低,应该线程1先获得执行。*/ -static void thread2_entry(void *parameter) -{ - int i; - - while(1) - { - rt_kprintf("try to release block\n"); - - for (i = 0 ; i < 48; i ++) - { - /* 释放所有分配成功的内存块 */ - if (ptr[i] != RT_NULL) - { - rt_kprintf("release block %d\n", i); - - rt_mp_free(ptr[i]); - ptr[i] = RT_NULL; - } - } - - /* 休眠10个OS Tick */ - rt_thread_delay(10); - } -} - -int mempool_simple_init() -{ - int i; - for (i = 0; i < 48; i ++) ptr[i] = RT_NULL; - - /* 初始化内存池对象 */ - rt_mp_init(&mp, "mp1", &mempool[0], sizeof(mempool), 80); - - /* 创建线程1 */ - tid1 = rt_thread_create("t1", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("t2", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 执行内存池脱离 */ - rt_mp_detach(&mp); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_mempool_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - mempool_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_mempool_simple, a memory pool example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - mempool_simple_init(); - - return 0; -} -#endif diff --git a/examples/kernel/messageq_simple.c b/examples/kernel/messageq_simple.c deleted file mode 100644 index 51b371f59c..0000000000 --- a/examples/kernel/messageq_simple.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 程序清单:消息队列例程 - * - * 这个程序会创建3个动态线程,一个线程会从消息队列中收取消息;一个线程会定时给消 - * 息队列发送消息;一个线程会定时给消息队列发送紧急消息。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -static rt_thread_t tid3 = RT_NULL; - -/* 消息队列控制块 */ -static struct rt_messagequeue mq; -/* 消息队列中用到的放置消息的内存池 */ -static char msg_pool[2048]; - -/* 线程1入口函数 */ -static void thread1_entry(void* parameter) -{ - char buf[128]; - - while (1) - { - rt_memset(&buf[0], 0, sizeof(buf)); - - /* 从消息队列中接收消息 */ - if (rt_mq_recv(&mq, &buf[0], sizeof(buf), RT_WAITING_FOREVER) == RT_EOK) - { - rt_kprintf("thread1: recv msg from message queue, the content:%s\n", buf); - } - - /* 延迟10个OS Tick */ - rt_thread_delay(10); - } -} - -/* 线程2入口函数 */ -static void thread2_entry(void* parameter) -{ - int i, result; - char buf[] = "this is message No.x"; - - while (1) - { - for (i = 0; i < 10; i++) - { - buf[sizeof(buf) - 2] = '0' + i; - - rt_kprintf("thread2: send message - %s\n", buf); - /* 发送消息到消息队列中 */ - result = rt_mq_send(&mq, &buf[0], sizeof(buf)); - if ( result == -RT_EFULL) - { - /* 消息队列满, 延迟1s时间 */ - rt_kprintf("message queue full, delay 1s\n"); - rt_thread_delay(100); - } - } - - /* 延时10个OS Tick */ - rt_thread_delay(10); - } -} - -/* 线程3入口函数 */ -static void thread3_entry(void* parameter) -{ - char buf[] = "this is an urgent message!"; - - while (1) - { - rt_kprintf("thread3: send an urgent message\n"); - - /* 发送紧急消息到消息队列中 */ - rt_mq_urgent(&mq, &buf[0], sizeof(buf)); - - /* 延时25个OS Tick */ - rt_thread_delay(25); - } -} - -int messageq_simple_init() -{ - /* 初始化消息队列 */ - rt_mq_init(&mq, "mqt", - &msg_pool[0], /* 内存池指向msg_pool */ - 128 - sizeof(void*), /* 每个消息的大小是 128 - void* */ - sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */ - RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */ - - /* 创建线程1 */ - tid1 = rt_thread_create("t1", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("t2", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程3 */ - tid3 = rt_thread_create("t3", - thread3_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid3 != RT_NULL) - rt_thread_startup(tid3); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid3); - - /* 执行消息队列对象脱离 */ - rt_mq_detach(&mq); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_messageq_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - messageq_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_messageq_simple, a simple message queue example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - messageq_simple_init(); - - return 0; -} -#endif diff --git a/examples/kernel/mutex_simple.c b/examples/kernel/mutex_simple.c deleted file mode 100644 index afbab3a3e1..0000000000 --- a/examples/kernel/mutex_simple.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 程序清单: - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -static rt_thread_t tid3 = RT_NULL; -static rt_mutex_t mutex = RT_NULL; - -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - /* 先让低优先级线程运行 */ - rt_thread_delay(10); - - /* 此时thread3持有mutex,并且thread2等待持有mutex */ - - /* 检查thread2与thread3的优先级情况 */ - if (tid2->current_priority != tid3->current_priority) - { - /* 优先级不相同,测试失败 */ - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return; - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - rt_err_t result; - - /* 先让低优先级线程运行 */ - rt_thread_delay(5); - - while (1) - { - /* - * 试图持有互斥锁,此时thread3持有,应把thread3的优先级提升到thread2相同 - * 的优先级 - */ - result = rt_mutex_take(mutex, RT_WAITING_FOREVER); - - if (result == RT_EOK) - { - /* 释放互斥锁 */ - rt_mutex_release(mutex); - } - } -} - -/* 线程3入口 */ -static void thread3_entry(void* parameter) -{ - rt_tick_t tick; - rt_err_t result; - - while (1) - { - result = rt_mutex_take(mutex, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - } - result = rt_mutex_take(mutex, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - } - - /* 做一个长时间的循环,总共50个OS Tick */ - tick = rt_tick_get(); - while (rt_tick_get() - tick < 50) ; - - rt_mutex_release(mutex); - rt_mutex_release(mutex); - } -} - -int mutex_simple_init() -{ - /* 创建互斥锁 */ - mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO); - if (mutex == RT_NULL) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - /* 创建线程1 */ - tid1 = rt_thread_create("t1", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("t2", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程3 */ - tid3 = rt_thread_create("t3", - thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); - if (tid3 != RT_NULL) - rt_thread_startup(tid3); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid3); - - if (mutex != RT_NULL) - { - rt_mutex_delete(mutex); - } - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_mutex_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - mutex_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_mutex_simple, sime mutex example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - mutex_simple_init(); - - return 0; -} -#endif diff --git a/examples/kernel/semaphore_buffer_worker.c b/examples/kernel/semaphore_buffer_worker.c deleted file mode 100644 index db3285c74b..0000000000 --- a/examples/kernel/semaphore_buffer_worker.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 程序清单:信号量实现生产者消费者间的互斥 - * - * 在这个程序中,会创建两个线程,一个是生成者线程worker一个是消费者线程thread - * - * 在数据信息生产、消费的过程中,worker负责把数据将写入到环形buffer中,而thread - * 则从环形buffer中读出。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 一个环形buffer的实现 */ -struct rb -{ - rt_uint16_t read_index, write_index; - rt_uint8_t *buffer_ptr; - rt_uint16_t buffer_size; -}; - -/* 指向信号量控制块的指针 */ -static rt_sem_t sem = RT_NULL; -/* 指向线程控制块的指针 */ -static rt_thread_t tid = RT_NULL, worker = RT_NULL; - -/* 环形buffer的内存块(用数组体现出来) */ -#define BUFFER_SIZE 256 -#define BUFFER_ITEM 32 -static rt_uint8_t working_buffer[BUFFER_SIZE]; -struct rb working_rb; - -/* 初始化环形buffer,size指的是buffer的大小。注:这里并没对数据地址对齐做处理 */ -static void rb_init(struct rb* rb, rt_uint8_t *pool, rt_uint16_t size) -{ - RT_ASSERT(rb != RT_NULL); - - /* 对读写指针清零*/ - rb->read_index = rb->write_index = 0; - - /* 设置环形buffer的内存数据块 */ - rb->buffer_ptr = pool; - rb->buffer_size = size; -} - -/* 向环形buffer中写入数据 */ -static rt_bool_t rb_put(struct rb* rb, const rt_uint8_t *ptr, rt_uint16_t length) -{ - rt_size_t size; - - /* 判断是否有足够的剩余空间 */ - if (rb->read_index > rb->write_index) - size = rb->read_index - rb->write_index; - else - size = rb->buffer_size - rb->write_index + rb->read_index; - - /* 没有多余的空间 */ - if (size < length) return RT_FALSE; - - if (rb->read_index > rb->write_index) - { - /* read_index - write_index 即为总的空余空间 */ - memcpy(&rb->buffer_ptr[rb->write_index], ptr, length); - rb->write_index += length; - } - else - { - if (rb->buffer_size - rb->write_index > length) - { - /* write_index 后面剩余的空间有足够的长度 */ - memcpy(&rb->buffer_ptr[rb->write_index], ptr, length); - rb->write_index += length; - } - else - { - /* - * write_index 后面剩余的空间不存在足够的长度,需要把部分数据复制到 - * 前面的剩余空间中 - */ - memcpy(&rb->buffer_ptr[rb->write_index], ptr, - rb->buffer_size - rb->write_index); - memcpy(&rb->buffer_ptr[0], &ptr[rb->buffer_size - rb->write_index], - length - (rb->buffer_size - rb->write_index)); - rb->write_index = length - (rb->buffer_size - rb->write_index); - } - } - - return RT_TRUE; -} - -/* 从环形buffer中读出数据 */ -static rt_bool_t rb_get(struct rb* rb, rt_uint8_t *ptr, rt_uint16_t length) -{ - rt_size_t size; - - /* 判断是否有足够的数据 */ - if (rb->read_index > rb->write_index) - size = rb->buffer_size - rb->read_index + rb->write_index; - else - size = rb->write_index - rb->read_index; - - /* 没有足够的数据 */ - if (size < length) return RT_FALSE; - - if (rb->read_index > rb->write_index) - { - if (rb->buffer_size - rb->read_index > length) - { - /* read_index的数据足够多,直接复制 */ - memcpy(ptr, &rb->buffer_ptr[rb->read_index], length); - rb->read_index += length; - } - else - { - /* read_index的数据不够,需要分段复制 */ - memcpy(ptr, &rb->buffer_ptr[rb->read_index], - rb->buffer_size - rb->read_index); - memcpy(&ptr[rb->buffer_size - rb->read_index], &rb->buffer_ptr[0], - length - rb->buffer_size + rb->read_index); - rb->read_index = length - rb->buffer_size + rb->read_index; - } - } - else - { - /* - * read_index要比write_index小,总的数据量够(前面已经有总数据量的判 - * 断),直接复制出数据。 - */ - memcpy(ptr, &rb->buffer_ptr[rb->read_index], length); - rb->read_index += length; - } - - return RT_TRUE; -} - -/* 生产者线程入口 */ -static void thread_entry(void* parameter) -{ - rt_bool_t result; - rt_uint8_t data_buffer[BUFFER_ITEM + 1]; - - while (1) - { - /* 持有信号量 */ - rt_sem_take(sem, RT_WAITING_FOREVER); - /* 从环buffer中获得数据 */ - result = rb_get(&working_rb, &data_buffer[0], BUFFER_ITEM); - /* 释放信号量 */ - rt_sem_release(sem); - data_buffer[BUFFER_ITEM] = '\0'; - - if (result == RT_TRUE) - { - /* 获取数据成功,打印数据 */ - rt_kprintf("%s\n", data_buffer); - } - - /* 做一个5 OS Tick的休眠 */ - rt_thread_delay(5); - } -} - -/* worker线程入口 */ -static void worker_entry(void* parameter) -{ - rt_bool_t result; - rt_uint32_t index, setchar; - rt_uint8_t data_buffer[BUFFER_ITEM]; - - setchar = 0x21; - while (1) - { - /* 构造数据 */ - for(index = 0; index < BUFFER_ITEM; index++) - { - data_buffer[index] = setchar; - if (++setchar == 0x7f) - setchar = 0x21; - } - - /* 持有信号量 */ - rt_sem_take(sem, RT_WAITING_FOREVER); - - /* 把数据放到环形buffer中 */ - result = rb_put(&working_rb, &data_buffer[0], BUFFER_ITEM); - if (result == RT_FALSE) - { - rt_kprintf("put error\n"); - } - - /* 释放信号量 */ - rt_sem_release(sem); - - /* 放入成功,做一个10 OS Tick的休眠 */ - rt_thread_delay(10); - } -} - -int semaphore_buffer_worker_init() -{ - /* 初始化ring buffer */ - rb_init(&working_rb, working_buffer, BUFFER_SIZE); - - /* 创建信号量 */ - sem = rt_sem_create("sem", 1, RT_IPC_FLAG_FIFO); - if (sem == RT_NULL) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - /* 创建线程1 */ - tid = rt_thread_create("thread", - thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid != RT_NULL) - rt_thread_startup(tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - worker = rt_thread_create("worker", - worker_entry, RT_NULL, /* 线程入口是worker_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (worker != RT_NULL) - rt_thread_startup(worker); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除信号量 */ - if (sem != RT_NULL) - rt_sem_delete(sem); - - /* 删除线程 */ - if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid); - if (worker != RT_NULL && worker->stat != RT_THREAD_CLOSE) - rt_thread_delete(worker); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_semaphore_buffer_worker() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - semaphore_buffer_worker_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_semaphore_buffer_worker, a buffer worker with semaphore example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - semaphore_buffer_worker_init(); - - return 0; -} -#endif diff --git a/examples/kernel/semaphore_dynamic.c b/examples/kernel/semaphore_dynamic.c deleted file mode 100644 index dc088e6e44..0000000000 --- a/examples/kernel/semaphore_dynamic.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 程序清单:动态信号量 - * - * 这个例子中将创建一个动态信号量(初始值为0 )及一个动态线程,在这个动态线程中 - * 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并 - * 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid = RT_NULL; -/* 指向信号量的指针 */ -static rt_sem_t sem = RT_NULL; -/* 线程入口 */ -static void thread_entry(void* parameter) -{ - rt_err_t result; - rt_tick_t tick; - - /* 获得当前的OS Tick */ - tick = rt_tick_get(); - - /* 试图持有一个信号量,如果10个OS Tick依然没拿到,则超时返回 */ - result = rt_sem_take(sem, 10); - if (result == -RT_ETIMEOUT) - { - rt_tick_t new_tick = rt_tick_get(); - /* 可以有两个 tick 的误差 */ - if (new_tick - tick >= 12) - { - rt_kprintf("tick error to large: expect: 10, get %d\n", - new_tick - tick); - - /* 如果失败,则测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_delete(sem); - return; - } - rt_kprintf("take semaphore timeout\n"); - } - else - { - /* 因为并没释放信号量,应该是超时返回,否则测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_delete(sem); - return; - } - - /* 释放一次信号量 */ - rt_sem_release(sem); - - /* 继续持有信号量,并永远等待直到持有到信号量 */ - result = rt_sem_take(sem, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - /* 返回不正确,测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_delete(sem); - return; - } - - /* 测试成功 */ - tc_done(TC_STAT_PASSED); - /* 删除信号量 */ - rt_sem_delete(sem); -} - -int semaphore_dynamic_init() -{ - /* 创建一个信号量,初始值是0 */ - sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO); - if (sem == RT_NULL) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - /* 创建线程 */ - tid = rt_thread_create("thread", - thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid != RT_NULL) - rt_thread_startup(tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - if (sem) - { - rt_sem_delete(sem); - sem = RT_NULL; - } - - /* 删除线程 */ - if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) - { - rt_thread_delete(tid); - } - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_semaphore_dynamic() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - semaphore_dynamic_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_semaphore_dynamic, a dynamic semaphore example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - semaphore_dynamic_init(); - - return 0; -} -#endif diff --git a/examples/kernel/semaphore_priority.c b/examples/kernel/semaphore_priority.c deleted file mode 100644 index d6e3ce3914..0000000000 --- a/examples/kernel/semaphore_priority.c +++ /dev/null @@ -1,134 +0,0 @@ -#include <rtthread.h> -#include "tc_comm.h" - -static rt_sem_t sem; -static rt_uint8_t t1_count, t2_count; -static rt_thread_t t1, t2, worker; -static void thread1_entry(void* parameter) -{ - rt_err_t result; - - while (1) - { - result = rt_sem_take(sem, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - tc_done(TC_STAT_FAILED); - return; - } - - t1_count ++; - rt_kprintf("thread1: got semaphore, count: %d\n", t1_count); - } -} - -static void thread2_entry(void* parameter) -{ - rt_err_t result; - - while (1) - { - result = rt_sem_take(sem, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - tc_done(TC_STAT_FAILED); - return; - } - - t2_count ++; - rt_kprintf("thread2: got semaphore, count: %d\n", t2_count); - } -} - -static void worker_thread_entry(void* parameter) -{ - rt_thread_delay(10); - - while (1) - { - rt_sem_release(sem); - rt_thread_delay(5); - } -} - -int semaphore_priority_init() -{ - sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO); - if (sem == RT_NULL) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - t1_count = t2_count = 0; - - t1 = rt_thread_create("t1", - thread1_entry, RT_NULL, - THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); - if (t1 != RT_NULL) - rt_thread_startup(t1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - t2 = rt_thread_create("t2", - thread2_entry, RT_NULL, - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (t2 != RT_NULL) - rt_thread_startup(t2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - worker = rt_thread_create("worker", - worker_thread_entry, RT_NULL, - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (worker != RT_NULL) - rt_thread_startup(worker); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* lock scheduler */ - rt_enter_critical(); - - /* delete t1, t2 and worker thread */ - rt_thread_delete(t1); - rt_thread_delete(t2); - rt_thread_delete(worker); - - if (sem) - { - rt_sem_delete(sem); - sem = RT_NULL; - } - - if (t1_count > t2_count) - tc_done(TC_STAT_FAILED); - else - tc_done(TC_STAT_PASSED); - - /* unlock scheduler */ - rt_exit_critical(); -} - -int _tc_semaphore_priority() -{ - /* set tc cleanup */ - tc_cleanup(_tc_cleanup); - semaphore_priority_init(); - - return 50; -} -FINSH_FUNCTION_EXPORT(_tc_semaphore_priority, a priority semaphore test); -#else -int rt_application_init() -{ - semaphore_priority_init(); - - return 0; -} -#endif diff --git a/examples/kernel/semaphore_producer_consumer.c b/examples/kernel/semaphore_producer_consumer.c deleted file mode 100644 index a240cfa8b2..0000000000 --- a/examples/kernel/semaphore_producer_consumer.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 程序清单:生产者消费者例子 - * - * 这个例子中将创建两个线程用于实现生产者消费者问题 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 定义最大5个元素能够被产生 */ -#define MAXSEM 5 - -/* 用于放置生产的整数数组 */ -rt_uint32_t array[MAXSEM]; -/* 指向生产者、消费者在array数组中的读写位置 */ -static rt_uint32_t set, get; - -/* 指向线程控制块的指针 */ -static rt_thread_t producer_tid = RT_NULL; -static rt_thread_t consumer_tid = RT_NULL; - -struct rt_semaphore sem_lock; -struct rt_semaphore sem_empty, sem_full; - -/* 生成者线程入口 */ -void producer_thread_entry(void* parameter) -{ - int cnt = 0; - - /* 运行100次 */ - while( cnt < 100) - { - /* 获取一个空位 */ - rt_sem_take(&sem_empty, RT_WAITING_FOREVER); - - /* 修改array内容,上锁 */ - rt_sem_take(&sem_lock, RT_WAITING_FOREVER); - array[set%MAXSEM] = cnt + 1; - rt_kprintf("the producer generates a number: %d\n", array[set%MAXSEM]); - set++; - rt_sem_release(&sem_lock); - - /* 发布一个满位 */ - rt_sem_release(&sem_full); - cnt++; - - /* 暂停一段时间 */ - rt_thread_delay(50); - } - - rt_kprintf("the producer exit!\n"); -} - -/* 消费者线程入口 */ -void consumer_thread_entry(void* parameter) -{ - rt_uint32_t no; - rt_uint32_t sum; - - /* 第n个线程,由入口参数传进来 */ - no = (rt_uint32_t)parameter; - - sum = 0; - while(1) - { - /* 获取一个满位 */ - rt_sem_take(&sem_full, RT_WAITING_FOREVER); - - /* 临界区,上锁进行操作 */ - rt_sem_take(&sem_lock, RT_WAITING_FOREVER); - sum += array[get%MAXSEM]; - rt_kprintf("the consumer[%d] get a number: %d\n", no, array[get%MAXSEM] ); - get++; - rt_sem_release(&sem_lock); - - /* 释放一个空位 */ - rt_sem_release(&sem_empty); - - /* 生产者生产到100个数目,停止,消费者线程相应停止 */ - if (get == 100) break; - - /* 暂停一小会时间 */ - rt_thread_delay(10); - } - - rt_kprintf("the consumer[%d] sum is %d \n ", no, sum); - rt_kprintf("the consumer[%d] exit!\n"); -} - -int semaphore_producer_consumer_init() -{ - /* 初始化3个信号量 */ - rt_sem_init(&sem_lock , "lock", 1, RT_IPC_FLAG_FIFO); - rt_sem_init(&sem_empty, "empty", MAXSEM, RT_IPC_FLAG_FIFO); - rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_FIFO); - - /* 创建线程1 */ - producer_tid = rt_thread_create("producer", - producer_thread_entry, RT_NULL, /* 线程入口是producer_thread_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (producer_tid != RT_NULL) - rt_thread_startup(producer_tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - consumer_tid = rt_thread_create("consumer", - consumer_thread_entry, RT_NULL, /* 线程入口是consumer_thread_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); - if (consumer_tid != RT_NULL) - rt_thread_startup(consumer_tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - rt_sem_detach(&sem_lock); - rt_sem_detach(&sem_empty); - rt_sem_detach(&sem_full); - - /* 删除线程 */ - if (producer_tid != RT_NULL && producer_tid->stat != RT_THREAD_CLOSE) - rt_thread_delete(producer_tid); - if (consumer_tid != RT_NULL && consumer_tid->stat != RT_THREAD_CLOSE) - rt_thread_delete(consumer_tid); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_semaphore_producer_consumer() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - semaphore_producer_consumer_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_semaphore_producer_consumer, producer and consumer example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - semaphore_producer_consumer_init(); - - return 0; -} -#endif diff --git a/examples/kernel/semaphore_static.c b/examples/kernel/semaphore_static.c deleted file mode 100644 index cb199886a4..0000000000 --- a/examples/kernel/semaphore_static.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 程序清单:静态信号量 - * - * 这个例子中将创建一个静态信号量(初始值为0 )及一个静态线程,在这个静态线程中 - * 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并 - * 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 线程控制块及栈 */ -static struct rt_thread thread; -static rt_uint8_t thread_stack[THREAD_STACK_SIZE]; -/* 信号量控制块 */ -static struct rt_semaphore sem; - -/* 线程入口 */ -static void thread_entry(void* parameter) -{ - rt_err_t result; - rt_tick_t tick; - - /* 获得当前的OS Tick */ - tick = rt_tick_get(); - - /* 试图持有信号量,最大等待10个OS Tick后返回 */ - result = rt_sem_take(&sem, 10); - if (result == -RT_ETIMEOUT) - { - rt_tick_t new_tick = rt_tick_get(); - /* 可以有两个 tick 的误差 */ - if (new_tick - tick >= 12) - { - rt_kprintf("tick error to large: expect: 10, get %d\n", - new_tick - tick); - - tc_done(TC_STAT_FAILED); - rt_sem_detach(&sem); - return; - } - rt_kprintf("take semaphore timeout\n"); - } - else - { - /* 因为没有其他地方是否信号量,所以不应该成功持有信号量,否则测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_detach(&sem); - return; - } - - /* 释放一次信号量 */ - rt_sem_release(&sem); - - /* 永久等待方式持有信号量 */ - result = rt_sem_take(&sem, RT_WAITING_FOREVER); - if (result != RT_EOK) - { - /* 不成功则测试失败 */ - tc_done(TC_STAT_FAILED); - rt_sem_detach(&sem); - return; - } - - /* 测试通过 */ - tc_done(TC_STAT_PASSED); - /* 脱离信号量对象 */ - rt_sem_detach(&sem); -} - -int semaphore_static_init(void) -{ - rt_err_t result; - - /* 初始化信号量,初始值是0 */ - result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO); - if (result != RT_EOK) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return 0; - } - - /* 初始化线程1 */ - result = rt_thread_init(&thread, "thread", /* 线程名:thread */ - thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是RT_NULL*/ - &thread_stack[0], sizeof(thread_stack), /* 线程栈是thread_stack */ - THREAD_PRIORITY, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程1 */ - rt_thread_startup(&thread); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup(void) -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 执行线程脱离 */ - if (thread.stat != RT_THREAD_CLOSE) - { - rt_thread_detach(&thread); - - /* 执行信号量对象脱离 */ - rt_sem_detach(&sem); - } - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_semaphore_static(void) -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - semaphore_static_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore example); -#else -/* 用户应用入口 */ -int rt_application_init(void) -{ - semaphore_static_init(); - - return 0; -} -#endif diff --git a/examples/kernel/tc_comm.c b/examples/kernel/tc_comm.c deleted file mode 100644 index f6493389a6..0000000000 --- a/examples/kernel/tc_comm.c +++ /dev/null @@ -1,198 +0,0 @@ -#include "tc_comm.h" -#ifdef RT_USING_FINSH -#include <finsh.h> -#endif - -#ifdef RT_USING_TC -#define TC_PRIORITY 25 -#define TC_STACK_SIZE 0x400 - -static rt_uint8_t _tc_stat; -static struct rt_semaphore _tc_sem; -static struct rt_thread _tc_thread; -static rt_uint8_t _tc_stack[TC_STACK_SIZE]; -static char _tc_prefix[64]; -static const char* _tc_current; -static void (*_tc_cleanup)(void) = RT_NULL; - -static rt_uint32_t _tc_scale = 1; -FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale) - -static rt_uint32_t _tc_loop; - -void tc_thread_entry(void* parameter) -{ - unsigned int fail_count = 0; - struct finsh_syscall* index; - - /* create tc semaphore */ - rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO); - - do { - for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index)) - { - /* search testcase */ - if (rt_strstr(index->name, _tc_prefix) == index->name) - { - long tick; - - _tc_current = index->name + 4; - rt_kprintf("Run TestCase: %s\n", _tc_current); - _tc_stat = TC_STAT_PASSED | TC_STAT_RUNNING; - tick = index->func(); - if (tick > 0) - { - /* Make sure we are going to be blocked. */ - rt_sem_control(&_tc_sem, RT_IPC_CMD_RESET, 0); - rt_sem_take(&_tc_sem, tick * _tc_scale); - } - - if (_tc_cleanup != RT_NULL) - { - /* perform testcase cleanup */ - _tc_cleanup(); - _tc_cleanup = RT_NULL; - } - - if (_tc_stat & TC_STAT_RUNNING) - { - rt_kprintf("TestCase[%s] exit with stat TC_STAT_RUNNING." - " Please fix the TC.\n", - _tc_current); - /* If the TC forgot to clear the flag, we do it. */ - _tc_stat &= ~TC_STAT_RUNNING; - } - - if (_tc_stat & TC_STAT_FAILED) - { - rt_kprintf("TestCase[%s] failed\n", _tc_current); - fail_count++; - } - else - { - rt_kprintf("TestCase[%s] passed\n", _tc_current); - } - } - } - } while (_tc_loop); - - rt_kprintf("RT-Thread TestCase Running Done!\n"); - if (fail_count) - { - rt_kprintf("%d tests failed\n", fail_count); - } - else - { - rt_kprintf("All tests passed\n"); - } - /* detach tc semaphore */ - rt_sem_detach(&_tc_sem); -} - -void tc_stop() -{ - _tc_loop = 0; - - rt_thread_delay(10 * RT_TICK_PER_SECOND); - if (_tc_thread.stat != RT_THREAD_INIT) - { - /* lock scheduler */ - rt_enter_critical(); - - /* detach old tc thread */ - rt_thread_detach(&_tc_thread); - rt_sem_detach(&_tc_sem); - - /* unlock scheduler */ - rt_exit_critical(); - } - rt_thread_delay(RT_TICK_PER_SECOND/2); -} -FINSH_FUNCTION_EXPORT(tc_stop, stop testcase thread); - -void tc_done(rt_uint8_t stat) -{ - _tc_stat |= stat; - _tc_stat &= ~TC_STAT_RUNNING; - - /* release semaphore */ - rt_sem_release(&_tc_sem); -} - -void tc_stat(rt_uint8_t stat) -{ - if (stat & TC_STAT_FAILED) - { - rt_kprintf("TestCases[%s] failed\n", _tc_current); - } - _tc_stat |= stat; -} - -void tc_cleanup(void (*cleanup)()) -{ - _tc_cleanup = cleanup; -} - -void tc_start(const char* tc_prefix) -{ - rt_err_t result; - - /* tesecase prefix is null */ - if (tc_prefix == RT_NULL) - { - rt_kprintf("TestCase Usage: tc_start(prefix)\n\n"); - rt_kprintf("list_tc() can list all testcases.\n"); - return ; - } - - /* init tc thread */ - if (_tc_stat & TC_STAT_RUNNING) - { - /* stop old tc thread */ - tc_stop(); - } - - rt_memset(_tc_prefix, 0, sizeof(_tc_prefix)); - rt_snprintf(_tc_prefix, sizeof(_tc_prefix), "_tc_%s", tc_prefix); - - result = rt_thread_init(&_tc_thread, "tc", - tc_thread_entry, RT_NULL, - &_tc_stack[0], sizeof(_tc_stack), - TC_PRIORITY - 3, 5); - - /* set tc stat */ - _tc_stat = TC_STAT_RUNNING | TC_STAT_FAILED; - - if (result == RT_EOK) - rt_thread_startup(&_tc_thread); -} -FINSH_FUNCTION_EXPORT(tc_start, start testcase with testcase prefix or name); - -void tc_loop(const char *tc_prefix) -{ - _tc_loop = 1; - tc_start(tc_prefix); -} -FINSH_FUNCTION_EXPORT(tc_loop, start testcase with testcase prefix or name in loop mode); - -void list_tc() -{ - struct finsh_syscall* index; - - rt_kprintf("TestCases List:\n"); - for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index)) - { - /* search testcase */ - if (rt_strstr(index->name, "_tc_") == index->name) - { -#ifdef FINSH_USING_DESCRIPTION - rt_kprintf("%-16s -- %s\n", index->name + 4, index->desc); -#else - rt_kprintf("%s\n", index->name + 4); -#endif - } - } -} -FINSH_FUNCTION_EXPORT(list_tc, list all testcases); -#endif - diff --git a/examples/kernel/tc_comm.h b/examples/kernel/tc_comm.h deleted file mode 100644 index aee1fec2d2..0000000000 --- a/examples/kernel/tc_comm.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __TC_COMM_H__ -#define __TC_COMM_H__ - -/* - * RT-Thread TestCase - * - */ -#include <rtthread.h> -#ifdef RT_USING_FINSH -#include <finsh.h> -#endif - -#if RT_THREAD_PRIORITY_MAX == 8 -#define THREAD_PRIORITY 6 -#elif RT_THREAD_PRIORITY_MAX == 32 -#define THREAD_PRIORITY 25 -#elif RT_THREAD_PRIORITY_MAX == 256 -#define THREAD_PRIORITY 200 -#endif -#define THREAD_STACK_SIZE 512 -#define THREAD_TIMESLICE 5 - -#define TC_STAT_END 0x00 -#define TC_STAT_RUNNING 0x01 -#define TC_STAT_FAILED 0x10 -#define TC_STAT_PASSED 0x00 - -#ifdef RT_USING_TC -void tc_start(const char* tc_prefix); -void tc_stop(void); -void tc_done(rt_uint8_t state); -void tc_stat(rt_uint8_t state); -void tc_cleanup(void (*cleanup)(void)); -#else -#define tc_start(x) -#define tc_stop() -#define tc_done(s) -#define tc_stat(s) -#define tc_cleanup(c) -#endif - -#endif - diff --git a/examples/kernel/tc_sample.c b/examples/kernel/tc_sample.c deleted file mode 100644 index 212875b716..0000000000 --- a/examples/kernel/tc_sample.c +++ /dev/null @@ -1,62 +0,0 @@ -#include <rtthread.h> -#include "tc_comm.h" - -static rt_thread_t tid = RT_NULL; -static void sample_thread(void* parameter) -{ - rt_kprintf("I'm sample!\n"); -} -static void sample_thread_cleanup(struct rt_thread *p) -{ - tid = RT_NULL; - tc_done(TC_STAT_PASSED); -} - -int sample_init() -{ - tid = rt_thread_create("t", - sample_thread, RT_NULL, - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid != RT_NULL) - { - rt_thread_startup(tid); - tid->cleanup = sample_thread_cleanup; - } - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* lock scheduler */ - rt_enter_critical(); - /* delete thread */ - if (tid != RT_NULL) - { - rt_kprintf("tid1 is bad\n"); - tc_stat(TC_STAT_FAILED); - } - /* unlock scheduler */ - rt_exit_critical(); -} - -int _tc_sample() -{ - /* set tc cleanup */ - tc_cleanup(_tc_cleanup); - sample_init(); - - return 25; -} -FINSH_FUNCTION_EXPORT(_tc_sample, a thread testcase example); -#else -int rt_application_init() -{ - sample_init(); - - return 0; -} -#endif diff --git a/examples/kernel/thread_delay.c b/examples/kernel/thread_delay.c deleted file mode 100644 index f9404d704c..0000000000 --- a/examples/kernel/thread_delay.c +++ /dev/null @@ -1,70 +0,0 @@ -#include <rtthread.h> -#include "tc_comm.h" - -/* - * This is an example for delay thread - */ -static struct rt_thread thread; -static char thread_stack[THREAD_STACK_SIZE]; -static void thread_entry(void* parameter) -{ - rt_tick_t tick; - rt_kprintf("thread inited ok\n"); - - rt_kprintf("thread delay 10 tick\n"); - tick = rt_tick_get(); - rt_thread_delay(10); - if (rt_tick_get() - tick > 11) - { - tc_done(TC_STAT_FAILED); - return; - } - - rt_kprintf("thread delay 15 tick\n"); - tick = rt_tick_get(); - rt_thread_delay(15); - if (rt_tick_get() - tick > 16) - { - tc_done(TC_STAT_FAILED); - return; - } - - rt_kprintf("thread exit\n"); - - tc_done(TC_STAT_PASSED); -} - -rt_err_t thread_delay_init() -{ - rt_err_t result; - - result = rt_thread_init(&thread, - "test", - thread_entry, RT_NULL, - &thread_stack[0], sizeof(thread_stack), - THREAD_PRIORITY, 10); - - if (result == RT_EOK) - rt_thread_startup(&thread); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return result; -} - -#ifdef RT_USING_TC -int _tc_thread_delay() -{ - thread_delay_init(); - - return 30; -} -FINSH_FUNCTION_EXPORT(_tc_thread_delay, a thread delay test); -#else -int rt_application_init() -{ - thread_delay_init(); - - return 0; -} -#endif diff --git a/examples/kernel/thread_delete.c b/examples/kernel/thread_delete.c deleted file mode 100644 index 72eb4ec008..0000000000 --- a/examples/kernel/thread_delete.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 程序清单:删除线程 - * - * 这个例子会创建两个线程,在一个线程中删除另外一个线程。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* - * 线程删除(rt_thread_delete)函数仅适合于动态线程,为了在一个线程 - * 中访问另一个线程的控制块,所以把线程块指针声明成全局类型以供全 - * 局访问 - */ -static rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL; -/* 线程1的入口函数 */ -static void thread1_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 线程1采用低优先级运行,一直打印计数值 */ - // rt_kprintf("thread count: %d\n", count ++); - count ++; - } -} -static void thread1_cleanup(struct rt_thread *tid) -{ - if (tid != tid1) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return ; - } - rt_kprintf("thread1 end\n"); - tid1 = RT_NULL; -} - -/* 线程2的入口函数 */ -static void thread2_entry(void* parameter) -{ - /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */ - - /* 线程2启动后先睡眠10个OS Tick */ - rt_thread_delay(RT_TICK_PER_SECOND); - - /* - * 线程2唤醒后直接删除线程1,删除线程1后,线程1自动脱离就绪线程 - * 队列 - */ - rt_thread_delete(tid1); - - /* - * 线程2继续休眠10个OS Tick然后退出,线程2休眠后应切换到idle线程 - * idle线程将执行真正的线程1控制块和线程栈的删除 - */ - rt_thread_delay(RT_TICK_PER_SECOND); -} - -static void thread2_cleanup(struct rt_thread *tid) -{ - /* - * 线程2运行结束后也将自动被删除(线程控制块和线程栈在idle线 - * 程中释放) - */ - - if (tid != tid2) - { - tc_stat(TC_STAT_END | TC_STAT_FAILED); - return ; - } - rt_kprintf("thread2 end\n"); - tid2 = RT_NULL; - tc_done(TC_STAT_PASSED); -} - -/* 线程删除示例的初始化 */ -int thread_delete_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */ - thread1_entry, RT_NULL, /* 入口是thread1_entry,参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */ - { - tid1->cleanup = thread1_cleanup; - rt_thread_startup(tid1); - } - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程1 */ - tid2 = rt_thread_create("t2", /* 线程1的名称是t2 */ - thread2_entry, RT_NULL, /* 入口是thread2_entry,参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */ - { - tid2->cleanup = thread2_cleanup; - rt_thread_startup(tid2); - } - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 10 * RT_TICK_PER_SECOND; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* lock scheduler */ - rt_enter_critical(); - - /* delete thread */ - if (tid1 != RT_NULL) - { - rt_kprintf("tid1 is %p, should be NULL\n", tid1); - tc_stat(TC_STAT_FAILED); - } - if (tid2 != RT_NULL) - { - rt_kprintf("tid2 is %p, should be NULL\n", tid2); - tc_stat(TC_STAT_FAILED); - } - - /* unlock scheduler */ - rt_exit_critical(); -} - -int _tc_thread_delete() -{ - /* set tc cleanup */ - tc_cleanup(_tc_cleanup); - return thread_delete_init(); -} -FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example); -#else -int rt_application_init() -{ - thread_delete_init(); - - return 0; -} -#endif diff --git a/examples/kernel/thread_detach.c b/examples/kernel/thread_detach.c deleted file mode 100644 index 9370f212e1..0000000000 --- a/examples/kernel/thread_detach.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 程序清单:线程脱离 - * - * 这个例子会创建两个线程,在其中一个线程中执行对另一个线程的脱离。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 线程1控制块 */ -static struct rt_thread thread1; -/* 线程1栈 */ -static rt_uint8_t thread1_stack[THREAD_STACK_SIZE]; -/* 线程2控制块 */ -static struct rt_thread thread2; -/* 线程2栈 */ -static rt_uint8_t thread2_stack[THREAD_STACK_SIZE]; - -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 线程1采用低优先级运行,一直打印计数值 */ - rt_kprintf("thread count: %d\n", count ++); - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */ - - /* 线程2启动后先睡眠10个OS Tick */ - rt_thread_delay(10); - - /* - * 线程2唤醒后直接执行线程1脱离,线程1将从就绪线程队列中删除 - */ - rt_thread_detach(&thread1); - - /* - * 线程2继续休眠10个OS Tick然后退出 - */ - rt_thread_delay(10); - - /* - * 线程2运行结束后也将自动被从就绪队列中删除,并脱离线程队列 - */ -} - -int thread_detach_init() -{ - rt_err_t result; - - /* 初始化线程1 */ - result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */ - thread1_entry, RT_NULL, /* 线程的入口是thread1_entry,入口参数是RT_NULL*/ - &thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */ - THREAD_PRIORITY, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程1 */ - rt_thread_startup(&thread1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 初始化线程2 */ - result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */ - thread2_entry, RT_NULL, /* 线程的入口是thread2_entry,入口参数是RT_NULL*/ - &thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */ - THREAD_PRIORITY - 1, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程2 */ - rt_thread_startup(&thread2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 执行线程脱离 */ - if (thread1.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread1); - if (thread2.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_detach() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_detach_init(); - - /* 返回TestCase运行的最长时间 */ - return 25; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_detach, a static thread example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_detach_init(); - - return 0; -} -#endif diff --git a/examples/kernel/thread_dynamic.c b/examples/kernel/thread_dynamic.c deleted file mode 100644 index 0afb7f8f84..0000000000 --- a/examples/kernel/thread_dynamic.c +++ /dev/null @@ -1,44 +0,0 @@ -#include <rtthread.h> -#include "tc_comm.h" - -static void thread_entry(void* parameter) -{ - rt_kprintf("thread dynamicly created ok\n"); - rt_thread_delay(10); - rt_kprintf("thread exit\n"); - - tc_done(TC_STAT_PASSED); -} - -int thread_dynamic_init() -{ - rt_thread_t tid; - - tid = rt_thread_create("test", - thread_entry, RT_NULL, - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid != RT_NULL) - rt_thread_startup(tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -int _tc_thread_dynamic() -{ - thread_dynamic_init(); - - return 20; -} -FINSH_FUNCTION_EXPORT(_tc_thread_dynamic, a dynamic thread test); -#else -int rt_application_init() -{ - thread_dynamic_init(); - - return 0; -} -#endif - diff --git a/examples/kernel/thread_dynamic_simple.c b/examples/kernel/thread_dynamic_simple.c deleted file mode 100644 index 28944b1f34..0000000000 --- a/examples/kernel/thread_dynamic_simple.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 程序清单:动态线程 - * - * 这个程序会初始化2个动态线程,它们拥有共同的入口函数,但参数不相同 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -/* 线程入口 */ -static void thread_entry(void* parameter) -{ - rt_uint32_t count = 0; - rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */ - - while (1) - { - /* 打印线程计数值输出 */ - rt_kprintf("thread%d count: %d\n", no, count ++); - - /* 休眠10个OS Tick */ - rt_thread_delay(10); - } -} - -int thread_dynamic_simple_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("t1", - thread_entry, (void*)1, /* 线程入口是thread_entry, 入口参数是1 */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("t2", - thread_entry, (void*)2, /* 线程入口是thread_entry, 入口参数是2 */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_dynamic_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_dynamic_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_dynamic_simple, a dynamic thread example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_dynamic_simple_init(); - - return 0; -} -#endif diff --git a/examples/kernel/thread_priority.c b/examples/kernel/thread_priority.c deleted file mode 100644 index 0045b0e578..0000000000 --- a/examples/kernel/thread_priority.c +++ /dev/null @@ -1,105 +0,0 @@ -#include <rtthread.h> -#include "tc_comm.h" - -struct rt_thread thread1; -struct rt_thread thread2; -static char thread1_stack[THREAD_STACK_SIZE]; -static char thread2_stack[THREAD_STACK_SIZE]; -static rt_uint32_t count = 0; - -/* - * the priority of thread1 > the priority of thread2 - */ -static void thread1_entry(void* parameter) -{ - while (1) - { - count ++; - rt_kprintf("count = %d\n", count); - - rt_thread_delay(10); - } -} - -static void thread2_entry(void* parameter) -{ - rt_tick_t tick; - - tick = rt_tick_get(); - while (1) - { - if (rt_tick_get() - tick >= 50) - { - if (count == 0) - tc_done(TC_STAT_FAILED); - else - tc_done(TC_STAT_PASSED); - - break; - } - } -} - -int thread_priority_init() -{ - rt_err_t result; - - result = rt_thread_init(&thread1, - "t1", - thread1_entry, RT_NULL, - &thread1_stack[0], sizeof(thread1_stack), - THREAD_PRIORITY - 1, THREAD_TIMESLICE); - - if (result == RT_EOK) - rt_thread_startup(&thread1); - else - tc_stat(TC_STAT_FAILED); - - rt_thread_init(&thread2, - "t2", - thread2_entry, RT_NULL, - &thread2_stack[0], sizeof(thread2_stack), - THREAD_PRIORITY + 1, THREAD_TIMESLICE); - - if (result == RT_EOK) - rt_thread_startup(&thread2); - else - tc_stat(TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* lock scheduler */ - rt_enter_critical(); - - if (thread1.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread1); - if (thread2.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread2); - - /* unlock scheduler */ - rt_exit_critical(); -} -int _tc_thread_priority() -{ - count = 0; - - /* set tc cleanup */ - tc_cleanup(_tc_cleanup); - thread_priority_init(); - - return RT_TICK_PER_SECOND; -} -FINSH_FUNCTION_EXPORT(_tc_thread_priority, a priority thread test); -#else -int rt_application_init() -{ - thread_priority_init(); - - return 0; -} -#endif - diff --git a/examples/kernel/thread_resume.c b/examples/kernel/thread_resume.c deleted file mode 100644 index cea814616f..0000000000 --- a/examples/kernel/thread_resume.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 程序清单:唤醒线程 - * - * 这个例子中将创建两个动态线程,低优先级线程将挂起自身,然后 - * 高优先级线程将在一定时刻后唤醒低优先级线程。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - /* 低优先级线程1开始运行 */ - rt_kprintf("thread1 startup%d\n"); - - /* 挂起自身 */ - rt_kprintf("suspend thread self\n"); - rt_thread_suspend(tid1); - /* 主动执行线程调度 */ - rt_schedule(); - - /* 当线程1被唤醒时 */ - rt_kprintf("thread1 resumed\n"); -} -static void thread_cleanup(rt_thread_t tid) -{ - if (tid == tid1) - { - tid1 = RT_NULL; - } - if (tid == tid2) - { - tid = RT_NULL; - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - /* 延时10个OS Tick */ - rt_thread_delay(10); - - /* 唤醒线程1 */ - rt_thread_resume(tid1); - rt_kprintf("thread2: to resume thread1\n"); - - /* 延时10个OS Tick */ - rt_thread_delay(10); - - /* 线程2自动退出 */ -} - -int thread_resume_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("thread", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - { - tid1->cleanup = thread_cleanup; - rt_thread_startup(tid1); - } - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("thread", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - { - tid2->cleanup = thread_cleanup; - rt_thread_startup(tid2); - } - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_resume() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_resume_init(); - - /* 返回TestCase运行的最长时间 */ - return 25; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_resume, a thread resume example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_resume_init(); - - return 0; -} -#endif diff --git a/examples/kernel/thread_same_priority.c b/examples/kernel/thread_same_priority.c deleted file mode 100644 index c7da2087a0..0000000000 --- a/examples/kernel/thread_same_priority.c +++ /dev/null @@ -1,96 +0,0 @@ -#include <rtthread.h> -#include "tc_comm.h" - -static struct rt_thread thread1; -static struct rt_thread thread2; -static char thread1_stack[THREAD_STACK_SIZE]; -static char thread2_stack[THREAD_STACK_SIZE]; - -volatile static rt_uint32_t t1_count = 0; -volatile static rt_uint32_t t2_count = 0; -static void thread1_entry(void* parameter) -{ - while (1) - { - t1_count ++; - } -} - -static void thread2_entry(void* parameter) -{ - while (1) - { - t2_count ++; - } -} - -rt_err_t thread_same_priority_init() -{ - rt_err_t result; - - result = rt_thread_init(&thread1, - "t1", - thread1_entry, RT_NULL, - &thread1_stack[0], sizeof(thread1_stack), - THREAD_PRIORITY, 10); - if (result == RT_EOK) - rt_thread_startup(&thread1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - result = rt_thread_init(&thread2, - "t2", - thread2_entry, RT_NULL, - &thread2_stack[0], sizeof(thread2_stack), - THREAD_PRIORITY, 5); - if (result == RT_EOK) - rt_thread_startup(&thread2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return result; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* lock scheduler */ - rt_enter_critical(); - - if (thread1.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread1); - if (thread2.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread2); - - /* unlock scheduler */ - rt_exit_critical(); - - rt_kprintf("t1_count=%d t2_count=%d\n",t1_count,t2_count); - - if (t1_count / t2_count != 2) - tc_stat(TC_STAT_END | TC_STAT_FAILED); - else - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_same_priority() -{ - t1_count = 0; - t2_count = 0; - - /* set tc cleanup */ - tc_cleanup(_tc_cleanup); - - thread_same_priority_init(); - - return 100; -} -FINSH_FUNCTION_EXPORT(_tc_thread_same_priority, a same priority thread test); -#else -int rt_application_init() -{ - thread_same_priority_init(); - - return 0; -} -#endif diff --git a/examples/kernel/thread_static.c b/examples/kernel/thread_static.c deleted file mode 100644 index 3033f2cda1..0000000000 --- a/examples/kernel/thread_static.c +++ /dev/null @@ -1,52 +0,0 @@ -#include <rtthread.h> -#include "tc_comm.h" - -/* - * This is an example for static thread - */ -static struct rt_thread thread; -static char thread_stack[THREAD_STACK_SIZE]; -static void thread_entry(void* parameter) -{ - rt_kprintf("thread staticly inited ok\n"); - rt_thread_delay(10); - rt_kprintf("thread exit\n"); - - tc_done(TC_STAT_PASSED); -} - -rt_err_t thread_static_init() -{ - rt_err_t result; - - result = rt_thread_init(&thread, - "test", - thread_entry, RT_NULL, - &thread_stack[0], sizeof(thread_stack), - THREAD_PRIORITY, 10); - - if (result == RT_EOK) - rt_thread_startup(&thread); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return result; -} - -#ifdef RT_USING_TC -int _tc_thread_static() -{ - thread_static_init(); - - return 20; -} -FINSH_FUNCTION_EXPORT(_tc_thread_static, a static thread test); -#else -int rt_application_init() -{ - thread_static_init(); - - return 0; -} -#endif - diff --git a/examples/kernel/thread_static_simple.c b/examples/kernel/thread_static_simple.c deleted file mode 100644 index d9e3ff6f61..0000000000 --- a/examples/kernel/thread_static_simple.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 程序清单:静态线程 - * - * 这个程序会初始化2个静态线程,它们拥有共同的入口函数,但参数不相同 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 线程1控制块 */ -static struct rt_thread thread1; -/* 线程1栈 */ -static rt_uint8_t thread1_stack[THREAD_STACK_SIZE]; -/* 线程2控制块 */ -static struct rt_thread thread2; -/* 线程2栈 */ -static rt_uint8_t thread2_stack[THREAD_STACK_SIZE]; - -/* 线程入口 */ -static void thread_entry(void* parameter) -{ - rt_uint32_t count = 0; - rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */ - - while (1) - { - /* 打印线程计数值输出 */ - rt_kprintf("thread%d count: %d\n", no, count ++); - - /* 休眠10个OS Tick */ - rt_thread_delay(10); - } -} - -int thread_static_simple_init() -{ - rt_err_t result; - - /* 初始化线程1 */ - result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */ - thread_entry, (void*)1, /* 线程的入口是thread_entry,入口参数是1 */ - &thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */ - THREAD_PRIORITY, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程1 */ - rt_thread_startup(&thread1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 初始化线程2 */ - result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */ - thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是2 */ - &thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */ - THREAD_PRIORITY + 1, 10); - if (result == RT_EOK) /* 如果返回正确,启动线程2 */ - rt_thread_startup(&thread2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 执行线程脱离 */ - if (thread1.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread1); - if (thread2.stat != RT_THREAD_CLOSE) - rt_thread_detach(&thread2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_static_simple() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_static_simple_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_static_simple, a static thread example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_static_simple_init(); - - return 0; -} -#endif diff --git a/examples/kernel/thread_suspend.c b/examples/kernel/thread_suspend.c deleted file mode 100644 index 947cc3cbf6..0000000000 --- a/examples/kernel/thread_suspend.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 程序清单:挂起线程 - * - * 这个例子中将创建两个动态线程,高优先级线程将在一定时刻后挂起低优先级线程。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 线程1采用低优先级运行,一直打印计数值 */ - rt_kprintf("thread count: %d\n", count ++); - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - /* 延时10个OS Tick */ - rt_thread_delay(10); - - /* 挂起线程1 */ - rt_thread_suspend(tid1); - - /* 延时10个OS Tick */ - rt_thread_delay(10); - - /* 线程2自动退出 */ - tid2 = RT_NULL; -} - -int thread_suspend_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("thread", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("thread", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_suspend() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_suspend_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_suspend, a thread suspend example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_suspend_init(); - - return 0; -} -#endif diff --git a/examples/kernel/thread_yield.c b/examples/kernel/thread_yield.c deleted file mode 100644 index 4ed6b90e2a..0000000000 --- a/examples/kernel/thread_yield.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 程序清单: - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 指向线程控制块的指针 */ -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; -/* 线程1入口 */ -static void thread1_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 打印线程1的输出 */ - rt_kprintf("thread1: count = %d\n", count ++); - - /* 执行yield后应该切换到thread2执行 */ - rt_thread_yield(); - } -} - -/* 线程2入口 */ -static void thread2_entry(void* parameter) -{ - rt_uint32_t count = 0; - - while (1) - { - /* 打印线程2的输出 */ - rt_kprintf("thread2: count = %d\n", count ++); - - /* 执行yield后应该切换到thread1执行 */ - rt_thread_yield(); - } -} - -int thread_yield_init() -{ - /* 创建线程1 */ - tid1 = rt_thread_create("thread", - thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建线程2 */ - tid2 = rt_thread_create("thread", - thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除线程 */ - if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid1); - if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_thread_yield() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - thread_yield_init(); - - /* 返回TestCase运行的最长时间 */ - return 30; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_thread_yield, a thread yield example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - thread_yield_init(); - - return 0; -} -#endif diff --git a/examples/kernel/timer_control.c b/examples/kernel/timer_control.c deleted file mode 100644 index 9fcb0d4c4d..0000000000 --- a/examples/kernel/timer_control.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 程序清单:动态定时器例程 - * - * 这个例程会创建1个动态周期型定时器对象,然后控制它进行定时时间长度的更改。 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 定时器的控制块 */ -static rt_timer_t timer1; -static rt_uint8_t count; - -/* 定时器超时函数 */ -static void timeout1(void* parameter) -{ - rt_tick_t timeout = 50; - - rt_kprintf("periodic timer is timeout\n"); - - count ++; - /* 停止定时器自身 */ - if (count >= 8) - { - /* 控制定时器然后更改超时时间长度 */ - rt_timer_control(timer1, RT_TIMER_CTRL_SET_TIME, (void *)&timeout); - count = 0; - } -} - -void timer_control_init() -{ - /* 创建定时器1 */ - timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */ - timeout1, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ - RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ - /* 启动定时器 */ - if (timer1 != RT_NULL) - rt_timer_start(timer1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除定时器对象 */ - rt_timer_delete(timer1); - timer1 = RT_NULL; - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_timer_control() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - - /* 执行定时器例程 */ - count = 0; - timer_control_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_timer_control, a timer control example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - timer_control_init(); - - return 0; -} -#endif diff --git a/examples/kernel/timer_dynamic.c b/examples/kernel/timer_dynamic.c deleted file mode 100644 index 1260d50c09..0000000000 --- a/examples/kernel/timer_dynamic.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 程序清单:动态定时器例程 - * - * 这个例程会创建两个动态定时器对象,一个是单次定时,一个是周期性的定时 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 定时器的控制块 */ -static rt_timer_t timer1; -static rt_timer_t timer2; - -/* 定时器1超时函数 */ -static void timeout1(void* parameter) -{ - rt_kprintf("periodic timer is timeout\n"); -} - -/* 定时器2超时函数 */ -static void timeout2(void* parameter) -{ - rt_kprintf("one shot timer is timeout\n"); -} - -void timer_create_init() -{ - /* 创建定时器1 */ - timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */ - timeout1, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ - RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ - /* 启动定时器 */ - if (timer1 != RT_NULL) - rt_timer_start(timer1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - /* 创建定时器2 */ - timer2 = rt_timer_create("timer2", /* 定时器名字是 timer2 */ - timeout2, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 30, /* 定时长度为30个OS Tick */ - RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */ - - /* 启动定时器 */ - if (timer2 != RT_NULL) - rt_timer_start(timer2); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除定时器对象 */ - rt_timer_delete(timer1); - rt_timer_delete(timer2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_timer_create() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - - /* 执行定时器例程 */ - timer_create_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_timer_create, a dynamic timer example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - timer_create_init(); - - return 0; -} -#endif diff --git a/examples/kernel/timer_static.c b/examples/kernel/timer_static.c deleted file mode 100644 index 884927bbc3..0000000000 --- a/examples/kernel/timer_static.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 程序清单:定时器例程 - * - * 这个程序会初始化2个静态定时器,一个是单次定时,一个是周期性的定时 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 定时器的控制块 */ -static struct rt_timer timer1; -static struct rt_timer timer2; - -/* 定时器1超时函数 */ -static void timeout1(void* parameter) -{ - rt_kprintf("periodic timer is timeout\n"); -} - -/* 定时器2超时函数 */ -static void timeout2(void* parameter) -{ - rt_kprintf("one shot timer is timeout\n"); -} - -void timer_static_init() -{ - /* 初始化定时器 */ - rt_timer_init(&timer1, "timer1", /* 定时器名字是 timer1 */ - timeout1, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ - RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ - rt_timer_init(&timer2, "timer2", /* 定时器名字是 timer2 */ - timeout2, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 30, /* 定时长度为30个OS Tick */ - RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */ - - /* 启动定时器 */ - rt_timer_start(&timer1); - rt_timer_start(&timer2); -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 执行定时器脱离 */ - rt_timer_detach(&timer1); - rt_timer_detach(&timer2); - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_timer_static() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - - /* 执行定时器例程 */ - timer_static_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_timer_static, a static timer example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - timer_static_init(); - - return 0; -} -#endif diff --git a/examples/kernel/timer_stop_self.c b/examples/kernel/timer_stop_self.c deleted file mode 100644 index 38ec9c441b..0000000000 --- a/examples/kernel/timer_stop_self.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 程序清单:动态定时器例程 - * - * 这个例程会创建1个动态周期型定时器对象 - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* 定时器的控制块 */ -static rt_timer_t timer1; -static rt_uint8_t count; - -/* 定时器超时函数 */ -static void timeout1(void* parameter) -{ - rt_kprintf("periodic timer is timeout\n"); - - count ++; - /* 停止定时器自身 */ - if (count >= 8) - { - /* 停止定时器 */ - rt_timer_stop(timer1); - count = 0; - } -} - -void timer_stop_self_init() -{ - /* 创建定时器1 */ - timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */ - timeout1, /* 超时时回调的处理函数 */ - RT_NULL, /* 超时函数的入口参数 */ - 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ - RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ - /* 启动定时器 */ - if (timer1 != RT_NULL) - rt_timer_start(timer1); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */ - rt_enter_critical(); - - /* 删除定时器对象 */ - rt_timer_delete(timer1); - timer1 = RT_NULL; - - /* 调度器解锁 */ - rt_exit_critical(); - - /* 设置TestCase状态 */ - tc_done(TC_STAT_PASSED); -} - -int _tc_timer_stop_self() -{ - /* 设置TestCase清理回调函数 */ - tc_cleanup(_tc_cleanup); - - /* 执行定时器例程 */ - count = 0; - timer_stop_self_init(); - - /* 返回TestCase运行的最长时间 */ - return 100; -} -/* 输出函数命令到finsh shell中 */ -FINSH_FUNCTION_EXPORT(_tc_timer_stop_self, a dynamic timer example); -#else -/* 用户应用入口 */ -int rt_application_init() -{ - timer_stop_self_init(); - - return 0; -} -#endif diff --git a/examples/kernel/timer_timeout.c b/examples/kernel/timer_timeout.c deleted file mode 100644 index d1a7099e2e..0000000000 --- a/examples/kernel/timer_timeout.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * �����嵥����Ϣ�������� - * - * �������ᴴ��3����̬�̣߳�һ���̻߳����Ϣ��������ȡ��Ϣ��һ���̻߳ᶨʱ���� - * Ϣ���з�����Ϣ��һ���̻߳ᶨʱ����Ϣ���з��ͽ�����Ϣ�� - */ -#include <rtthread.h> -#include "tc_comm.h" - -/* ָ���߳̿��ƿ��ָ�� */ -static rt_thread_t tid = RT_NULL; - -/* ��Ϣ���п��ƿ� */ -static struct rt_messagequeue mq; -/* ��Ϣ�������õ��ķ�����Ϣ���ڴ�� */ -static char msg_pool[2048]; - -/* ��ʱ���Ŀ��ƿ� */ -static struct rt_timer timer; -static rt_uint16_t no = 0; -static void timer_timeout(void* parameter) -{ - char buf[32]; - rt_uint32_t length; - - length = rt_snprintf(buf, sizeof(buf), "message %d", no++); - rt_mq_send(&mq, &buf[0], length); -} - -/* �߳���ں��� */ -static void thread_entry(void* parameter) -{ - char buf[64]; - rt_err_t result; - - /* ��ʼ����ʱ�� */ - rt_timer_init(&timer, "timer", /* ��ʱ�������� timer1 */ - timer_timeout, /* ��ʱʱ�ص��Ĵ������� */ - RT_NULL, /* ��ʱ��������ڲ��� */ - 1, /* ��ʱ���ȣ���OS TickΪ��λ����1��OS Tick */ - RT_TIMER_FLAG_PERIODIC); /* �����Զ�ʱ�� */ - - while (1) - { - rt_memset(&buf[0], 0, sizeof(buf)); - - /* ����Ϣ�����н�����Ϣ */ - result = rt_mq_recv(&mq, &buf[0], sizeof(buf), 1); - if (result == RT_EOK) - { - rt_kprintf("recv msg: %s\n", buf); - } - else if (result == -RT_ETIMEOUT) - { - rt_kprintf("recv msg timeout\n"); - } - } -} - -int timer_timeout_init() -{ - /* ��ʼ����Ϣ���� */ - rt_mq_init(&mq, "mqt", - &msg_pool[0], /* �ڴ��ָ��msg_pool */ - 128 - sizeof(void*), /* ÿ����Ϣ�Ĵ�С�� 128 - void* */ - sizeof(msg_pool), /* �ڴ�صĴ�С��msg_pool�Ĵ�С */ - RT_IPC_FLAG_FIFO); /* ����ж���̵߳ȴ������������ȵõ��ķ���������Ϣ */ - - /* �����߳� */ - tid = rt_thread_create("t", - thread_entry, RT_NULL, /* �߳������thread_entry, ��ڲ�����RT_NULL */ - THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); - if (tid != RT_NULL) - rt_thread_startup(tid); - else - tc_stat(TC_STAT_END | TC_STAT_FAILED); - - return 0; -} - -#ifdef RT_USING_TC -static void _tc_cleanup() -{ - /* �����������������������л��������̣߳�����Ӧ�ж� */ - rt_enter_critical(); - - /* ɾ���߳� */ - if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE) - rt_thread_delete(tid); - - /* ִ����Ϣ���ж������� */ - rt_mq_detach(&mq); - /* ִ�ж�ʱ������ */ - rt_timer_detach(&timer); - - /* ���������� */ - rt_exit_critical(); - - /* ����TestCase״̬ */ - tc_done(TC_STAT_PASSED); -} - -int _tc_timer_timeout() -{ - /* ����TestCase�����ص����� */ - tc_cleanup(_tc_cleanup); - timer_timeout_init(); - - /* ����TestCase���е��ʱ�� */ - return 100; -} -/* ����������finsh shell�� */ -FINSH_FUNCTION_EXPORT(_tc_timer_timeout, a thread timer testcase); -#else -/* �û�Ӧ����� */ -int rt_application_init() -{ - timer_timeout_init(); - - return 0; -} -#endif diff --git a/examples/libc/dirent.c b/examples/libc/dirent.c index 75604f6067..03fa94151d 100644 --- a/examples/libc/dirent.c +++ b/examples/libc/dirent.c @@ -1,8 +1,11 @@ /* - * dirent.c + * Copyright (c) 2006-2021, RT-Thread Development Team * - * Created on: 2010-11-17 - * Author: bernard + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-11-17 Bernard first version */ #include <stdio.h> #include <stdlib.h> @@ -11,46 +14,46 @@ #include <dirent.h> int libc_dirent() { - DIR * dirp; - long int save3 = 0; - long int cur; - int i = 0; - int result = 0; - struct dirent *dp; + DIR * dirp; + long int save3 = 0; + long int cur; + int i = 0; + int result = 0; + struct dirent *dp; - dirp = opendir("/"); - for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) - { - /* save position 3 (after fourth entry) */ - if (i++ == 3) - save3 = telldir(dirp); + dirp = opendir("/"); + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) + { + /* save position 3 (after fourth entry) */ + if (i++ == 3) + save3 = telldir(dirp); - printf("%s\n", dp->d_name); + printf("%s\n", dp->d_name); - /* stop at 400 (just to make sure dirp->__offset and dirp->__size are - scrambled */ - if (i == 400) - break; - } + /* stop at 400 (just to make sure dirp->__offset and dirp->__size are + scrambled */ + if (i == 400) + break; + } - printf("going back past 4-th entry...\n"); + printf("going back past 4-th entry...\n"); - /* go back to saved entry */ - seekdir(dirp, save3); + /* go back to saved entry */ + seekdir(dirp, save3); - /* Check whether telldir equals to save3 now. */ - cur = telldir(dirp); - if (cur != save3) - { - printf("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur); - result = 1; - } + /* Check whether telldir equals to save3 now. */ + cur = telldir(dirp); + if (cur != save3) + { + printf("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur); + result = 1; + } - /* print remaining files (3-last) */ - for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) - printf("%s\n", dp->d_name); + /* print remaining files (3-last) */ + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) + printf("%s\n", dp->d_name); - closedir(dirp); - return result; + closedir(dirp); + return result; } FINSH_FUNCTION_EXPORT(libc_dirent, dirent test for libc); diff --git a/examples/libc/env.c b/examples/libc/env.c index ca67ac2e2a..05005c2d1f 100644 --- a/examples/libc/env.c +++ b/examples/libc/env.c @@ -1,18 +1,22 @@ /* - * env.c + * Copyright (c) 2006-2021, RT-Thread Development Team * - * Created on: 2010-11-17 - * Author: bernard + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-11-17 Bernard first version */ + #include <stdio.h> #include <stdlib.h> #include <finsh.h> int libc_env() { - printf("PATH=%s\n", getenv("PATH")); - putenv("foo=bar"); - printf("foo=%s\n", getenv("foo")); - return 0; + printf("PATH=%s\n", getenv("PATH")); + putenv("foo=bar"); + printf("foo=%s\n", getenv("foo")); + return 0; } FINSH_FUNCTION_EXPORT(libc_env, get/set_env test); diff --git a/examples/libc/ex1.c b/examples/libc/ex1.c index 2acbfc3a39..8f0ccfff1c 100644 --- a/examples/libc/ex1.c +++ b/examples/libc/ex1.c @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ /* Creates two threads, one printing 10000 "a"s, the other printing 10000 "b"s. Illustrates: thread creation, thread joining. */ @@ -9,29 +17,29 @@ static void *process(void * arg) { - int i; - printf("Starting process %s\n", (char *)arg); - for (i = 0; i < 10000; i++) - write(1, (char *) arg, 1); - return NULL; + int i; + printf("Starting process %s\n", (char *)arg); + for (i = 0; i < 10000; i++) + write(1, (char *) arg, 1); + return NULL; } #define sucfail(r) (r != 0 ? "failed" : "succeeded") int libc_ex1(void) { - int pret, ret = 0; - pthread_t th_a, th_b; - void *retval; + int pret, ret = 0; + pthread_t th_a, th_b; + void *retval; - ret += (pret = pthread_create(&th_a, NULL, process, (void *)"a")); - printf("create a %s %d\n", sucfail(pret), pret); - ret += (pret = pthread_create(&th_b, NULL, process, (void *)"b")); - printf("create b %s %d\n", sucfail(pret), pret); - ret += (pret = pthread_join(th_a, &retval)); - printf("join a %s %d\n", sucfail(pret), pret); - ret += (pret = pthread_join(th_b, &retval)); - printf("join b %s %d\n", sucfail(pret), pret); - return ret; + ret += (pret = pthread_create(&th_a, NULL, process, (void *)"a")); + printf("create a %s %d\n", sucfail(pret), pret); + ret += (pret = pthread_create(&th_b, NULL, process, (void *)"b")); + printf("create b %s %d\n", sucfail(pret), pret); + ret += (pret = pthread_join(th_a, &retval)); + printf("join a %s %d\n", sucfail(pret), pret); + ret += (pret = pthread_join(th_b, &retval)); + printf("join b %s %d\n", sucfail(pret), pret); + return ret; } #include <finsh.h> FINSH_FUNCTION_EXPORT(libc_ex1, example 1 for libc); diff --git a/examples/libc/ex2.c b/examples/libc/ex2.c index 925f4e1f23..df8f9a26a3 100644 --- a/examples/libc/ex2.c +++ b/examples/libc/ex2.c @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ /* The classic producer-consumer example. Illustrates mutexes and conditions. All integers between 0 and 9999 should be printed exactly twice, diff --git a/examples/libc/ex3.c b/examples/libc/ex3.c index e4e3405d20..615ed8f35c 100644 --- a/examples/libc/ex3.c +++ b/examples/libc/ex3.c @@ -1,7 +1,15 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ /* Multi-thread searching. Illustrates: thread cancellation, cleanup handlers. */ -#include <errno.h> +#include <sys/errno.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> diff --git a/examples/libc/ex4.c b/examples/libc/ex4.c index eb79840372..ec1c533a98 100644 --- a/examples/libc/ex4.c +++ b/examples/libc/ex4.c @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ /* Making a library function that uses static variables thread-safe. Illustrates: thread-specific data, pthread_once(). */ diff --git a/examples/libc/ex5.c b/examples/libc/ex5.c index aa94c34063..cce5306894 100644 --- a/examples/libc/ex5.c +++ b/examples/libc/ex5.c @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ /* The classic producer-consumer example, implemented with semaphores. All integers between 0 and 9999 should be printed exactly twice, once to the right of the arrow and once to the left. */ diff --git a/examples/libc/ex6.c b/examples/libc/ex6.c index dea6ead8cb..ba687aa46f 100644 --- a/examples/libc/ex6.c +++ b/examples/libc/ex6.c @@ -1,4 +1,12 @@ -#include <errno.h> +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#include <sys/errno.h> #include <stdio.h> #include <string.h> #include <pthread.h> @@ -7,31 +15,31 @@ #define usleep rt_thread_sleep static void *test_thread(void *v_param) { - return NULL; + return NULL; } int libc_ex6(void) { - unsigned long count; + unsigned long count; - setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); - for (count = 0; count < 2000; ++count) { - pthread_t thread; - int status; + for (count = 0; count < 2000; ++count) { + pthread_t thread; + int status; - status = pthread_create(&thread, NULL, test_thread, NULL); - if (status != 0) { - printf("status = %d, count = %lu: %s\n", status, count, strerror( - errno)); - return 1; - } else { - printf("count = %lu\n", count); - } - /* pthread_detach (thread); */ - pthread_join(thread, NULL); - usleep(10); - } - return 0; + status = pthread_create(&thread, NULL, test_thread, NULL); + if (status != 0) { + printf("status = %d, count = %lu: %s\n", status, count, strerror( + errno)); + return 1; + } else { + printf("count = %lu\n", count); + } + /* pthread_detach (thread); */ + pthread_join(thread, NULL); + usleep(10); + } + return 0; } #include <finsh.h> FINSH_FUNCTION_EXPORT(libc_ex6, example 6 for libc); diff --git a/examples/libc/ex7.c b/examples/libc/ex7.c index 859d18e7bd..d1f05dbdcd 100644 --- a/examples/libc/ex7.c +++ b/examples/libc/ex7.c @@ -1,9 +1,17 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ /* ex7 * * Test case that illustrates a timed wait on a condition variable. */ -#include <errno.h> +#include <sys/errno.h> #include <stdio.h> #include <string.h> #include <pthread.h> @@ -14,88 +22,88 @@ /* Our event variable using a condition variable contruct. */ typedef struct { - pthread_mutex_t mutex; - pthread_cond_t cond; - int flag; + pthread_mutex_t mutex; + pthread_cond_t cond; + int flag; } event_t; /* Global event to signal main thread the timeout of the child thread. */ event_t main_event; static void *test_thread(void *ms_param) { - int status = 0; - event_t foo; - struct timespec time; - struct timeval now; - long ms = (long) ms_param; + int status = 0; + event_t foo; + struct timespec time; + struct timeval now; + long ms = (long) ms_param; - /* initialize cond var */ - pthread_cond_init(&foo.cond, NULL); - pthread_mutex_init(&foo.mutex, NULL); - foo.flag = 0; + /* initialize cond var */ + pthread_cond_init(&foo.cond, NULL); + pthread_mutex_init(&foo.mutex, NULL); + foo.flag = 0; - /* set the time out value */ - printf("waiting %ld ms ...\n", ms); - gettimeofday(&now, NULL); - time.tv_sec = now.tv_sec + ms / 1000 + (now.tv_usec + (ms % 1000) * 1000) - / 1000000; - time.tv_nsec = ((now.tv_usec + (ms % 1000) * 1000) % 1000000) * 1000; + /* set the time out value */ + printf("waiting %ld ms ...\n", ms); + gettimeofday(&now, NULL); + time.tv_sec = now.tv_sec + ms / 1000 + (now.tv_usec + (ms % 1000) * 1000) + / 1000000; + time.tv_nsec = ((now.tv_usec + (ms % 1000) * 1000) % 1000000) * 1000; - /* Just use this to test the time out. The cond var is never signaled. */ - pthread_mutex_lock(&foo.mutex); - while (foo.flag == 0 && status != ETIMEDOUT) { - status = pthread_cond_timedwait(&foo.cond, &foo.mutex, &time); - } - pthread_mutex_unlock(&foo.mutex); + /* Just use this to test the time out. The cond var is never signaled. */ + pthread_mutex_lock(&foo.mutex); + while (foo.flag == 0 && status != ETIMEDOUT) { + status = pthread_cond_timedwait(&foo.cond, &foo.mutex, &time); + } + pthread_mutex_unlock(&foo.mutex); - /* post the main event */ - pthread_mutex_lock(&main_event.mutex); - main_event.flag = 1; - pthread_cond_signal(&main_event.cond); - pthread_mutex_unlock(&main_event.mutex); + /* post the main event */ + pthread_mutex_lock(&main_event.mutex); + main_event.flag = 1; + pthread_cond_signal(&main_event.cond); + pthread_mutex_unlock(&main_event.mutex); - /* that's it, bye */ - return (void*) status; + /* that's it, bye */ + return (void*) status; } int libc_ex7(void) { - unsigned long count; + unsigned long count; - setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); - /* initialize main event cond var */ - pthread_cond_init(&main_event.cond, NULL); - pthread_mutex_init(&main_event.mutex, NULL); - main_event.flag = 0; + /* initialize main event cond var */ + pthread_cond_init(&main_event.cond, NULL); + pthread_mutex_init(&main_event.mutex, NULL); + main_event.flag = 0; - for (count = 0; count < 20; ++count) { - pthread_t thread; - int status; + for (count = 0; count < 20; ++count) { + pthread_t thread; + int status; - /* pass down the milli-second timeout in the void* param */ - status = pthread_create(&thread, NULL, test_thread, (void*) (count - * 100)); - if (status != 0) { - printf("status = %d, count = %lu: %s\n", status, count, strerror( - errno)); - return 1; - } else { + /* pass down the milli-second timeout in the void* param */ + status = pthread_create(&thread, NULL, test_thread, (void*) (count + * 100)); + if (status != 0) { + printf("status = %d, count = %lu: %s\n", status, count, strerror( + errno)); + return 1; + } else { - /* wait for the event posted by the child thread */ - pthread_mutex_lock(&main_event.mutex); - while (main_event.flag == 0) { - pthread_cond_wait(&main_event.cond, &main_event.mutex); - } - main_event.flag = 0; - pthread_mutex_unlock(&main_event.mutex); + /* wait for the event posted by the child thread */ + pthread_mutex_lock(&main_event.mutex); + while (main_event.flag == 0) { + pthread_cond_wait(&main_event.cond, &main_event.mutex); + } + main_event.flag = 0; + pthread_mutex_unlock(&main_event.mutex); - printf("count = %lu\n", count); - } + printf("count = %lu\n", count); + } - usleep(10); - } + usleep(10); + } - return 0; + return 0; } #include <finsh.h> FINSH_FUNCTION_EXPORT(libc_ex7, example 7 for libc); diff --git a/examples/libc/file.c b/examples/libc/file.c index f366e04702..878d3a98d7 100644 --- a/examples/libc/file.c +++ b/examples/libc/file.c @@ -1,516 +1,520 @@ /* - * fstat.c + * Copyright (c) 2006-2021, RT-Thread Development Team * - * Created on: 2010-11-17 - * Author: bernard + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-11-17 Bernard first version */ + #include <stdio.h> #include <stdlib.h> #include <finsh.h> -#include <errno.h> +#include <sys/errno.h> #include <sys/fcntl.h> #include <sys/stat.h> const char* text = "this is a test string\n"; void libc_fstat() { - int fd; - struct stat s; + int fd; + struct stat s; - fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0); - if (fd < 0) - { - printf("open failed\n"); - return; - } + fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0); + if (fd < 0) + { + printf("open failed\n"); + return; + } - write(fd, text, strlen(text) + 1); - printf("begin: %d\n", lseek(fd, 0, SEEK_SET)); - printf("end: %d\n", lseek(fd, 0, SEEK_END)); + write(fd, text, strlen(text) + 1); + printf("begin: %d\n", lseek(fd, 0, SEEK_SET)); + printf("end: %d\n", lseek(fd, 0, SEEK_END)); - printf("fstat result: %d\n", fstat(fd, &s)); - close(fd); + printf("fstat result: %d\n", fstat(fd, &s)); + close(fd); } FINSH_FUNCTION_EXPORT(libc_fstat, fstat test for libc); void libc_lseek() { - int fd; + int fd; - fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0); - if (fd < 0) - { - printf("open failed\n"); - return; - } + fd = open("/tmp/tt.txt", O_WRONLY | O_CREAT, 0); + if (fd < 0) + { + printf("open failed\n"); + return; + } - write(fd, text, strlen(text) + 1); - printf("begin: %d\n", lseek(fd, 0, SEEK_SET)); - printf("end: %d\n", lseek(fd, 0, SEEK_END)); - close(fd); + write(fd, text, strlen(text) + 1); + printf("begin: %d\n", lseek(fd, 0, SEEK_SET)); + printf("end: %d\n", lseek(fd, 0, SEEK_END)); + close(fd); } FINSH_FUNCTION_EXPORT(libc_lseek, lseek test for libc); void sleep(int tick) { - rt_thread_sleep(tick); + rt_thread_sleep(tick); } int libc_fseek(void) { - const char *tmpdir; - char *fname; - int fd; - FILE *fp; - const char outstr[] = "hello world!\n"; - char strbuf[sizeof outstr]; - char buf[200]; - struct stat st1; - struct stat st2; - int result = 0; + const char *tmpdir; + char *fname; + int fd; + FILE *fp; + const char outstr[] = "hello world!\n"; + char strbuf[sizeof outstr]; + char buf[200]; + struct stat st1; + struct stat st2; + int result = 0; - tmpdir = getenv("TMPDIR"); - if (tmpdir == NULL || tmpdir[0] == '\0') - tmpdir = "/tmp"; + tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL || tmpdir[0] == '\0') + tmpdir = "/tmp"; - asprintf(&fname, "%s/tst-fseek.XXXXXX", tmpdir); - if (fname == NULL) - { - fprintf(stderr, "cannot generate name for temporary file: %s\n", - strerror(errno)); - return 1; - } + asprintf(&fname, "%s/tst-fseek.XXXXXX", tmpdir); + if (fname == NULL) + { + fprintf(stderr, "cannot generate name for temporary file: %s\n", + strerror(errno)); + return 1; + } - /* Create a temporary file. */ - fd = mkstemp(fname); - if (fd == -1) - { - fprintf(stderr, "cannot open temporary file: %s\n", strerror(errno)); - return 1; - } + /* Create a temporary file. */ + fd = mkstemp(fname); + if (fd == -1) + { + fprintf(stderr, "cannot open temporary file: %s\n", strerror(errno)); + return 1; + } - fp = fdopen(fd, "w+"); - if (fp == NULL) - { - fprintf(stderr, "cannot get FILE for temporary file: %s\n", strerror( - errno)); - return 1; - } - setbuffer(fp, strbuf, sizeof(outstr) - 1); + fp = fdopen(fd, "w+"); + if (fp == NULL) + { + fprintf(stderr, "cannot get FILE for temporary file: %s\n", strerror( + errno)); + return 1; + } + setbuffer(fp, strbuf, sizeof(outstr) - 1); - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error\n", __LINE__); - result = 1; - goto out; - } + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error\n", __LINE__); + result = 1; + goto out; + } - /* The EOF flag must be reset. */ - if (fgetc(fp) != EOF) - { - printf("%d: managed to read at end of file\n", __LINE__); - result = 1; - } - else if (!feof(fp)) - { - printf("%d: EOF flag not set\n", __LINE__); - result = 1; - } - if (fseek(fp, 0, SEEK_CUR) != 0) - { - printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__); - result = 1; - } - else if (feof(fp)) - { - printf("%d: fseek() didn't reset EOF flag\n", __LINE__); - result = 1; - } + /* The EOF flag must be reset. */ + if (fgetc(fp) != EOF) + { + printf("%d: managed to read at end of file\n", __LINE__); + result = 1; + } + else if (!feof(fp)) + { + printf("%d: EOF flag not set\n", __LINE__); + result = 1; + } + if (fseek(fp, 0, SEEK_CUR) != 0) + { + printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__); + result = 1; + } + else if (feof(fp)) + { + printf("%d: fseek() didn't reset EOF flag\n", __LINE__); + result = 1; + } - /* Do the same for fseeko(). */ - if (fgetc(fp) != EOF) - { - printf("%d: managed to read at end of file\n", __LINE__); - result = 1; - } - else if (!feof(fp)) - { - printf("%d: EOF flag not set\n", __LINE__); - result = 1; - } - if (fseeko(fp, 0, SEEK_CUR) != 0) - { - printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__); - result = 1; - } - else if (feof(fp)) - { - printf("%d: fseek() didn't reset EOF flag\n", __LINE__); - result = 1; - } + /* Do the same for fseeko(). */ + if (fgetc(fp) != EOF) + { + printf("%d: managed to read at end of file\n", __LINE__); + result = 1; + } + else if (!feof(fp)) + { + printf("%d: EOF flag not set\n", __LINE__); + result = 1; + } + if (fseeko(fp, 0, SEEK_CUR) != 0) + { + printf("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__); + result = 1; + } + else if (feof(fp)) + { + printf("%d: fseek() didn't reset EOF flag\n", __LINE__); + result = 1; + } - /* Go back to the beginning of the file: absolute. */ - if (fseek(fp, 0, SEEK_SET) != 0) - { - printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - int pos = lseek(fd, 0, SEEK_CUR); - printf("%d: lseek() returned different position, pos %d\n", __LINE__, - pos); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } + /* Go back to the beginning of the file: absolute. */ + if (fseek(fp, 0, SEEK_SET) != 0) + { + printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + int pos = lseek(fd, 0, SEEK_CUR); + printf("%d: lseek() returned different position, pos %d\n", __LINE__, + pos); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } - /* Now with fseeko. */ - if (fseeko(fp, 0, SEEK_SET) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } + /* Now with fseeko. */ + if (fseeko(fp, 0, SEEK_SET) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } - /* Go back to the beginning of the file: relative. */ - if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0) - { - printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } + /* Go back to the beginning of the file: relative. */ + if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0) + { + printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } - /* Now with fseeko. */ - if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } + /* Now with fseeko. */ + if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_CUR) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } - /* Go back to the beginning of the file: from the end. */ - if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0) - { - printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } + /* Go back to the beginning of the file: from the end. */ + if (fseek(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0) + { + printf("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } - /* Now with fseeko. */ - if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); - result = 1; - } - else if (fflush(fp) != 0) - { - printf("%d: fflush() failed\n", __LINE__); - result = 1; - } - else if (lseek(fd, 0, SEEK_CUR) != 0) - { - printf("%d: lseek() returned different position\n", __LINE__); - result = 1; - } - else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: fread() failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) - { - printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); - result = 1; - } + /* Now with fseeko. */ + if (fseeko(fp, -((int) sizeof(outstr) - 1), SEEK_END) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__); + result = 1; + } + else if (fflush(fp) != 0) + { + printf("%d: fflush() failed\n", __LINE__); + result = 1; + } + else if (lseek(fd, 0, SEEK_CUR) != 0) + { + printf("%d: lseek() returned different position\n", __LINE__); + result = 1; + } + else if (fread(buf, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: fread() failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0) + { + printf("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__); + result = 1; + } - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error 2\n", __LINE__); - result = 1; - goto out; - } + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error 2\n", __LINE__); + result = 1; + goto out; + } - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error 3\n", __LINE__); - result = 1; - goto out; - } + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error 3\n", __LINE__); + result = 1; + goto out; + } - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error 4\n", __LINE__); - result = 1; - goto out; - } + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error 4\n", __LINE__); + result = 1; + goto out; + } - if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) - { - printf("%d: write error 5\n", __LINE__); - result = 1; - goto out; - } + if (fwrite(outstr, sizeof(outstr) - 1, 1, fp) != 1) + { + printf("%d: write error 5\n", __LINE__); + result = 1; + goto out; + } - if (fputc('1', fp) == EOF || fputc('2', fp) == EOF) - { - printf("%d: cannot add characters at the end\n", __LINE__); - result = 1; - goto out; - } + if (fputc('1', fp) == EOF || fputc('2', fp) == EOF) + { + printf("%d: cannot add characters at the end\n", __LINE__); + result = 1; + goto out; + } - /* Check the access time. */ - if (fstat(fd, &st1) < 0) - { - printf("%d: fstat64() before fseeko() failed\n\n", __LINE__); - result = 1; - } - else - { - sleep(1); + /* Check the access time. */ + if (fstat(fd, &st1) < 0) + { + printf("%d: fstat64() before fseeko() failed\n\n", __LINE__); + result = 1; + } + else + { + sleep(1); - if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_CUR) != 0) - { - printf("%d: fseek() after write characters failed\n", __LINE__); - result = 1; - goto out; - } - else - { + if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_CUR) != 0) + { + printf("%d: fseek() after write characters failed\n", __LINE__); + result = 1; + goto out; + } + else + { - time_t t; - /* Make sure the timestamp actually can be different. */ - sleep(1); - t = time(NULL); + time_t t; + /* Make sure the timestamp actually can be different. */ + sleep(1); + t = time(NULL); - if (fstat(fd, &st2) < 0) - { - printf("%d: fstat64() after fseeko() failed\n\n", __LINE__); - result = 1; - } - if (st1.st_ctime >= t) - { - printf("%d: st_ctime not updated\n", __LINE__); - result = 1; - } - if (st1.st_mtime >= t) - { - printf("%d: st_mtime not updated\n", __LINE__); - result = 1; - } - if (st1.st_ctime >= st2.st_ctime) - { - printf("%d: st_ctime not changed\n", __LINE__); - result = 1; - } - if (st1.st_mtime >= st2.st_mtime) - { - printf("%d: st_mtime not changed\n", __LINE__); - result = 1; - } - } - } + if (fstat(fd, &st2) < 0) + { + printf("%d: fstat64() after fseeko() failed\n\n", __LINE__); + result = 1; + } + if (st1.st_ctime >= t) + { + printf("%d: st_ctime not updated\n", __LINE__); + result = 1; + } + if (st1.st_mtime >= t) + { + printf("%d: st_mtime not updated\n", __LINE__); + result = 1; + } + if (st1.st_ctime >= st2.st_ctime) + { + printf("%d: st_ctime not changed\n", __LINE__); + result = 1; + } + if (st1.st_mtime >= st2.st_mtime) + { + printf("%d: st_mtime not changed\n", __LINE__); + result = 1; + } + } + } - if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2 - * (sizeof(outstr) - 1)) - { - printf("%d: reading 2 records plus bits failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp( - &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2 - * (sizeof(outstr) - 1)] != '1' || buf[2 * (sizeof(outstr) - 1) + 1] - != '2') - { - printf("%d: reading records failed\n", __LINE__); - result = 1; - } - else if (ungetc('9', fp) == EOF) - { - printf("%d: ungetc() failed\n", __LINE__); - result = 1; - } - else if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_END) != 0) - { - printf("%d: fseek after ungetc failed\n", __LINE__); - result = 1; - } - else if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2 - * (sizeof(outstr) - 1)) - { - printf("%d: reading 2 records plus bits failed\n", __LINE__); - result = 1; - } - else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp( - &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2 - * (sizeof(outstr) - 1)] != '1') - { - printf("%d: reading records for the second time failed\n", __LINE__); - result = 1; - } - else if (buf[2 * (sizeof(outstr) - 1) + 1] == '9') - { - printf("%d: unget character not ignored\n", __LINE__); - result = 1; - } - else if (buf[2 * (sizeof(outstr) - 1) + 1] != '2') - { - printf("%d: unget somehow changed character\n", __LINE__); - result = 1; - } + if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2 + * (sizeof(outstr) - 1)) + { + printf("%d: reading 2 records plus bits failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp( + &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2 + * (sizeof(outstr) - 1)] != '1' || buf[2 * (sizeof(outstr) - 1) + 1] + != '2') + { + printf("%d: reading records failed\n", __LINE__); + result = 1; + } + else if (ungetc('9', fp) == EOF) + { + printf("%d: ungetc() failed\n", __LINE__); + result = 1; + } + else if (fseek(fp, -(2 + 2 * (sizeof(outstr) - 1)), SEEK_END) != 0) + { + printf("%d: fseek after ungetc failed\n", __LINE__); + result = 1; + } + else if (fread(buf, 1, 2 + 2 * (sizeof(outstr) - 1), fp) != 2 + 2 + * (sizeof(outstr) - 1)) + { + printf("%d: reading 2 records plus bits failed\n", __LINE__); + result = 1; + } + else if (memcmp(buf, outstr, sizeof(outstr) - 1) != 0 || memcmp( + &buf[sizeof(outstr) - 1], outstr, sizeof(outstr) - 1) != 0 || buf[2 + * (sizeof(outstr) - 1)] != '1') + { + printf("%d: reading records for the second time failed\n", __LINE__); + result = 1; + } + else if (buf[2 * (sizeof(outstr) - 1) + 1] == '9') + { + printf("%d: unget character not ignored\n", __LINE__); + result = 1; + } + else if (buf[2 * (sizeof(outstr) - 1) + 1] != '2') + { + printf("%d: unget somehow changed character\n", __LINE__); + result = 1; + } - fclose(fp); + fclose(fp); - fp = fopen(fname, "r"); - if (fp == NULL) - { - printf("%d: fopen() failed\n\n", __LINE__); - result = 1; - } - else if (fstat(fileno(fp), &st1) < 0) - { - printf("%d: fstat64() before fseeko() failed\n\n", __LINE__); - result = 1; - } - else if (fseeko(fp, 0, SEEK_END) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__); - result = 1; - } - else if (ftello(fp) != st1.st_size) - { - printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__, - (size_t) st1.st_size, (size_t) ftello(fp)); - result = 1; - } - else - printf("%d: SEEK_END works\n", __LINE__); - if (fp != NULL) - fclose(fp); + fp = fopen(fname, "r"); + if (fp == NULL) + { + printf("%d: fopen() failed\n\n", __LINE__); + result = 1; + } + else if (fstat(fileno(fp), &st1) < 0) + { + printf("%d: fstat64() before fseeko() failed\n\n", __LINE__); + result = 1; + } + else if (fseeko(fp, 0, SEEK_END) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__); + result = 1; + } + else if (ftello(fp) != st1.st_size) + { + printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__, + (size_t) st1.st_size, (size_t) ftello(fp)); + result = 1; + } + else + printf("%d: SEEK_END works\n", __LINE__); + if (fp != NULL) + fclose(fp); - fp = fopen(fname, "r"); - if (fp == NULL) - { - printf("%d: fopen() failed\n\n", __LINE__); - result = 1; - } - else if (fstat(fileno(fp), &st1) < 0) - { - printf("%d: fstat64() before fgetc() failed\n\n", __LINE__); - result = 1; - } - else if (fgetc(fp) == EOF) - { - printf("%d: fgetc() before fseeko() failed\n\n", __LINE__); - result = 1; - } - else if (fseeko(fp, 0, SEEK_END) != 0) - { - printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__); - result = 1; - } - else if (ftello(fp) != st1.st_size) - { - printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__, - (size_t) st1.st_size, (size_t) ftello(fp)); - result = 1; - } - else - printf("%d: SEEK_END works\n", __LINE__); - if (fp != NULL) - fclose(fp); + fp = fopen(fname, "r"); + if (fp == NULL) + { + printf("%d: fopen() failed\n\n", __LINE__); + result = 1; + } + else if (fstat(fileno(fp), &st1) < 0) + { + printf("%d: fstat64() before fgetc() failed\n\n", __LINE__); + result = 1; + } + else if (fgetc(fp) == EOF) + { + printf("%d: fgetc() before fseeko() failed\n\n", __LINE__); + result = 1; + } + else if (fseeko(fp, 0, SEEK_END) != 0) + { + printf("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__); + result = 1; + } + else if (ftello(fp) != st1.st_size) + { + printf("%d: fstat64 st_size %zd ftello %zd\n", __LINE__, + (size_t) st1.st_size, (size_t) ftello(fp)); + result = 1; + } + else + printf("%d: SEEK_END works\n", __LINE__); + if (fp != NULL) + fclose(fp); - out: unlink(fname); + out: unlink(fname); - return result; + return result; } FINSH_FUNCTION_EXPORT(libc_fseek, lseek test for libc); diff --git a/examples/libc/memory.c b/examples/libc/memory.c index ee524fa43d..4a31b69017 100644 --- a/examples/libc/memory.c +++ b/examples/libc/memory.c @@ -1,56 +1,60 @@ /* - * memory.c + * Copyright (c) 2006-2021, RT-Thread Development Team * - * Created on: 2010-11-17 - * Author: bernard + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-11-17 Bernard first version */ + #include <stdio.h> #include <stdlib.h> #include <finsh.h> -#include <errno.h> +#include <sys/errno.h> static int errors = 0; static void merror(const char *msg) { - ++errors; - printf("Error: %s\n", msg); + ++errors; + printf("Error: %s\n", msg); } int libc_mem(void) { - void *p; - int save; + void *p; + int save; - errno = 0; + errno = 0; - p = malloc(-1); - save = errno; + p = malloc(-1); + save = errno; - if (p != NULL) - merror("malloc (-1) succeeded."); + if (p != NULL) + merror("malloc (-1) succeeded."); - if (p == NULL && save != ENOMEM) - merror("errno is not set correctly"); + if (p == NULL && save != ENOMEM) + merror("errno is not set correctly"); - p = malloc(10); - if (p == NULL) - merror("malloc (10) failed."); + p = malloc(10); + if (p == NULL) + merror("malloc (10) failed."); - /* realloc (p, 0) == free (p). */ - p = realloc(p, 0); - if (p != NULL) - merror("realloc (p, 0) failed."); + /* realloc (p, 0) == free (p). */ + p = realloc(p, 0); + if (p != NULL) + merror("realloc (p, 0) failed."); - p = malloc(0); - if (p == NULL) - { - printf("malloc(0) returns NULL\n"); - } + p = malloc(0); + if (p == NULL) + { + printf("malloc(0) returns NULL\n"); + } - p = realloc(p, 0); - if (p != NULL) - merror("realloc (p, 0) failed."); + p = realloc(p, 0); + if (p != NULL) + merror("realloc (p, 0) failed."); - return errors != 0; + return errors != 0; } FINSH_FUNCTION_EXPORT(libc_mem, memory test for libc); diff --git a/examples/libc/mq.c b/examples/libc/mq.c index 3163e27975..a7f3f924dc 100644 --- a/examples/libc/mq.c +++ b/examples/libc/mq.c @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-11-17 Bernard first version + */ + #include <stdio.h> #include <fcntl.h> #include <stdlib.h> @@ -7,113 +17,113 @@ #define MQ_NAME_1 "testmsg1" #define MQ_NAME_2 "testmsg2" -#define MSG_SIZE 128 -#define MAX_MSG 3 +#define MSG_SIZE 128 +#define MAX_MSG 3 const char *s_msg_ptr[] = {"msg test 1", "msg test 2", "msg test 3"}; char r_msg_ptr_1[MAX_MSG][MSG_SIZE]; char r_msg_ptr_2[MAX_MSG][MSG_SIZE]; pthread_t send1, send2, rev1, rev2; -int * send_1(void * mq) +int * send_1(void * mq) { - int i; - mqd_t mq1 = *(mqd_t *)mq; + int i; + mqd_t mq1 = *(mqd_t *)mq; - printf("Enter into send_1 \n"); - for (i = 0; i < MAX_MSG; i++ ) { - if ( -1 == mq_send(mq1, s_msg_ptr[i], MSG_SIZE, i)) { - perror("mq_send doesn't return success \n"); - pthread_exit((void *)1); - } - printf("[%d] send '%s' in thread send_1. \n", i+1, s_msg_ptr[i]); - } - pthread_exit((void *)0); + printf("Enter into send_1 \n"); + for (i = 0; i < MAX_MSG; i++ ) { + if ( -1 == mq_send(mq1, s_msg_ptr[i], MSG_SIZE, i)) { + perror("mq_send doesn't return success \n"); + pthread_exit((void *)1); + } + printf("[%d] send '%s' in thread send_1. \n", i+1, s_msg_ptr[i]); + } + pthread_exit((void *)0); } -int * send_2(void * mq) +int * send_2(void * mq) { - int i; - mqd_t mq2 = *(mqd_t *)mq; + int i; + mqd_t mq2 = *(mqd_t *)mq; - printf("Enter into send_2 \n"); - for (i = 0; i < MAX_MSG; i++ ) { - if ( -1 == mq_send(mq2, s_msg_ptr[i], MSG_SIZE, i)) { - perror("mq_send doesn't return success \n"); - pthread_exit((void *)1); - } - printf("[%d] send '%s' in thread send_2. \n", i+1, s_msg_ptr[i]); - } - pthread_exit((void *)0); + printf("Enter into send_2 \n"); + for (i = 0; i < MAX_MSG; i++ ) { + if ( -1 == mq_send(mq2, s_msg_ptr[i], MSG_SIZE, i)) { + perror("mq_send doesn't return success \n"); + pthread_exit((void *)1); + } + printf("[%d] send '%s' in thread send_2. \n", i+1, s_msg_ptr[i]); + } + pthread_exit((void *)0); } -int * receive_1(void * mq) +int * receive_1(void * mq) { - int i; - mqd_t mq1 = *(mqd_t *)mq; + int i; + mqd_t mq1 = *(mqd_t *)mq; - printf("Enter into receive_1 \n"); - for (i = 0; i< MAX_MSG; i++) { - if ( -1 == mq_receive(mq1, r_msg_ptr_1[i], MSG_SIZE, NULL) ) { - perror("mq_receive doesn't return success \n"); - pthread_exit((void *)1); - } - printf("[%d] receive '%s' in thread receive_1. \n", i+1, r_msg_ptr_1[i]); - } - pthread_exit((void *)0); + printf("Enter into receive_1 \n"); + for (i = 0; i< MAX_MSG; i++) { + if ( -1 == mq_receive(mq1, r_msg_ptr_1[i], MSG_SIZE, NULL) ) { + perror("mq_receive doesn't return success \n"); + pthread_exit((void *)1); + } + printf("[%d] receive '%s' in thread receive_1. \n", i+1, r_msg_ptr_1[i]); + } + pthread_exit((void *)0); } -int * receive_2(void * mq) +int * receive_2(void * mq) { - int i; - mqd_t mq2 = *(mqd_t *)mq; + int i; + mqd_t mq2 = *(mqd_t *)mq; - printf("Enter into receive_2 \n"); - for (i = 0; i< MAX_MSG; i++) { - if ( -1 == mq_receive(mq2, r_msg_ptr_2[i], MSG_SIZE, NULL) ) { - perror("mq_receive doesn't return success \n"); - pthread_exit((void *)1); - } - printf("[%d] receive '%s' in thread receive_2. \n", i+1, r_msg_ptr_2[i]); - } - pthread_exit((void *)0); + printf("Enter into receive_2 \n"); + for (i = 0; i< MAX_MSG; i++) { + if ( -1 == mq_receive(mq2, r_msg_ptr_2[i], MSG_SIZE, NULL) ) { + perror("mq_receive doesn't return success \n"); + pthread_exit((void *)1); + } + printf("[%d] receive '%s' in thread receive_2. \n", i+1, r_msg_ptr_2[i]); + } + pthread_exit((void *)0); } int libc_mq() { - mqd_t mq1 = 0, mq2 = 0; - struct mq_attr mqstat; - int oflag = O_CREAT|O_RDWR; + mqd_t mq1 = 0, mq2 = 0; + struct mq_attr mqstat; + int oflag = O_CREAT|O_RDWR; + + memset(&mqstat, 0, sizeof(mqstat)); + mqstat.mq_maxmsg = MAX_MSG; + mqstat.mq_msgsize = MSG_SIZE; + mqstat.mq_flags = 0; + + if( ((mqd_t) -1) == (mq1 = mq_open(MQ_NAME_1,oflag,0777, &mqstat)) ) { + printf("mq_open doesn't return success \n"); + return -1; + } + if( ((mqd_t) -1) == (mq2 = mq_open(MQ_NAME_2,oflag,0777, &mqstat)) ) { + printf("mq_open doesn't return success \n"); + return -1; + } + pthread_create(&send1, NULL, (void *)send_1, (void *)&mq1); + pthread_create(&send2, NULL, (void *)send_2, (void *)&mq2); + pthread_create(&rev1, NULL, (void *)receive_1, (void *)&mq1); + pthread_create(&rev2, NULL, (void *)receive_2, (void *)&mq2); + pthread_join(send1, NULL); + pthread_join(send2, NULL); + pthread_join(rev1, NULL); + pthread_join(rev2, NULL); - memset(&mqstat, 0, sizeof(mqstat)); - mqstat.mq_maxmsg = MAX_MSG; - mqstat.mq_msgsize = MSG_SIZE; - mqstat.mq_flags = 0; - - if( ((mqd_t) -1) == (mq1 = mq_open(MQ_NAME_1,oflag,0777, &mqstat)) ) { - printf("mq_open doesn't return success \n"); - return -1; - } - if( ((mqd_t) -1) == (mq2 = mq_open(MQ_NAME_2,oflag,0777, &mqstat)) ) { - printf("mq_open doesn't return success \n"); - return -1; - } - pthread_create(&send1, NULL, (void *)send_1, (void *)&mq1); - pthread_create(&send2, NULL, (void *)send_2, (void *)&mq2); - pthread_create(&rev1, NULL, (void *)receive_1, (void *)&mq1); - pthread_create(&rev2, NULL, (void *)receive_2, (void *)&mq2); - pthread_join(send1, NULL); - pthread_join(send2, NULL); - pthread_join(rev1, NULL); - pthread_join(rev2, NULL); - - mq_close(mq1); - mq_close(mq2); - mq_unlink(MQ_NAME_1); - mq_unlink(MQ_NAME_2); + mq_close(mq1); + mq_close(mq2); + mq_unlink(MQ_NAME_1); + mq_unlink(MQ_NAME_2); - printf("PASSED\n"); - return 0; + printf("PASSED\n"); + return 0; } #include <finsh.h> FINSH_FUNCTION_EXPORT(libc_mq, posix mqueue test); diff --git a/examples/libc/printf.c b/examples/libc/printf.c index 2d2d8a7763..c7968b9a0b 100644 --- a/examples/libc/printf.c +++ b/examples/libc/printf.c @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-11-17 Bernard first version + */ + #include <stdio.h> #include <stdlib.h> #include <sys/fcntl.h> @@ -142,59 +152,59 @@ int printf_test() int i; printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n", - snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf), - buf); + snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf), + buf); memset(buf2,0,sizeof(buf)); i=snprintf(buf2, 256, "%.9999u", 10); printf("%i %i\n",i,strlen(buf2)); printf ("snprintf (\"%%.999999u\", 10) == %d\n", - snprintf(buf2, sizeof(buf2), "%.999999u", 10)); + snprintf(buf2, sizeof(buf2), "%.999999u", 10)); } return 0; } void libc_printf() { - printf("stdout test!!\n"); - fprintf(stdout, "fprintf test!!\n"); - fprintf(stderr, "fprintf test!!\n"); - puts("puts test!!\n"); + printf("stdout test!!\n"); + fprintf(stdout, "fprintf test!!\n"); + fprintf(stderr, "fprintf test!!\n"); + puts("puts test!!\n"); - putc('1', stderr); - putc('2', stderr); - putc('\n', stderr); + putc('1', stderr); + putc('2', stderr); + putc('\n', stderr); - printf_test(); + printf_test(); } FINSH_FUNCTION_EXPORT(libc_printf, printf test in libc); void libc_dprintf() { - int fd; + int fd; - fd = open("/dev/console", O_WRONLY, 0); - if (fd >0) - { - dprintf(fd, "fd:%d printf test!!\n", fd); - close(fd); - } + fd = open("/dev/console", O_WRONLY, 0); + if (fd >0) + { + dprintf(fd, "fd:%d printf test!!\n", fd); + close(fd); + } } FINSH_FUNCTION_EXPORT(libc_dprintf, dprintf test); void libc_fdopen() { - int fd; - FILE* fp; + int fd; + FILE* fp; - fd = open("/dev/console", O_WRONLY, 0); - if (fd >0) - { - fp = fdopen(fd, "w"); - fprintf(fp, "fdopen test, fd %d!!\n", fileno(fp)); - fclose(fp); - } + fd = open("/dev/console", O_WRONLY, 0); + if (fd >0) + { + fp = fdopen(fd, "w"); + fprintf(fp, "fdopen test, fd %d!!\n", fileno(fp)); + fclose(fp); + } } FINSH_FUNCTION_EXPORT(libc_fdopen, fdopen test); diff --git a/examples/libc/rand.c b/examples/libc/rand.c index 8f52ad28bb..96f5628bb8 100644 --- a/examples/libc/rand.c +++ b/examples/libc/rand.c @@ -1,43 +1,47 @@ /* - * rand.c + * Copyright (c) 2006-2021, RT-Thread Development Team * - * Created on: 2010-11-17 - * Author: bernard + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-11-17 Bernard first version */ + #include <stdio.h> #include <stdlib.h> #include <finsh.h> int libc_rand(void) { - int i1, i2; - int j1, j2; + int i1, i2; + int j1, j2; - /* The C standard says that "If rand is called before any calls to - srand have been made, the same sequence shall be generated as - when srand is first called with a seed value of 1." */ - i1 = rand(); - i2 = rand(); - srand(1); - j1 = rand(); - j2 = rand(); - if (i1 < 0 || i2 < 0 || j1 < 0 || j2 < 0) - { - puts("Test FAILED!"); - } - if (j1 == i1 && j2 == i2) - { - puts("Test succeeded."); - return 0; - } - else - { - if (j1 != i1) - printf("%d != %d\n", j1, i1); - if (j2 != i2) - printf("%d != %d\n", j2, i2); - puts("Test FAILED!"); - return 1; - } + /* The C standard says that "If rand is called before any calls to + srand have been made, the same sequence shall be generated as + when srand is first called with a seed value of 1." */ + i1 = rand(); + i2 = rand(); + srand(1); + j1 = rand(); + j2 = rand(); + if (i1 < 0 || i2 < 0 || j1 < 0 || j2 < 0) + { + puts("Test FAILED!"); + } + if (j1 == i1 && j2 == i2) + { + puts("Test succeeded."); + return 0; + } + else + { + if (j1 != i1) + printf("%d != %d\n", j1, i1); + if (j2 != i2) + printf("%d != %d\n", j2, i2); + puts("Test FAILED!"); + return 1; + } } FINSH_FUNCTION_EXPORT(libc_rand, rand test for libc); diff --git a/examples/libc/sem.c b/examples/libc/sem.c index d081d246e9..55b85114b8 100644 --- a/examples/libc/sem.c +++ b/examples/libc/sem.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #include <pthread.h> #include <semaphore.h> #include <stdio.h> @@ -5,61 +14,61 @@ static sem_t sema; static void* other_thread() { - printf("other_thread here!\n"); + printf("other_thread here!\n"); + + sleep(1); - sleep(1); + while (1) + { + printf("other_thread: sem_post...\n"); + if(sem_post(&sema) == -1) + printf("sem_post failed\n"); + sleep(1); + } - while (1) - { - printf("other_thread: sem_post...\n"); - if(sem_post(&sema) == -1) - printf("sem_post failed\n"); - sleep(1); - } - - printf("other_thread dies!\n"); - pthread_exit(0); + printf("other_thread dies!\n"); + pthread_exit(0); } static void test_thread(void* parameter) { - pthread_t tid; + pthread_t tid; + + printf("main thread here!\n"); + printf("sleep 5 seconds..."); + sleep(5); + printf("done\n"); - printf("main thread here!\n"); - printf("sleep 5 seconds..."); - sleep(5); - printf("done\n"); + sem_init(&sema, 0, 0); - sem_init(&sema, 0, 0); - - /* create the "other" thread */ - if(pthread_create(&tid, 0, &other_thread, 0)!=0) - /* error */ - printf("pthread_create OtherThread failed.\n"); - else - printf("created OtherThread=%x\n", tid); + /* create the "other" thread */ + if(pthread_create(&tid, 0, &other_thread, 0)!=0) + /* error */ + printf("pthread_create OtherThread failed.\n"); + else + printf("created OtherThread=%x\n", tid); - /* let the other thread run */ - while (1) - { - printf("Main: sem_wait...\n"); - if(sem_wait(&sema) == -1) - printf("sem_wait failed\n"); - printf("Main back.\n\n"); - } + /* let the other thread run */ + while (1) + { + printf("Main: sem_wait...\n"); + if(sem_wait(&sema) == -1) + printf("sem_wait failed\n"); + printf("Main back.\n\n"); + } - pthread_exit(0); + pthread_exit(0); } #include <finsh.h> void libc_sem() { - rt_thread_t tid; + rt_thread_t tid; - tid = rt_thread_create("semtest", test_thread, RT_NULL, - 2048, 20, 5); - if (tid != RT_NULL) - { - rt_thread_startup(tid); - } + tid = rt_thread_create("semtest", test_thread, RT_NULL, + 2048, 20, 5); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } } FINSH_FUNCTION_EXPORT(libc_sem, posix semaphore test); diff --git a/examples/libc/termios_test.c b/examples/libc/termios_test.c index 192021b9ab..520fca6380 100644 --- a/examples/libc/termios_test.c +++ b/examples/libc/termios_test.c @@ -1,8 +1,11 @@ /* - * termios_test.c + * Copyright (c) 2006-2021, RT-Thread Development Team * - * Created on: 2017-12-06 - * Author: JasonJia + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-12-06 JasonJia first version */ #include <rtthread.h> @@ -11,18 +14,6 @@ #include <string.h> #include <sys/time.h> -#if defined (RT_USING_POSIX) - #include <dfs_posix.h> - #include <dfs_select.h> - #if defined (RT_USING_POSIX_TERMIOS) - #include <termios.h> - #else - #error "TERMIOS need RT_USING_POSIX_TERMIOS" - #endif -#else - #error "POSIX poll/select need RT_USING_POSIX" -#endif - #define JOINT(x,y) x##y #define B(x) JOINT(B,x) #define Default_baud_rate 115200 @@ -353,8 +344,8 @@ int termios_test(int argc, char **argv) #ifdef RT_USING_FINSH #include <finsh.h> - #ifdef FINSH_USING_MSH + #ifdef RT_USING_FINSH MSH_CMD_EXPORT_ALIAS(termios_test, termtest, e.g: termtest /dev/uart4 115200); - #endif /* FINSH_USING_MSH */ + #endif /* RT_USING_FINSH */ #endif /* RT_USING_FINSH */ diff --git a/examples/libc/time.c b/examples/libc/time.c index fa6dee74c8..5e91c1df80 100644 --- a/examples/libc/time.c +++ b/examples/libc/time.c @@ -1,8 +1,11 @@ /* - * time.c + * Copyright (c) 2006-2021, RT-Thread Development Team * - * Created on: 2010-11-17 - * Author: bernard + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-11-17 Bernard first version */ #include <stdio.h> @@ -11,14 +14,14 @@ int speed() { - int i; - time_t t; + int i; + time_t t; - printf("%d\n", time(0)); - for (i = 0; i < 10000000; ++i) - t = time(0); + printf("%d\n", time(0)); + for (i = 0; i < 10000000; ++i) + t = time(0); - printf("%d\n", time(0)); - return 0; + printf("%d\n", time(0)); + return 0; } FINSH_FUNCTION_EXPORT(speed, speed test); diff --git a/examples/network/chargen.c b/examples/network/chargen.c index 218449b845..69a6b13a5d 100644 --- a/examples/network/chargen.c +++ b/examples/network/chargen.c @@ -1,9 +1,22 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #include <rtthread.h> #include <sys/socket.h> #ifdef SAL_USING_POSIX #include <sys/select.h> // only dfs_net -#include <dfs_posix.h> +#include <dfs_file.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/statfs.h> #else #define read lwip_read #define write lwip_write diff --git a/examples/network/tcpclient.c b/examples/network/tcpclient.c index cc67645868..97ea690b6e 100644 --- a/examples/network/tcpclient.c +++ b/examples/network/tcpclient.c @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-01-24 ChungHsuan improve code comments + */ + #include <rtthread.h> #include <string.h> @@ -7,7 +17,7 @@ #include <sys/time.h> #include <sys/select.h> #endif -#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */ +#include <sys/socket.h> /* socket.h header file is needed when using BSD socket */ /* 使用BSD socket,需要包含socket.h头文件 */ #include "netdb.h" #define DEBUG_TCP_CLIENT @@ -26,8 +36,11 @@ static int started = 0; static int is_running = 0; static char url[256]; static int port = 8080; -static const char send_data[] = "This is TCP Client from RT-Thread."; /* 发送用到的数据 */ +static const char send_data[] = "This is TCP Client from RT-Thread."; /* The message be sent */ /* 发送用到的数据 */ +/** +* @brief This function is for creating a tcp client on RT-Thread +*/ static void tcpclient(void *arg) { int ret; @@ -39,7 +52,7 @@ static void tcpclient(void *arg) struct timeval timeout; fd_set readset; - + /* Get host address by parameter url(Domain name resolution if input domain) */ /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ host = gethostbyname(url); if (host == RT_NULL) @@ -47,7 +60,7 @@ static void tcpclient(void *arg) LOG_E("Get host by name failed!"); return; } - + /* Allocate space for recv_data */ /* 分配用于存放接收数据的缓冲 */ recv_data = rt_malloc(BUFSZ); if (recv_data == RT_NULL) @@ -55,24 +68,26 @@ static void tcpclient(void *arg) LOG_E("No memory"); return; } - + /* Create a socket and set it to SOCK_STREAM(TCP) */ /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + /* Failed on creatinf socket */ /* 创建socket失败 */ LOG_E("Create socket error"); goto __exit; } - + /* Initialize server side address */ /* 初始化预连接的服务端地址 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr = *((struct in_addr *)host->h_addr); rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); - + /* Connect to server */ /* 连接到服务端 */ if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { + /*Failed on connecting to server*/ /* 连接失败 */ LOG_E("Connect fail!"); goto __exit; @@ -92,49 +107,56 @@ static void tcpclient(void *arg) /* Wait for read */ if (select(sock + 1, &readset, RT_NULL, RT_NULL, &timeout) == 0) continue; - + /* Receive the maximum size 1024 bytes from socket */ /* 从sock连接中接收最大BUFSZ - 1字节数据 */ bytes_received = recv(sock, recv_data, BUFSZ - 1, 0); if (bytes_received < 0) { + /* Receive failed and close the connection */ /* 接收失败,关闭这个连接 */ LOG_E("Received error, close the socket."); goto __exit; } else if (bytes_received == 0) { + /* Print warning message when recv function return 0 */ /* 打印recv函数返回值为0的警告信息 */ LOG_W("Received warning, recv function return 0."); continue; } else { + /* Receive data sucessfully and append '\0' at the end of message */ /* 有接收到数据,把末端清零 */ recv_data[bytes_received] = '\0'; if (rt_strcmp(recv_data, "q") == 0 || rt_strcmp(recv_data, "Q") == 0) { + /* If the first letter is 'q' or 'Q', close the connection */ /* 如果是首字母是q或Q,关闭这个连接 */ LOG_I("Got a 'q' or 'Q', close the socket."); goto __exit; } else { + /* Show the message in terminal */ /* 在控制终端显示收到的数据 */ LOG_D("Received data = %s", recv_data); } } - + /* Send message to connected socket */ /* 发送数据到sock连接 */ ret = send(sock, send_data, rt_strlen(send_data), 0); if (ret < 0) { + /* Send failed, close the connection */ /* 发送失败,关闭这个连接 */ LOG_I("send error, close the socket."); goto __exit; } else if (ret == 0) { + /* Print warning message when send function return 0 */ /* 打印send函数返回值为0的警告信息 */ LOG_W("Send warning, send function return 0."); } @@ -156,6 +178,9 @@ __exit: return; } +/** +* @brief The usage description of tcp client on rt-Thread +*/ static void usage(void) { rt_kprintf("Usage: tcpclient -h <host> -p <port>\n"); @@ -169,6 +194,9 @@ static void usage(void) rt_kprintf(" --help Print help information\n"); } +/** +* @brief This function is for testing tcp client on rt-Thread +*/ static void tcpclient_test(int argc, char** argv) { rt_thread_t tid; diff --git a/examples/network/tcpsendpacket.c b/examples/network/tcpsendpacket.c index 47bb562506..da8bc4f524 100644 --- a/examples/network/tcpsendpacket.c +++ b/examples/network/tcpsendpacket.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #include <rtthread.h> #include <netdb.h> /* 为了解析主机名,需要包含netdb.h头文件 */ @@ -26,9 +35,9 @@ void tcp_senddata(const char *url, int port, int length) { /* 申请内存失败 */ rt_kprintf("No memory\n"); - return; + return; } - + /* 构造发送数据 */ for (index = 0; index < length; index ++) buffer_ptr[index] = index & 0xff; diff --git a/examples/network/tcpserver.c b/examples/network/tcpserver.c index 8c7382dcbb..ff89595c15 100644 --- a/examples/network/tcpserver.c +++ b/examples/network/tcpserver.c @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-01-24 ChungHsuan improve code comments + */ + #include <rtthread.h> #include <string.h> @@ -7,7 +17,7 @@ #include <sys/time.h> #include <sys/select.h> #endif -#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */ +#include <sys/socket.h> /* socket.h header file is needed when using BSD socket */ /* 使用BSD socket,需要包含socket.h头文件 */ #include "netdb.h" #define DEBUG_TCP_SERVER @@ -25,12 +35,15 @@ static int started = 0; static int is_running = 0; static int port = 5000; -static const char send_data[] = "This is TCP Server from RT-Thread."; /* 发送用到的数据 */ +static const char send_data[] = "This is TCP Server from RT-Thread."; /* The message be sent */ /* 发送用到的数据 */ +/** +* @brief This function is for creating a tcp server on RT-Thread +*/ static void tcpserv(void *arg) { int ret; - char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */ + char *recv_data; /* recv_data is a pointer used to receive data */ /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */ int sock, connected, bytes_received; struct sockaddr_in server_addr, client_addr; @@ -38,33 +51,33 @@ static void tcpserv(void *arg) fd_set readset, readset_c; socklen_t sin_size = sizeof(struct sockaddr_in); - recv_data = rt_malloc(BUFSZ + 1); /* 分配接收用的数据缓冲 */ + recv_data = rt_malloc(BUFSZ + 1);/* Allocate space for recv_data */ /* 分配接收用的数据缓冲 */ if (recv_data == RT_NULL) { LOG_E("No memory"); return; } - + /* Before making use of socket, socket should be created first and set the socket created to SOCK_STREAM(TCP) */ /* 一个socket在使用前,需要预先创建出来,指定SOCK_STREAM为TCP的socket */ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { LOG_E("Create socket error"); goto __exit; } - + /* Initialize server side address */ /* 初始化服务端地址 */ server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(port); /* 服务端工作的端口 */ + server_addr.sin_port = htons(port); /*Server side port number*//* 服务端工作的端口 */ server_addr.sin_addr.s_addr = INADDR_ANY; rt_memset(&(server_addr.sin_zero), 0x0, sizeof(server_addr.sin_zero)); - + /* Bind socket to server side address */ /* 绑定socket到服务端地址 */ if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { LOG_E("Unable to bind"); goto __exit; } - + /* Listen on socket */ /* 在socket上进行监听 */ if (listen(sock, 10) == -1) { @@ -90,20 +103,21 @@ static void tcpserv(void *arg) /* Wait for read or write */ if (select(sock + 1, &readset, RT_NULL, RT_NULL, &timeout) == 0) continue; - + /* Accept a request from client and the function is blocking */ /* 接受一个客户端连接socket的请求,这个函数调用是阻塞式的 */ connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); + /* Return the socket connected sucessfully */ /* 返回的是连接成功的socket */ if (connected < 0) { LOG_E("accept connection failed! errno = %d", errno); continue; } - + /* Accept the message which points by client address */ /* 接受返回的client_addr指向了客户端的地址信息 */ LOG_I("I got a connection from (%s , %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); - + /* Handle method of client connection */ /* 客户端连接的处理 */ while (is_running) { @@ -113,7 +127,7 @@ static void tcpserv(void *arg) /* Wait for read or write */ if (select(connected + 1, &readset_c, RT_NULL, RT_NULL, &timeout) == 0) continue; - + /* Receive message from connected socket. Buffer size is 1024 bytes,but it's not guranteed to receive size exactly 1024 */ /* 从connected socket中接收数据,接收buffer是1024大小,但并不一定能够收到1024大小的数据 */ bytes_received = recv(connected, recv_data, BUFSZ, 0); if (bytes_received < 0) @@ -125,16 +139,18 @@ static void tcpserv(void *arg) } else if (bytes_received == 0) { + /* Print warning message when recv function return 0 */ /* 打印recv函数返回值为0的警告信息 */ LOG_W("Received warning, recv function return 0."); continue; } else - { + { /* Receive data sucessfully and append '\0' at the end of message */ /* 有接收到数据,把末端清零 */ recv_data[bytes_received] = '\0'; if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0) { + /* If the first letter is 'q' or 'Q', close the connection */ /* 如果是首字母是q或Q,关闭这个连接 */ LOG_I("Got a 'q' or 'Q', close the connect."); closesocket(connected); @@ -143,6 +159,7 @@ static void tcpserv(void *arg) } else if (strcmp(recv_data, "exit") == 0) { + /* If the message received is 'exit', close the whole server side. */ /* 如果接收的是exit,则关闭整个服务端 */ closesocket(connected); connected = -1; @@ -150,11 +167,12 @@ static void tcpserv(void *arg) } else { + /* Show the message in terminal */ /* 在控制终端显示收到的数据 */ LOG_D("Received data = %s", recv_data); } } - + /* Send message to connected socket */ /* 发送数据到connected socket */ ret = send(connected, send_data, rt_strlen(send_data), 0); if (ret < 0) @@ -166,6 +184,7 @@ static void tcpserv(void *arg) } else if (ret == 0) { + /* Print warning message when send function return 0 */ /* 打印send函数返回值为0的警告信息 */ LOG_W("Send warning, send function return 0."); } @@ -193,6 +212,9 @@ __exit: return; } +/** +* @brief The usage description of tcp server on rt-Thread +*/ static void usage(void) { rt_kprintf("Usage: tcpserver -p <port>\n"); @@ -205,6 +227,9 @@ static void usage(void) rt_kprintf(" --help Print help information\n"); } +/** +* @brief This function is for testing tcp server on rt-Thread +*/ static void tcpserver_test(int argc, char** argv) { rt_thread_t tid; diff --git a/examples/network/udpclient.c b/examples/network/udpclient.c index f8c42f3a12..3ad27c76ff 100644 --- a/examples/network/udpclient.c +++ b/examples/network/udpclient.c @@ -1,6 +1,16 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-01-24 ChungHsuan improve code comments + */ + #include <rtthread.h> -#include <sys/socket.h> /* 使用BSD socket,需要包含sockets.h头文件 */ +#include <sys/socket.h> /* socket.h header file is needed when using BSD socket */ /* 使用BSD socket,需要包含sockets.h头文件 */ #include "netdb.h" #define DEBUG_UDP_CLIENT @@ -18,14 +28,17 @@ static int is_running = 0; static char url[256]; static int port = 8080; static int count = 10; -const char send_data[] = "This is UDP Client from RT-Thread.\n"; /* 发送用到的数据 */ +const char send_data[] = "This is UDP Client from RT-Thread.\n";/* The message be sent */ /* 发送用到的数据 */ +/** +* @brief This function is for creating a udp client on RT-Thread +*/ static void udpclient(void *arg) { int sock; struct hostent *host; struct sockaddr_in server_addr; - + /* Get host address by parameter URL (domain name resolution if input domain) */ /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ host = (struct hostent *) gethostbyname(url); if (host == RT_NULL) @@ -33,14 +46,15 @@ static void udpclient(void *arg) LOG_E("Get host by name failed!"); return; } - + /* Create a socket and set it to SOCK_DGRAM(UDP) */ /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { + /* Failed on creatinf socket */ LOG_E("Create socket error"); return; } - + /* Initialize server side address */ /* 初始化预连接的服务端地址 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); @@ -49,17 +63,18 @@ static void udpclient(void *arg) started = 1; is_running = 1; - + /* The total sending number(count) */ /* 总计发送count次数据 */ while (count && is_running) { + /* Send message to server side */ /* 发送数据到服务远端 */ sendto(sock, send_data, rt_strlen(send_data), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); - + /* Thread sllep for 1 second */ /* 线程休眠一段时间 */ rt_thread_mdelay(1000); - + /* count decrease 1 */ /* 计数值减一 */ count --; } @@ -68,7 +83,7 @@ static void udpclient(void *arg) { LOG_I("UDP client send data finished!"); } - + /* Close the socket */ /* 关闭这个socket */ if (sock >= 0) { @@ -79,6 +94,9 @@ static void udpclient(void *arg) is_running = 0; } +/** +* @brief The usage description of udp client on rt-Thread +*/ static void usage(void) { rt_kprintf("Usage: udpclient -h <host> -p <port> [--cnt] [count]\n"); @@ -93,6 +111,9 @@ static void usage(void) rt_kprintf(" --help Print help information\n"); } +/** +* @brief This function is for testing udp client on rt-Thread +*/ static void udpclient_test(int argc, char** argv) { rt_thread_t tid; diff --git a/examples/network/udpserver.c b/examples/network/udpserver.c index a249475e04..33442a72ed 100644 --- a/examples/network/udpserver.c +++ b/examples/network/udpserver.c @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-01-24 ChungHsuan improve code comments + */ + #include <rtthread.h> #include <string.h> @@ -7,7 +17,7 @@ #include <sys/time.h> #include <sys/select.h> #endif -#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */ +#include <sys/socket.h> /* socket.h header file is needed when using BSD socket */ /* 使用BSD socket,需要包含socket.h头文件 */ #include "netdb.h" #define DEBUG_UDP_SERVER @@ -26,6 +36,9 @@ static int started = 0; static int is_running = 0; static int port = 5000; +/** +* @brief This function is for creating a udp server on RT-Thread +*/ static void udpserv(void *paramemter) { int sock; @@ -36,7 +49,7 @@ static void udpserv(void *paramemter) struct timeval timeout; fd_set readset; - + /* Allocate space for recv_data */ /* 分配接收用的数据缓冲 */ recv_data = rt_malloc(BUFSZ); if (recv_data == RT_NULL) @@ -44,20 +57,20 @@ static void udpserv(void *paramemter) LOG_E("No memory"); return; } - + /* Create a socket and set it to SOCK_DGRAM(UDP) */ /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { LOG_E("Create socket error"); goto __exit; } - + /* Initialize server side address */ /* 初始化服务端地址 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr.s_addr = INADDR_ANY; rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); - + /* Bind socket to server side address */ /* 绑定socket到服务端地址 */ if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) @@ -83,7 +96,7 @@ static void udpserv(void *paramemter) /* Wait for read or write */ if (select(sock + 1, &readset, RT_NULL, RT_NULL, &timeout) == 0) continue; - + /* The maximum size received from sock is BUFSZ-1 bytes*/ /* 从sock中收取最大BUFSZ - 1字节数据 */ bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0, (struct sockaddr *)&client_addr, &addr_len); @@ -99,11 +112,11 @@ static void udpserv(void *paramemter) } else { - recv_data[bytes_read] = '\0'; /* 把末端清零 */ - + recv_data[bytes_read] = '\0'; /* Append '\0' at the end of message *//* 把末端清零 */ + /* Output received message */ /* 输出接收的数据 */ LOG_D("Received data = %s", recv_data); - + /* If the message received is 'exit', quit. */ /* 如果接收数据是exit,退出 */ if (strcmp(recv_data, "exit") == 0) { @@ -127,6 +140,9 @@ __exit: is_running = 0; } +/** +* @brief The usage description of udp server on rt-Thread +*/ static void usage(void) { rt_kprintf("Usage: udpserver -p <port>\n"); @@ -139,6 +155,9 @@ static void usage(void) rt_kprintf(" --help Print help information\n"); } +/** +* @brief This function is for testing udp server on rt-Thread +*/ static void udpserver_test(int argc, char** argv) { rt_thread_t tid; diff --git a/examples/pm/timer_app.c b/examples/pm/timer_app.c index b7ff675b39..5797693149 100644 --- a/examples/pm/timer_app.c +++ b/examples/pm/timer_app.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/examples/pm/wakeup_app.c b/examples/pm/wakeup_app.c index 0d4c42a997..230d30ac4e 100644 --- a/examples/pm/wakeup_app.c +++ b/examples/pm/wakeup_app.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -61,7 +61,7 @@ static int wakeup_app(void) { rt_thread_t tid; - wakeup_event = rt_event_create("wakup", RT_IPC_FLAG_FIFO); + wakeup_event = rt_event_create("wakup", RT_IPC_FLAG_PRIO); RT_ASSERT(wakeup_event != RT_NULL); tid = rt_thread_create("wakeup_app", wakeup_app_entry, RT_NULL, diff --git a/examples/rt-link/rtlink_dev_example.c b/examples/rt-link/rtlink_dev_example.c new file mode 100644 index 0000000000..027292769d --- /dev/null +++ b/examples/rt-link/rtlink_dev_example.c @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-19 Sherman the first version + */ + +#include <string.h> +#include <stdlib.h> + +#define DBG_TAG "example" +#define DBG_LVL DBG_LOG +#include <rtdbg.h> +#include <rtlink_dev.h> + +enum +{ + NONE_TEST = 0, + SHORT_FRAME_TEST, + LONG_FRAME_TEST +}; +static rt_uint8_t speed_test_type = NONE_TEST; + +static struct rt_link_device rtlink_dev = {0}; +#define RTLINK01 "rtlink01" +#define TEST_CONTEXT "This message is sent by RT-Link" +rt_uint8_t test_buff[1024] = {0}; + +static rt_err_t rtlink_dev_rx_ind(rt_device_t dev, rt_size_t size) +{ + RT_ASSERT(dev != RT_NULL); + LOG_I("rx_ind: dev name %s, rx size %d", dev->parent.name, size); + return RT_EOK; +} + +static rt_err_t rtlink_dev_tx_done(rt_device_t dev, void *buffer) +{ + RT_ASSERT(dev != RT_NULL); + struct rt_link_device *rtlink_dev = (struct rt_link_device *)dev; + LOG_I("tx_done: dev name %s, buffer 0x%p errno %d", dev->parent.name, buffer, rtlink_dev->service.err); + rt_free(buffer); + return RT_EOK; +} + +#ifdef RT_USING_POSIX_DEVIO +#include <dfs_file.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/statfs.h> +#include <poll.h> +#include <sys/select.h> + +#define RTLINK01_PATH "/dev/rtlink01" +int fd = -1; + +static void rtlink_fopen(int argc, char *argv[]) +{ + fd = open(RTLINK01_PATH, O_RDWR | O_NONBLOCK); + + if (fd < 0) + { + LOG_E("open rt_link failed!"); + } +} +MSH_CMD_EXPORT(rtlink_fopen, rtlink posix interface example); + +static void rtlink_fclose(int argc, char *argv[]) +{ + LOG_D("colse %d", fd); + close(fd); + fd = -1; +} +MSH_CMD_EXPORT(rtlink_fclose, rtlink posix interface example); + +static void rtlink_fread(int argc, char *argv[]) +{ + int read_len; + read_len = read(fd, test_buff, sizeof(test_buff)); + LOG_D("read len %d", read_len); + LOG_HEX("read", 8, test_buff, 32); +} +MSH_CMD_EXPORT(rtlink_fread, rtlink posix interface example); + +static void rtlink_fwrite(int argc, char *argv[]) +{ + char *data = RT_NULL; + rt_size_t length = 0; + rt_uint16_t count = 0; + rt_size_t ret = 0; + + if (argc == 1) + { + data = rt_malloc(sizeof(TEST_CONTEXT)); + if (data) + { + length = sizeof(TEST_CONTEXT) - 1; + rt_memcpy(data, TEST_CONTEXT, sizeof(TEST_CONTEXT) - 1); + ret = write(fd, data, length); + } + LOG_I("write data(0x%p) result: %d.", data, ret); + } + else if (argc >= 3) + { + if (strcmp(argv[1], "-l") == 0) + { + data = rt_malloc(atoi((const char *)argv[2])); + if (data) + { + for (count = 0; count < atoi((const char *)argv[2]); count++) + { + data[count] = (count % 93 + 33); + } + length = atoi((const char *)argv[2]); + ret = write(fd, data, length); + } + LOG_I("write data(0x%p) result: %d.", data, ret); + } + else + { + LOG_E("Invalid parameter."); + } + } +} +MSH_CMD_EXPORT(rtlink_fwrite, rtlink posix interface example); + +#define RTLINK02 "rtlink02" +#define RTLINK02_PATH "/dev/rtlink02" +static struct rt_link_device rtlink_fd = {0}; +rt_uint8_t fd_buff[1024] = {0}; + +static void listen_thread(void *param) +{ + int fd = open(RTLINK02_PATH, O_RDWR | O_NONBLOCK); + if (fd < 0) + { + LOG_E("open (%s) failed", RTLINK02); + return; + } + while (1) + { + rt_uint8_t *write_buf = RT_NULL; + int write_len = 0; + fd_set readfds, writefds; + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_SET(fd, &readfds); + FD_SET(fd, &writefds); + + int ret = select(fd + 1, &readfds, &writefds, RT_NULL, RT_NULL); + LOG_D("select ret(%d), read (%d), write (%d)", ret, readfds, writefds); + if (FD_ISSET(fd, &readfds)) + { + LOG_I("POLLIN"); + int read_len = read(fd, fd_buff, sizeof(test_buff)); + LOG_D("read len %d", read_len); + LOG_HEX("read", 8, test_buff, 32); + } + + if (FD_ISSET(fd, &writefds)) + { + LOG_I("POLLOUT"); + write_buf = rt_malloc(1024); + if (write_buf) + { + write_len = write(fd, write_buf, 1024); + LOG_D("write %d", write_len); + } + } + + rt_thread_delay(500); + } + LOG_I("fd (%s) listen thread exit", RTLINK02); +} + +static void rtlink_fselect() +{ + /* step1: register rtlink to to the device framework */ + rt_link_dev_register(&rtlink_fd, RTLINK02, + RT_DEVICE_FLAG_RDWR | + RT_DEVICE_FLAG_REMOVABLE | + RT_DEVICE_FLAG_STANDALONE, + RT_NULL); + + /* step2: Initialize the rlink device as the default configuration, */ + rt_device_t device = rt_device_find(RTLINK02); + if (device == RT_NULL) + { + LOG_E("device not find!"); + return ; + } + rt_device_init(device); + + /* step3: config rtlink device rx/tx callback, channel, send timeout */ + rt_device_set_rx_indicate(device, rtlink_dev_rx_ind); + rt_device_set_tx_complete(device, rtlink_dev_tx_done); + struct rt_link_service service; + service.service = RT_LINK_SERVICE_MNGT; + service.timeout_tx = RT_WAITING_NO; + rt_device_control(device, RT_DEVICE_CTRL_CONFIG, &service); + + rt_thread_t tid = rt_thread_create(RTLINK02, listen_thread, RT_NULL, 1024, 21, 20); + if (tid) + { + rt_thread_startup(tid); + } +} +MSH_CMD_EXPORT(rtlink_fselect, rtlink posix interface example); +#endif /* RT_USING_POSIX_DEVIO */ + +static void rtlink_dread(void) +{ + rt_size_t read_len = 0; + rt_device_t dev = rt_device_find(RTLINK01); + if (dev == RT_NULL) + { + LOG_E("dev %s not find ", RTLINK01); + return; + } + + read_len = rt_device_read(dev, 0, test_buff, sizeof(test_buff)); + + LOG_D("read len %d", read_len); + LOG_HEX("read", 8, test_buff, 32); +} +MSH_CMD_EXPORT(rtlink_dread, rtlink device interface example); + +void rt_link_speed_test(void *paremeter) +{ + int ret; + rt_uint8_t *send_buf, *data; + rt_size_t bufflen = 0; + rt_size_t sentlen = 0; + rt_size_t count = 0; + rt_tick_t tick1, tick2; + rt_size_t total = 0; + rt_uint32_t integer, decimal; + rt_device_t dev = rt_device_find(RTLINK01); + if (dev == RT_NULL) + { + LOG_E("dev %s not find!", RTLINK01); + return ; + } + + if (speed_test_type == SHORT_FRAME_TEST) + { + bufflen = 988; + } + else + { + bufflen = 3036; + } + + send_buf = rt_malloc(bufflen); + if (send_buf != RT_NULL) + { + data = send_buf; + for (count = 0; count < bufflen; count++) + { + *data++ = (count % 93 + 33); + } + } + else + { + rt_kprintf("speed of send buffer malloc failed."); + return; + } + + tick1 = rt_tick_get(); + while (speed_test_type) + { + ret = rt_device_write(dev, 0, send_buf, bufflen); + + if (ret == RT_EOK) + { + sentlen += bufflen; + } + + tick2 = rt_tick_get(); + if (tick2 - tick1 >= RT_TICK_PER_SECOND) + { + total = sentlen * RT_TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = total / 1000; + decimal = total % 1000; + LOG_I("%d.%03d0 Mbps!", integer, decimal); + sentlen = 0; + tick1 = tick2; + } + } + rt_free(send_buf); + LOG_W("speed test end, type %d", speed_test_type); +} + +void create_thead_to_test_speed(rt_uint8_t mutil_num) +{ + rt_uint8_t i = 0; + + LOG_D("Speed test type [%02d], mutil [%02d]", speed_test_type, mutil_num); + for (i = 0; i < mutil_num; i++) + { + rt_thread_t tid; + char tid_name[RT_NAME_MAX + 1] = {0}; + + rt_snprintf(tid_name, sizeof(tid_name), "lny_s%03d", i + 1); + tid = rt_thread_create(tid_name, rt_link_speed_test, RT_NULL, 1024, 20, 10); + rt_thread_startup(tid); + LOG_I("Speed test thread[%s] startup", tid_name); + } +} + +static void rtlink_dwrite(int argc, char *argv[]) +{ + char *data = RT_NULL; + rt_size_t length = 0; + rt_uint16_t count = 0; + rt_size_t ret = RT_ERROR; + + rt_device_t dev = rt_device_find(RTLINK01); + if (dev == RT_NULL) + { + LOG_E("device not find!"); + return ; + } + + if (argc == 1) + { + data = rt_malloc(sizeof(TEST_CONTEXT)); + length = sizeof(TEST_CONTEXT) - 1; + rt_memcpy(data, TEST_CONTEXT, sizeof(TEST_CONTEXT) - 1); + + ret = rt_device_write(dev, 0, data, length); + LOG_I("write data(0x%p) result: %d.", data, ret); + } + else if (argc >= 3) + { + if (strcmp(argv[1], "-l") == 0) + { + data = rt_malloc(atoi((const char *)argv[2])); + for (count = 0; count < atoi((const char *)argv[2]); count++) + { + data[count] = (count % 93 + 33); + } + length = atoi((const char *)argv[2]); + ret = rt_device_write(dev, 0, data, length); + LOG_I("write data(0x%p) result: %d.", data, ret); + } + else + { + LOG_E("Invalid parameter."); + } + } +} +MSH_CMD_EXPORT(rtlink_dwrite, rtlink device interface example); + +static void rtlink_dinit(void) +{ + /* step1: register rtlink to to the device framework */ + rt_link_dev_register(&rtlink_dev, RTLINK01, + RT_DEVICE_FLAG_RDWR | + RT_DEVICE_FLAG_REMOVABLE | + RT_DEVICE_FLAG_STANDALONE, + RT_NULL); + + /* step2: Initialize the rlink device as the default configuration, */ + rt_device_t device = rt_device_find(RTLINK01); + if (device == RT_NULL) + { + LOG_E("device not find!"); + return ; + } + rt_device_init(device); + + /* step3: config rtlink device rx/tx callback, channel, send timeout */ + rt_device_set_rx_indicate(device, rtlink_dev_rx_ind); + rt_device_set_tx_complete(device, rtlink_dev_tx_done); + struct rt_link_service service; + service.service = RT_LINK_SERVICE_SOCKET; + service.timeout_tx = RT_WAITING_FOREVER; + service.flag = RT_LINK_FLAG_ACK | RT_LINK_FLAG_CRC; + rt_device_control(device, RT_DEVICE_CTRL_CONFIG, &service); +} +MSH_CMD_EXPORT(rtlink_dinit, rtlink device interface example); + +static void rtlink_dopen() +{ + /* step4: open rtlink device, attach the service channel */ + rt_device_t device = rt_device_find(RTLINK01); + if (device == RT_NULL) + { + LOG_E("device not find!"); + return ; + } + rt_err_t ret = rt_device_open(device, RT_DEVICE_OFLAG_RDWR); + LOG_I("dev open ret %d", ret); +} +MSH_CMD_EXPORT(rtlink_dopen, rtlink device interface example); diff --git a/examples/rt-link/rtlink_example.c b/examples/rt-link/rtlink_example.c new file mode 100644 index 0000000000..77d488b786 --- /dev/null +++ b/examples/rt-link/rtlink_example.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-15 Sherman the first version + * 2021-08-04 Sherman Adapted to new version of rt-link API + */ + +#include <stdlib.h> +#include <string.h> +#include <rtthread.h> +#include <rtlink.h> + +#define DBG_ENABLE +#define DBG_TAG "rtlink_exam" +#define DBG_LVL DBG_INFO +#include <rtdbg.h> + +#define TEST_CONTEXT "This message is sent by RT-Link" + +enum +{ + NONE_TEST = 0, + SHORT_FRAME_TEST, + LONG_FRAME_TEST +}; + +void rt_link_speed_test(void *paremeter); +static rt_uint8_t speed_test_type = NONE_TEST; +static struct rt_link_service serv_socket; +static struct rt_link_service serv_wifi; + +static void send_cb(struct rt_link_service *service, void *buffer) +{ + LOG_I("send_cb: service (%d) buffer (0x%p) err(%d)", service->service, buffer, service->err); +} + +static void recv_cb(struct rt_link_service *service, void *data, rt_size_t size) +{ + LOG_I("service (%d) size (%d) data(0x%p)", service->service, size, data); + + if (size) + { + rt_free(data); + } +} + +static void rt_link_speed_test(void *paremeter) +{ + int ret; + rt_uint8_t *send_buf, *data; + rt_size_t bufflen = 0; + rt_size_t sentlen = 0; + rt_size_t count = 0; + rt_tick_t tick1, tick2; + rt_size_t total = 0; + rt_uint32_t integer, decimal; + + if (speed_test_type == SHORT_FRAME_TEST) + { + bufflen = RT_LINK_MAX_DATA_LENGTH; + } + else + { + bufflen = RT_LINK_MAX_DATA_LENGTH * RT_LINK_FRAMES_MAX; + } + + send_buf = rt_malloc(bufflen); + if (send_buf != RT_NULL) + { + data = send_buf; + for (count = 0; count < bufflen; count++) + { + *data++ = (count % 93 + 33); + } + } + else + { + rt_kprintf("speed of send buffer malloc failed."); + return; + } + + tick1 = rt_tick_get(); + while (speed_test_type) + { + ret = rt_link_send(&serv_socket, send_buf, bufflen); + if (ret > 0) + { + sentlen += ret; + } + else + { + LOG_W("send err %d", ret); + } + + tick2 = rt_tick_get(); + if (tick2 - tick1 >= RT_TICK_PER_SECOND) + { + total = sentlen * RT_TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = total / 1000; + decimal = total % 1000; + LOG_I("%d.%03d0 Mbps!", integer, decimal); + sentlen = 0; + tick1 = tick2; + } + } + rt_free(send_buf); + LOG_W("speed test end, type %d", speed_test_type); +} + +static void create_thead_to_test_speed(rt_uint8_t mutil_num) +{ + rt_uint8_t i = 0; + + LOG_D("Speed test type [%02d], mutil [%02d]", speed_test_type, mutil_num); + for (i = 0; i < mutil_num; i++) + { + rt_thread_t tid; + char tid_name[RT_NAME_MAX + 1] = {0}; + + rt_snprintf(tid_name, sizeof(tid_name), "lny_s%03d", i + 1); + tid = rt_thread_create(tid_name, rt_link_speed_test, RT_NULL, 1024, 20, 10); + if (tid) + { + rt_thread_startup(tid); + LOG_I("Speed test thread[%s] startup", tid_name); + } + } +} + +static int rtlink_exsend(int argc, char **argv) +{ + char *receive = RT_NULL; + rt_size_t length = 0; + rt_uint16_t count = 0; + + if (argc == 1) + { + receive = rt_malloc(sizeof(TEST_CONTEXT)); + rt_memcpy(receive, TEST_CONTEXT, sizeof(TEST_CONTEXT) - 1); + length = rt_link_send(&serv_socket, receive, sizeof(TEST_CONTEXT) - 1); + LOG_I("send data length: %d.", length); + rt_free(receive); + } + else if (argc >= 3) + { + if (strcmp(argv[1], "-l") == 0) + { + receive = rt_malloc(atoi((const char *)argv[2])); + for (count = 0; count < atoi((const char *)argv[2]); count++) + { + *receive++ = (count % 93 + 33); + } + length = rt_link_send(&serv_socket, receive - atoi((const char *)argv[2]), atoi((const char *)argv[2])); + rt_free(receive - atoi((const char *)argv[2])); + + LOG_I("send data length: %d.", length); + } + else if (strcmp(argv[1], "-s") == 0) + { + if (speed_test_type == NONE_TEST) + { + rt_uint8_t mutil_num = 1; + if (argc > 3) + { + mutil_num = atoi((const char *)argv[3]); + } + + if (strncmp(argv[2], "-s", rt_strlen(argv[2])) == 0) + { + speed_test_type = SHORT_FRAME_TEST; + } + else if (strncmp(argv[2], "-l", rt_strlen(argv[2])) == 0) + { + speed_test_type = LONG_FRAME_TEST; + } + create_thead_to_test_speed(mutil_num); + } + else + { + speed_test_type = NONE_TEST; + LOG_I("set NONE_TEST"); + } + } + else + { + LOG_E("Invalid parameter."); + } + } + return 0; +} +MSH_CMD_EXPORT(rtlink_exsend, rt link layer send test); + +int rtlink_exinit(void) +{ + serv_socket.service = RT_LINK_SERVICE_SOCKET; + serv_socket.timeout_tx = RT_WAITING_FOREVER; + serv_socket.flag = RT_LINK_FLAG_ACK | RT_LINK_FLAG_CRC; + serv_socket.recv_cb = recv_cb; + serv_socket.send_cb = send_cb; + rt_link_service_attach(&serv_socket); + + serv_wifi.service = RT_LINK_SERVICE_WIFI; + serv_wifi.timeout_tx = RT_WAITING_FOREVER; + serv_wifi.flag = RT_NULL; + serv_wifi.recv_cb = recv_cb; + serv_wifi.send_cb = send_cb; + rt_link_service_attach(&serv_wifi); + return RT_EOK; +} +MSH_CMD_EXPORT(rtlink_exinit, rt link example init); diff --git a/examples/test/device_test.c b/examples/test/device_test.c index d62c2168ff..f9a7591478 100644 --- a/examples/test/device_test.c +++ b/examples/test/device_test.c @@ -1,11 +1,7 @@ /* - * File : device_test.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://openlab.rt-thread.com/license/LICENSE. + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes diff --git a/examples/test/dhry.h b/examples/test/dhry.h index 8f47233802..dc42492417 100644 --- a/examples/test/dhry.h +++ b/examples/test/dhry.h @@ -3,9 +3,9 @@ * * "DHRYSTONE" Benchmark Program * ----------------------------- - * + * * Version: C, Version 2.1 - * + * * File: dhry.h (part 1 of 3) * * Date: May 25, 1988 @@ -33,12 +33,12 @@ * * Collection of Results: * Reinhold Weicker (address see above) and - * + * * Rick Richardson * PC Research. Inc. * 94 Apple Orchard Drive * Tinton Falls, NJ 07724 - * Phone: (201) 389-8963 (9-17 EST) + * Phone: (201) 389-8963 (9-17 EST) * Usenet: ...!uunet!pcrat!rick * * Please send results to Rick Richardson and/or Reinhold Weicker. @@ -91,7 +91,7 @@ * version previously distributed by Reinhold Weicker. * * At several places in the benchmark, code has been added, - * but within the measurement loop only in branches that + * but within the measurement loop only in branches that * are not executed. The intention is that optimizing compilers * should be prevented from moving code out of the measurement * loop, or from removing code altogether. Since the statements @@ -101,7 +101,7 @@ * still hold. Except for sophisticated optimizing compilers, * execution times for this version should be the same as * for previous versions. - * + * * Since it has proven difficult to subtract the time for the * measurement loop overhead in a correct way, the loop check * has been made a part of the benchmark. This does have @@ -151,7 +151,7 @@ * -DTIME * The "times" function of UNIX (returning process times) * or the "time" function (returning wallclock time) - * is used for measurement. + * is used for measurement. * For single user machines, "time ()" is adequate. For * multi-user machines where you cannot get single-user * access, use the "times ()" function. If you have @@ -198,23 +198,23 @@ * different from the Ada version.] * * The following program contains statements of a high level programming - * language (here: C) in a distribution considered representative: + * language (here: C) in a distribution considered representative: * * assignments 52 (51.0 %) * control statements 33 (32.4 %) * procedure, function calls 17 (16.7 %) * * 103 statements are dynamically executed. The program is balanced with - * respect to the three aspects: + * respect to the three aspects: * * - statement type * - operand type * - operand locality - * operand global, local, parameter, or constant. + * operand global, local, parameter, or constant. * - * The combination of these three aspects is balanced only approximately. + * The combination of these three aspects is balanced only approximately. * - * 1. Statement Type: + * 1. Statement Type: * ----------------- number * * V1 = V2 9 @@ -258,9 +258,9 @@ * library procedure 1 * X = F (...) * function call 6 - * user function 5 - * library function 1 - * -- + * user function 5 + * library function 1 + * -- * 17 17 * --- * 103 @@ -274,10 +274,10 @@ * number approximate * percentage * - * Arithmetic 32 50.8 + * Arithmetic 32 50.8 * - * + 21 33.3 - * - 7 11.1 + * + 21 33.3 + * - 7 11.1 * * 3 4.8 * / (int div) 1 1.6 * @@ -295,7 +295,7 @@ * && (AND-THEN) 1 1.6 * | (OR) 1 1.6 * ! (NOT) 2 3.2 - * + * * -- ----- * 63 100.1 * @@ -315,10 +315,10 @@ * 242 100.0 % * * When there is an access path leading to the final operand (e.g. a record - * component), only the final data type on the access path is counted. + * component), only the final data type on the access path is counted. * * - * 4. Operand Locality: + * 4. Operand Locality: * ------------------- * number approximate * percentage @@ -375,7 +375,7 @@ /* for strcpy, strcmp */ #include <rtthread.h> -#define Null 0 +#define Null 0 /* Value of a Null pointer */ #define true 1 #define false 0 @@ -388,7 +388,7 @@ typedef char Str_30 [31]; typedef int Arr_1_Dim [50]; typedef int Arr_2_Dim [50] [50]; -typedef struct record +typedef struct record { struct record *Ptr_Comp; Enumeration Discr; diff --git a/examples/test/dhry_1.c b/examples/test/dhry_1.c index b45b9ddafa..44283649f6 100644 --- a/examples/test/dhry_1.c +++ b/examples/test/dhry_1.c @@ -3,9 +3,9 @@ * * "DHRYSTONE" Benchmark Program * ----------------------------- - * + * * Version: C, Version 2.1 - * + * * File: dhry_1.c (part 2 of 3) * * Date: May 25, 1988 @@ -14,8 +14,8 @@ * **************************************************************************** */ - -#define NUMBER_OF_RUNS 1000000 + +#define NUMBER_OF_RUNS 1000000 #include "dhry.h" #define printf rt_kprintf @@ -34,7 +34,7 @@ int Arr_2_Glob [50] [50]; Enumeration Func_1 (); /* forward declaration necessary since Enumeration may not simply be int */ - + #ifndef REG Boolean Reg = false; #define REG @@ -71,7 +71,7 @@ void dhry_test(void) REG int Number_Of_Runs; /* Initializations */ - + Next_Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type)); Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type)); @@ -79,7 +79,7 @@ void dhry_test(void) Ptr_Glob->Discr = Ident_1; Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; Ptr_Glob->variant.var_1.Int_Comp = 40; - rt_strncpy (Ptr_Glob->variant.var_1.Str_Comp, + rt_strncpy (Ptr_Glob->variant.var_1.Str_Comp, "DHRYSTONE PROGRAM, SOME STRING", sizeof(Ptr_Glob->variant.var_1.Str_Comp)); rt_strncpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING", sizeof(Str_1_Loc)); @@ -114,9 +114,9 @@ void dhry_test(void) /***************/ /* Start timer */ /***************/ - + // Add your timer initializing code here - + Begin_Time = rt_tick_get(); /* get start tick */ for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) @@ -169,8 +169,8 @@ void dhry_test(void) /* Stop timer */ /**************/ - End_Time = rt_tick_get(); // Get end tick - + End_Time = rt_tick_get(); // Get end tick + printf ("Execution ends\n"); printf ("\n"); printf ("Final values of the variables used in the benchmark:\n"); @@ -226,7 +226,7 @@ void dhry_test(void) User_Time = (End_Time - Begin_Time) / RT_TICK_PER_SECOND; - Microseconds = (float) User_Time * Mic_secs_Per_Second + Microseconds = (float) User_Time * Mic_secs_Per_Second / (float) Number_Of_Runs; Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time; @@ -237,7 +237,7 @@ void dhry_test(void) printf ("Dhrystones MIPS: "); printf ("%6d \n", (int)(Dhrystones_Per_Second / 1757.0)); printf ("\n"); - + } Proc_1 (Ptr_Val_Par) @@ -246,27 +246,27 @@ Proc_1 (Ptr_Val_Par) REG Rec_Pointer Ptr_Val_Par; /* executed once */ { - REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp; + REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp; /* == Ptr_Glob_Next */ /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */ /* corresponds to "rename" in Ada, "with" in Pascal */ - - structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); + + structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); Ptr_Val_Par->variant.var_1.Int_Comp = 5; - Next_Record->variant.var_1.Int_Comp + Next_Record->variant.var_1.Int_Comp = Ptr_Val_Par->variant.var_1.Int_Comp; Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp; Proc_3 (&Next_Record->Ptr_Comp); - /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp + /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp == Ptr_Glob->Ptr_Comp */ if (Next_Record->Discr == Ident_1) /* then, executed */ { Next_Record->variant.var_1.Int_Comp = 6; - Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, + Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, &Next_Record->variant.var_1.Enum_Comp); Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp; - Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, + Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, &Next_Record->variant.var_1.Int_Comp); } else /* not executed */ @@ -281,7 +281,7 @@ Proc_2 (Int_Par_Ref) One_Fifty *Int_Par_Ref; { - One_Fifty Int_Loc; + One_Fifty Int_Loc; Enumeration Enum_Loc; Int_Loc = *Int_Par_Ref + 10; diff --git a/examples/test/dhry_2.c b/examples/test/dhry_2.c index 63a3d3ea03..ac5be3baf4 100644 --- a/examples/test/dhry_2.c +++ b/examples/test/dhry_2.c @@ -3,9 +3,9 @@ * * "DHRYSTONE" Benchmark Program * ----------------------------- - * + * * Version: C, Version 2.1 - * + * * File: dhry_2.c (part 3 of 3) * * Date: May 25, 1988 @@ -41,10 +41,10 @@ Enumeration *Enum_Ref_Par; *Enum_Ref_Par = Ident_4; switch (Enum_Val_Par) { - case Ident_1: + case Ident_1: *Enum_Ref_Par = Ident_1; break; - case Ident_2: + case Ident_2: if (Int_Glob > 100) /* then */ *Enum_Ref_Par = Ident_1; @@ -54,7 +54,7 @@ Enumeration *Enum_Ref_Par; *Enum_Ref_Par = Ident_2; break; case Ident_4: break; - case Ident_5: + case Ident_5: *Enum_Ref_Par = Ident_3; break; } /* switch */ @@ -63,7 +63,7 @@ Enumeration *Enum_Ref_Par; Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref) /**********************************************/ - /* executed three times */ + /* executed three times */ /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */ /* Int_Par_Ref becomes 7 */ /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */ diff --git a/examples/test/fs_test.c b/examples/test/fs_test.c index 2404b82e59..7fd70284cf 100644 --- a/examples/test/fs_test.c +++ b/examples/test/fs_test.c @@ -1,11 +1,7 @@ /* - * File : fs_test.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://openlab.rt-thread.com/license/LICENSE. + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes @@ -15,7 +11,11 @@ */ #include <rtthread.h> -#include <dfs_posix.h> +#include <dfs_file.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/statfs.h> static rt_uint32_t stop_flag = 0; static rt_thread_t fsrw1_thread = RT_NULL; diff --git a/examples/test/hwtimer_test.c b/examples/test/hwtimer_test.c index 428373dde0..08b0c5acaf 100644 --- a/examples/test/hwtimer_test.c +++ b/examples/test/hwtimer_test.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #include <rtthread.h> #include <rtdevice.h> #include <finsh.h> @@ -35,8 +44,8 @@ int hwtimer(void) return -1; } - /* ʱ����� */ - /* ����ʱ������(Ĭ��1Mhz��֧�ֵ���С����Ƶ��) */ + /* 时间测量 */ + /* 计数时钟设置(默认1Mhz或支持的最小计数频率) */ err = rt_device_control(dev, HWTIMER_CTRL_FREQ_SET, &freq); if (err != RT_EOK) { @@ -44,13 +53,13 @@ int hwtimer(void) goto EXIT; } - /* ����ģʽ */ + /* 周期模式 */ mode = HWTIMER_MODE_PERIOD; err = rt_device_control(dev, HWTIMER_CTRL_MODE_SET, &mode); tick = rt_tick_get(); rt_kprintf("Start Timer> Tick: %d\n", tick); - /* ���ö�ʱ����ʱֵ��������ʱ�� */ + /* 设置定时器超时值并启动定时器 */ val.sec = t; val.usec = 0; rt_kprintf("SetTime: Sec %d, Usec %d\n", val.sec, val.usec); @@ -62,22 +71,22 @@ int hwtimer(void) rt_kprintf("Sleep %d sec\n", t); rt_thread_delay(t*RT_TICK_PER_SECOND); - /* ֹͣ��ʱ�� */ + /* 停止定时器 */ err = rt_device_control(dev, HWTIMER_CTRL_STOP, RT_NULL); rt_kprintf("Timer Stoped\n"); - /* ��ȡ���� */ + /* 读取计数 */ rt_device_read(dev, 0, &val, sizeof(val)); rt_kprintf("Read: Sec = %d, Usec = %d\n", val.sec, val.usec); - /* ��ʱִ�лص����� -- ����ģʽ */ - /* ���ó�ʱ�ص����� */ + /* 定时执行回调函数 -- 单次模式 */ + /* 设置超时回调函数 */ rt_device_set_rx_indicate(dev, timer_timeout_cb); - /* ����ģʽ */ + /* 单次模式 */ mode = HWTIMER_MODE_PERIOD; err = rt_device_control(dev, HWTIMER_CTRL_MODE_SET, &mode); - /* ���ö�ʱ����ʱֵ��������ʱ�� */ + /* 设置定时器超时值并启动定时器 */ val.sec = t; val.usec = 0; rt_kprintf("SetTime: Sec %d, Usec %d\n", val.sec, val.usec); @@ -87,7 +96,7 @@ int hwtimer(void) goto EXIT; } - /* �ȴ��ص�����ִ�� */ + /* 等待回调函数执行 */ rt_thread_delay((t + 1)*RT_TICK_PER_SECOND); EXIT: @@ -96,7 +105,7 @@ EXIT: return err; } -#ifdef FINSH_USING_MSH +#ifdef RT_USING_FINSH MSH_CMD_EXPORT(hwtimer, "Test hardware timer"); #endif #endif /* RT_USING_HWTIMER */ diff --git a/examples/test/mem_test.c b/examples/test/mem_test.c index 549be80ab4..cd7d1b3552 100644 --- a/examples/test/mem_test.c +++ b/examples/test/mem_test.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #include <stdint.h> #include <rthw.h> diff --git a/examples/test/net_test.c b/examples/test/net_test.c index ec5d50197d..656686f091 100644 --- a/examples/test/net_test.c +++ b/examples/test/net_test.c @@ -1,4 +1,13 @@ /* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +/* * Net Test Utilities for RT-Thread */ #include <rtthread.h> @@ -7,7 +16,7 @@ #include <lwip/sockets.h> #include <lwip/init.h> -/* +/* * UDP echo server */ #define UDP_ECHO_PORT 7 @@ -30,12 +39,12 @@ void udpecho_entry(void *parameter) while(1) { /* received data to buffer */ -#if LWIP_VERSION_MINOR==3U +#if LWIP_VERSION_MINOR==3U buf = netconn_recv(conn); #else netconn_recv(conn, &buf); #endif - if(buf == NULL) + if(buf == NULL) { break; } @@ -46,25 +55,25 @@ void udpecho_entry(void *parameter) netconn_connect(conn, addr, port); /* reset address, and send to client */ -#if LWIP_VERSION_MINOR==3U +#if LWIP_VERSION_MINOR==3U buf->addr = RT_NULL; #else buf->addr = *IP_ADDR_ANY; #endif - + netconn_send(conn, buf); - + /* release buffer */ netbuf_delete(buf); } - + netconn_delete(conn); } /* * UDP socket echo server */ -#define UDP_SOCKET_ECHO_PORT 700 -#define UDP_SOCKET_BUFFER_SIZE 4096 +#define UDP_SOCKET_ECHO_PORT 700 +#define UDP_SOCKET_BUFFER_SIZE 4096 rt_thread_t udpecho_socket_tid = RT_NULL; void udpecho_socket_entry(void *parameter) { @@ -110,7 +119,7 @@ void udpecho_socket_entry(void *parameter) /* try to receive from UDP socket */ bytes_read = recvfrom(sock, recv_data, UDP_SOCKET_BUFFER_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len); - + /* send back */ sendto(sock, recv_data, bytes_read, 0, (struct sockaddr *)&client_addr, addr_len); @@ -148,7 +157,7 @@ void tcpecho_entry(void *parameter) while(1) { /* Grab new connection. */ -#if LWIP_VERSION_MINOR==3U +#if LWIP_VERSION_MINOR==3U newconn = netconn_accept(conn); if(newconn != NULL) #else @@ -172,25 +181,25 @@ void tcpecho_entry(void *parameter) err = netconn_write(newconn, data, len, NETCONN_COPY); if(err != ERR_OK) { - break; + break; } }while(netbuf_next(buf) >= 0); - + netbuf_delete(buf); } /* Close connection and discard connection identifier. */ netconn_delete(newconn); } } - + netconn_delete(conn); } /* * TCP socket echo server */ -#define TCP_SOCKET_ECHO_PORT 700 -#define TCP_SOCKET_BUFFER_SIZE 4096 +#define TCP_SOCKET_ECHO_PORT 700 +#define TCP_SOCKET_BUFFER_SIZE 4096 rt_thread_t tcpecho_socket_tid = RT_NULL; void tcpecho_socket_entry(void *parameter) { @@ -241,7 +250,7 @@ void tcpecho_socket_entry(void *parameter) if (connected > 0) { int timeout; - + /* set timeout option */ timeout = 5000; /* 5second */ setsockopt(connected, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); @@ -285,8 +294,8 @@ void net_test(void) { udpecho_tid = rt_thread_create("uecho", udpecho_entry, - RT_NULL, - 512, + RT_NULL, + 512, RT_THREAD_PRIORITY_MAX/2, 5); if (udpecho_tid != RT_NULL) { @@ -299,7 +308,7 @@ void net_test(void) udpecho_socket_tid = rt_thread_create("uecho_s", udpecho_socket_entry, RT_NULL, - 512, + 512, RT_THREAD_PRIORITY_MAX/2 + 1, 5); if (udpecho_socket_tid != RT_NULL) { @@ -310,22 +319,22 @@ void net_test(void) if (tcpecho_tid == RT_NULL) { tcpecho_tid = rt_thread_create("techo", - tcpecho_entry, + tcpecho_entry, RT_NULL, - 512, + 512, RT_THREAD_PRIORITY_MAX/2 + 2, 5); if (tcpecho_tid != RT_NULL) { rt_thread_startup(tcpecho_tid); } } - + if (tcpecho_socket_tid == RT_NULL) { tcpecho_socket_tid = rt_thread_create("techo_s", - tcpecho_socket_entry, + tcpecho_socket_entry, RT_NULL, - 512, + 512, RT_THREAD_PRIORITY_MAX/2 + 3, 5); if (tcpecho_socket_tid != RT_NULL) { diff --git a/examples/test/rbb_test.c b/examples/test/rbb_test.c index f276c993da..c4236bca44 100644 --- a/examples/test/rbb_test.c +++ b/examples/test/rbb_test.c @@ -1,21 +1,7 @@ /* - * File : rbb_test.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes diff --git a/examples/test/rtc_test.c b/examples/test/rtc_test.c index 992eb08d3d..79ea8450f9 100644 --- a/examples/test/rtc_test.c +++ b/examples/test/rtc_test.c @@ -1,74 +1,61 @@ /* - * File : rtc_test.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-01-15 Liu2guang the first version. */ -#include <rtthread.h> -#include <rtdevice.h> + +#include <rtthread.h> +#include <rtdevice.h> int rtc_test(void) -{ +{ uint8_t i; time_t now; - rt_err_t ret = RT_EOK; - + rt_err_t ret = RT_EOK; + rt_kprintf("[RTC Test]RTC Test Start...\n"); rt_thread_delay(RT_TICK_PER_SECOND); - rt_kprintf("[RTC Test]Set RTC 2017-04-01 12:30:46\n\n"); + rt_kprintf("[RTC Test]Set RTC 2017-04-01 12:30:46\n"); rt_thread_delay(RT_TICK_PER_SECOND); - - ret = set_date(2017, 4, 1); + + ret = set_date(2017, 4, 1); if(ret != RT_EOK) { - rt_kprintf("[RTC Test]Set RTC Date failed\n"); + rt_kprintf("[RTC Test]Set RTC Date failed\n"); return RT_ERROR; } - + rt_thread_delay(RT_TICK_PER_SECOND); - - ret = set_time(12, 30, 46); + + ret = set_time(12, 30, 46); if(ret != RT_EOK) { - rt_kprintf("[RTC Test]Set RTC Time failed\n"); + rt_kprintf("[RTC Test]Set RTC Time failed\n"); return RT_ERROR; } - + rt_thread_delay(RT_TICK_PER_SECOND); - + for(i = 0; i < 10; i++) { - rt_kprintf("[RTC Test]Read RTC Date and Time: "); + rt_kprintf("[RTC Test]Read RTC Date and Time: "); now = time(RT_NULL); - rt_kprintf("%s", ctime(&now)); - + rt_kprintf("%s\n", ctime(&now)); + rt_thread_delay(RT_TICK_PER_SECOND); } - + rt_kprintf("\n"); return RT_EOK; } #ifdef RT_USING_FINSH #include <finsh.h> -FINSH_FUNCTION_EXPORT(rtc_test, rtc drive test. e.g: rtc_test()); -MSH_CMD_EXPORT(rtc_test, rtc drive test. e.g: rtc_test()); +FINSH_FUNCTION_EXPORT(rtc_test, rtc driver test. e.g: rtc_test()); +MSH_CMD_EXPORT(rtc_test, rtc driver test. e.g: rtc_test()); #endif diff --git a/examples/ulog/ulog_example.c b/examples/ulog/ulog_example.c index 88572f5152..f7ee068799 100644 --- a/examples/ulog/ulog_example.c +++ b/examples/ulog/ulog_example.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/examples/utest/README.md b/examples/utest/README.md new file mode 100644 index 0000000000..bde3bd4b80 --- /dev/null +++ b/examples/utest/README.md @@ -0,0 +1,73 @@ +# RT-Thread 测试用例集合 + +## 简介 + +为了保证某一部分代码的质量,通常可以通过编写测试用例的方式,验证此代码的功能。为了保证 RT-Thread 相关仓库的代码质量,我们基于 utest 框架搭建了一套简易的自动化测试环境。有兴趣,有精力的小伙伴可以利用这套机制完善自己的代码检查。如果有意愿让社区上更多的小伙伴收益,也可以在提交代码的时候,把对应的测试用例也提交上来。 + +## 目录结构 + +| 目录 | 用途 | +| --------- | ------------------------------------------------------------ | +| configs | 配置文件集合(每一个目录代表一种功能集合,如:kernel,net等) | +| testcases | 测试用例源代码 | + +## 如何贡献 + +### 1. 编写测试用例 + +参考已有的测试用例在 [examples\utest\testcases](./testcases) 目录下添加自己的测试用例。测试用例的编写方法参考文档中心《utest 测试框架》章节。 + +### 2. 本地测试 + +1. 在 `bsp\qemu-vexpress-a9` 目录下打开 `menuconfig`,使能对应的测试用例,如下: + +``` +RT-Thread Utestcases ---> + [*] RT-Thread Utestcases + Utest Self Testcase ---> + [*] Pass test +``` + +2. 保存并退出,输入 scons 编译当前 bsp。 + +3. 输入 .\qemu.bat 运行当前 bsp,在 msh 环境下执行 utest_run 命令,验证代码运行是否正常。 + +``` +msh />utest_run +[I/utest] [==========] [ utest ] loop 1/1 +[I/utest] [==========] [ utest ] started +[I/utest] [----------] [ testcase ] (testcases.utest.pass_tc) started +[D/utest] [ OK ] [ unit ] (test_assert_pass:16) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:17) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:19) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:20) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:22) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:23) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:25) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:26) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:28) is passed +[D/utest] [ OK ] [ unit ] (test_assert_pass:29) is passed +[I/utest] [ PASSED ] [ result ] testcase (testcases.utest.pass_tc) +[I/utest] [----------] [ testcase ] (testcases.utest.pass_tc) finished +[I/utest] [==========] [ utest ] finished +``` + +### 3. 提交 + +1. 如果是对已有测试集合的完善,需要把添加的测试用例的配置项,以及对应的依赖项添加到对应测试集合的配置文件里,如:[examples\utest\configs\kernel\mem.conf](./configs/kernel/mem.conf)。 + +``` +CONFIG_UTEST_MEMHEAP_TC=y + +# dependencies +CONFIG_RT_USING_MEMHEAP=y +``` + +2. 如果要添加新的测试集合,需要参考已有的测试集合,在 [examples\utest\configs](./configs) 目录下添加新的测试集合配置项。并更新 [.github\workflows\action_utest.yml](../../.github/workflows/action_utest.yml) 内的测试集合。 + +``` +- {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "kernel/mem.conf", SD_FILE: "sd.bin"} +- {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", CONFIG_FILE: "utest_self/self.conf", SD_FILE: "sd.bin"} +``` + +3. 向 RT-Thread 主仓库提交合并请求。
\ No newline at end of file diff --git a/examples/utest/configs/kernel/ipc.conf b/examples/utest/configs/kernel/ipc.conf new file mode 100644 index 0000000000..8af98d607a --- /dev/null +++ b/examples/utest/configs/kernel/ipc.conf @@ -0,0 +1,13 @@ +CONFIG_UTEST_SEMAPHORE_TC=y +CONFIG_UTEST_EVENT_TC=y +CONFIG_UTEST_MESSAGEQUEUE_TC=y +CONFIG_UTEST_SIGNAL_TC=y +CONFIG_UTEST_MUTEX_TC=y +CONFIG_UTEST_MAILBOX_TC=y +# dependencies +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MESSAGEQUEUE=y +CONFIG_RT_USING_SIGNALS=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_MAILBOX=y diff --git a/examples/utest/configs/kernel/irq.conf b/examples/utest/configs/kernel/irq.conf new file mode 100644 index 0000000000..c8f044fce4 --- /dev/null +++ b/examples/utest/configs/kernel/irq.conf @@ -0,0 +1,3 @@ +CONFIG_UTEST_IRQ_TC=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +# dependencies diff --git a/examples/utest/configs/kernel/mem.conf b/examples/utest/configs/kernel/mem.conf new file mode 100644 index 0000000000..1a311ab9dd --- /dev/null +++ b/examples/utest/configs/kernel/mem.conf @@ -0,0 +1,4 @@ +CONFIG_UTEST_MEMHEAP_TC=y + +# dependencies +CONFIG_RT_USING_MEMHEAP=y diff --git a/examples/utest/configs/kernel/thread.conf b/examples/utest/configs/kernel/thread.conf new file mode 100644 index 0000000000..9b3234f0d7 --- /dev/null +++ b/examples/utest/configs/kernel/thread.conf @@ -0,0 +1,4 @@ +CONFIG_UTEST_THREAD_TC=y +# dependencies +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_USING_THREAD=y diff --git a/examples/utest/configs/kernel/timer.conf b/examples/utest/configs/kernel/timer.conf new file mode 100644 index 0000000000..20696f065f --- /dev/null +++ b/examples/utest/configs/kernel/timer.conf @@ -0,0 +1,4 @@ +CONFIG_UTEST_TIMER_TC=y + +# dependencies +CONFIG_RT_USING_TIMER_SOFT=y diff --git a/examples/utest/configs/utest_self/self.conf b/examples/utest/configs/utest_self/self.conf new file mode 100644 index 0000000000..b155a551d2 --- /dev/null +++ b/examples/utest/configs/utest_self/self.conf @@ -0,0 +1 @@ +CONFIG_UTEST_SELF_PASS_TC=y diff --git a/examples/utest/testcases/Kconfig b/examples/utest/testcases/Kconfig new file mode 100644 index 0000000000..5dc1c6c420 --- /dev/null +++ b/examples/utest/testcases/Kconfig @@ -0,0 +1,16 @@ +menu "RT-Thread Utestcases" + +config RT_USING_UTESTCASES + bool "RT-Thread Utestcases" + default n + select RT_USING_UTEST + +if RT_USING_UTESTCASES + +source "$RTT_DIR/examples/utest/testcases/utest/Kconfig" +source "$RTT_DIR/examples/utest/testcases/kernel/Kconfig" +source "$RTT_DIR/examples/utest/testcases/drivers/serial_v2/Kconfig" + +endif + +endmenu diff --git a/examples/utest/testcases/SConscript b/examples/utest/testcases/SConscript new file mode 100644 index 0000000000..4c815c49b8 --- /dev/null +++ b/examples/utest/testcases/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/examples/utest/testcases/drivers/SConscript b/examples/utest/testcases/drivers/SConscript new file mode 100644 index 0000000000..4c815c49b8 --- /dev/null +++ b/examples/utest/testcases/drivers/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/examples/utest/testcases/drivers/serial_v2/Kconfig b/examples/utest/testcases/drivers/serial_v2/Kconfig new file mode 100644 index 0000000000..3c8d480b3a --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/Kconfig @@ -0,0 +1,7 @@ +menu "Utest Serial Testcase" + +config UTEST_SERIAL_TC + bool "Serial testcase" + default n + +endmenu diff --git a/examples/utest/testcases/drivers/serial_v2/README.md b/examples/utest/testcases/drivers/serial_v2/README.md new file mode 100644 index 0000000000..38d71ce8e8 --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/README.md @@ -0,0 +1,120 @@ +## 1、介绍 + +该目录下 c 文件是新版本串口的测试用例,在 `examples/utest/testcases/drivers/serial_v2` 目录结构里,该测试用例用来测试串口的各个操作模式是否正常工作。 + +## 2、 文件说明 + +| 文件 | 描述 | +| ---------------- | ----------------------------------------- | +| uart_rxb_txb.c | 串口接收阻塞和发送阻塞模式 的测试用例 | +| uart_rxb_txnb.c | 串口接收阻塞和发送非阻塞模式 的测试用例 | +| uart_rxnb_txb.c | 串口接收非阻塞和发送阻塞模式 的测试用例 | +| uart_rxnb_txnb.c | 串口接收非阻塞和发送非阻塞模式 的测试用例 | + +## 3、软硬件环境 + +硬件上需要支持 RT-Thread 的完整版操作系统,版本为4.0.4及以上,且硬件有串口硬件外设,软件上需要支持 内核接口、IPC 、Device 框架。 + +## 4、测试项 + +### 4.1 测试说明 + +上文所提及的模式是指串口使用时的操作模式,不涉及硬件的工作模式的配置情况(硬件工作模式一般有轮询POLL、中断INT、DMA),因此使用时需要结合具体的硬件工作模式去配置使用。例如 发送阻塞和接收非阻塞模式 ,这个测试有很多种硬件配置,配置情况例如:DMA发送阻塞和DMA接收非阻塞,INT发送阻塞和DMA接收非阻塞,POLL发送阻塞和DMA接收非阻塞等等。因此通过排列组合后的测试场景有4*9=36种,有意义的组合方式为20种。如下表: + + +| 接收非阻塞 | 发送阻塞 | 组合 | 有意义的组合方式 | +| ---------- | -------- | ----------------- | ---------------- | +| POLL | POLL | RX_POLL + TX_POLL | | +| | INT | RX_POLL + TX_INT | | +| | DMA | RX_POLL + TX_DMA | | +| INT | POLL | RX_INT + TX_POLL | ✔ | +| | INT | RX_INT + TX_INT | ✔ | +| | DMA | RX_INT + TX_DMA | ✔ | +| DMA | POLL | RX_DMA + TX_POLL | ✔ | +| | INT | RX_DMA + TX_INT | ✔ | +| | DMA | RX_DMA + TX_DMA | ✔ | + +| 接收非阻塞 | 发送非阻塞 | 组合 | 有意义的组合方式 | +| ---------- | ---------- | ----------------- | ---------------- | +| POLL | POLL | RX_POLL + TX_POLL | | +| | INT | RX_POLL + TX_INT | | +| | DMA | RX_POLL + TX_DMA | | +| INT | POLL | RX_INT + TX_POLL | | +| | INT | RX_INT + TX_INT | ✔ | +| | DMA | RX_INT + TX_DMA | ✔ | +| DMA | POLL | RX_DMA + TX_POLL | | +| | INT | RX_DMA + TX_INT | ✔ | +| | DMA | RX_DMA + TX_DMA | ✔ | + +| 接收阻塞 | 发送阻塞 | 组合 | 有意义的组合方式 | +| -------- | -------- | ----------------- | ---------------- | +| POLL | POLL | RX_POLL + TX_POLL | | +| | INT | RX_POLL + TX_INT | | +| | DMA | RX_POLL + TX_DMA | | +| INT | POLL | RX_INT + TX_POLL | ✔ | +| | INT | RX_INT + TX_INT | ✔ | +| | DMA | RX_INT + TX_DMA | ✔ | +| DMA | POLL | RX_DMA + TX_POLL | ✔ | +| | INT | RX_DMA + TX_INT | ✔ | +| | DMA | RX_DMA + TX_DMA | ✔ | + +| 接收阻塞 | 发送非阻塞 | 组合 | 有意义的组合方式 | +| -------- | ---------- | ----------------- | ---------------- | +| POLL | POLL | RX_POLL + TX_POLL | | +| | INT | RX_POLL + TX_INT | | +| | DMA | RX_POLL + TX_DMA | | +| INT | POLL | RX_INT + TX_POLL | | +| | INT | RX_INT + TX_INT | ✔ | +| | DMA | RX_INT + TX_DMA | ✔ | +| DMA | POLL | RX_DMA + TX_POLL | | +| | INT | RX_DMA + TX_INT | ✔ | +| | DMA | RX_DMA + TX_DMA | ✔ | + +需要解释的是,为什么会存在无意义的组合模式,举个例子,非阻塞模式下,肯定是不会出现POLL(轮询)方式的,因为POLL方式已经表明是阻塞方式了。 +该测试用例在测试多种组合时,需要通过更改`rtconfig.h`文件对硬件模式进行静态配置。 + +### 4.2 测试思路 + +这四个测试用例的测试思路基本一致。 + +硬件上:**短接串口的发送TX引脚和接收RX引脚,完成自发自收的回路**。 + +软件上:创建两个线程A和B,A为接收线程,B为发送线程,设置A线程优先级比B线程优先级高。发送线程发送随机长度(长度范围是 0 到 1000)的数据,接收线程接收到数据进行校验,数据正确则测试通过,默认测试100次。 + +## 5、配置 + +使用该测试用例需要在 `env` 工具的 `menuconfig` 中做相关配置,配置如下所示(使用 RT-Thread-Studio 的配置路径一致 ): + +``` +RT-Thread Utestcases ---> + [*] RT-Thread Utestcases ---> + Utest Serial Testcase ---> + [*] Serial testcase +``` + +## 6、使用 + +\- 编译下载。 + +\- 在 MSH 中输入 `utest_run testcases.drivers.uart_rxb_txb` 运行串口接收阻塞和发送阻塞测试用例。 + +\- 在 MSH 中输入 `utest_run testcases.drivers.uart_rxb_txb` 运行串口接收阻塞和发送阻塞测试用例。 + +\- 在 MSH 中输入 `utest_run testcases.drivers.uart_rxb_txb` 运行串口接收阻塞和发送阻塞测试用例。 + +\- 在 MSH 中输入 `utest_run testcases.drivers.uart_rxb_txb` 运行串口接收阻塞和发送阻塞测试用例。 + +如果仅仅配置了 `Serial testcase` 相关的测试用例,则直接输入 `utest_run` 运行即可将上述测试用例按序测试。 + +## 7、注意事项 + +\- 需配置正确的测试用例。 + +\- 如有需要,可开启 ULOG 查看测试用例日志信息。 + +\- 需在 MSH 中输入正确的命令行。 + +\- 测试用例默认的测试数据长度范围最大为1000字节,如果接收端的缓冲区大小配置为小于1000字节时,那么在测试接收阻塞模式时,将会由于获取不了1000字节长度导致线程持续阻塞(因为测试用例是按 `recv_len` 长度去接收的,而不是按照单字节去接收的),因此建议接收端的缓冲区大小 (对应宏例如为 `BSP_UART2_RX_BUFSIZE`)设置为1024即可;当然也可按需减小测试的最大数据长度。 + +\- 该测试用例需要结合硬件具体的工作模式(POLL 、INT、DMA)进行测试,而硬件工作模式只能选择一种,因此需要在 `rtconfig.h` 中对串口相应的宏进行配置,来选择不同的工作模式去进行测试。 + diff --git a/examples/utest/testcases/drivers/serial_v2/SConscript b/examples/utest/testcases/drivers/serial_v2/SConscript new file mode 100644 index 0000000000..a7a46e656a --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/SConscript @@ -0,0 +1,16 @@ +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Split(''' +uart_rxb_txnb.c +uart_rxb_txb.c +uart_rxnb_txb.c +uart_rxnb_txnb.c +''') + +CPPPATH = [cwd] + +group = DefineGroup('utestcases', src, depend = ['UTEST_SERIAL_TC'], CPPPATH = CPPPATH) + +Return('group') diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c new file mode 100644 index 0000000000..8b2205ee1a --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include <rtthread.h> +#include "utest.h" +#include <rtdevice.h> +#include <stdlib.h> + +#define TC_UART_DEVICE_NAME "uart2" +#define TC_UART_SEND_TIMES 100 + + +#ifdef UTEST_SERIAL_TC + +#define TEST_UART_NAME TC_UART_DEVICE_NAME + +static struct rt_serial_device *serial; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", TEST_UART_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_uint16_t send_len; + + rt_uint32_t i = 0; + send_len = *(rt_uint16_t *)parameter; + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + /* send buffer */ + if (rt_device_write(&serial->parent, 0, uart_write_buffer, send_len) != send_len) + { + LOG_E("device write failed\r\n"); + } + rt_free(uart_write_buffer); + +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint16_t rev_len; + + rev_len = *(rt_uint16_t *)parameter; + rt_uint8_t *ch; + ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; + rt_uint32_t all_receive_length = 0; + + + while (1) + { + cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + if (cnt == 0) + { + continue; + } + + if (fisrt_flag != RT_TRUE) + { + if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + { + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + else + { + fisrt_flag = RT_FALSE; + } + + for (i = 0; i < cnt - 1; i++) + { + if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + { + LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + all_receive_length += cnt; + if (all_receive_length >= rev_len) + break; + else + last_old_data = ch[cnt - 1]; + } + rt_free(ch); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint16_t length) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = BSP_UART2_RX_BUFSIZE; + config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + thread_send = rt_thread_create("uart_send", uart_send_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); + if ((thread_send != RT_NULL) && (thread_recv != RT_NULL)) + { + rt_thread_startup(thread_send); + rt_thread_startup(thread_recv); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } +__exit: + rt_device_close(&serial->parent); + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t times = 0; + rt_uint16_t num = 0; + while (TC_UART_SEND_TIMES - times) + { + num = (rand() % 1000) + 1; + if(uart_api(num) == RT_EOK) + LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + else + { + LOG_E("uart test error"); + break; + } + } + uassert_true(uart_over_flag == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxb_txb", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c new file mode 100644 index 0000000000..f03a24fe13 --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include <rtthread.h> +#include "utest.h" +#include <rtdevice.h> +#include <stdlib.h> + +#define TC_UART_DEVICE_NAME "uart2" +#define TC_UART_SEND_TIMES 100 + + +#ifdef UTEST_SERIAL_TC + +#define TEST_UART_NAME TC_UART_DEVICE_NAME + +static struct rt_serial_device *serial; +static rt_sem_t tx_sem; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", TEST_UART_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t uart_tx_completion(rt_device_t device, void *buffer) +{ + rt_sem_release(tx_sem); + + return RT_EOK; +} + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_uint16_t send_len, len = 0; + rt_err_t result; + + rt_uint32_t i = 0; + send_len = *(rt_uint16_t *)parameter; + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + /* send buffer */ + while (send_len - len) + { + len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len); + result = rt_sem_take(tx_sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + LOG_E("take sem err in send."); + } + } + rt_free(uart_write_buffer); + +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint16_t rev_len; + + rev_len = *(rt_uint16_t *)parameter; + rt_uint8_t *ch; + ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; + rt_uint32_t all_receive_length = 0; + + while (1) + { + cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + if (cnt != rev_len) + { + continue; + } + + if (fisrt_flag != RT_TRUE) + { + if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + { + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + else + { + fisrt_flag = RT_FALSE; + } + + for (i = 0; i < cnt - 1; i++) + { + if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + { + LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + all_receive_length += cnt; + if (all_receive_length >= rev_len) + break; + else + last_old_data = ch[cnt - 1]; + } + rt_free(ch); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint16_t test_buf) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + tx_sem = rt_sem_create("tx_sem", 0, RT_IPC_FLAG_PRIO); + if (tx_sem == RT_NULL) + { + LOG_E("Init sem failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = BSP_UART2_RX_BUFSIZE; + config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING); + + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* set receive callback function */ + result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion); + if (result != RT_EOK) + { + goto __exit; + } + + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); + thread_send = rt_thread_create("uart_send", uart_send_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); + + if (thread_send != RT_NULL && thread_recv != RT_NULL) + { + rt_thread_startup(thread_recv); + rt_thread_startup(thread_send); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } +__exit: + if (tx_sem) + rt_sem_delete(tx_sem); + + rt_device_close(&serial->parent); + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t times = 0; + rt_uint16_t num = 0; + while (TC_UART_SEND_TIMES - times) + { + num = (rand() % 1000) + 1; + if(uart_api(num) == RT_EOK) + LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + else + { + LOG_E("uart test error"); + break; + } + } + uassert_true(uart_over_flag == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + tx_sem = RT_NULL; + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxb_txnb", utest_tc_init, utest_tc_cleanup, 30); + +#endif diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c new file mode 100644 index 0000000000..c1c88ddc9f --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include <rtthread.h> +#include "utest.h" +#include <rtdevice.h> +#include <stdlib.h> + +#define TC_UART_DEVICE_NAME "uart2" +#define TC_UART_SEND_TIMES 100 + + +#ifdef UTEST_SERIAL_TC + +#define TEST_UART_NAME TC_UART_DEVICE_NAME + +static struct rt_serial_device *serial; +static rt_sem_t rx_sem; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", TEST_UART_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t uart_rx_indicate(rt_device_t device, rt_size_t size) +{ + rt_sem_release(rx_sem); + + return RT_EOK; +} + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_uint16_t send_len; + + rt_uint32_t i = 0; + send_len = *(rt_uint16_t *)parameter; + + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + + /* send buffer */ + if (rt_device_write(&serial->parent, 0, uart_write_buffer, send_len) != send_len) + { + LOG_E("device write failed\r\n"); + } + rt_free(uart_write_buffer); +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint16_t rev_len; + + rev_len = *(rt_uint16_t *)parameter; + rt_uint8_t *ch; + ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; + rt_uint32_t all_receive_length = 0; + + while (1) + { + rt_err_t result; + + result = rt_sem_take(rx_sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + LOG_E("take sem err in recv."); + } + + cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + if (cnt == 0) + { + continue; + } + + if (fisrt_flag != RT_TRUE) + { + if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + { + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + else + { + fisrt_flag = RT_FALSE; + } + + for (i = 0; i < cnt - 1; i++) + { + if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + { + LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + all_receive_length += cnt; + if (all_receive_length >= rev_len) + break; + else + last_old_data = ch[cnt - 1]; + } + rt_free(ch); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint16_t test_buf) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + rx_sem = rt_sem_create("rx_sem", 0, RT_IPC_FLAG_PRIO); + if (rx_sem == RT_NULL) + { + LOG_E("Init sem failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = BSP_UART2_RX_BUFSIZE; + config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + uart_result = RT_FALSE; + rt_sem_delete(rx_sem); + return -RT_ERROR; + } + + /* set receive callback function */ + result = rt_device_set_rx_indicate(&serial->parent, uart_rx_indicate); + if (result != RT_EOK) + { + goto __exit; + } + + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); + thread_send = rt_thread_create("uart_send", uart_send_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); + + if (thread_send != RT_NULL && thread_recv != RT_NULL) + { + rt_thread_startup(thread_recv); + rt_thread_startup(thread_send); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } +__exit: + if (rx_sem) + rt_sem_delete(rx_sem); + rt_device_close(&serial->parent); + uart_over_flag = RT_FALSE; + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t times = 0; + rt_uint16_t num = 0; + while (TC_UART_SEND_TIMES - times) + { + num = (rand() % 1000) + 1; + if(uart_api(num) == RT_EOK) + LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + else + { + LOG_E("uart test error"); + break; + } + } + uassert_true(uart_result == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + rx_sem = RT_NULL; + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxnb_txb", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c new file mode 100644 index 0000000000..ad8d20b8cf --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include <rtthread.h> +#include "utest.h" +#include <rtdevice.h> +#include <stdlib.h> + +#define TC_UART_DEVICE_NAME "uart2" +#define TC_UART_SEND_TIMES 100 + + +#ifdef UTEST_SERIAL_TC + +#define TEST_UART_NAME TC_UART_DEVICE_NAME + +static struct rt_serial_device *serial; +static rt_sem_t tx_sem; +static rt_sem_t rx_sem; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", TEST_UART_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t uart_tx_completion(rt_device_t device, void *buffer) +{ + rt_sem_release(tx_sem); + return RT_EOK; +} + +static rt_err_t uart_rx_indicate(rt_device_t device, rt_size_t size) +{ + rt_sem_release(rx_sem); + return RT_EOK; +} + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_uint16_t send_len, len = 0; + rt_err_t result; + + rt_uint32_t i = 0; + send_len = *(rt_uint16_t *)parameter; + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + /* send buffer */ + while (send_len - len) + { + len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len); + result = rt_sem_take(tx_sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + LOG_E("take sem err in send."); + } + } + rt_free(uart_write_buffer); + +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint16_t rev_len; + + rev_len = *(rt_uint16_t *)parameter; + rt_uint8_t *ch; + ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; + rt_uint32_t all_receive_length = 0; + + while (1) + { + rt_err_t result; + + result = rt_sem_take(rx_sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + LOG_E("take sem err in recv."); + } + + cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + if (cnt == 0) + { + continue; + } + + if (fisrt_flag != RT_TRUE) + { + if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + { + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + else + { + fisrt_flag = RT_FALSE; + } + + for (i = 0; i < cnt - 1; i++) + { + if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + { + LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + + uart_result = RT_FALSE; + rt_free(ch); + return; + } + } + all_receive_length += cnt; + if (all_receive_length >= rev_len) + break; + else + last_old_data = ch[cnt - 1]; + } + rt_free(ch); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint16_t test_buf) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + rx_sem = rt_sem_create("rx_sem", 0, RT_IPC_FLAG_PRIO); + if (rx_sem == RT_NULL) + { + LOG_E("Init rx_sem failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + tx_sem = rt_sem_create("tx_sem", 0, RT_IPC_FLAG_PRIO); + if (tx_sem == RT_NULL) + { + LOG_E("Init tx_sem failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = BSP_UART2_RX_BUFSIZE; + config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING); + + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + /* set receive callback function */ + result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion); + if (result != RT_EOK) + { + goto __exit; + } + + result = rt_device_set_rx_indicate(&serial->parent, uart_rx_indicate); + if (result != RT_EOK) + { + goto __exit; + } + + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); + thread_send = rt_thread_create("uart_send", uart_send_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); + + if (thread_send != RT_NULL && thread_recv != RT_NULL) + { + rt_thread_startup(thread_recv); + rt_thread_startup(thread_send); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } +__exit: + if (tx_sem) + rt_sem_delete(tx_sem); + + if (rx_sem) + rt_sem_delete(rx_sem); + + rt_device_close(&serial->parent); + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t times = 0; + rt_uint16_t num = 0; + while (TC_UART_SEND_TIMES - times) + { + num = (rand() % 1000) + 1; + if(uart_api(num) == RT_EOK) + LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + else + { + LOG_E("uart test error"); + break; + } + } + uassert_true(uart_over_flag == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + tx_sem = RT_NULL; + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxnb_txnb", utest_tc_init, utest_tc_cleanup, 30); + +#endif diff --git a/examples/utest/testcases/kernel/Kconfig b/examples/utest/testcases/kernel/Kconfig new file mode 100644 index 0000000000..0faa3622fb --- /dev/null +++ b/examples/utest/testcases/kernel/Kconfig @@ -0,0 +1,58 @@ +menu "Kernel Testcase" + +config UTEST_MEMHEAP_TC + bool "memheap stability test" + default y + depends on RT_USING_MEMHEAP + +config UTEST_SMALL_MEM_TC + bool "mem test" + default y + depends on RT_USING_SMALL_MEM + +config UTEST_SLAB_TC + bool "slab test" + default n + depends on RT_USING_SLAB + +config UTEST_IRQ_TC + bool "IRQ test" + default n + +config UTEST_SEMAPHORE_TC + bool "semaphore test" + default n + depends on RT_USING_SEMAPHORE + +config UTEST_EVENT_TC + bool "event test" + default n + depends on RT_USING_EVENT + +config UTEST_TIMER_TC + bool "timer test" + default n + +config UTEST_MESSAGEQUEUE_TC + bool "message queue test" + default n + +config UTEST_SIGNAL_TC + bool "signal test" + default n + +config UTEST_MUTEX_TC + bool "mutex test" + default n + +config UTEST_MAILBOX_TC + bool "mailbox test" + default n + +config UTEST_THREAD_TC + bool "thread test" + default n + select RT_USING_TIMER_SOFT + select RT_USING_THREAD + +endmenu diff --git a/examples/utest/testcases/kernel/SConscript b/examples/utest/testcases/kernel/SConscript new file mode 100644 index 0000000000..95959f1f9b --- /dev/null +++ b/examples/utest/testcases/kernel/SConscript @@ -0,0 +1,48 @@ +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Split(''' +''') + +if GetDepend(['UTEST_MEMHEAP_TC']): + src += ['memheap_tc.c'] + +if GetDepend(['UTEST_SMALL_MEM_TC']): + src += ['mem_tc.c'] + +if GetDepend(['UTEST_SLAB_TC']): + src += ['slab_tc.c'] + +if GetDepend(['UTEST_IRQ_TC']): + src += ['irq_tc.c'] + +if GetDepend(['UTEST_SEMAPHORE_TC']): + src += ['semaphore_tc.c'] + +if GetDepend(['UTEST_EVENT_TC']): + src += ['event_tc.c'] + +if GetDepend(['UTEST_TIMER_TC']): + src += ['timer_tc.c'] + +if GetDepend(['UTEST_MESSAGEQUEUE_TC']): + src += ['messagequeue_tc.c'] + +if GetDepend(['UTEST_SIGNAL_TC']): + src += ['signal_tc.c'] + +if GetDepend(['UTEST_MUTEX_TC']): + src += ['mutex_tc.c'] + +if GetDepend(['UTEST_MAILBOX_TC']): + src += ['mailbox_tc.c'] + +if GetDepend(['UTEST_THREAD_TC']): + src += ['thread_tc.c'] + +CPPPATH = [cwd] + +group = DefineGroup('utestcases', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/examples/utest/testcases/kernel/event_tc.c b/examples/utest/testcases/kernel/event_tc.c new file mode 100644 index 0000000000..9847529214 --- /dev/null +++ b/examples/utest/testcases/kernel/event_tc.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-15 liukang the first version + */ + +#include <rtthread.h> +#include "utest.h" +#include <stdlib.h> + +#define EVENT_FLAG3 (1 << 3) +#define EVENT_FLAG5 (1 << 5) + +static struct rt_event static_event = {0}; +#ifdef RT_USING_HEAP +static rt_event_t dynamic_event = RT_NULL; +static rt_uint32_t dynamic_event_recv_thread_finish = 0, dynamic_event_send_thread_finish = 0; + +ALIGN(RT_ALIGN_SIZE) +static char thread3_stack[1024]; +static struct rt_thread thread3; + +ALIGN(RT_ALIGN_SIZE) +static char thread4_stack[1024]; +static struct rt_thread thread4; +#endif /* RT_USING_HEAP */ + +static rt_uint32_t recv_event_times1 = 0, recv_event_times2 = 0; +static rt_uint32_t static_event_recv_thread_finish = 0, static_event_send_thread_finish = 0; + +ALIGN(RT_ALIGN_SIZE) +static char thread1_stack[1024]; +static struct rt_thread thread1; + +ALIGN(RT_ALIGN_SIZE) +static char thread2_stack[1024]; +static struct rt_thread thread2; + +#define THREAD_PRIORITY 9 +#define THREAD_TIMESLICE 5 + +static void test_event_init(void) +{ + rt_err_t result; + + result = rt_event_init(&static_event, "event", RT_IPC_FLAG_PRIO); + if (result != RT_EOK) + { + uassert_false(1); + } + result = rt_event_detach(&static_event); + if (result != RT_EOK) + { + uassert_false(1); + } + + result = rt_event_init(&static_event, "event", RT_IPC_FLAG_FIFO); + if (result != RT_EOK) + { + uassert_false(1); + } + result = rt_event_detach(&static_event); + if (result != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static void test_event_detach(void) +{ + rt_err_t result = RT_EOK; + + result = rt_event_init(&static_event, "event", RT_IPC_FLAG_PRIO); + if (result != RT_EOK) + { + uassert_false(1); + } + + result = rt_event_detach(&static_event); + if (result != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static void thread1_recv_static_event(void *param) +{ + rt_uint32_t e; + + if (rt_event_recv(&static_event, (EVENT_FLAG3 | EVENT_FLAG5), + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, &e) != RT_EOK) + { + return; + } + + recv_event_times1 = e; + + rt_thread_mdelay(50); + + if (rt_event_recv(&static_event, (EVENT_FLAG3 | EVENT_FLAG5), + RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, &e) != RT_EOK) + { + return; + } + recv_event_times2 = e; + + static_event_recv_thread_finish = 1; +} + +static void thread2_send_static_event(void *param) +{ + rt_event_send(&static_event, EVENT_FLAG3); + rt_thread_mdelay(10); + + rt_event_send(&static_event, EVENT_FLAG5); + rt_thread_mdelay(10); + + rt_event_send(&static_event, EVENT_FLAG3); + + static_event_send_thread_finish = 1; +} + + +static void test_static_event_send_recv(void) +{ + rt_err_t result = RT_EOK; + + result = rt_event_init(&static_event, "event", RT_IPC_FLAG_PRIO); + if (result != RT_EOK) + { + uassert_false(1); + } + + rt_thread_init(&thread1, + "thread1", + thread1_recv_static_event, + RT_NULL, + &thread1_stack[0], + sizeof(thread1_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); + rt_thread_startup(&thread1); + + rt_thread_init(&thread2, + "thread2", + thread2_send_static_event, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(&thread2); + + while (static_event_recv_thread_finish != 1 || static_event_send_thread_finish != 1) + { + rt_thread_delay(1); + } + + if (recv_event_times1 == EVENT_FLAG3 && recv_event_times2 == (EVENT_FLAG3 | EVENT_FLAG5)) + { + if (rt_event_detach(&static_event) != RT_EOK) + { + uassert_false(1); + } + uassert_true(1); + } + else + { + if (rt_event_detach(&static_event) != RT_EOK) + { + uassert_false(1); + } + uassert_false(1); + } + + return; +} + +#ifdef RT_USING_HEAP +static void test_event_create(void) +{ + rt_err_t result = RT_EOK; + + dynamic_event = rt_event_create("dynamic_event", RT_IPC_FLAG_FIFO); + if (dynamic_event == RT_NULL) + { + uassert_false(1); + } + + result = rt_event_delete(dynamic_event); + if (result != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static void test_event_delete(void) +{ + rt_err_t result; + + dynamic_event = rt_event_create("dynamic_event", RT_IPC_FLAG_FIFO); + if (dynamic_event == RT_NULL) + { + uassert_false(1); + } + + result = rt_event_delete(dynamic_event); + if (result != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static void thread3_recv_dynamic_event(void *param) +{ + rt_uint32_t e; + + if (rt_event_recv(dynamic_event, (EVENT_FLAG3 | EVENT_FLAG5), + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, &e) != RT_EOK) + { + return; + } + + recv_event_times1 = e; + + rt_thread_mdelay(50); + + if (rt_event_recv(dynamic_event, (EVENT_FLAG3 | EVENT_FLAG5), + RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, &e) != RT_EOK) + { + return; + } + recv_event_times2 = e; + + dynamic_event_recv_thread_finish = 1; +} + +static void thread4_send_dynamic_event(void *param) +{ + rt_event_send(dynamic_event, EVENT_FLAG3); + rt_thread_mdelay(10); + + rt_event_send(dynamic_event, EVENT_FLAG5); + rt_thread_mdelay(10); + + rt_event_send(dynamic_event, EVENT_FLAG3); + + dynamic_event_send_thread_finish = 1; +} + +static void test_dynamic_event_send_recv(void) +{ + dynamic_event = rt_event_create("dynamic_event", RT_IPC_FLAG_PRIO); + if (dynamic_event == RT_NULL) + { + uassert_false(1); + } + + rt_thread_init(&thread3, + "thread3", + thread3_recv_dynamic_event, + RT_NULL, + &thread3_stack[0], + sizeof(thread3_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); + rt_thread_startup(&thread3); + + rt_thread_init(&thread4, + "thread4", + thread4_send_dynamic_event, + RT_NULL, + &thread4_stack[0], + sizeof(thread4_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(&thread4); + + while (dynamic_event_recv_thread_finish != 1 || dynamic_event_send_thread_finish != 1) + { + rt_thread_delay(1); + } + + if (recv_event_times1 == EVENT_FLAG3 && recv_event_times2 == (EVENT_FLAG3 | EVENT_FLAG5)) + { + if (rt_event_delete(dynamic_event) != RT_EOK) + { + uassert_false(1); + } + uassert_true(1); + } + else + { + if (rt_event_delete(dynamic_event) != RT_EOK) + { + uassert_false(1); + } + uassert_false(1); + } + + return; +} +#endif + +static rt_err_t utest_tc_init(void) +{ + static_event_recv_thread_finish = 0; + static_event_send_thread_finish = 0; +#ifdef RT_USING_HEAP + dynamic_event_recv_thread_finish = 0; + dynamic_event_send_thread_finish = 0; +#endif + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_event_init); + UTEST_UNIT_RUN(test_event_detach); + UTEST_UNIT_RUN(test_static_event_send_recv); +#ifdef RT_USING_HEAP + UTEST_UNIT_RUN(test_event_create); + UTEST_UNIT_RUN(test_event_delete); + UTEST_UNIT_RUN(test_dynamic_event_send_recv); +#endif +} +UTEST_TC_EXPORT(testcase, "src.ipc.event_tc", utest_tc_init, utest_tc_cleanup, 60); diff --git a/examples/utest/testcases/kernel/irq_tc.c b/examples/utest/testcases/kernel/irq_tc.c new file mode 100644 index 0000000000..86b6c144f1 --- /dev/null +++ b/examples/utest/testcases/kernel/irq_tc.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-15 supperthomas add irq_test + */ + +#include <rtthread.h> +#include "utest.h" +#include "rthw.h" + +#define UTEST_NAME "irq_tc" +static uint32_t irq_count = 0; +static uint32_t max_get_nest_count = 0; + +static void irq_callback() +{ + if(rt_interrupt_get_nest() > max_get_nest_count) + { + max_get_nest_count = rt_interrupt_get_nest(); + } + irq_count ++; +} + +static void irq_test(void) +{ + irq_count = 0; + rt_interrupt_enter_sethook(irq_callback); + rt_interrupt_leave_sethook(irq_callback); + rt_thread_mdelay(2); + LOG_D("%s test irq_test! irq_count %d max_get_nest_count %d\n", UTEST_NAME, irq_count, max_get_nest_count); + uassert_int_not_equal(0, irq_count); + uassert_int_not_equal(0, max_get_nest_count); + rt_interrupt_enter_sethook(RT_NULL); + rt_interrupt_leave_sethook(RT_NULL); + LOG_D("irq_test OK!\n"); +} + +static rt_err_t utest_tc_init(void) +{ + irq_count = 0; + max_get_nest_count = 0; + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void interrupt_test(void) +{ + rt_base_t level; + uint32_t i = 1000; + + rt_interrupt_enter_sethook(irq_callback); + rt_interrupt_leave_sethook(irq_callback); + irq_count = 0; + level = rt_hw_interrupt_disable(); + while(i) + { + i --; + } + uassert_int_equal(0, irq_count); + rt_hw_interrupt_enable(level); + rt_interrupt_enter_sethook(RT_NULL); + rt_interrupt_leave_sethook(RT_NULL); + +} +static void testcase(void) +{ + UTEST_UNIT_RUN(irq_test); + UTEST_UNIT_RUN(interrupt_test); +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.irq_tc", utest_tc_init, utest_tc_cleanup, 10); diff --git a/examples/utest/testcases/kernel/mailbox_tc.c b/examples/utest/testcases/kernel/mailbox_tc.c new file mode 100644 index 0000000000..e18613b559 --- /dev/null +++ b/examples/utest/testcases/kernel/mailbox_tc.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-09-08 liukang the first version + */ + +#include <rtthread.h> +#include "utest.h" +#include <stdlib.h> + +static struct rt_mailbox test_static_mb; +static char mb_pool[128]; + +static rt_mailbox_t test_dynamic_mb; + +static uint8_t static_mb_recv_thread_finish, static_mb_send_thread_finish; +static uint8_t dynamic_mb_recv_thread_finish, dynamic_mb_send_thread_finish; + +ALIGN(RT_ALIGN_SIZE) +static char thread1_stack[1024]; +static struct rt_thread thread1; + +ALIGN(RT_ALIGN_SIZE) +static char thread2_stack[1024]; +static struct rt_thread thread2; + +#define THREAD_PRIORITY 9 +#define THREAD_TIMESLICE 5 + +static rt_thread_t mb_send = RT_NULL; +static rt_thread_t mb_recv = RT_NULL; + +static rt_uint8_t mb_send_str1[] = "this is first mail!"; +static rt_uint8_t mb_send_str2[] = "this is second mail!"; +static rt_uint8_t mb_send_str3[] = "this is thirdy mail!"; + +static rt_uint8_t *mb_recv_str1; +static rt_uint8_t *mb_recv_str2; +static rt_uint8_t *mb_recv_str3; + +static void test_mailbox_init(void) +{ + rt_err_t result; + + result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO); + if (result != RT_EOK) + { + uassert_false(1); + } + result = rt_mb_detach(&test_static_mb); + if (result != RT_EOK) + { + uassert_false(1); + } + + result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_PRIO); + if (result != RT_EOK) + { + uassert_false(1); + } + + result = rt_mb_detach(&test_static_mb); + if (result != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static void test_mailbox_deatch(void) +{ + rt_err_t result; + + result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO); + if (result != RT_EOK) + { + uassert_false(1); + } + result = rt_mb_detach(&test_static_mb); + if (result != RT_EOK) + { + uassert_false(1); + } + + result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_PRIO); + if (result != RT_EOK) + { + uassert_false(1); + } + result = rt_mb_detach(&test_static_mb); + if (result != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static void test_mailbox_create(void) +{ + rt_err_t result; + + test_dynamic_mb = rt_mb_create("test_dynamic_mb", sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO); + if (test_dynamic_mb == RT_NULL) + { + uassert_false(1); + } + result = rt_mb_delete(test_dynamic_mb); + if (result != RT_EOK) + { + uassert_false(1); + } + + test_dynamic_mb = rt_mb_create("test_dynamic_mb", sizeof(mb_pool) / 4, RT_IPC_FLAG_PRIO); + if (test_dynamic_mb == RT_NULL) + { + uassert_false(1); + } + result = rt_mb_delete(test_dynamic_mb); + if (result != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static void test_mailbox_delete(void) +{ + rt_err_t result; + + test_dynamic_mb = rt_mb_create("test_dynamic_mb", sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO); + if (test_dynamic_mb == RT_NULL) + { + uassert_false(1); + } + result = rt_mb_delete(test_dynamic_mb); + if (result != RT_EOK) + { + uassert_false(1); + } + + test_dynamic_mb = rt_mb_create("test_dynamic_mb", sizeof(mb_pool) / 4, RT_IPC_FLAG_PRIO); + if (test_dynamic_mb == RT_NULL) + { + uassert_false(1); + } + result = rt_mb_delete(test_dynamic_mb); + if (result != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static void thread2_send_static_mb(void *arg) +{ + rt_err_t res = RT_EOK; + + res = rt_mb_send(&test_static_mb, (rt_ubase_t)&mb_send_str1); + if (res != RT_EOK) + { + uassert_false(1); + } + rt_thread_mdelay(100); + + res = rt_mb_send_wait(&test_static_mb, (rt_ubase_t)&mb_send_str2, 10); + if (res != RT_EOK) + { + uassert_false(1); + } + rt_thread_mdelay(100); + + res = rt_mb_urgent(&test_static_mb, (rt_ubase_t)&mb_send_str3); + if (res != RT_EOK) + { + uassert_false(1); + } + + static_mb_send_thread_finish = 1; +} + +static void thread1_recv_static_mb(void *arg) +{ + rt_err_t result = RT_EOK; + + result = rt_mb_recv(&test_static_mb, (rt_ubase_t *)&mb_recv_str1, RT_WAITING_FOREVER); + if (result != RT_EOK || strcmp(mb_recv_str1, mb_send_str1) != 0) + { + uassert_false(1); + } + + result = rt_mb_recv(&test_static_mb, (rt_ubase_t *)&mb_recv_str2, RT_WAITING_FOREVER); + if (result != RT_EOK || strcmp(mb_recv_str2, mb_send_str2) != 0) + { + uassert_false(1); + } + + result = rt_mb_recv(&test_static_mb, (rt_ubase_t *)&mb_recv_str3, RT_WAITING_FOREVER); + if (result != RT_EOK || strcmp(mb_recv_str3, mb_send_str3) != 0) + { + uassert_false(1); + } + + static_mb_recv_thread_finish = 1; +} + +static void test_static_mailbox_send_recv(void) +{ + rt_err_t result; + + result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO); + if (result != RT_EOK) + { + uassert_false(1); + } + + rt_thread_init(&thread1, + "thread1", + thread1_recv_static_mb, + RT_NULL, + &thread1_stack[0], + sizeof(thread1_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); + rt_thread_startup(&thread1); + + rt_thread_init(&thread2, + "thread2", + thread2_send_static_mb, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(&thread2); + + while (static_mb_recv_thread_finish != 1 || static_mb_send_thread_finish != 1) + { + rt_thread_delay(1); + } + + if (rt_mb_detach(&test_static_mb) != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static void thread4_send_dynamic_mb(void *arg) +{ + rt_err_t res = RT_EOK; + + res = rt_mb_send(test_dynamic_mb, (rt_ubase_t)&mb_send_str1); + if (res != RT_EOK) + { + uassert_false(1); + } + rt_thread_mdelay(100); + + res = rt_mb_send_wait(test_dynamic_mb, (rt_ubase_t)&mb_send_str2, 10); + if (res != RT_EOK) + { + uassert_false(1); + } + rt_thread_mdelay(100); + + res = rt_mb_urgent(test_dynamic_mb, (rt_ubase_t)&mb_send_str3); + if (res != RT_EOK) + { + uassert_false(1); + } + + dynamic_mb_send_thread_finish = 1; +} + +static void thread3_recv_dynamic_mb(void *arg) +{ + rt_err_t result = RT_EOK; + + result = rt_mb_recv(test_dynamic_mb, (rt_ubase_t *)&mb_recv_str1, RT_WAITING_FOREVER); + if (result != RT_EOK || strcmp(mb_recv_str1, mb_send_str1) != 0) + { + uassert_false(1); + } + + result = rt_mb_recv(test_dynamic_mb, (rt_ubase_t *)&mb_recv_str2, RT_WAITING_FOREVER); + if (result != RT_EOK || strcmp(mb_recv_str2, mb_send_str2) != 0) + { + uassert_false(1); + } + + result = rt_mb_recv(test_dynamic_mb, (rt_ubase_t *)&mb_recv_str3, RT_WAITING_FOREVER); + if (result != RT_EOK || strcmp(mb_recv_str3, mb_send_str3) != 0) + { + uassert_false(1); + } + + dynamic_mb_recv_thread_finish = 1; +} + +static void test_dynamic_mailbox_send_recv(void) +{ + test_dynamic_mb = rt_mb_create("mbt", sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO); + if (test_dynamic_mb == RT_NULL) + { + uassert_false(1); + } + + mb_recv = rt_thread_create("mb_recv_thread", + thread3_recv_dynamic_mb, + RT_NULL, + 1024, + THREAD_PRIORITY - 1, + THREAD_TIMESLICE); + if (mb_recv == RT_NULL) + { + uassert_false(1); + } + rt_thread_startup(mb_recv); + + mb_send = rt_thread_create("mb_send_thread", + thread4_send_dynamic_mb, + RT_NULL, + 1024, + THREAD_PRIORITY - 1, + THREAD_TIMESLICE); + if (mb_send == RT_NULL) + { + uassert_false(1); + } + rt_thread_startup(mb_send); + + while (dynamic_mb_recv_thread_finish != 1 || dynamic_mb_send_thread_finish != 1) + { + rt_thread_delay(1); + } + + if (rt_mb_delete(test_dynamic_mb) != RT_EOK) + { + uassert_false(1); + } + + uassert_true(1); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_mailbox_init); + UTEST_UNIT_RUN(test_mailbox_deatch); + UTEST_UNIT_RUN(test_mailbox_create); + UTEST_UNIT_RUN(test_mailbox_delete); + UTEST_UNIT_RUN(test_static_mailbox_send_recv); + UTEST_UNIT_RUN(test_dynamic_mailbox_send_recv); +} +UTEST_TC_EXPORT(testcase, "src.ipc.mailbox_tc", utest_tc_init, utest_tc_cleanup, 60); diff --git a/examples/utest/testcases/kernel/mem_tc.c b/examples/utest/testcases/kernel/mem_tc.c new file mode 100644 index 0000000000..028876dfa9 --- /dev/null +++ b/examples/utest/testcases/kernel/mem_tc.c @@ -0,0 +1,588 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-10-14 tyx the first version + */ + +#include <rtthread.h> +#include <stdlib.h> +#include "utest.h" + +struct rt_small_mem_item +{ + rt_ubase_t pool_ptr; /**< small memory object addr */ +#ifdef ARCH_CPU_64BIT + rt_uint32_t resv; +#endif /* ARCH_CPU_64BIT */ + rt_size_t next; /**< next free item */ + rt_size_t prev; /**< prev free item */ +#ifdef RT_USING_MEMTRACE +#ifdef ARCH_CPU_64BIT + rt_uint8_t thread[8]; /**< thread name */ +#else + rt_uint8_t thread[4]; /**< thread name */ +#endif /* ARCH_CPU_64BIT */ +#endif /* RT_USING_MEMTRACE */ +}; + +struct rt_small_mem +{ + struct rt_memory parent; /**< inherit from rt_memory */ + rt_uint8_t *heap_ptr; /**< pointer to the heap */ + struct rt_small_mem_item *heap_end; + struct rt_small_mem_item *lfree; + rt_size_t mem_size_aligned; /**< aligned memory size */ +}; + +#define MEM_SIZE(_heap, _mem) \ + (((struct rt_small_mem_item *)(_mem))->next - ((rt_ubase_t)(_mem) - \ + (rt_ubase_t)((_heap)->heap_ptr)) - RT_ALIGN(sizeof(struct rt_small_mem_item), RT_ALIGN_SIZE)) + +#define TEST_MEM_SIZE 1024 + +static rt_size_t max_block(struct rt_small_mem *heap) +{ + struct rt_small_mem_item *mem; + rt_size_t max = 0, size; + + for (mem = (struct rt_small_mem_item *)heap->heap_ptr; + mem != heap->heap_end; + mem = (struct rt_small_mem_item *)&heap->heap_ptr[mem->next]) + { + if (((rt_ubase_t)mem->pool_ptr & 0x1) == 0) + { + size = MEM_SIZE(heap, mem); + if (size > max) + { + max = size; + } + } + } + return max; +} + +static int _mem_cmp(void *ptr, rt_uint8_t v, rt_size_t size) +{ + while (size-- != 0) + { + if (*(rt_uint8_t *)ptr != v) + return *(rt_uint8_t *)ptr - v; + } + return 0; +} + +struct mem_test_context +{ + void *ptr; + rt_size_t size; + rt_uint8_t magic; +}; + +static void mem_functional_test(void) +{ + rt_size_t total_size; + rt_uint8_t *buf; + struct rt_small_mem *heap; + rt_uint8_t magic = __LINE__; + + /* Prepare test memory */ + buf = rt_malloc(TEST_MEM_SIZE); + uassert_not_null(buf); + uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf); + rt_memset(buf, 0xAA, TEST_MEM_SIZE); + /* small heap init */ + heap = (struct rt_small_mem *)rt_smem_init("mem_tc", buf, TEST_MEM_SIZE); + /* get total size */ + total_size = max_block(heap); + uassert_int_not_equal(total_size, 0); + /* + * Allocate all memory at a time and test whether + * the memory allocation release function is effective + */ + { + struct mem_test_context ctx; + ctx.magic = magic++; + ctx.size = max_block(heap); + ctx.ptr = rt_smem_alloc(&heap->parent, ctx.size); + uassert_not_null(ctx.ptr); + rt_memset(ctx.ptr, ctx.magic, ctx.size); + uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0); + rt_smem_free(ctx.ptr); + uassert_int_equal(max_block(heap), total_size); + } + /* + * Apply for memory release sequentially and + * test whether memory block merging is effective + */ + { + rt_size_t i, max_free = 0; + struct mem_test_context ctx[3]; + /* alloc mem */ + for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++) + { + ctx[i].magic = magic++; + ctx[i].size = max_block(heap) / (sizeof(ctx) / sizeof(ctx[0]) - i); + ctx[i].ptr = rt_smem_alloc(&heap->parent, ctx[i].size); + uassert_not_null(ctx[i].ptr); + rt_memset(ctx[i].ptr, ctx[i].magic, ctx[i].size); + } + /* All memory has been applied. The remaining memory should be 0 */ + uassert_int_equal(max_block(heap), 0); + /* Verify that the memory data is correct */ + for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++) + { + uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0); + } + /* Sequential memory release */ + for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++) + { + uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0); + rt_smem_free(ctx[i].ptr); + max_free += ctx[i].size; + uassert_true(max_block(heap) >= max_free); + } + /* Check whether the memory is fully merged */ + uassert_int_equal(max_block(heap), total_size); + } + /* + * Apply for memory release at an interval to + * test whether memory block merging is effective + */ + { + rt_size_t i, max_free = 0; + struct mem_test_context ctx[3]; + /* alloc mem */ + for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++) + { + ctx[i].magic = magic++; + ctx[i].size = max_block(heap) / (sizeof(ctx) / sizeof(ctx[0]) - i); + ctx[i].ptr = rt_smem_alloc(&heap->parent, ctx[i].size); + uassert_not_null(ctx[i].ptr); + rt_memset(ctx[i].ptr, ctx[i].magic, ctx[i].size); + } + /* All memory has been applied. The remaining memory should be 0 */ + uassert_int_equal(max_block(heap), 0); + /* Verify that the memory data is correct */ + for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++) + { + uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0); + } + /* Release even address */ + for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++) + { + if (i % 2 == 0) + { + uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0); + rt_smem_free(ctx[i].ptr); + uassert_true(max_block(heap) >= ctx[0].size); + } + } + /* Release odd addresses and merge memory blocks */ + for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++) + { + if (i % 2 != 0) + { + uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0); + rt_smem_free(ctx[i].ptr); + max_free += ctx[i - 1].size + ctx[i + 1].size; + uassert_true(max_block(heap) >= max_free); + } + } + /* Check whether the memory is fully merged */ + uassert_int_equal(max_block(heap), total_size); + } + /* mem realloc test,Small - > Large */ + { + /* Request a piece of memory for subsequent reallocation operations */ + struct mem_test_context ctx[3]; + ctx[0].magic = magic++; + ctx[0].size = max_block(heap) / 3; + ctx[0].ptr = rt_smem_alloc(&heap->parent, ctx[0].size); + uassert_not_null(ctx[0].ptr); + rt_memset(ctx[0].ptr, ctx[0].magic, ctx[0].size); + /* Apply for a small piece of memory and split the continuous memory */ + ctx[1].magic = magic++; + ctx[1].size = RT_ALIGN_SIZE; + ctx[1].ptr = rt_smem_alloc(&heap->parent, ctx[1].size); + uassert_not_null(ctx[1].ptr); + rt_memset(ctx[1].ptr, ctx[1].magic, ctx[1].size); + /* Check whether the maximum memory block is larger than the first piece of memory */ + uassert_true(max_block(heap) > ctx[0].size); + /* Reallocate the first piece of memory */ + ctx[2].magic = magic++; + ctx[2].size = max_block(heap); + ctx[2].ptr = rt_smem_realloc(&heap->parent, ctx[0].ptr, ctx[2].size); + uassert_not_null(ctx[2].ptr); + uassert_int_not_equal(ctx[0].ptr, ctx[2].ptr); + uassert_int_equal(_mem_cmp(ctx[2].ptr, ctx[0].magic, ctx[0].size), 0); + rt_memset(ctx[2].ptr, ctx[2].magic, ctx[2].size); + /* Free the second piece of memory */ + uassert_int_equal(_mem_cmp(ctx[1].ptr, ctx[1].magic, ctx[1].size), 0); + rt_smem_free(ctx[1].ptr); + /* Free reallocated memory */ + uassert_int_equal(_mem_cmp(ctx[2].ptr, ctx[2].magic, ctx[2].size), 0); + rt_smem_free(ctx[2].ptr); + /* Check memory integrity */ + uassert_int_equal(max_block(heap), total_size); + } + /* mem realloc test,Large - > Small */ + { + rt_size_t max_free; + struct mem_test_context ctx; + /* alloc a piece of memory */ + ctx.magic = magic++; + ctx.size = max_block(heap) / 2; + ctx.ptr = rt_smem_alloc(&heap->parent, ctx.size); + uassert_not_null(ctx.ptr); + rt_memset(ctx.ptr, ctx.magic, ctx.size); + uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0); + /* Get remaining memory */ + max_free = max_block(heap); + /* Change memory size */ + ctx.size = ctx.size / 2; + uassert_int_equal((rt_ubase_t)rt_smem_realloc(&heap->parent, ctx.ptr, ctx.size), (rt_ubase_t)ctx.ptr); + /* Get remaining size */ + uassert_true(max_block(heap) > max_free); + /* Free memory */ + uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0); + rt_smem_free(ctx.ptr); + /* Check memory integrity */ + uassert_int_equal(max_block(heap), total_size); + } + /* mem realloc test,equal */ + { + rt_size_t max_free; + struct mem_test_context ctx; + /* alloc a piece of memory */ + ctx.magic = magic++; + ctx.size = max_block(heap) / 2; + ctx.ptr = rt_smem_alloc(&heap->parent, ctx.size); + uassert_not_null(ctx.ptr); + rt_memset(ctx.ptr, ctx.magic, ctx.size); + uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0); + /* Get remaining memory */ + max_free = max_block(heap); + /* Do not change memory size */ + uassert_int_equal((rt_ubase_t)rt_smem_realloc(&heap->parent, ctx.ptr, ctx.size), (rt_ubase_t)ctx.ptr); + /* Get remaining size */ + uassert_true(max_block(heap) == max_free); + /* Free memory */ + uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0); + rt_smem_free(ctx.ptr); + /* Check memory integrity */ + uassert_int_equal(max_block(heap), total_size); + } + /* small heap deinit */ + rt_smem_detach(&heap->parent); + /* release test resources */ + rt_free(buf); +} + +struct mem_alloc_context +{ + rt_list_t node; + rt_size_t size; + rt_uint8_t magic; +}; + +struct mem_alloc_head +{ + rt_list_t list; + rt_size_t count; + rt_tick_t start; + rt_tick_t end; + rt_tick_t interval; +}; + +#define MEM_RANG_ALLOC_BLK_MIN 2 +#define MEM_RANG_ALLOC_BLK_MAX 5 +#define MEM_RANG_ALLOC_TEST_TIME 5 + +static void mem_alloc_test(void) +{ + struct mem_alloc_head head; + rt_uint8_t *buf; + struct rt_small_mem *heap; + rt_size_t total_size, size; + struct mem_alloc_context *ctx; + + /* init */ + rt_list_init(&head.list); + head.count = 0; + head.start = rt_tick_get(); + head.end = rt_tick_get() + rt_tick_from_millisecond(MEM_RANG_ALLOC_TEST_TIME * 1000); + head.interval = (head.end - head.start) / 20; + buf = rt_malloc(TEST_MEM_SIZE); + uassert_not_null(buf); + uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf); + rt_memset(buf, 0xAA, TEST_MEM_SIZE); + heap = (struct rt_small_mem *)rt_smem_init("mem_tc", buf, TEST_MEM_SIZE); + total_size = max_block(heap); + uassert_int_not_equal(total_size, 0); + /* test run */ + while (head.end - head.start < RT_TICK_MAX / 2) + { + if (rt_tick_get() - head.start >= head.interval) + { + head.start = rt_tick_get(); + rt_kprintf("#"); + } + /* %60 probability to perform alloc operation */ + if (rand() % 10 >= 4) + { + size = rand() % MEM_RANG_ALLOC_BLK_MAX + MEM_RANG_ALLOC_BLK_MIN; + size *= sizeof(struct mem_alloc_context); + ctx = rt_smem_alloc(&heap->parent, size); + if (ctx == RT_NULL) + { + if (head.count == 0) + { + break; + } + size = head.count / 2; + while (size != head.count) + { + ctx = rt_list_first_entry(&head.list, struct mem_alloc_context, node); + rt_list_remove(&ctx->node); + if (ctx->size > sizeof(*ctx)) + { + if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0) + { + uassert_true(0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_smem_free(ctx); + head.count --; + } + continue; + } + if (RT_ALIGN((rt_ubase_t)ctx, RT_ALIGN_SIZE) != (rt_ubase_t)ctx) + { + uassert_int_equal(RT_ALIGN((rt_ubase_t)ctx, RT_ALIGN_SIZE), (rt_ubase_t)ctx); + } + rt_memset(ctx, 0, size); + rt_list_init(&ctx->node); + ctx->size = size; + ctx->magic = rand() & 0xff; + if (ctx->size > sizeof(*ctx)) + { + rt_memset(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + } + rt_list_insert_after(&head.list, &ctx->node); + head.count += 1; + } + else + { + if (!rt_list_isempty(&head.list)) + { + ctx = rt_list_first_entry(&head.list, struct mem_alloc_context, node); + rt_list_remove(&ctx->node); + if (ctx->size > sizeof(*ctx)) + { + if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0) + { + uassert_true(0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_smem_free(ctx); + head.count --; + } + } + } + while (!rt_list_isempty(&head.list)) + { + ctx = rt_list_first_entry(&head.list, struct mem_alloc_context, node); + rt_list_remove(&ctx->node); + if (ctx->size > sizeof(*ctx)) + { + if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0) + { + uassert_true(0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_smem_free(ctx); + head.count --; + } + uassert_int_equal(head.count, 0); + uassert_int_equal(max_block(heap), total_size); + /* small heap deinit */ + rt_smem_detach(&heap->parent); + /* release test resources */ + rt_free(buf); +} + +#define MEM_RANG_REALLOC_BLK_MIN 0 +#define MEM_RANG_REALLOC_BLK_MAX 5 +#define MEM_RANG_REALLOC_TEST_TIME 5 + +struct mem_realloc_context +{ + rt_size_t size; + rt_uint8_t magic; +}; + +struct mem_realloc_head +{ + struct mem_realloc_context **ctx_tab; + rt_size_t count; + rt_tick_t start; + rt_tick_t end; + rt_tick_t interval; +}; + +static void mem_realloc_test(void) +{ + struct mem_realloc_head head; + rt_uint8_t *buf; + struct rt_small_mem *heap; + rt_size_t total_size, size, idx; + struct mem_realloc_context *ctx; + int res; + + size = RT_ALIGN(sizeof(struct mem_realloc_context), RT_ALIGN_SIZE) + RT_ALIGN_SIZE; + size = TEST_MEM_SIZE / size; + /* init */ + head.ctx_tab = RT_NULL; + head.count = size; + head.start = rt_tick_get(); + head.end = rt_tick_get() + rt_tick_from_millisecond(MEM_RANG_ALLOC_TEST_TIME * 1000); + head.interval = (head.end - head.start) / 20; + buf = rt_malloc(TEST_MEM_SIZE); + uassert_not_null(buf); + uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf); + rt_memset(buf, 0xAA, TEST_MEM_SIZE); + heap = (struct rt_small_mem *)rt_smem_init("mem_tc", buf, TEST_MEM_SIZE); + total_size = max_block(heap); + uassert_int_not_equal(total_size, 0); + /* init ctx tab */ + size = head.count * sizeof(struct mem_realloc_context *); + head.ctx_tab = rt_smem_alloc(&heap->parent, size); + uassert_not_null(head.ctx_tab); + rt_memset(head.ctx_tab, 0, size); + /* test run */ + while (head.end - head.start < RT_TICK_MAX / 2) + { + if (rt_tick_get() - head.start >= head.interval) + { + head.start = rt_tick_get(); + rt_kprintf("#"); + } + size = rand() % MEM_RANG_ALLOC_BLK_MAX + MEM_RANG_ALLOC_BLK_MIN; + size *= sizeof(struct mem_realloc_context); + idx = rand() % head.count; + ctx = rt_smem_realloc(&heap->parent, head.ctx_tab[idx], size); + if (ctx == RT_NULL) + { + if (size == 0) + { + if (head.ctx_tab[idx]) + { + head.ctx_tab[idx] = RT_NULL; + } + } + else + { + for (idx = 0; idx < head.count; idx++) + { + ctx = head.ctx_tab[idx]; + if (rand() % 2 && ctx) + { + if (ctx->size > sizeof(*ctx)) + { + res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + if (res != 0) + { + uassert_int_equal(res, 0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_smem_realloc(&heap->parent, ctx, 0); + head.ctx_tab[idx] = RT_NULL; + } + } + } + continue; + } + /* check mem */ + if (head.ctx_tab[idx] != RT_NULL) + { + res = 0; + if (ctx->size < size) + { + if (ctx->size > sizeof(*ctx)) + { + res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + } + } + else + { + if (size > sizeof(*ctx)) + { + res = _mem_cmp(&ctx[1], ctx->magic, size - sizeof(*ctx)); + } + } + if (res != 0) + { + uassert_int_equal(res, 0); + } + } + /* init mem */ + ctx->magic = rand() & 0xff; + ctx->size = size; + if (ctx->size > sizeof(*ctx)) + { + rt_memset(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + } + head.ctx_tab[idx] = ctx; + } + /* free all mem */ + for (idx = 0; idx < head.count; idx++) + { + ctx = head.ctx_tab[idx]; + if (ctx == RT_NULL) + { + continue; + } + if (ctx->size > sizeof(*ctx)) + { + res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + if (res != 0) + { + uassert_int_equal(res, 0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_smem_realloc(&heap->parent, ctx, 0); + head.ctx_tab[idx] = RT_NULL; + } + uassert_int_not_equal(max_block(heap), total_size); + /* small heap deinit */ + rt_smem_detach(&heap->parent); + /* release test resources */ + rt_free(buf); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(mem_functional_test); + UTEST_UNIT_RUN(mem_alloc_test); + UTEST_UNIT_RUN(mem_realloc_test); +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.mem_tc", utest_tc_init, utest_tc_cleanup, 20); diff --git a/examples/utest/testcases/kernel/memheap_tc.c b/examples/utest/testcases/kernel/memheap_tc.c new file mode 100644 index 0000000000..ee52bdb185 --- /dev/null +++ b/examples/utest/testcases/kernel/memheap_tc.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-01-16 flybreak the first version + */ + +#include <rtthread.h> +#include <stdlib.h> +#include "utest.h" + +#define HEAP_SIZE (64 * 1024) +#define HEAP_ALIGN (4) +#define SLICE_NUM (40) +#define TEST_TIMES (100000) +#define HEAP_NAME "heap1" +#define SLICE_SIZE_MAX (HEAP_SIZE/SLICE_NUM) + +static void memheap_test(void) +{ + struct rt_memheap heap1; + rt_uint32_t ptr_start; + void *ptr[SLICE_NUM]; + int i, cnt = 0; + + /* init heap */ + ptr_start = (rt_uint32_t)rt_malloc_align(HEAP_SIZE, HEAP_ALIGN); + if (ptr_start == RT_NULL) + { + rt_kprintf("totle size too big,can not malloc memory!"); + return; + } + + rt_memheap_init(&heap1, HEAP_NAME, (void *)ptr_start, HEAP_SIZE); + + /* test start */ + for (i = 0; i < SLICE_NUM; i++) + { + ptr[i] = 0; + } + /* test alloc */ + for (i = 0; i < SLICE_NUM; i++) + { + rt_uint32_t slice_size = rand() % SLICE_SIZE_MAX; + ptr[i] = rt_memheap_alloc(&heap1, slice_size); + } + /* test realloc */ + while (cnt < TEST_TIMES) + { + rt_uint32_t slice_size = rand() % SLICE_SIZE_MAX; + rt_uint32_t ptr_index = rand() % SLICE_NUM; + rt_uint32_t operation = rand() % 2; + + if (ptr[ptr_index]) + { + if (operation == 0) /* free and malloc */ + { + if (ptr[ptr_index]) + { + rt_memheap_free(ptr[ptr_index]); + } + ptr[ptr_index] = rt_memheap_alloc(&heap1, slice_size); + } + else /* realloc */ + { + ptr[ptr_index] = rt_memheap_realloc(&heap1, ptr[ptr_index], slice_size); + } + } + cnt ++; + if (cnt % (TEST_TIMES / 10) == 0) + { + rt_kprintf(">"); + } + } + + rt_kprintf("test OK!\n"); + + /* test end */ + rt_memheap_detach(&heap1); + rt_free_align((void *)ptr_start); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(memheap_test); +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.memheap_tc", utest_tc_init, utest_tc_cleanup, 10); diff --git a/examples/utest/testcases/kernel/messagequeue_tc.c b/examples/utest/testcases/kernel/messagequeue_tc.c new file mode 100644 index 0000000000..335c591ab6 --- /dev/null +++ b/examples/utest/testcases/kernel/messagequeue_tc.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-28 Sherman the first version + */ + +#include <rtthread.h> +#include "utest.h" + +#define MSG_SIZE 4 +#define MAX_MSGS 5 + +static struct rt_messagequeue static_mq; +static rt_uint8_t mq_buf[(MSG_SIZE + 4) * MAX_MSGS]; + +static struct rt_thread mq_send_thread; +static struct rt_thread mq_recv_thread; +static rt_uint8_t mq_send_stack[512]; +static rt_uint8_t mq_recv_stack[512]; + +static struct rt_event finish_e; +#define MQSEND_FINISH 0x01 +#define MQRECV_FINIHS 0x02 + +#ifdef RT_USING_HEAP +static rt_mq_t dynamic_mq; +#endif /* RT_USING_HEAP */ + +static void test_mq_init(void) +{ + rt_err_t ret; + ret = rt_mq_init(&static_mq,"testmq1", mq_buf, MSG_SIZE, sizeof(mq_buf), RT_IPC_FLAG_FIFO); + uassert_true(ret == RT_EOK); +} + +static void test_mq_create(void) +{ +#ifdef RT_USING_HEAP + dynamic_mq = rt_mq_create("testmq2", MSG_SIZE, MAX_MSGS, RT_IPC_FLAG_FIFO); + uassert_true(dynamic_mq != RT_NULL); +#endif /* RT_USING_HEAP */ +} + +static void mq_send_case(rt_mq_t testmq) +{ + rt_uint32_t send_buf[MAX_MSGS+1] = {0}; + rt_err_t ret = RT_EOK; + + for (int var = 0; var < MAX_MSGS; ++var) + { + send_buf[var] = var + 1; + ret = rt_mq_send_wait(testmq, &send_buf[var], sizeof(send_buf[0]), RT_WAITING_FOREVER); + uassert_true(ret == RT_EOK); + } + send_buf[MAX_MSGS] = MAX_MSGS + 1; + ret = rt_mq_send(testmq, &send_buf[MAX_MSGS], sizeof(send_buf[0])); + uassert_true(ret == -RT_EFULL); + + ret = rt_mq_send_wait(testmq, &send_buf[MAX_MSGS], sizeof(send_buf[0]), RT_WAITING_FOREVER); + uassert_true(ret == RT_EOK); + + while (testmq->entry != 0) + { + rt_thread_delay(100); + } + + ret = rt_mq_send(testmq, &send_buf[1], sizeof(send_buf[0])); + uassert_true(ret == RT_EOK); + + ret = rt_mq_send(testmq, &send_buf[2], sizeof(send_buf[0])); + uassert_true(ret == RT_EOK); + + ret = rt_mq_urgent(testmq, &send_buf[0], sizeof(send_buf[0])); + uassert_true(ret == RT_EOK); + + while (testmq->entry != 0) + { + rt_thread_delay(100); + } + + ret = rt_mq_send(testmq, &send_buf[1], sizeof(send_buf[0])); + uassert_true(ret == RT_EOK); + ret = rt_mq_control(testmq, RT_IPC_CMD_RESET, RT_NULL); + uassert_true(ret == RT_EOK); + uassert_true(testmq->entry == 0); +} + +static void mq_send_entry(void *param) +{ + mq_send_case(&static_mq); + +#ifdef RT_USING_HEAP + if(dynamic_mq != RT_NULL) + { + mq_send_case(dynamic_mq); + } +#endif /* RT_USING_HEAP */ + + rt_event_send(&finish_e, MQSEND_FINISH); +} + +static void mq_recv_case(rt_mq_t testmq) +{ + rt_uint32_t recv_buf[MAX_MSGS+1] = {0}; + rt_err_t ret = RT_EOK; + + for (int var = 0; var < MAX_MSGS + 1; ++var) + { + ret = rt_mq_recv(testmq, &recv_buf[var], sizeof(recv_buf[0]), RT_WAITING_FOREVER); + uassert_true(ret == RT_EOK); + uassert_true(recv_buf[var] == (var + 1)); + } + + for (int var = 0; var < 3; ++var) + { + ret = rt_mq_recv(testmq, &recv_buf[var], sizeof(recv_buf[0]), RT_WAITING_FOREVER); + uassert_true(ret == RT_EOK); + uassert_true(recv_buf[var] == (var + 1)); + } +} + +static void mq_recv_entry(void *param) +{ + mq_recv_case(&static_mq); + +#ifdef RT_USING_HEAP + if(dynamic_mq != RT_NULL) + { + mq_recv_case(dynamic_mq); + } +#endif /* RT_USING_HEAP */ + rt_event_send(&finish_e, MQRECV_FINIHS); +} + +static void test_mq_testcase(void) +{ + rt_thread_startup(&mq_send_thread); + rt_thread_startup(&mq_recv_thread); + + rt_event_recv(&finish_e, MQSEND_FINISH | MQRECV_FINIHS, RT_EVENT_FLAG_AND, RT_WAITING_FOREVER, RT_NULL); +} + +static void test_mq_detach(void) +{ + rt_err_t ret = rt_mq_detach(&static_mq); + uassert_true(ret == RT_EOK); +} + +static void test_mq_delete(void) +{ +#ifdef RT_USING_HEAP + rt_err_t ret = rt_mq_delete(dynamic_mq); + uassert_true(ret == RT_EOK); +#endif /* RT_USING_HEAP */ +} + +static rt_err_t utest_tc_init(void) +{ + rt_err_t ret ; + ret = rt_thread_init(&mq_send_thread, "mq_send", mq_send_entry, RT_NULL, mq_send_stack, sizeof(mq_send_stack), 22, 20); + if(ret != RT_EOK) + return -RT_ERROR; + + ret = rt_thread_init(&mq_recv_thread, "mq_recv", mq_recv_entry, RT_NULL, mq_recv_stack, sizeof(mq_recv_stack), 23, 20); + if(ret != RT_EOK) + return -RT_ERROR; + + ret = rt_event_init(&finish_e, "finish", RT_IPC_FLAG_FIFO); + if(ret != RT_EOK) + return -RT_ERROR; + + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_mq_init); + UTEST_UNIT_RUN(test_mq_create); + UTEST_UNIT_RUN(test_mq_testcase); + UTEST_UNIT_RUN(test_mq_detach); + UTEST_UNIT_RUN(test_mq_delete); +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.messagequeue_tc", utest_tc_init, utest_tc_cleanup, 1000); diff --git a/examples/utest/testcases/kernel/mutex_tc.c b/examples/utest/testcases/kernel/mutex_tc.c new file mode 100644 index 0000000000..9a25219a1a --- /dev/null +++ b/examples/utest/testcases/kernel/mutex_tc.c @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-09.01 luckyzjq the first version + */ + +#include <rtthread.h> +#include <stdlib.h> +#include "utest.h" + +static struct rt_mutex static_mutex; + +#ifdef RT_USING_HEAP +static rt_mutex_t dynamic_mutex; +#endif /* RT_USING_HEAP */ + +/* init test */ +static void test_static_mutex_init(void) +{ + rt_err_t result = -RT_ERROR; + + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + result = rt_mutex_detach(&static_mutex); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + result = rt_mutex_detach(&static_mutex); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + uassert_true(RT_TRUE); +} + +/* static take test */ +static void static_mutex_take_entry(void *param) +{ + rt_err_t result; + rt_mutex_t mutex; + + int rand_num = rand() % 0x1000; + mutex = (rt_mutex_t)param; + + result = rt_mutex_take(mutex, rand_num); + if (RT_EOK == result) + { + uassert_true(RT_FALSE); + } +} +static void test_static_mutex_take(void) +{ + rt_err_t result; + + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + /* take mutex and not release */ + result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + rt_thread_t tid = rt_thread_create("mutex_th", + static_mutex_take_entry, + &static_mutex, + 2048, + 10, + 10); + if (RT_NULL == tid) + { + uassert_true(RT_FALSE); + return; + } + + /* startup thread take second */ + rt_thread_startup(tid); + + /* let system schedule */ + rt_thread_mdelay(5); + + result = rt_mutex_detach(&static_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + uassert_true(RT_TRUE); +} + +/* static release test */ +static void static_mutex_release_entry(void *param) +{ + rt_err_t result; + rt_mutex_t mutex; + + int rand_num = rand() % 0x1000; + mutex = (rt_mutex_t)param; + + result = rt_mutex_take(mutex, rand_num); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} +static void test_static_mutex_release(void) +{ + rt_err_t result; + + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + /* take mutex */ + result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + /* release mutex */ + result = rt_mutex_release(&static_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + rt_thread_t tid = rt_thread_create("mutex_th", + static_mutex_release_entry, + &static_mutex, + 2048, + 10, + 10); + if (RT_NULL == tid) + { + uassert_true(RT_FALSE); + return; + } + + /* startup thread and take mutex second */ + rt_thread_startup(tid); + + /* let system schedule */ + rt_thread_mdelay(5); + + result = rt_mutex_detach(&static_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + uassert_true(RT_TRUE); +} + +/* static trytake test */ +static void static_mutex_trytake_entry(void *param) +{ + rt_err_t result; + rt_mutex_t mutex; + + mutex = (rt_mutex_t)param; + + result = rt_mutex_trytake(mutex); + if (RT_EOK == result) + { + uassert_true(RT_FALSE); + } +} +static void test_static_mutex_trytake(void) +{ + rt_err_t result; + + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + /* take mutex and not release */ + result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + rt_thread_t tid = rt_thread_create("mutex_th", + static_mutex_trytake_entry, + &static_mutex, + 2048, + 10, + 10); + if (RT_NULL == tid) + { + uassert_true(RT_FALSE); + return; + } + + /* startup thread and trytake mutex second */ + rt_thread_startup(tid); + + /* let system schedule */ + rt_thread_mdelay(5); + + result = rt_mutex_detach(&static_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + uassert_true(RT_TRUE); +} + +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; +static rt_thread_t tid3 = RT_NULL; + +/* static mutex priority reverse test */ +static void static_thread1_entry(void *param) +{ + /* let system schedule */ + rt_thread_mdelay(100); + + /* thread3 hode mutex thread2 take mutex */ + /* check thread2 and thread3 priority */ + if (tid2->current_priority != tid3->current_priority) + { + uassert_true(RT_FALSE); + } + else + { + uassert_true(RT_TRUE); + } +} + +static void static_thread2_entry(void *param) +{ + rt_err_t result; + rt_mutex_t mutex = (rt_mutex_t)param; + + /* let system schedule */ + rt_thread_mdelay(50); + + result = rt_mutex_take(mutex, RT_WAITING_FOREVER); + if (result == RT_EOK) + { + rt_mutex_release(mutex); + } +} +static void static_thread3_entry(void *param) +{ + rt_tick_t tick; + rt_err_t result; + rt_mutex_t mutex = (rt_mutex_t)param; + + result = rt_mutex_take(mutex, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + uassert_true(RT_FALSE); + } + + tick = rt_tick_get(); + while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2)); + + rt_mutex_release(mutex); +} + +static void test_static_pri_reverse(void) +{ + rt_err_t result; + tid1 = RT_NULL; + tid2 = RT_NULL; + tid3 = RT_NULL; + + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + /* thread1 */ + tid1 = rt_thread_create("thread1", + static_thread1_entry, + &static_mutex, + 1024, + 10 - 1, + 10); + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + + /* thread2 */ + tid2 = rt_thread_create("thread2", + static_thread2_entry, + &static_mutex, + 1024, + 10, + 10); + if (tid2 != RT_NULL) + rt_thread_startup(tid2); + + /* thread3 */ + tid3 = rt_thread_create("thread3", + static_thread3_entry, + &static_mutex, + 1024, + 10 + 1, + 10); + if (tid3 != RT_NULL) + rt_thread_startup(tid3); + + rt_thread_mdelay(1000); + + result = rt_mutex_detach(&static_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + uassert_true(RT_TRUE); +} + +/* create test */ +static void test_dynamic_mutex_create(void) +{ + rt_err_t result = -RT_ERROR; + + /* PRIO mode */ + dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); + if (RT_NULL == result) + { + uassert_true(RT_FALSE); + } + + result = rt_mutex_delete(dynamic_mutex); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + /* FIFO mode */ + dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); + if (RT_NULL == dynamic_mutex) + { + uassert_true(RT_FALSE); + } + + result = rt_mutex_delete(dynamic_mutex); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + uassert_true(RT_TRUE); +} + +/* dynamic take test */ +static void dynamic_mutex_take_entry(void *param) +{ + rt_err_t result; + rt_mutex_t mutex; + + int rand_num = rand() % 0x1000; + mutex = (rt_mutex_t)param; + + result = rt_mutex_take(mutex, rand_num); + if (RT_EOK == result) + { + uassert_true(RT_FALSE); + } +} +static void test_dynamic_mutex_take(void) +{ + rt_err_t result; + + dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); + if (RT_NULL == dynamic_mutex) + { + uassert_true(RT_FALSE); + return; + } + + /* take mutex and not release */ + result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + rt_thread_t tid = rt_thread_create("mutex_th", + dynamic_mutex_take_entry, + dynamic_mutex, + 2048, + 10, + 10); + if (RT_NULL == tid) + { + uassert_true(RT_FALSE); + return; + } + + /* startup thread take second */ + rt_thread_startup(tid); + + /* let system schedule */ + rt_thread_mdelay(5); + + result = rt_mutex_delete(dynamic_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + uassert_true(RT_TRUE); +} + +/* dynamic release test */ +static void dynamic_mutex_release_entry(void *param) +{ + rt_err_t result; + rt_mutex_t mutex; + + int rand_num = rand() % 0x1000; + mutex = (rt_mutex_t)param; + + result = rt_mutex_take(mutex, rand_num); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} +static void test_dynamic_mutex_release(void) +{ + rt_err_t result; + + dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); + if (RT_NULL == dynamic_mutex) + { + uassert_true(RT_FALSE); + return; + } + + /* take mutex */ + result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + /* release mutex */ + result = rt_mutex_release(dynamic_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + rt_thread_t tid = rt_thread_create("mutex_th", + dynamic_mutex_release_entry, + dynamic_mutex, + 2048, + 10, + 10); + if (RT_NULL == tid) + { + uassert_true(RT_FALSE); + return; + } + + /* startup thread and take mutex second */ + rt_thread_startup(tid); + + /* let system schedule */ + rt_thread_mdelay(5); + + result = rt_mutex_delete(dynamic_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + uassert_true(RT_TRUE); +} + +/* dynamic trytake test */ +static void dynamic_mutex_trytake_entry(void *param) +{ + rt_err_t result; + rt_mutex_t mutex; + + mutex = (rt_mutex_t)param; + + result = rt_mutex_trytake(mutex); + if (RT_EOK == result) + { + uassert_true(RT_FALSE); + } +} +static void test_dynamic_mutex_trytake(void) +{ + rt_err_t result; + + dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); + if (RT_NULL == dynamic_mutex) + { + uassert_true(RT_FALSE); + return; + } + + /* take mutex and not release */ + result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + rt_thread_t tid = rt_thread_create("mutex_th", + dynamic_mutex_trytake_entry, + dynamic_mutex, + 2048, + 10, + 10); + if (RT_NULL == tid) + { + uassert_true(RT_FALSE); + return; + } + + /* startup thread and trytake mutex second */ + rt_thread_startup(tid); + + /* let system schedule */ + rt_thread_mdelay(5); + + result = rt_mutex_delete(dynamic_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + uassert_true(RT_TRUE); +} + +/* dynamic mutex priority reverse test */ +static void dynamic_thread1_entry(void *param) +{ + /* let system schedule */ + rt_thread_mdelay(100); + + /* thread3 hode mutex thread2 take mutex */ + /* check thread2 and thread3 priority */ + if (tid2->current_priority != tid3->current_priority) + { + uassert_true(RT_FALSE); + } + else + { + uassert_true(RT_TRUE); + } +} + +static void dynamic_thread2_entry(void *param) +{ + rt_err_t result; + rt_mutex_t mutex = (rt_mutex_t)param; + + /* let system schedule */ + rt_thread_mdelay(50); + + result = rt_mutex_take(mutex, RT_WAITING_FOREVER); + if (result == RT_EOK) + { + rt_mutex_release(mutex); + } +} +static void dynamic_thread3_entry(void *param) +{ + rt_tick_t tick; + rt_err_t result; + rt_mutex_t mutex = (rt_mutex_t)param; + + result = rt_mutex_take(mutex, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + uassert_true(RT_FALSE); + } + + tick = rt_tick_get(); + while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2)); + + rt_mutex_release(mutex); +} + +static void test_dynamic_pri_reverse(void) +{ + rt_err_t result; + tid1 = RT_NULL; + tid2 = RT_NULL; + tid3 = RT_NULL; + + dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); + if (RT_NULL == dynamic_mutex) + { + uassert_true(RT_FALSE); + return; + } + + /* thread1 */ + tid1 = rt_thread_create("thread1", + dynamic_thread1_entry, + dynamic_mutex, + 1024, + 10 - 1, + 10); + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + + /* thread2 */ + tid2 = rt_thread_create("thread2", + dynamic_thread2_entry, + dynamic_mutex, + 1024, + 10, + 10); + if (tid2 != RT_NULL) + rt_thread_startup(tid2); + + /* thread3 */ + tid3 = rt_thread_create("thread3", + dynamic_thread3_entry, + dynamic_mutex, + 1024, + 10 + 1, + 10); + if (tid3 != RT_NULL) + rt_thread_startup(tid3); + + rt_thread_mdelay(1000); + + result = rt_mutex_delete(dynamic_mutex); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + uassert_true(RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ +#ifdef RT_USING_HEAP + dynamic_mutex = RT_NULL; +#endif /* RT_USING_HEAP */ + + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ +#ifdef RT_USING_HEAP + dynamic_mutex = RT_NULL; +#endif /* RT_USING_HEAP */ + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_static_mutex_init); + UTEST_UNIT_RUN(test_static_mutex_take); + UTEST_UNIT_RUN(test_static_mutex_release); + UTEST_UNIT_RUN(test_static_mutex_trytake); + UTEST_UNIT_RUN(test_static_pri_reverse); +#ifdef RT_USING_HEAP + UTEST_UNIT_RUN(test_dynamic_mutex_create); + UTEST_UNIT_RUN(test_dynamic_mutex_take); + UTEST_UNIT_RUN(test_dynamic_mutex_release); + UTEST_UNIT_RUN(test_dynamic_mutex_trytake); + UTEST_UNIT_RUN(test_dynamic_pri_reverse); +#endif +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.mutex_tc", utest_tc_init, utest_tc_cleanup, 1000); + +/********************* end of file ************************/ diff --git a/examples/utest/testcases/kernel/semaphore_tc.c b/examples/utest/testcases/kernel/semaphore_tc.c new file mode 100644 index 0000000000..2992831d87 --- /dev/null +++ b/examples/utest/testcases/kernel/semaphore_tc.c @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-12 luckyzjq the first version + */ + +#include <rtthread.h> +#include <stdlib.h> +#include "utest.h" + +static struct rt_semaphore static_semaphore; +#ifdef RT_USING_HEAP +static rt_sem_t dynamic_semaphore; +#endif /* RT_USING_HEAP */ + +static void test_static_semaphore_init(void) +{ + rt_err_t result; + int rand_num = rand() % 0x10000; + + for (int i = 0; i < rand_num; i++) + { + result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + rt_sem_detach(&static_semaphore); + + result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_FIFO); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + rt_sem_detach(&static_semaphore); + } + + uassert_true(RT_TRUE); +} + +static void test_static_semaphore_detach(void) +{ + rt_err_t result; + int rand_num = rand() % 0x10000; + + for (int i = 0; i < rand_num; i++) + { + result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_PRIO); + if (RT_EOK != result) + { + break; + } + + result = rt_sem_detach(&static_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + + result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_FIFO); + if (RT_EOK != result) + { + break; + } + result = rt_sem_detach(&static_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + } + + uassert_true(RT_TRUE); +} + +static void test_static_semaphore_take(void) +{ + rt_err_t result; + result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + /* first take */ + result = rt_sem_take(&static_semaphore, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + /* second take */ + result = rt_sem_take(&static_semaphore, 100); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_detach(&static_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_static_semaphore_trytake(void) +{ + rt_err_t result; + result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + /* first take */ + result = rt_sem_trytake(&static_semaphore); + if (RT_EOK != result) + uassert_true(RT_FALSE); + /* second take */ + result = rt_sem_trytake(&static_semaphore); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_detach(&static_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_static_semaphore_release(void) +{ + rt_err_t result; + result = rt_sem_init(&static_semaphore, "static_sem", 0, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + /* first take */ + result = rt_sem_take(&static_semaphore, 100); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + + /* release */ + result = rt_sem_release(&static_semaphore); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + /* second take */ + result = rt_sem_take(&static_semaphore, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_detach(&static_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_static_semaphore_control(void) +{ + rt_err_t result; + int value = 0; + + value = rand() % 100; + result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + result = rt_sem_control(&static_semaphore, RT_IPC_CMD_RESET, &value); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + else + { + return; + } + + for (int i = 0; i < value; i++) + { + result = rt_sem_take(&static_semaphore, 10); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + + rt_sem_detach(&static_semaphore); + uassert_true(RT_TRUE); +} + +static void static_release_isr_hardware_callback(void *param) +{ + rt_err_t result; + + result = rt_sem_release(&static_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} + +static void static_release_isr_software_callback(void *param) +{ + rt_err_t result; + + result = rt_sem_release(&static_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} + +static void test_static_semaphore_release_isr(void) +{ + rt_err_t result; + rt_timer_t hardware_timer; + rt_timer_t software_timer; + + /* create timer */ + hardware_timer = rt_timer_create("release_isr", + static_release_isr_hardware_callback, + RT_NULL, + 100, + RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_ONE_SHOT); + software_timer = rt_timer_create("release_isr", + static_release_isr_software_callback, + RT_NULL, + 100, + RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT); + /* start tiemr */ + if (hardware_timer) + rt_timer_start(hardware_timer); + if (software_timer) + rt_timer_start(software_timer); + + result = rt_sem_init(&static_semaphore, "static_sem", 0, RT_IPC_FLAG_PRIO); + if (RT_EOK == result) + { + for (int i = 0; i < 2; i++) + { + result = rt_sem_take(&static_semaphore, 1000); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + } + else + { + return; + } + + rt_sem_detach(&static_semaphore); + rt_timer_delete(hardware_timer); + rt_timer_delete(software_timer); + + uassert_true(RT_TRUE); +} + +#ifdef RT_USING_HEAP +static void test_dynamic_semaphore_create(void) +{ + rt_err_t result; + int rand_num = rand() % 0x10000; + + for (int i = 0; i < rand_num; i++) + { + dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_PRIO); + if (RT_NULL == dynamic_semaphore) + { + uassert_true(RT_FALSE); + break; + } + rt_sem_delete(dynamic_semaphore); + + dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_FIFO); + if (RT_NULL == dynamic_semaphore) + { + uassert_true(RT_FALSE); + break; + } + rt_sem_delete(dynamic_semaphore); + } + + uassert_true(RT_TRUE); +} + +static void test_dynamic_semaphore_delete(void) +{ + rt_err_t result; + int rand_num = rand() % 0x10000; + + for (int i = 0; i < rand_num; i++) + { + dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_PRIO); + if (RT_NULL == dynamic_semaphore) + { + break; + } + + result = rt_sem_delete(dynamic_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + + dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_FIFO); + if (RT_NULL == dynamic_semaphore) + { + break; + } + result = rt_sem_delete(dynamic_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + break; + } + } + + uassert_true(RT_TRUE); +} + +static void test_dynamic_semaphore_take(void) +{ + rt_err_t result; + dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + /* first take */ + result = rt_sem_take(dynamic_semaphore, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + /* second take */ + result = rt_sem_take(dynamic_semaphore, 100); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_delete(dynamic_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_dynamic_semaphore_trytake(void) +{ + rt_err_t result; + dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + /* first take */ + result = rt_sem_trytake(dynamic_semaphore); + if (RT_EOK != result) + uassert_true(RT_FALSE); + /* second take */ + result = rt_sem_trytake(dynamic_semaphore); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_delete(dynamic_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_dynamic_semaphore_release(void) +{ + rt_err_t result; + dynamic_semaphore = rt_sem_create("static_sem", 0, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + /* first take */ + result = rt_sem_take(dynamic_semaphore, 100); + if (-RT_ETIMEOUT != result) + uassert_true(RT_FALSE); + + /* release */ + result = rt_sem_release(dynamic_semaphore); + if (RT_EOK != result) + uassert_true(RT_FALSE); + + /* second take */ + result = rt_sem_take(dynamic_semaphore, RT_WAITING_FOREVER); + if (RT_EOK != result) + uassert_true(RT_FALSE); + } + else + { + return; + } + + rt_sem_delete(dynamic_semaphore); + uassert_true(RT_TRUE); + + return; +} + +static void test_dynamic_semaphore_control(void) +{ + rt_err_t result; + int value = 0; + + value = rand() % 100; + dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + result = rt_sem_control(dynamic_semaphore, RT_IPC_CMD_RESET, &value); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + else + { + return; + } + + for (int i = 0; i < value; i++) + { + result = rt_sem_take(dynamic_semaphore, 10); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + + rt_sem_delete(dynamic_semaphore); + uassert_true(RT_TRUE); +} + +static void dynamic_release_isr_hardware_callback(void *param) +{ + rt_err_t result; + + result = rt_sem_release(dynamic_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} + +static void dynamic_release_isr_software_callback(void *param) +{ + rt_err_t result; + + result = rt_sem_release(dynamic_semaphore); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } +} + +static void test_dynamic_semaphore_release_isr(void) +{ + rt_err_t result; + rt_timer_t hardware_timer; + rt_timer_t software_timer; + + /* create timer */ + hardware_timer = rt_timer_create("release_isr", + dynamic_release_isr_hardware_callback, + RT_NULL, + 100, + RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_ONE_SHOT); + software_timer = rt_timer_create("release_isr", + dynamic_release_isr_software_callback, + RT_NULL, + 100, + RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT); + /* start tiemr */ + if (hardware_timer) + rt_timer_start(hardware_timer); + if (software_timer) + rt_timer_start(software_timer); + + dynamic_semaphore = rt_sem_create("static_sem", 0, RT_IPC_FLAG_PRIO); + if (RT_NULL != dynamic_semaphore) + { + for (int i = 0; i < 2; i++) + { + result = rt_sem_take(dynamic_semaphore, 1000); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + } + } + else + { + return; + } + + rt_sem_delete(dynamic_semaphore); + rt_timer_delete(hardware_timer); + rt_timer_delete(software_timer); + + uassert_true(RT_TRUE); +} + +#endif /* RT_USING_HEAP */ + +static rt_err_t utest_tc_init(void) +{ +#ifdef RT_USING_HEAP + dynamic_semaphore = RT_NULL; +#endif /* RT_USING_HEAP */ + + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ +#ifdef RT_USING_HEAP + dynamic_semaphore = RT_NULL; +#endif /* RT_USING_HEAP */ + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_static_semaphore_init); + UTEST_UNIT_RUN(test_static_semaphore_take); + UTEST_UNIT_RUN(test_static_semaphore_release); + UTEST_UNIT_RUN(test_static_semaphore_detach); + UTEST_UNIT_RUN(test_static_semaphore_trytake); + UTEST_UNIT_RUN(test_static_semaphore_control); + UTEST_UNIT_RUN(test_static_semaphore_release_isr); + +#ifdef RT_USING_HEAP + UTEST_UNIT_RUN(test_dynamic_semaphore_create); + UTEST_UNIT_RUN(test_dynamic_semaphore_take); + UTEST_UNIT_RUN(test_dynamic_semaphore_release); + UTEST_UNIT_RUN(test_dynamic_semaphore_delete); + UTEST_UNIT_RUN(test_dynamic_semaphore_trytake); + UTEST_UNIT_RUN(test_dynamic_semaphore_control); + UTEST_UNIT_RUN(test_dynamic_semaphore_release_isr); +#endif /* RT_USING_HEAP */ +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.semaphore_tc", utest_tc_init, utest_tc_cleanup, 1000); diff --git a/examples/utest/testcases/kernel/signal_tc.c b/examples/utest/testcases/kernel/signal_tc.c new file mode 100644 index 0000000000..40c08f7402 --- /dev/null +++ b/examples/utest/testcases/kernel/signal_tc.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-12 flybreak the first version + * + * case 1:rt_signal_install, install all available signal + * case 2:rt_signal_install, install illegal signal + * case 3:rt_signal_mask/unmask, one thread self, install and unmask, then kill, should received. + * case 4:rt_signal_mask/unmask, one thread self, install and unmask and mask, then kill, should can't received. + * case 5:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: kill, should received. + * case 6:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: sleep 2s then kill, should can't received. + * case 7:rt_signal_kill, kill legal thread, return 0; + * case 8:rt_signal_kill, kill illegal thread, return failed (unused); + * case 9:rt_signal_kill, kill illegal signo, return -RT_EINVAL; + * + */ + +#include <rtthread.h> +#include "utest.h" + +int recive_sig = 0; + +void sig_handle_default(int signo) +{ + recive_sig = signo; +} + +static void rt_signal_install_test(void) +{ + int signo; + rt_sighandler_t result; + + /* case 1:rt_signal_install, install all available signal. */ + for (signo = 0; signo < RT_SIG_MAX; signo++) + { + result = rt_signal_install(signo, sig_handle_default); + uassert_true(result != SIG_ERR); + } + /* case 2:rt_signal_install, install illegal signal. */ + result = rt_signal_install(signo, sig_handle_default); + uassert_true(result == SIG_ERR); + + return; +} + +static void rt_signal_mask_test(void) +{ + int signo; + rt_sighandler_t result; + + /* case 3:rt_signal_mask/unmask, one thread self, install and unmask, then kill, should received. */ + for (signo = 0; signo < RT_SIG_MAX; signo++) + { + recive_sig = -1; + result = rt_signal_install(signo, sig_handle_default); + uassert_true(result != SIG_ERR); + rt_signal_unmask(signo); + uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK); + rt_thread_mdelay(1); + uassert_int_equal(recive_sig, signo); + } + + return; +} + +static void rt_signal_unmask_test(void) +{ + int signo; + rt_sighandler_t result; + + /* case 4:rt_signal_mask/unmask, one thread self, install and unmask and mask, then kill, should can't received. */ + for (signo = 0; signo < RT_SIG_MAX; signo++) + { + recive_sig = -1; + result = rt_signal_install(signo, sig_handle_default); + uassert_true(result != SIG_ERR); + rt_signal_unmask(signo); + rt_signal_mask(signo); + uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK); + rt_thread_mdelay(1); + uassert_int_not_equal(recive_sig, signo); + } + + return; +} + +static void rt_signal_kill_test(void) +{ + int signo; + rt_sighandler_t result; + + /* case 7:rt_signal_kill, kill legal thread, return 0; */ + for (signo = 0; signo < RT_SIG_MAX; signo++) + { + recive_sig = -1; + result = rt_signal_install(signo, sig_handle_default); + uassert_true(result != SIG_ERR); + rt_signal_unmask(signo); + uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK); + rt_thread_mdelay(1); + uassert_int_equal(recive_sig, signo); + } + /* case 8:rt_signal_kill, kill illegal thread, return failed; */ +// uassert_true(rt_thread_kill((rt_thread_t)-1, signo) == -RT_ERROR); + + /* case 9:rt_signal_kill, kill illegal signo, return -RT_EINVAL; */ + uassert_true(rt_thread_kill(rt_thread_self(), -1) == -RT_EINVAL); + + return; +} + +void rt_signal_wait_thread(void *parm) +{ + sigset_t selectset; + siginfo_t recive_si; + + rt_signal_install(SIGUSR1, sig_handle_default); + rt_signal_unmask(SIGUSR1); + + sigemptyset(&selectset); + sigaddset(&selectset, SIGUSR1); + + /* case 5:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: kill, should received. */ + if (rt_signal_wait(&selectset, &recive_si, RT_TICK_PER_SECOND) != RT_EOK) + { + return; + } + + recive_sig = recive_si.si_signo; +} + +static void rt_signal_wait_test(void) +{ + rt_thread_t t1; + + recive_sig = -1; + t1 = rt_thread_create("sig_t1", rt_signal_wait_thread, 0, 4096, 14, 10); + if (t1) + { + rt_thread_startup(t1); + } + + rt_thread_mdelay(1); + /* case 5:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: kill, should received. */ + uassert_int_equal(rt_thread_kill(t1, SIGUSR1), RT_EOK); + rt_thread_mdelay(1); + uassert_int_equal(recive_sig, SIGUSR1); + + return; +} + +static void rt_signal_wait_test2(void) +{ + rt_thread_t t1; + + recive_sig = -1; + t1 = rt_thread_create("sig_t1", rt_signal_wait_thread, 0, 4096, 14, 10); + if (t1) + { + rt_thread_startup(t1); + } + + /* case 6:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: sleep 2s then kill, should can't received. */ + rt_thread_mdelay(2000); + uassert_int_equal(rt_thread_kill(t1, SIGUSR1), RT_EOK); + rt_thread_mdelay(1); + uassert_int_not_equal(recive_sig, SIGUSR1); + + return; +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ +#ifdef RT_USING_HEAP + UTEST_UNIT_RUN(rt_signal_install_test); + UTEST_UNIT_RUN(rt_signal_mask_test); + UTEST_UNIT_RUN(rt_signal_unmask_test); + UTEST_UNIT_RUN(rt_signal_kill_test); + UTEST_UNIT_RUN(rt_signal_wait_test); + UTEST_UNIT_RUN(rt_signal_wait_test2); +#endif /* RT_USING_HEAP */ +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.signal_tc", utest_tc_init, utest_tc_cleanup, 1000); + +/*********************** end of file ****************************/ diff --git a/examples/utest/testcases/kernel/slab_tc.c b/examples/utest/testcases/kernel/slab_tc.c new file mode 100644 index 0000000000..b273870cca --- /dev/null +++ b/examples/utest/testcases/kernel/slab_tc.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-10-14 tyx the first version + */ + +#include <rtthread.h> +#include <stdlib.h> +#include "utest.h" + +#define TEST_SLAB_SIZE 1024 * 1024 + +static int _mem_cmp(void *ptr, rt_uint8_t v, rt_size_t size) +{ + while (size-- != 0) + { + if (*(rt_uint8_t *)ptr != v) + return *(rt_uint8_t *)ptr - v; + } + return 0; +} + +struct slab_alloc_context +{ + rt_list_t node; + rt_size_t size; + rt_uint8_t magic; +}; + +struct slab_alloc_head +{ + rt_list_t list; + rt_size_t count; + rt_tick_t start; + rt_tick_t end; + rt_tick_t interval; +}; + +#define SLAB_RANG_ALLOC_BLK_MIN 2 +#define SLAB_RANG_ALLOC_BLK_MAX 5 +#define SLAB_RANG_ALLOC_TEST_TIME 5 + +static void slab_alloc_test(void) +{ + struct slab_alloc_head head; + rt_uint8_t *buf; + rt_slab_t heap; + rt_size_t size; + struct slab_alloc_context *ctx; + + /* init */ + rt_list_init(&head.list); + head.count = 0; + head.start = rt_tick_get(); + head.end = rt_tick_get() + rt_tick_from_millisecond(SLAB_RANG_ALLOC_TEST_TIME * 1000); + head.interval = (head.end - head.start) / 20; + buf = rt_malloc(TEST_SLAB_SIZE); + uassert_not_null(buf); + uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf); + rt_memset(buf, 0xAA, TEST_SLAB_SIZE); + heap = rt_slab_init("slab_tc", buf, TEST_SLAB_SIZE); + // test run + while (head.end - head.start < RT_TICK_MAX / 2) + { + if (rt_tick_get() - head.start >= head.interval) + { + head.start = rt_tick_get(); + rt_kprintf("#"); + } + // %60 probability to perform alloc operation + if (rand() % 10 >= 4) + { + size = rand() % SLAB_RANG_ALLOC_BLK_MAX + SLAB_RANG_ALLOC_BLK_MIN; + size *= sizeof(struct slab_alloc_context); + ctx = rt_slab_alloc(heap, size); + if (ctx == RT_NULL) + { + if (head.count == 0) + { + break; + } + size = head.count / 2; + while (size != head.count) + { + ctx = rt_list_first_entry(&head.list, struct slab_alloc_context, node); + rt_list_remove(&ctx->node); + if (ctx->size > sizeof(*ctx)) + { + if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0) + { + uassert_true(0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_slab_free(heap, ctx); + head.count --; + } + continue; + } + //if (RT_ALIGN((rt_ubase_t)ctx, RT_ALIGN_SIZE) != (rt_ubase_t)ctx) + //{ + // uassert_int_equal(RT_ALIGN((rt_ubase_t)ctx, RT_ALIGN_SIZE), (rt_ubase_t)ctx); + //} + rt_memset(ctx, 0, size); + rt_list_init(&ctx->node); + ctx->size = size; + ctx->magic = rand() & 0xff; + if (ctx->size > sizeof(*ctx)) + { + rt_memset(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + } + rt_list_insert_after(&head.list, &ctx->node); + head.count += 1; + } + else + { + if (!rt_list_isempty(&head.list)) + { + ctx = rt_list_first_entry(&head.list, struct slab_alloc_context, node); + rt_list_remove(&ctx->node); + if (ctx->size > sizeof(*ctx)) + { + if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0) + { + uassert_true(0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_slab_free(heap, ctx); + head.count --; + } + } + } + while (!rt_list_isempty(&head.list)) + { + ctx = rt_list_first_entry(&head.list, struct slab_alloc_context, node); + rt_list_remove(&ctx->node); + if (ctx->size > sizeof(*ctx)) + { + if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0) + { + uassert_true(0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_slab_free(heap, ctx); + head.count --; + } + uassert_int_equal(head.count, 0); + // slab heap deinit + rt_slab_detach(heap); + /* release test resources */ + rt_free(buf); +} + +#define SLAB_RANG_REALLOC_BLK_MIN 0 +#define SLAB_RANG_REALLOC_BLK_MAX 5 +#define SLAB_RANG_REALLOC_TEST_TIME 5 + +struct slab_realloc_context +{ + rt_size_t size; + rt_uint8_t magic; +}; + +struct slab_realloc_head +{ + struct slab_realloc_context **ctx_tab; + rt_size_t count; + rt_tick_t start; + rt_tick_t end; + rt_tick_t interval; +}; + +static void slab_realloc_test(void) +{ + struct slab_realloc_head head; + rt_uint8_t *buf; + rt_slab_t heap; + rt_size_t size, idx; + struct slab_realloc_context *ctx; + int res; + + size = RT_ALIGN(sizeof(struct slab_realloc_context), RT_ALIGN_SIZE) + RT_ALIGN_SIZE; + size = TEST_SLAB_SIZE / size; + /* init */ + head.ctx_tab = RT_NULL; + head.count = size; + head.start = rt_tick_get(); + head.end = rt_tick_get() + rt_tick_from_millisecond(SLAB_RANG_ALLOC_TEST_TIME * 1000); + head.interval = (head.end - head.start) / 20; + buf = rt_malloc(TEST_SLAB_SIZE); + uassert_not_null(buf); + uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf); + rt_memset(buf, 0xAA, TEST_SLAB_SIZE); + heap = rt_slab_init("slab_tc", buf, TEST_SLAB_SIZE); + /* init ctx tab */ + size = head.count * sizeof(struct slab_realloc_context *); + head.ctx_tab = rt_slab_alloc(heap, size); + uassert_not_null(head.ctx_tab); + rt_memset(head.ctx_tab, 0, size); + // test run + while (head.end - head.start < RT_TICK_MAX / 2) + { + if (rt_tick_get() - head.start >= head.interval) + { + head.start = rt_tick_get(); + rt_kprintf("#"); + } + size = rand() % SLAB_RANG_ALLOC_BLK_MAX + SLAB_RANG_ALLOC_BLK_MIN; + size *= sizeof(struct slab_realloc_context); + idx = rand() % head.count; + ctx = rt_slab_realloc(heap, head.ctx_tab[idx], size); + if (ctx == RT_NULL) + { + if (size == 0) + { + if (head.ctx_tab[idx]) + { + head.ctx_tab[idx] = RT_NULL; + } + } + else + { + for (idx = 0; idx < head.count; idx++) + { + ctx = head.ctx_tab[idx]; + if (rand() % 2 && ctx) + { + if (ctx->size > sizeof(*ctx)) + { + res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + if (res != 0) + { + uassert_int_equal(res, 0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_slab_realloc(heap, ctx, 0); + head.ctx_tab[idx] = RT_NULL; + } + } + } + continue; + } + /* check slab */ + if (head.ctx_tab[idx] != RT_NULL) + { + res = 0; + if (ctx->size < size) + { + if (ctx->size > sizeof(*ctx)) + { + res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + } + } + else + { + if (size > sizeof(*ctx)) + { + res = _mem_cmp(&ctx[1], ctx->magic, size - sizeof(*ctx)); + } + } + if (res != 0) + { + uassert_int_equal(res, 0); + } + } + /* init slab */ + ctx->magic = rand() & 0xff; + ctx->size = size; + if (ctx->size > sizeof(*ctx)) + { + rt_memset(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + } + head.ctx_tab[idx] = ctx; + } + // free all slab + for (idx = 0; idx < head.count; idx++) + { + ctx = head.ctx_tab[idx]; + if (ctx == RT_NULL) + { + continue; + } + if (ctx->size > sizeof(*ctx)) + { + res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)); + if (res != 0) + { + uassert_int_equal(res, 0); + } + } + rt_memset(ctx, 0xAA, ctx->size); + rt_slab_realloc(heap, ctx, 0); + head.ctx_tab[idx] = RT_NULL; + } + // slab heap deinit + rt_slab_detach(heap); + /* release test resources */ + rt_free(buf); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(slab_alloc_test); + UTEST_UNIT_RUN(slab_realloc_test); +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.slab_tc", utest_tc_init, utest_tc_cleanup, 20); diff --git a/examples/utest/testcases/kernel/thread_tc.c b/examples/utest/testcases/kernel/thread_tc.c new file mode 100644 index 0000000000..e95c97c293 --- /dev/null +++ b/examples/utest/testcases/kernel/thread_tc.c @@ -0,0 +1,642 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-09.01 yangjie the firet version + * 2021-10.11 mazhiyuan add idle, yield, suspend, control, priority, delay_until + */ + +#include <rtthread.h> +#include <stdlib.h> +#include "utest.h" + +#define THREAD_STACK_SIZE 512 +#define THREAD_TIMESLICE 10 + +ALIGN(RT_ALIGN_SIZE) +static char thread2_stack[1024]; +static struct rt_thread thread2; +#ifdef RT_USING_HEAP + static rt_thread_t tid1 = RT_NULL; + static rt_thread_t tid3 = RT_NULL; + static rt_thread_t tid4 = RT_NULL; + static rt_thread_t tid5 = RT_NULL; + static rt_thread_t tid6 = RT_NULL; + static rt_thread_t tid7 = RT_NULL; +#endif /* RT_USING_HEAP */ + +static rt_uint32_t tid3_delay_pass_flag = 0; +static rt_uint32_t tid3_finish_flag = 0; +static rt_uint32_t tid4_finish_flag = 0; +static rt_uint32_t tid6_finish_flag = 0; +static rt_uint32_t thread5_source = 0; + +#ifndef RT_USING_SMP + static rt_uint32_t thread_yield_flag = 0; +#endif +static rt_uint32_t entry_idle_hook_times = 0; +static rt_thread_t __current_thread; +static rt_uint8_t change_priority; +static rt_uint32_t count = 0; + +void thread1_entry(void *param) +{ + while (1); +} + +static void test_dynamic_thread(void) +{ + rt_err_t ret_startup = -RT_ERROR; + rt_err_t ret_delete = -RT_ERROR; + + tid1 = rt_thread_create("thread1", + thread1_entry, + (void *)1, + THREAD_STACK_SIZE, + __current_thread->current_priority + 1, + THREAD_TIMESLICE - 5); + if (tid1 == RT_NULL) + { + uassert_false(tid1 == RT_NULL); + goto __exit; + } + + ret_startup = rt_thread_startup(tid1); + if (ret_startup != RT_EOK) + { + uassert_false(ret_startup != RT_EOK); + goto __exit; + } + + ret_delete = rt_thread_delete(tid1); + if (ret_delete != RT_EOK) + { + uassert_false(ret_delete != RT_EOK); + goto __exit; + } + + uassert_true(tid1 != RT_NULL && ret_startup == RT_EOK && ret_delete == RT_EOK); + +__exit: + if (tid1 != RT_NULL && ret_delete != RT_EOK) + { + rt_thread_delete(tid1); + } + return; +} + +void thread2_entry(void *param) +{ + while (1); +} + +static void test_static_thread(void) +{ + rt_err_t ret_init = -RT_ERROR; + rt_err_t ret_startup = -RT_ERROR; + rt_err_t ret_detach = - RT_ERROR; + + ret_init = rt_thread_init(&thread2, + "thread2", + thread2_entry, + (void *)2, + &thread2_stack[0], + sizeof(thread2_stack), + __current_thread->current_priority + 1, + THREAD_TIMESLICE); + if (ret_init != RT_EOK) + { + uassert_false(ret_init != RT_EOK); + goto __exit; + } + + ret_startup = rt_thread_startup(&thread2); + if (ret_startup != RT_EOK) + { + uassert_false(ret_startup != RT_EOK); + goto __exit; + } + + ret_detach = rt_thread_detach(&thread2); + if (ret_detach != RT_EOK) + { + uassert_false(ret_detach != RT_EOK); + goto __exit; + } + + uassert_true(ret_init == RT_EOK && ret_startup == RT_EOK && ret_detach == RT_EOK); + +__exit: + if (ret_init == RT_EOK && ret_detach != RT_EOK) + { + rt_thread_detach(&thread2); + } + return; +} + +static void thread3_entry(void *parameter) +{ + rt_tick_t tick; + tick = rt_tick_get(); + rt_thread_delay(15); + if (rt_tick_get() - tick > 16) + { + tid3_finish_flag = 1; + tid3_delay_pass_flag = 0; + return; + } + tid3_delay_pass_flag = 1; + tid3_finish_flag = 1; +} + +static void test_thread_delay(void) +{ + rt_err_t ret_startup = -RT_ERROR; + + tid3 = rt_thread_create("thread3", + thread3_entry, + RT_NULL, + THREAD_STACK_SIZE, + __current_thread->current_priority - 1, + THREAD_TIMESLICE); + if (tid3 == RT_NULL) + { + LOG_E("rt_thread_create failed!"); + uassert_false(tid3 == RT_NULL); + goto __exit; + } + + ret_startup = rt_thread_startup(tid3); + if (ret_startup != RT_EOK) + { + LOG_E("rt_thread_startup failed!"); + uassert_false(1); + goto __exit; + } + + while (tid3_finish_flag != 1); + uassert_true(tid3_delay_pass_flag == 1); + +__exit: + return; +} + +static void idle_hook(void) +{ + entry_idle_hook_times ++; +} + +static void thread4_entry(void *parameter) +{ + rt_uint32_t delay_times = 5; + while (delay_times --) + { + rt_thread_mdelay(300); + } + rt_thread_idle_delhook(idle_hook); + tid4_finish_flag = 1; +} + +static void test_idle_hook(void) +{ + rt_err_t ret_startup = -RT_ERROR; + + rt_thread_idle_sethook(idle_hook); + + tid4 = rt_thread_create("thread4", + thread4_entry, + RT_NULL, + THREAD_STACK_SIZE, + __current_thread->current_priority - 1, + THREAD_TIMESLICE); + if (tid4 == RT_NULL) + { + LOG_E("rt_thread_create failed!"); + uassert_false(tid4 == RT_NULL); + goto __exit; + } + + ret_startup = rt_thread_startup(tid4); + if (ret_startup != RT_EOK) + { + LOG_E("rt_thread_startup failed!"); + uassert_false(1); + goto __exit; + } + + while (tid4_finish_flag != 1) + { + rt_thread_mdelay(200); + } + uassert_true(entry_idle_hook_times > 0); + +__exit: + return; +} + +static void thread5_entry(void *parameter) +{ + while (1) + { + thread5_source ++; + rt_thread_delay(5); + if (thread5_source == 5) + { + rt_thread_yield(); + } + } +} + +static void thread6_entry(void *parameter) +{ + while (++ thread5_source <= 9); + tid6_finish_flag = 1; +} + +static void test_thread_yield(void) +{ + rt_err_t ret_startup = -RT_ERROR; + tid5 = rt_thread_create("thread5", + thread5_entry, + RT_NULL, + THREAD_STACK_SIZE, + __current_thread->current_priority - 1, + THREAD_TIMESLICE); + if (tid5 == RT_NULL) + { + LOG_E("rt_thread_create failed!"); + uassert_false(tid5 == RT_NULL); + goto __exit; + } + ret_startup = rt_thread_startup(tid5); + if (ret_startup != RT_EOK) + { + LOG_E("rt_thread_startup failed!"); + uassert_false(1); + goto __exit; + } + tid6 = rt_thread_create("thread6", + thread6_entry, + RT_NULL, + THREAD_STACK_SIZE, + __current_thread->current_priority - 1, + THREAD_TIMESLICE); + if (tid6 == RT_NULL) + { + LOG_E("rt_thread_create failed!"); + uassert_false(tid6 == RT_NULL); + goto __exit; + } + ret_startup = rt_thread_startup(tid6); + if (ret_startup != RT_EOK) + { + LOG_E("rt_thread_startup failed!"); + uassert_false(1); + goto __exit; + } + + while (tid6_finish_flag != 1); + uassert_true(thread5_source == 10); + +__exit: + if (tid5 != RT_NULL) + { + rt_thread_delete(tid5); + } + return; +} + +static void thread7_entry(void *parameter) +{ + while (1); +} + +static void test_thread_control(void) +{ + rt_err_t ret_control = -RT_ERROR; + rt_err_t rst_delete = -RT_ERROR; + + tid7 = rt_thread_create("thread7", + thread7_entry, + RT_NULL, + THREAD_STACK_SIZE, + __current_thread->current_priority + 1, + THREAD_TIMESLICE); + if (tid7 == RT_NULL) + { + LOG_E("rt_thread_create failed!"); + uassert_false(tid7 == RT_NULL); + goto __exit; + } + + ret_control = rt_thread_control(tid7, RT_THREAD_CTRL_STARTUP, RT_NULL); + if (ret_control != RT_EOK) + { + LOG_E("rt_thread_control failed!"); + uassert_false(1); + goto __exit; + } + rt_thread_mdelay(200); + rt_thread_control(tid7, RT_THREAD_CTRL_CHANGE_PRIORITY, &change_priority); + if (tid7->current_priority != change_priority) + { + LOG_E("rt_thread_control failed!"); + uassert_false(1); + goto __exit; + } + rst_delete = rt_thread_control(tid7, RT_THREAD_CTRL_CLOSE, RT_NULL); + if (rst_delete != RT_EOK) + { + LOG_E("rt_thread_control failed!"); + uassert_false(rst_delete != RT_EOK); + goto __exit; + } + + uassert_true(1); + +__exit: + if (tid7 != RT_NULL && rst_delete != RT_EOK) + { + rt_thread_delete(tid7); + } + return; +} + +static void thread8_entry(void *parameter) +{ + for (; count < 10; count ++); +} + +static void test_thread_priority(void) +{ + rt_err_t ret_startup = -RT_ERROR; + rt_thread_t tid8 = RT_NULL; + + tid8 = rt_thread_create("thread8", + thread8_entry, + RT_NULL, + THREAD_STACK_SIZE, + __current_thread->current_priority - 1, + THREAD_TIMESLICE); + if (tid8 == RT_NULL) + { + LOG_E("rt_thread_create failed!"); + uassert_false(tid8 == RT_NULL); + return; + } + count = 0; + ret_startup = rt_thread_startup(tid8); + if (ret_startup != RT_EOK) + { + uassert_false(ret_startup != RT_EOK); + return ; + } + uassert_true(count == 10); + + return; +} + +static void test_delay_until(void) +{ + rt_tick_t tick; + rt_tick_t check_tick = 0; + rt_tick_t delta = 0; + + tick = rt_tick_get(); + + check_tick = tick; + rt_thread_delay_until(&tick, 100); + delta = rt_tick_get() - check_tick; + rt_kprintf("delta[100] -> %d\n", delta); + uassert_int_equal(delta, 100); + + check_tick = tick; + rt_thread_delay(2); + rt_thread_delay_until(&tick, 200); + delta = rt_tick_get() - check_tick; + rt_kprintf("delta[200] -> %d\n", delta); + uassert_int_equal(delta, 200); + + check_tick = tick; + rt_thread_delay(2); + rt_thread_delay_until(&tick, 300); + delta = rt_tick_get() - check_tick; + rt_kprintf("delta[300] -> %d\n", delta); + uassert_int_equal(delta, 300); + + check_tick = tick; + rt_thread_delay(2); + rt_thread_delay_until(&tick, 100); + delta = rt_tick_get() - check_tick; + uassert_int_equal(delta, 100); + + check_tick = tick; + rt_thread_delay(2); + rt_thread_delay_until(&tick, 50); + delta = rt_tick_get() - check_tick; + rt_kprintf("delta[50] -> %d\n", delta); + uassert_int_equal(delta, 50); + + check_tick = tick; + rt_thread_delay(2); + rt_thread_delay_until(&tick, 20); + delta = rt_tick_get() - check_tick; + rt_kprintf("delta[20] -> %d\n", delta); + uassert_int_equal(delta, 20); + + check_tick = tick; + rt_thread_delay(2); + rt_thread_delay_until(&tick, 10); + delta = rt_tick_get() - check_tick; + rt_kprintf("delta[10] -> %d\n", delta); + uassert_int_equal(delta, 10); +} + +#ifndef RT_USING_SMP +static volatile rt_uint32_t yield_count; + +static void test_thread_yield_inc_entry(void *parameter) +{ + rt_uint32_t loop = 0; + + while (1) + { + if (loop++ > 10001) + break; + yield_count++; + rt_thread_yield(); + } +} + +static void test_thread_yield_entry(void *parameter) +{ + rt_err_t ret_startup = -RT_ERROR; + + rt_thread_t tid; + rt_uint32_t loop = 0; + rt_uint32_t count_before; + + tid = rt_thread_create("inc", test_thread_yield_inc_entry, RT_NULL, + 2048, 1, 10); + if (!tid) + { + LOG_E("rt_thread_create failed!"); + return; + } + + ret_startup = rt_thread_startup(tid); + if (ret_startup != RT_EOK) + { + LOG_E("rt_thread_startup failed!"); + uassert_false(1); + return ; + } + + while (1) + { + if (loop++ > 10000) + break; + + count_before = yield_count; + rt_thread_yield(); + if (yield_count == count_before) + { + LOG_E("yield error!"); + return; + } + } + thread_yield_flag = 1; +} + +void test_thread_yield_nosmp(void) +{ + rt_err_t ret_startup = -RT_ERROR; + + rt_thread_t tid; + + yield_count = 0; + + tid = rt_thread_create("chkcnt", test_thread_yield_entry, RT_NULL, + 2048, 1, 10); + if (!tid) + { + LOG_E("rt_thread_create failed!"); + return; + } + + ret_startup = rt_thread_startup(tid); + if (ret_startup != RT_EOK) + { + LOG_E("rt_thread_startup failed!"); + uassert_false(1); + return ; + } + + uassert_true(thread_yield_flag == 1); +} + +static rt_uint32_t thread9_count = 0; +static void thread9_entry(void *parameter) +{ + while (1) + { + thread9_count ++; + } + +} +static void test_thread_suspend(void) +{ + static rt_thread_t tid; + rt_err_t ret_startup = -RT_ERROR; + uint32_t count_before_suspend, count_before_resume, count_after_resume; + tid = rt_thread_create("thread9", + thread9_entry, + RT_NULL, + THREAD_STACK_SIZE, + __current_thread->current_priority + 1, + THREAD_TIMESLICE); + if (tid == RT_NULL) + { + LOG_E("rt_thread_create failed!"); + uassert_false(tid4 == RT_NULL); + goto __exit; + } + + ret_startup = rt_thread_startup(tid); + if (ret_startup != RT_EOK) + { + LOG_E("rt_thread_startup failed!"); + uassert_false(1); + goto __exit; + } + rt_thread_delay(5); + rt_thread_suspend(tid); + count_before_suspend = thread9_count; + uassert_true(count_before_suspend != 0); + rt_thread_delay(5); + count_before_resume = thread9_count; + uassert_true(count_before_suspend == count_before_resume); + rt_thread_resume(tid); + rt_thread_delay(5); + count_after_resume = thread9_count; + uassert_true(count_after_resume != count_before_resume); + +__exit: + if (tid != RT_NULL) + { + rt_thread_delete(tid); + } + return; +} +#endif + +static rt_err_t utest_tc_init(void) +{ + __current_thread = rt_thread_self(); + change_priority = __current_thread->current_priority + 5; + tid3_delay_pass_flag = 0; + tid3_finish_flag = 0; + tid4_finish_flag = 0; + tid6_finish_flag = 0; + entry_idle_hook_times = 0; + count = 0; + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + /* init, detach */ + UTEST_UNIT_RUN(test_static_thread); + /* create, delete */ + UTEST_UNIT_RUN(test_dynamic_thread); + /* delay */ + UTEST_UNIT_RUN(test_thread_delay); + /* idle_sethook, idle_delhook */ + UTEST_UNIT_RUN(test_idle_hook); + /* yield */ + UTEST_UNIT_RUN(test_thread_yield); +#ifndef RT_USING_SMP + /* yield_nosmp */ + UTEST_UNIT_RUN(test_thread_yield_nosmp); + /* suspend, resume */ + UTEST_UNIT_RUN(test_thread_suspend); +#endif + /* control */ + UTEST_UNIT_RUN(test_thread_control); + UTEST_UNIT_RUN(test_thread_priority); + /* delay_until */ + UTEST_UNIT_RUN(test_delay_until); +} + + +UTEST_TC_EXPORT(testcase, "testcases.kernel.thread_tc", utest_tc_init, utest_tc_cleanup, 1000); + +/********************* end of file ************************/ diff --git a/examples/utest/testcases/kernel/timer_tc.c b/examples/utest/testcases/kernel/timer_tc.c new file mode 100644 index 0000000000..e7fffcb617 --- /dev/null +++ b/examples/utest/testcases/kernel/timer_tc.c @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-12 luckyzjq the first version + */ + +#include <rtthread.h> +#include <stdlib.h> +#include "utest.h" + +static rt_uint8_t timer_flag_oneshot[] = { + RT_TIMER_FLAG_ONE_SHOT, + RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_HARD_TIMER, + RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER, +}; + +static rt_uint8_t timer_flag_periodic[] = { + RT_TIMER_FLAG_PERIODIC, + RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_HARD_TIMER, + RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER, +}; + +typedef struct test_timer_struct +{ + struct rt_timer static_timer; /* static timer handler */ + rt_timer_t dynamic_timer; /* dynamic timer pointer */ + rt_tick_t expect_tick; /* expect tick */ + rt_uint8_t test_flag; /* timer callback done flag */ +} timer_struct; +static timer_struct timer; + +#define test_static_timer_start test_static_timer_init +#define test_static_timer_stop test_static_timer_init +#define test_static_timer_detach test_static_timer_init + +static void static_timer_oneshot(void *param) +{ + timer_struct *timer_call; + timer_call = (timer_struct *)param; + timer_call->test_flag = RT_TRUE; + + /* check expect tick */ + if (rt_tick_get() - timer_call->expect_tick > 1) + { + uassert_true(RT_FALSE); + } + + return; +} +static void static_timer_periodic(void *param) +{ + rt_err_t result; + timer_struct *timer_call; + timer_call = (timer_struct *)param; + timer_call->test_flag = RT_TRUE; + + /* check expect tick */ + if (rt_tick_get() - timer_call->expect_tick > 1) + { + uassert_true(RT_FALSE); + } + + /* periodic timer can stop */ + result = rt_timer_stop(&timer_call->static_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + return; +} + +static void test_static_timer_init(void) +{ + rt_err_t result; + int rand_num = rand() % 10; + + /* one shot timer test */ + for (int time_out = 0; time_out < rand_num; time_out++) + { + for (int i = 0; i < sizeof(timer_flag_oneshot); i++) + { + rt_timer_init(&timer.static_timer, + "static_timer", + static_timer_oneshot, + &timer, + time_out, + timer_flag_oneshot[i]); + + /* calc expect tick */ + timer.expect_tick = rt_tick_get() + time_out; + + /* start timer */ + result = rt_timer_start(&timer.static_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + /* wait for timerout */ + rt_thread_delay(time_out + 1); + + /* detach timer */ + result = rt_timer_detach(&timer.static_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + if (timer.test_flag != RT_TRUE) + { + uassert_true(RT_FALSE); + return; + } + } + } + + /* periodic timer test */ + for (int time_out = 0; time_out < rand_num; time_out++) + { + for (int i = 0; i < sizeof(timer_flag_periodic); i++) + { + rt_timer_init(&timer.static_timer, + "static_timer", + static_timer_periodic, + &timer, + time_out, + timer_flag_periodic[i]); + + /* calc expect tick */ + timer.expect_tick = rt_tick_get() + time_out; + + /* start timer */ + result = rt_timer_start(&timer.static_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + /* wait for timerout */ + rt_thread_delay(time_out + 1); + + /* detach timer */ + result = rt_timer_detach(&timer.static_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + if (timer.test_flag != RT_TRUE) + { + uassert_true(RT_FALSE); + return; + } + } + } + + timer.test_flag = RT_FALSE; + uassert_true(RT_TRUE); + + return; +} + +static void static_timer_control(void *param) +{ + rt_err_t result; + timer_struct *timer_call; + timer_call = (timer_struct *)param; + timer_call->test_flag = RT_TRUE; + + /* check expect tick */ + if (rt_tick_get() - timer_call->expect_tick > 1) + { + uassert_true(RT_FALSE); + } + + /* periodic timer can stop */ + result = rt_timer_stop(&timer_call->static_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + return; +} + +static void test_static_timer_control(void) +{ + rt_err_t result; + int rand_num = rand() % 10; + int set_data; + int get_data; + + rt_timer_init(&timer.static_timer, + "static_timer", + static_timer_control, + &timer, + 5, + RT_TIMER_FLAG_PERIODIC); + + /* test set data */ + set_data = rand_num; + result = rt_timer_control(&timer.static_timer, RT_TIMER_CTRL_SET_TIME, &set_data); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + /* test get data */ + result = rt_timer_control(&timer.static_timer, RT_TIMER_CTRL_GET_TIME, &get_data); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + /* a set of test */ + if (set_data != get_data) + { + uassert_true(RT_FALSE); + } + + /* calc expect tick */ + timer.expect_tick = rt_tick_get() + set_data; + + /* start timer */ + result = rt_timer_start(&timer.static_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + rt_thread_delay(set_data + 1); + + /* detach timer */ + result = rt_timer_detach(&timer.static_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + if (timer.test_flag != RT_TRUE) + { + uassert_true(RT_FALSE); + return; + } + + timer.test_flag = RT_FALSE; + uassert_true(RT_TRUE); +} + +#ifdef RT_USING_HEAP + +#define test_dynamic_timer_start test_dynamic_timer_create +#define test_dynamic_timer_stop test_dynamic_timer_create +#define test_dynamic_timer_delete test_dynamic_timer_create + +static void dynamic_timer_oneshot(void *param) +{ + timer_struct *timer_call; + timer_call = (timer_struct *)param; + timer_call->test_flag = RT_TRUE; + + /* check expect tick */ + if (rt_tick_get() - timer_call->expect_tick > 1) + { + uassert_true(RT_FALSE); + } + + return; +} +static void dynamic_timer_periodic(void *param) +{ + rt_err_t result; + timer_struct *timer_call; + timer_call = (timer_struct *)param; + timer_call->test_flag = RT_TRUE; + + /* check expect tick */ + if (rt_tick_get() - timer_call->expect_tick > 1) + { + uassert_true(RT_FALSE); + } + + /* periodic timer can stop */ + result = rt_timer_stop(timer_call->dynamic_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + return; +} + +static void test_dynamic_timer_create(void) +{ + rt_err_t result; + int rand_num = rand() % 10; + + /* one shot timer test */ + for (int time_out = 0; time_out < rand_num; time_out++) + { + for (int i = 0; i < sizeof(timer_flag_oneshot); i++) + { + timer.dynamic_timer = rt_timer_create("dynamic_timer", + dynamic_timer_oneshot, + &timer, + time_out, + timer_flag_oneshot[i]); + + /* calc expect tick */ + timer.expect_tick = rt_tick_get() + time_out; + + /* start timer */ + result = rt_timer_start(timer.dynamic_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + /* wait for timerout */ + rt_thread_delay(time_out + 1); + + /* detach timer */ + result = rt_timer_delete(timer.dynamic_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + if (timer.test_flag != RT_TRUE) + { + uassert_true(RT_FALSE); + return; + } + } + } + + /* periodic timer test */ + for (int time_out = 0; time_out < rand_num; time_out++) + { + for (int i = 0; i < sizeof(timer_flag_periodic); i++) + { + timer.dynamic_timer = rt_timer_create("dynamic_timer", + dynamic_timer_periodic, + &timer, + time_out, + timer_flag_periodic[i]); + + /* calc expect tick */ + timer.expect_tick = rt_tick_get() + time_out; + + /* start timer */ + result = rt_timer_start(timer.dynamic_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + /* wait for timerout */ + rt_thread_delay(time_out + 1); + + /* detach timer */ + result = rt_timer_delete(timer.dynamic_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + if (timer.test_flag != RT_TRUE) + { + uassert_true(RT_FALSE); + return; + } + } + } + + timer.test_flag = RT_FALSE; + uassert_true(RT_TRUE); + + return; +} + +static void dynamic_timer_control(void *param) +{ + rt_err_t result; + timer_struct *timer_call; + timer_call = (timer_struct *)param; + timer_call->test_flag = RT_TRUE; + + /* check expect tick */ + if (rt_tick_get() - timer_call->expect_tick > 1) + { + uassert_true(RT_FALSE); + } + + /* periodic timer can stop */ + result = rt_timer_stop(timer_call->dynamic_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + return; +} + +static void test_dynamic_timer_control(void) +{ + rt_err_t result; + int rand_num = rand() % 10; + int set_data; + int get_data; + + timer.dynamic_timer = rt_timer_create("dynamic_timer", + dynamic_timer_control, + &timer, + 5, + RT_TIMER_FLAG_PERIODIC); + + /* test set data */ + set_data = rand_num; + result = rt_timer_control(timer.dynamic_timer, RT_TIMER_CTRL_SET_TIME, &set_data); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + /* test get data */ + result = rt_timer_control(timer.dynamic_timer, RT_TIMER_CTRL_GET_TIME, &get_data); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + } + + /* a set of test */ + if (set_data != get_data) + { + uassert_true(RT_FALSE); + } + + /* calc expect tick */ + timer.expect_tick = rt_tick_get() + set_data; + + /* start timer */ + result = rt_timer_start(timer.dynamic_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + rt_thread_delay(set_data + 1); + + /* detach timer */ + result = rt_timer_delete(timer.dynamic_timer); + if (RT_EOK != result) + { + uassert_true(RT_FALSE); + return; + } + + if (timer.test_flag != RT_TRUE) + { + uassert_true(RT_FALSE); + return; + } + + timer.test_flag = RT_FALSE; + uassert_true(RT_TRUE); +} + +#endif /* RT_USING_HEAP */ + +static rt_err_t utest_tc_init(void) +{ + timer.dynamic_timer = RT_NULL; + timer.test_flag = RT_FALSE; + + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + timer.dynamic_timer = RT_NULL; + timer.test_flag = RT_FALSE; + + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_static_timer_init); + UTEST_UNIT_RUN(test_static_timer_start); + UTEST_UNIT_RUN(test_static_timer_stop); + UTEST_UNIT_RUN(test_static_timer_detach); + UTEST_UNIT_RUN(test_static_timer_control); +#ifdef RT_USING_HEAP + UTEST_UNIT_RUN(test_dynamic_timer_create); + UTEST_UNIT_RUN(test_dynamic_timer_start); + UTEST_UNIT_RUN(test_dynamic_timer_stop); + UTEST_UNIT_RUN(test_dynamic_timer_delete); + UTEST_UNIT_RUN(test_dynamic_timer_control); +#endif /* RT_USING_HEAP */ +} +UTEST_TC_EXPORT(testcase, "testcases.kernel.timer_tc", utest_tc_init, utest_tc_cleanup, 1000); + +/*********************** end of file ****************************/ diff --git a/examples/utest/testcases/utest/Kconfig b/examples/utest/testcases/utest/Kconfig new file mode 100644 index 0000000000..85b4d796bd --- /dev/null +++ b/examples/utest/testcases/utest/Kconfig @@ -0,0 +1,7 @@ +menu "Utest Self Testcase" + +config UTEST_SELF_PASS_TC + bool "Pass test" + default y + +endmenu diff --git a/examples/utest/testcases/utest/SConscript b/examples/utest/testcases/utest/SConscript new file mode 100644 index 0000000000..1b35042e44 --- /dev/null +++ b/examples/utest/testcases/utest/SConscript @@ -0,0 +1,13 @@ +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Split(''' +pass_tc.c +''') + +CPPPATH = [cwd] + +group = DefineGroup('utestcases', src, depend = ['UTEST_SELF_PASS_TC'], CPPPATH = CPPPATH) + +Return('group') diff --git a/examples/utest/testcases/utest/pass_tc.c b/examples/utest/testcases/utest/pass_tc.c new file mode 100644 index 0000000000..c9ee912fbf --- /dev/null +++ b/examples/utest/testcases/utest/pass_tc.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-01-16 MurphyZhao the first version + */ + +#include <rtthread.h> +#include "utest.h" + +static void test_assert_pass(void) +{ + uassert_true(1); + uassert_false(0); + + uassert_null(RT_NULL); + uassert_not_null(!RT_NULL); + + uassert_int_equal(1, 1); + uassert_int_not_equal(1, 2); + + uassert_str_equal("Hello RT-Thread!", "Hello RT-Thread!"); + uassert_str_not_equal("Hello RT-Thread!", "Hello"); + + uassert_in_range(2048, 1024, 4096); + uassert_not_in_range(0, 1024, 4096); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_assert_pass); +} +UTEST_TC_EXPORT(testcase, "testcases.utest.pass_tc", utest_tc_init, utest_tc_cleanup, 10); diff --git a/examples/var_export/var_export_example.c b/examples/var_export/var_export_example.c new file mode 100644 index 0000000000..9ea45de1c3 --- /dev/null +++ b/examples/var_export/var_export_example.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-09-02 WillianChan add var_export example code + */ + +#include <var_export.h> + +/* use VAR_EXPOR() to export 10 pieces of data into sections */ +VAR_EXPORT(module0, identi0, 0); +VAR_EXPORT(module1, identi1, 1); +VAR_EXPORT(module2, identi2, 2); +VAR_EXPORT(module3, identi3, 3); +VAR_EXPORT(module4, identi4, 4); +VAR_EXPORT(module5, identi5, 5); +VAR_EXPORT(module6, identi6, 6); +VAR_EXPORT(module7, identi7, 7); +VAR_EXPORT(module8, identi8, 8); +VAR_EXPORT(module9, identi9, 9); + +void found_by_module(void) +{ + ve_iterator_t iter; + const ve_exporter_t* exporter; + ve_module_t module; + rt_base_t value; + + /* query all exporters with the same name as module1 */ + if (!ve_module_init(&module, "module1")) + /* initialize the iterator */ + ve_iter_init(&module, &iter); + else + return; + + while (1) + { + /* start iterating */ + exporter = ve_iter_next(&iter); + if (exporter == RT_NULL) + break; + else + { + /* checks whether the value exists */ + if (ve_value_exist(&module, "identi1") == RT_TRUE) + { + value = ve_value_get(&module, "identi1"); + rt_kprintf("[ve_example] value = %dn", value); + return; + } + else + { + rt_kprintf("[ve_example] value not exist.\n"); + return; + } + } + } +} +#ifdef RT_USING_FINSH +#include <finsh.h> +MSH_CMD_EXPORT(found_by_module, found by module); +#endif /* RT_USING_FINSH */
\ No newline at end of file diff --git a/examples/ymodem/echo.c b/examples/ymodem/echo.c index 5cb807f519..fdd7e5228b 100644 --- a/examples/ymodem/echo.c +++ b/examples/ymodem/echo.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #include <ymodem.h> static rt_device_t _odev; diff --git a/examples/ymodem/null.c b/examples/ymodem/null.c index c72ea064f8..640b8ba11b 100644 --- a/examples/ymodem/null.c +++ b/examples/ymodem/null.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #include <ymodem.h> static enum rym_code _rym_dummy_write( diff --git a/examples/ymodem/tofile.c b/examples/ymodem/tofile.c index 4a3705ede7..8fb2d0c06b 100644 --- a/examples/ymodem/tofile.c +++ b/examples/ymodem/tofile.c @@ -1,6 +1,19 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #include <rtthread.h> #include <ymodem.h> -#include <dfs_posix.h> +#include <dfs_file.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/statfs.h> #include <stdlib.h> #include <board.h> |
