版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第九章
μc/OS-Ⅱ高級(jí)系統(tǒng)組件 9.1 μC/OS-Ⅱ事件標(biāo)志組 9.2 μC/OS-Ⅱ軟定時(shí)器 9.3 μC/OS-Ⅱ動(dòng)態(tài)內(nèi)存管理 9.4 μC/OS-Ⅱ多事件請(qǐng)求管理
在項(xiàng)目ZLX15的基礎(chǔ)上,新建項(xiàng)目ZLX16,保存在目錄D:\ZLXLPC824\ZLX16中,此時(shí)的項(xiàng)目ZLX16與ZLX15相同,然后進(jìn)行如表9-1所示的修改。表9-1 項(xiàng)目ZLX16在ZLX15基礎(chǔ)上的改動(dòng) 項(xiàng)目ZLX16的工程管理器如圖9-1所示。 項(xiàng)目ZLX16運(yùn)行時(shí)串口調(diào)試助手將顯示如圖9-2所示的信息。圖9-1 項(xiàng)目ZLX16的工程管理器
圖9-2 串口調(diào)試助手顯示的ZLX16執(zhí)行信息 由圖9-2可知,項(xiàng)目ZLX16中有5個(gè)任務(wù),每秒的任務(wù)總切換次數(shù)為42次,CPU占用率為1%或4%,任務(wù)優(yōu)先級(jí)號(hào)為4的用戶任務(wù)Task01堆??臻e56字節(jié)。
注:本章后續(xù)章節(jié)中所有的項(xiàng)目均建立在項(xiàng)目ZLX16的基礎(chǔ)上。 在項(xiàng)目ZLX16的基礎(chǔ)上,新建項(xiàng)目ZLX17,保存在目錄D:\ZLXLPC824\ZLX17中,此時(shí)的項(xiàng)目ZLX17與ZLX16相同。項(xiàng)目ZLX17擬實(shí)現(xiàn)的功能為:用戶任務(wù)Task02每1秒釋放一次事件標(biāo)志組Flag01,事件標(biāo)志為0x2A5B;用戶任務(wù)Task03始終請(qǐng)求事件標(biāo)志組,請(qǐng)求的標(biāo)志為0x2A00;用戶任務(wù)Task04始終請(qǐng)求事件標(biāo)志組,請(qǐng)求的標(biāo)志為0x5B。這樣,用戶任務(wù)Task03和Task04與用戶任務(wù)Task02同步執(zhí)行,即通過(guò)事件標(biāo)志組Flag01,實(shí)現(xiàn)了兩個(gè)用戶任務(wù)同步一個(gè)用戶任務(wù)的情況。項(xiàng)目ZLX17相對(duì)ZLX16修改的部分如表9-2所示。表9-2 項(xiàng)目ZLX17在ZLX16基礎(chǔ)上的改動(dòng)部分9.1 μC/OS-Ⅱ事件標(biāo)志組9.1 μC/OS-Ⅱ事件標(biāo)志組
程序段9-1文件task02.c
1 //Filename:task02.c 2 3 #include"includes.h" 4 5 externOS_FLAG_GRP*FlagGrp01;
6
第5行聲明外部定義的事件標(biāo)志組FlagGrp01,定義在文件task01.c中。
7 voidTask02(void*data) 8 { 9 INT8Uerr;
10 data=data;
11 12 while(1) 13 { 14 OSFlagPost(FlagGrp01,0x2A5B,OS_FLAG_SET,&err); 15 OSTimeDlyHMSM(0,0,1,0);
16 } 17 }
用戶任務(wù)Task02每1秒執(zhí)行一次(第15行),向事件標(biāo)志組FlagGrp01中釋放事件標(biāo)志0x2A5B。9.1 μC/OS-Ⅱ事件標(biāo)志組
程序段9-2文件task02.h 1 //Filename:task02.h 2 3 #ifndef_TASK02_H 4 #define_TASK02_H 5 6 #defineTask02StkSize 50 7 #defineTask02ID 2 8 #defineTask02Prio (Task02ID+3) 9 10 voidTask02(void*);
11 12 #endif
文件task02.h中宏定義了用戶任務(wù)Task02的堆棧大小、任務(wù)ID號(hào)和任務(wù)優(yōu)先級(jí)號(hào)(第6~8行),第10行聲明了任務(wù)Task02的任務(wù)函數(shù)原型。9.1 μC/OS-Ⅱ事件標(biāo)志組
程序段9-3文件task03.c 1 //Filename:task03.c 2 3 #include"includes.h" 4 5 externOS_FLAG_GRP*FlagGrp01;
6 externconstInt08UDig16X8[];
7
第6行聲明外部定義的事件標(biāo)志組FlagGrp01。 8 voidTask03(void*data) 9 { 10 INT8Uerr;
11 INT8Ucount=0,sec10,sec01;
12 OS_FLAGSflag;
13
第11行定義變量count用于秒計(jì)數(shù)值,變量sec10和sec01分別保存秒計(jì)數(shù)值十位和個(gè)位上的數(shù)字。第12行定義事件標(biāo)志flag,保存從事件標(biāo)志組FlagGrp01中請(qǐng)求的事件標(biāo)志。
9.1 μC/OS-Ⅱ事件標(biāo)志組 14 data=data;
15 16 while(1) 17 { 18 flag=OSFlagPend(FlagGrp01,0x2A00,OS_FLAG_WAIT_SET_ALL+OS_FLAG_CONSUME,0,&err);
19 if(flag==0x2A00) 20 { 21 sec10=count/10;
22 sec01=count%10;
23 24 LCDSMDrawChar16X8(8,8,&Dig16X8[sec10*16],1);
25 LCDSMDrawChar16X8(8+8,8,&Dig16X8[sec01*16],1);
26 27 count++;
28 if(count>=60)
9.1 μC/OS-Ⅱ事件標(biāo)志組 29 count=0;
30 } 31 } 32 }
第18行調(diào)用系統(tǒng)函數(shù)OSFlagPend請(qǐng)求事件標(biāo)志組FlagGrp01中的事件標(biāo)志,請(qǐng)求的標(biāo)志樣式為0x2A00(即16位的標(biāo)志中第9、11和13位為1),請(qǐng)求成功后,將標(biāo)志清除。第19行表示如果請(qǐng)求到的標(biāo)志為0x2A00,則計(jì)算秒計(jì)數(shù)值變量count的十位和個(gè)位上的數(shù)字sec10和sec01(第21、22行),第24、25行輸出sec10和sec01的值,第27~30行將秒計(jì)數(shù)值累加,如果秒計(jì)數(shù)值大于或等于60,則秒計(jì)數(shù)值清零。9.1 μC/OS-Ⅱ事件標(biāo)志組
程序段9-4文件task03.h 1 //Filename:task03.h 2 3 #ifndef_TASK03_H 4 #define_TASK03_H 5 6 #defineTask03StkSize 50 7 #defineTask03ID 3 8 #defineTask03Prio (Task03ID+3) 9 10 voidTask03(void*);
11 12 #endif
文件task03.h中宏定義了用戶任務(wù)Task03的堆棧大小、任務(wù)ID號(hào)和任務(wù)優(yōu)先級(jí)號(hào)(第6~8行),第10行聲明了任務(wù)Task03的任務(wù)函數(shù)原型。9.1 μC/OS-Ⅱ事件標(biāo)志組
程序段9-5文件task04.c 1 //Filename:task04.c 2 3 #include"includes.h" 4 5 externOS_FLAG_GRP*FlagGrp01;
6 externconstInt08UDig16X8[];
7
第5行聲明外部定義的事件標(biāo)志組FlagGrp01。 8 voidTask04(void*data) 9 { 10 INT8Uerr;
11 INT8Ucount=60,sec10,sec01;
12 OS_FLAGSflag;
13
第11行定義秒減計(jì)數(shù)變量count,初值為60,sec10和sec01分別用于保存秒計(jì)數(shù)變量的十位和個(gè)位上的數(shù)字。第12行定義事件標(biāo)志flag,用于保存從事件標(biāo)志組FlagGrp01中請(qǐng)求到的標(biāo)志。
9.1 μC/OS-Ⅱ事件標(biāo)志組 14 data=data;
15 16 while(1) 17 { 18 flag=OSFlagPend(FlagGrp01,0x005B,OS_FLAG_WAIT_SET_ALL+OS_FLAG_CONSUME,0,&err); 第18行調(diào)用系統(tǒng)函數(shù)OSFlagPend請(qǐng)求事件標(biāo)志組FlagGrp01中的事件標(biāo)志,請(qǐng)求的標(biāo)志樣式為0x5B(即16位的標(biāo)志中第0、1、3、4和6位為1),請(qǐng)求成功后,將標(biāo)志清除。 19 if(flag==0x005B) 20 { 21 sec10=count/10;
22 sec01=count%10;
23 24 LCDSMDrawChar16X8(8*4,8,&Dig16X8[sec10*16],1);
25 LCDSMDrawChar16X8(8*4+8,8,&Dig16X8[sec01*16],1);
26 27 count--;9.1 μC/OS-Ⅱ事件標(biāo)志組 28 if(count==0) 29 count=60;
30 } 31 } 32 } 第19行表示如果請(qǐng)求到的標(biāo)志為0x5B,則計(jì)算秒計(jì)數(shù)值變量count的十位和個(gè)位上的數(shù)字sec10和sec01(第21、22行),第24、25行輸出sec10和sec01的值,第27~30行將秒計(jì)數(shù)值自減,如果秒計(jì)數(shù)值等于0,則秒計(jì)數(shù)值賦為60。9.1 μC/OS-Ⅱ事件標(biāo)志組
程序段9-6文件task04.h 1 //Filename:task04.h 2 3 #ifndef_TASK04_H 4 #define_TASK04_H 5 6 #defineTask04StkSize 50 7 #defineTask04ID 4 8 #defineTask04Prio (Task04ID+3) 9 10 voidTask04(void*);
11 12 #endif
文件task04.h中宏定義了用戶任務(wù)Task04的堆棧大小、任務(wù)ID號(hào)和任務(wù)優(yōu)先級(jí)號(hào)(第6~8行),第10行聲明了任務(wù)Task04的任務(wù)函數(shù)原型。9.1 μC/OS-Ⅱ事件標(biāo)志組
結(jié)合程序段9-1至段9-6可知,用戶任務(wù)Task02、Task03和Task04的執(zhí)行流程如圖9-3所示。圖9-3 用戶任務(wù)Task02、Task03和Task04的執(zhí)行流程
9.1 μC/OS-Ⅱ事件標(biāo)志組
由圖9-3可知,通過(guò)事件標(biāo)志組可以使兩個(gè)任務(wù)Task03和Task04同步一個(gè)任務(wù)Task02的執(zhí)行,信號(hào)量一般僅能實(shí)現(xiàn)兩個(gè)任務(wù)間的同步,而事件標(biāo)志組可以實(shí)現(xiàn)多個(gè)任務(wù)同步一個(gè)任務(wù)的執(zhí)行。 將項(xiàng)目ZLX17下載到LPC824學(xué)習(xí)板上執(zhí)行時(shí),LPC824學(xué)習(xí)板的顯示情況如圖9-4所示。圖9-4 項(xiàng)目ZLX17在LPC824學(xué)習(xí)板上的執(zhí)行情況示意 圖9-4中顯示了兩個(gè)秒計(jì)數(shù)值,左邊的為加計(jì)數(shù)顯示,右邊的為減計(jì)數(shù)顯示,兩個(gè)計(jì)數(shù)值的和總為60。9.1 μC/OS-Ⅱ事件標(biāo)志組9.2.1 看門狗定時(shí)器 商業(yè)應(yīng)用場(chǎng)合下的電路系統(tǒng)都要求配備看門狗,看門狗時(shí)刻監(jiān)視著微控制器的運(yùn)行情況,微控制器程序正常運(yùn)行時(shí),看門狗不起作用,當(dāng)微控制器程序工作異常時(shí),看門狗將啟動(dòng)并復(fù)位微控制器??撮T狗的基本操作為: (1)初始化看門狗定時(shí)器; (2)在用戶程序中周期性地喂狗(俗稱“狗吃食”); (3)當(dāng)用戶程序異常時(shí),無(wú)法運(yùn)行喂狗程序,看門狗定時(shí)器等待一段時(shí)間后溢出,發(fā)出復(fù)位信號(hào)復(fù)位微控制器。 LPC824微控制器內(nèi)置了一個(gè)高性能的帶窗口功能的看門狗定時(shí)器,不但可以復(fù)位LPC824,還可以作為普通定時(shí)器使用,它的特點(diǎn)如下: (1)專用的看門狗振蕩器。 (2)當(dāng)看門狗定時(shí)器定時(shí)超時(shí)后,可復(fù)位LPC824。 (3)可產(chǎn)生普通的看門狗定時(shí)器中斷。 (4)可設(shè)定喂狗的窗口,如果設(shè)定了喂狗窗口,當(dāng)看門狗定時(shí)器的當(dāng)前定時(shí)值比窗口值大時(shí),喂狗將產(chǎn)生看門狗復(fù)位事件。這可有效地防止用戶程序異常但是喂狗程序(或函數(shù))工作正常的不良情況發(fā)生??撮T狗定時(shí)器的結(jié)構(gòu)如圖9-5所示。圖9-5請(qǐng)看下頁(yè)9.2 μC/OS-Ⅱ軟定時(shí)器圖9-5 看門狗定時(shí)器9.2 μC/OS-Ⅱ軟定時(shí)器 根據(jù)圖9-5可知,看門狗振蕩器為看門狗定時(shí)器提供時(shí)鐘源,假設(shè)看門狗振蕩器提供的時(shí)鐘信號(hào)頻率為10kHz,由于看門狗內(nèi)置了4分頻器,所以看門狗的24位減計(jì)數(shù)器的頻率為2.5kHz,即周期為0.4ms。如果WARNINT的值為100,TC的值設(shè)為2500+100-1(TC的最小值為0xFF,如果設(shè)定的值小于0xFF,則自動(dòng)將0xFF賦給TC),TC為看門狗計(jì)數(shù)值常數(shù)寄存器,TV為看門狗當(dāng)前計(jì)數(shù)值寄存器。當(dāng)喂狗成功后,TC的值被復(fù)制到TV中,則TV的值為2500+100-1,當(dāng)TV的值減到100時(shí),即減到與WARNINT(看門狗中斷比較值寄存器)的值相等時(shí),在下一個(gè)時(shí)鐘到來(lái)時(shí),將觸發(fā)看門狗中斷,這樣從喂狗完成到一次看門狗中斷的時(shí)間剛好為1秒。如果用戶程序異常,喂狗程序不工作,則TV的值按0.4ms的節(jié)拍很快減到0;當(dāng)TV的值減到0后,下一個(gè)看門狗時(shí)鐘到來(lái)時(shí),將產(chǎn)生看門狗復(fù)位事件。如果設(shè)定了喂狗窗口(WINDOW),當(dāng)TV的值比WINDOW的值大時(shí),喂狗也將導(dǎo)致產(chǎn)生看門狗復(fù)位事件。 看門狗定時(shí)器具有以下6個(gè)寄存器,如圖9-5和表9-3所示。表9-3請(qǐng)看下頁(yè)9.2 μC/OS-Ⅱ軟定時(shí)器表9-3 看門狗定時(shí)器的寄存器(基地址:0x40000000)
下面介紹表9-3中所列的各個(gè)寄存器的含義。
1)看門狗模式寄存器MOD
看門狗模式寄存器WDMOD各位的含義如表9-4所示。表9-4請(qǐng)看下頁(yè)9.2 μC/OS-Ⅱ軟定時(shí)器
表9-4 看門狗模式寄存器WDMOD各位含義
由表9-4可知,看門狗一旦啟動(dòng)后,無(wú)法借助軟件方式停止它。此外,看門狗有兩種工作模式:其一為WDEN位為1,WDRESET位為0,此時(shí)的工作模式稱為看門狗中斷模式;其二為WDEN位和WDRESET位均為1,此時(shí)的工作模式稱為看門狗復(fù)位模式。在看門狗中斷工作模式下,當(dāng)看門狗的TV值達(dá)到WARNINT寄存器的值時(shí),WDMOD寄存器的WDINT位被置1,向LPC824內(nèi)核發(fā)出看門狗中斷請(qǐng)求。在看門狗復(fù)位工作模式下,當(dāng)看門狗的TV值達(dá)到WARNINT寄存器的值時(shí),WDMOD寄存器的WDINT位被置1并產(chǎn)生看門狗中斷;當(dāng)TV的值減計(jì)數(shù)到0時(shí),將產(chǎn)生復(fù)位信號(hào);同時(shí),如果設(shè)定了喂狗窗口,在TV的值大于WINDOW寄存器的值時(shí)喂狗,也將產(chǎn)生復(fù)位信號(hào)。9.2 μC/OS-Ⅱ軟定時(shí)器
2)看門狗計(jì)數(shù)值重裝常數(shù)寄存器TC
寄存器TC只有第[23∶0]位域有效,用COUNT符號(hào)表示,其余位保留。COUNT的最小值為0xFF,當(dāng)設(shè)定TC的值小于0xFF時(shí),將把0xFF自動(dòng)裝入COUNT中。當(dāng)喂狗成功后,TC的值被復(fù)制到TV中,由于啟動(dòng)看門狗至少要喂狗一次,所以TV的值最小為0xFF。如果看門狗振蕩器的時(shí)鐘信號(hào)頻率為wdt_clk,則看門狗減計(jì)數(shù)到0的最短時(shí)間為256×4/wdt_clk;由于TC只有低24位的COUNT域有效,故看門狗溢出的最長(zhǎng)時(shí)間為224×4/wdt_clk。
3)看門狗喂狗寄存器FEED 32位的寄存器FEED只有第[7∶0]位有效,向其寫入0xAA,接著再寫入0x55,則執(zhí)行一次喂狗動(dòng)作,即將TC的值復(fù)制到TV中。
4)看門狗當(dāng)前計(jì)數(shù)值寄存器TV TV寄存器只有第[23∶0]位有效,保存了看門狗當(dāng)前的計(jì)數(shù)值,當(dāng)該計(jì)數(shù)值與WARNINT寄存器的值相同時(shí),下一個(gè)計(jì)數(shù)時(shí)鐘到來(lái)時(shí)產(chǎn)生中斷;當(dāng)該計(jì)數(shù)值減計(jì)數(shù)到0時(shí),下一個(gè)計(jì)數(shù)時(shí)鐘到來(lái)時(shí)產(chǎn)生復(fù)位信號(hào)。
5)看門狗警告中斷比較值寄存器
WARNINTWARNINT寄存器只有第[9∶0]位有效,當(dāng)TV的值減計(jì)數(shù)到與WARNINT的值相同時(shí),將產(chǎn)生看門狗中斷請(qǐng)求。
6)看門狗窗口值寄存器WINDOW WINDOW寄存器只有第[23∶0]位有效,復(fù)位值為0xFFFFFF,當(dāng)WDMOD寄存器的WDRESET位置為1時(shí),當(dāng)TV的值比WINDOW的值大時(shí)喂狗將產(chǎn)生復(fù)位信號(hào)。9.2 μC/OS-Ⅱ軟定時(shí)器9.2.2 μC/OS-Ⅱ軟定時(shí)器 μC/OS-Ⅱ系統(tǒng)的定時(shí)器任務(wù)屬于系統(tǒng)任務(wù),它的主要作用在于創(chuàng)建軟定時(shí)器。本書的項(xiàng)目中將定時(shí)器任務(wù)的優(yōu)先級(jí)號(hào)配置為24,即僅比統(tǒng)計(jì)任務(wù)和空閑任務(wù)的優(yōu)先級(jí)高。在第五章表52中,將第20號(hào)“OS_TMR_EN”設(shè)為1,打開定時(shí)器任務(wù),將第21號(hào)的“OS_TMR_CFG_MAX”設(shè)為6,即最多允許創(chuàng)建6個(gè)軟定時(shí)器,這是因?yàn)長(zhǎng)PC824片內(nèi)RAM空間只有8KB,過(guò)多的軟定時(shí)器將占用大量的RAM空間,導(dǎo)致LPC824的RAM空間不足。但是μC/OSⅡ定時(shí)器任務(wù)可管理的定時(shí)器數(shù)量?jī)H受定時(shí)器數(shù)據(jù)類型的限制,對(duì)于16位無(wú)符號(hào)整型數(shù)而言,可管理多達(dá)65536個(gè)定時(shí)器。 由于定時(shí)器任務(wù)為μC/OS-Ⅱ創(chuàng)建的系統(tǒng)任務(wù),程序員只需要為定時(shí)器任務(wù)指定優(yōu)先級(jí),不需要關(guān)心定時(shí)器任務(wù)的內(nèi)部實(shí)現(xiàn)機(jī)理,下面重點(diǎn)討論軟定時(shí)器的用法,即
(1)定義一個(gè)軟定時(shí)器,例如:“OS_TMR*Tmr01;”;然后定義該軟定時(shí)器的回調(diào)函數(shù),例如:“voidTmr01Func(void*ptmr,void*callback_arg);”,回調(diào)函數(shù)是指定時(shí)器定時(shí)完成后將自動(dòng)調(diào)用的函數(shù),一般地在該函數(shù)中釋放信號(hào)量或消息郵箱,激活某個(gè)用戶任務(wù)去執(zhí)行特定的功能。
(2)調(diào)用OSTmrCreate函數(shù)創(chuàng)建該定時(shí)器,例如: Tmr01=OSTmrCreate(10,10,OS_TMR_OPT_PERIODIC, Tmr01Func,(void*)0,“Timer01”,&err);9.2 μC/OS-Ⅱ軟定時(shí)器 OSTmrCreate函數(shù)有7個(gè)參數(shù),依次為:初次定時(shí)延時(shí)值、定時(shí)周期值、定時(shí)方式、回調(diào)函數(shù)、回調(diào)函數(shù)參數(shù)、定時(shí)器名稱和出錯(cuò)碼信息。初次定時(shí)延時(shí)值,表示第一次定時(shí)結(jié)束時(shí)要經(jīng)歷的時(shí)間;定時(shí)周期值表示周期性定時(shí)器的定時(shí)周期。這里都為10,由于定時(shí)器的頻率為10Hz,因此,“10”表示1秒。定時(shí)方式有兩種,即周期型定時(shí)OS_TMR_OPT_PERIODIC和單拍型定時(shí)OS_TMR_OPT_ONE_SHOT,后者定時(shí)器僅執(zhí)行一次,延時(shí)時(shí)間為其第一個(gè)參數(shù),此時(shí),第二個(gè)參數(shù)無(wú)效,所以,單拍型定時(shí)器的回調(diào)函數(shù)僅被執(zhí)行一次。
(3)軟定時(shí)器的動(dòng)作主要有:啟動(dòng)軟定時(shí)器,如“OSTmrStart(Tmr01,&err);”;停止軟定時(shí)器。停止軟定時(shí)器函數(shù)原型為: OSTmrStop(OS_TMR*ptmr,INT8Uopt,void*callback_arg,INT8U*perr);上述函數(shù)的四個(gè)參數(shù)依次為:定時(shí)器、定時(shí)器停止后是否調(diào)用回調(diào)函數(shù)的選項(xiàng)、傳遞給回調(diào)函數(shù)的參數(shù)和出錯(cuò)碼信息。當(dāng)opt為OS_TMR_OPT_NONE時(shí),不調(diào)用回調(diào)函數(shù);當(dāng)為OS_TMR_OPT_CALLBACK時(shí),定時(shí)器停止時(shí)調(diào)用回調(diào)函數(shù),使用原回調(diào)函數(shù)的參數(shù);當(dāng)為OS_TMR_OPT_CALLBACK_ARG時(shí),定時(shí)器停止時(shí)調(diào)用回調(diào)函數(shù),但使用OST-mrStop函數(shù)中指定的參數(shù)callback_arg。
9.2 μC/OS-Ⅱ軟定時(shí)器 (4)可獲得軟定時(shí)器的狀態(tài),例如, INT8UTmr01State;
Tmr01State=OSTmrStateGet(Tmr01,&err);上述代碼將返回定時(shí)器Tmr01當(dāng)前的工作狀態(tài),如果定時(shí)器沒(méi)有創(chuàng)建,則返回常量OS_TMR_STATE_UNUSED;如果定時(shí)器處于運(yùn)行態(tài),則返回常量OS_TMR_STATE_RUNNING;如果定時(shí)器處于停止?fàn)顟B(tài),則返回常量OS_TMR_STATE_STOPPED。
(5)當(dāng)定時(shí)到期時(shí),將自動(dòng)調(diào)用定時(shí)器的回調(diào)函數(shù)。一般地,不允許在回調(diào)函數(shù)中放置耗時(shí)較多的數(shù)據(jù)處理代碼,通?;卣{(diào)函數(shù)只有幾行代碼,用于釋放信號(hào)量或消息郵箱。9.2 μC/OS-Ⅱ軟定時(shí)器9.2.3 μC/OS-Ⅱ軟定時(shí)器實(shí)例 在項(xiàng)目ZLX16的基礎(chǔ)上新建項(xiàng)目ZLX18,保存在目錄D:\ZLXLPC824\ZLX18中,此時(shí)的項(xiàng)目ZLX18與ZLX16相同,然后,如表9-5所示對(duì)項(xiàng)目ZLX18進(jìn)行修改。表9-5 項(xiàng)目ZLX18在ZLX16基礎(chǔ)上的改動(dòng)9.2 μC/OS-Ⅱ軟定時(shí)器9.2 μC/OS-Ⅱ軟定時(shí)器
程序段9-7文件watchdog.c 1 //Filename:watchdog.c 2 3 #include"includes.h" 4 5 voidFeedDog(void) 6 { 7 LPC_WWDT->FEED=0xAA;
8 LPC_WWDT->FEED=0x55;
9 } 10
第5~9行為喂狗函數(shù)FeedDog,喂狗的方法為向FEED寄存器依次寫入0xAA和0x55(第7、8行)。
11 voidWDTIRQEnable(void) 12 { 13 NVIC_ClearPendingIRQ(WDT_IRQn);
14 NVIC_EnableIRQ(WDT_IRQn);
15 } 16
第11~15行的函數(shù)WDTIRQEnable為調(diào)用CMSIS庫(kù)函數(shù),清除看門狗定時(shí)器的NVIC中斷標(biāo)志,并打開看門狗定時(shí)器的NVIC中斷。9.2 μC/OS-Ⅱ軟定時(shí)器 17 voidWatchDogInit(void) 18 { 19 LPC_SYSCON->W(wǎng)DTOSCCTRL=(1uL<<5)|(29uL<<0); //WatchdogOSC: 20 //0.6MHz/60=10kHz 21 LPC_SYSCON->SYSAHBCLKCTRL|=(1uL<<17); //EnableClockforWWDT 22 LPC_SYSCON->PDRUNCFG&=~(1uL<<6); //PowerOnWatchdogOsc 23 24 LPC_WWDT->TC=5000+100-1; //10kHz/4=2500,2s 25 LPC_WWDT->W(wǎng)ARNINT=100;
26 LPC_WWDT->MOD=(1uL<<0)|(1uL<<1); //ResetMode 27 28 FeedDog();
29 WDTIRQEnable();
30 } 31
9.2 μC/OS-Ⅱ軟定時(shí)器第17~30行為看門狗初始化函數(shù)WatchDogInit。第19行配置看門狗振蕩器工作頻率為10kHz;第21~22行啟動(dòng)看門狗振蕩器;第24行設(shè)置TC=5000+100-1;第25行設(shè)置WARNINT=100;第26行配置MOD的第0位和第1位為1,即處于看門狗復(fù)位工作模式下;第28行調(diào)用FeedDog函數(shù)喂狗,因?yàn)閱?dòng)看門狗前必須喂狗一次,即第28行執(zhí)行完后,看門狗定時(shí)器才開始工作。第29行調(diào)用WDTIRQEnable打開看門狗中斷。由于看門狗定時(shí)器內(nèi)部具有4分頻器,其減計(jì)數(shù)頻率為2.5kHz,因此,當(dāng)看門狗的TV從5000+100-1減計(jì)數(shù)到WARNINT(值為100)時(shí),產(chǎn)生看門狗中斷,其周期正好為2秒。 32 voidWDT_IRQHandler(void) 33 { 34 OSIntEnter();
35 NVIC_ClearPendingIRQ(WDT_IRQn);
36 LPC_WWDT->MOD|=((1u<<3)|(1u<<2));
37 LPC_WWDT->MOD&=~((1u<<3)|(1u<<2));
38 39 //Todo
9.2 μC/OS-Ⅱ軟定時(shí)器 40 OSIntExit();
41 } 第32~40行的WDT_IRQHandler為看門狗中斷服務(wù)函數(shù),該函數(shù)名取自表4-1第12號(hào)中斷對(duì)應(yīng)的標(biāo)號(hào),當(dāng)看門狗產(chǎn)生中斷后,將自動(dòng)跳轉(zhuǎn)到該函數(shù)執(zhí)行。第35行為清除看門狗中斷請(qǐng)求標(biāo)志;第36~37行為清除看門狗MOD寄存器的第2~3位,即WDTOF和WDINT位清零;第39行可添加一些用戶代碼;第34行和第40行為μC/OS-Ⅱ的系統(tǒng)函數(shù),用于中斷切換時(shí)保護(hù)μC/OS-Ⅱ的程序工作環(huán)境。9.2 μC/OS-Ⅱ軟定時(shí)器
程序段9-8文件watchdog.h 1 //Filename:watchdog.h 2 3 #ifndef_WATCHDOG_H 4 #define_WATCHDOG_H 5 6 voidWatchDogInit(void);
7 voidFeedDog(void);
8 9 #endif
文件watchdog.h中聲明了函數(shù)WatchDogInit和FeedDog的原型,這兩個(gè)函數(shù)的函數(shù)體位于watchdog.c文件中,分別用于初始化看門狗定時(shí)器和喂狗。9.2 μC/OS-Ⅱ軟定時(shí)器
程序段9-9文件task02.c 1 //Filename:task02.c 2 3 #include"includes.h" 4 5 externOS_EVENT*Sem01;
6 externconstInt08UDig16X8[];
7
第5行聲明外部定義的信號(hào)量Sem01。
8 voidTask02(void*data) 9 { 10 INT8Uerr;
11 INT8Ui=0,k,dig10,dig01;
12
第11行定義計(jì)數(shù)變量i,變量k保存變量i的最低兩位數(shù)字,dig10和dig01變量分別用于保存k的十位和個(gè)位上的數(shù)字。
9.2 μC/OS-Ⅱ軟定時(shí)器 13 data=data;
14 15 while(1) 16 { 17 OSSemPend(Sem01,0,&err);
18 FeedDog();
19 20 k=(i++)%100;
21 dig10=k/10;
22 dig01=k%10;
23 LCDSMDrawChar16X8(8+8,8,&Dig16X8[dig10*16],1);
24 LCDSMDrawChar16X8(8*2+8,8,&Dig16X8[dig01*16],1);
25 } 26 }
在任務(wù)Task02中,請(qǐng)求信號(hào)量Sem01(第17行),如果請(qǐng)求成功,則進(jìn)行一次喂狗操作(第18行),然后第20~24行在LPC824片內(nèi)緩存SM中輸出變量k的計(jì)數(shù)值。9.2 μC/OS-Ⅱ軟定時(shí)器
程序段9-10文件task02.h 1 //Filename:task02.h 2 3 #ifndef_TASK02_H 4 #define_TASK02_H 5 6 #defineTask02StkSize 50 7 #defineTask02ID 2 8 #defineTask02Prio (Task02ID+3) 9 10 voidTask02(void*);
11 12 #endif
文件task02.h中宏定義了任務(wù)Task02的堆棧大小為50字、任務(wù)ID號(hào)為2、優(yōu)先級(jí)號(hào)為5。第8行聲明了任務(wù)函數(shù)Task02的原型。9.2 μC/OS-Ⅱ軟定時(shí)器
程序段9-11文件task03.c 1 //Filename:task03.c 2 3 #include"includes.h" 4 5 externOS_EVENT*Sem02;
6 externconstInt08UDig16X8[];
7
第5行聲明外部定義的信號(hào)量Sem02。 8 voidTask03(void*data) 9 { 10 INT8Uerr;
11 INT8Ui=0,k,dig10,dig01;
12 13 data=data;
14
9.2 μC/OS-Ⅱ軟定時(shí)器 15 while(1) 16 { 17 OSSemPend(Sem02,0,&err);
18 19 k=(i++)%100;
20 dig10=k/10;
21 dig01=k%10;
22 23 LCDSMDrawChar16X8(8*4+8,8,&Dig16X8[dig10*16],1);
24 LCDSMDrawChar16X8(8*5+8,8,&Dig16X8[dig01*16],1);
25 } 26 } 在任務(wù)Task03中,請(qǐng)求信號(hào)量Sem02(第17行),如果請(qǐng)求成功,則在LPC824內(nèi)部緩存SM的坐標(biāo)(40,8)位置處輸出變量k的值。9.2 μC/OS-Ⅱ軟定時(shí)器
程序段9-13文件uctmr.c 1 //Filename:uctmr.c 2 3 #include"includes.h" 4 5 OS_TMR*Tmr01;
6 OS_TMR*Tmr02;
7 externOS_EVENT*Sem01;
8 externOS_EVENT*Sem02;
9
第5、6行定義軟定時(shí)器Tmr01和Tmr02,第7、8行聲明外部定義的信號(hào)量Sem01和Sem02。 10 voidTmr01Func(void*ptmr,void*arg) 11 { 12 OSSemPost(Sem01);
13 } 14
第10~13行為定時(shí)器Tmr01的回調(diào)函數(shù)Tmr01Func,第12行釋放信號(hào)量Sem01。
9.2 μC/OS-Ⅱ軟定時(shí)器 15 voidTmr02Func(void*ptmr,void*arg) 16 { 17 OSSemPost(Sem02);
18 } 19
第15~18行為定時(shí)器Tmr02的回調(diào)函數(shù)Tmr02Func,第17行釋放信號(hào)量Sem02。
20 voiducTmrsCreate(void) 21 { 22 INT8Uerr;
23 Tmr01=OSTmrCreate(10,10,OS_TMR_OPT_PERIODIC,Tmr01Func,(void*)0,(INT8U*)"Tmr1",&err);
24 Tmr02=OSTmrCreate(10,10,OS_TMR_OPT_PERIODIC,Tmr02Func,(void*)0,(INT8U*)"Tmr2",&err);
25 OSTmrStart(Tmr01,&err);
26 OSTmrStart(Tmr02,&err);
27 }
第20~27行的函數(shù)ucTmrsCreate用于創(chuàng)建定時(shí)器Tmr01和Tmr02(第23、24行),兩個(gè)定時(shí)器均工作在周期定時(shí)模式下,定時(shí)周期為1s,即每1秒調(diào)用一次它們的回調(diào)函數(shù)。第25、26行啟動(dòng)定時(shí)器Tmr01和Tmr02。9.2 μC/OS-Ⅱ軟定時(shí)器
程序段9-14文件uctmr.h 1 //Filename:uctmr.h 2 3 #ifndef_UCTMR_H 4 #define_UCTMR_H 5 6 voiducTmrsCreate(void);
7 8 #endif
文件uctmr.h中聲明了函數(shù)ucTmrsCreate的原型,該函數(shù)位于uctmr.c文件中。9.2 μC/OS-Ⅱ軟定時(shí)器 結(jié)合表9-5和上述程序段9-7至程序段9-14可知,項(xiàng)目ZLX18的執(zhí)行情況如圖9-6所示。圖9-6 項(xiàng)目ZLX18的執(zhí)行情況9.2 μC/OS-Ⅱ軟定時(shí)器 由圖9-6可知,用戶任務(wù)Task01中創(chuàng)建軟定時(shí)器Tmr01和Tmr02,它們的定時(shí)周期均為1秒,Tmr01每定時(shí)1秒后釋放信號(hào)量Sem01,Tmr02每定時(shí)1秒后釋放信號(hào)量Sem02。用戶任務(wù)Task02請(qǐng)求信號(hào)量Sem01,請(qǐng)求成功后進(jìn)行一次喂狗操作,然后,將其局部變量k的值累加1,并在LPC824內(nèi)部緩存SM中輸出k的值。用戶任務(wù)Task03請(qǐng)求信號(hào)量Sem02,請(qǐng)求成功后將其局部變量k的值累加1,并在LPC824內(nèi)部緩存SM中輸出k的值。用戶任務(wù)Task20用于刷新LCD屏的顯示,刷新周期為0.2秒。 項(xiàng)目ZLX18中還打開了看門狗中斷(見程序段9-7),配置看門狗中斷的周期為2秒,由于用戶任務(wù)Task02每1秒喂狗一次,使得項(xiàng)目正常工作狀態(tài)下,看門狗定時(shí)器不可能減計(jì)數(shù)到WARNINT寄存器設(shè)定的值,即正常工作狀態(tài)下看門狗中斷不可能被觸發(fā)。因此,可在程序段97的第39行添加一些警告語(yǔ)句,例如,使LED燈點(diǎn)亮或者使蜂鳴器報(bào)警等,告訴用戶程序運(yùn)行已經(jīng)出錯(cuò),即將復(fù)位LPC824微控制器。9.2 μC/OS-Ⅱ軟定時(shí)器 μC/OS-Ⅱ動(dòng)態(tài)內(nèi)存管理是一種多用戶任務(wù)共享RAM空間的技術(shù),它在RAM內(nèi)存中開辟一塊存儲(chǔ)空間,稱為內(nèi)存分區(qū),內(nèi)存分區(qū)由許多大小相同的內(nèi)存塊組成。每個(gè)用戶任務(wù)中的局部變量均使用指針類型,當(dāng)使用某個(gè)局部變量時(shí),臨時(shí)從內(nèi)存分區(qū)中為它分配內(nèi)存塊,當(dāng)使用完該局部變量時(shí),把它占用的內(nèi)存塊回收到內(nèi)存分區(qū)中。 動(dòng)態(tài)內(nèi)存管理相關(guān)的常用函數(shù)主要有3個(gè),列于表9-6中。表9-6 常用的動(dòng)態(tài)內(nèi)存管理函數(shù)9.3 μC/OS-Ⅱ動(dòng)態(tài)內(nèi)存管理 使用內(nèi)存分區(qū)的步驟如下所示: (1)首先定義內(nèi)存分區(qū),即“OS_MEM*mem01”。
(2)為內(nèi)存分區(qū)開辟一塊存儲(chǔ)空間,即“INT32UmemBuf01[5][10]”。
(3)創(chuàng)建內(nèi)存分區(qū),即“mem01=OSMemCreate(&memBuf01[0][0],5,10*sizeof(INT32U),&err);”,表示創(chuàng)建的內(nèi)存分區(qū)mem01中包含了5個(gè)內(nèi)存塊,每個(gè)內(nèi)存塊的大小為10個(gè)字(即40字節(jié))。 (4)內(nèi)存分區(qū)主要用于存放用戶任務(wù)中的局部變量,例如,在一個(gè)任務(wù)中定義一個(gè)局部變量“INT8U*v;”,然后調(diào)用表9-6中的OSMemGet函數(shù)獲取一個(gè)內(nèi)存塊,即“v=OSMemGet(mem01,&err);”。 (5)當(dāng)這個(gè)用戶任務(wù)中不再使用局部變量v時(shí),將v指向的內(nèi)存塊空間歸還給內(nèi)存分區(qū),即“OSMemPut(mem01,(void*)v);”。先在項(xiàng)目ZLX18的基礎(chǔ)上,新建項(xiàng)目ZLX19,保存在目錄D:\ZLXLPC824\ZLX19-下,此時(shí)的項(xiàng)目ZLX19與ZLX18相同。然后,修改項(xiàng)目ZLX19如表9-7所示。表9-7 項(xiàng)目ZLX19在ZLX18基礎(chǔ)上的改動(dòng)
9.3 μC/OS-Ⅱ動(dòng)態(tài)內(nèi)存管理
經(jīng)過(guò)表9-7的改動(dòng)后,項(xiàng)目ZLX19執(zhí)行時(shí),計(jì)算機(jī)串口調(diào)試助手顯示內(nèi)容如圖9-7所示。圖9-7 項(xiàng)目ZLX19運(yùn)行時(shí)串口調(diào)試助手顯示內(nèi)容 從圖9-7可知,優(yōu)先級(jí)號(hào)為5的用戶任務(wù)Task02在項(xiàng)目執(zhí)行時(shí),占用堆棧大小為112字節(jié),空閑堆棧大小為88字節(jié)。
9.3 μC/OS-Ⅱ動(dòng)態(tài)內(nèi)存管理 下面在項(xiàng)目ZLX19的基礎(chǔ)上,新建項(xiàng)目ZLX20,保存在目錄D:\ZLXLPC824\ZLX20下,此時(shí)的項(xiàng)目ZLX20與ZLX19相同。然后,按表9-8所示修改項(xiàng)目ZLX20。表9-8 項(xiàng)目ZLX20在項(xiàng)目ZLX19基礎(chǔ)上所做的改動(dòng)
程序段9-15文件ucmem.c 1 //Filename:ucmem.c 2 3 #include"includes.h" 4 5 OS_MEM*mem01;
6 INT32UmemBuf01[5][10];
7
第5行定義內(nèi)存分區(qū)mem01,第6行為內(nèi)存分區(qū)開辟二維數(shù)組空間memBuf01,大小為50字(200字節(jié))。
9.3 μC/OS-Ⅱ動(dòng)態(tài)內(nèi)存管理 8 voidUserMemCreate(void) 9 { 10 INT8Uerr;
11 mem01=OSMemCreate(memBuf01,5,10*sizeof(INT32U),&err);
12 }
第8~12行的函數(shù)UserMemCreate調(diào)用系統(tǒng)函數(shù)OSMemCreate創(chuàng)建內(nèi)存分區(qū)mem01,包含5個(gè)內(nèi)存塊,每個(gè)內(nèi)存塊的大小為10字(40字節(jié))。
程序段9-16文件ucmem.h 1 //Filename:ucmem.h 2 3 #ifndef_UCMEM_H 4 #define_UCMEM_H 5 6 voidUserMemCreate(void);
7 8 #endif
文件ucmem.h中聲明了
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 薛冰安全指南講解
- 達(dá)安深圳一體化項(xiàng)目手冊(cè)模板
- 2026年劇本殺運(yùn)營(yíng)公司行業(yè)展會(huì)參展管理制度
- 學(xué)生評(píng)價(jià)數(shù)字化改革對(duì)高校學(xué)生評(píng)價(jià)體系的影響策略研究教學(xué)研究課題報(bào)告
- 2026年旅游元宇宙應(yīng)用創(chuàng)新報(bào)告
- 保安公司上班時(shí)間制度
- 企業(yè)三個(gè)清單制度
- 中石化安委會(huì)制度
- 專業(yè)人員職稱制度
- 小手流血了安全教育課件
- 漢源縣審計(jì)局關(guān)于公開招聘編外專業(yè)技術(shù)人員的備考題庫(kù)附答案
- GB/T 46758-2025紙漿硫酸鹽法蒸煮液總堿、活性堿和有效堿的測(cè)定(電位滴定法)
- 2026屆福建省龍巖市龍巖一中生物高一第一學(xué)期期末綜合測(cè)試試題含解析
- 2026年上海市普陀區(qū)社區(qū)工作者公開招聘筆試參考題庫(kù)及答案解析
- 二元思辨:向外探索(外)與向內(nèi)審視(內(nèi))-2026年高考語(yǔ)文二元思辨作文寫作全面指導(dǎo)
- 智能清掃機(jī)器人設(shè)計(jì)與研發(fā)方案
- 《中華人民共和國(guó)危險(xiǎn)化學(xué)品安全法》全套解讀
- 糖尿病足護(hù)理指導(dǎo)
- 甲狀腺腫瘤的課件
- 新型鋁合金雨棚施工方案
- 戰(zhàn)略屋策略體系roadmapPP T模板(101 頁(yè))
評(píng)論
0/150
提交評(píng)論