FreeRTOS-01移植及任务创建和删除
根据正点原子FreeRTOS视频整理
单片机:STM32F207VC
FreeRTOS源码版本:v10.0.1
任务创建和删除API函数:
工程列表:
1. main.c
1 /**/ 2 #include "main.h" 3 #include "gpio.h" 4 #include "delay.h" 5 #include "sys.h" 6 7 #include "stm32f2xx_gpio.h" 8 9 #include "FreeRTOS.h" 10 #include "task.h" 11 12 #define START_TASK_PRIO 1 /*任务优先级*/ 13 #define START_STK_SIZE 128 /*任务堆栈大小*/ 14 TaskHandle_t StartTask_Handle; /*任务句柄*/ 15 void StartTask(void *pvParameters); /*任务函数*/ 16 17 #define LED1_TASK_PRIO 2 18 #define LED1_STK_SIZE 50 19 TaskHandle_t LED1Task_Handle; 20 void LED1Task(void *pvParameters); 21 22 #define LED2_TASK_PRIO 3 23 #define LED2_STK_SIZE 50 24 TaskHandle_t LED2Task_Handle; 25 void LED2Task(void *pvParameters); 26 27 28 29 /***** 声明 *****/ 30 static void SystemInitial(void); 31 32 33 void StartTask(void *pvParameters) 34 { 35 taskENTER_CRITICAL(); /*进入临界区*/ 36 37 xTaskCreate((TaskFunction_t )LED1Task, /*任务函数*/ 38 (const char * )"LED1Task", /*任务名称*/ 39 (uint16_t )LED1_STK_SIZE, /*任务堆栈大小*/ 40 (void * )NULL, /*传递给任务函数的参数*/ 41 (UBaseType_t )LED1_TASK_PRIO, /*任务优先级*/ 42 (TaskHandle_t )&LED1Task_Handle); /*任务句柄*/ 43 44 xTaskCreate((TaskFunction_t )LED2Task, 45 (const char * )"LED2Task", 46 (uint16_t )LED2_STK_SIZE, 47 (void * )NULL, 48 (UBaseType_t )LED2_TASK_PRIO, 49 (TaskHandle_t )&LED2Task_Handle); 50 51 vTaskDelete(StartTask_Handle); /*删除开始任务*/ 52 taskEXIT_CRITICAL(); /*推出临界区*/ 53 } 54 55 56 void LED1Task(void *pvParameters) 57 { 58 while (1) 59 { 60 GPIOE->ODR ^= LED_ALARM; 61 vTaskDelay(200); 62 // DelayNms(2); 63 } 64 } 65 66 void LED2Task(void *pvParameters) 67 { 68 while (1) 69 { 70 GPIOE->ODR ^= LED_RUN; 71 vTaskDelay(500); 72 } 73 } 74 75 76 static void SystemInitial(void) 77 { 78 DelayInitial(); 79 GPIO_Initial(); 80 } 81 82 int main(void) 83 { 84 SystemInitial(); 85 86 87 /*创建开始任务*/ 88 xTaskCreate((TaskFunction_t )StartTask, /*任务函数*/ 89 (const char * )"StartTask", /*任务名称*/ 90 (uint16_t )START_STK_SIZE, /*任务堆栈大小*/ 91 (void * )NULL, /*传递给任务函数的参数*/ 92 (UBaseType_t )START_TASK_PRIO, /*任务优先级*/ 93 (TaskHandle_t )&StartTask_Handle); /*任务句柄*/ 94 95 /*开启任务调度*/ 96 vTaskStartScheduler(); 97 } 98 99 /***************************END OF FILE***************************/
2. main.h
1 /**/ 2 #ifndef __MAIN_H__ 3 #define __MAIN_H__ 4 5 6 7 8 #endif /*__MAIN_H__*/ 9 10 /***************************END OF FILE***************************/
3. sys.c
1 /**/ 2 #include "sys.h" 3 #include "stdio.h" 4 5 6 /***************************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 extern void xPortSysTickHandler(void); 14 15 /*systick中断服务函数,使用FreeRTOS时用到*/ 16 void SysTick_Handler(void) 17 { 18 TimingDelayDecrement(); 19 20 if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) /*系统已运行*/ 21 { 22 xPortSysTickHandler(); 23 } 24 } 25 26 void DelayInitial(void) 27 { 28 /* 29 * SystemCoreClock / 1000 1ms中断一次 30 * SystemCoreClock / 100000 10us中断一次 31 * SystemCoreClock / 1000000 1us中断一次 32 */ 33 if (SysTick_Config(SystemCoreClock / 1000)) 34 { 35 while (1); 36 } 37 /*关闭systick timer定时器*/ 38 /* SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;*/ 39 40 /*使能滴答定时器*/ 41 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; 42 } 43 44 /* 45 * 本函数在中断函数中调用,滴答定时器中断一次调用一次。 46 */ 47 void TimingDelayDecrement(void) 48 { 49 if (TimingDelay != 0x00) 50 { 51 TimingDelay--; 52 } 53 } 54 55 /* 56 * TimingDelay值在TimingDelayDecrement函数中递减 57 */ 58 void DelayNms(uint32_t nTimes) 59 { 60 TimingDelay = nTimes; 61 62 while (TimingDelay!=0); //等待计数停止 63 } 64 65 /***************************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 #endif /*__DELAY_H__*/ 14 /***************************END OF FILE***************************/
7. gpio.c
1 /**/ 2 #include "gpio.h" 3 4 /***** 声明 *****/ 5 static void GPIO_LED_Configuration(void); 6 7 8 void GPIO_Initial(void) 9 { 10 GPIO_LED_Configuration(); 11 } 12 13 14 static void GPIO_LED_Configuration(void) 15 { 16 GPIO_InitTypeDef GPIO_InitStructure; 17 18 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 19 20 GPIO_InitStructure.GPIO_Pin = LED_POWER | LED_RUN | LED_ALARM; 21 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 22 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 23 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 24 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 25 GPIO_Init(GPIOE, &GPIO_InitStructure); 26 27 LED_Power_On(); 28 LED_Run_Off(); 29 LED_Alarm_Off(); 30 } 31 32 /***************************END OF FILE***************************/
8. gpio.h
1 /**/ 2 #ifndef __GPIO_H__ 3 #define __GPIO_H__ 4 5 #include "stm32f2xx_gpio.h" 6 7 #define LED_POWER GPIO_Pin_2 /*PE2*/ 8 #define LED_RUN GPIO_Pin_3 /*PE3*/ 9 #define LED_ALARM GPIO_Pin_4 /*PE4*/ 10 11 #define LED_Power_On() GPIO_ResetBits(GPIOE, LED_POWER) 12 #define LED_Power_Off() GPIO_SetBits(GPIOE, LED_POWER) 13 #define LED_Run_On() GPIO_ResetBits(GPIOE, LED_RUN) 14 #define LED_Run_Off() GPIO_SetBits(GPIOE, LED_RUN) 15 #define LED_Alarm_On() GPIO_ResetBits(GPIOE, LED_ALARM) 16 #define LED_Alarm_Off() GPIO_SetBits(GPIOE, LED_ALARM) 17 18 19 extern void GPIO_Initial(void); 20 21 #endif /*__GPIO_H__*/ 22 /***************************END OF FILE***************************/
9. 移植过程及问题解决
1. 新建基础例程。 2. 在工程目录中添加FreeRTOS源码。 3. 在MDK中增加FreeRTOS_CODE和FreeRTOS_POARTABLE组,并添加对应文件。 并包含相应头文件路径。 编译报错:打不开FreeRTOSConfig.h文件。 解决办法:在FreeRTOS源码的例程中,复制一个到FreeRTOS\include文件夹下。 问题:下载程序后,灯不闪烁。 解决1:选择Use MicroLIB后,重新编译。 解决2:新建一个文件(如:sys.c),添加以下内容,添加到工程并编译--正点原子的解决方法。 #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; } 4. 新建sys.h文件,添加以下内容: /*0不支持OS,1支持OS*/ #define SYSTEM_SUPPORT_OS 1 /*定义系统文件夹是否支持OS*/ 5. 在delay.c文件中,增加或修改以下内容: #include "sys.h" /*如果需要使用OS,则包括下面的头文件即可*/ #if SYSTEM_SUPPORT_OS #include "FreeRTOS.h" #include "task.h" #endif /***** 声明 *****/ extern void xPortSysTickHandler(void); /*systick中断服务函数,使用FreeRTOS时用到*/ void SysTick_Handler(void) { TimingDelayDecrement(); if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) /*系统已运行*/ { xPortSysTickHandler(); } } 6. main.c函数中新建任务。 7. 具体程序参考上面的内容。