根据正点原子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 /* 2 * 1. 要使用vTaskGetRunTimeStats()函数,需满足以下条件: 3 * a 宏configGENERATE_RUN_TIME_STATS必须为1 4 * b 定义宏:portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() 配置一个高精度定时器提供时基 5 * c 定义宏:portGET_RUN_TIME_COUNTER_VALUE() 读取时基的时间值 6 */ 7 #include "main.h" 8 #include "delay.h" 9 #include "sys.h" 10 #include "usart.h" 11 #include <string.h> /*memset()*/ 12 13 #include "stm32f2xx_gpio.h" 14 #include "stm32f2xx_tim.h" 15 16 #include "FreeRTOS.h" 17 #include "task.h" 18 19 #define START_TASK_PRIO 1 /*任务优先级*/ 20 #define START_STK_SIZE 128 /*任务堆栈大小*/ 21 TaskHandle_t StartTask_Handle; /*任务句柄*/ 22 void StartTask(void *pvParameters); /*任务函数*/ 23 24 #define LED_TASK_PRIO 2 25 #define LED_STK_SIZE 128 26 TaskHandle_t LedTask_Handle; 27 void LedTask(void *pvParameters); 28 29 #define RUNTIMESTATS_TASK_PRIO 3 30 #define RUNTIMESTATS_STK_SIZE 128 31 TaskHandle_t RunTimeStats_Handle; 32 void RunTimeStatsTask(void *pvParameters); 33 34 35 char RunTimeInfo[400]; /*保存任务运行时间信息*/ 36 uint8_t ControlCounter = 0; 37 volatile unsigned long long FreeRTOSRunTimeTicks; 38 39 40 /***** 声明 *****/ 41 static void SystemInitial(void); 42 static void GPIO_LED_Configuration(void); 43 static void Timer4_Configuration(void); 44 static void Timer4_NVIC_Configuration(void); 45 46 static void GPIO_LED_Configuration(void) 47 { 48 GPIO_InitTypeDef GPIO_InitStructure; 49 50 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 51 52 GPIO_InitStructure.GPIO_Pin = LED_POWER | LED_RUN | LED_ALARM; 53 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 54 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 55 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 56 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 57 GPIO_Init(GPIOE, &GPIO_InitStructure); 58 59 LED_Power_On(); 60 GPIO_SetBits(GPIOE, LED_RUN); 61 } 62 63 64 void StartTask(void *pvParameters) 65 { 66 taskENTER_CRITICAL(); /*进入临界区*/ 67 68 xTaskCreate((TaskFunction_t )LedTask, /*任务函数*/ 69 (const char * )"LedTask", /*任务名称*/ 70 (uint16_t )LED_STK_SIZE, /*任务堆栈大小*/ 71 (void * )NULL, /*传递给任务函数的参数*/ 72 (UBaseType_t )LED_TASK_PRIO, /*任务优先级*/ 73 (TaskHandle_t )&LedTask_Handle); /*任务句柄*/ 74 75 xTaskCreate((TaskFunction_t )RunTimeStatsTask, /*任务函数*/ 76 (const char * )"RunTimeStatsTask", /*任务名称*/ 77 (uint16_t )RUNTIMESTATS_STK_SIZE, /*任务堆栈大小*/ 78 (void * )NULL, /*传递给任务函数的参数*/ 79 (UBaseType_t )RUNTIMESTATS_TASK_PRIO, /*任务优先级*/ 80 (TaskHandle_t )&RunTimeStats_Handle); /*任务句柄*/ 81 82 vTaskDelete(StartTask_Handle); /*删除开始任务*/ 83 taskEXIT_CRITICAL(); /*退出临界区*/ 84 } 85 86 void LedTask(void *pvParameters) 87 { 88 while (1) 89 { 90 GPIOE->ODR ^= LED_RUN; 91 vTaskDelay(1000); 92 } 93 } 94 95 void RunTimeStatsTask(void * pvParameters) 96 { 97 while (1) 98 { 99 if (5 == ControlCounter) 100 { 101 ControlCounter = 0; 102 memset(RunTimeInfo, 0, 400); /*信息缓冲区清零*/ 103 vTaskGetRunTimeStats(RunTimeInfo); /*获取任务运行时间信息*/ 104 printf("任务名\t\t运行时间\t运行所占百分比\r\n"); 105 printf("%s\r\n", RunTimeInfo); 106 } 107 vTaskDelay(10); 108 } 109 } 110 111 112 113 static void SystemInitial(void) 114 { 115 /*组4,16级抢占优先级,无响应优先级*/ 116 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); 117 118 DelayInitial(); 119 USART1_Initialization(); 120 GPIO_LED_Configuration(); 121 ConfigureTimeForRunTimeStats(); 122 } 123 124 int main(void) 125 { 126 SystemInitial(); 127 128 /*创建开始任务*/ 129 xTaskCreate((TaskFunction_t )StartTask, /*任务函数*/ 130 (const char * )"StartTask", /*任务名称*/ 131 (uint16_t )START_STK_SIZE, /*任务堆栈大小*/ 132 (void * )NULL, /*传递给任务函数的参数*/ 133 (UBaseType_t )START_TASK_PRIO, /*任务优先级*/ 134 (TaskHandle_t * )&StartTask_Handle); /*任务句柄*/ 135 136 /*开启任务调度*/ 137 vTaskStartScheduler(); 138 } 139 140 ///////////////////定时器4////////////////////////////////////// 141 /***** Timer4 *****/ 142 void ConfigureTimeForRunTimeStats(void) 143 { 144 FreeRTOSRunTimeTicks = 0; 145 Timer4_Configuration(); 146 Timer4_NVIC_Configuration(); 147 } 148 149 /*timer4:APB1 30MHz*/ 150 static void Timer4_Configuration(void) 151 { 152 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 153 154 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); 155 156 /*预分频系数*/ 157 TIM_TimeBaseStructure.TIM_Prescaler = 30-1; 158 /*计数值,每计50个数,产生一次中断. 50*(1/1MHk) = 50us */ 159 TIM_TimeBaseStructure.TIM_Period = 50-1; 160 /*设置计数器模式为向上计数模式*/ 161 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 162 /*设置时钟分频系数,TIM_CKD_DIV1不分频*/ 163 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 164 165 TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure); 166 167 /*使能TIM4外设。在使用外设时,不仅要使能其时钟,还要调用此函数使能外设才可以正常使用*/ 168 TIM_Cmd(TIM4, ENABLE); 169 170 /*清除溢出中断标志*/ 171 TIM_ClearFlag(TIM4, TIM_IT_Update); 172 173 /*开启中断*/ 174 TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); 175 } 176 177 /**/ 178 static void Timer4_NVIC_Configuration(void) 179 { 180 NVIC_InitTypeDef NVIC_InitStructure; 181 182 /*3级抢占优先级,0级响应优先级*/ 183 NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; 184 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; 185 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 186 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 187 188 NVIC_Init(&NVIC_InitStructure); 189 } 190 191 /*中断服务函数*/ 192 uint16_t Timer4Counter = 0; 193 void TIM4_IRQHandler(void) 194 { 195 if (TIM_GetITStatus(TIM4, TIM_IT_Update)==SET) 196 { 197 FreeRTOSRunTimeTicks++; 198 199 Timer4Counter++; 200 if (Timer4Counter>=40000) 201 { 202 Timer4Counter = 0; 203 GPIOE->ODR ^= LED_ALARM; 204 205 ControlCounter++; 206 } 207 } 208 TIM_ClearITPendingBit(TIM4, TIM_IT_Update); 209 } 210 211 /***************************END OF FILE***************************/