?? os_task.c
字號:
/*
*********************************************************************************************************
* uC/OS-II 實時內核
* 任務管理
*
* (c) 版權 1992-2002, 所有版權歸Jean J. Labrosse, Weston, FL
*
*
* 文件名稱 : OS_TASK.C
* 程序作者 : Jean J. Labrosse
*********************************************************************************************************
*/
#ifndef OS_MASTER_FILE
#include "includes.h"
#endif
/*
*********************************************************************************************************
* 改變任務的優先級
*
* 程序描述: 本函數可以動態地改變任務的優先級。但是,新改變的優先級必須有效。
*
* 輸入參數: oldp 舊的優先級
*
* newp 新的優先級
*
* 返回值: OS_NO_ERR 調用成功
* OS_PRIO_INVALID 如果定義的優先級高于最大的許可范圍,則返回該參數
* (例如 >= OS_LOWEST_PRIO)
* OS_PRIO_EXIST 如果新的優先級已經存在,則返回該參數
* OS_PRIO_ERR 找不到舊的優先級對應的任務,則返回該參數 (例如 舊優先級的任務已不存在)
*
*********************************************************************************************************
*/
#if OS_TASK_CHANGE_PRIO_EN > 0
INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio)
{
#if OS_CRITICAL_METHOD == 3 /* 給CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
#if OS_EVENT_EN > 0
OS_EVENT *pevent;
#endif
OS_TCB *ptcb;
INT8U x;
INT8U y;
INT8U bitx;
INT8U bity;
#if OS_ARG_CHK_EN > 0
if ((oldprio >= OS_LOWEST_PRIO && oldprio != OS_PRIO_SELF) ||
newprio >= OS_LOWEST_PRIO)
{
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[newprio] != (OS_TCB *)0)
{ /* 新優先級是否已經存在? */
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
else
{
OSTCBPrioTbl[newprio] = (OS_TCB *)1; /* 保留該優先級避免其他處理 */
OS_EXIT_CRITICAL();
y = newprio >> 3; /* 預先計算減少中斷隱患 */
bity = OSMapTbl[y];
x = newprio & 0x07;
bitx = OSMapTbl[x];
OS_ENTER_CRITICAL();
if (oldprio == OS_PRIO_SELF)
{ /* 是否改變自身? */
oldprio = OSTCBCur->OSTCBPrio; /* 是,得到優先級 */
}
ptcb = OSTCBPrioTbl[oldprio];
if (ptcb != (OS_TCB *)0)
{ /* 待改變優先級的任務是否存在? */
OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* 從舊優先級中去除任務控制塊 */
if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) /* 如果任務就緒,讓其脫離就緒。 */
{
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00)
{
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
OSRdyGrp |= bity; /* 讓新的優先級就緒 */
OSRdyTbl[y] |= bitx;
#if OS_EVENT_EN > 0
}
else
{
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0)
{ /* 從事件等待列表中移除舊的優先級 */
if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
{
pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
}
pevent->OSEventGrp |= bity; /* 讓新的優先級加入等待列表 */
pevent->OSEventTbl[y] |= bitx;
}
#endif
}
OSTCBPrioTbl[newprio] = ptcb; /* 設置指向新優先級任務控制塊的指針 */
ptcb->OSTCBPrio = newprio; /* 設置新的任務優先級 */
ptcb->OSTCBY = y;
ptcb->OSTCBX = x;
ptcb->OSTCBBitY = bity;
ptcb->OSTCBBitX = bitx;
OS_EXIT_CRITICAL();
OS_Sched(); /* 運行就緒的最高優先級的任務 */
return (OS_NO_ERR);
}
else
{
OSTCBPrioTbl[newprio] = (OS_TCB *)0; /* 釋放保留的優先級 */
OS_EXIT_CRITICAL();
return (OS_PRIO_ERR); /* 改變任務的優先級不存在 */
}
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 創建任務
*
* 函數描述: 該函數用于 uC/OS-II 管理任務的執行。任務可在啟動多任務之前建立,也可在運行中的任務中建立。
* 任務不能在中斷服務子程序中建立。
*
* 輸入參數 : task 指向任務代碼的指針
*
* pdata 當任務首先執行時,指向能把可選數據地址內的參數傳遞給任務的指針。 被調用和傳遞
* 參數如下:
*
* void Task (void *pdata)
* {
* for (;;) {
* Task code;
* }
* }
*
* ptos 指向任務堆棧棧頂的指針。 如果配置常量OS_STK_GROWTH設為1,堆棧向下增長(從高
* 存儲地址到低存儲地址)。因此,'pstk' 將指向堆棧的最高的有效的存儲位置。如果
* OS_STK_GROWTH 設為0,'pstk' 將指向堆棧的最低的存儲位置。并且,堆棧將向上增長。 memory locations.
*
* prio 任務的優先級別。每一個任務需分配不同的優先級。數字越小,優先級別越高。
*
* 返回值 : OS_NO_ERR 函數建立成功
* OS_PRIO_EXIT 任務優先級已經存在
* OS_PRIO_INVALID 指定的優先級高于允許的最大值
* (例如 >= OS_LOWEST_PRIO)
*********************************************************************************************************
*/
#if OS_TASK_CREATE_EN > 0
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
OS_STK *psp;
INT8U err;
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO)
{ /* 確認優先級在許可范圍之內 */
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) /* 確認優先級未被其他任務占用 */
{
OSTCBPrioTbl[prio] = (OS_TCB *)1; /* 保留該優先級避免其他處理 ... */
/* ... 直到任務建立. */
OS_EXIT_CRITICAL();
psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /* 初始化任務堆棧 */
err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
if (err == OS_NO_ERR)
{
OS_ENTER_CRITICAL();
OSTaskCtr++; /* 增加任務計數器 */
OS_EXIT_CRITICAL();
if (OSRunning == TRUE)
{ /* 如果多任務啟動尋找最高優先級任務 */
OS_Sched();
}
}
else
{
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* 放棄該優先級 */
OS_EXIT_CRITICAL();
}
return (err);
}
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 創建任務 (擴展函數)
*
* 函數描述: 該函數用于 uC/OS-II 管理任務的執行。任務可在啟動多任務之前建立,也可在運行中的任務中建立。
* 任務不能在中斷服務子程序中建立。該函數近似于 OSTaskCreate(),除了允許指定任務的一些補充信息。
*
* 輸入參數 : task 指向任務代碼的指針
*
* pdata 當任務首先執行時,指向能把可選數據地址內的參數傳遞給任務的指針。 被調用和傳遞
* 參數如下:
*
* void Task (void *pdata)
* {
* for (;;) {
* Task code;
* }
* }
*
* ptos 指向任務堆棧棧頂的指針。 如果配置常量OS_STK_GROWTH設為1,堆棧向下增長(從高
* 存儲地址到低存儲地址)。因此,'pstk' 將指向堆棧的最高的有效的存儲位置。如果
* OS_STK_GROWTH 設為0,'pstk' 將指向堆棧的最低的存儲位置。并且,堆棧將向上增長。
* 'pstk' 一定指向一個有效的空余數據單元。
*
* prio 任務的優先級別。每一個任務需分配不同的優先級。數字越小,優先級別越高。
*
*
* id 任務的識別號 (0..65535)
*
* pbos 指向任務棧底的指針。如果配置常量OS_STK_GROWTH 設為1,堆棧向下增長(從高
* 存儲地址到低存儲地址)。因此,‘pbos' 將指向堆棧的最低的存儲位置(有效)。如果
* OS_STK_GROWTH 設為0, 'pbos'將指向堆棧的最高的存儲位置。堆棧從低向高增長。
* 'pbos' 一定指向一個有效的空余數據單元。
*
* stk_size 指定堆棧的容量。如果 OS_STK 設定為 INT8U,則'stk_size'則包含該數量個字節,如果
* OS_STK 定義為 INT16U,則包含該數量個半字,如果OS_STK 設定為 INT32U,則'stk_size'
* 包含該數量個字。
*
* pext 指向用戶附加的數據域的指針,用來擴展任務中任務控制塊。
* 例如,這個用戶存儲器在任務切換中能保持浮點寄存器,每個任務的執行時間,任務切換次數。
*
* opt 包含補充信息。當高8位應用時,低8位由 uC/OS-II 保留。見uCOS-II.H文件中OS_TASK_OPT_???
*
* 返回值 : OS_NO_ERR 函數建立成功
* OS_PRIO_EXIT 任務優先級已經存在
* OS_PRIO_INVALID 指定的優先級高于允許的最大值
* (例如 >= OS_LOWEST_PRIO)
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U OSTaskCreateExt (void (*task)(void *pd),
void *pdata,
OS_STK *ptos,
INT8U prio,
INT16U id,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -