diff --git a/examples/kernel/SConscript b/examples/kernel/SConscript index cd215ade7..3977040d0 100644 --- a/examples/kernel/SConscript +++ b/examples/kernel/SConscript @@ -5,6 +5,10 @@ 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 """) # The set of source files associated with this SConscript file. diff --git a/examples/kernel/tc_comm.c b/examples/kernel/tc_comm.c index ad0a200e8..3f26416b7 100644 --- a/examples/kernel/tc_comm.c +++ b/examples/kernel/tc_comm.c @@ -37,22 +37,32 @@ void tc_thread_entry(void* parameter) if (tick > 0) { result = rt_sem_take(&_tc_sem, tick); + + if (_tc_cleanup != RT_NULL) + { + /* perform testcase cleanup */ + _tc_cleanup(); + _tc_cleanup = RT_NULL; + } + if (result != RT_EOK) rt_kprintf("TestCase[%s] failed\n", _tc_current); else { if (_tc_stat & TC_STAT_FAILED) rt_kprintf("TestCase[%s] failed\n", _tc_current); - else + else rt_kprintf("TestCase[%s] passed\n", _tc_current); } } - - if (_tc_cleanup != RT_NULL) + else { - /* perform testcase cleanup */ - _tc_cleanup(); - _tc_cleanup = RT_NULL; + if (_tc_cleanup != RT_NULL) + { + /* perform testcase cleanup */ + _tc_cleanup(); + _tc_cleanup = RT_NULL; + } } } } @@ -126,12 +136,12 @@ void tc_start(const char* tc_prefix) } rt_memset(_tc_prefix, 0, sizeof(_tc_prefix)); - rt_snprintf(_tc_prefix, sizeof(_tc_prefix), + rt_snprintf(_tc_prefix, sizeof(_tc_prefix), "_tc_%s", tc_prefix); - result = rt_thread_init(&_tc_thread, "tc", + result = rt_thread_init(&_tc_thread, "tc", tc_thread_entry, RT_NULL, - &_tc_stack[0], sizeof(_tc_stack), + &_tc_stack[0], sizeof(_tc_stack), TC_PRIORITY - 3, 5); /* set tc stat */ diff --git a/examples/kernel/thread_delay.c b/examples/kernel/thread_delay.c new file mode 100644 index 000000000..de69db389 --- /dev/null +++ b/examples/kernel/thread_delay.c @@ -0,0 +1,70 @@ +#include +#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"); + + tick = rt_tick_get(); + rt_kprintf("thread delay 10 tick\n"); + rt_thread_delay(10); + if (rt_tick_get() - tick > 10) + { + tc_done(TC_STAT_FAILED); + return; + } + + tick = rt_tick_get(); + rt_kprintf("thread delay 15 tick\n"); + rt_thread_delay(15); + if (rt_tick_get() - tick > 15) + { + 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 new file mode 100644 index 000000000..cd632815c --- /dev/null +++ b/examples/kernel/thread_delete.c @@ -0,0 +1,80 @@ +#include +#include "tc_comm.h" + +/* + * This is an example for dynamic thread + */ +static rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL; +static void thread1_entry(void* parameter) +{ + rt_uint32_t count = 0; + + while (1) + { + rt_kprintf("thread count: %d\n", count ++); + } +} + +static void thread2_entry(void* parameter) +{ + rt_thread_delay(10); + rt_thread_delete(tid1); + + /* delay thread2 to switch to idle thread */ + rt_thread_delay(10); +} + +int thread_delete_init() +{ + tid1 = rt_thread_create("t1", + thread1_entry, (void*)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); + + tid2 = rt_thread_create("t2", + thread2_entry, (void*)2, + 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() +{ + /* lock scheduler */ + rt_enter_critical(); + + /* delete thread */ + if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE) + tc_stat(TC_STAT_FAILED); + if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE) + tc_stat(TC_STAT_FAILED); + + /* unlock scheduler */ + rt_exit_critical(); +} + +int _tc_thread_delete() +{ + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + thread_delete_init(); + + return 100; +} +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_dynamic_simple.c b/examples/kernel/thread_dynamic_simple.c new file mode 100644 index 000000000..9f822eefc --- /dev/null +++ b/examples/kernel/thread_dynamic_simple.c @@ -0,0 +1,75 @@ +#include +#include "tc_comm.h" + +/* + * This is an example for dynamic thread + */ +static rt_thread_t tid1 = RT_NULL, 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 ++); + rt_thread_delay(10); + } +} + +int thread_dynamic_simple_init() +{ + tid1 = rt_thread_create("t1", + thread_entry, (void*)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); + + tid2 = rt_thread_create("t2", + thread_entry, (void*)2, + 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() +{ + /* lock scheduler */ + rt_enter_critical(); + + /* delete thread */ + 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); + + /* unlock scheduler */ + rt_exit_critical(); + + tc_done(TC_STAT_PASSED); +} + +int _tc_thread_dynamic_simple() +{ + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + thread_dynamic_simple_init(); + + return 100; +} +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 index 7864a9123..469991336 100644 --- a/examples/kernel/thread_priority.c +++ b/examples/kernel/thread_priority.c @@ -10,7 +10,7 @@ static rt_uint32_t count = 0; /* * the priority of thread1 > the priority of thread2 */ -void thread1_entry(void* parameter) +static void thread1_entry(void* parameter) { while (1) { @@ -21,7 +21,7 @@ void thread1_entry(void* parameter) } } -void thread2_entry(void* parameter) +static void thread2_entry(void* parameter) { rt_tick_t tick; @@ -43,7 +43,7 @@ void thread2_entry(void* parameter) int thread_priority_init() { rt_err_t result; - + result = rt_thread_init(&thread1, "t1", thread1_entry, RT_NULL, @@ -73,7 +73,7 @@ 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) diff --git a/examples/kernel/thread_same_priority.c b/examples/kernel/thread_same_priority.c new file mode 100644 index 000000000..3c1d91ddf --- /dev/null +++ b/examples/kernel/thread_same_priority.c @@ -0,0 +1,92 @@ +#include +#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]; + +static rt_uint32_t t1_count = 0; +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(); + + if (t1_count / t2_count != 2) + tc_stat(TC_STAT_END | TC_STAT_FAILED); +} + +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_simple.c b/examples/kernel/thread_static_simple.c new file mode 100644 index 000000000..24514c1a5 --- /dev/null +++ b/examples/kernel/thread_static_simple.c @@ -0,0 +1,83 @@ +#include +#include "tc_comm.h" + +/* + * This is an example for static thread + */ +static struct rt_thread thread1; +static struct rt_thread thread2; +static char thread1_stack[THREAD_STACK_SIZE]; +static char 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 ++); + rt_thread_delay(10); + } +} + +rt_err_t thread_static_simple_init() +{ + rt_err_t result; + + result = rt_thread_init(&thread1, + "t1", + thread_entry, (void*)1, + &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", + thread_entry, (void*)2, + &thread2_stack[0], sizeof(thread2_stack), + THREAD_PRIORITY + 1, 10); + 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(); +} + +int _tc_thread_static_simple() +{ + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + thread_static_simple_init(); + + return 20; +} +FINSH_FUNCTION_EXPORT(_tc_thread_static_simple, a static thread example); +#else +int rt_application_init() +{ + thread_static_simple_init(); + + return 0; +} +#endif +