任務(wù)堆棧:存儲(chǔ)任務(wù)中的調(diào)用的函數(shù)、局部變量、中斷服務(wù)程序和CPU寄存器的值。
全局變量的保護(hù):
1.如果只在一個(gè)任務(wù)中寫(或只有一個(gè)數(shù)據(jù)),而在其他任務(wù)中只是讀取,則可以不用互斥型信號(hào)量,最多會(huì)造成讀取的數(shù)據(jù)未被完全寫完。
2.如果全局變量在多個(gè)任務(wù)中寫,則需要用互斥型信號(hào)量保護(hù),這樣當(dāng)有任務(wù)申請(qǐng)到互斥型信號(hào)量(保護(hù)不可重入的程序段)寫數(shù)據(jù)時(shí),其他任務(wù)的同一個(gè)互斥型信號(hào)量必須等待上一個(gè)任務(wù)的釋放才可進(jìn)行寫。
3.如果全局變量在中斷中寫,則在其他任務(wù)中的全局變量的寫操作要用臨界段(禁止中斷和禁止調(diào)度:保護(hù)不可被分割的程序段)保護(hù)。(因?yàn)槿绻魂P(guān)中斷相當(dāng)于中斷的優(yōu)先級(jí)最高,而且不能被像其他任務(wù)那樣掛起。)
OS_CFG_ISR_POST_DEFERRED_EN為1臨界段使用鎖調(diào)度器方式;
為0臨界段使用禁中斷方式(CPU_SR_ALLOC();
OS_CRITICAL_ENTER();OS_CRITICAL_EXIT();
OS_CRITICAL_EXIT_NO_SCHED();
OSSchedLockNestingCtr記錄調(diào)度器被鎖的次數(shù))。
檢測(cè)任務(wù)堆棧的使用情況:
OS_CFG_STAT_TASK_STK_CHK_EN使能 OS_ERRerr; CPU_STK_SIZE stk_free; CPU_STK_SIZE stk_used; OSTaskStkChk(&TaskBStkTCB,&stk_free,&stk_used,&err); 中斷中使用OSIntEnter(); 和OSIntExit();是為了退出中斷后執(zhí)行中斷調(diào)度操作,如果中斷中并未用到OSSemPost();等系統(tǒng)函數(shù),則退出中斷服務(wù)程序后不需要進(jìn)行任務(wù)調(diào)度,就可以不在中斷服務(wù)程序中使用OSIntEnter(); 和OSIntExit();。
(有時(shí)候用:CPU_CRITICAL_ENTER();OSIntNestingCtr++; CPU_CRITICAL_EXIT();替代OSIntEnter();) 一、 變量類型 在cpu.h中是有關(guān)cpu變量的重新定義,還包括CPU_STK(CPU堆棧類型), 和CPU_STK_SIZE(CPU堆棧類型的大小)的定義,CPU_SR(CPU狀態(tài)寄存 器的定義)。 在os.h中是有關(guān)os類型的定義如OS_TCB(任務(wù)控制塊)、OS_SEM(信號(hào)量)、OS_MUTEX(互斥型信號(hào)量)、OS_MSG(消息)、OS_Q(消息隊(duì)列)、OS_ERR(系統(tǒng)錯(cuò)誤)等。 在cpu_core.h中是有關(guān)cpu的定義,如CPU_ERR、CPU_TS、CPU_TS_TMR等。 CPU_STK:typedef unsigned int堆棧的類型定義
OS_TCB:struct os_tcb任務(wù)控制塊的類型定義
OS_ERR:enum os_err錯(cuò)誤信息定義
CPU_TS:typedef unsigned int時(shí)間戳變量
CPU_TS_TMR:typedef unsigned int定時(shí)器變量
二、 全局變量 (OS_CFG_STAT_TASK_EN使能且調(diào)用了OSStatTaskCPUUsageInit(&err); 則開啟了統(tǒng)計(jì)任務(wù)的功能:可以統(tǒng)計(jì)CPU使用率等。) OSStatTaskCPUUsage:CPU的使用率(0—10000= 0.00-100.00%)
OSStatTaskCPUUsageMax:CPU的使用率最大值(0—10000= 0.00-100.00%)
OSTaskCtxSwCtr:任務(wù)切換次數(shù)的記錄變量
OSStatTaskCtr:已經(jīng)建立了的任務(wù)數(shù)
三、常用函數(shù)
一、OS_CORE.C (1)void OSInit() //系統(tǒng)初始化 (2)void OSIntEnter() //發(fā)生了一次中斷(中斷嵌套的逐層進(jìn)入) (3)void OSIntExit() //退出了一次中斷(中斷嵌套的逐層退出) (4)void OSSched() //系統(tǒng)進(jìn)行調(diào)度 (5)void OSSchedLock() //給調(diào)度器上鎖 (6)void OSSchedUnlock() //給調(diào)度器解鎖,成對(duì)使用 (7)void OSStart() //啟動(dòng)多任務(wù)過程,在啟動(dòng)之前必須調(diào)用OSInit(),并已建立一個(gè)任務(wù)。其中OSStartHighRdy()必須調(diào)用OSTaskSwHook(),并令OSRunning = TRUE. (8)void OS_Pend() //掛起任務(wù) (9)void OS_Post() //解掛任務(wù) (10)void OS_PendAbort() //取消掛起任務(wù) (11)INT16UOSVersion () //返回uc/os的版本號(hào)*10000 (12)void OS_IdleTaskInit() //空閑任務(wù)初始化 (13)void OS_IdleTask() //空閑任務(wù) 二、OS_TASK.C (1)void OSTaskCreate(OS_TCB *p_tcb,//任務(wù)控制塊 CPU_CHAR *p_name,//任務(wù)名 OS_TASK_PTR p_task,//任務(wù)函數(shù)指針 void *p_arg,//任務(wù)函數(shù)參數(shù) OS_PRIO prio,//任務(wù)優(yōu)先級(jí) CPU_STK *p_stk_base,//堆棧指針 CPU_STK_SIZE stk_limit,//任務(wù)的堆棧剩余警戒線 CPU_STK_SIZE stk_size,//任務(wù)的空間大小 OS_MSG_QTY q_size, //能接收的信息隊(duì)列最大值 OS_TICK time_quanta,//時(shí)間片輪轉(zhuǎn)時(shí)間 void *p_ext,// 任務(wù)控制塊的擴(kuò)展信息 OS_OPT opt, //任務(wù)的選項(xiàng) OS_ERR *p_err) //任務(wù)的錯(cuò)誤信息 (2)void OSTaskChangePrio() //任務(wù)優(yōu)先級(jí)別的改變 (3)void OSTaskDel() //任務(wù)的刪除 (4)void OSTaskSuspend() //任務(wù)的暫停 (5)void OSTaskResume() //任務(wù)的恢復(fù) (6)void OSTaskStkChk() //校核空余內(nèi)存的數(shù)量 (7)OS_MSG_QTY OSTaskQFlush() //清空任務(wù)級(jí)消息隊(duì)列中的消息 (8)void *OSTaskQPend() //掛起任務(wù)級(jí)消息隊(duì)列 (9)CPU_BOOLEAN OSTaskQPendAbort()//取消任務(wù)級(jí)消息隊(duì)列的掛起狀態(tài) (10)void OSTaskQPost() //向任務(wù)級(jí)消息隊(duì)列中發(fā)送消息 (11)OS_REG OSTaskRegGet() //獲取任務(wù)寄存器的當(dāng)前值 (12)void OSTaskRegSet() //設(shè)置任務(wù)寄存器的當(dāng)前值 (13)OS_SEM_CTR OSTaskSemPend() //任務(wù)信號(hào)量等待信號(hào) (14)CPU_BOOLEAN OSTaskSemPendAbort()//任務(wù)信號(hào)量取消掛起狀態(tài) (15)OS_SEM_CTR OSTaskSemPost() //任務(wù)信號(hào)量發(fā)送消息 (16)OS_SEM_CTR OSTaskSemSet() //設(shè)置任務(wù)信號(hào)量的計(jì)數(shù)值 (17)void OSTaskTimeQuantaSet() //改變?nèi)蝿?wù)的時(shí)間片
voidTaskMain(void *pdata); //任務(wù)聲明 static OS_TCB TaskMainTCB; //任務(wù)控制塊 #define TASK_MAIN_PRIO 3 //任務(wù)優(yōu)先級(jí) #define TASK_MAIN_STK_SIZE 256 //任務(wù)堆棧大小256*4=1024B static CPU_STK TaskMainStk[TASK_MAIN_STK_SIZE];//任務(wù)堆棧定義 OSTaskCreate((OS_TCB *)&TaskMainTCB, //任務(wù)的控制塊 (CPU_CHAR *)"Task Main Start", //任務(wù)的名稱 (OS_TASK_PTR )TaskMain, //任務(wù)的函數(shù)指針 (void *)0, //任務(wù)的函數(shù)初值 (OS_PRIO )TASK_MAIN_PRIO, //任務(wù)的優(yōu)先級(jí) (CPU_STK *)&TaskMainStk[0], //任務(wù)的堆棧 (CPU_STK_SIZE)TASK_MAIN_STK_SIZE/10,//任務(wù)的堆棧剩余警戒線 (CPU_STK_SIZE)TASK_MAIN_STK_SIZE,//任務(wù)的空間大小 (OS_MSG_QTY )0, //所能接收的信息隊(duì)列最大值 (OS_TICK )0, //任務(wù)的時(shí)間片輪轉(zhuǎn)時(shí)間 (void *)0, //任務(wù)的任務(wù)控制塊的擴(kuò)展信息 (OS_OPT )(OS_OPT_TASK_STK_CHK| OS_OPT_TASK_STK_CLR), //任務(wù)的選項(xiàng) (OS_ERR *)&err); //任務(wù)的錯(cuò)誤信息 三、OS_TIME.C (1)void OSTimeDly() //以時(shí)鐘節(jié)拍數(shù)為單位延時(shí) (2)void OSTimeDlyHMSM() //用時(shí)、分、秒、毫秒為單位延時(shí) (3)void OSTimeDlyResume() //取消任務(wù)中的延時(shí),引發(fā)一次調(diào)度 (4)OS_TICKOSTimeGet() //獲取OSTime 值 (5)void OSTimeSet() //設(shè)置 OSTime 值 四、OS_SEM.C (1)void OSSemCreate() //創(chuàng)建信號(hào)量 (2)OS_OBJ_QTY OSSemDel() //刪除信號(hào)量 (3)OS_SEM_CTR OSSemPend() //請(qǐng)求信號(hào)量 (4)OS_SEM_CTR OSSemPost() //發(fā)送(釋放)信號(hào)量 (5)void OSSemSet() //設(shè)置信號(hào)量的計(jì)數(shù)值 (6)OS_OBJ_QTYOSSemPendAbort() //取消信號(hào)量
static OS_SEM AppSem; //定義一個(gè)信號(hào)量變量 CPU_TS ts=0;//存放發(fā)送消息時(shí)的時(shí)間戳OS_TS_GET();(獲取當(dāng)前時(shí)間戳) OS_ERR err; //返回的錯(cuò)誤信息 OSSemCreate(&AppSem,"Test Sem", 0, &err);//要在使用之前創(chuàng)建(如果在兩個(gè)任務(wù)中都用到,則最好在兩個(gè)任務(wù)創(chuàng)建前建立,也可在優(yōu)先級(jí)高的任務(wù)中建立) OSSemPend(&AppSem,0,OS_OPT_PEND_BLOCKING,&ts,&err);//等待信號(hào)量(ts為發(fā)送信號(hào)量的時(shí)間戳) OSSemPost(&AppSem, OS_OPT_POST_1,&err);//發(fā)送信號(hào)量 五、OS_FLAG.C (1)void OSFlagCreate() //信號(hào)標(biāo)志組的創(chuàng)建函數(shù) (2)OS_OBJ_QTY OSFlagDel() //刪除信號(hào)標(biāo)志組 (3)OS_FLAGS OSFlagPend() //掛起信號(hào)標(biāo)志組 (4)OS_FLAGS OSFlagPost() //向信號(hào)標(biāo)志組發(fā)送信號(hào) (5)OS_OBJ_QTYOSFlagPendAbort() //取消掛起信號(hào)標(biāo)志組
staticOS_FLAG_GRP AppFlag; //定義一個(gè)信號(hào)標(biāo)志組變量 CPU_TSts=0; //存放發(fā)送消息時(shí)的時(shí)間戳OS_TS_GET();(獲取當(dāng)前時(shí)間戳) OS_ERRerr; //返回的錯(cuò)誤信息 OSFlagCreate(&AppFlag,"TestFlag",0x00,&err);//創(chuàng)建信號(hào)標(biāo)志組且設(shè)置初值為0x00 OSFlagPend(&AppFlag,0x03,0,OS_OPT_PEND_FLAG_SET_ALL,&ts,&err); //等待信號(hào)標(biāo)志組的bit0和bit1都為1 OSFlagPost(&AppFlag,0x01,OS_OPT_POST_FLAG_SET,&err); //把信號(hào)標(biāo)志組的bit0設(shè)置為1 六、OS_MUTEX.C (1)void OSMutexCreate() //創(chuàng)建互斥型信號(hào)量 (2)OS_OBJ_QTY OSMutexDel() //刪除互斥型信號(hào)量 (3)void OSMutexPend() //請(qǐng)求互斥型信號(hào)量 (4)void OSMutexPost() //發(fā)送(釋放)互斥型信號(hào)量 (5)OS_OBJ_QTYOSMutexPendAbort() //取消互斥型信號(hào)量 static OS_MUTEX AppMutex; //定義一個(gè)互斥型信號(hào)量變量 CPU_TS ts=0;//存放發(fā)送消息時(shí)的時(shí)間戳OS_TS_GET();(獲取當(dāng)前時(shí)間戳) OS_ERR err; //返回的錯(cuò)誤信息 OSMutexCreate(&AppMutex,"Test Mutex", &err);//創(chuàng)建互斥型信號(hào)量 OSMutexPend(&AppMutex, 0, OS_OPT_PEND_BLOCKING,&ts,&err); //互斥型信號(hào)量申請(qǐng)(阻塞方式) OSMutexPost(&AppMutex, OS_OPT_POST_NONE,&err); //互斥型信號(hào)量釋放 七、OS_Q.C (1)void OSQCreate() //創(chuàng)建一個(gè)消息隊(duì)列 (2)OS_OBJ_QTY OSQDel() //刪除消息隊(duì)列 (3)OS_MSG_QTY OSQFlush() //清空消息隊(duì)列 (4)void *OSQPend() //請(qǐng)求一個(gè)消息隊(duì)列 (6)void OSQPost() //向消息隊(duì)列發(fā)送消息 (6)OS_OBJ_QTYOSQPendAbort() //取消消息隊(duì)列的等待狀態(tài) 以指針和長(zhǎng)度的形式向其他任務(wù)發(fā)送消息,如果是阻塞方式則接收到的數(shù)據(jù)的次數(shù)等于發(fā)送的次數(shù)才會(huì)被阻塞。 static OS_Q AppQ; //定義一個(gè)消息隊(duì)列變量 u8sendq_a[2]={1,2}; //要發(fā)送的數(shù)據(jù) OSQCreate(&AppQ,"Test Q", 13, &err);//創(chuàng)建消息隊(duì)列包含存放消息的條數(shù) OSQPost(&AppQ,sendq_a,2, OS_OPT_POST_FIFO,&err);//發(fā)送數(shù)據(jù) OS_MSG_SIZEmsg_size=0; //接收到的數(shù)據(jù)的大小 CPU_TS ts=0; //發(fā)送數(shù)據(jù)時(shí)的時(shí)間戳 OS_ERRerr; u8 *req; //接收到的數(shù)據(jù)的地址 req=(u8*)OSQPend (&AppQ, 0, OS_OPT_PEND_BLOCKING, &msg_size,&ts,&err); //接收數(shù)據(jù)(阻塞方式,非阻塞方式是給中斷用的) 八、OS_MEM.C (1) void OSMemCreate() //創(chuàng)建一個(gè)固定大小的內(nèi)存分區(qū) (2)void *OSMemGet() //從分區(qū)中獲取一個(gè)內(nèi)存塊 (3)void OSMemPut() //返還一個(gè)內(nèi)存塊到分區(qū) 九、OS_TMR.C (1)void OSTmrCreate() //創(chuàng)建一個(gè)定時(shí)器,定時(shí)調(diào)用函數(shù) (2)CPU_BOOLEAN OSTmrDel() //刪除定時(shí)器 (3)OS_TICK OSTmrRemainGet() //定時(shí)器的剩余時(shí)間 (4)CPU_BOOLEAN OSTmrStart() //定時(shí)器開始計(jì)時(shí) (5)OS_STATE OSTmrStateGet() //獲取定時(shí)器的當(dāng)前狀態(tài)
(6)CPU_BOOLEAN OSTmrStop() //定時(shí)器停止計(jì)時(shí) |