生活随笔
收集整理的這篇文章主要介紹了
实现线程栈初始化(RTT)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
節選自 RTT編程指南;
在動態創建線程和初始化線程的時候,會使用到內部的線程初始化函數 _rt_thread_init(),
_rt_thread_init() 函數會調用棧初始化函數 rt_hw_stack_init(),在棧初始化函數里會手動構造一個
上下文內容,這個上下文內容將被作為每個線程第一次執行的初始值。上下文在棧里的排布如下圖所示:
下代碼是棧初始化的代碼:
在棧里構建上下文
?
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
{struct stack_frame *stack_frame;rt_uint8_t *stk;unsigned long i;/* 對 傳 入 的 棧 指 針 做 對 齊 處 理 */stk = stack_addr + sizeof(rt_uint32_t);stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);stk -= sizeof(struct stack_frame);/* 得 到 上 下 文 的 棧 幀 的 指 針 */stack_frame = (struct stack_frame *)stk;/* 把 所 有 寄 存 器 的 默 認 值 設 置 為 0xdeadbeef */for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++){((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef;}/* 根 據 ARM APCS 調 用 標 準, 將 第 一 個 參 數 保 存 在 r0 寄 存 器 */stack_frame->exception_stack_frame.r0 = (unsigned long)parameter;/* 將 剩 下 的 參 數 寄 存 器 都 設 置 為 0 */stack_frame->exception_stack_frame.r1 = 0; /* r1 寄 存 器 */stack_frame->exception_stack_frame.r2 = 0; /* r2 寄 存 器 */stack_frame->exception_stack_frame.r3 = 0; /* r3 寄 存 器 *//* 將 IP(Intra-Procedure-call scratch register.) 設 置 為 0 */stack_frame->exception_stack_frame.r12 = 0; /* r12 寄 存 器 *//* 將 線 程 退 出 函 數 的 地 址 保 存 在 lr 寄 存 器 */stack_frame->exception_stack_frame.lr = (unsigned long)texit;/* 將 線 程 入 口 函 數 的 地 址 保 存 在 pc 寄 存 器 */stack_frame->exception_stack_frame.pc = (unsigned long)tentry;/* 設 置 psr 的 值 為 0x01000000L, 表 示 默 認 切 換 過去 是 Thumb 模 式 */stack_frame->exception_stack_frame.psr = 0x01000000L;/* 返 回 當 前 線 程 的 棧 地 址 */return stk;
}
需要注意的是,任務會在自己的棧內存的頂部,專門分出一段內存用來保存CPU內核寄存器的值,并做一些初始化的操作;
這樣一來,每個任務都會一套屬于自己的一套"CPU寄存器"了;
?
總結
以上是生活随笔為你收集整理的实现线程栈初始化(RTT)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。