版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
本篇包括第五至九章,詳細介紹基于嵌入式實時操作系統(tǒng)μC/OS-Ⅱ的任務級別的應用程序設計方法,依次講述μC/OS-Ⅱ工作原理及其移植、μC/OS-Ⅱ任務、μC/OS-Ⅱ信號量與互斥信號量、μC/OS-Ⅱ消息郵箱與隊列以及μC/OSⅡ高級系統(tǒng)組件。這部分內容結合了具體的工程實例進行介紹,重點在于用戶任務、信號量和消息郵箱的學習。
嵌入式實時操作系統(tǒng)
μC/OS-Ⅱ的應用第五章
μc/OS-Ⅱ工作原理及其移植 5.1 μC/OSⅡ系統(tǒng)任務 5.2 信號量與互斥信號量 5.3 消息郵箱與消息隊列 5.4 事件標志組 5.5 μC/OS-Ⅱ在Cortex-M0+
微控制器上的移植
5.1.1 μC/OS-Ⅱ系統(tǒng)文件與配置
從上下載到最新的μC/OS-Ⅱ嵌入式實時操作系統(tǒng),最新版本號為V2.91,μC/OS-Ⅱ共有14個系統(tǒng)文件,如表5-1所示。表5-1 μC/OS-Ⅱ系統(tǒng)文件5.1
μC/OS-Ⅱ系統(tǒng)任務 如果對μC/OS-Ⅱ系統(tǒng)內核工作原理感興趣,需要認真閱讀表5-1中的全部文件,大約有11000多行源代碼。如果重點關注μC/OS-Ⅱ系統(tǒng)的應用程序設計,可以只關心系統(tǒng)配置文件os_cfg.h,通過該文件對μC/OS-Ⅱ系統(tǒng)進行裁剪,該文件內容如下:
程序段5-1os_cfg.h文件 1 //Filename:os_cfg.h,OwnedbyJ.J.Labrosse,Micrium 2 3 #ifndefOS_CFG_H 4 #defineOS_CFG_H 5 6 #defineOS_APP_HOOKS_EN 1u 7 #defineOS_ARG_CHK_EN 0u 8 #defineOS_CPU_HOOKS_EN 1u 9
第6行OS_APP_HOOKS_EN為1表示μC/OS-Ⅱ支持用戶定義的應用程序鉤子函數(shù),缺省為支持。第7行OS_ARG_CHK_EN為1表示系統(tǒng)函數(shù)進行參數(shù)合法性檢查,為0表示不做合法性檢查,缺省為0,建議設為1。第8行OS_CPU_HOOKS_EN為1表示支持系統(tǒng)鉤子函數(shù),為0表示不支持,缺省為1。5.1
μC/OS-Ⅱ系統(tǒng)任務 10 #defineOS_DEBUG_EN 1u 11 12 #defineOS_EVENT_MULTI_EN 1u 13 #defineOS_EVENT_NAME_EN 1u 14
第10行OS_DEBUG_EN為1,使調試變量有效,缺省為1。第12行OS_EVENT_MULTI_EN為1表示支持多事件請求系統(tǒng)函數(shù),缺省為1,建議設為0。第13行OS_EVENT_NAME_EN為1表示可為各個組件指定名稱,缺省為1,建議為1。 15 #defineOS_LOWEST_PRIO 63u 16
第15行OS_LOWEST_PRIO表示用戶任務的最大優(yōu)先級號值,缺省為63,μC/OS-Ⅱ最多可支持255個任務,因此,這里OS_LOWEST_PRIO的值最大不要超過254(因為優(yōu)先級號從0開始,計數(shù)到第254時,共有255個任務;255(即0xFF)專用于表示當前正在執(zhí)行任務的任務優(yōu)先級號)。5.1
μC/OS-Ⅱ系統(tǒng)任務 17 #defineOS_MAX_EVENTS 10u 18 #defineOS_MAX_FLAGS 5u 19 #defineOS_MAX_MEM_PART 5u 20 #defineOS_MAX_QS 4u 21 #defineOS_MAX_TASKS 20u 22
第17行OS_MAX_EVENTS指定系統(tǒng)中事件控制塊的最大數(shù)量,缺省值為10;第18行OS_MAX_FLAGS指定事件標志組的最大個數(shù),缺省值為5;第19行OS_MAX_MEM_PART指定內存分區(qū)的最大個數(shù),缺省值為5;第20行OS_MAX_QS指定消息隊列的最大個數(shù),缺省值為4;第21行OS_MAX_TASKS指定最多可創(chuàng)建的任務個數(shù),缺省值為20,最小值為2,因為μC/OSⅡ系統(tǒng)要求必須創(chuàng)建空閑任務(系統(tǒng)任務)和至少要有一個用戶任務。 23 #defineOS_SCHED_LOCK_EN 1u 24 25 #defineOS_TICK_STEP_EN 1u 26 #defineOS_TICKS_PER_SEC 100u 275.1
μC/OS-Ⅱ系統(tǒng)任務
第23行OS_SCHED_LOCK_EN為1表示用于任務上鎖和解鎖的函數(shù)OSSchedLock和OSSchedUnLock可用,為0表示不可用;第25行OS_TICK_STEP_EN為1表示μC/OS-View可觀測時鐘節(jié)拍;第26行為時鐘節(jié)拍頻率,默認值為100Hz。 28 #defineOS_TASK_TMR_STK_SIZE 128u 29 #defineOS_TASK_STAT_STK_SIZE 128u 30 #defineOS_TASK_IDLE_STK_SIZE 128u 31
第28~30行規(guī)定了3個系統(tǒng)任務,即定時器任務、統(tǒng)計任務和空閑任務的堆棧大小,均設為128,單位為OS_STK,對于LPC824而言,OS_STK為無符號32位整型,即128相當于512字節(jié)。 32 #defineOS_TASK_CHANGE_PRIO_EN 1u 33 #defineOS_TASK_CREATE_EN 1u 34 #defineOS_TASK_CREATE_EXT_EN 1u 35 #defineOS_TASK_DEL_EN 1u 36 #defineOS_TASK_NAME_EN 1u 37 #defineOS_TASK_PROFILE_EN 1u 38 #defineOS_TASK_QUERY_EN 1u5.1
μC/OS-Ⅱ系統(tǒng)任務 39 #defineOS_TASK_REG_TBL_SIZE 1u 40 #defineOS_TASK_STAT_EN 1u 41 #defineOS_TASK_STAT_STK_CHK_EN 1u 42 #defineOS_TASK_SUSPEND_EN 1u 43 #defineOS_TASK_SW_HOOK_EN 1u 44
第32~43行為任務管理相關的宏定義,各行的宏定義值均為1,依次表示函數(shù)OSTaskChangePrio可用、OSTaskCreate函數(shù)可用、OSTaskCreateExt函數(shù)可用、OSTaskDel函數(shù)可用、任務可命名、OS_TCB任務控制塊中包括測試信息、OSTaskQuery函數(shù)可用、任務寄存器變量數(shù)組長度為1、統(tǒng)計任務可用、統(tǒng)計任務可統(tǒng)計各個任務的堆棧使用情況、函數(shù)OSTaskSuspend和OSTaskResume可用以及OSTaskSwHook函數(shù)可用。除了第39行的OS_TASK_REG_TBL_SIZE外,其余行宏定義的值為0時,含義剛好與上述相反。5.1
μC/OS-Ⅱ系統(tǒng)任務 45 #defineOS_FLAG_EN 1u 46 #defineOS_FLAG_ACCEPT_EN 1u 47 #defineOS_FLAG_DEL_EN 1u 48 #defineOS_FLAG_NAME_EN 1u 49 #defineOS_FLAG_QUERY_EN 1u 50 #defineOS_FLAG_WAIT_CLR_EN 1u 51 #defineOS_FLAGS_NBITS 16u 52
第45~51行為事件標志組相關的宏定義,第45~50行的宏定義值均為1,各行的含義依次為事件標志組可用、函數(shù)OSFlagAccept可用、函數(shù)OSFlagDel可用、可為事件標志組命名、函數(shù)OSFlagQuery可用、等待清除事件標志的代碼有效;上述各行的宏定義值為0時,其含義剛好相反。第51行將事件標志OS_FLAGS類型宏定義為16位無符號整型。如果第45行的宏定義改為0,則事件標志組被裁剪掉了,于是第46~51行無效。5.1
μC/OS-Ⅱ系統(tǒng)任務 53 #defineOS_MBOX_EN 1u 54 #defineOS_MBOX_ACCEPT_EN 1u 55 #defineOS_MBOX_DEL_EN 1u 56 #defineOS_MBOX_PEND_ABORT_EN 1u 57 #defineOS_MBOX_POST_EN 1u 58 #defineOS_MBOX_POST_OPT_EN 1u 59 #defineOS_MBOX_QUERY_EN 1u 60
第53~59行為消息郵箱相關的宏定義,各行的宏定義值均為1,其含義依次為:消息郵箱可用、函數(shù)OSMboxAccept可用、函數(shù)OSMboxDel可用、函數(shù)OSMboxPendAbort可用、函數(shù)OSMboxPost可用以及函數(shù)OSMboxQuery可用;如果各行的宏定義值為0,則含義剛好相反。如果第53行的宏定義值為0,則消息郵箱被裁剪掉了,于是第54~59行無效。5.1
μC/OS-Ⅱ系統(tǒng)任務 61 #defineOS_MEM_EN 1u 62 #defineOS_MEM_NAME_EN 1u 63 #defineOS_MEM_QUERY_EN 1u 64
第61~63行為存儲管理相關的宏定義,各行的宏定義值均為1,依次表示:存儲管理組件可用、可為內存分區(qū)命名以及函數(shù)OSMemQuery可用;如果各行的宏定義值為0,含義剛好相反。如果第61行的宏定義值為0,則存儲管理組件被裁剪掉了,則第62~63行無效。 65 #defineOS_MUTEX_EN 1u 66 #defineOS_MUTEX_ACCEPT_EN 1u 67 #defineOS_MUTEX_DEL_EN 1u 68 #defineOS_MUTEX_QUERY_EN 1u 69
第65~68行為互斥信號量相關的宏定義,各行的宏定義值均為1,依次為:互斥信號量組件可用、函數(shù)OSMutexAccept可用、函數(shù)OSMutexDel可用以及函數(shù)OSMutexQuery可用;如果各行的宏定義值為0,則含義剛好相反。如果第65行的宏定義值為0,則互斥信號量被從系統(tǒng)中裁剪掉了,于是第66~68行無效。5.1
μC/OS-Ⅱ系統(tǒng)任務 70 #defineOS_Q_EN 1u 71 #defineOS_Q_ACCEPT_EN 1u 72 #defineOS_Q_DEL_EN 1u 73 #defineOS_Q_FLUSH_EN 1u 74 #defineOS_Q_PEND_ABORT_EN 1u 75 #defineOS_Q_POST_EN 1u 76 #defineOS_Q_POST_FRONT_EN 1u 77 #defineOS_Q_POST_OPT_EN 1u 78 #defineOS_Q_QUERY_EN 1u 79
第70~78行為消息隊列相關的宏定義,各行的宏定義值均為1,依次表示:消息隊列組件可用、函數(shù)OSQAccept可用、函數(shù)OSQDel可用、函數(shù)OSQFlush可用、函數(shù)OSQPendAbort可用、函數(shù)OSQPost可用、函數(shù)QPostFront可用、函數(shù)OSQPostOpt可用以及函數(shù)OSQQuery可用;當各行的宏定義值為0時,含義剛好與上述相反。當?shù)?0行的宏定義值為0時,消息隊列組件被從系統(tǒng)中裁剪掉,則第71~78行無效。5.1
μC/OS-Ⅱ系統(tǒng)任務
80 #defineOS_SEM_EN 1u 81 #defineOS_SEM_ACCEPT_EN 1u 82 #defineOS_SEM_DEL_EN 1u 83 #defineOS_SEM_PEND_ABORT_EN 1u 84 #defineOS_SEM_QUERY_EN 1u 85 #defineOS_SEM_SET_EN 1u 86
第80~85行為信號量相關的宏定義,各行的宏定義值均為1,依次表示:信號量組件可用、函數(shù)OSSemAccept可用、函數(shù)OSSemDel可用、函數(shù)OSSemPendAbort可用、函數(shù)OSSemQuery可用以及函數(shù)OSSemSet可用;如果各行的宏定義值為0,則含義剛好相反。如果第80行的宏定義值為0,則信號量被從系統(tǒng)中裁剪掉了,于是第81~85行均無效。 87 #defineOS_TIME_DLY_HMSM_EN 1u 88 #defineOS_TIME_DLY_RESUME_EN 1u 89 #defineOS_TIME_GET_SET_EN 1u 90 #defineOS_TIME_TICK_HOOK_EN 1u 91
第87~90行為延時管理相關的宏定義,各行的宏定義值為1,依次表示:函數(shù)OSTimeDlyHMSM可用、函數(shù)OSTimeDlyResume可用、函數(shù)OSTimeGet和OSTimeSet可用以及函數(shù)OSTimeTickHook可用;如果各行的宏定義值為0,則其含義剛好相反。5.1
μC/OS-Ⅱ系統(tǒng)任務 92 #defineOS_TMR_EN 1u 93 #defineOS_TMR_CFG_MAX 16u 94 #defineOS_TMR_CFG_NAME_EN 1u 95 #defineOS_TMR_CFG_WHEEL_SIZE 8u 96 #defineOS_TMR_CFG_TICKS_PER_SEC 10u 97 98 #endif 第92~96行為定時器管理相關的宏定義,第92行OS_TMR_EN為1表示使用定時器任務;為0表示關閉定時器任務。第93行OS_TMR_CFG_MAX用于設置最大可創(chuàng)建的定時器個數(shù),缺省值為16。第94行OS_TMR_CFG_NAME_EN為1表示可為定時器命名。第95行OS_TMR_CFG_WHEEL_SIZE表示定時器盤的個數(shù),默認值為8。第96行OS_TMR_CFG_TICKS_PER_SEC表示定時器的頻率,默認值為10Hz。 下面將os_cfg.h文件中常用的配置宏列在表5-2中。表5-2請看下頁5.1
μC/OS-Ⅱ系統(tǒng)任務表5-2 針對LPC824的μC/OSⅡ系統(tǒng)常用配置5.1
μC/OS-Ⅱ系統(tǒng)任務5.1
μC/OS-Ⅱ系統(tǒng)任務 按表5-2中的配置,工程中最多可創(chuàng)建的用戶任務數(shù)為20個,優(yōu)先級號取值為4~23(優(yōu)先級號0~3預留給優(yōu)先級繼承優(yōu)先級號),μC/OS-Ⅱ自動把OS_LOWEST_PRIO(這里為26)設置為空閑任務的優(yōu)先級號,把OS_LOWEST_PRIO1(這里為25)設置為統(tǒng)計任務的優(yōu)先級號(如果統(tǒng)計任務有效)。在工程中,把定時器任務的優(yōu)先級號定義為24,其他用戶任務的優(yōu)先級號為4~23。在μC/OS-Ⅱ中要求每個任務有獨一無二的優(yōu)先級號,且滿足OS_MAX_TASKS≤OS_LOWEST_PRIO1,優(yōu)先級號的最大值為254,可見,表5-2中的定義滿足這些要求。 在μC/OS-Ⅱ中,優(yōu)先級號值越小,優(yōu)先級越高,因此,優(yōu)先級號為0的任務優(yōu)先級最高,優(yōu)先級號為OS_LOWEST_PRIO的空閑任務優(yōu)先級最低,而由于統(tǒng)計任務的優(yōu)先級號固定為OS_LOWEST_PRIO1,因此統(tǒng)計任務的優(yōu)先級只比空閑任務高。μC/OS-Ⅱ要求每個任務具有獨立的堆棧空間,由于LPC824片上RAM空間為8KB,而每個任務的堆棧一般要在200B以上,且μC/OSⅡ系統(tǒng)占用了一定數(shù)量的RAM空間(3KB左右),因此,LPC824最大可容納20個用戶任務。5.1
μC/OS-Ⅱ系統(tǒng)任務5.1.2 空閑任務
μC/OS-Ⅱ具有3個系統(tǒng)任務,即空閑任務、統(tǒng)計任務和定時器任務,統(tǒng)計任務用于統(tǒng)計CPU的使用率和各個任務的堆棧使用情況,定時器任務用于創(chuàng)建系統(tǒng)定時器,而空閑任務是當所有其他任務均沒有使用CPU時,空閑任務占用CPU,因此,空閑任務是μC/OSⅡ中優(yōu)先級最低的任務,該任務實現(xiàn)的工作為:每執(zhí)行一次空閑任務,系統(tǒng)全局變量OSIdleCtr自增1;每次空閑任務的執(zhí)行都將調用一次鉤子函數(shù)OSTaskIdleHook,用戶可以通過該鉤子函數(shù)擴展功能。5.1
μC/OS-Ⅱ系統(tǒng)任務5.1.3 統(tǒng)計任務 統(tǒng)計任務的優(yōu)先級號固定為OS_LOWEST_PRIO-1,僅比空閑任務的優(yōu)先級高,對于μC/OS-ⅡV2.91而言,每0.1秒執(zhí)行統(tǒng)計任務一次,將統(tǒng)計這段時間內空閑任務運行的時間,用OSIdleCtr表示,用該數(shù)值與0.1秒時間內只有空閑任務運行時的OSIdleCtr的值(用OSIdleCtrMax表示,在OSStatInit函數(shù)中統(tǒng)計到該值)相比,即得到這0.1秒時間內的CPU空閑率,1減去CPU空閑率的差為CPU使用率。 當需要查詢某個任務的堆棧使用情況時,必須在創(chuàng)建這個任務時把它的堆棧內容全部清零,這樣,統(tǒng)計任務在統(tǒng)計每個任務的堆棧使用情況時,統(tǒng)計其堆棧中不為0的元素個數(shù),該值為其堆棧使用的長度,堆??傞L度減去前者即得到該任務的空閑空間長度。 當程序段51的第40行OS_TASK_STAT_EN為1時,則開啟μC/OS-Ⅱ統(tǒng)計任務功能。此時需要在第一個用戶任務的無限循環(huán)體前面插入語句“OSStatInit();”以初始化統(tǒng)計任務,并且要求使用函數(shù)OSTaskCreateExt創(chuàng)建用戶任務,最后一個參數(shù)使用“OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR”。統(tǒng)計任務可以統(tǒng)計用戶任務的CPU占用率以及各個用戶任務的堆棧占用情況。 一般地,在第一個用戶任務中顯示CPU使用率和用戶任務堆棧占用情況,CPU使用率保存在一個系統(tǒng)全局變量OSCPUUsage中,其值為0~100的整數(shù),如果為5,則表示CPU使用率為5%。
5.1
μC/OS-Ⅱ系統(tǒng)任務
當查詢某個任務的堆棧使用情況時,需要定義結構體變量類型OS_STK_DATA的變量,然后調用函數(shù)OSTaskStkChk,該函數(shù)有兩個參數(shù),第一個為任務優(yōu)先級號,第二個為指向OS_STK_DATA變量的指針。例如, OS_STK_DATA StkData;
OSTaskStkChk(2,&StkData);則將優(yōu)先級號為2的任務的堆棧使用情況保存在StkData變量中,其中,StkData.OSFree為該任務空閑的堆棧大小,StkData.OSUsed為該任務使用的堆棧大小,單位為字節(jié)。5.1
μC/OS-Ⅱ系統(tǒng)任務5.1.4 定時器任務 根據(jù)表5-2所示的配置方式,在后續(xù)的工程中將定時器任務的優(yōu)先級號配置為24。定時器任務屬于系統(tǒng)任務,由μC/OS-Ⅱ系統(tǒng)提供,它的主要作用在于創(chuàng)建軟定時器(或稱系統(tǒng)定時器)。程序段5-1中第93行宏定義了常量OS_TMR_CFG_MAX為16,表示最多可以創(chuàng)建16個軟定時器,因為軟定時器占用RAM空間較多,所以本書建議僅創(chuàng)建6個軟定時器。但是,μC/OS-Ⅱ定時器任務可創(chuàng)建的軟定時器數(shù)量僅受軟定時器數(shù)據(jù)類型的限制,對于16位無符號整型而言,可創(chuàng)建多達65536個軟定時器。 創(chuàng)建軟定時器的步驟為: (1)定義一個軟定時器,例如:“OS_TMR*Timer01;”;然后定義該軟定時器的回調函數(shù),例如:“voidTimer01Func(void*ptmr,void*callback_arg);”,回調函數(shù)是指軟定時器定時完成后將自動調用的函數(shù),一般地在該函數(shù)中釋放信號量或消息郵箱,激活某個用戶任務去執(zhí)行特定的功能。
(2)調用OSTmrCreate函數(shù)創(chuàng)建該軟定時器,例如: Timer01=OSTmrCreate(10,10,OS_TMR_OPT_PERIODIC, Timer01Func,(void*)0,“UserTimer01”,&err);5.1
μC/OS-Ⅱ系統(tǒng)任務
OSTmrCreate函數(shù)有7個參數(shù),依次為:初次定時延時值、定時周期值、定時方式、回調函數(shù)、回調函數(shù)參數(shù)、定時器名稱和出錯信息碼。初次定時延時值,表示第一次定時結束時要經歷的時間;定時周期值表示周期性定時器的定時周期。這里都為10,由于定時器的頻率為10Hz,因此,10表示1秒。定時方式有兩種,即周期型定時OS_TMR_OPT_PERIODIC和單拍型定時OS_TMR_OPT_ONE_SHOT,后者定時器僅執(zhí)行一次,延時時間為其第一個參數(shù),此時,第二個參數(shù)無效,所以,回調函數(shù)將僅被執(zhí)行一次。
(3)軟定時器的動作主要有:啟動軟定時器,如“OSTmrStart(Timer01,&err);”;停止定時器,停止定時器函數(shù)原型為: OSTmrStop(OS_TMR*ptmr,INT8Uopt,void*callback_arg,INT8U*perr); 上述函數(shù)的四個參數(shù)依次為:定時器、定時器停止后是否調用回調函數(shù)的選項、傳遞給回調函數(shù)的參數(shù)和出錯信息碼。當opt為OS_TMR_OPT_NONE時,不調用回調函數(shù);當為OS_TMR_OPT_CALLBACK,定時器停止時調用回調函數(shù),使用原回調函數(shù)的參數(shù);當為OS_TMR_OPT_CALLBACK_ARG時,定時器停止時調用回調函數(shù),但使用OSTmrStop函數(shù)中指定的參數(shù)callback_arg。
5.1
μC/OS-Ⅱ系統(tǒng)任務 (4)可獲得軟定時器的狀態(tài),例如, INT8UTimer01State;
Timer01State=OSTmrStateGet(Timer01,&err);上述代碼將返回定時器Timer01當前的狀態(tài),如果定時器沒有創(chuàng)建,則返回常量OS_TMR_STATE_UNUSED;如果定時器處于運行態(tài),返回常量OS_TMR_STATE_RUN-NING;如果定時器處于停止狀態(tài),則返回常量OS_TMR_STATE_STOPPED。
(5)當定時到期時,將自動調用定時器的回調函數(shù),一般地,不允許在回調函數(shù)中放置耗時較多的數(shù)據(jù)處理代碼,通?;卣{函數(shù)只有幾行代碼,用于釋放信號量或消息郵箱。5.1
μC/OS-Ⅱ系統(tǒng)任務5.2.1 信號量 信號量的工作原理如圖5-1所示。圖5-1 信號量工作原理 由圖5-1可知,借助于信號量,任務X可以同步另一個任務A的執(zhí)行,也可同步中斷服務程序的執(zhí)行。信號量本質上是一個全局的計數(shù)器變量,當任務A釋放該信號量時,信號量S的值自增1,任務A周期性地釋放信號量S,則S的值周期性地自增1;任務X始終請求信號量S,如果S的值大于0,表示信號量有效,任務X將請求成功,之后信號量S的值自減1,當信號量S的值為0時,表示無信號量,則任務X需等待,直到某個任務A釋放信號量S,使S的值大于0。5.2
信號量與互斥信號量 中斷服務程序可以釋放信號量。當某一個中斷到來后,其中斷服務程序得到執(zhí)行,一般地,中斷服務程序不應包括太多的處理代碼,而應該通過釋放信號量,使請求該信號量的任務就緒去執(zhí)行與該中斷相關的操作。 信號量相關的主要操作有:創(chuàng)建信號量OSSemCreate、請求信號量OSSemPend和釋放信號量OSSemPost。使用信號量的步驟為: (1)定義事件,如:“OS_EVENT*Sem01;”。
(2)創(chuàng)建信號量,如“Sem01=OSSemCreate(0);”,此時,創(chuàng)建了信號量Sem01,信號量的初始值為0。
(3)在任務A中周期性地釋放該信號量,調用“OSSemPost(Sem01);”實現(xiàn)。
(4)在任務X中請求該信號量,用“OSSemPend(Sem01,0,&err);”實現(xiàn),該函數(shù)的第二個參數(shù)表示等待超時,如果為0,表示請求不到信號量時永久等待;如果為大于0的整數(shù),則任務X等待該整數(shù)值的時鐘節(jié)拍后,仍然沒有請求到信號量時,則不再等待而繼續(xù)執(zhí)行。 信號量還支持多對一的同步,如圖5-2所示。5.2
信號量與互斥信號量圖5-2 多個任務同步一個任務的情況
圖5-2所示情況下,任務X、Y、Z的執(zhí)行將受任務A的控制,每個任務請求到信號量后,應延時一段時間再繼續(xù)請求,否則,將只有任務優(yōu)先級最高的任務與任務A同步。當任務X、Y和Z請求到信號量后,需要訪問共享資源,則有可能導致死鎖。這種情況下需要使用互斥信號量。5.2
信號量與互斥信號量5.2.2 互斥信號量 當有多個任務因為使用同一個共享資源而請求同一個信號量時,可能會造成死鎖,互斥信號量可以有效地解決死鎖問題,保證某個任務對共享資源的獨占式訪問,即當某個任務訪問共享資源時,其他要訪問共享資源的任務(無論其優(yōu)先級比當前任務高還是低)需要等到該任務使用完共享資源后再進行訪問。其工作原理為:當?shù)蛢?yōu)先級的任務請求到互斥信號量而使用共享資源時將臨時提升該任務的優(yōu)先級,使其略高于全部要請求互斥信號量的任務的優(yōu)先級,這種現(xiàn)象稱為優(yōu)先級提升或優(yōu)先級反轉,提升后的優(yōu)先級稱為優(yōu)先級繼承優(yōu)先級(PIP)。當該任務使用完共享資源后,其優(yōu)先級將還原為原來的優(yōu)先級。 互斥信號量的工作情況如圖5-3所示。圖5-3 互斥信號量使用情況5.2
信號量與互斥信號量 互斥信號量只有0和1兩個值,表示兩種狀態(tài),即互斥信號量被占用和未被占用。如圖5-3所示,某一任務X需要使用共享資源時,首先需要請求互斥信號量M,如果沒有請求到,說明共享資源被其他任務正在使用;如果請求到M,則優(yōu)先級反轉到比其他要請求該共享資源的所有任務的優(yōu)先級略高的優(yōu)先級繼承優(yōu)先級,任務X使用完共享資源后,釋放互斥信號量M??梢?互斥信號量的請求和釋放是在同一個任務中實現(xiàn)的。 使用互斥信號量的步驟如下: (1)定義事件,如“OS_EVENT*Mutex01;”。
(2)定義優(yōu)先級繼承優(yōu)先級(PIP)的值PIP_Prio,PIP的數(shù)值應比所有請求同一共享資源的任務的優(yōu)先級號數(shù)值要小。
(3)創(chuàng)建互斥信號量,如“Mutex01=OSMutexCreate(PIP_Prio,&err);”。
(4)如果某一任務X要使用共享資源,應先調用OSMutexPend函數(shù)請求互斥信號量,如“OSMutexPend(Mutex01,0,&err);”;請求到互斥信號量之后,開始使用共享資源,使用完后再調用OSMutexPost函數(shù)釋放互斥信號量,如“OSMutexPost(Mutex01);”。函數(shù)OSMutexPend的第2個參數(shù)為等待超時參數(shù),如果為0,表示請求不到互斥信號量時,一直等待;如果為大于0的整數(shù),表示等待該整數(shù)值的時鐘節(jié)拍后,仍然請求不到互斥信號量時,則放棄等待。5.2
信號量與互斥信號量5.3.1 消息郵箱
共享資源可以實現(xiàn)任務間的數(shù)據(jù)通信,共享資源是指所有任務均可以訪問但是某一時刻僅能有一個任務訪問和使用的資源。使用共享資源進行任務間的通信,容易造成數(shù)據(jù)混亂和死鎖。消息郵箱是一種借助共享資源的訪問機制,使用消息郵箱可以安全地實現(xiàn)任務間的數(shù)據(jù)通信。消息郵箱的基本原理為:借助全局的一維數(shù)組變量V,在某一任務A中,將消息釋放到該數(shù)組V中,V即所謂的消息郵箱,另一任務X始終在請求消息郵箱V,當發(fā)現(xiàn)郵箱中有消息時,將消息接收到任務X中。消息郵箱常用的函數(shù)如表5-3所示。表5-3 消息郵箱的常用函數(shù)5.3
消息郵箱與消息隊列 消息郵箱的工作情況如圖5-4所示。圖5-4 消息郵箱的工作情況 由圖5-4可知,任務和中斷服務程序可以釋放消息,只有任務才能請求消息,郵箱中僅能存放一條消息,如果釋放消息的速度比請求消息的速度快,則原來的消息將丟失??梢酝ㄟ^廣播的方式,使得釋放的消息傳遞給所有請求該消息郵箱的任務。如果當前郵箱為空,且有某一任務X正在請求郵箱,則當另一任務A向郵箱中釋放消息時,釋放的消息將直接送給任務X,而不用經過郵箱中轉。如果使用啞元消息(如(void*)1),可以實現(xiàn)一對一或多對一的同步,此時消息郵箱與信號量的作用相同。但是,用作同步,消息郵箱比信號量的速度慢。5.3
消息郵箱與消息隊列 消息郵箱的用法如下:
(1)定義事件,如“OS_EVENT*Mbox01;”。
(2)定義全局一維數(shù)組保存消息,如“INT8UMessage[80];”。
(3)創(chuàng)建消息郵箱,如“Mbox01=OSMboxCreate(NULL);”,NULL參數(shù)表示創(chuàng)建的郵箱中沒有消息。
(4)在某一個任務A中釋放消息,如:“OSMboxPost(Mbox01,(void*)Message);”,如果發(fā)送的消息為“Msg:A-X”,則需要事先將該消息存在Message中,可以使用“strcpy((char*)Message,"Msg:A-X");”。
(5)在另一個任務X中請求消息,如“pmsg=OSMboxPend(Mbox01,0,&err);”,這里的pmsg為“void*”類型的任務局部變量,這樣,消息“Msg:A-X”就從任務A傳遞到任務X中來。5.3
消息郵箱與消息隊列5.3.2 消息隊列 消息隊列可以視為消息郵箱的數(shù)組形式,消息郵箱一次只能傳遞一則消息,而消息隊列可以一次傳遞多則消息。因此,消息郵箱是消息隊列的一種特例。消息隊列的工作情況如圖5-5所示。圖5-5 消息隊列的工作情況 由圖5-5可知,任務和中斷服務程序可以向消息隊列中釋放消息,只有任務才能從消息隊列中請求消息,任務可以始終請求消息,也可周期性地請求消息。消息隊列具有一定的長度,其長度為可包含的消息個數(shù),如果向隊列中釋放消息的速度大于從隊列中請求消息的速度,那么消息、隊列將溢出。 在μC/OS-ⅡV2.91中,消息隊列相關的管理函數(shù)約有10個,常用的5個列于表5-4中。表5-4請看下頁5.3
消息郵箱與消息隊列表5-4 常用的消息隊列管理函數(shù)5.3
消息郵箱與消息隊列 消息隊列的使用方法如下: (1)定義事件,如“OS_EVENT*Queue01;”。
(2)定義一維指針數(shù)組,如“void*QMessage[10];”;定義全局二維數(shù)組存放隊列中的消息,如“INT8UQMsg[10][80];”。
(3)創(chuàng)建消息隊列,如“Queue01=OSQCreate(&QMessage[0],10);”,這里創(chuàng)建了一個長度為10的消息隊列。
(4)在某一任務A中,向隊列中釋放消息,如“OSQPost(Queue01,(void*)&QMsg[0][0];”。
(5)在另一任務X中,向隊列請求消息,如“pmsg=OSQPend(Queue01,0,&err);”,這里pmsg為“void*”類型的局部變量,指向請求到的消息。 消息隊列和消息郵箱一樣,是一種任務間的通信機制,需要借助于全局變量實現(xiàn)。
5.3
消息郵箱與消息隊列 事件標志組是一種比信號量更加靈活的任務間同步方式,可以實現(xiàn)多個任務間的同步控制。事件標志是OS_FLAGS類型的變量(默認為16位無符號整型)。事件標志組的事件釋放就是使事件標志中的某些位為1、某些位為0,而請求事件標志組,按一定的規(guī)則,查詢某些位為1或某些位為0,如果滿足特定的條件,則請求成功;否則等待。事件標志組的工作原理如圖5-6所示。圖5-6 事件標志組工作情況
5.4
事件標志組
從圖5-6可知,任務和中斷服務程序可以向事件標志組中釋放事件標志,只有任務才能請求事件標志組。如果圖5-6所示的為一種事件標志的模式,則該請求規(guī)則為0x2912,即標注為1的位置的位的值為1。只考慮其各位為1或其組合情況下的事件標志,就可以有216-1種規(guī)則(有些規(guī)則不互斥,例如,0x000B包含0x000A等),這相當于216-1個信號量。常用的事件標志組函數(shù)如表5-5所示。表5-5 常用的事件標志組函數(shù)5.4
事件標志組 事件標志組的用法如下: (1)定義事件標志組,如“OS_FLAG_GRP*FlagGrp01;”。在μC/OS-Ⅱ中,信號量、消息郵箱和消息隊列共用事件類型OS_EVENT,在程序段51中第17行規(guī)定了最大事件數(shù)為10,表示信號量、消息郵箱和消息隊列的個數(shù)之和不能超過10個(而第20行還規(guī)定了消息隊列不能超過4個);而事件標志組
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣播電視線務員安全規(guī)程模擬考核試卷含答案
- 鐵渣處理工QC考核試卷含答案
- 水生植物病害防治員崗前設備巡檢考核試卷含答案
- 筒并搖工標準化強化考核試卷含答案
- 海克斯三坐標培訓課件
- 老年人入住老人關愛活動制度
- 城管協(xié)管培訓
- 酒店客房環(huán)境與設備維護制度
- 酒店安全消防管理制度
- 濟寧培訓班教學課件
- 2026.05.01施行的中華人民共和國漁業(yè)法(2025修訂)課件
- 原始股認購協(xié)議書
- 八年級數(shù)學人教版下冊第十九章《二次根式》單元測試卷(含答案)
- 嚴肅財經紀律培訓班課件
- (2025年)廣東省事業(yè)單位集中招聘筆試試題及答案解析
- 上海市復旦大學附中2026屆數(shù)學高一上期末質量檢測試題含解析
- 企業(yè)員工食堂營養(yǎng)搭配方案
- 2025年國家公務員國家能源局面試題及答案
- 智慧中藥房講解課件
- 固廢買賣居間合同范本
- 藥廠車間安全培訓記錄內容課件
評論
0/150
提交評論