ARM Cortex-M3嵌入式開發及應用教與學 課件 第12、13章 信號量與互斥信號量;消息郵箱與消息隊列_第1頁
ARM Cortex-M3嵌入式開發及應用教與學 課件 第12、13章 信號量與互斥信號量;消息郵箱與消息隊列_第2頁
ARM Cortex-M3嵌入式開發及應用教與學 課件 第12、13章 信號量與互斥信號量;消息郵箱與消息隊列_第3頁
ARM Cortex-M3嵌入式開發及應用教與學 課件 第12、13章 信號量與互斥信號量;消息郵箱與消息隊列_第4頁
ARM Cortex-M3嵌入式開發及應用教與學 課件 第12、13章 信號量與互斥信號量;消息郵箱與消息隊列_第5頁
已閱讀5頁,還剩45頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第十二章

信號量與互斥信號量目錄μC/OS-II信號量μC/OS-II互斥信號量信號量與互斥信號量實例本章小結1信號量和互斥信號量是μC/OS-II中最重要的兩個組件,信號量用于實現任務間的同步以及任務同步中斷服務函數的運行,互斥信號量用于保護共享資源。本章將介紹信號量與互斥信號量的概念和程序設計方法。10.1μC/OS-II信號量23信號量本質上是一個全局計數器的實現機制,釋放信號量的任務使得該計數器的值加1,請求到信號量的任務使該計數器的值減1,如果計數器的值為0,則請求該信號量的任務將掛起等待,直到別的任務釋放該信號量。通過這種方式,使得釋放信號量的任務可以控制請求信號量的任務的運行。信號量相關的函數列于右表中,這些函數的定義位于μC/OS-II內核文件os_sem.c中。μC/OS-II信號量4信號量的工作原理如下圖所示。μC/OS-II信號量5信號量相關的主要操作有:創建信號量OSSemCreate、請求信號量OSSemPend和釋放信號量OSSemPost。使用信號量的步驟為:(1)定義事件,如:“OS_EVENT*sem01;”。(2)創建信號量,如“sem01=OSSemCreate(0);”,此時,創建了信號量sem01,信號量的初始值為0。(3)在任務A中周期性地釋放該信號量,調用“OSSemPost(sem01);”實現。(4)在任務X中始終請求該信號量,用“OSSemPend(sem01,0,&err);”實現,該函數的第二個參數表示等待超時,如果為0,表示請求不到信號量時永久等待;如果為大于0的整數,則任務X等待該整數值的時鐘節拍后,仍然沒有請求到信號量時,則不再等待而繼續執行。μC/OS-II信號量10.2μC/OS-II互斥信號量67互斥信號量只有0和1兩個值,與信號量的操作類似,常用的互斥信號量管理函數列于下表中,這些函數位于μC/OS-II內核文件os_mutex.c中。μC/OS-II互斥信號量8互斥信號量的工作情況如下圖所示。μC/OS-II互斥信號量互斥信號量只有0和1兩個值,表示兩種狀態,即互斥信號量被占用和未被占用。如上圖所示,某一任務X需要使用共享資源時,首先需要請求互斥信號量M,如果沒有請求到,說明共享資源被其他任務正在使用;如果請求到M,則優先級反轉到比其他要請求該共享資源的所有任務的優先級略高的優先級繼承優先級,任務X使用完共享資源后,釋放互斥信號量M??梢姡コ庑盘柫康恼埱蠛歪尫攀窃谕粋€任務中實現的。9μC/OS-II互斥信號量使用互斥信號量的步驟如下:(1)定義事件,如“OS_EVENT*mtx01;”。(2)定義優先級繼承優先級(PIP)的值PIP_Prio,PIP的數值應比所有請求同一共享資源的任務的優先級數值要小。(3)創建互斥信號量,如“mtx01=OSMutexCreate(PIP_Prio,&err);”。(4)如果某一任務X要使用共享資源,應先調用OSMutexPend函數請求互斥信號量,如“OSMutexPend(mtx01,0,&err);”;請求到互斥信號量之后,開始使用共享資源,使用完后再調用OSMutexPost函數釋放互斥信號量,如“OSMutexPost(mtx01);”。函數OSMutexPend的第2個參數為等待超時參數,如果為0,表示請求不到互斥信號量時,一直等待;如果為大于0的整數,表示等待該整數值的時鐘節拍后,仍然請求不到互斥信號量時,則放棄等待。10.3信號量與互斥信號量實例1011信號量與互斥信號量實例工程PRJ31的具體建設步驟如下所示:(1)在工程PRJ30的基礎上,新建工程“PRJ31”,保存在目錄“D:\STM32F103RCT6PRJ\PRJ31”下,此時的工程PRJ31與工程PRJ30完全相同。(2)修改task01.c文件,如下面的程序段所示。12信號量與互斥信號量實例13信號量與互斥信號量實例14信號量與互斥信號量實例15信號量與互斥信號量實例16信號量與互斥信號量實例17信號量與互斥信號量實例(3)新建文件task07.c、task07.h、task08.c和task08.h,保存在目錄“D:\STM32F103RCT6PRJ\PRJ31\USER”下,其代碼如下面的程序段所示。18信號量與互斥信號量實例20信號量與互斥信號量實例(4)修改uctmr.c和uctmr.h文件,如程序段所示。20信號量與互斥信號量實例(5)新建文件task09.c和task09.h,保存在目錄“D:\STM32F103RCT6PRJ\PRJ31\USER”下,其代碼如下面的程序段所示。21信號量與互斥信號量實例(6)修改文件exti.c,其代碼如下面的程序段所示。22信號量與互斥信號量實例23信號量與互斥信號量實例(7)新建文件task10.c和task10.h,保存在“D:\STM32F103RCT6PRJ\PRJ31\USER”目錄下,其代碼如下面的程序段所示。24信號量與互斥信號量實例(8)修改文件task02.c,其代碼如下面的程序段所示。25信號量與互斥信號量實例(9)新建文件task11.c和task11.h,保存在“D:\STM32F103RCT6PRJ\PRJ31\USER”目錄下,其代碼如下面的程序段所示。26信號量與互斥信號量實例(10)修改文件includes.h,其代碼如下面的程序段所示。27信號量與互斥信號量實例(11)將文件task07.c~task11.c添加到工程管理器的“USER”分組下,建設好的工程PRJ31如下圖所示。28信號量與互斥信號量實例工程PRJ31的執行流程如下圖所示。10.4本章小結2930本章小結本章詳細介紹了信號量和互斥信號量的用法,信號量的主要作用在于實現兩個用戶任務間的同步執行,或用戶任務同步中斷服務程序的執行。“信號量+全局變量”的方式還可以實現在任務間傳遞信息,或由中斷服務程序向任務傳遞信息。互斥信號量的作用在于保護共享資源,避免出現死鎖或者全局變量訪問出錯。信號量和互斥信號量均屬于事件,在os_cfg.h文件中宏定義了OS_MAX_EVENTS的值為20(參考表10-2和程序段10-10第19行),因此,工程PRJ31中,最多可創建的信號量和互斥信號量為20個。實際工程中,若使用的信號量數量較多,應設置較大的OS_MAX_EVENTS宏常量的值。thankyouARMCortex-M3嵌入式控制技術

