add thread example.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@456 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
8aaddbaf38
commit
6ccd04543c
|
@ -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')
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue