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

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%。

这里写图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值