9-FreeRTOS API获取任务使用CPU时间

摘要:
获取CPU时间的API:vTaskGetRunTimeStats()获取任务运行时间信息。此函数统计任务的运行时间,以表的形式组织计算的运行时间信息,并将其存储在用户设置的缓冲区中。缓冲区的第一个地址通过参数传递给函数vTaskGetRunTimeStats()。做好初步准备:(1)启用宏配置GENERATE_ RUN_ TIME_ STATS1(2)实现两个宏① 并配置高精度计时器

获取CPU时间的API:

vTaskGetRunTimeStats() 获取任务运行时间信息,此函数会统计任务的运行时间,并且将统计到的运行时间信息按照表格的形式组织在一起并存放在用户设置的缓冲区里面,缓冲区的首地址通过参数传递给函数 vTaskGetRunTimeStats()

 

获取前期准备:

(1)开启宏configGENERATE_RUN_TIME_STATS 1
(2)实现两个宏

① 配置一个高精度定时器/计数器提供时基,因为时间统计功能需要用户提供一个高精度的时钟,这里使用定时器 3这个时钟的精度要比 FreeRTOS 的系统时钟高,大约 10~20 倍即可
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()  ConfigureTimeForRunTimeStats()  //函数 ConfigureTimeForRunTimeStats()其实就是初始化定时器

② 读取时基时间值 

#define portGET_RUN_TIME_COUNTER_VALUE()       FreeRTOSRunTimeTicks 

实验代码:

①时基的实现:

//FreeRTOS时间统计所用的节拍计数器
volatile unsigned long long FreeRTOSRunTimeTicks;

//初始化TIM3使其为FreeRTOS的时间统计提供时基
void ConfigureTimeForRunTimeStats(void)
{
    //为72M/72=1M,自动重装载为50-1,那么定时器周期就是50us
    FreeRTOSRunTimeTicks=0;
    TIM6_Time_Init(50-1,72-1);    //初始化TIM6
}


//1/(72 000 000÷psc)×arr~5ms
void TIM6_Time_Init(u16 arr,u16 psc)//如arr=49 psc=7199 ---10khz(0.1ms)--5ms
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef         NVIC_InitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE); //72M
        
    NVIC_InitStructure.NVIC_IRQChannel =TIM6_IRQn;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 4;  //抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;  //响应优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE; 
    NVIC_Init(&NVIC_InitStructure);
    
    TIM_TimeBaseStructure. TIM_Period = arr;//自动重装值
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //时钟预分频数
    TIM_TimeBaseInit(TIM6,&TIM_TimeBaseStructure); //初始化TIM6
    TIM_ClearFlag(TIM6,TIM_FLAG_Update); //清除计数器中断标志位
    
    TIM_ITConfig(TIM6,TIM_IT_Update, ENABLE );//TIM中断使能
  TIM_Cmd(TIM6, ENABLE); //使能定时器
}


void TIM6_IRQHandler(void)   
{
    
  if(TIM_GetITStatus(TIM6, TIM_IT_Update)) //是否产生中断
   {  

         FreeRTOSRunTimeTicks++;   //FreeRTOS时间统计所用的节拍计数器
         TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清除中断标志位
   }
}

