[計算機]綜述+任務堆棧初始化過程分析_第1頁
[計算機]綜述+任務堆棧初始化過程分析_第2頁
[計算機]綜述+任務堆棧初始化過程分析_第3頁
[計算機]綜述+任務堆棧初始化過程分析_第4頁
[計算機]綜述+任務堆棧初始化過程分析_第5頁
已閱讀5頁,還剩5頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、. 窗體頂端 綜述+任務堆棧初始化過程分析2010-10-27 03:40轉(zhuǎn)載自 likunyuan最終編輯 chiefsniper首先在看本文時有以下幾個知識點需要了解:1、為什么我要把工作模式切換在管理模式呢?答:根據(jù)第二版的ARM體系結(jié)構(gòu)參考手冊,我們可以查看到在用戶模式和系統(tǒng)模式下,使用LDM指令時,會導致對不可預知的錯誤。但是在IAREWARM環(huán)境下,對系統(tǒng)初始化時,是默認將ARM切換到系統(tǒng)模式的,因此在uCOS-II啟動時,我們默認的將系統(tǒng)切換到管理模式下工作。這樣就可以避免了在使用LDM指令時產(chǎn)生不可預知的錯誤了。2、著重強調(diào)一下在OS_CPU_A.A中匯編指令中的BX指令,為什

2、么要強調(diào)呢?答:根據(jù)第二版的ARM體系結(jié)構(gòu)參考手冊,在ARM體系的T變種版本4、ARM體系版本5及其以上版本。BX指令把通用寄存器Rm中的值拷貝到PC,同時判斷拷貝后的PC寄存器的第0位值是否是1,如果第0位的值是1,則將當前處理器切換到Thumd指令集下進行執(zhí)行。3、此處再講解一下向PC寄存器寫操作的注意事項,為什么要強調(diào)呢?答:根據(jù)第二版的ARM體系結(jié)構(gòu)參考手冊,我們可知,在向該寄存器進行寫操作時會導致程序跳轉(zhuǎn)到寫入PC寄存器的地址處進行執(zhí)行。在ARM指令集必須要求是字對齊的,那么寫入PC寄存器的值得最低2位就必須為0;在Thumd指令集下必須是半字對齊的,那么寫入PC寄存器的值得最低1位

3、就必須是0;ARM體系的版本較多,在ARM體系版本3及其以下版本,在ARM指令下寫入PC寄存器的最低2位是被忽略了的(也就是說是由硬件實現(xiàn)PC = PC&0xFFFFFFFC操作)在ARM體系版本4及其以上版本,在ARM指令下寫入PC寄存器的最低2位值是必須為0的,這部分是必須軟件完成的,即:在將地址寫入PC之前,必須將地址的值與0xFFFFFFFC進行與操作,再將操作的結(jié)果傳遞給PC寄存去。在Thumd指令集下要求所有指令為半字對齊,因此寫入PC寄存器的值必須先與0xFFFFFFFE進行與操作,然后再將與操作的結(jié)果傳遞給PC寄存器。4、特別提到大家注意一下LDM指令。為什么呢?答:該

4、指令只能在ARM指令集中,在Thumd指令集中是沒有該指令的。在查看到ARM+Architecture+Reference+Manual(2nd+Edition)手冊后,會發(fā)現(xiàn)對于LDM的操作有如下操作,用示意性代碼表示如下:If 條件滿足Address = start_addressFor( I = 0 ; I <= 14 ; i+)If (register_list = 1)Ri = Memoryaddress,4;Address += 4 ;If(register_list15 = 1)value = memoryaddress,4;If( ARM體系5版本及其以上版本)PC =

5、value & 0xFFFFFFFET bit = Value0 ;ElsePC = value&0xFFFFFFFCAddress = address + 4 ;上面的示意性代碼意思就是說,如果LDM的目的操作數(shù)包含PC寄存器的話,寫入PC寄存器的值得最后一位路過時1的話,執(zhí)行完畢LDM指令后,處理器就會切換到Thumd模式。本次分析所使用到的資料或書籍如下:1、ARM+Architecture+Reference+Manual(2nd+Edition)2、ARM體系結(jié)構(gòu)與編程-杜春蕾3、嵌入式實時操作系統(tǒng)COS-II(第二版)-邵貝貝翻譯4、ARM® IAR As

6、sembler Reference Guide5、IAR Embedded Workbench IDE User Guide6、IAR C/C+ Development Guide Compiling and linking 7、LPC2103的datasheet8、ARM and Thumb-2 Instruction Set Quick Reference Card9、Thumb 16-bit Instruction Set Quick Reference Card10、ARM7TDMI-S Technical Reference Manual轉(zhuǎn)自Tony嵌入式論壇,地址:文中所示代碼下載

