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