FreeRTOS系列|处理器利用率

处理器利用率

1. 处理器利用率统计的作用

处理器利用率其实就是系统运行的程序占用的CPU资源,表示机器在某段时间程序运行的情况,如果这段时间中,程序一直在占用CPU的使用权,那么可以认为CPU的利用率是100%;CPU的利用率越高,说明机器在这个时间上运行了很多程序,反之较少。利用率的高低与CPU强弱有直接关系。比如同一段程序,如果在运算速度很慢的CPU上运行,它可能要1000ms,而在运算速度很快的CPU上运行可能只需要10ms,那么在1000ms这段时间中,前者的处理器利用率就是100%,而后者只有1%,因为1000ms内前者都在使用 CPU做运算,而后者只使用10ms的时间做运算,剩下的时间CPU可以做其他事情。

调试的时候很有必要得到当前系统的CPU利用率相关信息,但是在产品发布时,就可以去掉CPU利用率统计功能,以避免消耗系统资源。FreeRTOS 是使用一个外部的变量进行时间统计,并且消耗一个高精度的定时器,其用于定时的精度是系统时钟节拍的10-20倍。比如当前系统时钟节拍是1000Hz,那么定时器的计数节拍就要是10000-20000Hz。

但是FreeRTOS进行CPU利用率统计时,也有一定缺陷,即没有对进行CPU利用率统计时间的变量做溢出保护,一般使用的是32位变量来记录系统运行时间计数值,若按20000Hz 的中断频率计算,每50us进入一次中断,变量加一,则最大支持计数时间为:232*50us / 3600s = 59.6分钟,即运行时间超过了59.6分钟后变量将溢出,统计结果将不准确,此外系统一直响应定时器50us一次的中断会比较影响系统的性能

2. 处理器利用率统计API函数

FreeRTOS可以通过相关的配置来统计任务的运行时间信息,任务的运行时间信息提供了每个任务获取到CPU使用权总的时间。函数vTaskGetRunTimeStats( )会将统计到的信息填充到一个表里,表里面提供了每个任务的运行时间和其所占总时间的百分比,如下图示:
在这里插入图片描述

/*****************************相关宏的配置*****************************/
#define configGENERATE_RUN_TIME_STATS 			 必须置为1
#define configUSE_STATS_FORMATTING_FUNCTIONS	 必须置为1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS   初始化高精度定时器
#define portGET_RUN_TIME_COUNTER_VALUE   		 获取高精度定时器计数值
/***************************任务运行时间函数***************************/
函数原型:void vTaskGetRunTimeStats(char *pcWriteBuffer)
传 入 值:pcWriteBuffer 保存任务时间信息的存储区

3. 处理器利用率统计实例

使用STM32CubeMX配置FreeRTOS,打开相关配置,创建如下三个任务:

  • Led_Task:D2指示灯闪烁
  • Usart_Task:每隔1s向串口输出字符串
  • Key_Task:按下K_UP,打印任务的运行时间信息
3.1 STM32CubeMX设置
  • RCC设置外接HSE,时钟设置为72M

  • PC1设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平

  • PA0设置为GPIO输入模式、下拉模式;PE2/PE3/PE4设置为GPIO输入模式、上拉模式

  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位

  • 激活FreeRTOS,添加任务,设置任务名称、优先级、堆栈大小、函数名称等参数
    在这里插入图片描述在这里插入图片描述

  • 配置宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS为1
    在这里插入图片描述

  • 激活TIM6作为时间统计功能的高精度时钟,分频值为72-1,自动重装载值为50-1,所以定时器6周期是50us;打开TIM6中断
    在这里插入图片描述
    在这里插入图片描述

  • 使用FreeRTOS操作系统,一定要将HAL库的Timebase Source从SysTick改为其他定时器,选好定时器后,系统会自动配置TIM
    在这里插入图片描述

  • 输入工程名,选择路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码

3.2 MDK-ARM软件编程
  • 创建按键驱动文件key.c和key.h,参考按键输入例程
  • 初始化高精度计时器,并获取高精度定时器计数值
//#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS configureTimerForRunTimeStats
__weak void configureTimerForRunTimeStats(void){
  HAL_TIM_Base_Start_IT(&htim6);	//开启TIM6中断并启动定时器
  u32TimeCount = 0ul;		//定时器统计值初始化为0
}
//#define portGET_RUN_TIME_COUNTER_VALUE getRunTimeCounterValue 
__weak unsigned long getRunTimeCounterValue(void){
  return u32TimeCount;
} 

  • 在main.c文件中添加TIM6定时器中断回调函数,中断一次定时器计数器加一
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
  if(htim->Instance == TIM1){
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */
  if(htim->Instance == TIM6){
    u32TimeCount++;
  }
  /* USER CODE END Callback 1 */
}

  • 添加Led_Task、Usart_Task和Key_Task任务函数代码
void Led_Task(void const * argument){
  for(;;){
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_RESET);
    osDelay(500);  //1ms时基
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET);
    osDelay(500);  //1ms时基
  }
}
/*******************************************************/
void Usart_Task(void const * argument){
  for(;;){
	printf("UsartTask is Runing!\r\n");
    osDelay(1000);
  }
}
/*******************************************************/
uint8_t u8TaskListBuff[400];
void KeyTask(void const * argument){
  uint8_t key = 0;	
  for(;;){
    key = KEY_Scan(0);	
	switch(key){
	  case KEY_UP_PRES:
		memset(u8TaskListBuff, 0, 400);
		vTaskGetRunTimeStats((char*)u8TaskListBuff);
		printf("Name      Abs Time    Time\r\n");
		printf("******************************************************\r\n");
		printf("%s",u8TaskListBuff);
		printf("******************************************************\r\n");
		key = 0;
		break;
	  case KEY_DOWN_PRES:
		//....
		key = 0;
		break;
	}
	osDelay(10);
  }
}

3.3 下载验证

编译无误下载到开发板后,D2指示灯闪烁表示程序正常运行。打开串口调试助手,可以看到串口每隔1s输出相应字符;按下K_UP按键,串口打印出每个任务的运行时间信息
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值