7、:(稍后提供)下面先探討一下LPC2103這個芯片的堆??臻g。我們在建立該項目之前,就對編譯器設置了該工程的endian mode為little。Endian模式不清楚的就去查查ARM體系結(jié)構(gòu)與編程,這里就不多說了。在以ARM7TDMI-S為內(nèi)核的ARM芯片,其堆棧增長方向是由高地址向低地址增長。因此我們給每個任務分配的堆棧也必須按照這樣的方式進行“push”和“pop”操作。即可這樣理解:1、當我們在任務堆棧上執(zhí)行類似的“push”操作時,首先將所需保存的數(shù)據(jù)壓入到堆棧中,然后再對“任務的SP寄存器的值“-4。(這里-4的偏移量是因為我的整個移植代碼都是在ARM指令集下進行的所以偏移量的設置

8、是4);2、當我們在任務堆棧上執(zhí)行類似的“pop“操作時,首先將堆棧中的數(shù)據(jù)彈出堆棧,然后再對”任務的SP寄存器的值“+4。(這里+4的偏移量是因為我的整個移植代碼都是放在ARM指令集下進行的,所以偏移量的設置是4);任務堆棧的初始化過程分析一、OSTaskStkInit函數(shù)好了,現(xiàn)在就可以進行我們的代碼移植分析了。首先是對任務堆棧的初始化工作,代碼如下:#define ARM_MODE_ARM 0x00000000#define ARM_MODE_THUMB 0x00000020#define ARM_SVC_MODE_THUMB (0x00000013L + ARM_MODE_THUMB)

9、#define ARM_SVC_MODE_ARM (0x00000013L + ARM_MODE_ARM)OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)OS_STK *stk;INT32U task_addr;opt= opt;stk= ptos;task_addr = (INT32U)task & 1;*(stk)= (INT32U)task_addr;/PC*(-stk)= (INT32U)0x14141414L;/R14*(-stk)= (INT32U

10、)0x12121212L;/R12*(-stk)= (INT32U)0x11111111L;/R11*(-stk)= (INT32U)0x10101010L;/R10*(-stk)= (INT32U)0x09090909L;/R9*(-stk)= (INT32U)0x08080808L;/R8*(-stk)= (INT32U)0x07070707L;/R7*(-stk)= (INT32U)0x06060606L;/R6*(-stk)= (INT32U)0x05050505L;/R5*(-stk)= (INT32U)0x04040404L;/R4*(-stk)= (INT32U)0x030303

11、03L;/R3*(-stk)= (INT32U)0x02020202L;/R2*(-stk)= (INT32U)0x01010101L;/R1*(-stk)= (INT32U)p_arg;/R0if (INT32U)task & 0x01) *(-stk) = (INT32U)ARM_SVC_MODE_THUMB; else *(-stk) = (INT32U)ARM_SVC_MODE_ARM;return (stk);現(xiàn)在一句一句來分析:1、opt= opt;stk= ptos;這兩句放到這里是沒有任何實際意義,只是為了防止編譯器報警;2、task_addr = (INT32U)ta

12、sk & 1;這一句可能很多人都不理解,干嘛還要對任務的地址&1呢?答:實際上任務的地址(就是調(diào)用函數(shù)的起始地址)是要在LDMFD寫入到PC的,而對于LDM的操作,寫入PC的最后1bit會影響到處理器是否切換到Thumd模式下的,我在這里將任務地址的最后1bit清0,是為了保證任務在ARM模式下進行工作的。因為在部分ARM指令和Thumd指令混合編譯的情況下,可能會導致整個uCOS系統(tǒng)崩潰的。加上這一句就能很好的保證系統(tǒng)在進行任務切換的時候,所有指令均能在ARM指令系統(tǒng)下工作。我說了是不是大家就很清楚了呢?3、*(-stk)= (INT32U)0x14141414L;/R14很

13、多朋友可能會在這一句上有非常大的疑問了,R14寄存器不是LR寄存器么?這個可以存儲子程序的返回地址或者是存儲分子語句的返回地址?。吭趺催@里會對R14賦值成(INT32U)0x14141414L。這樣做會不會讓整個系統(tǒng)工作不正常???答:回答這個問題,就要用uCOS對于任務的定義了,在uCOS處理機制中,所有的任務都是一個包含死循環(huán)的函數(shù),死循環(huán)中是根本就不會有返回地址的了,所以這里隨便寫入一個值都不會影響到任務的正常運行的。4、對R12和R1的初始化,大家可能又要問了,干嘛這樣賦值???答:實際上對任務的初始化時在任務運行之前進行的,一個任務都還沒有運行,他有怎么可能有影響R1到R12的值了,對于

14、這點大家可以想象一下一個前后臺的系統(tǒng)在程序剛開始執(zhí)行的時候是否會需要使用到這些寄存器呢?所以初始化這些寄存器根本就不會對任務運行有任何影響。5、*(-stk)= (INT32U)p_arg;這個是對R0寄存器的初始化。為什么要這樣做呢?相信熟悉IAREWARM的朋友可能會知道(當然不知道的話,建議去做一個簡單的測試程序),所有函數(shù)的第一個形式參數(shù)都是傳遞給R0的。P_arg就是我們建立的任務的第一個形參,盡管很多朋友在這個形參的設計上沒有使用到。注意:實際上MDK也是用R0作為函數(shù)的第一個形參壓棧處理的。6、對于最后的最后一個參數(shù)的初始化時對當前任務運行的異常模式和ARM或Thumd模式的一個壓入堆棧的操作。7、還有的朋友可能會問道,怎么沒有看到對SP寄存器的保存呢?答:SP寄存器的保存實際是將SP寄存器的值保存到TCB的數(shù)據(jù)結(jié)構(gòu)中了,所以這里就不再需要對SP進行重復保存了。在這個函數(shù)完成以后,任務的任務堆棧就像下面的方式建立了:低地址CPSRARM_SVC_MODE_ARM|R

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論