目錄
一 建立任務
任務三要素:任務棧,任務控制塊,任務函數
OS_TCB StartTaskTCB; //任務控制塊
CPU_STK START_TASK_STK[128];//任務堆棧
void start_task(void *p_arg);//任務函數
任務創建函數OSTaskCreate各參數介紹如下:
void OSTaskCreate(OS_TCB *p_tcb, //任務控制塊
CPU_CHAR *p_name, //任務名字,字符串形式
OS_TASK_PTR p_task, //任務入口函數
void *p_arg, //任務入口函數形參,不用的時候配置爲 0 或者 NULL
OS_PRIO prio, //任務的優先級
CPU_STK *p_stk_base,//指向任務堆棧的基地址
CPU_STK_SIZE stk_limit, //設置堆棧深度的限制位置,一般設置爲堆棧大小的1/10
CPU_STK_SIZE stk_size, //任務堆棧大小
OS_MSG_QTY q_size, //可以發送到任務的最大消息數
OS_TICK time_quanta,//在任務之間循環時的時間片的時間量
void *p_ext, //是指向用戶提供的內存位置的指針,用作 TCB 擴展
OS_OPT opt, //用戶可選的任務特定選項,在os.h中搜索“TASK OPTIONS”
OS_ERR *p_err); //用於保存返回的錯誤代碼
創建一個簡單的任務,代碼如下:
#include "main.h"
#define START_TASK_PRIO 3 //任務優先級
#define START_STK_SIZE 128 //任務堆棧大小
OS_TCB StartTaskTCB; //任務控制塊
CPU_STK START_TASK_STK[START_STK_SIZE];//任務堆棧
void start_task(void *p_arg);//任務函數
void ucos_init(void)
{
OS_ERR err;
CPU_SR_ALLOC();//定義cpu_sr變量
OSInit(&err); //初始化 UCOSIII
OS_CRITICAL_ENTER(); //進入臨界區
//創建開始任務
OSTaskCreate((OS_TCB* )&StartTaskTCB, //任務控制塊
(CPU_CHAR* )"start task", //任務名字
(OS_TASK_PTR )start_task, //任務函數
(void* )0, //傳遞給任務函數的參數
(OS_PRIO )START_TASK_PRIO, //任務優先級
(CPU_STK* )&START_TASK_STK[0], //任務堆棧基地址
(CPU_STK_SIZE )START_STK_SIZE/10, //任務堆棧深度限位
(CPU_STK_SIZE )START_STK_SIZE, //任務堆棧大小
(OS_MSG_QTY )0, //任務內部消息隊列能夠接收
//的最大消息數目,爲 0 時禁止
//接收消息
(OS_TICK )0, //當使能時間片輪轉時的時間片長度,爲 0 時爲默認長度。
(void* )0, //用戶補充的存儲區
(OS_OPT ) OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|\
OS_OPT_TASK_SAVE_FP,
(OS_ERR* )&err); //存放該函數錯誤時的返回值
OS_CRITICAL_EXIT(); //退出臨界區
OSStart(&err); //開啓 UCOSIII
}
//開始任務函數
void start_task(void *p_arg)
{
while(1)
{
}
}
二 任務狀態切換圖
三 任務就緒表
任務就緒表有兩部分:優先級位映射表OSPrioTbl[]和就緒任務列表 OSRdyList[]。
優先級表OSPrioTbl:實際就是一個數組,其中OSPrioTbl[0]的bit31爲最高優先級,即優先級爲0,下面舉例說明:
OSPrioTbl[0] = 0xE000001 表示優先級爲4,5,6的任務正在等待執行,
當優先級爲4的任務執行完畢後,OSPrioTbl[0] = 0x6000001 .
就緒列表OSRdyList:在代碼的層面上看就是一個 OS_RDY_LIST 數據類型的數組 OSRdyList[],數組的大小由
宏 OS_CFG_PRIO_MAX 決定任務的優先級與 OSRdyList[]的索引一一對應,比如優先級 3 的任務的 TCB會被放到 OSRdyList[3]中。
四 時間片輪轉調度任務
要實現時間片輪轉調度需要滿足以下條件
- os_cfg.h中的OS_CFG_SCHED_ROUND_ROBIN_EN宏是否設置爲1
- 在新建任務的時候,爲任務設置time_quanta,該值表示該任務最多執行的時間段
- 調用 OSSchedRoundRobinCfg()函數來使能 UCOSIII的時間片功能
- 需要兩個同等優先級的任務
在程序設計的時候,我們設置的任務時間一般會大於執行任務的實際時間,所以我們在任務執行完成後,使用函數OSSchedRoundRobinYield可以立即切換到下一個需要執行的任務。
五 統計任務OS_StatTask
統計任務可用來統計 CPU 的使用率、各個任務的 CPU 使用率和各任務的堆棧使用情況,使用統計任務需要滿足以下條件:
- os_cfg.h中的OS_CFG_STAT_TASK_EN宏是否設置爲1
- 調用OSStatTaskCPUUsageInit()函數,需要統計的任務在該函數調用後進行創建。
- CPU 的使用率用一個0~10000 之間的整數表示,其中OSStatTaskCPUUsageMax報存了CPU歷史最大使用率,OSStatTaskCPUUsage保存了當前CPU使用率,OS_TCB中的CPUUsage成員保存了單個任務的CPU使用率。
- 將宏 OS_CFG_STAT_TASK_STK_CHK_EN 置 1 ,檢查任務堆棧使用情況將檢測結果
寫入到每個任務的 OS_TCB 中的 StkFree 和 StkUsed 中
六 任務相關的其他函數介紹
修改任務優先級 | OSTaskChangePrio | |
刪除任務 | OSTaskDel | OS_CFG_TASK_DEL_EN |
掛起任務 | OS_TaskSuspend | OS_CFG_TASK_SUSPEND_EN |
將掛起任務恢復 | OSTaskResume | OS_CFG_TASK_SUSPEND_EN |
設置某個任務的寄存器 | OSTaskRegSet | OS_CFG_TASK_REG_TBL_SIZE |
獲取某個任務的寄存器 | OSTaskRegGet | OS_CFG_TASK_REG_TBL_SIZE |
獲取任務堆棧使用情況 | OSTaskStkChk | OS_CFG_TASK_STAT_CHK_EN |
設置任務時間片 | OSTaskTimeQuantaSet | OS_CFG_SCHED_ROUND_ROBIN_EN |