详细分析一个rt_thread_init的过程

以空闲线程为例

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]));
	}
}

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值