FreeRTOS-06任务运行时间信息统计
根据正点原子FreeRTOS视频整理
单片机:STM32F207VC
FreeRTOS源码版本:v10.0.1
- * 1. 要使用vTaskGetRunTimeStats()函数,需满足以下条件:
- * a 宏configGENERATE_RUN_TIME_STATS必须为1
- * b 定义宏:portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() 配置一个高精度定时器提供时基
- * c 定义宏:portGET_RUN_TIME_COUNTER_VALUE() 读取时基的时间值
1. main.c
- /*
- * 1. 要使用vTaskGetRunTimeStats()函数,需满足以下条件:
- * a 宏configGENERATE_RUN_TIME_STATS必须为1
- * b 定义宏:portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() 配置一个高精度定时器提供时基
- * c 定义宏:portGET_RUN_TIME_COUNTER_VALUE() 读取时基的时间值
- */
- #include "main.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include <string.h> /*memset()*/
- #include "stm32f2xx_gpio.h"
- #include "stm32f2xx_tim.h"
- #include "FreeRTOS.h"
- #include "task.h"
- #define START_TASK_PRIO 1 /*任务优先级*/
- #define START_STK_SIZE 128 /*任务堆栈大小*/
- TaskHandle_t StartTask_Handle; /*任务句柄*/
- void StartTask(void *pvParameters); /*任务函数*/
- #define LED_TASK_PRIO 2
- #define LED_STK_SIZE 128
- TaskHandle_t LedTask_Handle;
- void LedTask(void *pvParameters);
- #define RUNTIMESTATS_TASK_PRIO 3
- #define RUNTIMESTATS_STK_SIZE 128
- TaskHandle_t RunTimeStats_Handle;
- void RunTimeStatsTask(void *pvParameters);
- char RunTimeInfo[]; /*保存任务运行时间信息*/
- uint8_t ControlCounter = ;
- volatile unsigned long long FreeRTOSRunTimeTicks;
- /***** 声明 *****/
- static void SystemInitial(void);
- static void GPIO_LED_Configuration(void);
- static void Timer4_Configuration(void);
- static void Timer4_NVIC_Configuration(void);
- static void GPIO_LED_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
- GPIO_InitStructure.GPIO_Pin = LED_POWER | LED_RUN | LED_ALARM;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOE, &GPIO_InitStructure);
- LED_Power_On();
- GPIO_SetBits(GPIOE, LED_RUN);
- }
- void StartTask(void *pvParameters)
- {
- taskENTER_CRITICAL(); /*进入临界区*/
- xTaskCreate((TaskFunction_t )LedTask, /*任务函数*/
- (const char * )"LedTask", /*任务名称*/
- (uint16_t )LED_STK_SIZE, /*任务堆栈大小*/
- (void * )NULL, /*传递给任务函数的参数*/
- (UBaseType_t )LED_TASK_PRIO, /*任务优先级*/
- (TaskHandle_t )&LedTask_Handle); /*任务句柄*/
- xTaskCreate((TaskFunction_t )RunTimeStatsTask, /*任务函数*/
- (const char * )"RunTimeStatsTask", /*任务名称*/
- (uint16_t )RUNTIMESTATS_STK_SIZE, /*任务堆栈大小*/
- (void * )NULL, /*传递给任务函数的参数*/
- (UBaseType_t )RUNTIMESTATS_TASK_PRIO, /*任务优先级*/
- (TaskHandle_t )&RunTimeStats_Handle); /*任务句柄*/
- vTaskDelete(StartTask_Handle); /*删除开始任务*/
- taskEXIT_CRITICAL(); /*退出临界区*/
- }
- void LedTask(void *pvParameters)
- {
- while ()
- {
- GPIOE->ODR ^= LED_RUN;
- vTaskDelay();
- }
- }
- void RunTimeStatsTask(void * pvParameters)
- {
- while ()
- {
- if ( == ControlCounter)
- {
- ControlCounter = ;
- memset(RunTimeInfo, , ); /*信息缓冲区清零*/
- vTaskGetRunTimeStats(RunTimeInfo); /*获取任务运行时间信息*/
- printf("任务名\t\t运行时间\t运行所占百分比\r\n");
- printf("%s\r\n", RunTimeInfo);
- }
- vTaskDelay();
- }
- }
- static void SystemInitial(void)
- {
- /*组4,16级抢占优先级,无响应优先级*/
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
- DelayInitial();
- USART1_Initialization();
- GPIO_LED_Configuration();
- ConfigureTimeForRunTimeStats();
- }
- int main(void)
- {
- SystemInitial();
- /*创建开始任务*/
- xTaskCreate((TaskFunction_t )StartTask, /*任务函数*/
- (const char * )"StartTask", /*任务名称*/
- (uint16_t )START_STK_SIZE, /*任务堆栈大小*/
- (void * )NULL, /*传递给任务函数的参数*/
- (UBaseType_t )START_TASK_PRIO, /*任务优先级*/
- (TaskHandle_t * )&StartTask_Handle); /*任务句柄*/
- /*开启任务调度*/
- vTaskStartScheduler();
- }
- ///////////////////定时器4//////////////////////////////////////
- /***** Timer4 *****/
- void ConfigureTimeForRunTimeStats(void)
- {
- FreeRTOSRunTimeTicks = ;
- Timer4_Configuration();
- Timer4_NVIC_Configuration();
- }
- /*timer4:APB1 30MHz*/
- static void Timer4_Configuration(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
- /*预分频系数*/
- TIM_TimeBaseStructure.TIM_Prescaler = -;
- /*计数值,每计50个数,产生一次中断. 50*(1/1MHk) = 50us */
- TIM_TimeBaseStructure.TIM_Period = -;
- /*设置计数器模式为向上计数模式*/
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- /*设置时钟分频系数,TIM_CKD_DIV1不分频*/
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
- /*使能TIM4外设。在使用外设时,不仅要使能其时钟,还要调用此函数使能外设才可以正常使用*/
- TIM_Cmd(TIM4, ENABLE);
- /*清除溢出中断标志*/
- TIM_ClearFlag(TIM4, TIM_IT_Update);
- /*开启中断*/
- TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
- }
- /**/
- static void Timer4_NVIC_Configuration(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- /*3级抢占优先级,0级响应优先级*/
- NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- /*中断服务函数*/
- uint16_t Timer4Counter = ;
- void TIM4_IRQHandler(void)
- {
- if (TIM_GetITStatus(TIM4, TIM_IT_Update)==SET)
- {
- FreeRTOSRunTimeTicks++;
- Timer4Counter++;
- if (Timer4Counter>=)
- {
- Timer4Counter = ;
- GPIOE->ODR ^= LED_ALARM;
- ControlCounter++;
- }
- }
- TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
- }
- /***************************END OF FILE***************************/
2. main.h
- /**/
- #ifndef __MAIN_H__
- #define __MAIN_H__
- #define LED_POWER GPIO_Pin_2 /*PE2*/
- #define LED_RUN GPIO_Pin_3 /*PE3*/
- #define LED_ALARM GPIO_Pin_4 /*PE4*/
- #define LED_Power_On() GPIO_ResetBits(GPIOE, LED_POWER)
- extern void ConfigureTimeForRunTimeStats(void);
- #endif /*__MAIN_H__*/
- /***************************END OF FILE***************************/
3. sys.c
- /**/
- #include "sys.h"
- #include "stdio.h"
- #pragma import(__use_no_semihosting)
- //标准库需要的支持函数
- struct __FILE
- {
- int handle;
- };
- FILE __stdout;
- //定义_sys_exit()以避免使用半主机模式
- void _sys_exit(int x)
- {
- x = x;
- }
- /* //重定义fputc函数
- int fputc(int ch, FILE *f)
- {
- while((USART1->SR&0X40)==0) //循环发送,直到发送完毕
- USART1->DR = (u8) ch;
- return ch;
- } */
- /***************************END OF FILE***************************/
4. sys.h
- /**/
- #ifndef __SYS_H__
- #define __SYS_H__
- /*0不支持OS,1支持OS*/
- #define SYSTEM_SUPPORT_OS 1 /*定义系统文件夹是否支持OS*/
- #endif /*__SYS_H__*/
- /***************************END OF FILE***************************/
5. delay.c
- /**/
- #include "delay.h"
- #include "sys.h"
- /*如果需要使用OS,则包括下面的头文件即可*/
- #if SYSTEM_SUPPORT_OS
- #include "FreeRTOS.h"
- #include "task.h"
- #endif
- __IO uint32_t TimingDelay;
- //////////////////////////
- //static uint8_t fac_us = 0;
- //////////////////////////
- /***** 声明 *****/
- extern void xPortSysTickHandler(void);
- /*systick中断服务函数,使用FreeRTOS时用到*/
- void SysTick_Handler(void)
- {
- TimingDelayDecrement();
- if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) /*系统已运行*/
- {
- xPortSysTickHandler();
- }
- }
- void DelayInitial(void)
- {
- /*
- * SystemCoreClock / 1000 1ms中断一次
- * SystemCoreClock / 100000 10us中断一次
- * SystemCoreClock / 1000000 1us中断一次
- */
- if (SysTick_Config(SystemCoreClock / ))
- {
- while ();
- }
- /*关闭systick timer定时器*/
- /* SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;*/
- /*使能滴答定时器*/
- SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
- }
- //void DelayNus(uint32_t nus)
- //{
- // uint32_t ticks;
- // uint32_t told, tnow, tcnt = 0;
- // uint32_t reload = SysTick->LOAD;
- //
- // fac_us = SystemCoreClock / 1000000;
- // ticks = nus * fac_us;
- // told = SysTick->VAL;
- //
- // while (1)
- // {
- // tnow = SysTick->VAL;
- // if (tnow != told)
- // {
- // if (tnow < told)
- // {
- // tcnt += told - tnow;
- // }
- // else
- // {
- // tcnt += reload - tnow + told;
- // }
- // told = tnow;
- // if (tcnt >= ticks) break;
- // }
- // }
- //}
- ///*不会引起调度*/
- //void DelayXms(uint32_t nms)
- //{
- // uint32_t i;
- //
- // for (i=0;i<nms;++i)
- // {
- // DelayNus(1000);
- // }
- //}
- /*
- * 本函数在中断函数中调用,滴答定时器中断一次调用一次。
- */
- void TimingDelayDecrement(void)
- {
- if (TimingDelay != 0x00)
- {
- TimingDelay--;
- }
- }
- /*
- * TimingDelay值在TimingDelayDecrement函数中递减
- */
- void DelayNms(uint32_t nTimes)
- {
- TimingDelay = nTimes;
- while (TimingDelay!=); //等待计数停止
- }
- /***************************END OF FILE***************************/
6. delay.h
- /**/
- #ifndef __DELAY_H__
- #define __DELAY_H__
- #include "stm32f2xx.h"
- #include <stdint.h>
- extern void DelayInitial(void);
- extern void TimingDelayDecrement(void);
- extern void DelayNms(uint32_t nTimes);
- /////////////////////////
- extern void DelayXms(uint32_t nms);
- /////////////////////////
- #endif /*__DELAY_H__*/
- /***************************END OF FILE***************************/
7. usart.c
- /*
- * USART1: 中断优先级选择第4组, 3级抢占优先级 无响应优先级
- */
- #include "usart.h"
- #include "stdio.h" /*printf*/
- #include "stm32f2xx.h"
- #include "stm32f2xx_gpio.h"
- #include "stm32f2xx_rcc.h"
- #include "stm32f2xx_usart.h"
- uint8_t USART1_RxBuffer[USART1_RECEIVE_SIZE];
- uint8_t Flag_USART1Receive = ;
- uint8_t USART1_ReceiveCount = ;
- uint8_t USART1_ReceiveIndex = ;
- void USART1_Initialization(void)
- {
- USART1_GPIO_Configuration();
- USART1_NVIC_Configuration();
- /*USART1使能接收中断*/
- // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
- /*USART1使能发送中断*/
- /* USART_ITConfig(USART1, USART_IT_TXE, ENABLE); */
- }
- /*
- */
- void USART1_GPIO_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
- GPIO_PinAFConfig(GPIOA, , GPIO_AF_USART1); /*GPIO连接到串口1上,PA9-TXD*/
- GPIO_PinAFConfig(GPIOA, , GPIO_AF_USART1); /*GPIO连接到串口1上,PA10-RXD*/
- /*tx, PA9*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- /*rx, PA10*/
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- /*配置波特率9600*/
- USART_InitStructure.USART_BaudRate = ;
- /*配置串口的模式。为了配置双线全双工通讯,需要把Rx和Tx模式都开启. Tx发送使能和Rx接收使能*/
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- /*无奇偶校验*/
- USART_InitStructure.USART_Parity = USART_Parity_No;
- /*1停止位*/
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- /*配置串口传输字长8位*/
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- /*不采用硬件流控制*/
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- /*向寄存器写入配置参数*/
- USART_Init(USART1, &USART_InitStructure);
- /*使能USART1外设。在使用外设时,不仅要使能其时钟,还要调用此函数使能外设才可以正常使用*/
- USART_Cmd(USART1, ENABLE);
- }
- //void USART1_SendNChar(uint8_t *str, uint8_t n)
- //{
- // /*发送区是否为空*/
- // while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
- //
- // while (n--)
- // {
- // USART_SendData(USART1, (uint8_t)(*str++));
- // /*是否发送完成*/
- // while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
- // }
- //}
- /*
- * 如果一次发送多个字节数据,可能会多次进入此函数
- * 调用时,应先延时几十毫秒,确保把数据都接收完
- */
- //void USART1_ReceiveIRQ(void)
- //{
- // /*如果寄存器中有数据*/
- // while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET)
- // {
- // USART1_RxBuffer[USART1_ReceiveIndex++] = USART_ReceiveData(USART1);
- // USART1_ReceiveCount++;
- // }
- //
- // Flag_USART1Receive = 1;
- //}
- void USART1_NVIC_Configuration(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- /*中断优先级选择第1组*/
- // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
- /*3级抢占优先级 0级响应优先级*/
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- /*重定义fputc函数 2种方法都可以*/
- /*
- int fputc(int ch,FILE *f)
- {
- while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);
- USART_SendData(USART1,(uint8_t)ch);
- while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);
- return (ch);
- }
- */
- int fputc(int ch, FILE *f)
- {
- while((USART1->SR&0X40)==) /*循环发送,直到发送完毕*/
- {}
- USART1->DR = (uint8_t)ch;
- return ch;
- }
- /***************************END OF FILE***************************/
8. usart.h
- /*
- *
- */
- #ifndef __USART_H__
- #define __USART_H__
- #include <stdint.h> /* uint8_t */
- #define USART1_RECEIVE_SIZE 20
- void USART1_Initialization(void);
- void USART1_GPIO_Configuration(void);
- void USART1_SendNChar(uint8_t *str, uint8_t n);
- void USART1_ReceiveIRQ(void);
- void USART1_NVIC_Configuration(void);
- #endif /*__USART_H__*/
- /***************************END OF FILE***************************/
打印结果:
- 问题:
- 1. 在串口助手中,只显示:任务名、运行时间、运行所占百分比这一行,不显示LedTask等信息。
- 解决:中断服务函数中,忘记这一行:FreeRTOSRunTimeTicks++;
FreeRTOS-06任务运行时间信息统计的更多相关文章
- FreeRTOS任务运行时间信息统计
相关宏的设置 configGENERATE_RUN_TIME_STATS //使能 portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() //配置一个高精度定时器/计数器提 ...
- 12C CLONE PDB and config service_listener
Clone PDB PtestDEV to Ptestuat in testuat 1) Clone PtestDEV to Ptestuat C:\Windows\system32> ...
- Oracle——listener数据库监听 lsnrctl
lsnrctl(Listener Control)是一个SQL*Net工具,用于控制数据库listener,这个工具提供了命令用于控制listener的启动.停止,查看listener的状态,改变li ...
- 【FreeRTOS学习06】深度解剖中断与任务之间同步的具体使用场景
嵌入式系统中中断是必不可少的一部分: [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 1 前言 2 中断特点 3 延迟中断处理 3.1 信号量的使用 3.2 ...
- 在Amazon FreeRTOS V10中使用运行时统计信息
在MCU on Eclipse网站上看到Erich Styger在8月2日发的博文,一篇关于在Amazon FreeRTOS V10中使用运行时统计信息的文章,本人觉得很有启发,特将其翻译过来以备参考 ...
- C#中提供的精准测试程序运行时间的类Stopwatch
C#中提供的精准测试程序运行时间的类Stopwatch http://www.cnblogs.com/ret00100/archive/2010/08/06/1793680.html 在需要对程序的执 ...
- FreeRTOS随记
任务函数原型: void ATaskFunction(void * pvParameters); 任务不允许从实现函数中返回.如果一个任务不再需要,可以用vTaskDelete()删除; 一个任务函数 ...
- C# 精准获取代码运行时间
纯粹转载,转载请注明参考链接及作者! 参考链接:http://www.cnblogs.com/ret00100/archive/2010/08/06/1793680.html,作者:博客园 大佬辉 ...
- FreeRTOS——任务管理
1. FreeRTOS 任务不允许以任何方式从实现函数中返回——他们绝不能有一条“return”语句,也不可能执行到函数的末尾.如果一个函数不需要,可以将其删除,如在任务中使用函数vTaskDelet ...
随机推荐
- tomcat端口作用
<Server port="8005" shutdown="SHUTDOWN"> <Connector port="8080&q ...
- Django学习笔记:为Model添加Action
|- Django版本:1.8 |- Python版本:3.4 models.py 1 class Story(models.Model): #编辑Story状态 STATUS_CHOICES = ( ...
- Tag recommendaion... 论文中的小例子,使用HOSVD算法推荐
本文内容来自于论文:Tag recommendations based on tensor dimensioanlity reduction 在社会标签系统中,存在三元关系,用户-物品-标签.这些数据 ...
- [GO]用go语言实现区块链工作原理
基本原理这里就不写了,只写一个简单demo的实现 首先得有一个区块用来存储区块头和区块体 type Block struct { Version int64 PreBlockHash []byte H ...
- Spring框架总结(三)
SpringIOC容器 一.创建对象 SpringIOC容器,是spring核心内容. 作用: 创建对象 & 处理对象的依赖关系 IOC容器创建对象: 创建对象, 有几种方式: 1) 调用无参 ...
- SQl语句收藏
/* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限验证登录MySQL */ mysq ...
- 编写高质量代码改善C#程序的157个建议——建议127:用形容词组给接口命名
建议127:用形容词组给接口命名 接口规范的是“Can do”,也就是说,它规范的是类型可以具有哪些行为.所以,接口的命名应该是一个形容词,如: IDisposable表示可以被释放 IEnumera ...
- Getting Started with Node.js on Heroku
NodeJS应用托管平台 https://devcenter.heroku.com/articles/getting-started-with-nodejs#dyno-sleeping-and-sca ...
- Windows pip
pip 最常用命令(go语言用go get) 显示版本和路径 pip --version 获取帮助 pip --help 升级 pip pip install -U pip 如果这个升级命令出现问题 ...
- jeecms栏目模型和内容模型的使用以及对应前台的标签中的属性名
第一步:模型管理-添加模型: 栏目模板前缀设定方案下的channel目录下的ch_menu.html作为浏览栏目的模板页.对应访问网址:项目名/栏目名(一级或者二级栏目如news或者gnxw)/ind ...