以空闲线程为例
1.定义点数据存在内存的静态空间
/*空闲线程的线程控制块*/
struct rt_thread idle;
rt_ubase_t rt_idletask_ctr=0; //空闲时将要自加的零碎
extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX]; //线程优先级链表
static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE]; //将会分配的空间
void rt_thread_idle_entry(void *parameter) //线程入口函数
{
parameter = parameter;
while(1)
{
rt_idletask_ctr ++;
}
}
来来,把上面已经在内存上开辟出空间,占了位置的value都填到下面的函数中
rt_thread_init(&idle, //线程控制块
"idle", //线程名字字符串
rt_thread_idle_entry, //入口函数
RT_NULL, //空
&rt_thread_stack[0], //栈首地址
sizeof(rt_thread_stack),//获取栈的大小
RT_THREAD_PRIORITY_MAX-1);//优先级呀
任何线程初始化都要调用rt-thread_init函数,只不过填入不同的参数罢了。那就来康康rt-thread_init吧
rt_err_t rt_thread_init(struct rt_thread *thread,
const char *name,
void (*entry)(void *parameter),
void *parameter,
void *stack_start,
rt_uint32_t stack_size,
rt_uint8_t priority)
{ /* 线程结构体开头部分的成员就是rt_object_t类型 */
rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name); (1)
rt_list_init(&(thread->tlist));(2)
thread->entry = (void*)entry;(3)
thread->parameter = parameter;(4)
thread->stack_addr = stack_start;(5)
thread->stack_size = stack_size;(6)
/*初始化线程栈,并返回线程栈指针*/
thread->sp = (void*)rt_hw_stack_init(thread->entry ,
thread->parameter,
(void*)((char *)thread->stack_addr+thread->stack_size-4));(7)
thread->init_priority = priority;(8)
thread->current_priority = priority ;(9)
thread->number_mask = 0;(10)
/*错误码和状态*/
thread->error = RT_EOK ;(11)
thread->stat = RT_THREAD_INIT ;(12)
/*初始化线程定时器*/
rt_timer_init (&(thread->thread_timer ), /*静态定时器对象*/
thread->name , /*定时器的名字,直接使用的是线程的名字*/
rt_thread_timeout , /*超时函数*/
thread, /*超时函数形参*/
0, /*延时时间*/
RT_TIMER_FLAG_ONE_SHOT ); /*定时器的标志*/(13)
return RT_EOK;(14)
}
淦!我们来逐句分析:
(1)rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name);
附执行rt_object_init后,线程容器链表示意图:
/**线程初始化过程包含着容器初始化,那就转到容器初始化
*仅从入口函数分析,首先将strcut thread 型的线程控制块强制转化为struct object型
*然后rt_object_class_type 为 RT_Object_Class_Thread, 最后name是“idle”****/
void rt_object_init(struct rt_object *object,
enum rt_object_class_type type,
const char *name)
{
register rt_base_t temp; //定义寄存区变量,访问迅速
//struct rt_object内核对象基础数据结构 中主要包含 1.char name 内核对象的名字
2.rt_uint8 type 内核对象的类型
3. rt-uint8 flag 内核对象的状态
4. rt_list-t list; 内核对象的列表节点
struct rt_object_information *information;
//这个rt_object_information 又是何方神圣他是内核对象信息结构体,
包括: 1.enum rt_object_class_type type; /*对象类型*/
2.rt_list_t object_list; /*对象列表节点*/
3.rt_size_t object_size; /*对象大小*/
information = rt_object_get_information (type);
//该函数的作用为获取对象信息,即从容器里拿到对应对象列表头指针,
其函数原型为:
/*struct rt_object_information *rt_object_get_information(enum rt_object_class_type type)
{
int index;
for (index = 0; index<RT_Object_Info_Unknown ;index ++)
if(rt_object_container [index].type == type) return &rt_object_container [index];
return RT_NULL ;
}*/
/*设置对象的类型为静态*/
object ->type =type | RT_Object_Class_Static ;
/*拷贝名字*/
rt_strncpy(object->name,name,RT_NAME_MAX );
/*关中断*/
temp=rt_hw_interrupt_disable ();
/*将对象插入到容器的对应列表中,不同的类型的对象所在列表不一样*/
rt_list_insert_after(&(information ->object_list ),&(object ->list ));
/*开中断*/
rt_hw_interrupt_enable (temp);
}
rt_list_init(&(thread->tlist));(2)
rt_inline void rt_list_init(rt_list_t *l)
{
l->next = l->prev =l;
这段代码自然不用多说,列表初始化,自己指向自己
thread->entry = (void*)entry;(3)
thread->parameter = parameter;(4)
thread->stack_addr = stack_start;(5)
thread->stack_size = stack_size;(6)
"以上都是正常简单的参数赋值:对于空闲线程而言参数写入如下:"
idle->entry = rt_thread_idle_entry;(3)
idle->parameter = NULL;(4)
idle->stack_addr = &rt_thread_stack[0];(5)
idle->stack_size = sizeof(rt_thread_stack);(6)
/*初始化线程栈,并返回线程栈指针*/
/*初始化线程栈,并返回线程栈指针*/
thread->sp = (void*)rt_hw_stack_init(thread->entry ,
thread->parameter,
(void*)((char *)thread->stack_addr+thread->stack_size-4));(7)
"来吧,说得清但又说不清的栈"
/*线程栈的初始化*/
rt_uint8_t *rt_hw_stack_init(void *tentry,
void *parameter,
rt_uint8_t *stack_addr)
{
struct stack_frame *stack_frame; //寄存器类型的结构体
rt_uint8_t *stk; //指针
unsigned long i; //变量i
/*获取栈顶指针
rt_hw_stack_init 在调用的时候,传给stack_addr的是栈顶指针-4*/
stk = stack_addr+sizeof(rt_uint32_t);
/*让stk指针向下8字节对齐*/
stk = (rt_uint8_t *)RT_ALIGN_DOWN ((rt_uint32_t )stk,8);
/*stk指针继续向下移动 sizeof(struct stack_frame)个偏移*/
stk -=sizeof (struct stack_frame );
/*将sta指针强制转化为stack_frame类型后保存到stack_frame*/
stack_frame =(struct stack_frame *)stk;
/*以stack_frame为起始地址,将栈空间里面的sizeof(struct stack_frame)个内存初始化为0xdeadbeef*/
for(i=0;i<sizeof (struct stack_frame) / sizeof (rt_uint32_t); i++)
{
((rt_uint32_t *)stack_frame )[i] = 0xdeadbeef;
}
/*初始化异常发生时自动保存的寄存器*/
stack_frame->exception_stack_frame .r0 =(unsigned long)parameter ;/*r0:argument*/
stack_frame ->exception_stack_frame .r1 =0;
stack_frame ->exception_stack_frame .r2 = 0;
stack_frame ->exception_stack_frame .r3 =0;
stack_frame ->exception_stack_frame .r12 = 0;
stack_frame ->exception_stack_frame .lr = 0;
stack_frame ->exception_stack_frame .pc = (unsigned long)tentry ;/*entry point,pc*/
stack_frame ->exception_stack_frame .psr = 0x1000000L; /*PSR*/
/*返回线程栈指针*/
return stk;
}
thread->init_priority = priority;(8)
thread->current_priority = priority ;(9)
thread->number_mask = 0;(10)
/*错误码和状态*/
thread->error = RT_EOK ;(11)
thread->stat = RT_THREAD_INIT ;(12)
"以上都是正常简单的参数赋值:对于空闲线程而言参数写入如下:"
idle->init_priority = RT_THREAD_PRIORITY_MAX-1;(8)
idle->current_priority = RT_THREAD_PRIORITY_MAX-1;(9)
idle->number_mask = 0;(10)
/*错误码和状态*/
idle->error = RT_EOK ;(11)
idle->stat = RT_THREAD_INIT ;(12)
/*初始化线程定时器*/
rt_timer_init (&(thread->thread_timer ), /*静态定时器对象*/
thread->name , /*定时器的名字,直接使用的是线程的名字*/
rt_thread_timeout , /*超时函数*/
thread, /*超时函数形参*/
0, /*延时时间*/
RT_TIMER_FLAG_ONE_SHOT ); /*定时器的标志*/(13)
void rt_timer_init(rt_timer_t timer,
const char *name,
void(*timeout) (void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag )
{
/*定时器对象初始化*/
rt_object_init ((rt_object_t )timer ,RT_Object_Class_Timer ,name);
//rt_object_init 完成的就是一个容器以RT_Object_Info_Timer为节点的容器链表搭建
/*定时器初始化*/
_rt_timer_init (timer,timeout ,parameter,time,flag);
}
//在这里我们展开来看static void _rt_timer_init(rt_timer_t timer,
void (*timeout) (void *parameter),
void *paramerter,
rt_tick_t time,
rt_uint8_t flag)
{
//展开看struct rt_timer
主要包含6大件:
1.struct rt_object parent;//具有容器结构的parent
2. rt_list_t row[RT_TIMER_SKIP_LIST_LEVEL]; //数组链表row[]
3.void (*timeout_func)(void *parameter); /*超时函数*/
4. void *parameter; /*超时函数形参*/
5. rt_tick_t init_tick; /*定时器实际需要延时的时间*/
6. rt_tick_t timeout_tick; /*定时器实际超时时的系统节拍数*/
int i;
/*设置标志位*/
timer->parent .flag = flag;
/*先设置为非激活状态*/
timer->parent .flag &=~RT_TIMER_FLAG_ACTIVATED ;
timer->timeout_func = timeout ;
timer->parameter = paramerter ;
/*初始化定时器实际超时时的系统节拍数*/
timer->timeout_tick = 0;
/*初始化 定时器需要超时时的节拍数*/
timer->init_tick = time;
/*初始化定时器的内置节点*/
for (i=0; i<RT_TIMER_SKIP_LIST_LEVEL ; i++)
{
rt_list_init(&(timer->row [i]));
}
}