




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
UCOSIICortex-M3/M4基礎(chǔ)第三章移植文件講解UCOSIIIUCOSIIIAPI函數(shù)使用UCOSIII中斷和時(shí)間管理第八章UCOSIII軟件定時(shí)器UCOSIII信號(hào)量和互斥信號(hào)量第十章UCOSIII消息傳遞第十一章標(biāo)志任務(wù)中由于任務(wù)堆棧設(shè)置小而進(jìn)入hardfault的p_msg_size10-1的代碼。 第一章UCOSII移 移植準(zhǔn)備工 UCOSII移 軟件設(shè) 驗(yàn) Cortex-M3/M4通用寄存 操作模式和級(jí) Lazy 堆 Cortex-M3/M4堆棧操 雙堆棧機(jī) Stack SVC和PendSV異 第三章移植文件講 滴答定時(shí)器 第四章UCOSIII移 移植準(zhǔn)備工 準(zhǔn)備基礎(chǔ)工 UCOSIII移 向工程中添加相應(yīng)的文 修改 軟件設(shè) 驗(yàn) 第五章UCOSIII任務(wù)管 任務(wù)狀 任務(wù)控制 任務(wù)堆 任務(wù)就緒 優(yōu)先級(jí)位映射 就緒任務(wù)列 任務(wù)調(diào)度和切 可型調(diào) 時(shí)間片輪轉(zhuǎn)調(diào) 第六章任務(wù)相關(guān)API函數(shù)使 任務(wù)創(chuàng)建和刪除實(shí) 實(shí)驗(yàn)程序設(shè) 程序運(yùn)行結(jié)果分 任務(wù)掛起和恢復(fù)實(shí) 實(shí)驗(yàn)程序設(shè) 程序運(yùn)行結(jié)果分 時(shí)間片輪轉(zhuǎn)調(diào)度實(shí) 實(shí)驗(yàn)程序設(shè) 實(shí)驗(yàn)程序運(yùn)行結(jié) 第七章UCOSIII中斷和時(shí)間管 中斷管 直接發(fā)布和延遲發(fā) 臨界段代碼保 時(shí)間管 其他有關(guān)時(shí)間函 第八章UCOSIII軟件定時(shí) 定時(shí)器工作模 創(chuàng)建一個(gè)定時(shí) 單次定時(shí) 實(shí)驗(yàn)程序設(shè) 實(shí)驗(yàn)程序運(yùn)行結(jié) 信號(hào) 創(chuàng)建信號(hào) 請(qǐng)求信號(hào) 發(fā)送信號(hào) 優(yōu)先級(jí)反 互斥信號(hào) 創(chuàng)建互斥型信號(hào) 請(qǐng)求互斥型信號(hào) 發(fā)送互斥信號(hào) 直接共享資源區(qū)實(shí) 實(shí)驗(yàn)程序設(shè) 實(shí)驗(yàn)程序運(yùn)行結(jié) 使用信號(hào)量共享資源區(qū)實(shí) 實(shí)驗(yàn)程序設(shè) 實(shí)驗(yàn)程序運(yùn)行結(jié) 任務(wù)同步實(shí) 實(shí)驗(yàn)程序設(shè) 實(shí)驗(yàn)程序運(yùn)行結(jié) 第十章UCOSIII消息傳 消息隊(duì) 消息隊(duì)列相關(guān)函 創(chuàng)建消息隊(duì) 等待消息隊(duì) 向消息隊(duì)列發(fā)送消 消息隊(duì)列實(shí) 實(shí)驗(yàn)程序設(shè) 實(shí)驗(yàn)程序運(yùn)行結(jié) 第十一章標(biāo)志 11.1標(biāo)志 11.2標(biāo)志組相關(guān)函 創(chuàng)建標(biāo)志 等待標(biāo)志 向標(biāo)志組發(fā)布標(biāo) 時(shí)間標(biāo)志組實(shí) 實(shí)驗(yàn)程序設(shè) 實(shí)驗(yàn)程序結(jié)果分 UCOSII在以前學(xué)習(xí)的例程中大多都不帶操作系統(tǒng),也就是奔,本將帶領(lǐng)大家進(jìn)入RTOS的世界,關(guān)于RTOS類(lèi)操作系統(tǒng)有很多,本選取的是非常有名的UCOS操作系統(tǒng)。在使用STM32F407開(kāi)發(fā)板上移植UCOSII操作系統(tǒng),本章只是講解如何移植,關(guān)于移植過(guò)程中使用到UCOSII國(guó)際慣例,首先準(zhǔn)備移植所需的基礎(chǔ)工程,本章是在庫(kù)函數(shù)版跑馬燈實(shí)驗(yàn)的基礎(chǔ)上完OSII既然要移植UCOSII,那么源碼肯定是要有的,我們可以在Micrium官網(wǎng)上,地址: 界面如圖1.1.1所示,在Micrium官網(wǎng)東西需要賬號(hào),我們已經(jīng)好UCOSII源碼放在光盤(pán)中,路徑:6,軟件資料2,UCOS學(xué)習(xí)資料UCOSII資料UCOSII源碼下的圖1.1.1UCOSII頁(yè)有時(shí)候我們下來(lái)的可能是.html結(jié)尾的文件,其后綴改為.zip,然后使用解壓軟件解壓就可以了,解壓后的文件名為:MircriumUCOSII的源碼文件。1.1.2UCOSII1.1.2中DocUCOSII的文檔,SourceUCOSIISII1)我們?cè)诠?下新建UCOSII文件夾,并在UCOSII文件夾另外中新建三個(gè)文件夾CONFIG、CORE和PORT1.2.1圖1.2.1新建UCOSII文件夾及其2COREUCOSIICORE1.2.2所示。3CONFIGUCOSII1.2.3所示。1.2.3CONFIGos_dgb_r.cPORTPORT文件夾中,拷1.2.4所示。4UCOSII UCOSII-建立完成后如圖1.2.5所示。1.2.5UCOSII-CORECOREucosii.c外的所有.c文件,向UCOSII-PORT分組中添加PORT文件夾下的os_cpu.hos_cpu_a.asm和os_cpu_c.c這三個(gè)文件,UCOSII-CONFIG分組添加CONFIGincludes.hos_cfg.h這兩個(gè)文件,添1.2.61.2.7UCOSII1.2.8所示的1.2.8app_cfg.h我們可以追蹤一下是在哪里出現(xiàn)的錯(cuò)誤,結(jié)果發(fā)現(xiàn)在ucos_ii.happ_cfg.h1.2.9所示。1.2.91.2.10所示,提示我們?cè)趏s_cpu_a.ostm32f4xx_it.oPendSV_Handler這個(gè)函數(shù)。中斷服務(wù)函數(shù)PendSV_Handler我們下一章講解。1.2.10PendSV_Handlerstm32f4xx_it.cstm32f4xx_it.c中的PendSV5sys.h0的話不支持UCOS,其改為1支持UCOSSYSTEM_SUPPORT_UCOS11.2.12所示錯(cuò)stm32f4xx_it.odelay.oSysTick_Handler這個(gè)函數(shù),SysTick_Handler我們?cè)谙乱徽轮v解。同樣,stm32f4xx_it.c文件中的中斷服務(wù)函數(shù)SysTick_Handler掉,后如1.2.13圖1.2.13掉中斷服務(wù)函數(shù)2)STM32F407FPUUCOSII以后就要測(cè)試一下是否FPUFPU的過(guò)程如下。1.2.14從圖1.2.14中我們可以看出如果要使用FPU的話FPU_PRESENT和FPU_USED要為stm32f4xx.h文件中已經(jīng)定義了FPU_PRESENT1,但是并未定義FPU_USED,因此我1.2.15所示添加FPU_USED的定義。1.2.15定義1.2.16通過(guò)上面幾節(jié)我們已經(jīng)完成了UCOSII在STM32F4073個(gè)簡(jiǎn)單的任務(wù)來(lái)測(cè)試一下,這里我們還另外建立了start_task3個(gè)任務(wù),main.c#define #define OS_STKvoidstart_task(void//LED0#define #define OS_STKvoidled0_task(void//LED1#define #define OS_STKvoidled1_task(void#define #define align(8)OS_STKvoidfloat_task(voidint{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中斷分組配置 //LED //UCOS初始化START_TASK_PRIO);//創(chuàng)建開(kāi)始任務(wù)();//}voidstart_task(void{OS_CPU_SRcpu_sr=0; //LED0//LED1 }//LED0voidled0_task(void{{}//LED1voidled1_task(void{{}voidfloat_task(void{OS_CPU_SRcpu_sr=0;staticfloatfloat_num=0.01;{ printf("float_num的值為:%.4f\r\n",float_num);//串口打印結(jié)果 }}main.c4個(gè)任務(wù):start_task、led0_task、led1_taskfloat_task。start_task33個(gè)任務(wù)后就會(huì)掛起的。led0_task和FPU500msfloat_num0.01,然后通過(guò)串口1.4驗(yàn)編譯代碼后到開(kāi)發(fā)板中,打開(kāi)串口調(diào)試助手,我們可以看到LED0和LED1開(kāi)始按照1.4.1所示,從圖中可以看出float_num0.01遞增,和我們程序中設(shè)置的一樣。1.4.1FPUSTM32F407的內(nèi)部FPU指令,我們進(jìn)入調(diào)試界面,打開(kāi)匯編窗口:View->Disassembly1.4.2所示的地方1.4.21.4.3所示。1.4.3UserGuide》(光盤(pán)資料中:8,STM32參考資料Cortex-M4DevicesGenericUserGuide.pdf)的173頁(yè)我們可以知道VLDR、VADD.F32FPUSTM32F407內(nèi)部FPU成功。上一章中我們講解了如何在STM32F407UCOSII2.1Cortex-M3/M42.2操作模式和級(jí)2.3FPU2.42.5SVC和PendSVCortex-M3/M4和M3是一樣的,以下內(nèi)容參考自《ARMCortex-M3指南》和《Cortex-M3與M4指8,STM32參考資料。Cortex-M3/M4R0R15以及一些特殊功能寄R0R1216R0‐R7(低組寄存器,而32位的Thumb‐2指令則可以所有通用寄存器。特殊功能寄存器有預(yù)定義的功能,而且必須通過(guò)的指令來(lái),Cortex-M3/M4的通用寄存器如圖2.1.1所示。2.1.1Cortex-M3/M4R0‐R7也被稱為低組寄存器。所有指令都能它們。它們的字長(zhǎng)全是32位,復(fù)位后R8-R8‐R12也被稱為高組寄存器這是因?yàn)橹挥泻苌俚?6位Thumb指令能它們,32R13CM3/CM4當(dāng)R13(或?qū)懽鱏P)時(shí),你到的是當(dāng)前正在使用的那一個(gè),另一個(gè)必須用特殊的指令來(lái)(MRS,MSR指令。這兩個(gè)堆棧指針?lè)謩e是:主堆棧指針(MSPSP_mainOS內(nèi)核、異常(PSPMSP就夠了。堆棧指針用于堆棧,并且PUSH指令和POP指令默認(rèn)使用SP。R14(LRbothLRR14LR用于在調(diào)用子程序時(shí)返回地址。例如,當(dāng)你在使用BL(分支并連接,BranchandLink)指令時(shí),就自動(dòng)填充LR的值。盡管PCLSB0(因?yàn)榇a至少是字對(duì)齊的,LRLSB卻是可讀可寫(xiě)的。這0ARM/ThumbARM處理器ARMThumbCM3/CM4需要允許LSB可讀可R15是程序計(jì)數(shù)器,在匯編代碼中你也可以使用名字“PC”來(lái)它。因?yàn)镻C時(shí)返回的值是當(dāng)前指令的地址+4 ;R0=PC中寫(xiě)數(shù)據(jù),就會(huì)引起一次程序的分支(LR寄存器。CM3/CM4PCLSB0。然而,在分支時(shí),無(wú)論是直接寫(xiě)PCPC的數(shù)值是奇數(shù)(LSB=1,用以表明這是在Thumb0ARM模式,CM3fault異2.1.2/程序狀態(tài)寄存器組(PSRs中斷寄存器組(PRIMASK,FAULTMASK,以及控制寄存器(它們只能被的MSR和MRS指令,而且它們也沒(méi)有器地址。 ;讀特殊功能寄存器的值到通用寄存器 <special_reg>,<gp_reg> ;寫(xiě)通用寄存器的值到特殊功能寄存器7)程序狀態(tài)寄存器(PSRs或曰PSR)PSR(PSR(PSR(EP通過(guò)MRS/MSR指令,這3個(gè)PSRs既可以單獨(dú),也可以組合(2個(gè)組合PSR2.1.所示。98765NZCVQExceptionT2.1.1Cortex-M3/M42.1.2fault0fault0這個(gè)寄存器最多有9位(由表達(dá)優(yōu)先級(jí)的位數(shù)決定。它定義了被優(yōu)先級(jí)的號(hào)越大,優(yōu)先級(jí)越低00表2.1.2Cortex-M3/M4寄存對(duì)于時(shí)間‐關(guān)鍵任務(wù)而言,PRIMASK和BASEPRI對(duì)于暫時(shí)關(guān)閉中斷是非常重要的。而FAULTMASK則可以被OS用于暫時(shí)關(guān)閉fault處理機(jī)能這種處理在某個(gè)任務(wù)時(shí)可能需要。因?yàn)樵谌蝿?wù)時(shí),常常伴隨著一大堆faults。在系統(tǒng)料理“后事”時(shí),通常不再需要faultFAULTMASKOS要PRIMASK,FAULTMASK以及BASEPRI,同樣要使用MRS/MSR指令,如MRS ;BASEPRI到R0MRS MRS R0BASEPRI只有在級(jí)下,才允許這3個(gè)寄存器,為了快速地開(kāi)關(guān)中斷,CM3/CM4還專門(mén)設(shè)置CPSIDI;PRIMASK=1CPSIEI;PRIMASK=0CPSIDF;FAULTMASK=1CPSIEF;FAULTMASK=0控制寄存器CONTROL寄存器用于定義級(jí)別和堆棧指針的使用,CONTROL寄存器如表2.1.3所示,注CONTROL[2Cortex-M4位0=MSP(復(fù)位后缺省值1=PSPhandlerMSP,所以此時(shí)不得往該位寫(xiě)1。Handler模式都是級(jí)
2.1.3CONTROLCortex-M4FPUFPUFPU在Cortex‐M3的handler模式中,CONTROL[1]總是0程模式中則可以為0或1。僅當(dāng)處于級(jí)的線程模式下,此位才可寫(xiě),其它場(chǎng)合下寫(xiě)此位。改變處理器的模式也有其它的方式:在異常返回時(shí),通過(guò)修改LR的位2,也能實(shí)現(xiàn)模式切換。僅當(dāng)在級(jí)下操作時(shí)才允許寫(xiě)該位。一旦進(jìn)入了用戶級(jí),唯一返回級(jí)的途徑,就是觸發(fā)一個(gè)(軟)中斷,再由服務(wù)例程改寫(xiě)該位。CONTROLMRSMSR LREXC_RETURNCortex-M4271的值(M3281)。M4中[4:0]M3中[3:0]M4中的相同,EXC_RETURN2.1.4所示。注意!EXC_RETURN的bit4非常重要,我們可以根據(jù)此位的值來(lái)獲知硬件會(huì)對(duì)哪些寄存器進(jìn)40=硬件自堆棧中壓入26個(gè)字1=硬件自堆棧中壓入8個(gè)0。30=Handler2100=ARM1=ThumbCM3/CM42.1.4EXC_RETURN2.1.5EXC_RETURNCortex-M3/M4的另一個(gè)側(cè)面則是的分級(jí)——級(jí)和用戶級(jí)這可以提供一種器的保護(hù)機(jī)制,使得普通的用戶程序代碼不能意外地,甚至是地執(zhí)行涉及到要害的操作。處理器支持兩種級(jí),如表2.2.1所示,這也是一個(gè)基本的安全模型。級(jí)handlerhandler表2.2.1Cortex-M3/M4下的操作模式和級(jí)是異常服務(wù)例程必須在級(jí)下執(zhí)行。復(fù)位后,處理器默認(rèn)進(jìn)入線程模式,級(jí)。在特權(quán)級(jí)下,程序可以所有范圍的器(如果有MPU,還要在MPU規(guī)定的禁地之外并在級(jí)下的程序可以,但也可能會(huì)把自己給玩進(jìn)去——切換到用戶級(jí)。一旦進(jìn)入用戶級(jí),再想回來(lái)就得走“法律程序”了——用戶級(jí)的程序不能簡(jiǎn)簡(jiǎn)單單地試圖改寫(xiě)序執(zhí)行過(guò)程中觸發(fā)了一個(gè)異常,處理器總是先切換入級(jí),并且在異常服務(wù)例程執(zhí)行完畢退FPUFPUFPU單元的話就可以使用它來(lái)對(duì)單精度浮點(diǎn)數(shù)進(jìn)行計(jì)算,雙精度浮C運(yùn)行庫(kù)。FPUFPUFPU>CACRCACRCP112.2.1CP10和CP112bit2.3.1CP10CP1100通過(guò)設(shè)置CP10和CP1111來(lái)開(kāi)啟,實(shí)例代碼如下: //323232642.3.1B之前一定要保存這些寄存器,因?yàn)樵谡{(diào)用的時(shí)候這些寄存器會(huì)被改變。S16-S31callee-saved寄存器,如果一個(gè)應(yīng)用A調(diào)用應(yīng)用BB16個(gè)LazyCortex-M4LazyStackingFPU的情況下,不使用這29258LazyStacking12個(gè)時(shí)鐘LazyStacking是使能的Cortex-M4的這個(gè)特性將會(huì)極大的提高任務(wù)切換的速度,我們UCOSII的時(shí)候就使用了這個(gè)特性。Cortex-M3/M4SP指向最后一個(gè)被壓入堆棧32位數(shù)值。在下一次壓棧時(shí),SP先自減42.4.1所示。2.4.1PUSHPOPSPSP42.4.2POPISR時(shí),CM3/CM4ISR之前使用的PSP前的SP指針來(lái)執(zhí)行出棧操作。CM3/CM4的堆棧是分為兩個(gè):主堆棧和進(jìn)程堆棧,CONTROL[1]決定如CONTROL[1]=0MSPhandler共享同一個(gè)堆棧。2.4.3所示。2.4.3CONTROL[1]=0當(dāng)CONTROL[1]=1時(shí)線程模式將不再使用PSP而改用MSP(handler模式使用MSP此時(shí),進(jìn)入異常時(shí)的自動(dòng)壓棧使用的是進(jìn)程堆棧,進(jìn)入異常handlerMSP,退出異常時(shí)切換回PSP2.4.4所示。2.4.4CONTROL[1]=1 MSP;主堆棧指針到R0;進(jìn)程堆棧指針到R0通過(guò)PSP的值,OS就能夠獲取用戶應(yīng)用程序使用的堆棧,進(jìn)一步地就知道了在發(fā)生異常時(shí),被壓入寄存器的內(nèi)容,而且還可以把其它寄存器進(jìn)一步壓棧的書(shū)寫(xiě)形式。OS還可以修改PSP,用于實(shí)現(xiàn)多任務(wù)中的任務(wù)上下文切換。Stack2.4.5所示。2.45FPUStackAAPCSM3其雙字對(duì)齊。雙字對(duì)齊是一個(gè)可選項(xiàng),欲使能此特性,需要把NVIC配置控制寄存器的STKALIGN置位,如下面匯編代碼所演示: R0=NVICCCR W R1,# ;設(shè)置STKALIGN ;NVICC#defineNVIC_CCR((volatileunsignedlong*NVIC_CCR=*NVIC_CCR| xPSPbit9SP是否需要對(duì)齊,bit91的話就需要雙字對(duì)齊,如0FPUStackframe2.4.6所示。個(gè)寄存器R4-R112.4.6FPU時(shí)的Stack對(duì)于Cortex-M4FPUFPUStackframe就會(huì)S0-S15FPSCR寄存器,也可選擇是否使用雙字對(duì)齊,在Cortex-M4中默認(rèn)開(kāi)啟了雙字對(duì)齊功能,Stackframe2.4.7所示。2.4.7FPUStackFPSCRStackframeUCOSII的堆棧初始化函數(shù)OSTaskStkInit()0就是這么來(lái)的。我們可以看出還有R4-R11,S16-S31這些寄存器沒(méi)有做處理,那么我們就要手動(dòng)對(duì)這些寄SVCPendSVSVC務(wù)函數(shù)的呼叫請(qǐng)求,以這種方法調(diào)用它們來(lái)間接硬件。因此,當(dāng)用戶程序想要控制特定的從而能使系統(tǒng)更加健壯和可靠。第三,它使用戶程序無(wú)需在級(jí)下執(zhí)行,用戶程序無(wú)需承擔(dān)口(API)SVC來(lái)提出要求了。其實(shí),嚴(yán)格2.5.1所示。2.5.1SVC ;3在SVC服務(wù)例程執(zhí)行后上次執(zhí)行的SVC指令地址可以根據(jù)自動(dòng)入棧的返回地址計(jì)算出。找到了SVC指令后,就可以該SVC指令的機(jī)器碼,從機(jī)器碼中萃取出立即數(shù),就獲知了請(qǐng)求執(zhí)行的功能代號(hào)。如果用戶程序使用的是PSP,服務(wù)例程還需要先執(zhí)行MRS 指令來(lái)獲取應(yīng)用程序的堆棧指針。通過(guò)分析LR的值,可以獲知在SVC指令執(zhí)行時(shí)正在使用哪PendSVPendSV(可懸起的系統(tǒng)調(diào)用SVCSVC異常是必須立即得到SVC時(shí)都是希望所需的請(qǐng)求立即得到響應(yīng)。另一方面,PendSV則不同,個(gè)異常,直到其它重要的任務(wù)完成后才執(zhí)行動(dòng)作。懸起PendSV的方法是:手工往NVIC的PendSV懸起寄存器中寫(xiě)1。懸起后,如果優(yōu)先級(jí)不夠高,則將等待執(zhí)行。PendSV的典型使用場(chǎng)合是在上下文切換時(shí)(在不同任務(wù)之間切換。例如,一個(gè)系統(tǒng)中有(且通過(guò)SysTick2.5.2所示。2.5.2SysTick2.5.2SysTick異常時(shí)正在響應(yīng)一個(gè)中斷,CM3/CM4OS在某中斷活躍時(shí)嘗試切入線fault2.5.3所示。2.5.3IRQSysTick異常SysTick異常的頻率比較接近時(shí),會(huì)發(fā)生“。PendSVPendSV異常會(huì)自動(dòng)延遲上下文切換的請(qǐng)求,直到其它的ISR都完成了處理后才放行。為實(shí)現(xiàn)這個(gè)機(jī)制,需要把PendSV編程為最低優(yōu)先級(jí)的異常。如果OS檢測(cè)到某IRQ正在活動(dòng)并且被SysTick搶占,它將懸起一個(gè)PendSV異常,以便執(zhí)行上下文切換,如圖2.5.4。2.5.4PendSV控制上下文切換圖2.5.4中的記錄如下:ASVC來(lái)請(qǐng)求任務(wù)切換(例如,等待某些工作完成OSpendPendSVCPUSVCPendSVPendSVBISRSysTickISROSpendPendSVSysTickISRISRISRPendSVPendSVA在第一章我們講解了UCOSII在STM32F407開(kāi)發(fā)板上的移植過(guò)程,第二章講解了一下UCOSII的過(guò)程中都做了那些工作,本章分為如下幾部os_cpu_a.asmos_cpu.h240時(shí),將從RELOAD寄存器中自動(dòng)重裝載定時(shí)器初值,只要不把它在SysTick控制以及狀態(tài)寄存器中的使能位,就將永久不息。SysTick的最大使命,就是定期地產(chǎn)生異常請(qǐng)求作為系統(tǒng)的時(shí)基。OS都需要這種“滴答”來(lái)推voiddelay_init(u8{voiddelay_init(u8{#ifdefu32reload; //ucos,fac_us都需要使用//OS_CRITICAL_METHOD定義了,ucosII了.#ifdefOS_CRITICAL_METHOD /OS_TICKS_PER_SEC;//根據(jù)OS_TICKS_PER_SEC//reload為24位寄存器,最大值 ,在168M下,約合0.7989s左 }其中紅色代碼部分就是在使用UCOSII時(shí)配置SysTick的代碼,如果UCOSIIOS_TICKS_PER_SECSysTickreload,開(kāi)啟SysTickreloadSysTickLOADSysTick。//OS_CRITICAL_METHOD定義了,ucosII//OS_CRITICAL_METHOD定義了,ucosII了.#ifdefOS_CRITICAL_METHODvoid{ } IMPORTEXPORT來(lái)定義。;NVIC_SYSPRI14 ;系統(tǒng)優(yōu)先級(jí)寄存器 0xFFFFPendSV ; R0, PRIMASKR0,R0 ;NVIC_SYSPRI14 ;系統(tǒng)優(yōu)先級(jí)寄存器 0xFFFFPendSV ; R0, PRIMASKR0,R0 PRIMASK, ;R0PRIMASK中,R0 I來(lái)關(guān)中斷 I來(lái)關(guān)中斷 ;設(shè)置PendSV; ;設(shè)置;觸發(fā)PendSVI{R4,{R4, R5,R4];NVIC_INT_CTRL寫(xiě)入NVIC_PENDSVSET觸發(fā)PendSV{R4,R5}{R4,R5}R5,R4NVIC_INT_CTRL寫(xiě)入NVIC_PENDSVSETPendSV{R4,R5}IR0,R0PendSV_Handler_Nosave;如果PSP0OSCtxSwOSIntCtxSw這兩個(gè)是用來(lái)做任務(wù)切換的,這兩個(gè)看起來(lái)都是一樣的,其實(shí)它IR0,R0PendSV_Handler_Nosave;如果PSP0 R14,#0x10 VSTMDBEQR0!,{S16- R0,R0, R0,R4- ;R4-R11 R1, ; R1,[R1] ;R1=*R1既R1=OSTCBCur R0,[R1] ;*R1=R0既OSTCBCur=SP ;保存R14 R0,OSTaskSwHook;R0=&OSTaskSwHook ;調(diào)用 R0,=OSPrioCur R1,=OSPrioHighRdy;R1=&OSPrioHighRdy R2 ;R2=*R1既 R2, ;*R0=R2 R0, R1,=OSTCBHighRdy R2, ;R2=*R1既 R2, ;*R0=R2既 R0,[R2] ;R0=*R2,既R0=OSTCBHighRdy,R0是新任務(wù)的SP R0,{R4-R11} ;從堆棧中恢復(fù)R4-R11 R0,R0, ④TST R14,#0x10 VLDMIAEQR0!,{S16-PSP=R0,SPLR,LR,;LR21IPendSV_Handler_Nosave。⑤MSPPSPLR的21。在第一章UCOSII移植的時(shí)候要掉stm32f4xx_it.c文件中的PendSV_Handler()中斷os_cpu_a.asm中重新定義了PendSV_Handler()函數(shù),我們有時(shí)候在移植的時(shí)候可能會(huì)發(fā)現(xiàn)有OS_CPU_PendSVHandler這樣的函數(shù),其實(shí)這是移植使用到的,具體作用和PendSV_Handler一樣都是PendSV的中斷服務(wù)函數(shù),不過(guò)ST啟動(dòng)文件startup_stm32f40_41xxx.sPendSVPendSV_Handler,所以說(shuō)如果要使OS_CPU_PendSVHandler作為PendSV的中斷服務(wù)函數(shù)就需要修改啟動(dòng)文件startup_stm32f40_41xxx.s中的中斷向量表。os_cpu.htypedefunsignedtypedefunsigned//8typedef //8typedefunsigned//16typedef //16typedefunsigned//32typedef //32typedeftypedef//STM3232位位寬的,OS_STKOS_CPU_SR32typedefunsigned//OS_STK324typedefunsigned//CPU32 1=: #ifOS_CRITICAL_METHOD== {cpu_sr=OS_CPU_SR_Save();} 上面代碼中我們定義了堆棧的增長(zhǎng)方向,任務(wù)級(jí)切換的宏定義OS_TASK_SW。如果OS_CRITICAL_METHOD被定義為3的話那么進(jìn)出臨界段的宏定義分別為os_cpu_c.cos_cpu_c.c文件里面主要定義了幾鉤子函數(shù),這里我們就不具體講解這些鉤子函數(shù)了,我OSTaskStkInit()這個(gè)函數(shù),OSTaskStkInit()是堆棧初始化函數(shù),函數(shù)代碼如下。OS_STK*OSTaskStkInit(void(*task)(void*p_arg),void*p_arg,OS_STK*ptos,INT16Uopt){OS_STK //optstk= //Loadstack#if(FPU_PRESENT==1)&&(*(--stk)= //NoName*(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= *(--stk)= = = = = = = =#if(FPU_PRESENT==1)&&(*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=*(--stk)=====return} = = = = = = FPULazyStacking特性的話(Cortex-M4默認(rèn)是開(kāi)啟了的)FPSCR、S0-S15、xPSR、PC、LR、R12、R0-R3這些寄Stackframe的時(shí)候已經(jīng)講了,可以看到在OSTaskStkInit()S16-S31和R4-R11就需要我們手動(dòng)入U(xiǎn)COSIII輪轉(zhuǎn)調(diào)度,極短的關(guān)中斷等。本章我們就講解如何在STM32F407開(kāi)發(fā)板上移植UCOSIIIUCOSIIIUCOSIIIUCOSIIIUCOSIII是一個(gè)可裁剪、可、可的多任務(wù)系統(tǒng),沒(méi)有任務(wù)數(shù)目的限制,是可多任務(wù)管理:UCOSIII和UCOSII一樣都屬于可的多任務(wù)內(nèi)核,總是執(zhí)行當(dāng)前同優(yōu)先級(jí)任務(wù)的時(shí)間片輪轉(zhuǎn)調(diào)度:UCOSIIIUCOSII一個(gè)比較大的區(qū)別,UCOSIII允許一個(gè)任務(wù)優(yōu)先級(jí)被多個(gè)任務(wù)使用,當(dāng)這個(gè)優(yōu)先級(jí)處于最高就緒態(tài)的時(shí)候,UCOSIII就會(huì)輪極短的關(guān)中斷時(shí)間:UCOSIII可以采用鎖定內(nèi)核調(diào)度的方式而不是關(guān)中斷的方式來(lái)保護(hù)臨UCOSIII能夠非常快速的響應(yīng)中斷請(qǐng)求。優(yōu)先級(jí)數(shù)量不受限制:UCOSIII支持無(wú)限多的任務(wù)優(yōu)先級(jí)。內(nèi)核對(duì)象數(shù)目不受限制:UCOSIII允許定義任意數(shù)目的內(nèi)核對(duì)象。內(nèi)核對(duì)象指任務(wù)、信號(hào)量、互斥信號(hào)量、標(biāo)志組、消息隊(duì)列、定時(shí)器和快等。同時(shí)等待多個(gè)內(nèi)核對(duì)象:UCOSIII允許一個(gè)任務(wù)同時(shí)等待多個(gè)。也就是說(shuō),一個(gè)任務(wù)能夠掛起在多個(gè)信號(hào)量或消息隊(duì)列上,當(dāng)其中任何一個(gè)等待的發(fā)生時(shí),等待任務(wù)就會(huì)被喚直接向任務(wù)發(fā)送信號(hào):UCOSIII允許中斷或任務(wù)直接給另一個(gè)任務(wù)發(fā)送信號(hào),避免創(chuàng)建和使用諸如信號(hào)量或標(biāo)志等內(nèi)核對(duì)象作為向其他任務(wù)發(fā)送信號(hào)的中介,該特性有效地提高了直接向任務(wù)發(fā)送消息:UCOSIII允許中斷或任務(wù)直接給另一個(gè)任務(wù)發(fā)送消息,避免創(chuàng)建和是不同的,主要用來(lái)保存各個(gè)任務(wù)的錯(cuò)誤信息,ID識(shí)別信息,中斷關(guān)閉時(shí)間的測(cè)量結(jié)果等。任務(wù)級(jí)時(shí)鐘節(jié)拍處理:UCOSIII的時(shí)鐘節(jié)拍是通過(guò)一個(gè)專門(mén)任務(wù)完成的,定時(shí)中斷僅觸發(fā)防止死鎖:所有UCOSIII的“等待”功能都提供了超時(shí)檢測(cè)機(jī)制,有效地避免了死鎖。量,在系統(tǒng)運(yùn)行時(shí),可以通過(guò)該計(jì)數(shù)器來(lái)測(cè)量某一個(gè)的時(shí)間信息。例如,當(dāng)ISR給任務(wù)發(fā)送消息時(shí),會(huì)自動(dòng)該計(jì)數(shù)器的數(shù)值并將其附加在消息中。當(dāng)任務(wù)消息時(shí),可得到該消息攜帶的時(shí)標(biāo),這樣,再通過(guò)當(dāng)前的時(shí)標(biāo),并計(jì)算兩個(gè)時(shí)標(biāo)的差值,就可以確定傳遞√√√可型任務(wù)調(diào)√√√11××√√√√×√×√√√√√√√固定大小的管×√√××√無(wú)無(wú)××√×√√×√√√√√√√代碼可√√√××√√√√×√√×√√×√√××√√××√×√√××√××√××√4.1.1UCOSUCOSIII碼,一個(gè)是Micrium在STM32F4xx上移植好的工程文件。UCOSIII源碼地址 路徑:6、軟件資料->UCOS學(xué)習(xí)資料->UCOSIII3.03。圖4.2.1UCOSIII源碼界我們打開(kāi)好的UCOSIII3.03版本的源碼如圖4.2.2所示我們可以看到有5個(gè)文件,SourceUCOSIII3.03的源碼。4.2.2UCOSIII3.03,接著我們Micrium在STM32F4xx上移植好的UCOSIII工程,址: orted=true界面如圖4.2.3所示,我們已經(jīng)好放到光盤(pán)中,路徑:6、軟件資料->UCOS學(xué)習(xí)資料->UCOSIII3.04。,
圖4.2.3Micrium移植工1、從圖4.2.2可以看出Micrium是在STM32F429上移植的,并且UCOSIII的版本3.04。從第一章UCOSII的移植中我們可以看出有一些中間文件需要我們來(lái)實(shí)現(xiàn)。UCOSIIIMicriumSTM32F4UCOSIII,那么為了方便,這些MicriumSTM32F407上!2我們?cè)谝浦驳倪^(guò)程中會(huì)將Micrium使用的3.04版本的UCOSIII用3.03版本替換掉。3.04UCOSIIIOSStatTaskCPUUsageInit()MDK5.11AKEIL問(wèn)題還是UCOSIII3.04版本UCOSIII3.033.03UCOSIII的另一個(gè)主要原因。如果一定要使用UCOSIII3.04KEIL時(shí)一定要選擇-O1或者-O2優(yōu)化。我們打開(kāi)Micrium移植好的工程,也就是我們下來(lái)的UCOSIII3.04源碼,打開(kāi)后4.2.4所示。圖4.2.4Micrium移植工4.2.4中有四個(gè)文件夾:EvalBoards、uC-CPU、uC-LIBuCOS-III,這四個(gè)文件的內(nèi)1、EvalBoards4.2.5所示。4.2.5EvalBoards4.2.58個(gè)文2、uC-CPU該文件包含了適用于所有CPU架構(gòu)的C代碼。該文件包含了用來(lái)測(cè)量中斷關(guān)閉的函數(shù)(CPU_CRITICAL_ENTER()CPU_CRITICAL_EXIT()兩個(gè)宏實(shí)現(xiàn)),cpu_core.hcpu_def.hcpu.hUCOSIIICPU架構(gòu)和編譯器字寬度無(wú)關(guān)。在該文件中用戶能夠找到CPU_INT16U、CPU_INT32U、CPU_FP32等數(shù)據(jù)類(lèi)型的定義。該文件CPU使用的是大端模式還是小端模式,定義了UCOSIIICPU_STK數(shù)據(jù)類(lèi)型,CPU_CRITICAL_ENTER()CPU_CRITICAL_EXTI()CPU架構(gòu)相關(guān)的函數(shù)的。cpu_a.asm支持這條指令)CPU相關(guān)的函數(shù),這個(gè)文件中的函數(shù)C代碼中調(diào)用。cpu_c.cCPUCC代碼,作為一個(gè)普通原則,除非匯編語(yǔ)言能顯著提高性能,否則盡量用C語(yǔ)言編寫(xiě)函數(shù)。注意,上面的cpu.h、cpu_a.asm和cpu_c.c這三個(gè)文件,是在uC-CPU文件夾中4.2.6ARM-Cortex-M4cpu_a.asmcpu_c.cKEILUCOSIII的時(shí)候選擇3、uC-LIBUCOSUCOSIIIuC-CPUlib_def.h是存在的,uC-LIB包含以下幾個(gè)文件:lib_ascii.hlib_ascii.ctolower()、toupper()、isalpha()isdigit()等。lib_def.h但是,該文件中所有#define常量都以DEF_打頭,所以上述常量的名字實(shí)際上為DEF_TRUE/DEF_FALSE、DEF_YES/DEF_NO、DEF_ENABLE/DEF_DISABLE等。該文件還lib_math.hlib_math.c包含了Math_Rand()、Math_SetRand()等函數(shù)的源代碼,可用來(lái)替代標(biāo)準(zhǔn)庫(kù)函數(shù)rand()、lib_mem.clib_mem.hmemclr()、memset()、memcpy()memcmp()等。包含了Str_Lenr()Str_Copy()Str_Cmp()srtlen()、strcpy()strcmp()等。4、uCOS-IIIPortsSourec,PortsCPU平臺(tái)有關(guān)的文件,Source文件夾里面為UCOSIII3.04Source4.2.7所示。4.2.7UCOSIII3.04UCOSIII3.04和UCOSIII3.03源碼的文件都是一樣的,不同的是各個(gè)文件里面的有些函數(shù)做了修改,UCOSIII4.2.1所示。根據(jù)os_cfg_app.h中的宏定義變量和數(shù)包含標(biāo)志的管理代碼包含UCOSIII數(shù)據(jù)類(lèi)型的4.2.1UCOSIIIUCOSIII 中新建一個(gè)UCOSIII文件夾,然后將我們的Micrium移植工程中uC-CPU、uC-LIB和UCOS-III這三個(gè)文件到工程中,如圖4.3.1所示4.3.1UCOSIII我們還需要在UCOIII文件中再新建兩個(gè)文件:UCOS_BSP和UCOS_CONFIG4.3.2UCOS_BSPUCOS_CONFIGMicrium移植好的工程中的相關(guān)文件到UCOS_CONFIG文件夾下這些文件如圖4.3.3所示,這些文件在Micrium移植工程中的路徑為4.3.3UCOS_CONFIG同樣Micrium移植好的工程中的相關(guān)文件到UCOS_BSP文件下需要的文件如圖4.3.4所示,這些文件在Micrium移植工程中的路徑為:4.3.4UCOS_BSPKEIL4.3.54.3.54.3.6所示4.3.6KEIL4.3.74.3.8bsp.c文件中4.3.8bsp.cbsp.hbsp.c文件,里面有很多的代碼我們只需要其中的很少一部分關(guān)于DWT的代碼,因此我們要做相應(yīng)的修改,在修改之前我們稍微講解一下Cortex-M3/M4的組件。要將DEMCRTRCENA位(bit24)1,DEMCR寄存器地址為:0XE000EDFC,在我們的光盤(pán)中STM32參考資料下《Cortex-M3與M4指南(英文名《TheDefinitiveGuidetoARMCortex-M3andCortex-M4Processors,3rdEdition》)的501頁(yè)有詳細(xì)的講解,感的朋DWT組件中有一個(gè)T寄存器,這個(gè)寄存器用來(lái)對(duì)時(shí)鐘周期計(jì)DWT組件有多個(gè)寄存器,我們這里只使用DWT的控制寄存器 T寄存器,CTRL寄存器地址為 T寄存器地址為0XE 計(jì)數(shù)功能需要將CTRL寄存器的bit0置1。 (*(CPU_REG32*)0xE000EDFC)//DEMCR (*(CPU_REG32 T*(CPU_REG32 //DWT時(shí)鐘計(jì)數(shù)寄存器 (*(CPU_REG32 //DEMCR24位,DWTETMITMTPIU的話DEMCR //DWTCR寄存器的第0位,當(dāng)為1的時(shí)候使 T計(jì)數(shù)器使 T之前應(yīng)當(dāng)先初 //返回值:系統(tǒng)時(shí)鐘HCLK BSP_CPU_ClkFreq(void){ return //HCLK}//此函數(shù)用來(lái)開(kāi)啟和初始化CPU的時(shí)間戳定時(shí)器,其實(shí)就是使能DWT和 T為0。#if(CPU_CFG_TS_TMR_EN== { fclk_freq=BSP_CPU_ClkFreq(); =(;// = 初始 T寄存BSP_REG_DWT_CR|= 開(kāi) } T中的#if(CPU_CFG_TS_TMR_EN== CPU_TS_TmrRd{ts=return}#if(CPU_CFG_TS_32_EN== CPU_TS32_to_uSec { fclk_freq=BSP_CPU_ClkFreq(); ts/(fclk_freq/DEF_TIME_NBR_uS_PER_SEC);return(ts_us);}#if(CPU_CFG_TS_64_EN==DEF_ENABLED) CPU_TS64_to_uSec(CPU_TS64{ fclk_freq=BSP_CPU_ClkFreq(); ts/(fclk_freq/DEF_TIME_NBR_uS_PER_SEC);return(ts_us);} os_cpu_a.asmos_cpu_a.asmUCOSIIos_cpu_a.asm文件基本一致,大家根據(jù)1-1UCOSII移植”os_cpu_a.asmos_cpu_a.asm文件,修改完os_cpu_a.asm文件后我們編譯一下工程提示如圖4.3.9所示錯(cuò)誤,提示我們?cè)趏s_cpu_c.c文件修改的時(shí)候講到。4.3.8os_cpu_c.c4.3.9includes.hos_cpu_a.asmos_cpu_c.c文件來(lái)消除這兩個(gè)錯(cuò)誤。我們找到在os_cpu_c.cOSTaskSwHook()函數(shù)使用到這兩個(gè)FPUFPU寄存器的入棧和出棧有相應(yīng)的處理,這里不使用這兩個(gè)函數(shù),因此把OSTaskSwHook函數(shù)中關(guān)于4.3.10 { p_stk=p_stk { p_stk=p_stkCPU_STK*)((CPU_STK)(p_stk)& //8#if(FPU_PRESENT==1)&&(*(--p_stk)= *(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)=(CPU_STK)0x u;//s0*(--p_stk)= *(--p_stk)=//Entry*(--p_stk)=//R14*(--p_stk)= //*(--p_stk)= //*(--p_stk)= //*(--p_stk)=//*(--p_stk)=#if(FPU_PRESENT==1)&&(*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)= u;*(--p_stk)=(CPU_STK)0x u;//s16*(--p_stk)=*(--p_stk)=*(--p_stk)=*(--p_stk)=//*(--p_stk)=*(--p_stk)=*(--p_stk)=//*(--p_stk)=return}4.3.5os_cfg_app.h文件,os_cfg_app.hUCOSIII內(nèi)部一些系統(tǒng)任務(wù)的配置,如任務(wù)優(yōu)先級(jí)、任務(wù)堆棧、UCOSIII的系統(tǒng)時(shí)鐘節(jié)拍等等,os_cfg_app.h文件都是一些#ifndefOS_CFG_APP_H#define //任務(wù)堆棧深度,比如當(dāng)定義為10時(shí)表示當(dāng)任務(wù)堆棧剩余百分之10%時(shí)就說(shuō)明堆棧為空 OS_CFG_INT_Q_TASK_STK_SIZE ////(1/OS_CFG_STAT_TASK_RATE_HZ)秒的時(shí)間內(nèi)OSStatTaskCtr能夠達(dá)到的最大值來(lái)得到 理任務(wù)的優(yōu)先級(jí)應(yīng)該為最高0。其他3個(gè)任務(wù)的優(yōu)先級(jí)用戶可以自行設(shè)置,本手冊(cè)中統(tǒng)OS_CFG_PRIO_MAX-2和OS_CFG_PRIO_MAX-15個(gè)優(yōu)先級(jí)用戶應(yīng)用程序是不能使用的!4.3.6SYSTEMsys.h,#define1首先我們要修改sys.h,#define1統(tǒng)的,但是UCOSIII中有好多宏定義和UCOSII不同,因此這里要做相應(yīng)的修改使其支持UCOSIII操作系統(tǒng)。//CPU_CFG_CRITICAL_METHOD//CPU_CFG_CRITICAL_METHODUCOSIII#ifdefCPU_CFG_CRITICAL_METHOD#define#defineOS_TICKS_PER_SEC #defineOS_TRUE #define UCOSIIIOS_CRITICAL_METHOD、OS_TICKS_PER_SEC、OSLockNesting4delay.c4UCOSIII4CPU_CFG_CRITICAL_METHOD被定義就說(shuō)明使用UCOSIII。//nus:us數(shù).voiddelay_us(u32nus)//nus:us數(shù).voiddelay_us(u32nus){#ifdefCPU_CFG_CRITICAL_METHOD OS_ERRerr;u32 u32reload=SysTick->LOAD; //LOAD的值 #ifdefCPU_CFG_CRITICAL_METHOD ucosus {{//SYSTICK是一個(gè)遞減的計(jì)數(shù)器就可以了.elsetcnt+=reload-tnow+told; }#ifdefCPU_CFG_CRITICAL_METHOD //使用UCOSIII //開(kāi)啟ucos調(diào)度 //ucos}voiddelay_ms(u16{#ifdefCPU_CFG_CRITICAL_METHOD OS_ERRerr;{{#ifdef //UCOSIII } } }我們需要使用到調(diào)度器加鎖和函數(shù),UCOSIII和UCOSII中調(diào)度器加鎖和函數(shù)有點(diǎn)不同,UCOSIIIUCOSII是不delay_ms()UCOSUCOSII中我們調(diào)#include"sys.h"#include"delay.h"#include"usart.h"#include"led.h"#include"includes.h"#define#include"sys.h"#include"delay.h"#include"usart.h"#include"led.h"#include"includes.h"#define#defineOS_TCB3CPU_STKvoidstart_task(void#define #define OS_TCBCPU_STKvoidled0_task(void#define #define OS_TCBCPU_STKvoidled1_task(void#define #define OS_TCBalign(8) voidfloat_task(voidint{OS_ERRerr; //LED初始化 //UCOSIII )"starttask", (OS_TASK_PTR)start_task, (CPU_STK_SIZE)START_STK_SIZE/10, (CPU_STK_SIZE)START_STK_SIZE, (OS_MSG_QTY) ////的最大消息數(shù)目,0 // }voidstart_task(void{OS_ERRerr;p_arg= #ifdefCPU_CFG_INT_DIS_MEAS_EN #if OS_CRITICAL_ENTER();////LED0 )"led0task",(OS_TASK_PTR)led0_task, (CPU_STK_SIZE)LED0_STK_SIZE/10,(CPU_STK_SIZE)LED0_STK_SIZE,(OS_MSG_QTY)0, //LED1 )"led1task",(OS_TASK_PTR)led1_task, (CPU_STK_SIZE)LED1_STK_SIZE/10,(CPU_STK_SIZE)LED1_STK_SIZE,(OS_MSG_QTY)0, )"floattesttask",(OS_TASK_PTR)float_task, (CPU_STK_SIZE)FLOAT_STK_SIZE/10,(CPU_STK_SIZE)FLOAT_STK_SIZE,(OS_MSG_QTY)0, }//led0voidled0_task(void{OS_ERRerr;p_arg=p_arg;{;//}}//led1voidled1_task(void{OS_ERRerr;p_arg=p_arg;{;//}}voidfloat_task(void{staticfloatfloat_num=0.01;{OS_CRITICAL_ENTER();//進(jìn)入臨界區(qū)printf("float_num的值為.4f\r\n",float_num); }}4.5驗(yàn)代碼編譯完成后我們就可以到STM32F407開(kāi)發(fā)板中,進(jìn)去以后我們可以看到4.5.14.5.1中可以看出串口調(diào)試助手接收到數(shù)據(jù),float_num0.01。這UCOSIIIUCOSIII5.3最先肯定是要調(diào)用CPU_Init()UCOSIII創(chuàng)建任務(wù),一般我們?cè)趍ain()函數(shù)中只創(chuàng)建一個(gè)start_task任務(wù),其他任務(wù)都在start_task任務(wù)中創(chuàng)建,在調(diào)用OSTaskCreate()函數(shù)創(chuàng)建任務(wù)的時(shí)候一定要調(diào)用OS_CRITICAL_ENTER()OS_CRITICAL_EXIT()函數(shù)退int{OS_ERRerr; int{OS_ERRerr; //LED OS_CRITICAL_ENTER();//進(jìn)入臨界區(qū))"start(OS_TASK_PTR址(CPU_STK_SIZE)START_STK_SIZE,(OS_MSG_QTY////的最大消息數(shù)目,0//區(qū) }UCOSIIIUCOSIIIstart_task()OSStart()UCOSIII。用權(quán)進(jìn)入運(yùn)行態(tài),其他的任務(wù)就會(huì)進(jìn)入其他狀態(tài),UCOSIII5.2.1未用OSTaskCreate()UCOSIII任務(wù)在就緒表中已經(jīng)登記,等待獲取CPU正在運(yùn)行的任務(wù)需要等待某一個(gè),比如信號(hào)量、消息、標(biāo)志組等就會(huì)暫時(shí)讓出CPU使用權(quán),進(jìn)入等待狀態(tài)UCOSIII55.2.15.2.1UCOSIIIstructos_tcb*StkLimitPtr;//structos_tcb*StkLimitPtr;////NexPtr和PrevPtr;//*TickPrevPtr;//的任務(wù)的OS_TCB;////spoke *StkBasePtr;//任務(wù)堆棧 //options PendDataTblEntries;//任務(wù)同時(shí)等待的 TS; TickCtrPrev; // OSTickCtr之前的數(shù)值 MsgQPendTimeMax;//記錄一條消息到達(dá)所花費(fèi)的最長(zhǎng)時(shí)間 //CPU//CPU//CPUUCOSIII中任務(wù)堆棧是一個(gè)非常重要的概念,任務(wù)堆棧用來(lái)在切換任務(wù)和調(diào)用其它函數(shù)1、定義一個(gè)CPU_STK變量,在UCOSIII中用CPU_STK數(shù)據(jù)類(lèi)型來(lái)定義任務(wù)堆棧,CPU_STKcpu.h中有定義,其實(shí)CPU_STK就是CPU_INT32UCPU_STK變TASK_STK64*4=256字節(jié)。 TASK_STK[LED1_STK_SIZE];//)"start)"start,//址)TASK_STK_SIZE/10,//區(qū)CPU的寄存器保存在任務(wù)堆棧中,OSTaskStkInit()UCOSIII的時(shí)OSTaskCreate()函數(shù)在創(chuàng)建任務(wù)數(shù)目由宏OS_CFG_PRIO_MAX配置的(os_cfg.h)。5.5.15.5.1OSPrioTbl[]數(shù)組的元素最低位在右,最 { prio; =p_tbl OS_Pri { prio; =p_tbl //當(dāng)數(shù)組OSPrioTbl中的某個(gè)元素為0prio//CPU_DATA32位,那么DEF_INT_CPU_NBR_BITS32,prio32。prio+=DEF_INT_CPU_NBR_BITS;++;//}prio+=(OS_PRIO) return} R0,R0,;和 OS_PrioInsert { =prio/=<<=(DEF_INT_CPU_NBR_BITS-1u)-OSPrioTbl[ix]|=} { =prio/=<<=(DEF_INT_CPU_NBR_BITS-1u)-1OSPrioTbl[ix]OSPrioTbl[ix]&=}上一小節(jié)詳細(xì)的講解了優(yōu)先級(jí)位映射表OSPrioTbl[],這個(gè)表主要是用來(lái)標(biāo)記哪些任務(wù)就緒OSRdyList[]是用來(lái)記錄每一個(gè)優(yōu)先級(jí)下所有就緒的任務(wù),OSRdyList[]os.hOS_RDY_LIST,OS_RDY_LIST為一個(gè)結(jié)構(gòu) os_rdy_listUCOSIII支持時(shí)間片輪轉(zhuǎn)調(diào)度,因此在一個(gè)優(yōu)先級(jí)下會(huì)有多個(gè)任務(wù),那么我們就要對(duì)這些任務(wù)做一個(gè)管理,這里使用OSRdyList[]數(shù)組管理這些任務(wù)。OSRdyList[]數(shù)組中的每個(gè)元素對(duì)應(yīng)一個(gè)優(yōu)先級(jí),比如OSRdyList[0]就用來(lái)管理優(yōu)先級(jí)0下的所有任務(wù)。OSRdyList[0]為指向OS_TCBOS_TCB是可以用來(lái)構(gòu)造鏈表的,因此同一個(gè)優(yōu)先級(jí)下的所有任務(wù)是5.5.243個(gè)任務(wù)時(shí)候的就緒任務(wù)列表。5.5.24HeadPtr指向鏈表頭,TailPtr指向鏈表尾,NbrEntries33個(gè)任務(wù)。注意有些優(yōu)任務(wù)OS_TickTask()、統(tǒng)計(jì)任務(wù)OS_StatTask、定時(shí)任務(wù)OS_TmrTask()和中斷服務(wù)管理任務(wù)65.5.1os_core.c這個(gè)文件中,這幾個(gè)函數(shù)是UCOSIII的,用戶程序不能使用。將任務(wù)控制塊TCB將一個(gè)任務(wù)控制塊TCB5.5.1可型調(diào) OSSched{OSSched()為任務(wù)級(jí)調(diào)度器,如果是在中斷服務(wù)函數(shù)中不能使用! OSSched{OSSched()為任務(wù)級(jí)調(diào)度器,如果是在中斷服務(wù)函數(shù)中不能使用!if(OSIntNestingCtr>(OS_NESTING_CTR)0){}if(OSSchedLockNestingCtr>(OS_NESTING_CTR)0){} =OS_PrioGetHighest();OSTCBHighRdyPtr=OSRdyList[OSPrioHighRdy].HeadPtr;if(OSTCBHighRdyPtr==OSTCBCurPtr){}#ifdefined(OS_CFG_TLS_TBL_SIZE)&&(OS_CFG_TLS_TBL_SIZE>0u) }獲取任務(wù)就緒表中就緒了的最高優(yōu)先級(jí)任務(wù),OSPrioHighRdy用來(lái)保存當(dāng)前就緒表中UCOSIII的一個(gè)優(yōu)先級(jí)下可以有是就緒任務(wù)列表中的第一個(gè)任務(wù),OSTCBHighRdyPtr指向?qū)⒁袚Q任務(wù)的OS_TCB。判斷要運(yùn)行的任務(wù)是否是正在運(yùn)行的任務(wù),如果是的話就不需要做任務(wù)切換,OSSched中真正執(zhí)行任務(wù)切換的是宏OS_TASK_SW()在os_cpu.h中定義),宏OS_TASK_SW()OSCtxSW(),OSCtxSW()os_cpu_a.asm中用匯編寫(xiě)的一段代碼,OS_TCBCPU的堆棧指CPU寄存器的值。 OSIntExit{ OSIntExit{if(OSRunning!=OS_STATE_OS_RUNNING){}if(OSIntNestingCtr==(OS_NESTING_CTR)0){}}if(OSIntNestingCtr>(OS_NESTING_CTR)0){}if(OSSchedLockNestingCtr>(OS_NESTING_CTR)0){} =OSTCBHighRdyPtr=OSRdyList[OSPrioHighRdy].HeadPtr;if(OSTCBHighRdyPtr==OSTCBCurPtr){}#ifdefined(OS_CFG_TLS_TBL_SIZE)&&(OS_CFG_TLS_TBL_SIZE>0u) }判斷UCOSIIIUCOSIIIOSIntNestingCtrOSIntEnter()函數(shù),在這個(gè)函數(shù)中會(huì)將OSIntNestingCtr1OSIntNestingCtr0OSIntExit()后不會(huì)等于負(fù)數(shù)。1。OSIntNestingCtr0,說(shuō)明還有其他的中斷發(fā)生,那么就跳回到中斷服務(wù)程5OSSechd()OSRdyList[]中取出最高優(yōu)OS_TCB。在中斷級(jí)調(diào)度器中真正完成任務(wù)切換的就是中斷級(jí)任務(wù)切換函數(shù)OSIntCtxSW(),與任務(wù)級(jí)OSCtxSW()OSIntCtxSW()CPU寄存器的值。UCOSIII中允許一個(gè)任務(wù)運(yùn)行一段時(shí)間(時(shí)間片)后5.6.1N3個(gè)就緒的任務(wù),我4個(gè)時(shí)鐘節(jié)拍。5.6.13UCOSIII11N33OSSchedRoundRobinYield()(os_core.c文件中定義)函數(shù)放棄剩余的時(shí)間X下的下一個(gè)就緒的任務(wù)運(yùn)行。1 {如果當(dāng)前任務(wù)的時(shí)間片已經(jīng)運(yùn)行完,但是同一優(yōu)先級(jí)下有多個(gè)任務(wù),那么UCOSIII就會(huì)切換到該優(yōu)先級(jí)對(duì)應(yīng)的下一個(gè)任務(wù),通過(guò)調(diào)用 { if(OSSchedRoundRobinEn!=DEF_TRUE){ }p_tcb=p_rdy_list- if(p_tcb==(OS_TCB*)0) }if(p_tcb==&OSIdleTaskTCB) }if(p_tcb->TimeQuantaCtr>(OS_TICK)0){ }if(p_tcb->TimeQuantaCtr>(OS_TICK)0){ }if(p_rdy_list->NbrEntries<(OS_OBJ_QTY)2){ }if(OSSchedLockNestingCtr>(OS_NESTING_CTR)0){ } p_tcb=p_rdy_list- if(p_tcb->TimeQuanta==(OS_TICK)0){ p_tcb->TimeQuantaCtr=OSSchedRoundRobinDfltTimeQuanta;}else }}}首先檢查時(shí)間片輪轉(zhuǎn)調(diào)度是否允許。要允許時(shí)間片輪轉(zhuǎn)調(diào)度的話需要使用()如果p_tcb0如果p_tcbTCBOS_TCBTimeQuantaCtr字段表示當(dāng)前任務(wù)的時(shí)間片還剩多少,在這TimeQuantaCtr1。在經(jīng)過(guò)(5)TimeQuantaCtr1TimeQuantaCtr0,如果大0說(shuō)明任務(wù)的時(shí)間片還沒(méi)用完,那么就不能進(jìn)行任務(wù)切換,直接返回。前面就緒任務(wù)列表中的NbrEntries字段表示某一優(yōu)先級(jí)下的任務(wù)數(shù)量,這里判OS_TCB從雙
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 農(nóng)村材料合同范本
- 動(dòng)產(chǎn)汽車(chē)互易合同范本
- 企業(yè)投資期權(quán)合同范本
- 2024年徐州市凱信電子設(shè)備有限公司招聘考試真題
- 勞動(dòng)關(guān)系合同范本
- 2024年西安醫(yī)學(xué)院第一附屬醫(yī)院灃東醫(yī)院招聘筆試真題
- 2024年臺(tái)州仙居縣人民醫(yī)院醫(yī)共體招聘工作人員筆試真題
- 2024鞍鋼資本金融管理業(yè)務(wù)人才招聘4人筆試參考題庫(kù)附帶答案詳解
- 第16課《誡子書(shū)》教學(xué)設(shè)計(jì) 2024-2025學(xué)年統(tǒng)編版語(yǔ)文七年級(jí)上冊(cè)
- 出售環(huán)衛(wèi)用車(chē)合同范本
- GB/T 44561-2024石油天然氣工業(yè)常規(guī)陸上接收站液化天然氣裝卸臂的設(shè)計(jì)與測(cè)試
- 員工履歷表(標(biāo)準(zhǔn)樣本)
- 薪酬管理制度、員工薪資結(jié)構(gòu)規(guī)定、薪酬福利管理制度
- 2024-2030年中國(guó)實(shí)驗(yàn)室自動(dòng)行業(yè)市場(chǎng)發(fā)展分析及投資發(fā)展戰(zhàn)略研究報(bào)告
- 睪丸扭轉(zhuǎn)的護(hù)理課件
- 小兒(兒童)常見(jiàn)皮疹理論考核試題
- 北京市《配電室安全管理規(guī)范》(DB11T 527-2021)地方標(biāo)準(zhǔn)
- 北師大版(三起)(2024)三年級(jí)上冊(cè)英語(yǔ)Unit 1 Family單元測(cè)試卷(含答案)
- 2024中考語(yǔ)文《儒林外史》歷年真題專練(學(xué)生版+解析版)
- 人教版數(shù)學(xué)八年級(jí)下冊(cè)19.1.2《函數(shù)》說(shuō)課稿
- 《高速鐵路行車(chē)組織》課程標(biāo)準(zhǔn)(高職)
評(píng)論
0/150
提交評(píng)論