1. 定义线程的栈
多线程操作系统中,每个线程都是独立的,互不干扰,所以要为每个线程分配独立的栈空间,这个栈空间通常是一个预先定义好的全局数组, 也可以是动态分配的一段内存空间,但它们都存在于 RAM 中。定义两个线程栈如下:
// 定义线程栈 大小设置为512
rt_uint8_t rt_flag1_thread_stack[512];
rt_uint8_t rt_flag2_thread_stack[512];
2. 定义线程函数
线程是一个独立的函数,函数主体无限循环不能返回。定义相关线程函数如下:
/********************************线程函数******************************/
/* 延时函数*/
void delay(uint32_t count)
{
for(;count!=0;count--);
}
/* 线程 1 */
void flag1_thread_entry(void *p_arg)
{
while(1)
{
flag1=1;
delay(100);
flag1=0;
delay(100);
/* 线程切换*/
rt_schedule();
}
}
/* 线程 2 */
void flag2_thread_entry(void *p_arg)
{
while(1)
{
flag2=1;
delay(100);
flag2=0;
delay(100);
/* 线程切换*/
rt_schedule();
}
}
/*******************************************************************************/
3. 定义线程控制块
如果要顺利调度线程,需要为每个线程额外定义一个线程控制块,存着线程的所有信息(线程栈指针,线程名称,线程形参)。以后系统对线程的全部操作都是通过线程控制块来实现,这里的线程控制块特别重要,一定牢牢掌握。为了使每个线程方便定义线程控制块实体,RT—Thread 在rtdef.h中定义了一个新的数据类型,并将其声明。
/* 线程控制块声明 */
struct rt_thread
{
void *sp; /* 线程栈指针*/
void *entry; /*线程入口地址*/
void *parameter; /*线程形参*/
void *stack_adder; /*线程栈起始地址*/
rt_uint32_t stack_size; /*线程栈大小*/
};
typedef struct rt_thread *rt_thread_t;
在主函数 main 中还需要定义两个 线程控制块,代码如下:
/* 定义两个线程控制块,对应之前定义的两个线程 */
struct rt_thread rt_flag1_thread;
struct rt_thread rt_flag2_thread;
4. 线程初始化函数
前面我们坑此坑次的定义了 线程函数实体,线程的栈,线程控制块,需要将三者联系在一起的就是线程初始化函数,这样才能由系统统一调度。线程初始化函数: rt_thread_init() 改函数在thread.c文件中,代码如下:
/* 线程出初始化函数 */
rt_err_t rt_thread_init(struct rt_thread *thread,
void (*entry) (void *parameter),
void *parameter,
void *stack_start,
rt_uint32_t stack_size)
{
rt_list_init(&(thread->tlist));
thread->entry =(void*)entry;
thread->parameter =parameter;
thread->stack_adder = stack_start;
thread->stack_size = stack_size;
thread->sp =
(void*)rt_hw_stack_init(thread->entry,
thread->parameter,
(void*)((char*)thread->stack_adder+thread->stack_size-4));
return RT_EOK;
}
在主函数中建立两个初始化线程,代码如下:
/* 初始化线程*/
rt_thread_init(&rt_flag1_thread, /* 线程控制块*/
flag1_thread_entry , /* 线程入口参数*/
RT_NULL, /* 线程形参*/
&rt_flag1_thread_stack[0], /* 线程栈起始地址*/
sizeof(rt_flag1_thread_stack)); /*线程栈大小,单位为字节*/
rt_thread_init(&rt_flag2_thread, /* 线程控制块*/
flag2_thread_entry , /* 线程入口参数*/
RT_NULL, /* 线程形参*/
&rt_flag2_thread_stack[0], /* 线程栈起始地址*/
sizeof(rt_flag2_thread_stack)); /*线程栈大小,单位为字节*/