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