1. 程式人生 > 實用技巧 >ucosIII學習筆記——鉤子函式

ucosIII學習筆記——鉤子函式

一開始聽見鉤子函式感覺很莫名其妙,更不知道它有何作用,這是第一篇部落格,也是學習ucosIII作業系統的一個開始吧。

在系統中有開發者自己建立的任務也有系統內部任務 ,UCOSIII中有五個系統任務,分別為

  • 1.空閒任務,

  UCOSIII 的任務數是無數的,但是在實際使用中考慮到硬體資源 (ROM 和 RAM)等因素,不可能真的使用無數的任務,

在 UCOSIII 中可以使用巨集 OS_CFG_PRIO_MAX 來定義可使用的任務數,

預設情況下 OS_CFG_PRIO_MAX 為 64。空閒 任務優先順序為 OS_CFG_PRIO_MAX-1,說明空閒任務的優先順序為最低的。

  • 2.時鐘節拍任務,

  時鐘節拍任務是 UCOSIII 必須建立的,同樣,不需要我們手工建立。
時鐘節拍任務的任務優先順序為 OSCfg_TickTaskPrio,時鐘節拍任務的優先順序儘可能的高一點, 有些 預設設定時鐘節拍任務的任務優先順序為 1。

  時鐘節拍任務的作用是跟蹤正在延時的任務,以及在指定時間內等待某個核心物件的任務,

  • 3.統計任務,

  在 UCOSIII 中統計任務可用來統計 CPU 的使用率、各個任務的 CPU 使用率和各任務的堆 棧使用情況,預設情況下統計任務是不會建立的,

如果要使能統計任務的話需要將巨集 OS_CFG_STAT_TASK_EN 置 1,巨集 OS_CFG_STAT_TASK_EN 在 os_cfg.h 檔案中有定義。

當我 們將巨集 OS_CFG_STAT_TASK_EN 置 1 以後,

OSinit()函式中有關統計任務的程式碼就可以編譯了 額。OS_StatTaskInit() 函 數 用 來 創 建 統 計 任 務 ,

統 計 任 務 的 優 先 級 通 過 巨集 OS_CFG_STAT_TASK_PRIO 設定,

ALIENTEK 將 統 計 任 務 的 優 先 級 設 置 為 OS_CFG_PRIO_MAX-2,也就是倒數第二。

  • 4.定時任務,

UCOSIII 提供軟體定時器功能,定時任務是可選的,將巨集 OS_CFG_TMR_EN 設定為 1 就 會使能定時任務,在 OSInit()中將會呼叫函式 OS_TmrInit()來建立定時任務。

定時任務的優先順序 通過巨集 OS_CFG_TMR_TASK_PRIO 定義

  • 5.中斷服務管理服務,

當把 os_cfg.h 檔案中的巨集 OS_CFG_ISR_POST_DEFERRED_EN 置 1 就會使能中斷服務管 理任務,UCOSIII 會建立一個名為 OS_IntQTask()的任務,

該任務負責“延遲”在 ISR 中呼叫的 系統 post 服務函式的行為。中斷服務管理任務的任務優先順序永遠是最高的,為 0!

在 UCOS 中可以通過關閉中斷和任務排程器上鎖兩種方式來管理臨界段程式碼

如果採用後一種,即排程器上鎖的方式來管理臨界段程式碼的話, 那麼在中斷服務函式中呼叫的“post”類函式就不允許操作諸如任務就緒表、等待表等系統內部 資料結構。

當 ISR(中斷服務函式)呼叫 UCOSIII 提供的“post”函式時,要傳送的資料和傳送的目的地 都會存入一個特別的緩衝佇列中,當所有巢狀的 ISR 都執行完成以後 UCOSIII 會做任務切換,

執行中斷服務管理任務,該任務會把快取佇列中存放的資訊重發給相應的任務。這樣做的好處 就是可以減少中斷關閉的時間,否則,在 ISR 中還需要把任務從等待列表中刪除,

並把任務放 入就緒表,以及做一些其他的耗時操作。

  • 6.鉤子函式。

鉤子函式是這篇文章中自己最想記錄的,在ucosIII中有8個鉤子函式,

空閒任務的鉤子函式為數 OSIdleTaskHook()

可以用來讓CPU進入低功耗模式要使用空閒任務的鉤子函式需要先將 巨集 OS_CFG_APP_HOOKS_EN 置 1

即允許使用空閒任務的鉤子函式。當時使能空閒任務的鉤子函式以後每次進入空閒任務就會呼叫指標 OS_AppIdleTaskHookPtr 所指向的函式

 1 void  OSIdleTaskHook (void)
 2  { 
 3 #if OS_CFG_APP_HOOKS_EN > 0u   
 4     if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) 
 5 {       
 6   (*OS_AppIdleTaskHookPtr)();    
 7  } 
 8 #endif 2020-12-20
 9 }
10  

os_app_hooks.c 檔案,在檔案中有個函式 App_OS_SetAllHooks(),

1 void  App_OS_SetAllHooks (void) {
2  #if OS_CFG_APP_HOOKS_EN > 0u     CPU_SR_ALLOC(); 
3  
4     CPU_CRITICAL_ENTER();     
5     OS_AppTaskCreateHookPtr = App_OS_TaskCreateHook;       
6 OS_AppTaskDelHookPtr = App_OS_TaskDelHook;
7     OS_AppTaskReturnHookPtr = App_OS_TaskReturnHook; 8    OS_AppIdleTaskHookPtr = App_OS_IdleTaskHook;
9 OS_AppStatTaskHookPtr = App_OS_StatTaskHook;
10 OS_AppTaskSwHookPtr = App_OS_TaskSwHook;
11 OS_AppTimeTickHookPtr = App_OS_TimeTickHook;
12 CPU_CRITICAL_EXIT(); 13 #endif }

App_OS_IdleTaskHook 複製給 OS_AppIdleTaskHookPtr,App_OS_IdleTaskHook 是一個函式,也就是說如果我們要想在空閒 任務的鉤子函式中做一些其他處理的話

就需要將程式程式碼寫在 App_OS_IdleTaskHook()

1 void  App_OS_IdleTaskHook (void)
2  { 
3  ******
4 } 

函式中。在空閒任務的鉤子函式中不能呼叫任何可以是空閒進入等待態的程式碼,。

在 UCOS 中為了讓 CPU 一直工作,在所有應用任 務都進入等待態的時候 CPU 會執行空閒任務,我們可以從空閒任務的任務函式 OS_IdleTask() 看出,

在 OS_IdleTask()中沒有任何可以讓空閒任務進入等待態的程式碼。如果在 OS_IdleTask()中 有可以讓空閒任務進入等待態的程式碼的話有可能會在同一時刻所有任務(應用任務和空閒任務) 同時進入等待態,

此時 CPU 就會無所事事了,所以在空閒任務的鉤子函式 OSIdleTaskHook()中 不能出現可以讓空閒任務進入等待態的程式碼

鉤子函式一般主要是用來擴充套件其他函式(任務)功能的,鉤子函式有如下幾個:

1、空閒任務的鉤子函式OSIdleTaskHook(),空閒任務呼叫這個函式,可以用來讓CPU進入低功耗模式

2、系統初始化的鉤子函式OSInitHook(),系統初始化函式OSInit()呼叫此函式。

3、統計任務的鉤子函式OSStatTaskHook(),統計任務每秒中都會呼叫這個函式,此函式允許你向統計任務中新增自己的應用函式。

4、OSTaskCreateHook(),任務建立的鉤子函式。

5、OSTaskDelHook(),任務刪除的鉤子函式。

6、OSTaskReturnHook(),任務意外返回時呼叫的鉤子函式,比如刪除某個任務

7、OSTaskSwHook(),任務切換時候呼叫的鉤子函式。

8、OSTimeTickHook(),滴答定時器呼叫的鉤子函式

空閒任務的鉤子函式使用

1 #if OS_CFG_APP_HOOKS_EN    //開啟巨集,使用空閒任務的鉤子函式            
2     App_OS_SetAllHooks();            
3 #endif

1 void  App_OS_IdleTaskHook (void)//鉤子函式功能程式碼
2 {
3     static int num;
4     num++;
5     if(num%50000==0)
6     {
7         printf("Idle Task Running 50000 times!\r\n");
8     }
9 }

2020-12-20