第二章 CMSIS-RTOS2內核信息與控制

 

 

描述

內核信息和控制功能組允許:

  • 獲取有關係統和底層內核的信息。
  • 獲取有關CMSIS-RTOS API的版本信息。
  • 用於創建對象的RTOS內核的初始化。
  • 啓動RTOS內核和線程切換。
  • 檢查RTOS內核的執行狀態。

注意:

不能從中斷服務例程中調用內核信息和控制功能。

RTX5的內核初始化記錄在系統啓動中。

代碼示例:

/*----------------------------------------------------------------------------
 * Application main thread
 *---------------------------------------------------------------------------*/
void app_main (void *argument) {
 
  // ...
  for (;;) {}
}
 
int main (void) {
 
  // System Initialization
  SystemCoreClockUpdate();
  // ...
 
  osKernelInitialize();                 // Initialize CMSIS-RTOS
  osThreadNew(app_main, NULL, NULL);    // Create application main thread
  osKernelStart();                      // Start thread execution
  for (;;) {}
}

/// Version information.
typedef struct {
  uint32_t                       api;   ///< API version (major.minor.rev: mmnnnrrrr dec).
  uint32_t                    kernel;   ///< Kernel version (major.minor.rev: mmnnnrrrr dec).
} osVersion_t;

標識基礎的RTOS內核和API版本號。版本以組合的十進制數字表示,格式爲:major.minor.rev:mmnnnrrrr

使用osKernelGetInfo檢索版本號。


/// Kernel state.
typedef enum {
  osKernelInactive        =  0,         ///< Inactive.
  osKernelReady           =  1,         ///< Ready.
  osKernelRunning         =  2,         ///< Running.
  osKernelLocked          =  3,         ///< Locked.
  osKernelSuspended       =  4,         ///< Suspended.
  osKernelError           = -1,         ///< Error.
  osKernelReserved        = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization.
} osKernelState_t;

osKernelGetState檢索的內核狀態。萬一osKernelGetState失敗或從ISR調用,它將返回osKernelError,否則返回內核狀態。


/// Initialize the RTOS Kernel.
/// \return status code that indicates the execution status of the function.
osStatus_t osKernelInitialize (void);

返回值:

返回指示函數執行狀態的狀態代碼。

函數osKernelInitialize初始化RTOS內核。在成功執行之前,只能調用函數osKernelGetInfoosKernelGetState

可能的osStatus_t返回值:

  • osOK成功。
  • osError如果發生不確定的錯誤。
  • osErrorISR(如果從中斷服務例程中調用)。
  • osErrorNoMemory如果無法爲該操作保留任何內存。

注意:

不能中斷服務程序中調用此函數。

代碼示例

#include "RTE_Components.h"
#include  CMSIS_device_header
#include "cmsis_os2.h"
 
/*----------------------------------------------------------------------------
 * Application main thread
 *---------------------------------------------------------------------------*/
void app_main (void *argument) {
 
  // ...
  for (;;) {}
}
 
int main (void) {
 
  // System Initialization
  SystemCoreClockUpdate();
  // ...
 
  osKernelInitialize();                 // Initialize CMSIS-RTOS
  osThreadNew(app_main, NULL, NULL);    // Create application main thread
  osKernelStart();                      // Start thread execution
  for (;;) {}
}

///  Get RTOS Kernel Information.
/// \param[out]    version       指向用於檢索版本信息的緩衝區的版本指針.
/// \param[out]    id_buf        指向用於檢索內核標識字符串的緩衝區的指針.
/// \param[in]     id_size       內核標識字符串的緩衝區大小.
/// \                            返回指示函數執行狀態的狀態代碼.
osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size);

函數osKernelGetInfo檢索底層RTOS內核的API和內核版本以及該內核的可讀標識符字符串。在初始化或啓動RTOS之前可以安全地調用它(調用osKernelInitializeosKernelStart)。

可能的osStatus_t返回值:

  • osOK     成功。
  • osError  如果發生不確定的錯誤。

注意:

可以從中斷服務程序中調用此函數。

代碼示例

void info (void) 
{
  char infobuf[100];
  osVersion_t osv;
  osStatus_t status;
 
  status = osKernelGetInfo(&osv, infobuf, sizeof(infobuf));
  if(status == osOK) 
  {
    printf("Kernel Information: %s\r\n", infobuf);
    printf("Kernel Version    : %d\r\n", osv.kernel);
    printf("Kernel API Version: %d\r\n", osv.api);
  }
}

/// Get the current RTOS Kernel state.
/// \return current RTOS Kernel state.
osKernelState_t osKernelGetState (void);

函數osKernelGetState返回內核的當前狀態,可以在初始化或啓動RTOS之前安全地調用該函數(調用osKernelInitializeosKernelStart)。如果失敗,它將返回osKernelError,否則將返回內核狀態(有關內核狀態列表,請參見osKernelState_t)。

可能的osKernelState_t返回值:

  • osKernelError如果發生了不確定的錯誤。
  • 否則爲實際內核狀態。

注意

可以從中斷服務程序中調用此函數。

代碼示例

int main (void) 
{
  // System Initialization
  SystemCoreClockUpdate();
  // ...
  if(osKernelGetState() == osKernelInactive)       // Is the kernel initialized?
  {
     osKernelInitialize();                         // Initialize CMSIS-RTOS kernel
  }
  ;
}

/// Start the RTOS Kernel scheduler.
/// \return status code that indicates the execution status of the function.
osStatus_t osKernelStart (void);

