使用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 */ #ifdefined(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));