日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

freeRtos学习笔记 (9) 移植和CPU利用率统计

發布時間:2025/4/16 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 freeRtos学习笔记 (9) 移植和CPU利用率统计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

freeRtos學習筆記 (9) 移植和CPU利用率統計

使用官方固件移植

首先準備一個能跑的裸機工程

  • 注意,freertos需要使用systick定時器,而stm32HAL庫默認使用systick作為時基
  • 方法一 :可以在stm32CUBEMX創建工程時修改HAL庫時基使用的定時器

  • 方法二 :修改HAL庫關于時基的函數

    由于這兩個函數HAL庫中都是帶__weak前綴的(如果用戶不提供則用該函數,如果用戶重寫則會覆蓋帶__weak前綴的函數),直接寫自己的即可
/*!* @brief 匯編延時** @param ulCount:延時時鐘數** @return 無** @note ulCount每增加1,該函數增加6個時鐘(M4是3個時鐘)** @see */ #if defined (__CC_ARM) /*!< ARM Compiler */ __asm void userDelay(unsigned long ulCount) {subs r0, #1;bne userDelay;bx lr; } #elif defined ( __ICCARM__ ) /*!< IAR Compiler */ void userDelay(unsigned long ulCount) {__asm(" subs r0, #1\n"" bne.n userDelay\n"" bx lr"); }#elif defined (__GNUC__) /*!< GNU Compiler */ void __attribute__((naked)) userDelay(unsigned long ulCount) {__asm(" subs r0, #1\n"" bne userDelay\n"" bx lr"); }#elif defined (__TASKING__) /*!< TASKING Compiler */ /*?*/ #endif /* __CC_ARM */ #include "FreeRTOS.h" #include "task.h" uint32_t HAL_GetTick (void) {static uint32_t ticks = 0U;if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING){return ((uint32_t)xTaskGetTickCount());}/* 如果OS還沒有運行,采用下面方式 */userDelay((SystemCoreClock/6000));return ++ticks; }HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority) {return HAL_OK; }

下載freeRtos固件

下載地址 https://freertos.org/a00104.html
GitHub地址 https://github.com/FreeRTOS/FreeRTOS