②基本功能,按下按键串口打印出每个任务所占用的CPU时间

 //----------------------------------------任务优先级
 #define START_TASK_PRIO     1 
 #define TASK1_PRIO          2 
 #define TASK2_PRIO          3 //优先级高
 
 
 //----------------------------------------任务堆栈大小
 #define START_STK_SIZE 128 
 #define TASK1_STK_SIZE 128 
 #define TASK2_STK_SIZE 256 

 
 //----------------------------------------任务句柄
 TaskHandle_t Task1_Handler; 
 TaskHandle_t Task2_Handler; 
 TaskHandle_t StartTask_Handler; 

 
 
 //----------------------------------------任务函数
 void start_task(void *pvParameters); 
 void task1_task(void *pvParameters); 
 void task2_task(void *pvParameters); 

 char InfoBuffer[1000];                //保存信息的数组
 
 int main(void)
 {
   BaseType_t OS;
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);  
   User_GPIO_Init();
     Delay_init();
     USART_Config();
     
     
     OS= xTaskCreate(
                                            (TaskFunction_t        ) start_task,       //任务函数
                                            (const char *          )  "start_task",    //任务名
                                            (configSTACK_DEPTH_TYPE) START_STK_SIZE,   //堆栈大小
                                            (void *                )NULL,              //传递给任务函数的参数
                                            (UBaseType_t           ) START_TASK_PRIO,  //任务优先级
                                            (TaskHandle_t *        ) &StartTask_Handler  //任务句柄
                    );
                                  
     if(OS==pdPASS) 
         GPIO_SetBits(GPIOA, GPIO_Pin_8);
         
     vTaskStartScheduler(); //开启任务调度
     
 }
 
 
 void start_task(void *pvParameters)
 {
  
         taskENTER_CRITICAL(); //进入临界区
         
       //创建任务Task1
xTaskCreate((TaskFunction_t )task1_task, //任务函数
         (const char* )"task1_task", //任务名称
         (uint16_t )TASK1_STK_SIZE, //任务堆栈大小
         (void* )NULL,
         (UBaseType_t )TASK1_PRIO, //任务优先级
         (TaskHandle_t* )&Task1_Handler); //任务句柄
 
xTaskCreate((TaskFunction_t )task2_task, //任务函数
         (const char* )"task2_task", //任务名称
         (uint16_t )TASK2_STK_SIZE, //任务堆栈大小
         (void* )NULL,
         (UBaseType_t )TASK2_PRIO, //任务优先级
         (TaskHandle_t* )&Task2_Handler); //任务句柄           
                 
         vTaskDelete(StartTask_Handler); //vTaskDelete(NULL)也可以   删除开始任务
         taskEXIT_CRITICAL();            //退出临界区
 }
 
 
 //任务1
 void task1_task(void *pvParameters)
 {  
     while(1)
     {
             
       vTaskDelay(5000);      //vTaskDelay      delay_xms不发生任务切换
     }
         
 }
 
 
  //任务2
 void task2_task(void *pvParameters)
 {  
       uint8_t key=0;
     while(1)
     {
       key=KEY_Scan();
             if(key==TASK2_SUSPEND)
             {
               printf("按下
");
               memset(InfoBuffer,0,1000);                //信息缓冲区清零
                 vTaskGetRunTimeStats(InfoBuffer);        //获取任务运行时间信息
                 printf("任务名		运行时间	运行所占百分比
");
               printf("%s
",InfoBuffer);
             }
             vTaskDelay(10);                      //延时10ms,也就是1000个时钟节拍    
     }
         
 }

执行结果:

9-FreeRTOS API获取任务使用CPU时间第1张

 vTaskGetRunTimeStats()相对来说会很耗时间,所以不要太过于频繁的调用此函数,测试阶段可以使用此函数来分析任务的运行情况。 还有就是运行时间不是真正的运行时间,真正的时间值要乘以 100us
因为上面实现的时基为100us, FreeRTOS的时基为1ms,正好是其精度的10倍。

免责声明:文章转载自《9-FreeRTOS API获取任务使用CPU时间》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Zookeeper入门安装Docker版MS SQL Server并远程连接SQL Server下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

剖析CPU温度监控技术【转】

转自:http://blog.csdn.net/hunanchenxingyu/article/details/46476545 迄今为止还没有一种cpu散热系统能保证永不失效。失去了散热系统保护伞的“芯”,往往会在几秒钟内永远停止“跳动”。值得庆幸的是,聪明的工程师们开发出有效的CPU温度监控、保护技术。以特殊而敏锐的“嗅觉”随时监测CPU的温度变化,并...

Python多进程和多线程(跑满CPU)及IO模型详解

目录 Python多进程和多线程(跑满CPU)IO模型详解 Python多进程和多线程(跑满CPU) 转载自:https://www.liaoxuefeng.com/wiki/1016959663602400/1017627212385376 Python多进程和多线程(跑满CPU****) 概念 任务可以理解为进程(process),如打开一...

PHP stdClass类 使用

总结一下: stdClass类是PHP的一个内部保留类,初始时没有成员变量也没成员方法,所有的魔术方法都被设置为NULL,可以使用其传递变量参数,但是没有可以调用的方法。stdClass类可以被继承,只是这样做没有什么意义。 这是zend_builtin_module的模块初始化函数,在PHP内核进行模块初始化操作时会自动加载这个函数, 这样,stdCla...

Adobe flash cs5 的Java运行时环境初始化错误 完美解决方法

Adobe flash cs5 的Java运行时环境初始化错误 完美解决方法 下载网络上的Adobe flash cs5 精简版(绿色版),Java运行时环境初始化时出现错误,你可能需要重装Flash。 adobe cs 5的java运行时(Runtime)放到windows公共目录下面了。 因为adobe 有很多的产品用到了java Runtime 运行...

Mac电脑mds_store进程占用cpu过高

  mds、mds_stores、mdworker占用大量的CPU,是因为系统在建立索引,开机后的一段时间比较明显 解决方案1: sudo mdutil -a -i off    # 关闭sudo mdutil -a -i on # 还原 解决方案二: 关闭控制聚焦参数文件的加载: sudo launchctl unload -w /System/L...

iOS阶段学习第12天笔记(类的初始化)

iOS学习(OC语言)知识点整理 一、类的初始化 1)init初始化方法(构造方法):一般和alloc一起调用,用于给成员变量初始化。 2)id类型:相当于C中的void*,可以指向任何对象,不能加*,类似.net或java中的泛型。 3)带参的初始化方法(自定义的初始化方法),是实例方法,必须以initWith开头 。例如: 1 -(id)initWit...