单片机 > 单片机程序设计 > 详情

STM32CubeMX中FreeRTOS系统CPU使用率监测测试

发布时间:2020-09-02 发布时间:
|

1.测试描述:


使用STM32CubeMX自动配置的工程,对其提供的FreeRTOS系统的CPU使用率进行监测,并通过串口打印。


2.测试环境:


(1)软件环境:STM32CubeMX-4.22.0,IAR-7.5,串口调试工具 
(2)硬件环境:原子战舰V3开发板


3.测试准备:


(1)STM32CubeMX软件主要配置:


管脚和其他外设的配置直接省略了,具体的可查看源码文件里的ioc文件。下面贴出主要的系统方面配置图: 

首先是Configuration界面,从图中可以看出测试工程使用的东西并不多;



点击中间层的FREERTOS进入系统配置界面,主要注意下图中红色标注的部分;



下图对一些系统的函数进行使能和失能操作,由于测试工程里有用到vTaskDelayUntil函数,所以对其使能。



(2)IAR软件配置:


首先从stm32官网下载的固件包里找到如下文件: 

 

细心的人会发现这个是在F7的固件包里找的,当然F1的固件包里也可以找到,所以此方式也适用于其他支持FreeRTOS的stm32芯片。 

将两个文件复制到测试工程文件夹内,对应地址如下图(地址在后面添加头文件时有用,可实际根据自身情况拖放): 



在工程里添加cpu_utils.c文件



在工程配置选项里添加cpu_utils.h文件路径,这里我用的是相对路径,如果换别的电脑上时使用只需要重新ReBuild一下工程就好了。



在cpu_utils.h里添加使用到的两个头文件:



最后在FreeRTOSConfig.h文件的用户代码区添加如下两段代码。这一步很重要,如果没有,那么监测到的使用率一直为100%。