將freeRtos添加進工程

  • 將下載后的freeRtos固件解壓,將Source文件夾復制到準備好的裸機工程中并將文件夾名由Source改為FreeRtos
  • 向工程中添加一個FreeRTOSConfig.h文件模板,并根據要求自行裁剪
  • #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H/*-----------------------------------------------------------* Application specific definitions.** These definitions should be adjusted for your particular hardware and* application requirements.** THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.** See http://www.freertos.org/a00110.html*----------------------------------------------------------*/#if (defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__)) #include <stdint.h>extern uint32_t SystemCoreClock; #endif/* Constants that describe the hardware and memory usage. */ #define configCPU_CLOCK_HZ (SystemCoreClock) #define configTICK_RATE_HZ ((TickType_t)1000) #define configTOTAL_HEAP_SIZE ((size_t)1024*40) #define configMINIMAL_STACK_SIZE ((uint16_t)256) #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configSUPPORT_STATIC_ALLOCATION 0/* Constants related to the behaviour or the scheduler. */ #define configMAX_PRIORITIES 5 #define configUSE_PREEMPTION 1 #define configUSE_TIME_SLICING 1 #define configIDLE_SHOULD_YIELD 0 #define configMAX_TASK_NAME_LEN (10) #define configUSE_16_BIT_TICKS 0/* Software timer definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY 2 #define configTIMER_QUEUE_LENGTH 5 #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)/* Constants that build features in or out. */ #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_QUEUE_SETS 1 #define configUSE_TASK_NOTIFICATIONS 1 #define configUSE_TRACE_FACILITY 1 #define configUSE_TICKLESS_IDLE 0 #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_NEWLIB_REENTRANT 0 #define configUSE_CO_ROUTINES 0/* Constants provided for debugging and optimisation assistance. */ #define configCHECK_FOR_STACK_OVERFLOW 0 #define configQUEUE_REGISTRY_SIZE 0 #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }/* Constants that define which hook (callback) functions should be used. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0/* Port specific configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 1 #define configMINIMAL_SECURE_STACK_SIZE ((uint32_t)1024) #define configRUN_FREERTOS_SECURE_ONLY 0/* Cortex-M specific definitions. */ #ifdef __NVIC_PRIO_BITS/* __NVIC_PRIO_BITS will be specified when CMSIS is being used. */#define configPRIO_BITS __NVIC_PRIO_BITS #else/* 7 priority levels */#define configPRIO_BITS 4 #endif/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f/* The highest interrupt priority that can be used by any interrupt service* routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT* CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A* HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values). */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5/* Interrupt priorities used by the kernel port layer itself. These are generic* to all Cortex-M ports, and do not rely on any particular library functions. */ #define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!* See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))/* Set the following definitions to 1 to include the API function, or zero* to exclude the API function. NOTE: Setting an INCLUDE_ parameter to 0 is* only necessary if the linker does not automatically remove functions that are* not referenced anyway. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetIdleTaskHandle 1 #define INCLUDE_xTaskAbortDelay 1 #define INCLUDE_xQueueGetMutexHolder 1 #define INCLUDE_xSemaphoreGetMutexHolder 1 #define INCLUDE_xTaskGetHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_uxTaskGetStackHighWaterMark2 1 #define INCLUDE_eTaskGetState 1 #define INCLUDE_xTaskResumeFromISR 1 #define INCLUDE_xTimerPendFunctionCall 1 #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetCurrentTaskHandle 1/* Map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define xPortPendSVHandler PendSV_Handler #define vPortSVCHandler SVC_Handler #define xPortSysTickHandler SysTick_Handler#if (defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__)) /* Include debug event definitions */ //#include "freertos_evr.h" #endif#endif /* FREERTOS_CONFIG_H */
  • 將FreeRTOS文件和文件路徑信息添加到工程中

    heap_4.c文件和內存分配有關,可以根據需要自行選擇 heap_1-4文件,不過一般選擇heap_4.c文件即可

    需要注意的是port.c文件,當選擇不同編譯器版本時,使用的port.c是不同的,AC5用的是RVDS文件夾下ARM_CM3(STM32F1系列是CM3內核的)內的port.c

    AC6用的是GCC文件夾下ARM_CM3(STM32F1系列是CM3內核的)內的port.c,個人比較喜歡用AC6,因為編譯速度更快,但是有個小問題,不能有中文路徑 否則不能gotodef

    最后記得將頭文件路徑告訴MDK,FreeRTOSConfig.h的頭文件路徑也要記得告訴MDK

  • 屏蔽HAL庫中的中斷服務函數

  • freeRtos使用了三個中斷 SVC、PenSVC、Systick。SVC只在vTaskStartScheduler中被調用一次,用作啟動第一個任務,簡單來說就是進入線程模式,將MSP變成PSP。PenSVC用作任務切換,Systick用作系統時基。

    編寫閃燈任務,驗證移植結果

    /*!* @brief 匯編延時** @param ulCount:延時時鐘數** @return 無** @note ulCount每增加1,該函數增加6個時鐘(M4是3個時鐘)** @see */ #if defined (__CC_ARM) /*!< ARM Compiler */ __asm void userDelay(unsigned long ulCount) {subs r0, #1;bne userDelay;bx lr; } #elif defined ( __ICCARM__ ) /*!< IAR Compiler */ void userDelay(unsigned long ulCount) {__asm(" subs r0, #1\n"" bne.n userDelay\n"" bx lr"); }#elif defined (__GNUC__) /*!< GNU Compiler */ void __attribute__((naked)) userDelay(unsigned long ulCount) {__asm(" subs r0, #1\n"" bne userDelay\n"" bx lr"); }#elif defined (__TASKING__) /*!< TASKING Compiler */ /*?*/ #endif /* __CC_ARM */ #include "FreeRTOS.h" #include "task.h" uint32_t HAL_GetTick (void) {static uint32_t ticks = 0U;if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING){return ((uint32_t)xTaskGetTickCount());}/* 如果OS還沒有運行,采用下面方式 */userDelay((SystemCoreClock/6000));return ++ticks; }HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority) {return HAL_OK; }void vTaskLED(void * pvParameters) {while(1){vTaskDelay(100);HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);} } static TaskHandle_t ledTaskHandle; /*** @brief The application entry point.* @retval int*/ int main(void) {/* 關閉中斷 防止初始化過程中進入中斷 因為中斷服務函數中可能使用freertos API 而此時freertos還未啟動 freertos啟動時會自動開啟中斷*/taskDISABLE_INTERRUPTS();HAL_Init();SystemClock_Config();MX_GPIO_Init();BaseType_t pd = xTaskCreate(vTaskLED, "TaskLED", 128, 0, 1, &ledTaskHandle);if(pd != pdPASS){//創建任務失敗}vTaskStartScheduler();while (1){}/* USER CODE END 3 */ }

    CPU利用率

    CPU利用率的原理就是定義一個精度至少是systick精度10倍的定時器,當任務切換時,任務控制塊記錄任務累計運行時長(利用高精度定時器)

  • 開啟高精度定時器

    創建回調函數,記錄高精度定時器節拍,注意高精度定時器中斷會嚴重影響系統性能。
  • /* 高精度定時器計數器 */ volatile uint32_t g_ulTick = 0; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM6){g_ulTick++;} }
  • 修改FreeRTOSConfig.h配置文件
    使用FreeRTOS中自帶的性能統計函數需要開啟一些宏定義,任務切換時,任務控制塊記錄任務累計運行時長(利用高精度定時器)
  • #define configUSE_TRACE_FACILITY 1 #define configGENERATE_RUN_TIME_STATS 1 #define configUSE_STATS_FORMATTING_FUNCTIONS 1 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (g_ulTick = 0ul) #define portGET_RUN_TIME_COUNTER_VALUE() g_ulTick

  • 創建一個CPU利用率統計任務
    為了提高效率,將printf重定向到Event Recorder中間件,詳細過程參考 https://blog.csdn.net/weixin_42378319/article/details/117920784
  • /*!* @brief 匯編延時** @param ulCount:延時時鐘數** @return 無** @note ulCount每增加1,該函數增加6個時鐘(M4是3個時鐘)** @see */ #if defined (__CC_ARM) /*!< ARM Compiler */ __asm void userDelay(unsigned long ulCount) {subs r0, #1;bne userDelay;bx lr; } #elif defined ( __ICCARM__ ) /*!< IAR Compiler */ void userDelay(unsigned long ulCount) {__asm(" subs r0, #1\n"" bne.n userDelay\n"" bx lr"); }#elif defined (__GNUC__) /*!< GNU Compiler */ void __attribute__((naked)) userDelay(unsigned long ulCount) {__asm(" subs r0, #1\n"" bne userDelay\n"" bx lr"); }#elif defined (__TASKING__) /*!< TASKING Compiler */ /*?*/ #endif /* __CC_ARM */ #include "FreeRTOS.h" #include "task.h" #include <stdio.h> #include "EventRecorder.h" uint32_t HAL_GetTick (void) {static uint32_t ticks = 0U;if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING){return ((uint32_t)xTaskGetTickCount());}/* 如果OS還沒有運行,采用下面方式 */userDelay((SystemCoreClock/6000));return ++ticks; }HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority) {return HAL_OK; }void vTaskLED(void * pvParameters) {while(1){vTaskDelay(100);HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);} }void vTaskTaskUtilization(void *pvParameters) {uint8_t ucKeyCode;uint8_t pcWriteBuffer[500];while(1){printf("=================================================\r\n");printf("任務名 任務狀態 優先級 剩余棧 任務序號\r\n");vTaskList((char *)&pcWriteBuffer);printf("%s\r\n", pcWriteBuffer);printf("\r\n任務名 運行計數 使用率\r\n");vTaskGetRunTimeStats((char *)&pcWriteBuffer);printf("%s\r\n", pcWriteBuffer);vTaskDelay(2000);} }static TaskHandle_t ledTaskHandle; static TaskHandle_t taskUtilizationTaskHandle; /* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/ int main(void) {/* 關閉中斷 防止初始化過程中進入中斷 因為中斷服務函數中可能使用freertos API 而此時freertos還未啟動 freertos啟動時會自動開啟中斷*/taskDISABLE_INTERRUPTS();EventRecorderInitialize(EventRecordAll, 1);HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_TIM6_Init();HAL_TIM_Base_Start_IT(&htim6);BaseType_t pd = xTaskCreate(vTaskLED, "TaskLED", 128, 0, 2, &ledTaskHandle);if(pd != pdPASS){//創建任務失敗}pd = xTaskCreate(vTaskTaskUtilization, "TaskUtilization", 1024, 0, 1, &taskUtilizationTaskHandle);if(pd != pdPASS){//創建任務失敗}vTaskStartScheduler();while (1);}/* 高精度定時器計數器 */ volatile uint32_t g_ulTick = 0; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM6){g_ulTick++;} }

    使用MDK中間件移植

    首先準備一個能跑的裸機工程

    和使用固件庫移植第一步一樣

    安裝MDK中間件

    如果網不好,可以通過 http://www.armbbs.cn/forum.php?mod=viewthread&tid=96992&highlight=pack 鏡像下載后,自行安裝


    安裝完組件后,向工程中添加組件

    修改FreeRTOSConfig.h文件模板,并根據要求自行裁剪

    #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H/*-----------------------------------------------------------* Application specific definitions.** These definitions should be adjusted for your particular hardware and* application requirements.** THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.** See http://www.freertos.org/a00110.html*----------------------------------------------------------*/#if (defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__)) #include <stdint.h>extern uint32_t SystemCoreClock; #endif/* Constants that describe the hardware and memory usage. */ #define configCPU_CLOCK_HZ (SystemCoreClock) #define configTICK_RATE_HZ ((TickType_t)1000) #define configTOTAL_HEAP_SIZE ((size_t)1024*40) #define configMINIMAL_STACK_SIZE ((uint16_t)256) #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configSUPPORT_STATIC_ALLOCATION 0/* Constants related to the behaviour or the scheduler. */ #define configMAX_PRIORITIES 5 #define configUSE_PREEMPTION 1 #define configUSE_TIME_SLICING 1 #define configIDLE_SHOULD_YIELD 0 #define configMAX_TASK_NAME_LEN (10) #define configUSE_16_BIT_TICKS 0/* Software timer definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY 2 #define configTIMER_QUEUE_LENGTH 5 #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)/* Constants that build features in or out. */ #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_QUEUE_SETS 1 #define configUSE_TASK_NOTIFICATIONS 1 #define configUSE_TRACE_FACILITY 1 #define configUSE_TICKLESS_IDLE 0 #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_NEWLIB_REENTRANT 0 #define configUSE_CO_ROUTINES 0/* Constants provided for debugging and optimisation assistance. */ #define configCHECK_FOR_STACK_OVERFLOW 0 #define configQUEUE_REGISTRY_SIZE 0 #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }/* Constants that define which hook (callback) functions should be used. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0/* Port specific configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 1 #define configMINIMAL_SECURE_STACK_SIZE ((uint32_t)1024) #define configRUN_FREERTOS_SECURE_ONLY 0/* Cortex-M specific definitions. */ #ifdef __NVIC_PRIO_BITS/* __NVIC_PRIO_BITS will be specified when CMSIS is being used. */#define configPRIO_BITS __NVIC_PRIO_BITS #else/* 7 priority levels */#define configPRIO_BITS 4 #endif/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f/* The highest interrupt priority that can be used by any interrupt service* routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT* CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A* HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values). */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5/* Interrupt priorities used by the kernel port layer itself. These are generic* to all Cortex-M ports, and do not rely on any particular library functions. */ #define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!* See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))/* Set the following definitions to 1 to include the API function, or zero* to exclude the API function. NOTE: Setting an INCLUDE_ parameter to 0 is* only necessary if the linker does not automatically remove functions that are* not referenced anyway. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetIdleTaskHandle 1 #define INCLUDE_xTaskAbortDelay 1 #define INCLUDE_xQueueGetMutexHolder 1 #define INCLUDE_xSemaphoreGetMutexHolder 1 #define INCLUDE_xTaskGetHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_uxTaskGetStackHighWaterMark2 1 #define INCLUDE_eTaskGetState 1 #define INCLUDE_xTaskResumeFromISR 1 #define INCLUDE_xTimerPendFunctionCall 1 #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetCurrentTaskHandle 1/* Map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define xPortPendSVHandler PendSV_Handler #define vPortSVCHandler SVC_Handler #define xPortSysTickHandler SysTick_Handler#if (defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__)) /* Include debug event definitions */ #include "freertos_evr.h" #endif#endif /* FREERTOS_CONFIG_H */

    編寫閃燈任務,驗證移植結果

    /*!* @brief 匯編延時** @param ulCount:延時時鐘數** @return 無** @note ulCount每增加1,該函數增加6個時鐘(M4是3個時鐘)** @see */ #if defined (__CC_ARM) /*!< ARM Compiler */ __asm void userDelay(unsigned long ulCount) {subs r0, #1;bne userDelay;bx lr; } #elif defined ( __ICCARM__ ) /*!< IAR Compiler */ void userDelay(unsigned long ulCount) {__asm(" subs r0, #1\n"" bne.n userDelay\n"" bx lr"); }#elif defined (__GNUC__) /*!< GNU Compiler */ void __attribute__((naked)) userDelay(unsigned long ulCount) {__asm(" subs r0, #1\n"" bne userDelay\n"" bx lr"); }#elif defined (__TASKING__) /*!< TASKING Compiler */ /*?*/ #endif /* __CC_ARM */ #include "FreeRTOS.h" #include "task.h" uint32_t HAL_GetTick (void) {static uint32_t ticks = 0U;if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING){return ((uint32_t)xTaskGetTickCount());}/* 如果OS還沒有運行,采用下面方式 */userDelay((SystemCoreClock/6000));return ++ticks; }HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority) {return HAL_OK; }void vTaskLED(void * pvParameters) {while(1){vTaskDelay(100);HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);} } static TaskHandle_t ledTaskHandle; /*** @brief The application entry point.* @retval int*/ int main(void) {/* 關閉中斷 防止初始化過程中進入中斷 因為中斷服務函數中可能使用freertos API 而此時freertos還未啟動 freertos啟動時會自動開啟中斷*/taskDISABLE_INTERRUPTS();HAL_Init();SystemClock_Config();MX_GPIO_Init();BaseType_t pd = xTaskCreate(vTaskLED, "TaskLED", 128, 0, 1, &ledTaskHandle);if(pd != pdPASS){//創建任務失敗}vTaskStartScheduler();while (1){}/* USER CODE END 3 */ }

    CPU利用率

    使用中間件的情況下,出來上面使用高精度定時器的方法來統計CPU利用率外,還有一種更為簡單的方法

    使用keil的Event Recorder中間件可以十分簡單的觀察RTOS運行時的狀態, Event Recorder中間件使用可以參考博客 https://blog.csdn.net/weixin_42378319/article/details/110131289?spm=1001.2014.3001.5501

  • 勾選 Event Recorder中間件
  • 初始化Event Recorder中間件
  • 細心的童鞋可能會發現,使用MDK中間件創建的FreeRTOS工程多了一個文件,這個文件是官方專為FreeRTOS調試編寫的


    3. 調出FreeRTOS RTOS窗口和System Analyzer窗口,查看RTOS運行狀態

    本質上還是利用Event Recorder中間件,啟用Event Recorder中間件后,FreeRTOS代碼會通過宏定義開啟一些函數,例如任務在創建時,會通過Event Recorder中間件在RAM中緩存固定格式數據,MDK讀取固定格式數據,轉換到窗體上顯示出來



    System Analyzer窗口有點小問題,不能顯示任務名稱,只顯示了任務的地址信息,可以兩個窗口結合著看

    使用中間件缺點是需要安裝對應中間件,不方便更換電腦,但是也可以根據文件目錄,將對應中間件文件復制添加到工程中,從而不適用中間件

    總結

    以上是生活随笔為你收集整理的freeRtos学习笔记 (9) 移植和CPU利用率统计的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。