线程第一次运行的时候,加载到CPU寄存器的参数就放在线程栈里面,改函数 rt_hw_stack_init()在cpuport.c中实现。具体代
码如下:
/* 初始化线程栈 */
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);
/* 将stk指针强制转换为 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;
stack_frame->exception_stack_frame.r1 = 0; /* r1 */
stack_frame->exception_stack_frame.r2 = 0; /* r2 */
stack_frame->exception_stack_frame.r3 = 0; /* r3 */
stack_frame->exception_stack_frame.r12 = 0; /* r12 */
stack_frame->exception_stack_frame.lr = 0; /* lr */
stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */
stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */
/* 返回线程指针 */
return stk;
}
代码 stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk,8); 让stk这个指针向下8个字节对齐,确保stk是8字节对齐的地址。
代码 stk -=sizeof(struct stack_frame); stk 指针继续向下移动sizeof(struct stack_frame)个偏移,即16字的大小。
代码 stack_frame =(struct stack_frame *)stk; 将stk指针强制转换为stack-frame类型后存到指针变量stack_frame中。
改函数最终会返回线程栈顶指针stk,
在线程栈初始化函数中,定义了struct stack_frame 类型的结构体指针stack_frame,改结构体类型具体如下:
struct exception_stack_frame
{
/*异常发生时自动加载CPU寄存器的内容*/
rt_uint32_t r0;
rt_uint32_t r1;
rt_uint32_t r2;
rt_uint32_t r3;
rt_uint32_t r12;
rt_uint32_t lr;
rt_uint32_t pc;
rt_uint32_t psr;
};
struct stack_frame
{
/*异常发生时需要手动加载CPU寄存器的内容*/
rt_uint32_t r4;
rt_uint32_t r5;
rt_uint32_t r6;
rt_uint32_t r7;
rt_uint32_t r8;
rt_uint32_t r9;
rt_uint32_t r10;
rt_uint32_t r11;
struct exception_stack_frame exception_stack_frame;
};