/*
*****************************************************************************************
* 函数实现 开辟栈空间
*****************************************************************************************
*/
/*线程栈的初始化*/
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;
/*获取栈顶指针
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 ); (7)
/*将sta指针强制转化为stack_frame类型后保存到stack_frame*/
stack_frame =(struct stack_frame *)stk; (8)
/*以stack_frame为起始地址,将栈空间里面的sizeof(struct stack_frame)个内存初始化为0xdeadbeef*/
for(i=0;i<sizeof (struct stack_frame) / sizeof (rt_uint32_t); i++) (9)
{
((rt_uint32_t *)stack_frame )[i] = 0xdeadbeef;
}
/*初始化异常发生时自动保存的寄存器*/ (10)
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;
} (11)
/*stk指针继续向下移动 sizeof(struct stack_frame)个偏移*/
stk -=sizeof (struct stack_frame ); (7)
执行完上述语句后线程栈的变化:
/*将sta指针强制转化为stack_frame类型后保存到stack_frame*/
stack_frame =(struct stack_frame *)stk; (8)
继续执行(8),将stk指针强制转化为stack_frame类型
/*以stack_frame为起始地址,将栈空间里面的sizeof(struct stack_frame)个内存初始化为0xdeadbeef*/
for(i=0;i<sizeof (struct stack_frame) / sizeof (rt_uint32_t); i++) (9)
{
((rt_uint32_t *)stack_frame )[i] = 0xdeadbeef;
}
执行代码 /*初始化异常发生时自动保存的寄存器*/ (10)
线程第一次运行的时候,加载到CPU寄存器的环境参数我们要预先初始化好。从栈顶开始,初始化顺序固定(指令集决定的)。首先是异常发生时自动保存的8个寄存器,
xpsr, r25, r14, r12,r3,r2,r1和r0.其中xpsr寄存器的位24必须是1,r15PC指针必须存的是线程的入口地址,r0必须是线程形参,剩下的r14,r12,r3,r2和r1我们初始化为0.