UCOS中的OSStatInit()函數

ucos啓動之後,會創建兩個任務,空閒任務和統計任務(若是配置了的話),咱們常常會在代碼裏看到OSStatInit(),其實這個函數使用的時候要當心了。
做者原著中提到,OSStatInit()要在創建的第一個,而且只有一個任務的時候調用,因此會常常見到下面的結構:
int main(void)
{
OSInit();


OSStart();
}

void AppTask(void *pdata)
{

}

這樣作是由於統計任務計算CPU利用率的須要。函數

之因此說,調用這個函數要注意,主要緣由就是由於在OSStatInit()中調用OSTimeDly發生了任務的調度,而這一點特別容易被忽略掉。學習

 

----------------------------------------------------------------------.net

----------------------------------------------------------------------get

void OSStatInit (void)

#if OS_TASK_STAT_EN > 0
void OSStatInit (void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif


OSTimeDly(2);
OS_ENTER_CRITICAL();
OSIdleCtr = 0L;
OS_EXIT_CRITICAL();
OSTimeDly(OS_TICKS_PER_SEC / 10);
OS_ENTER_CRITICAL();
OSIdleCtrMax = OSIdleCtr;
OSStatRdy = TRUE;
OS_EXIT_CRITICAL();
}
#endif

在OSStatInit一開始延遲時間爲2時鐘節拍裏:第一在就緒表中刪除掉當前任務的就緒標誌,這個當前任務也就是調用OSStatInt()的用戶編寫的TaskStart()任務,這是用戶建立的優先級最高的任務;第二令OSTCBDly =ticks也就是這個任務要延遲ticks所表明的時間;第三,調用 OS_Sched(),進行一次任務調度,在任務調度裏找出優先級最高的任務,並進行任務切換,切換到如今的具備最高優先級的任務,使其運行。此時在任務調度的時候,TaskStart()任務又從新處於就緒狀態,此時程序從OSTimeDly(2)中返回,接着執行下面的程序。執行完OSIdleCtr= 0L; 後,又進入一個延時程序OSTimeDly(OS_TICKS_PER_SEC / 10);,本程序是又延遲了100毫秒,在這100毫秒中,TaskStart()任務處於等待狀態,所以在這100毫秒中執行的是Idle任務。Idle任務會不斷給OSIdelCtr計數,從而100毫秒後OSIdelCtr記錄的就是100毫秒內被增長的最大次數(在這一秒中沒有其它任務高於Idle任務,因此結果是最大的)。100毫秒延遲結束後。TaskStart()任務從新就緒,得到cpu使用權,就執行OSIdleCtrMax= OSIdleCtr; OSStatRdy = TRUE;此後程序結束。

OSStatInit一開始延遲時間爲2時鐘節拍,用於保持與系統時鐘的同步,由於延遲以後調用的第一個語句爲「OSIdelCtr=0」,基本不用花費系統時間,而後就進入第二個語句OSTimeDly(OS_TICKS_PER_SEC);至關於再次延遲1s;在這延遲的一秒中,Idle任務會不斷給OSIdelCtr計數,從而1s後OSIdelCtr記錄的就是1s內被增長的最大次數(在這一秒中沒有其它任務高於Idle任務,因此結果是最大的)。

在創建其餘任務以前,必須調用OSStatInit()來肯定用戶的PC有多快。在一開始,OSStatInit()就將自身延時了兩個時鐘節拍,這樣它就能夠與時鐘節拍中斷同步。所以,OSStatInit()必須在時鐘節拍啓動以後調用;不然,用戶的應用程序就會崩潰。當µC/OS-II調用OSStatInit()時,一個32位的計數器OSIdleCtr被清爲0,併產生另外一個延時,這個延時使OSStatInit()掛起。此時,uCOS-II沒有別的任務能夠執行,它只能執行空閒任務(µC/OS-II的內部任務)。空閒任務是一個無線的循環,它不斷的遞增OSIdleCtr。1秒之後,uCOS-II從新開始OSStatInit(),而且將OSIdleCtr保存在OSIdleMax中。因此OSIdleMax是OSIdleCtr所能達到的最大值。而當用戶再增長其餘應用代碼時,空閒任務就不會佔用那樣多的CPU時間。若是用戶程序每秒撫慰一次OSIdleCtr()那麼OSIdleCtr不可能達到那樣多的記數。CPU利用率的計算由µC/OS-II中的OSStatTask()函數來完成,這個任務每秒執行一次。而當OSStatRdy置爲TRUE表示µC/OS-II將統計CPU的利用率。

OSStatInit()將返回到TaskStart()。全部任務能夠都由TaskStart()中創建,因爲TaskStart()的優先級爲0(最高),新任務創建後不進行任務調度。當全部任務都創建完成後,TaskStart()將進入無限循環之中。

嵌入式應用時,用戶必須在第一個任務中打開時鐘節拍中斷。

void ARMStartTimer(void)
{
//autoreload and start m
rTCON = 0x9;
}同步


學習統計任務的過程當中,要十分注意統計任務初始化函數OSStatInit和OSTaksStat之間時間延遲的區別和應用!
OSStatInit一開始延遲時間爲2時鐘節拍,用於保持與系統時鐘的同步,由於延遲以後調用的第一個語句爲「OSIdelCtr=0」,基本不用花費系統時間,而後就進入第二個語句OSTimeDly(OS_TICKS_PER_SEC);至關於再次延遲1s;在這延遲的一秒中,Idle任務會不斷給OSIdelCtr計數,從而1s後OSIdelCtr記錄的就是1s內被增長的最大次數(在這一秒中沒有其它任務高於Idle任務,因此結果是最大的)。it

OSTaskStat則不一樣,它一開始就直接延遲2s(注意不是2時鐘節拍),而2s>>2時鐘節拍,所以在OSStatInit中進行時鐘同步和最大值記錄過程當中,OSTaskStat一直處於休眠狀態,不會影響到前面的操做。配置

相關文章
相關標籤/搜索