diff options
Diffstat (limited to 'examples/kernel')
| -rw-r--r-- | examples/kernel/SConscript | 13 | ||||
| -rw-r--r-- | examples/kernel/tc_comm.c | 165 | ||||
| -rw-r--r-- | examples/kernel/tc_comm.h | 41 | ||||
| -rw-r--r-- | examples/kernel/thread_dynamic.c | 44 | ||||
| -rw-r--r-- | examples/kernel/thread_priority.c | 104 | ||||
| -rw-r--r-- | examples/kernel/thread_static.c | 52 |
6 files changed, 419 insertions, 0 deletions
diff --git a/examples/kernel/SConscript b/examples/kernel/SConscript new file mode 100644 index 0000000000..cd215ade73 --- /dev/null +++ b/examples/kernel/SConscript @@ -0,0 +1,13 @@ +Import('env')
+
+src_local = Split("""
+tc_comm.c
+thread_static.c
+thread_dynamic.c
+thread_priority.c
+""")
+
+# The set of source files associated with this SConscript file.
+obj = env.Object(src_local)
+
+Return('obj')
diff --git a/examples/kernel/tc_comm.c b/examples/kernel/tc_comm.c new file mode 100644 index 0000000000..ad0a200e88 --- /dev/null +++ b/examples/kernel/tc_comm.c @@ -0,0 +1,165 @@ +#include "tc_comm.h"
+#include <finsh.h>
+
+#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;
+
+void tc_thread_entry(void* parameter)
+{
+ rt_err_t result;
+ struct finsh_syscall* index;
+
+ /* create tc semaphore */
+ rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO);
+
+ while (_tc_stat & TC_STAT_RUNNING)
+ {
+ for (index = _syscall_table_begin; index < _syscall_table_end; 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)
+ {
+ result = rt_sem_take(&_tc_sem, tick);
+ 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
+ rt_kprintf("TestCase[%s] passed\n", _tc_current);
+ }
+ }
+
+ if (_tc_cleanup != RT_NULL)
+ {
+ /* perform testcase cleanup */
+ _tc_cleanup();
+ _tc_cleanup = RT_NULL;
+ }
+ }
+ }
+ }
+
+ /* detach tc semaphore */
+ rt_sem_detach(&_tc_sem);
+}
+
+void tc_stop()
+{
+ _tc_stat &= ~TC_STAT_RUNNING;
+
+ rt_thread_delay(RT_TICK_PER_SECOND/2);
+ 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 list_tc()
+{
+ struct finsh_syscall* index;
+
+ rt_kprintf("TestCases List:\n");
+ for (index = _syscall_table_begin; index < _syscall_table_end; 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 new file mode 100644 index 0000000000..9f96d24e09 --- /dev/null +++ b/examples/kernel/tc_comm.h @@ -0,0 +1,41 @@ +#ifndef __TC_COMM_H__
+#define __TC_COMM_H__
+
+/*
+ * RT-Thread TestCase
+ *
+ */
+#include <rtthread.h>
+#include <finsh.h>
+
+#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/thread_dynamic.c b/examples/kernel/thread_dynamic.c new file mode 100644 index 0000000000..9d1218be5d --- /dev/null +++ b/examples/kernel/thread_dynamic.c @@ -0,0 +1,44 @@ +#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_priority.c b/examples/kernel/thread_priority.c new file mode 100644 index 0000000000..7864a91232 --- /dev/null +++ b/examples/kernel/thread_priority.c @@ -0,0 +1,104 @@ +#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
+ */
+void thread1_entry(void* parameter)
+{
+ while (1)
+ {
+ count ++;
+ rt_kprintf("count = %d\n", count);
+
+ rt_thread_delay(10);
+ }
+}
+
+void thread2_entry(void* parameter)
+{
+ rt_tick_t tick;
+
+ tick = rt_tick_get();
+ while (1)
+ {
+ if (rt_tick_get() - tick >= 100)
+ {
+ 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_static.c b/examples/kernel/thread_static.c new file mode 100644 index 0000000000..9a8c158c86 --- /dev/null +++ b/examples/kernel/thread_static.c @@ -0,0 +1,52 @@ +#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
+
|
