使用stm32 cubemx 自带生成的代码中,如何使用freertos 系统实现cmsis rtos api2 接口 - 2


previous:  

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));