FreeRTOS-05任务相关API函数
根据正点原子FreeRTOS视频整理
单片机:STM32F207VC
FreeRTOS源码版本:v10.0.1
任务相关API函数:
1. main.c
1 /* 2 * 3 */ 4 #include "main.h" 5 #include "delay.h" 6 #include "sys.h" 7 #include "usart.h" 8 9 #include "stm32f2xx_gpio.h" 10 11 #include "FreeRTOS.h" 12 #include "task.h" 13 14 #define START_TASK_PRIO 1 /*任务优先级*/ 15 #define START_STK_SIZE 128 /*任务堆栈大小*/ 16 TaskHandle_t StartTask_Handle; /*任务句柄*/ 17 void StartTask(void *pvParameters); /*任务函数*/ 18 19 #define LED_TASK_PRIO 2 20 #define LED_STK_SIZE 128 21 TaskHandle_t LedTask_Handle; 22 void LedTask(void *pvParameters); 23 24 #define QUERY_TASK_PRIO 3 25 #define QUERY_STK_SIZE 256 26 TaskHandle_t QueryTask_Handle; 27 void QueryTask(void *pvParameters); 28 29 char InfoBuffer[1000]; /*保存信息的数组*/ 30 31 32 /***** 声明 *****/ 33 static void SystemInitial(void); 34 static void GPIO_LED_Configuration(void); 35 36 static void GPIO_LED_Configuration(void) 37 { 38 GPIO_InitTypeDef GPIO_InitStructure; 39 40 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 41 42 GPIO_InitStructure.GPIO_Pin = LED_POWER | LED_RUN; 43 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 44 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 45 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 46 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 47 GPIO_Init(GPIOE, &GPIO_InitStructure); 48 49 LED_Power_On(); 50 GPIO_SetBits(GPIOE, LED_RUN); 51 } 52 53 54 void StartTask(void *pvParameters) 55 { 56 taskENTER_CRITICAL(); /*进入临界区*/ 57 58 xTaskCreate((TaskFunction_t )LedTask, /*任务函数*/ 59 (const char * )"LedTask", /*任务名称*/ 60 (uint16_t )LED_STK_SIZE, /*任务堆栈大小*/ 61 (void * )NULL, /*传递给任务函数的参数*/ 62 (UBaseType_t )LED_TASK_PRIO, /*任务优先级*/ 63 (TaskHandle_t )&LedTask_Handle); /*任务句柄*/ 64 65 xTaskCreate((TaskFunction_t )QueryTask, /*任务函数*/ 66 (const char * )"QueryTask", /*任务名称*/ 67 (uint16_t )QUERY_STK_SIZE, /*任务堆栈大小*/ 68 (void * )NULL, /*传递给任务函数的参数*/ 69 (UBaseType_t )QUERY_TASK_PRIO, /*任务优先级*/ 70 (TaskHandle_t )&QueryTask_Handle); /*任务句柄*/ 71 72 vTaskDelete(StartTask_Handle); /*删除开始任务*/ 73 taskEXIT_CRITICAL(); /*退出临界区*/ 74 } 75 76 void LedTask(void *pvParameters) 77 { 78 while (1) 79 { 80 GPIOE->ODR ^= LED_RUN; 81 vTaskDelay(1000); 82 } 83 } 84 85 void QueryTask(void * pvParameters) 86 { 87 UBaseType_t x; 88 /*1. 函数uxTaskPriorityGet()的使用*/ 89 printf("/*********** 1. 函数uxTaskPriorityGet()的使用 ***********/\r\n"); 90 x = uxTaskPriorityGet(LedTask_Handle); 91 printf("函数LedTask的优先级是%ld\r\n", x); 92 x = uxTaskPriorityGet(QueryTask_Handle); 93 printf("函数QueryTask的优先级是%ld\r\n", x); 94 printf("/*************************** end ***************************/\r\n"); 95 printf("\r\n"); 96 97 /*2. 函数vTaskPrioritySet()的使用*/ 98 printf("/*********** 2. 函数vTaskPrioritySet()的使用 ***********/\r\n"); 99 x = uxTaskPriorityGet(LedTask_Handle); 100 printf("函数LedTask的优先级是%ld\r\n", x); 101 printf("设置LedTask函数优先级为5\r\n"); 102 vTaskPrioritySet(LedTask_Handle, (UBaseType_t)5); 103 x = uxTaskPriorityGet(LedTask_Handle); 104 printf("更改后,函数LedTask的优先级是%ld\r\n", x); 105 printf("/*************************** end ***************************/\r\n"); 106 printf("\r\n"); 107 108 /*3. 函数uxTaskGetSystemState()的使用*/ 109 uint32_t TotalRunTime; 110 UBaseType_t ArraySize; 111 TaskStatus_t *StatusArray; 112 113 printf("/*********** 3. 函数uxTaskGetSystemState()的使用 ***********/\r\n"); 114 ArraySize = uxTaskGetNumberOfTasks(); /*获取系统任务数量*/ 115 StatusArray = pvPortMalloc(ArraySize * sizeof(TaskStatus_t)); /*申请内存*/ 116 if (StatusArray != NULL) 117 { 118 ArraySize = uxTaskGetSystemState( (TaskStatus_t * )StatusArray, 119 (UBaseType_t )ArraySize, 120 (uint32_t * )&TotalRunTime ); 121 printf("TaskName\t\tPriority\t\tTaskNumber\t\t\r\n"); 122 for (x=0;x<ArraySize;++x) 123 { 124 printf("%s\t\t%d\t\t\t%d\t\t\t\r\n", 125 StatusArray[x].pcTaskName, 126 (int)StatusArray[x].uxCurrentPriority, 127 (int)StatusArray[x].xTaskNumber ); 128 } 129 } 130 vPortFree(StatusArray); /*释放内存*/ 131 printf("/*************************** end ***************************/\r\n"); 132 printf("\r\n"); 133 134 /*4. 函数vTaskGetInfo()的使用*/ 135 TaskHandle_t LedTaskHandle; 136 TaskStatus_t LedTaskStatus; 137 138 printf("/*********** 4. 函数vTaskGetInfo()的使用 ***********/\r\n"); 139 LedTaskHandle = xTaskGetHandle("LedTask"); /*函数xTaskGetHandle()的使用*/ 140 vTaskGetInfo(LedTaskHandle, 141 (TaskStatus_t *)&LedTaskStatus, 142 pdTRUE, 143 eInvalid); 144 printf("任务名 %s\r\n", LedTaskStatus.pcTaskName); 145 printf("任务编号 %ld\r\n", LedTaskStatus.xTaskNumber); 146 printf("任务状态 %d\r\n", LedTaskStatus.eCurrentState); 147 printf("任务优先级 %ld\r\n", LedTaskStatus.uxCurrentPriority); 148 printf("任务基础优先级 %ld\r\n", LedTaskStatus.uxBasePriority); 149 printf("任务栈基地址 %#x\r\n", (int)LedTaskStatus.pxStackBase); 150 printf("任务栈历史剩余最小值 %d\r\n", LedTaskStatus.usStackHighWaterMark); 151 printf("/*************************** end ***************************/\r\n"); 152 printf("\r\n"); 153 154 /* 155 * 栈历史剩余最小值是针对定义的“QUERY_STK_SIZE 256”来说的, 156 * 假如QueryTask函数用了62字节,那么查询到的最小值就应该是256-62=194了。 157 */ 158 /*5. 函数uxTaskGetStackHighWaterMark()的使用*/ 159 printf("/*********** 5. 函数uxTaskGetStackHighWaterMark()的使用 ***********/\r\n"); 160 x = uxTaskGetStackHighWaterMark(LedTask_Handle); 161 printf("LedTask任务,栈历史剩余最小值:%ld\r\n", x); 162 x = uxTaskGetStackHighWaterMark(QueryTask_Handle); 163 printf("QueryTask任务,栈历史剩余最小值:%ld\r\n", x); 164 x = uxTaskGetStackHighWaterMark(LedTask_Handle); 165 printf("LedTask任务,栈历史剩余最小值:%ld\r\n", x); 166 x = uxTaskGetStackHighWaterMark(QueryTask_Handle); 167 printf("QueryTask任务,栈历史剩余最小值:%ld\r\n", x); 168 printf("/*************************** end ***************************/\r\n"); 169 printf("\r\n"); 170 171 /*6. 函数eTaskGetState()的使用*/ 172 eTaskState LedTaskState; 173 eTaskState QueryTaskState; 174 175 printf("/*********** 6. 函数eTaskGetState()的使用 ***********/\r\n"); 176 LedTaskState = eTaskGetState(LedTask_Handle); 177 printf("LedTask任务状态:%d\r\n", LedTaskState); 178 QueryTaskState = eTaskGetState(QueryTask_Handle); 179 printf("QueryTask任务状态:%d\r\n", QueryTaskState); 180 printf("/*************************** end ***************************/\r\n"); 181 printf("\r\n"); 182 183 /*7. 函数pcTaskGetName()的使用,根据任务句柄查询任务名*/ 184 char *TaskName; 185 186 printf("/*********** 7. 函数pcTaskGetName()的使用 ***********/\r\n"); 187 TaskName = pcTaskGetName(LedTask_Handle); 188 printf("LedTask任务名:%s\r\n", TaskName); 189 TaskName = pcTaskGetName(QueryTask_Handle); 190 printf("QueryTask任务名:%s\r\n", TaskName); 191 printf("/*************************** end ***************************/\r\n"); 192 printf("\r\n"); 193 194 /*8. 函数uxTaskGetNumberOfTasks()的使用,查询系统当前存在的任务数量*/ 195 printf("/*********** 8. 函数uxTaskGetNumberOfTasks()的使用 ***********/\r\n"); 196 x = uxTaskGetNumberOfTasks(); 197 printf("任务总数是:%ld\r\n", x); 198 printf("ArraySize值是:%ld\r\n", ArraySize); 199 printf("/*************************** end ***************************/\r\n"); 200 printf("\r\n"); 201 202 /* 203 * Name: 创建任务的时候给任务分配的名字 204 * State: 任务的状态信息。B阻塞态,R就绪态,S挂起态,D删除态 205 * Priority: 任务优先级 206 * Stack: 栈历史最小剩余大小 207 * Num: 任务编号 208 */ 209 /*9. 函数vTaskList()的使用*/ 210 printf("/*********** 9. 函数vTaskList()的使用 ***********/\r\n"); 211 vTaskList(InfoBuffer); 212 printf("Name State Priority\tStack\tNum\t\r\n"); 213 printf("*******************************************\r\n"); 214 printf("%s\r\n", InfoBuffer); 215 printf("/*************************** end ***************************/\r\n"); 216 printf("\r\n"); 217 218 while (1) 219 { 220 vTaskDelay(1000); 221 } 222 } 223 224 225 226 static void SystemInitial(void) 227 { 228 /*组4,16级抢占优先级,无响应优先级*/ 229 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); 230 231 DelayInitial(); 232 USART1_Initialization(); 233 GPIO_LED_Configuration(); 234 } 235 236 int main(void) 237 { 238 SystemInitial(); 239 240 /*创建开始任务*/ 241 xTaskCreate((TaskFunction_t )StartTask, /*任务函数*/ 242 (const char * )"StartTask", /*任务名称*/ 243 (uint16_t )START_STK_SIZE, /*任务堆栈大小*/ 244 (void * )NULL, /*传递给任务函数的参数*/ 245 (UBaseType_t )START_TASK_PRIO, /*任务优先级*/ 246 (TaskHandle_t * )&StartTask_Handle); /*任务句柄*/ 247 248 /*开启任务调度*/ 249 vTaskStartScheduler(); 250 } 251 252 /***************************END OF FILE***************************/
2. main.h
1 /**/ 2 #ifndef __MAIN_H__ 3 #define __MAIN_H__ 4 5 #define LED_POWER GPIO_Pin_2 /*PE2*/ 6 #define LED_RUN GPIO_Pin_3 /*PE3*/ 7 8 #define LED_Power_On() GPIO_ResetBits(GPIOE, LED_POWER) 9 10 11 #endif /*__MAIN_H__*/ 12 13 /***************************END OF FILE***************************/
3. sys.c
1 /**/ 2 #include "sys.h" 3 #include "stdio.h" 4 5 #pragma import(__use_no_semihosting) 6 //标准库需要的支持函数 7 struct __FILE 8 { 9 int handle; 10 11 }; 12 13 FILE __stdout; 14 //定义_sys_exit()以避免使用半主机模式 15 void _sys_exit(int x) 16 { 17 x = x; 18 } 19 /* //重定义fputc函数 20 int fputc(int ch, FILE *f) 21 { 22 while((USART1->SR&0X40)==0) //循环发送,直到发送完毕 23 USART1->DR = (u8) ch; 24 return ch; 25 } */ 26 27 28 /***************************END OF FILE***************************/
4. sys.h
1 /**/ 2 #ifndef __SYS_H__ 3 #define __SYS_H__ 4 5 /*0不支持OS,1支持OS*/ 6 #define SYSTEM_SUPPORT_OS 1 /*定义系统文件夹是否支持OS*/ 7 8 #endif /*__SYS_H__*/ 9 10 /***************************END OF FILE***************************/
5. delay.c
1 /**/ 2 #include "delay.h" 3 #include "sys.h" 4 /*如果需要使用OS,则包括下面的头文件即可*/ 5 #if SYSTEM_SUPPORT_OS 6 #include "FreeRTOS.h" 7 #include "task.h" 8 #endif 9 10 __IO uint32_t TimingDelay; 11 12 ////////////////////////// 13 //static uint8_t fac_us = 0; 14 ////////////////////////// 15 16 /***** 声明 *****/ 17 extern void xPortSysTickHandler(void); 18 19 /*systick中断服务函数,使用FreeRTOS时用到*/ 20 void SysTick_Handler(void) 21 { 22 TimingDelayDecrement(); 23 24 if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) /*系统已运行*/ 25 { 26 xPortSysTickHandler(); 27 } 28 } 29 30 31 void DelayInitial(void) 32 { 33 /* 34 * SystemCoreClock / 1000 1ms中断一次 35 * SystemCoreClock / 100000 10us中断一次 36 * SystemCoreClock / 1000000 1us中断一次 37 */ 38 if (SysTick_Config(SystemCoreClock / 1000)) 39 { 40 while (1); 41 } 42 /*关闭systick timer定时器*/ 43 /* SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;*/ 44 45 /*使能滴答定时器*/ 46 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; 47 } 48 49 //void DelayNus(uint32_t nus) 50 //{ 51 // uint32_t ticks; 52 // uint32_t told, tnow, tcnt = 0; 53 // uint32_t reload = SysTick->LOAD; 54 // 55 // fac_us = SystemCoreClock / 1000000; 56 // ticks = nus * fac_us; 57 // told = SysTick->VAL; 58 // 59 // while (1) 60 // { 61 // tnow = SysTick->VAL; 62 // if (tnow != told) 63 // { 64 // if (tnow < told) 65 // { 66 // tcnt += told - tnow; 67 // } 68 // else 69 // { 70 // tcnt += reload - tnow + told; 71 // } 72 // told = tnow; 73 // if (tcnt >= ticks) break; 74 // } 75 // } 76 //} 77 78 ///*不会引起调度*/ 79 //void DelayXms(uint32_t nms) 80 //{ 81 // uint32_t i; 82 // 83 // for (i=0;i<nms;++i) 84 // { 85 // DelayNus(1000); 86 // } 87 //} 88 89 /* 90 * 本函数在中断函数中调用,滴答定时器中断一次调用一次。 91 */ 92 void TimingDelayDecrement(void) 93 { 94 if (TimingDelay != 0x00) 95 { 96 TimingDelay--; 97 } 98 } 99 100 /* 101 * TimingDelay值在TimingDelayDecrement函数中递减 102 */ 103 void DelayNms(uint32_t nTimes) 104 { 105 TimingDelay = nTimes; 106 107 while (TimingDelay!=0); //等待计数停止 108 } 109 110 /***************************END OF FILE***************************/
6. delay.h
1 /**/ 2 #ifndef __DELAY_H__ 3 #define __DELAY_H__ 4 5 #include "stm32f2xx.h" 6 7 #include <stdint.h> 8 9 extern void DelayInitial(void); 10 extern void TimingDelayDecrement(void); 11 extern void DelayNms(uint32_t nTimes); 12 13 ///////////////////////// 14 extern void DelayXms(uint32_t nms); 15 ///////////////////////// 16 17 #endif /*__DELAY_H__*/ 18 /***************************END OF FILE***************************/
7. usart.c
1 /* 2 * USART1: 中断优先级选择第4组, 3级抢占优先级 无响应优先级 3 */ 4 #include "usart.h" 5 #include "stdio.h" /*printf*/ 6 #include "stm32f2xx.h" 7 #include "stm32f2xx_gpio.h" 8 #include "stm32f2xx_rcc.h" 9 #include "stm32f2xx_usart.h" 10 11 12 uint8_t USART1_RxBuffer[USART1_RECEIVE_SIZE]; 13 uint8_t Flag_USART1Receive = 0; 14 uint8_t USART1_ReceiveCount = 0; 15 uint8_t USART1_ReceiveIndex = 0; 16 17 18 void USART1_Initialization(void) 19 { 20 USART1_GPIO_Configuration(); 21 USART1_NVIC_Configuration(); 22 /*USART1使能接收中断*/ 23 // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 24 /*USART1使能发送中断*/ 25 /* USART_ITConfig(USART1, USART_IT_TXE, ENABLE); */ 26 } 27 /* 28 */ 29 void USART1_GPIO_Configuration(void) 30 { 31 GPIO_InitTypeDef GPIO_InitStructure; 32 USART_InitTypeDef USART_InitStructure; 33 34 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 35 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 36 GPIO_PinAFConfig(GPIOA, 9, GPIO_AF_USART1); /*GPIO连接到串口1上,PA9-TXD*/ 37 GPIO_PinAFConfig(GPIOA, 10, GPIO_AF_USART1); /*GPIO连接到串口1上,PA10-RXD*/ 38 39 /*tx, PA9*/ 40 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 41 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 42 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 43 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 44 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 45 GPIO_Init(GPIOA, &GPIO_InitStructure); 46 47 /*rx, PA10*/ 48 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 49 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 50 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 51 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 52 GPIO_Init(GPIOA, &GPIO_InitStructure); 53 54 /*配置波特率9600*/ 55 USART_InitStructure.USART_BaudRate = 115200; 56 /*配置串口的模式。为了配置双线全双工通讯,需要把Rx和Tx模式都开启. Tx发送使能和Rx接收使能*/ 57 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 58 /*无奇偶校验*/ 59 USART_InitStructure.USART_Parity = USART_Parity_No; 60 /*1停止位*/ 61 USART_InitStructure.USART_StopBits = USART_StopBits_1; 62 /*配置串口传输字长8位*/ 63 USART_InitStructure.USART_WordLength = USART_WordLength_8b; 64 /*不采用硬件流控制*/ 65 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 66 /*向寄存器写入配置参数*/ 67 USART_Init(USART1, &USART_InitStructure); 68 /*使能USART1外设。在使用外设时,不仅要使能其时钟,还要调用此函数使能外设才可以正常使用*/ 69 USART_Cmd(USART1, ENABLE); 70 } 71 72 //void USART1_SendNChar(uint8_t *str, uint8_t n) 73 //{ 74 // /*发送区是否为空*/ 75 // while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); 76 // 77 // while (n--) 78 // { 79 // USART_SendData(USART1, (uint8_t)(*str++)); 80 // /*是否发送完成*/ 81 // while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 82 // } 83 //} 84 85 /* 86 * 如果一次发送多个字节数据,可能会多次进入此函数 87 * 调用时,应先延时几十毫秒,确保把数据都接收完 88 */ 89 //void USART1_ReceiveIRQ(void) 90 //{ 91 // /*如果寄存器中有数据*/ 92 // while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) 93 // { 94 // USART1_RxBuffer[USART1_ReceiveIndex++] = USART_ReceiveData(USART1); 95 // USART1_ReceiveCount++; 96 // } 97 // 98 // Flag_USART1Receive = 1; 99 //} 100 101 void USART1_NVIC_Configuration(void) 102 { 103 NVIC_InitTypeDef NVIC_InitStructure; 104 105 /*中断优先级选择第1组*/ 106 // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); 107 108 /*3级抢占优先级 0级响应优先级*/ 109 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 110 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; 111 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 112 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 113 NVIC_Init(&NVIC_InitStructure); 114 } 115 116 /*重定义fputc函数 2种方法都可以*/ 117 /* 118 int fputc(int ch,FILE *f) 119 { 120 while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET); 121 USART_SendData(USART1,(uint8_t)ch); 122 while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET); 123 124 return (ch); 125 } 126 */ 127 128 int fputc(int ch, FILE *f) 129 { 130 while((USART1->SR&0X40)==0) /*循环发送,直到发送完毕*/ 131 {} 132 133 USART1->DR = (uint8_t)ch; 134 return ch; 135 } 136 /***************************END OF FILE***************************/
8. usart.h
1 /* 2 * 3 */ 4 #ifndef __USART_H__ 5 #define __USART_H__ 6 7 #include <stdint.h> /* uint8_t */ 8 9 #define USART1_RECEIVE_SIZE 20 10 11 12 void USART1_Initialization(void); 13 void USART1_GPIO_Configuration(void); 14 void USART1_SendNChar(uint8_t *str, uint8_t n); 15 void USART1_ReceiveIRQ(void); 16 void USART1_NVIC_Configuration(void); 17 18 #endif /*__USART_H__*/ 19 20 /***************************END OF FILE***************************/
打印结果: