求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
要资料
 
追随技术信仰

随时听讲座
每天看新闻
 
 
FreeRTOS源码分析及应用开发
1. FreeRTOS系列 | FreeRTOS简介
2. FreeRTOS系列 | 开发环境
3. FreeRTOS系列 | 任务基础知识
4. FreeRTOS系列 | 任务创建和删除
5. FreeRTOS系列 | 任务挂起和恢复
6. FreeRTOS系列|多任务调度
7. FreeRTOS系列|时间管理
8. FreeRTOS系列|中断管理和临界段
9. FreeRTOS系列|任务堆栈
10. FreeRTOS系列 | 处理器利用率
11. FreeRTOS系列|任务相关API函数
12. FreeRTOS系列 | 列表和列表项
13. FreeRTOS系列|消息队列一
14. FreeRTOS系列|消息队列二
15. FreeRTOS系列 | 二值信号量
16. FreeRTOS系列 | 互斥信号量
17. FreeRTOS系列 | 计数信号量
18. FreeRTOS系列 | 递归互斥信号量
19. FreeRTOS系列 | 事件标志组
20. FreeRTOS系列 | 软件定时器
21. FreeRTOS系列 | 低功耗管理
22. FreeRTOS系列 | 内存管理一
23. FreeRTOS系列 | 内存管理二
 

 
目录
FreeRTOS系列|处理器利用率
作者:安迪西嵌入式
262 次浏览
6次  

处理器利用率

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( )会将统计到的信息填充到一个表里,表里面提供了每个任务的运行时间和其所占总时间的百分比,如下图示:

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按键,串口打印出每个任务的详细信息


您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码: 验证码,看不清楚?请点击刷新验证码 必填



262 次浏览
6次