——基于STM32F103RCT6

嵌入式實時操作系統μC/OS-II第十三章

消息郵箱與消息隊列

消息郵箱和消息隊列是μC/OS-II系統中非常重要的兩個組件。信號量主要用于任務間的同步,而消息郵箱和消息隊列不僅可以實現任務間的同步,而且可用于任務間相互通信。本章將詳細介紹消息郵箱和消息隊列的概念和用法。

本章的學習目標:

了解消息郵箱的工作原理;

熟悉消息郵箱與隊列的系統函數;

掌握消息郵箱與隊列的應用方法。

1μC/OS-II消息郵箱2μC/OS-II多任務工程實例3

統計任務實例4系統定時器13.1μC/OS-II消息郵箱消息郵箱不僅能實現任務間的同步,而且還可用于任務間相互通信。在μC/OS-II中,與消息郵箱管理相關的函數有8個,位于μC/OS-II內核文件os_mbox.c中,如表所示。函數原型功能OS_EVENT*OSMboxCreate(void*msg);創建并初始化一個消息郵箱。如果參數不為空,則新建的郵箱將包含消息void*OSMboxPend(OS_EVENT*pevent,INT16Utimeout,INT8U*perr);向郵箱請求消息,如果郵箱中有消息,則消息傳遞到任務中,郵箱清空;如果郵箱中沒有消息,當前任務掛起等待,直到郵箱中有消息或等待超時。如果有多個任務等待同一個消息,則該消息到來時,μC/OS-II使優先級最高的任務獲得消息并運行(中斷服務程序不能調用該函數)INT8UOSMboxPost(OS_EVENT*pevent,void*pmsg);向郵箱傳入消息(可理解為向郵箱釋放消息),如果有任務在等待該消息,則高優先級的任務將會:(1)如果此任務優先級低于調用該函數的任務,則在調用該函數的任務執行完后,立即得到消息并執行;(2)如果此任務優先級高于調用該函數的任務,則此任務立即執行,調用該函數的任務被掛起等待。pmsg不允許傳遞空指針INT8UOSMboxPostOpt(OS_EVENT*pevent,void*pmsg,INT8Uopt);向郵箱中釋放消息。opt可?。海?)OS_POST_OPT_BROADCAST,消息將廣播給所有請求該消息郵箱的任務;(2)OS_POST_OPT_NONE,此時與OSMboxPost含義相同;(3)OS_POST_OPT_NO_SCHED,釋放消息后不進行任務調度,可用于一次性地釋放多個消息后,再進行任務調度OS_EVENT*OSMboxDel(OS_EVENT*pevent,INT8Uopt,INT8U*perr);刪除一個消息郵箱。通常,在刪除郵箱前,應刪除那些請求該郵箱的任務(中斷服務程序不能調用該函數)INT8UOSMboxQuery(OS_EVENT*pevent,OS_MBOX_DATA*p_mbox_data);查詢郵箱當前的消息及等待該消息的事件列表INT8UOSMboxPendAbort(OS_EVENT*pevent,INT8Uopt,INT8U*perr);中止任務對消息郵箱的請求,使等待該消息的任務繼續執行(中斷服務程序不能調用該函數)void*OSMboxAccept(OS_EVENT*pevent);向指定的郵箱請求消息,如果沒有消息,則調用該函數的任務不掛起等待;如果有消息,則消息傳遞到任務中,然后清空郵箱。可被任務或中斷服務程序調用,多用于中斷服務程序中消息郵箱的工作情況消息郵箱的用法如下:(1)定義事件,如“OS_EVENT*mbox01;”。(2)定義全局一維數組保存消息,如“INT8Umsgbx[80];”。(3)創建消息郵箱,如“mbox01=OSMboxCreate(NULL);”,NULL參數表示創建的郵箱中沒有消息。(4)在某一個任務A中釋放消息,如:“OSMboxPost(mbox01,(void*)msgbx);”,如果發送的消息為“Msg:A-X”,則需要事先將該消息存在msgbx中,可以使用語句“strcpy((char*)msgbx,“Msg:A-X”);”。(5)在另一個任務X中請求消息,如“pmsg=OSMboxPend(mbox01,0,&err);”,這里的pmsg為“void*”類型的任務局部變量,這樣,消息“Msg:A-X”就從任務A傳遞到任務X中了。13.2μC/OS-II消息隊列消息隊列可以視為消息郵箱的數組形式,消息郵箱一次只能傳遞一則消息,而消息隊列可以一次傳遞多則消息。因此,消息郵箱是消息隊列的一種特例。消息隊列的工作情況如圖所示。任務和中斷服務程序可以向消息隊列中釋放消息,只有任務才能從消息隊列中請求消息,任務可以始終請求消息,也可周期性地請求消息。消息隊列具有一定的長度,其長度為可包含的消息個數,如果向隊列中釋放消息的速度大于從隊列中請求消息的速度,那么消息隊列將溢出。在μC/OS-II中,消息隊列相關的管理函數約有10個,列于表中,這些函數位于μC/OS-II內核文件os_q.c中函數原型功能OS_EVENT*OSQCreate(void**start,INT16Usize);創建一個消息隊列,允許任務或中斷服務程序發送一些指針類型的變量(消息)給一個或多個任務,消息內容由應用程序指定void*OSQPend(OS_EVENT*pevent,INT16Utimeout,INT8U*perr);向消息隊列請求消息。如果隊列中有消息,則該消息傳遞給任務,并從隊列中清除該消息;如果隊列中沒有消息,則調用該函數的任務被掛起等待,直到有消息或等待超時。當有多個任務請求到同一消息隊列時,μC/OS-II進行任務調度,使優先級最高的任務得到消息(中斷服務程序不能調用該函數)INT8UOSQPost(OS_EVENT*pevent,void*pmsg);向消息隊列送入消息(即向隊列釋放消息),消息隊列為先進先出(FIFO)方式。如果隊列已滿,則消息不會進入隊列,OSQPost立即返回;否則,消息進入隊列,如果有任務在請求該消息隊列,則μC/OS-II進行任務調度,當前任務和所有請求該消息隊列的任務中最高優先級的任務得到執行權INT8UOSQPostFront(OS_EVENT*pevent,void*pmsg);向消息隊列送入消息(即向隊列釋放消息),消息插入到隊列前端,消息隊列為后進先出(LIFO)方式。如果隊列已滿,則消息不會插入隊列,OSQPostFront立即返回;否則,消息插入隊列,如果有任務在請求該消息隊列,則μC/OS-II進行任務調度,當前任務和所有請求該消息隊列的任務中最高優先級的任務得到執行權INT8UOSQPostOpt(OS_EVENT*pevent,void*pmsg,INT8Uopt);向隊列中釋放消息。opt可取以下值:(1)OS_POST_OPT_NONE,與OSQPost相同;(2)OS_POST_OPT_FRONT,與OSQPostFront相同;(3)OS_POST_OPT_BROADCAST,每個消息均廣播給所有請求隊列的任務;(4)OS_POST_OPT_NO_SCHED,釋放消息后不進行任務調度,借助該參數可以一次性向隊列中釋放多個消息,在釋放完最后一個消息時,不使用該參數,進行任務調度。OS_EVENT*OSQDel(OS_EVENT*pevent,INT8Uopt,INT8U*perr);刪除一個消息隊列。通常,刪除消息隊列前,應刪除所有請求該消息隊列的任務(中斷服務程序不能調用該函數)void*OSQAccept(OS_EVENT*pevent,INT8U*perr);向消息隊列請求消息。與OSQPend不同的是,如果隊列中沒有消息,調用該函數的任務并不掛起等待,主要用于中斷服務程序中。如果隊列中有消息,該消息傳遞到任務中,在OSQAccept返回前,該消息從隊列中移除INT8UOSQPendAbort(OS_EVENT*pevent,INT8Uopt,INT8U*perr);放棄請求消息隊列,繼續執行當前任務(中斷服務程序不能調用該函數)INT8UOSQQuery(OS_EVENT*pevent,OS_Q_DATA*p_q_data);查詢消息隊列信息。INT8UOSQFlush(OS_EVENT*pevent);清空消息隊列消

溫馨提示

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

評論

0/150

提交評論