版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、嵌入式操作系統(tǒng)嵌入式操作系統(tǒng)FREERTOS何杰 操作系統(tǒng)操作系統(tǒng)的作用屏蔽硬件,提供軟件接口,調(diào)度應(yīng)用程序,實(shí)現(xiàn)資源分配提供硬件驅(qū)動(dòng)接口,與應(yīng)用無(wú)關(guān)提供用戶操作接口(桌面)通用操作系統(tǒng)通常用于PC機(jī)、服務(wù)器等大中小型計(jì)算機(jī)操作系統(tǒng)功能的全集,極其復(fù)雜實(shí)時(shí)性不強(qiáng)Windows NT/XP、Linux、Unix、Mac、Solaris用過(guò)Windows的都知道,常常“死”的很難看,連蓋茨也不放過(guò)!想象一下這樣的系統(tǒng)用在航空器或醫(yī)療設(shè)備上。嵌入式操作系統(tǒng)通常用于嵌入式系統(tǒng)通用操作系統(tǒng)功能的子集,功能復(fù)雜度降低實(shí)時(shí)性較強(qiáng)嵌入式Linux,Windows CE/Mobile,uC/OS,VxWorks
2、等等與桌面操作系統(tǒng)的比較嵌入式操作系統(tǒng)的分類Embedded operating system structure怎么使用一個(gè)嵌入式操作系統(tǒng)1、了解基本原理2、了解提供的APIFreeRTOS小型嵌入式系統(tǒng)FreeRTOS是一個(gè)迷你操作系統(tǒng)內(nèi)核的小型嵌入式系統(tǒng)。由于RTOS需占用一定的系統(tǒng)資源(尤其是RAM資源),只有C/OS-II、embOS、salvo、FreeRTOS等少數(shù)實(shí)時(shí)操作系統(tǒng)能在小RAM單片機(jī)上運(yùn)行。功能包括:任務(wù)管理、時(shí)間管理、信號(hào)量、消息隊(duì)列、內(nèi)存管理、記錄功能等,可基本滿足較小系統(tǒng)的需要。FreeRTOS免費(fèi)的嵌入式操作系統(tǒng)相對(duì)C/OS-II、embOS等商業(yè)操作系統(tǒng),F(xiàn)
3、reeRTOS操作系統(tǒng)是完全免費(fèi)的操作系統(tǒng),操作系統(tǒng)是完全免費(fèi)的操作系統(tǒng),具有源碼公開(kāi)、可移植、可裁減、調(diào)度策略靈活的特點(diǎn),可以方便地移植到各種單片機(jī)上運(yùn)行。AppendixFreeRTOS官網(wǎng):/FreeRTOS 內(nèi)核使用說(shuō)明:Using The FREERTOS Real Time Kernal中英文版 FreeRTOSDownload FreeRTOS demoDemon code and your code will appear here FreeRTOS source codeGet close to FreeRTOSTask manag
4、ementInter-task Communication and SynchronizationInterrupt managementResource managementMemory managementTrouble shooting table of contents2 FreeRTOS Scheduler1 Scheduling algorithm2 Define and Create a task3 Status of task4 Other APIs of task management 1 調(diào)度機(jī)制也可稱為線程,是一個(gè)獨(dú)立的小程序,每個(gè)Task 都可以看成一個(gè)獨(dú)立的應(yīng)用程序。
5、實(shí)時(shí)應(yīng)用程序的設(shè)計(jì)過(guò)程,包括如何把問(wèn)題分割成多個(gè)任務(wù)例如:無(wú)線溫度監(jiān)測(cè)系統(tǒng),任務(wù)包括:溫度采集、數(shù)據(jù)發(fā)送、命令接收等等任務(wù)(Task)1 調(diào)度機(jī)制多任務(wù)運(yùn)行的實(shí)現(xiàn)實(shí)際上是靠CPU(MPU)在多個(gè)任務(wù)之間轉(zhuǎn)換、調(diào)度,交錯(cuò)運(yùn)行CPU只有一個(gè),輪番服務(wù)于一系列任務(wù)中的某一個(gè),一個(gè)CPU被虛擬化為若干個(gè)CPU多任務(wù)運(yùn)行很像前后臺(tái)系統(tǒng),但后臺(tái)任務(wù)有多個(gè)多任務(wù)運(yùn)行使CPU的利用率得到最大的發(fā)揮,并使應(yīng)用程序模塊化在實(shí)時(shí)應(yīng)用中,多任務(wù)化使開(kāi)發(fā)人員可以將很復(fù)雜的應(yīng)用程序?qū)哟位嗳蝿?wù)(Multi-task)物理世界本身是并發(fā)的!調(diào)度算法:FIFO(FCFS) Example: Three processes a
6、rrive in order P1, P2, P3.P1 CPU time: 24P2 CPU time: 3P3 CPU time: 3Waiting TimeP1: 0P2: 24P3: 27Completion Time:P1: 24P2: 27P3: 30Average Waiting Time: (0+24+27)/3 = 17Average Completion Time: (24+27+30)/3 = 27P1P2 P30242730調(diào)度算法:Round-Robin(時(shí)間片輪時(shí)間片輪詢?cè)?ProcessCPU TimeP124 P2 3 P3 3P1P2P3P1P1P1P1P10
7、36912 1518 21 24FCFSRound-RobinAverage Waiting Time173Average Completion Time2715FCFSRRP1P127 30P1P2P3調(diào)度算法:Round-RobinAdvantage公平性:Better for short jobs Disadvantage開(kāi)銷:Context-switching time adds up for long jobs P1P2P3P1P1P1P1P1036912 1518 21 24P1P127 30調(diào)度算法:Priority-driven schedulingtime0301020604
8、050P2P2P1P3TaskP1: priority 1, execution time 10P2: priority 2, execution time 30P3: priority 3, execution time 20New TaskPriority-driven scheduling exampletime0301020604050P2P2P1P3TaskP1: priority 1, execution time 10P2: priority 2, execution time 30P3: priority 3, execution time 20New TaskP3搶占式和非搶
9、占式time0301020604050P2P2P1P3TaskP1: priority 1, execution time 10P2: priority 2, execution time 30P3: priority 3, execution time 20New TaskP2 is running非搶占式(non-Preemptive)time0301020604050P2P2P1P3TaskP1: priority 1, execution time 10P2: priority 2, execution time 30P3: priority 3, execution time 20N
10、ew TaskP3P2 is running搶占式(Preemptive)time0301020604050P2P2P1P3TaskP1: priority 1, execution time 10P2: priority 2, execution time 30P3: priority 3, execution time 20New TaskP2P3P2 is runningFreeRTOS :Round Robin+Priority+Preemptive P1P2P3P1P1P1P1P1036912 1518 21 24P127 30P1P2P3P1P1P1P1P1036912 1518
11、21 24P1P127 30Round Robin Round Robin+ Priority P1P2P3P1P1P1P1P1036 912 1518 21 24P1P127 30Round Robin+Priority+ PreemptiveP1P1Running2 Define a task/*初始化,只會(huì)執(zhí)行一次*/和定義一個(gè)我們普通函數(shù)一樣,注意:1、 必須 void類型函數(shù)2、 空循環(huán)前是初始化,只會(huì)執(zhí)行一次。3、 task內(nèi)容寫(xiě)在空循環(huán)里。4、 函數(shù)形參必須是一個(gè) void 指針 用于傳遞參數(shù)。5、如果Task不用了,要?jiǎng)h除6、Task內(nèi)部可以產(chǎn)生另外一個(gè)taskCreate a
12、 taskDefine a task 和 Creat a task, 相當(dāng)于定義一個(gè)類和對(duì)象。 pvTaskCode:指向任務(wù)的實(shí)現(xiàn)函數(shù)的指針(效果上僅僅是函數(shù)名)。 pcName:具有描述性的任務(wù)名。用于程序員識(shí)別,但不會(huì)被FreeRTOS使用。 usStackDepth :用于告訴內(nèi)核為它分配多大的??臻g pvParameters:傳遞到任務(wù)中的參數(shù)值 uxPriority:指定任務(wù)執(zhí)行的優(yōu)先級(jí)。 pxCreatedTask :pxCreatedTask 用于傳出任務(wù)的句柄。在在 API 調(diào)用中調(diào)用中對(duì)該對(duì)該創(chuàng)建出來(lái)的任務(wù)進(jìn)行引用,比如改變?nèi)蝿?wù)優(yōu)先級(jí),或者刪除任務(wù)。創(chuàng)建出來(lái)的任務(wù)進(jìn)行引用,
13、比如改變?nèi)蝿?wù)優(yōu)先級(jí),或者刪除任務(wù)。例1創(chuàng)建并啟動(dòng)兩個(gè)任務(wù),這兩個(gè)任務(wù)只是周期性地打印輸出字符串,采用原始的空循環(huán)方式來(lái)產(chǎn)生周期延遲。 方法一:創(chuàng)建兩個(gè)Task方法一:創(chuàng)建兩個(gè)TaskTASK PRIORITIES方法二:Task create task方法三: Task 傳遞參數(shù)TASK PRIORITIES如果把Task 2的優(yōu)先級(jí)設(shè)為2會(huì)有什么結(jié)果?TASK PRIORITIESIt contains several sub-states3任務(wù)狀態(tài)非運(yùn)行狀態(tài)1 Blocked(阻塞)2 Suspend(掛起)3 Ready(就緒)Blocked(阻塞)客觀上,需要等待數(shù)據(jù)或者時(shí)間,無(wú)法執(zhí)行
14、任務(wù)可以進(jìn)入阻塞態(tài)以等待以下兩種不同類型的事件:定時(shí)(時(shí)間相關(guān))事件:這類事件可以是延遲到期或是絕對(duì)時(shí)間到點(diǎn)。同步事件源于其它任務(wù)或中斷的事件。任務(wù)可以在進(jìn)入阻塞態(tài)以等待同步事件時(shí)指定一個(gè)等待超時(shí)時(shí)間,這樣可以有效地實(shí)現(xiàn)阻塞狀態(tài)下同時(shí)等待兩種類型的事件。Suspend(掛起)主觀讓任務(wù)不執(zhí)行。處于掛起狀態(tài)的任務(wù)對(duì)調(diào)度器而言是不可見(jiàn)的。讓一個(gè)任務(wù)進(jìn)入掛起狀態(tài)的唯一辦法就是調(diào)用vTaskSuspend() API 函數(shù);而把一個(gè)掛起狀態(tài)的任務(wù)喚 醒的唯一途徑就是調(diào)用 vTaskResume() 或vTaskResumeFromISR() API 函數(shù)。大多數(shù)應(yīng)用程序中都不會(huì)用到掛起狀態(tài)。Ready
15、(就緒)如果任務(wù)處于非運(yùn)行狀態(tài),但既沒(méi)有阻塞也沒(méi)有掛起,則這個(gè)任務(wù)處于就緒。處于就緒態(tài)的任務(wù)能夠被運(yùn)行,但只是”準(zhǔn)備(ready)”運(yùn)行,而當(dāng)前尚未運(yùn)行。任務(wù)狀態(tài)FreeRTOS實(shí)現(xiàn)方法: (1)阻塞任務(wù)隊(duì)列(2)就緒任務(wù)隊(duì)列THE IDLE TASKThe processor always needs something to execute there must always be that can enter the Running state.An Idle task is automatically created by the scheduler when vTaskStartSc
16、heduler() is called.Prioirty:0例子:利用阻塞狀態(tài)實(shí)現(xiàn)延遲延遲通過(guò)延遲通過(guò) 計(jì)數(shù)來(lái)實(shí)現(xiàn)的。消耗計(jì)數(shù)來(lái)實(shí)現(xiàn)的。消耗CPU資源資源例子:利用阻塞狀態(tài)實(shí)現(xiàn)延遲阻塞延遲函數(shù):阻塞延遲函數(shù): 運(yùn)行vTaskDelay函數(shù),將當(dāng)前任務(wù)放入“阻塞隊(duì)列”; 延遲時(shí)間到達(dá)后,將任務(wù)放回“就緒隊(duì)列”。例子:利用阻塞狀態(tài)實(shí)現(xiàn)延遲2,例子:利用阻塞狀態(tài)實(shí)現(xiàn)延遲4 任務(wù)優(yōu)先級(jí)動(dòng)態(tài)設(shè)置優(yōu)先級(jí)設(shè)置函數(shù):優(yōu)先級(jí)讀取函數(shù):被查詢?nèi)蝿?wù)的句柄(目標(biāo)任務(wù)) 參考xTaskCreate() API函數(shù)的參數(shù) pxCreatedTask 以了解如何得到任務(wù)句柄方面的信息。任務(wù)可以通過(guò)傳入 NULL 值來(lái)修改自
17、己的優(yōu)先級(jí)。pxTask uxNewPriority目標(biāo)任務(wù)將被設(shè)置到哪個(gè)優(yōu)先級(jí)上。如果設(shè)置的值超過(guò)了最大可用優(yōu)先級(jí)(configMAX_PRIORITIES 1),則會(huì)被自動(dòng)封頂為最大值。任務(wù)句柄,任務(wù)可以通過(guò)傳入 NULL 值來(lái)查詢自己的優(yōu)先級(jí)。pxTask被查詢?nèi)蝿?wù)的當(dāng)前優(yōu)先級(jí)。返回值 優(yōu)先級(jí)設(shè)置例子例 具有以下行為方式: 任務(wù) 1(程序清單 22)創(chuàng)建在最高優(yōu)先級(jí),以保證其可以最先運(yùn)行。任務(wù) 1 首先打印輸出兩個(gè)字符串,然后將任務(wù)2的優(yōu)先級(jí)提升到自己之上。 任務(wù) 2 一旦擁有最高優(yōu)先級(jí)便啟動(dòng)執(zhí)行(進(jìn)入運(yùn)行態(tài))。由于任何時(shí)候只可能有一個(gè)任務(wù)處于運(yùn)行態(tài),所以當(dāng)任務(wù)2運(yùn)行時(shí),任務(wù) 1處于就緒
18、態(tài)。 任務(wù)2打印輸出一個(gè)信息,然后把自己的優(yōu)先級(jí)設(shè)回低于任務(wù) 1的初始值。 任務(wù) 2 降低自己的優(yōu)先級(jí)意味著任務(wù) 1 又成為具有最高優(yōu)先級(jí)的任務(wù),所以任務(wù)1重新進(jìn)入運(yùn)行態(tài),任務(wù)2被強(qiáng)制切入就緒態(tài)。 代碼void vTask1( void *pvParameters ) unsigned portBASE_TYPE uxPriority; uxPriority = uxTaskPriorityGet( NULL ); /*傳遞一個(gè)NULL值表示說(shuō)“返回我自己的優(yōu)先級(jí)”。*/ for( ; ) /* Print out the name of this task. */ vPrintString(
19、 Task1 is runningrn ); vPrintString( About to raise the Task2 priorityrn ); vTaskPrioritySet( xTask2Handle, ( uxPriority + 1 ) ); 代碼void vTask2( void *pvParameters ) unsigned portBASE_TYPE uxPriority; uxPriority = uxTaskPriorityGet( NULL ); for( ; ) vPrintString( Task2 is runningrn ); vPrintString(
20、About to lower the Task2 priorityrn ); vTaskPrioritySet( NULL, ( uxPriority - 2 ) ); 代碼xTaskHandle xTask2Handle; int main( void ) xTaskCreate( vTask1, Task 1, 1000, NULL, 2, NULL ); xTaskCreate( vTask2, Task 2, 1000, NULL, 1, &xTask2Handle ); vTaskStartScheduler(); for( ; ); 執(zhí)行過(guò)程刪除task被刪除任務(wù)的句柄(目
21、標(biāo)任務(wù)) 參考xTaskCreate() API函數(shù)的參數(shù) pxCreatedTask 以了解如何得到任務(wù)句柄方面的信息。 任務(wù)可以通過(guò)傳入 NULL 值來(lái)刪除自己。 pxTaskToDelete刪除任務(wù)例子例 9. 刪除任務(wù) 任務(wù)1則 main()創(chuàng)建在優(yōu)先級(jí)1上。任務(wù) 1運(yùn)行時(shí),以優(yōu)先級(jí) 2創(chuàng)建任務(wù) 2?,F(xiàn)在任務(wù) 2 具有最高優(yōu)先級(jí),所以會(huì)立即得到執(zhí)行。任務(wù) 2 什么也沒(méi)有做,只是刪除自己??梢酝ㄟ^(guò)傳遞 NULL 值以 vTaskDelete()來(lái)刪除自己當(dāng)任務(wù)2被自己刪除之后,任務(wù) 1成為最高優(yōu)先級(jí)的任務(wù),所以繼續(xù)執(zhí)行,調(diào)用vTaskDelay()阻塞一小段時(shí)間。 當(dāng)任務(wù)1進(jìn)入阻塞狀態(tài)后
22、,空閑任務(wù)得到執(zhí)行的機(jī)會(huì)。任務(wù)1離開(kāi)阻塞態(tài)后,再一次成為就緒態(tài)中具有最高優(yōu)先級(jí)的任務(wù),因此會(huì)搶占空閑任務(wù)。又再一次創(chuàng)建任務(wù)2,如此往復(fù)。 代碼void vTask1( void *pvParameters ) const portTickType xDelay100ms = 100 / portTICK_RATE_MS; for( ; ) vPrintString( Task1 is runningrn ); xTaskCreate( vTask2, Task 2, 1000, NULL, 2, &xTask2Handle ); vTaskDelay( xDelay100ms ); v
23、oid vTask2( void *pvParameters ) vPrintString( Task2 is running and about to delete itselfrn ); vTaskDelete( xTask2Handle ); 代碼int main( void ) /* 任務(wù)1創(chuàng)建在優(yōu)先級(jí)1上 */ xTaskCreate( vTask1, Task 1, 1000, NULL, 1, NULL ); /* The task is created at priority 1 _. */ /* Start the scheduler so the tasks start e
24、xecuting. */ vTaskStartScheduler(); /* main() should never reach here as the scheduler has been started. */ for( ; ); 結(jié)果Other Related API functionstaskYIELD()THE SCHEDULING ALGORITHMFreeRTOS 任務(wù)管理小結(jié)Round-Robin + Priority + PreemptiveOnly one task can exist in the Running state at any one time.The sch
25、eduler will always select the highest priority Ready state task to enter the Running state. Define, Create a taskRunning, Ready, Blocked, SuspendedDelete, Setpriority Get close to FreeRTOSTask managementInter-task Communication and SynchronizationInterrupt managementResource managementMemory managem
26、entTrouble shooting table of contents1、任務(wù)通信/同步的基本概念2、FreeRTOS:隊(duì)列3、FreeRTOS:信號(hào)量1、基本概念任務(wù)間通信基本概念任務(wù)同步我們把異步環(huán)境下的一組并發(fā)任務(wù)因直接制約而互相發(fā)送消息、進(jìn)行互相合作、互相等待,使得各任務(wù)按一定的速度執(zhí)行的過(guò)程稱為任務(wù)間的同步。消息通信和信號(hào)量是實(shí)現(xiàn)任務(wù)同步的主要方法FreeRTOS的通信和同步都是由Queue(隊(duì)列)實(shí)現(xiàn)2、隊(duì)列QUEUE隊(duì)列:是一個(gè)隊(duì)列:是一個(gè)FIFO,有長(zhǎng)度(隊(duì)列深度),有長(zhǎng)度(隊(duì)列深度)可以被多個(gè)可以被多個(gè)Task訪問(wèn)訪問(wèn)讀隊(duì)列時(shí)阻塞讀隊(duì)列時(shí)阻塞寫(xiě)隊(duì)列寫(xiě)隊(duì)列時(shí)阻塞時(shí)阻塞Exa
27、mple of QueueUSING A QUEUE in FreeRTOSuxQueueLength 隊(duì)列能夠存儲(chǔ)的最大單元數(shù)目,即隊(duì)列深度。 uxItemSize 隊(duì)列中數(shù)據(jù)單元的長(zhǎng)度,以字節(jié)為單位。 返回值 NULL表示沒(méi)有足夠的堆空間分配給隊(duì)列而導(dǎo)致創(chuàng)建失敗。 非 NULL值表示隊(duì)列創(chuàng)建成功。此返回值應(yīng)當(dāng)保存下來(lái),以作為操作此隊(duì)列的句柄。USING A QUEUE in FreeRTOSxTicksToWait 阻塞阻塞超時(shí)時(shí)間。超時(shí)時(shí)間。如果在發(fā)送時(shí)隊(duì)列已滿,讀取不成功,則如果在發(fā)送時(shí)隊(duì)列已滿,讀取不成功,則阻塞阻塞xTicksToWait 個(gè)個(gè)周期周期。xQueueSendToFr
28、ont()用于將數(shù)據(jù)發(fā)送到隊(duì)列首;xQueueSendToBack()用于將數(shù)據(jù)發(fā)送到隊(duì)列尾;xQueueSend()完全等同于 xQueueSendToBack()。USING A QUEUE in FreeRTOSxQueueReceive()用于從隊(duì)列中接收(讀?。?shù)據(jù)單元。接收到的單元同時(shí)會(huì)從隊(duì)列中刪除。 xQueuePeek()也是從從隊(duì)列中接收數(shù)據(jù)單元,不同的是并不從隊(duì)列中刪出接收到的單元。xQueuePeek()從隊(duì)列首接收到數(shù)據(jù)后,不會(huì)修改隊(duì)列中的數(shù)據(jù),也不會(huì)改變數(shù)據(jù)在隊(duì)列中的存儲(chǔ)序順。 USING A QUEUE in FreeRTOSuxQueueMessagesWaiti
29、ng() 用于查詢隊(duì)列中當(dāng)前有效數(shù)據(jù)單元個(gè)數(shù)。Example例 10. 讀隊(duì)列時(shí)阻塞 創(chuàng)建一個(gè)保存 long 型數(shù)據(jù)單元的隊(duì)列,2個(gè)寫(xiě)數(shù)據(jù)任務(wù)和1個(gè)讀數(shù)據(jù)任務(wù)。往隊(duì)列中寫(xiě)數(shù)據(jù)的任務(wù)沒(méi)有設(shè)定阻塞超時(shí)時(shí)間,而讀隊(duì)列的任務(wù)設(shè)定了阻塞超時(shí)時(shí)間。讀數(shù)據(jù)任務(wù)優(yōu)先級(jí)高于寫(xiě)數(shù)據(jù)任務(wù)的優(yōu)先級(jí)分析: 隊(duì)列中永遠(yuǎn)不會(huì)保持超過(guò)一個(gè)的數(shù)據(jù)單元。因?yàn)橐坏┯袛?shù)據(jù)被寫(xiě)入隊(duì)列,讀隊(duì)列任務(wù)立即解除阻塞,搶占寫(xiě)隊(duì)列任務(wù),并從隊(duì)列中接收數(shù)據(jù),同時(shí)數(shù)據(jù)從隊(duì)列中刪除,隊(duì)列再一次變?yōu)榭贞?duì)列。 MainxQueueHandle xQueue; int main( void ) xQueue = xQueueCreate( 5, sizeof
30、( long ) ); if( xQueue != NULL ) xTaskCreate( vSenderTask, Sender1, 1000, ( void * ) 100, 1, NULL ); xTaskCreate( vSenderTask, Sender2, 1000, ( void * ) 200, 1, NULL ); xTaskCreate( vReceiverTask, Receiver, 1000, NULL, 2, NULL ); vTaskStartScheduler(); else /* 隊(duì)列創(chuàng)建失敗*/ for( ; ); vSenderTaskstatic vo
31、id vSenderTask( void *pvParameters ) long lValueToSend; portBASE_TYPE xStatus; lValueToSend = ( long ) pvParameters; for( ; ) xStatus = xQueueSendToBack( xQueue, &lValueToSend, 0 ); if( xStatus != pdPASS ) /* 發(fā)送操作由于隊(duì)列滿而無(wú)法完成 這必然存在錯(cuò)誤,因?yàn)楸纠械年?duì)列不可能滿。 */ vPrintString( Could not send to the queue.rn );
32、 taskYIELD(); /* 允許其它發(fā)送任務(wù)執(zhí)行。 taskYIELD()通知調(diào)度器現(xiàn)在就切換到其它任務(wù),而不必等到本任務(wù)的時(shí)間片耗盡 */ vReceiverTaskstatic void vReceiverTask( void *pvParameters ) long lReceivedValue; portBASE_TYPE xStatus; const portTickType xTicksToWait = 100 / portTICK_RATE_MS; for( ; ) if( uxQueueMessagesWaiting( xQueue ) != 0 ) vPrintStri
33、ng( Queue should have been empty!rn ); xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait ); if( xStatus = pdPASS ) vPrintStringAndNumber( Received = , lReceivedValue ); else vPrintString( Could not receive from the queue.rn ); /* 等待100ms也沒(méi)有收到任何數(shù)據(jù) */ 結(jié)果3、信號(hào)量信號(hào)量的本質(zhì)是一種數(shù)據(jù)操作鎖或者一種同步標(biāo)志,它本身
34、不具有數(shù)據(jù)交換的功能。通常程序通過(guò)信號(hào)量來(lái)控制其他的通信資源(文件,外部設(shè)備)來(lái)實(shí)現(xiàn)任務(wù)間通信,實(shí)現(xiàn)數(shù)據(jù)操作的互斥、任務(wù)同步等功能?;蛘呷蝿?wù)僅僅通過(guò)信號(hào)量的數(shù)值,來(lái)判斷任務(wù)進(jìn)入運(yùn)行狀態(tài)或者阻塞狀態(tài),實(shí)現(xiàn)任務(wù)同步。信號(hào)量的類型二值信號(hào)量(Binary Semaphores):只有0和1, 事件發(fā)生了置1,事件處理了置0,一般用作同步。計(jì)數(shù)信號(hào)量(Counting Semaphores):沒(méi)發(fā)生一個(gè)事件,計(jì)數(shù)值+1。 事件發(fā)生可能比處理快,記錄未處理事件數(shù)量?;コ庑盘?hào)量(Mutex Semaphores ): 是一種特殊的二值信號(hào)量,用于控制在兩個(gè)或多個(gè)任務(wù)間訪問(wèn)共享資源。 FreeRTOS信號(hào)量
35、APIxSemaphoreCreateBinary()/創(chuàng)建二值信號(hào)量創(chuàng)建二值信號(hào)量xSemaphoreCreateCounting()/創(chuàng)建計(jì)數(shù)信號(hào)量創(chuàng)建計(jì)數(shù)信號(hào)量xSemaphoreCreateMutex()/創(chuàng)建互斥信號(hào)量創(chuàng)建互斥信號(hào)量vSemaphoreDelete()/刪除信號(hào)量xSemaphoreTake()/獲取信號(hào)量獲取信號(hào)量xSemaphoreTakeFromISR()/中斷處理程序中獲取信號(hào)量中斷處理程序中獲取信號(hào)量xSemaphoreGive()/設(shè)置信號(hào)量設(shè)置信號(hào)量xSemaphoreGiveFromISR()中斷處理程序中,設(shè)置信號(hào)量中斷處理程序中,設(shè)置信號(hào)量xSem
36、aphoreGetMutexHolder()/獲取互斥信號(hào)量的使用者Get close to FreeRTOSTask managementQueue managementInterrupt managementResource managementMemory managementTrouble shooting table of contents1、中斷與事件處理2、利用二值信號(hào)量實(shí)現(xiàn)中斷與任務(wù)同步3、利用計(jì)數(shù)信號(hào)量鎖存多次中斷4、中斷中使用隊(duì)列中斷中斷1. Normal program execution2. Interrupt occurs3. Processor state save
37、d4. Interrupt routine runs5. Interrupt routine terminates6. Processor state restored7. Normal program execution resumesCPU在執(zhí)行一個(gè)程序時(shí),對(duì)系統(tǒng)發(fā)生的某個(gè)事件(程序自身或外界的原因)作出的一種反應(yīng):CPU暫停正在執(zhí)行的程序,保留現(xiàn)場(chǎng)后自動(dòng)轉(zhuǎn)去處理相應(yīng)的事件,處理完該事件后,到適當(dāng)?shù)臅r(shí)候返回?cái)帱c(diǎn),繼續(xù)完成被打斷的程序。中斷與事件處理 嵌入式實(shí)時(shí)系統(tǒng)需要對(duì)整個(gè)系統(tǒng)環(huán)境產(chǎn)生的各種事件作出反應(yīng), 這些事件對(duì)處理時(shí)間和響應(yīng)時(shí)間都有不同的要求。1. 事件如何被檢測(cè)到?通常采用中斷方式
38、,但是也可以通過(guò)查詢獲得。 2. 事件處理多少在中斷服務(wù)例程(ISR)中的處理?多少在 ISR 外處理?通常情況下,ISR越短越好。 3. 中斷如何通知到主程序?什么樣的程序結(jié)構(gòu)才能最好地適應(yīng)異步和并發(fā)事件? 2、利用二值信號(hào)量延遲處理中斷如何實(shí)現(xiàn)創(chuàng)建二創(chuàng)建二值(值(Binary)信號(hào)量)信號(hào)量void vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore );xSemaphore 所創(chuàng)建信號(hào)量的句柄 獲取信號(hào)量獲取信號(hào)量portBASE_TYPE xSemaphoreTake( xSemaphoreHandle xSemaphore, por
39、tTickType xTicksToWait ); xTicksToWait如果獲取不成功,則阻塞xTicksToWait 個(gè)tick周期中斷處理程序中設(shè)置信號(hào)量中斷處理程序中設(shè)置信號(hào)量portBASE_TYPE xSemaphoreGiveFromISR( xSemaphoreHandle xSemaphore, portBASE_TYPE *pxHigherPriorityTaskWoken ); pxHigherPriorityTaskWoken 標(biāo)識(shí)符,函數(shù)內(nèi)部賦值。表示被解除阻塞的 任務(wù)優(yōu)先級(jí)是否高于當(dāng)前正在執(zhí)行的任務(wù)。例 12. 利用二值信號(hào)量對(duì)任務(wù)和中斷進(jìn)行同步在中斷服務(wù)例程中使
40、用一個(gè)二值信號(hào)量讓任務(wù)從阻塞態(tài)中切換出來(lái)從效果上等同于讓任務(wù)與中斷進(jìn)行同步。中斷源:一個(gè)簡(jiǎn)單的周期性任務(wù)用于每隔 500 毫秒產(chǎn)生一個(gè)軟件中斷。vPeriodicTaskstatic void vPeriodicTask( void *pvParameters ) for( ; ) /* 此任務(wù)通過(guò)每500毫秒產(chǎn)生一個(gè)軟件中斷來(lái)”模擬”中斷事件 */ vTaskDelay( 500 / portTICK_RATE_MS ); /* 產(chǎn)生中斷,并在產(chǎn)生之前和之后輸出信息,以便在執(zhí)行結(jié)果中直觀直出執(zhí)行流程 */ vPrintString( Periodic task - About to gene
41、rate an interrupt.rn ); _asm int 0 x82 /* 這條語(yǔ)句產(chǎn)生中斷 */ vPrintString( Periodic task - Interrupt generated.rnrnrn ); vHandlerTaskstatic void vHandlerTask( void *pvParameters ) /* As per most tasks, this task is implemented within an infinite loop. */ for( ; ) /* 使用信號(hào)量等待一個(gè)事件。信號(hào)量在調(diào)度器啟動(dòng)之前,也即此任務(wù)執(zhí)行之前就已被創(chuàng)建。任
42、務(wù)被無(wú)超時(shí)阻塞,所以此函數(shù)調(diào)用也只會(huì)在成功獲取信號(hào)量之后才會(huì)返回。此處也沒(méi)有必要檢測(cè)返回值 */ xSemaphoreTake( xBinarySemaphore, portMAX_DELAY ); /* 程序運(yùn)行到這里時(shí),事件必然已經(jīng)發(fā)生。本例的事件處理只是簡(jiǎn)單地打印輸出一個(gè)信息 */ vPrintString( Handler task - Processing event.rn ); interruptstatic void _interrupt _far vExampleInterruptHandler( void ) static portBASE_TYPE xHigherPrior
43、ityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; /* Give the semaphore to unblock the task. */ xSemaphoreGiveFromISR( xBinarySemaphore, &xHigherPriorityTaskWoken ); if( xHigherPriorityTaskWoken = pdTRUE ) /* 給出信號(hào)量以使得等待此信號(hào)量的任務(wù)解除阻塞。如果解出阻塞的任務(wù)的優(yōu)先級(jí)高于當(dāng)前任務(wù)的優(yōu)級(jí) 強(qiáng)制進(jìn)行一次任務(wù)切換,以確保中斷直接返回到解出阻塞的任務(wù)(優(yōu)選級(jí)更高) */ por
44、tSWITCH_CONTEXT(); mianint main( void ) vSemaphoreCreateBinary( xBinarySemaphore ); /* 創(chuàng)建了一個(gè)二值信號(hào)量 */ _dos_setvect( 0 x82, vExampleInterruptHandler ); /* 安裝中斷服務(wù)例程 */ if( xBinarySemaphore != NULL ) /* 檢查信號(hào)量是否成功創(chuàng)建 */ xTaskCreate( vHandlerTask, “Handler”, 1000, NULL, 3, NULL );/*延遲處理任務(wù) */ xTaskCreate( v
45、PeriodicTask, “Periodic”, 1000, NULL, 1, NULL ); /*周期性任務(wù) */ /* Start the scheduler so the created tasks start executing. */ vTaskStartScheduler(); for( ; ); 結(jié)果利用計(jì)數(shù)信號(hào)量鎖存多次中斷What to do when Interrupts occurs more frequently?Only one interruptMore interrupts3、利用計(jì)數(shù)信號(hào)量鎖存多次中斷一個(gè)二值信號(hào)量最多只可以鎖存一個(gè)中斷事件。在鎖存的事件還未被
46、處理之前,如果還有中斷事件發(fā)生,那么后續(xù)發(fā)生的中斷事件將會(huì)丟失。解決方法:計(jì)數(shù)信號(hào)量事件發(fā)生時(shí),中斷服務(wù)例程都會(huì)“給出(Give)”信號(hào)量信號(hào)量在每次被給出時(shí)其計(jì)數(shù)值加 1。延遲處理任務(wù)每處理一個(gè)任務(wù)都會(huì)”獲取(Take)”一次信號(hào)量信號(hào)量在每次被獲取時(shí)其計(jì)數(shù)值減 1。定義定義計(jì)數(shù)計(jì)數(shù)(Counting)信號(hào)量)信號(hào)量xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount );uxMaxCount 最大計(jì)數(shù)值。uxIni
47、tialCount信號(hào)量的初始計(jì)數(shù)值。返回值句柄或者Null(表示失敗)例 13. 利用計(jì)數(shù)信號(hào)量對(duì)任務(wù)和中斷進(jìn)行同步用計(jì)數(shù)信號(hào)量代替二值信號(hào)量對(duì)例 12 的實(shí)現(xiàn)進(jìn)行了改進(jìn)。修改 main()函數(shù)調(diào)用xSemaphoreCreateCounting(),以代替對(duì)xSemaphoreCreateBinary()的調(diào)用。mianint main( void ) xCountingSemaphore = xSemaphoreCreateCounting( 10, 0 ); /* 創(chuàng)建創(chuàng)建了了計(jì)數(shù)計(jì)數(shù)信號(hào)量信號(hào)量 */ _dos_setvect( 0 x82, vExampleInterruptHan
48、dler ); /* 安裝中斷服務(wù)例程 */ if( xBinarySemaphore != NULL ) /* 檢查信號(hào)量是否成功創(chuàng)建 */ xTaskCreate( vHandlerTask, “Handler”, 1000, NULL, 3, NULL );/*延遲處理任務(wù) */ xTaskCreate( vPeriodicTask, “Periodic”, 1000, NULL, 1, NULL ); /*周期性任務(wù) */ /* Start the scheduler so the created tasks start executing. */ vTaskStartSchedule
49、r(); for( ; ); interruptstatic void _interrupt _far vExampleInterruptHandler( void ) static portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; /* 多次給出信號(hào)量。第一次給出時(shí)使得延遲處理任務(wù)解除阻塞。后續(xù)給出用于演示利多次給出信號(hào)量。第一次給出時(shí)使得延遲處理任務(wù)解除阻塞。后續(xù)給出用于演示利用被信號(hào)量鎖存事件用被信號(hào)量鎖存事件,以便,以便延遲處理任何依序?qū)@些中斷事件進(jìn)行處理而不會(huì)丟中斷。延遲處理任何依
50、序?qū)@些中斷事件進(jìn)行處理而不會(huì)丟中斷。用這種方式來(lái)模擬處理器產(chǎn)生多個(gè)中斷,用這種方式來(lái)模擬處理器產(chǎn)生多個(gè)中斷,盡管這些盡管這些事件只是在單次中斷中模擬出來(lái)的事件只是在單次中斷中模擬出來(lái)的 */ xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xCountingSemaphore, &xHi
51、gherPriorityTaskWoken ); Free http:/www.F if( xHigherPriorityTaskWoken = pdTRUE ) portSWITCH_CONTEXT(); 結(jié)果4、中斷中使用隊(duì)列信號(hào)量用于事件同步. 隊(duì)列可以同時(shí)傳遞事件和數(shù)據(jù)。例14創(chuàng)建一個(gè)周期任務(wù)用于每 200 毫秒往隊(duì)列中發(fā)送五個(gè)數(shù)值,五個(gè)數(shù)值都發(fā)送完后便產(chǎn)生一個(gè)軟件中斷。中斷處理程序,在字符串隊(duì)列放入五個(gè)字符串由handler任務(wù)進(jìn)行輸出例14 創(chuàng)建一個(gè)周期任務(wù)用于每 200 毫秒往隊(duì)列中發(fā)送五個(gè)數(shù)值,五個(gè)數(shù)值都發(fā)送完后便產(chǎn)生一個(gè)軟件中斷結(jié)果Interrupt nestingGet c
52、lose to FreeRTOSTask managementInter-task Communication and SynchronizationInterrupt managementResource managementMemory managementTrouble shooting table of contentscritical sectionmutexgatekeeper task1、多任務(wù)的風(fēng)險(xiǎn)2、臨界區(qū)3、互斥信號(hào)量1、多任務(wù)系統(tǒng)的風(fēng)險(xiǎn)當(dāng)一個(gè)任務(wù)在使用某個(gè)資源的過(guò)程中,即還沒(méi)有完全結(jié)束對(duì)資源的訪問(wèn)時(shí),便被切出運(yùn)行態(tài),使得資源處于非一致,不完整的狀態(tài)。如果這個(gè)時(shí)候有另一個(gè)任
53、務(wù)或者中斷來(lái)訪問(wèn)這個(gè)資源,則會(huì)導(dǎo)致數(shù)據(jù)損壞或是其它相似的錯(cuò)誤。例:數(shù)據(jù)共享問(wèn)題考慮如下情形,有兩個(gè)任務(wù)都試圖往一個(gè)LCD中寫(xiě)數(shù)據(jù): 任務(wù) A運(yùn)行,并往 LCD寫(xiě)字符串”Hello world”。 任務(wù) A被任務(wù) B搶占,但此時(shí)字符串才輸出到”Hello w”。 任務(wù) B 往 LCD寫(xiě)”Abort, Retry, Fail?”,然后進(jìn)入阻塞態(tài)。 任務(wù) A從被搶占處繼續(xù)執(zhí)行,完成剩余的字符輸出“orld”。 現(xiàn)在LCD 顯示的是被破壞了的字符串”Hello wAbort, Retry, Fail?orld”。 解決方法?2、臨界區(qū)(Criticl)指運(yùn)行時(shí)不可被打斷的程序區(qū)域 一旦這部分程序開(kāi)始執(zhí)
54、行,則不允許以任何方式中斷其運(yùn)行。為確保臨界區(qū)代碼的獨(dú)占執(zhí)行,在進(jìn)入臨界段之前要關(guān)中斷,而臨界段代碼執(zhí)行完以后要立即開(kāi)中斷,以免系統(tǒng)實(shí)時(shí)性下降。 FreeRTOS 基本臨界區(qū)定義基本臨界區(qū)是指宏 taskENTER_CRITICAL()與 taskEXIT_CRITICAL()之間的代碼區(qū)間 在taskENTER_CRITICAL() 與 taskEXIT_CRITICAL()之間不會(huì)切換到其它任務(wù)。 中斷可以執(zhí)行,也允許嵌套,但只是針對(duì)優(yōu)先級(jí)高于configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷 , 而且這些中斷不允許訪問(wèn) FreeRTOS API 函數(shù).Exam
55、ple通過(guò)掛起調(diào)度器建立臨界區(qū)基本臨界區(qū)保護(hù)一段代碼區(qū)間不被其它任務(wù)或中斷打斷。由掛起調(diào)度器實(shí)現(xiàn)的臨界區(qū)只可以保護(hù)一段代碼區(qū)間不被其它任務(wù)打斷,因?yàn)檫@種方式下,中斷是使能的。 如果一個(gè)臨界區(qū)太長(zhǎng)而不適合簡(jiǎn)單地關(guān)中斷來(lái)實(shí)現(xiàn),可以考慮采用掛起調(diào)度器的方式。但是喚醒(resuming, or un-suspending)調(diào)度器卻是一個(gè)相對(duì)較長(zhǎng)的操作。所以評(píng)估哪種是最佳方式需要結(jié)合實(shí)際情況。 3、互斥信號(hào)量互斥量是一種特殊的二值信號(hào)量,用于控制在兩個(gè)或多個(gè)任務(wù)間訪問(wèn)共享資源訪問(wèn)共享資源。類似于令牌,要想訪問(wèn)資源必須先獲互斥取信號(hào)量訪問(wèn)完后必須歸還(Give)與二值信號(hào)量的區(qū)別:用于互斥的信號(hào)量必須歸還。二值信號(hào)量用于同步,用完就丟棄相關(guān)函數(shù)定義互斥信號(hào)量定義互斥信號(hào)量xSemaphoreHandle xSemaphoreCreateMutex( void )獲取信號(hào)量獲取信號(hào)量portBASE_TYPE xSemaphoreTake( xSemaphoreHandle xSemaphore,
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度數(shù)字廣告平臺(tái)運(yùn)營(yíng)與維護(hù)服務(wù)合同細(xì)則
- 2025年股權(quán)投資居間服務(wù)合同樣本
- 2025版化工企業(yè)市場(chǎng)營(yíng)銷人員勞動(dòng)合同范本
- 二零二五年度建筑沉降觀測(cè)與施工質(zhì)量監(jiān)理合同4篇
- 二零二四年度三方新能源技術(shù)服務(wù)銷售合同3篇
- 2025年度古董珠寶鑒定與定制交易合同
- 2025年度管樁施工質(zhì)量控制與驗(yàn)收合同
- 2025年度家電產(chǎn)品供應(yīng)鏈協(xié)同營(yíng)銷合同
- 二零二五年度房產(chǎn)買賣合同(含稅費(fèi)結(jié)算與交付)3篇
- 2025年度護(hù)工技能提升培訓(xùn)合同范本
- 2025年個(gè)人土地承包合同樣本(2篇)
- (完整版)高考英語(yǔ)詞匯3500詞(精校版)
- 網(wǎng)絡(luò)貨運(yùn)行業(yè)研究報(bào)告
- 2024-2025年突發(fā)緊急事故(急救護(hù)理學(xué))基礎(chǔ)知識(shí)考試題庫(kù)與答案
- 左心耳封堵術(shù)護(hù)理
- 2024年部編版八年級(jí)語(yǔ)文上冊(cè)電子課本(高清版)
- 合唱課程課件教學(xué)課件
- 2024-2025學(xué)年廣東省大灣區(qū)40校高二上學(xué)期聯(lián)考英語(yǔ)試題(含解析)
- 旅拍店兩人合作協(xié)議書(shū)范文
- 2024-2030年電炒鍋?lái)?xiàng)目融資商業(yè)計(jì)劃書(shū)
- 防火墻漏洞掃描基礎(chǔ)知識(shí)
評(píng)論
0/150
提交評(píng)論