4.测试代码:


  • /* Includes ------------------------------------------------------------------*/

  • #include "FreeRTOS.h"

  • #include "task.h"

  • #include "cmsis_os.h"

  •  

  • /* USER CODE BEGIN Includes */     

  • #include "gpio.h"

  • #include "string.h"

  • #include "usart.h"

  • #include "cpu_utils.h"

  • /* USER CODE END Includes */

  •  

  • /* Variables -----------------------------------------------------------------*/

  • osThreadId defaultTaskHandle;

  •  

  • /* USER CODE BEGIN Variables */

  •  

  • #define START_TASK_PRIO           1

  • #define START_STK_SIZE            64

  • TaskHandle_t xHandleTaskStart;

  • void StartTask(void const * argument);

  •  

  • #define LED1_TASK_PRIO            5

  • #define LED1_STK_SIZE             128

  • TaskHandle_t xHandleTaskLED1;

  • void TaskLED1(void const * argument);

  •  

  • #define LED2_TASK_PRIO            6

  • #define LED2_STK_SIZE             128

  • TaskHandle_t xHandleTaskLED2;

  • void TaskLED2(void const * argument);

  •  

  • void MX_FREERTOS_Init(void) {

  • //系统自建的任务,不去动它,屏蔽了也没关系。

  •   osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);

  •   defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  •  

  •   /* USER CODE BEGIN RTOS_QUEUES */

  •   /* add queues, ... */

  •   //创建开始任务

  •   xTaskCreate((TaskFunction_t )StartTask,

  •         (const char *  )"Start Task",

  •         (uint16_t       )START_STK_SIZE,

  •         (void *         )NULL,

  •         (UBaseType_t    )START_TASK_PRIO,

  •         (TaskHandle_t * )&xHandleTaskStart);       

  •   /* USER CODE END RTOS_QUEUES */

  • }

  •  

  • //开始任务,用于创建两个新的测试任务

  • void StartTask(void const * argument)

  • {

  •   taskENTER_CRITICAL();

  •   xTaskCreate((TaskFunction_t )TaskLED1,

  •               (const char *  )"LED1 Task",

  •               (uint16_t       )LED1_STK_SIZE,

  •               (void *         )str1,

  •               (UBaseType_t    )LED1_TASK_PRIO,

  •               (TaskHandle_t * )&xHandleTaskLED1);

  •  

  •   xTaskCreate((TaskFunction_t )TaskLED2,

  •               (const char *  )"LED2 Task",

  •               (uint16_t       )LED2_STK_SIZE,

  •               (void *         )str2,

  •               (UBaseType_t    )LED2_TASK_PRIO,

  •               (TaskHandle_t * )&xHandleTaskLED2);

  •  

  •   vTaskDelete(xHandleTaskStart);

  •   taskEXIT_CRITICAL();

  • }

  •  

  • //LED1任务

  • void TaskLED1(void const * argument)

  • {

  •   char str1[] = "TASK LED1 is Running!\r\n";

  •   portTickType xLastWakeTime;

  •   static uint16_t usage = 0;

  •   uint32_t num  = 0;

  •   char buffer[100];

  •   //延时时间单元初始值记录

  •   xLastWakeTime = xTaskGetTickCount();

  •   while(1)

  •   {

  •     //串口1发送提示字符串

  •     HAL_UART_Transmit(&huart1,(uint8_t *)str1,strlen(str1),0xFFFF);

  •     while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);

  •  

  •     //获取CPU使用率并串口打印

  •     usage = osGetCPUUsage();

  •     num = sprintf(buffer,"1---CPU 使用率为:%d%%\r\n",usage);

  •  

  •     HAL_UART_Transmit(&huart1,(uint8_t *)buffer,num,0xFFFF);

  •     while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);

  •  

  •     //LED闪烁

  •     HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);

  •     vTaskDelayUntil(&xLastWakeTime,(1000/portTICK_RATE_MS));

  •   }

  • }

  •  

  • //LED2任务

  • void TaskLED2(void const * argument)

  • {

  •   char str2[] = "TASK LED2 is Running!\r\n";

  •   portTickType xLastWakeTime;

  •  

  •   static  uint16_t usage = 0;

  •   uint32_t num  = 0;

  •   char buffer[100];

  •  

  •   //延时时间单元初始值记录

  •   xLastWakeTime = xTaskGetTickCount();

  •   while(1)

  •   {

  •     //串口1发送提示字符串

  •     HAL_UART_Transmit(&huart1,(uint8_t *)str2,strlen(str2),0xFFFF);

  •     while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);

  •  

  •     //获取CPU使用率并串口打印

  •     usage = osGetCPUUsage();

  •     num = sprintf(buffer,"2---CPU 使用率为:%d%%\r\n",usage);

  •  

  •     HAL_UART_Transmit(&huart1,(uint8_t *)buffer,num,0xFFFF);

  •     while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);

  •  

  •     //LED闪烁

  •     HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);

  •     vTaskDelayUntil(&xLastWakeTime,(300/portTICK_RATE_MS));

  •     HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);

  •     vTaskDelayUntil(&xLastWakeTime,(1200/portTICK_RATE_MS));

  •   }

  • }

  • /* USER CODE END Application */


5.测试源码分析:


在嵌入式系统中,如果当前没有任何计划的任务运行,则系统会自动切换到空闲任务当中去。当一个系统中空闲任务占用一段时间的比值越大,对应硬件CPU对于工程所留的计算余量也就越大,则这个系统的CPU使用率越低。 
实际算法可简化为以下公式:


系统使用率 = 1 - 空闲任务占用时间/总测算时间


下图中箭头指向的位置是CPU使用率计算的算法核心,它是在Tick中断发生1000次时进行一次计算处理。也就是总测算时间为1000个心跳时钟。其中计算部分对原公式右边乘上了100倍,实际计算出来的osCPU_Usage为百分数。



以下两个函数是在FreeRTOSConfig.h宏定义中提到的函数,红色数字标注的是要重点关注的地方。这两个函数就是用来测算进入空闲函数的时间。



以上两个函数通过宏定义的方式,实际调用在系统任务切换函数里。也就是在这两个位置进行处理,进而得到需要的空闲任务占用时间。



6.测试结果:


在IAR的Live Watch窗口监测的系统使用率的值、系统心跳时基和空闲任务总占用时间。



下面是串口的输出,看出系统在刚开始时使用率有一段波动,后面趋于平稳,一直处于1%。



关键字:STM32CubeMX  FreeRTOS系统  CPU使用率

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C8051F020的UART