1. 程式人生 > 其它 >使用stm32 cubemx 自帶生成的程式碼中,如何使用freertos 系統實現cmsis rtos api2 介面 - 2

使用stm32 cubemx 自帶生成的程式碼中,如何使用freertos 系統實現cmsis rtos api2 介面 - 2

previous:https://www.cnblogs.com/zhangzhiwei122/p/15889718.html

osStatus_t osKernelInitialize (void)

{

  osStatus_t stat;


  if (IS_IRQ()) {

    stat = osErrorISR;

  }

  else {

    if (KernelState == osKernelInactive) {

      #if defined(USE_FreeRTOS_HEAP_5)

        vPortDefineHeapRegions (xHeapRegions);

      
#endif KernelState = osKernelReady; stat = osOK; } else { stat = osError; } } return (stat); }

只有當 使用heap5 時,才需要呼叫一下 freertos 的 vPortDefineHeapRegions (xHeapRegions)

xHeapRegions 也在 cmsis_os2.c 裡面定義,如下:

/* Heap region definition used by heap_5 variant */

#if
defined(USE_FreeRTOS_HEAP_5) #if (configAPPLICATION_ALLOCATED_HEAP == 1) /* The application writer has already defined the array used for the RTOS heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[configTOTAL_HEAP_SIZE]; #else static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
#endif /* configAPPLICATION_ALLOCATED_HEAP */ static HeapRegion_t xHeapRegions[] = { { ucHeap, configTOTAL_HEAP_SIZE }, { NULL, 0 } }; #endif /* USE_FreeRTOS_HEAP_5 */

osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size)

cmsis_os2.c 裡面定義

/* Kernel version and identification string definition */

#define KERNEL_VERSION            (((uint32_t)tskKERNEL_VERSION_MAJOR * 10000000UL) | \

                                   ((uint32_t)tskKERNEL_VERSION_MINOR *    10000UL) | \

                                   ((uint32_t)tskKERNEL_VERSION_BUILD *        1UL))

 

#define KERNEL_ID                 "FreeRTOS V10.0.1"

tskKERNEL_VERSION_MAJOR 等來自於 freertos task.h 標頭檔案

osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
  if (version != NULL) {
    version->api    = KERNEL_VERSION;
    version->kernel = KERNEL_VERSION;

  }

  if ((id_buf != NULL) && (id_size != 0U)) {

    if (id_size > sizeof(KERNEL_ID)) {

      id_size = sizeof(KERNEL_ID);

    }
    memcpy(id_buf, KERNEL_ID, id_size);
  }

  return (osOK);
}

 

osKernelState_t osKernelGetState (void)

osKernelState_t osKernelGetState (void)
{
  osKernelState_t state;
  switch (xTaskGetSchedulerState()) {
    case taskSCHEDULER_RUNNING:
      state = osKernelRunning;
      break;
    case taskSCHEDULER_SUSPENDED:
      state = osKernelLocked;
      break;
    case taskSCHEDULER_NOT_STARTED:
    default:
      if (KernelState == osKernelReady) {
        state = osKernelReady;
      } else {
        state = osKernelInactive;
      }
      break;
  }
  return (state);

}

將freertos 的 xTaskGetSchedulerState() 【task.c 中實現,依賴xSchedulerRunning 和uxSchedulerSuspend 這兩個全域性變數得到】獲取的3中狀態,對映到 cmsis 標準的4中狀態。

osStatus_t osKernelStart (void)

osStatus_t osKernelStart (void) {
  osStatus_t stat;
  if (IS_IRQ()) {
    stat = osErrorISR;
  }
  else {
    if (KernelState == osKernelReady) {
      KernelState = osKernelRunning;
      vTaskStartScheduler();
      stat = osOK;
    } else {
      stat = osError;
    }
  }
  return (stat);

}

 

呼叫freertos 的 void vTaskStartScheduler( void )

vTaskStartScheduler

1、#if( configSUPPORT_STATIC_ALLOCATION == 1 ) ,使用 xTaskCreateStatic 建立了 idletask

2、#if ( configUSE_TIMERS == 1 ) ,使用xTimerCreateTimerTask 建立

3、portDISABLE_INTERRUPTS();

4、xSchedulerRunning = pdTRUE;

5、xTickCount = ( TickType_t ) 0U;

6、xPortStartScheduler() – 啟動systick 定時器

int32_t osKernelLock (void)

呼叫 xTaskGetSchedulerState() 和vTaskSuspendAll();

int32_t osKernelUnlock (void)

呼叫 xTaskGetSchedulerState() 和xTaskResumeAll();

int32_t osKernelRestoreLock (int32_t lock)

呼叫 xTaskGetSchedulerState() 和xTaskResumeAll(); 和vTaskSuspendAll()

uint32_t osKernelGetTickCount (void)

使用xTaskGetTickCountFromISR(); 或者 xTaskGetTickCount();

uint32_t osKernelGetSysTimerCount (void)

獲得systick 數目ticks = xTaskGetTickCount();

要給systick ,timer 計數值為 configCPU_CLOCK_HZ / configTICK_RATE_HZ,則累計計數值為

val = ticks * ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );

osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)

如果attr 裡面指定的 cb_mem (control block mem足夠 ),使用 xTaskCreateStatic函式建立,否則,使用xTaskCreate 建立

osThreadId_t osThreadGetId (void)

xTaskGetCurrentTaskHandle();

osThreadState_t osThreadGetState (osThreadId_t thread_id)

eTaskGetState (hTask)

osStatus_t osThreadYield (void)

taskYIELD();

osStatus_t osThreadSuspend (osThreadId_t thread_id)

vTaskSuspend (hTask);

osStatus_t osThreadResume (osThreadId_t thread_id)

vTaskResume (hTask);

__NO_RETURN void osThreadExit (void)

如果使用 heap1 實現,則 死迴圈

其他heap 時,呼叫vTaskDelete (NULL); 當前任務退出,切換到其他任務。

osStatus_t osThreadTerminate (osThreadId_t thread_id)

如果使用 heap1 實現,返回osError ,無法終止task .

其他heap 實現,呼叫 eTaskGetState (hTask); vTaskDelete (hTask);

uint32_t osThreadGetCount (void)

uxTaskGetNumberOfTasks();

osStatus_t osDelay (uint32_t ticks)

vTaskDelay(ticks);

osStatus_t osDelayUntil (uint32_t ticks)

vTaskDelayUntil (&tcnt, (TickType_t)(ticks - tcnt));