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添加进工程

  1. 将下载后的freeRtos固件解压,将Source文件夹复制到准备好的裸机工程中并将文件夹名由Source改为FreeRtos
  2. 向工程中添加一个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 */
  1. 将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

  2. 屏蔽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倍的定时器,当任务切换时,任务控制块记录任务累计运行时长(利用高精度定时器)

  1. 开启高精度定时器

    创建回调函数,记录高精度定时器节拍,注意高精度定时器中断会严重影响系统性能。
/* 高精度定时器计数器 */
volatile uint32_t g_ulTick = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM6){g_ulTick++;}
}
  1. 修改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

  1. 创建一个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

  1. 勾选 Event Recorder中间件
  2. 初始化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利用率统计相关推荐

  1. STM32F407霸天虎FreeRTOS学习笔记——移植FreeRTOS到开发板上

    STM32F407霸天虎FreeRTOS学习笔记--移植FreeRTOS到开发板上 FreeRTOS源码获取 移植第一步:创建文件夹 Keil main.c 实验效果 FreeRTOS源码获取 在移植 ...

  2. 1、野火freertos学习笔记

    野火freertos学习笔记 1.任务 1.1 栈 1.2 任务的切换 taskYIELD(); 1.3 临界段 2.空闲任务 3.任务优先级 4.任务延时的表现 5.时间片 5.1抢占式.协做式 6 ...

  3. 小猫爪:i.MX RT1050学习笔记23-FreeRTOS移植之宇宙最详细

    小猫爪:i.MX RT1050学习笔记23-FreeRTOS移植之宇宙最详细 1 前言 2 准备 2.1 下载FreeRTOS源代码 2.2 准备一个RT1050的普通工程 3 移植 3.1 添加文件 ...

  4. FreeRTOS学习笔记20200526

    FreeRTOS学习笔记-Day1-20200526 nFlag = TRUE; 先立个Flag,是时候点亮嵌入式实时操作系统这个技能了.座右铭:坚持.认真.沉静.笃行. FreeRTOS优势 总结F ...

  5. FreeRtos学习笔记(11)查找就绪任务中优先级最高任务原理刨析

    FreeRtos学习笔记(11)查找就绪任务中优先级最高任务原理刨析 怎么查找就绪任务中优先级最高的? tasks.c中声明了一个全局变量 uxTopReadyPriority,任务从其他状态进入就绪 ...

  6. freeRtos学习笔记 (6)软件定时器

    freeRtos学习笔记 freeRtos软件定时器 软件定时器需要注意事项 软件定时器的精度基于时钟节拍,例如系统时钟节拍为10ms, 软件定时器定时时间必须是10ms的整数倍,因此软件定时器一般用 ...

  7. FreeRTOS学习笔记——互斥型信号量

    来自:http://blog.csdn.net/xukai871105/article/details/43456985 0.前言 在嵌入式操作系统中互斥型信号量是任务间资源保护的重要手段.下面结合一 ...

  8. FreeRTOS学习笔记

    FreeRTOS学习笔记 (这是我自己学习FreeRTOS整理的笔记,仅供参考) 第一部分:实现FreeRTOS内核 变量名: 定义变量时往往会把变量的类型当作前缀加在变量上 变量类型 前缀 char ...

  9. freeRtos学习笔记 (8) 任务通知

    freeRtos学习笔记 freeRtos任务通知 任务通知的优缺点 freeRtos任务控制块中包含两个32位的变量,用于任务通知,在一些情况下,任务通知可以替代信号量和事件组,并且比信号量和事件组 ...

最新文章

  1. [转] 中国的车祸为什么多?一个”海归”的亲身体验(转)
  2. Python单元测试框架 unittest详解
  3. C++Primer笔记-----day04
  4. 【机器学习算法-python实现】矩阵去噪以及归一化
  5. windows平台下caffe可视化配置
  6. cocos2d-x游戏实例(14)-纵版射击游戏(1)
  7. IOS研究之App转让流程须知具体介绍
  8. Spring Reactor教程
  9. 【C++ Primer | 15】虚函数表剖析(一)
  10. 统计数字(信息学奥赛一本通-T1239)
  11. mysql 表名规范_MYSQL数据库命名及设计规范
  12. php设置 uploadtmpdir_PHP上传 找不到临时文件夹的解决方法
  13. linux简易扫雷c语言代码,C语言代码实现简易扫雷
  14. Qt:#pragma comment(lib,“ws2_32.lib“) 报错
  15. 本特利振动变送器990-05-50-02-00
  16. 遥感导论(梅安新版)知识点概括
  17. windscribe使用方法详细指导【新手入门手把手教程】
  18. 日常中的迅捷PDF转换器
  19. 先睹为快,Go2 Error 的挣扎之路
  20. SAN光纤交换机常用命令整理(转)

热门文章

  1. Windows Azure: Blob Container的访问权限与策略设置
  2. 想找首歌来表达心情!
  3. Linux服务器网卡驱动安装及故障排除(转)
  4. Android查看挂载的分区(如oem)
  5. nboot通过DNW下载并运行eboot.nb0
  6. fso 拒绝访问_java.sql.sql异常:用户“asus”@“localhost”的访问被拒绝(使用密码:YES)...
  7. redis数据类型_认识Redis与Redis的数据类型
  8. 哪个是更早的时间 date_淘宝用户行为分析(漏斗模型+pv,uv,pv/uv,复购率,用户活跃时间段)...
  9. Mongodb分布式集群搭建
  10. Py中的类型注解【转载】