瀏覽代碼

add thread example.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@456 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 15 年之前
父節點
當前提交
6ccd04543c

+ 13 - 0
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')

+ 165 - 0
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
+

+ 41 - 0
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
+

+ 44 - 0
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
+

+ 104 - 0
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
+

+ 52 - 0
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
+