日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

启动之OS_CPU_C

發布時間:2024/4/18 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 启动之OS_CPU_C 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
任務堆棧結構的初始化

在uC/OS-II中,任務是一個無限循環,任務之間也不會互相調用,但是uC/OS-II總是執行優先級最高的任務,假定當前有一個更高優先級的任務進入就緒狀態,為了保證原來低優先級任務的完整性,uC/OS-II為每個任務建立了任務堆棧,就相當于函數調用時保存返回地址和參數一樣,用來保存當前任務的狀態,保證任務切換能和函數調用一樣正確.只不過函數調用時函數堆棧的操作過程是編譯器自動完成的,而任務切換時需要模擬一個和編譯器類似的任務堆棧的操作過程.
OS_STK? *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
??? INT16U *stk;

??? opt??? = opt;?????????????????????????? /* 'opt' is not used, prevent warning????????????????????? */

//堆棧棧頂指針
??? stk??? = (INT16U *)ptos;??????????????? /* Load stack pointer????????????????????????????????????? */

//堆棧有高地址往低地址增長,故使用*stk--
//pada參數
//假定pdata會被編譯器保存到堆棧中,OSTaskStkInit()就會模仿編譯器的這種行為,將pdata保存到堆棧中.
??? *stk-- = (INT16U)FP_SEG(pdata);???????? /* Simulate call to function with argument???????????????? */
??? *stk-- = (INT16U)FP_OFF(pdata);

//任務起始地址.理論上,此處應該為任務的返回地址,但在uC/OS-II中,任務函數必須為無限循環結構,不能有返回點?????????
??? *stk-- = (INT16U)FP_SEG(task);
??? *stk-- = (INT16U)FP_OFF(task);

/*
PC:是你退出的當時執行程序時program counter,相當于你放下手中的事A去進行另一莊事情B,你得記住之前A事情已經做到什么階段了,也許B事情你得花上1年2年

PSW:是program status word.同樣道理,你開始做B事情的時候必須記住A事情的大致情況status.

堆棧:stack memory就像是一本舊的筆記本,記下A事情的各種問題,以便以后再做A事情,如果又有一個C事情,那B事情也得記到stack memory中

psw指程序狀態字(program status word的縮寫),是用來控制指令執行順序并且保留和指示與程序相關的系統狀態.
一般說來,程序狀態字包含程序基本狀態、中斷碼、中斷屏蔽位三部分內容.

基本狀態包括:指令地址,條件碼,目態管態,等待計算

中斷碼:保存程序執行時當前發生的中斷事件,以便操作系統進行分析處理

中斷屏蔽位:用來指出不要響應出現的中斷事件,若設置了中斷屏蔽位,則即使出現了中斷事件也不中止程序的執行,就像沒有發生中斷事件一樣

*/
//中斷使能-PSW狀態字-0000 0010 0000 0010即
//堆棧中的SW初始化為0x0202,這將使任務啟動后允許中斷發生;如果設為0x0002,則任務啟動后將禁止中斷
??? *stk-- = (INT16U)0x0202;??????????????? /* SW = Interrupts enabled???????????????????????????????? */

//堆棧頂端放置指向任務代碼的指針
??? *stk-- = (INT16U)FP_SEG(task);????????? /* Put pointer to task on top of stack?????????????????? */
??? *stk-- = (INT16U)FP_OFF(task);


//注意寄存器在堆棧中的位置要和運行指令PUSHA,PUSH ES,和PUSH DS和壓入堆棧的次序相同
//AX,BX,CX,DX,SP,BP,SI,和DI的次序是和指令PUSHA的壓棧次序相同的.如果使用沒有PUSHA指令的8086處理器,就要使用多個PUSH指令壓入上述寄存器,且順序要與PUSHA相同
//AX……的值在任務運行前無所謂的,因為在任務運行后在這些寄存器會有新的需要的值,寫0xAAAA……是為了堆棧的這個位置是AX……,其實用其他的值也行
??? *stk-- = (INT16U)0xAAAA;??????????????? /* AX = 0xAAAA???????????????????????????????????????????? */
??? *stk-- = (INT16U)0xCCCC;???????????????/* CX = 0xCCCC????????????????????????????????????????????*/
??? *stk-- = (INT16U)0xDDDD;???????????????/* DX = 0xDDDD????????????????????????????????????????????*/
??? *stk-- = (INT16U)0xBBBB;??????????????? /* BX = 0xBBBB???????????????????????????????????????????? */
??? *stk-- = (INT16U)0x0000;??????????????? ?/* SP = 0x0000?????????????????????????????????????????????? */
??? *stk-- = (INT16U)0x1111;??????????????? ?/* BP = 0x1111?????????????????????????????????????????????? */
??? *stk-- = (INT16U)0x2222;???????????????? /* SI = 0x2222??????????????????????????????????????????????? */
??? *stk-- = (INT16U)0x3333;???????????????? /* DI = 0x3333??????????????????????????????????????????????? */
??? *stk-- = (INT16U)0x4444;??????????????? ?/* ES = 0x4444?????????????????????????????????????????????? */
??? *stk?? = _DS;?????????????????????????? /* DS = Current value of DS???????????????????????????????????? */
??? return ((OS_STK *)stk);
}


//浮點仿真任務棧初始化函數 OSTaskStkInit_FPE_x86(),其中將分段尋址的地址轉換為線性地址
void? OSTaskStkInit_FPE_x86 (OS_STK **pptos, OS_STK **ppbos, INT32U *psize)
{
??? INT32U?? lin_tos;???????????????????????????????? /* 'Linear' version of top-of-stack??? address?? */
??? INT32U?? lin_bos;???????????????????????????????? /* 'Linear' version of bottom-of-stack address?? */
??? INT16U?? seg;
??? INT16U?? off;
??? INT32U?? bytes;


??? seg????? = FP_SEG(*pptos);??????????????????????? /* Decompose top-of-stack pointer into seg:off?? */
??? off????? = FP_OFF(*pptos);
??? lin_tos? = ((INT32U)seg << 4) + (INT32U)off;????? /* Convert seg:off to linear address???????????? */
??? bytes??? = *psize * sizeof(OS_STK);?????????????? /* Determine how many bytes for the stack??????? */
??? lin_bos? = (lin_tos - bytes + 15) & 0xFFFFFFF0L;? /* Ensure paragraph alignment for BOS??????????? */
????
??? seg????? = (INT16U)(lin_bos >> 4);??????????????? /* Get new 'normalized' segment????????????????? */
??? *ppbos?? = (OS_STK *)MK_FP(seg, 0x0000);????????? /* Create 'normalized' BOS pointer?????????????? */
??? memcpy(*ppbos, MK_FP(_SS, 0), 384);?????????????? /* Copy FP emulation memory to task's stack????? */
??? bytes??? = bytes - 16;??????????????????????????? /* Loose 16 bytes because of alignment?????????? */
??? *pptos?? = (OS_STK *)MK_FP(seg, (INT16U)bytes);?? /* Determine new top-of-stack??????????????????? */
??? *ppbos?? = (OS_STK *)MK_FP(seg, 384);???????????? /* Determine new bottom-of-stack???????????????? */
??? bytes??? = bytes - 384;
??? *psize?? = bytes / sizeof(OS_STK);??????????????? /* Determine new stack size????????????????????? */
}

總結

以上是生活随笔為你收集整理的启动之OS_CPU_C的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。