zoukankan      html  css  js  c++  java
  • 9-FreeRTOS API获取任务使用CPU时间

    获取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个时钟节拍    
         }
             
     }

    执行结果:

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

  • 相关阅读:
    Linux 部署 nginx
    Linux 部署vue项目(使用nginx)
    git 操作规范
    mysql grant权限分配(转)。
    前端优化,包括css,jss,img,cookie
    关于js里的那一堆事件
    个人作业——软件工程实践总结作业
    Unity3D 快捷键
    Beta冲刺第二天
    Beta冲刺第一天
  • 原文地址:https://www.cnblogs.com/darren-pty/p/14267464.html
Copyright © 2011-2022 走看看