函數osKernelStart啓動RTOS內核並開始線程切換。如果成功,它將不會返回其調用函數。在成功執行之前,只能調用函數osKernelGetInfoosKernelGetState和對象創建函數(osXxxNew)。

至少應在osKernelStart之前創建一個初始線程,請參見osThreadNew

可能的osStatus_t返回值:

注意

不能中斷服務程序中調用此函數。

代碼示例

int main (void) 
{
  // System Initialization
  SystemCoreClockUpdate();

  // ...

  if(osKernelGetState() == osKernelInactive) 
  {
    osKernelInitialize();
  }

  ; // ... Start Threads

  if (osKernelGetState() == osKernelReady)          // If kernel is ready to run...
  {
    osKernelStart();                                // ... start thread execution
  }
  
  while(1);                                         // only reached in case of error
}

/// Lock the RTOS Kernel scheduler.
/// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
int32_t osKernelLock (void);

功能osKernelLock允許鎖定所有任務開關。它返回鎖定狀態的前一個值(如果已鎖定,則返回1;如果未鎖定,則返回0),否則返回表示錯誤代碼的負數(請參閱osStatus_t)。

可能的osStatus_t返回值:

注意

不能中斷服務程序中調用此函數。

代碼示例

int32_t state = osKernelLock();
// ... critical code
osKernelRestore(state);

 

/// Unlock the RTOS Kernel scheduler.
/// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
int32_t osKernelUnlock (void);

函數osKernelUnlockosKernelLock恢復。它返回鎖定狀態的前一個值(如果已鎖定,則返回1;如果未鎖定,則返回0),否則返回表示錯誤代碼的負數(請參閱osStatus_t)。

可能的osStatus_t返回值:

注意

不能中斷服務程序中調用此函數。

代碼示例

int32_t sl = osKernelLock();
// ... critical code
{
  int32_t su = osKernelUnlock();
  // ... uncritical code
  osKernelRestoreLock(su);
}
// ... critical code
osKernelRestoreLock(sl);

/// Restore the RTOS Kernel scheduler lock state.
/// \param[in]     lock          lock state obtained by \ref osKernelLock or \ref osKernelUnlock.
/// \return new lock state (1 - locked, 0 - not locked, error code if negative).
int32_t osKernelRestoreLock (int32_t lock);

函數osKernelRestoreLockosKernelLockosKernelUnlock之後恢復先前的鎖定狀態。

參數lock指定由osKernelLockosKernelUnlock獲得的鎖定狀態。

該函數返回鎖定狀態的新值(如果已鎖定,則返回1;如果未鎖定,則返回0),否則返回表示錯誤代碼的負數(請參閱osStatus_t)。

可能的osStatus_t返回值:

注意

不能中斷服務程序中調用此函數。

代碼示例

int32_t sl = osKernelLock();
// ... critical code
{
  int32_t su = osKernelUnlock();
  // ... uncritical code
  osKernelRestoreLock(su);
}
// ... critical code
osKernelRestoreLock(sl);

 

/// Suspend the RTOS Kernel scheduler.
/// \return time in ticks, for how long the system can sleep or power-down.
uint32_t osKernelSuspend (void);

CMSIS-RTOS擴展了無滴答操作,這對於使用廣泛的低功耗模式(同時也禁用了SysTick定時器)的應用程序很有用。爲了在這種省電模式下提供時間間隔,使用喚醒定時器來得出定時器間隔。函數osKernelSuspend掛起RTX內核調度程序,從而啓用睡眠模式。

返回值可用於確定系統滴答的數量,直到發生下一個基於滴答的內核事件,即,延遲的線程再次變爲就緒狀態爲止。建議設置低功耗定時器,以基於該返回值生成喚醒中斷。

注意:

不能中斷服務程序中調用此函數。

代碼示例

void osRtxIdleThread (void) 
{
                                               /* 當沒有其他線程準備運行時,空閒線程正在運行.*/
  unsigned int sleep;
 
  for (;;) 
  {
                                               /* 這裏:包括在沒有任務運行時要執行的可選用戶代碼。 */
    sleep = osKernelSuspend();                 /* 掛起RTX線程調度程序           */
 
    if (sleep)                                 /* 我們能睡多久?                */
    {
                                               /* “sleep”在RTX定時器信號中,在這個配置中是1毫秒   */
       
                                               /* 設置喚醒,如看門狗 */
 
      __WFE();                                 /* Enter Power-down mode        */
      
                                               /* After Wake-up                */
      sleep = tc;                              /* 調整睡眠週期                  */  
    }
 
    osKernelResume(sleep);                     /* 恢復線程調度程序              */
  }
}

/// Resume the RTOS Kernel scheduler.
/// \param[in]     sleep_ticks   time in ticks for how long the system was in sleep or power-down mode.
void osKernelResume (uint32_t sleep_ticks);

CMSIS-RTOS擴展了無滴答操作,這對於使用廣泛的低功耗模式(同時也禁用了SysTick定時器)的應用程序很有用。爲了在這種省電模式下提供時間間隔,使用喚醒定時器來得出定時器間隔。函數osKernelResume啓用RTX內核調度程序,從而將系統從睡眠模式中喚醒。

注意

不能中斷服務程序中調用此函數。

代碼示例

參考 osKernelSuspend (void);


/// Get the RTOS kernel tick count.
/// \return RTOS kernel current tick count.
uint32_t osKernelGetTickCount (void);

函數osKernelGetTickCount返回當前的RTOS內核滴答計數。

注意:

可以從中斷服務程序中調用此函數。

代碼示例

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章