STM32移植FreeRTOS(1)
“STM32F103VET6<_>FreeRTOS”
1、项目功能实现
1)LED灯定时闪烁
2)KEY按键检测
3)FreeRTOS任务创建
4)串口输出程序运行状态
2、软件代码实现
1)LED灯初始化代码
1 1 #ifndef __BSP_LED_H 2 2 #define __BSP_LED_H 3 3 4 4 /*---------------------------宏定义-----------------------------*/ 5 5 6 6 #define LED1_GPIO_PORT GPIOB 7 7 #define LED1_GPIO_CLK RCC_APB2Periph_GPIOB 8 8 #define LED1_GPIO_PIN GPIO_Pin_5 9 9 10 10 #define LED2_GPIO_PORT GPIOB 11 11 #define LED2_GPIO_CLK RCC_APB2Periph_GPIOB 12 12 #define LED2_GPIO_PIN GPIO_Pin_0 13 13 14 14 #define LED3_GPIO_PORT GPIOB 15 15 #define LED3_GPIO_CLK RCC_APB2Periph_GPIOB 16 16 #define LED3_GPIO_PIN GPIO_Pin_1 17 17 18 18 #define ON 0 19 19 #define OFF 1 20 20 21 21 #define LED1_ON GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN) 22 22 #define LED1_OFF GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN) 23 23 24 24 #define LED2_ON GPIO_ResetBits(LED2_GPIO_PORT,LED2_GPIO_PIN) 25 25 #define LED2_OFF GPIO_SetBits(LED2_GPIO_PORT,LED2_GPIO_PIN) 26 26 27 27 #define LED3_ON GPIO_ResetBits(LED3_GPIO_PORT,LED3_GPIO_PIN) 28 28 #define LED3_OFF GPIO_SetBits(LED3_GPIO_PORT,LED3_GPIO_PIN) 29 29 30 30 /*-------------------------------函数声明---------------------------*/ 31 31 32 32 void LED_Init(void); /* 初始化GPIO端口状态 */ 33 33 void LED_GPIO_Config(void); /* 配置外设GPIO端口 */ 34 34 35 35 #endif
bsp_LED.h
1 1 #include "stm32f10x.h" 2 2 #include "bsp_LED.h" 3 3 4 4 void LED_GPIO_Config(void) 5 5 { 6 6 GPIO_InitTypeDef GPIO_InitStructure; 7 7 RCC_APB2PeriphClockCmd(LED1_GPIO_CLK|LED1_GPIO_CLK|LED1_GPIO_CLK,ENABLE); 8 8 9 9 /* 初始化结构体参数,并配置寄存器 */ 10 10 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 11 11 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 12 12 13 13 GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN; 14 14 GPIO_Init(LED1_GPIO_PORT,&GPIO_InitStructure); 15 15 16 16 GPIO_InitStructure.GPIO_Pin = LED2_GPIO_PIN; 17 17 GPIO_Init(LED2_GPIO_PORT,&GPIO_InitStructure); 18 18 19 19 GPIO_InitStructure.GPIO_Pin = LED3_GPIO_PIN; 20 20 GPIO_Init(LED3_GPIO_PORT,&GPIO_InitStructure); 21 21 } 22 22 23 23 void LED_Init(void) 24 24 { 25 25 LED_GPIO_Config(); 26 26 27 27 /* 关闭LED灯 */ 28 28 LED1_OFF; 29 29 LED2_OFF; 30 30 LED3_OFF; 31 31 }
bsp_LED.c
2)KEY按键初始化代码
1 #ifndef __BSP_KEY_H 2 #define __BSP_KEY_H 3 #include "stm32f10x.h" 4 5 /* GPIO端口宏定义 */ 6 7 #define KEY1_GPIO_PORT GPIOA 8 #define KYE1_GPIO_CLK RCC_APB2Periph_GPIOA 9 #define KEY1_GPIO_PIN GPIO_Pin_0 10 11 #define KEY2_GPIO_PORT GPIOC 12 #define KYE2_GPIO_CLK RCC_APB2Periph_GPIOC 13 #define KEY2_GPIO_PIN GPIO_Pin_13 14 15 #define KEY_ON 1 16 #define KEY_OFF 0 17 18 /* 函数声明 */ 19 void KEY_Init(void); 20 uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin); 21 22 #endif
bsp_KEY.h
1 #include "bsp_KEY.h" 2 3 void KEY_Init(void) 4 { 5 GPIO_InitTypeDef GPIO_InitStructure; 6 7 RCC_APB2PeriphClockCmd(KYE1_GPIO_CLK|KYE2_GPIO_CLK,ENABLE); 8 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 10 11 GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN; 12 GPIO_Init(KEY1_GPIO_PORT,&GPIO_InitStructure); 13 14 GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN; 15 GPIO_Init(KEY2_GPIO_PORT,&GPIO_InitStructure); 16 } 17 uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin) 18 { 19 if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON) 20 { 21 while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON); 22 return KEY_ON; 23 } 24 else 25 { 26 KEY_OFF; 27 } 28 }
bsp_KEY.c
3)USART串口初始化
1 #ifndef __BSP_USART_H 2 #define __BSP_USART_H 3 4 #include "stm32f10x.h" 5 6 /* USART串口宏定义 */ 7 #define USARTx USART1 8 #define USARTx_CLK RCC_APB2Periph_USART1 9 #define USARTx_ClockCmd RCC_APB2PeriphClockCmd 10 #define USARTx_BaudRate 115200 11 12 /* 中断NVIC宏定义 */ 13 #define NVIC_PriorityGroup_x NVIC_PriorityGroup_2 14 #define USARTx_IRQn USART1_IRQn 15 16 /* GPIO端口宏定义 */ 17 #define USART_RX_GPIO_PORT GPIOA 18 #define USART_RX_GPIO_CLK RCC_APB2Periph_GPIOA 19 #define USART_RX_GPIO_PIN GPIO_Pin_10 20 21 #define USART_TX_GPIO_PORT GPIOA 22 #define USART_TX_GPIO_CLK RCC_APB2Periph_GPIOA 23 #define USART_TX_GPIO_PIN GPIO_Pin_9 24 25 /* 函数声明 */ 26 void USART_x_Init(void); 27 static void NVIC_Config(void); 28 void USART_Send_Byte(USART_TypeDef* pUSARTx,uint8_t ch); 29 void USART_Send_String(USART_TypeDef* pUSARTx,char *str); 30 31 #endif
bsp_USART.h
1 #include "bsp_USART.h" 2 #include "stdio.h" 3 4 void USART_x_Init(void) 5 { 6 GPIO_InitTypeDef GPIO_InitStructure; 7 USART_InitTypeDef USART_InitStructure; 8 9 /* 使能GPIO端口时钟,初始化GPIO结构体,并配置寄存器参数 */ 10 USARTx_ClockCmd(USART_RX_GPIO_CLK|USART_TX_GPIO_CLK,ENABLE); 11 12 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 13 14 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /* 复用推挽输出 */ 15 GPIO_InitStructure.GPIO_Pin = USART_TX_GPIO_PIN; 16 GPIO_Init(USART_TX_GPIO_PORT,&GPIO_InitStructure); 17 18 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; /* 浮空输入 */ 19 GPIO_InitStructure.GPIO_Pin = USART_RX_GPIO_PIN; 20 GPIO_Init(USART_RX_GPIO_PORT,&GPIO_InitStructure); 21 22 /* 初始化USART结构体,并配置寄存器 */ 23 USARTx_ClockCmd(USARTx_CLK,ENABLE); 24 25 USART_InitStructure.USART_BaudRate = USARTx_BaudRate; /* 设置波特率 */ 26 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;/* 配置硬件控制流 */ 27 USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; /* 配置工作模式,一般配置成收发一起 */ 28 USART_InitStructure.USART_Parity = USART_Parity_No; /* 配置效验位,普通情况下设置成无效验位 */ 29 USART_InitStructure.USART_StopBits = USART_StopBits_1; /* 配置停止位,一般设置成1位 */ 30 USART_InitStructure.USART_WordLength = USART_WordLength_8b; /* 配置帧数据字长,如果有校验位则设置成9位,否则设置成8位即可 */ 31 32 USART_Init(USARTx,&USART_InitStructure); 33 34 NVIC_Config(); /* 串口中断配置 */ 35 USART_ITConfig(USARTx,USART_IT_RXNE,ENABLE); /* 配置串口接收中断 */ 36 USART_Cmd(USARTx,ENABLE); /* 使能串口 */ 37 } 38 static void NVIC_Config(void) 39 { 40 NVIC_InitTypeDef NVIC_InitStructure; 41 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_x); 42 43 NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn; /* 配置中断源 */ 44 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 设置抢断优先级 */ 45 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 设置子优先级 */ 46 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 使能中断 */ 47 48 NVIC_Init(&NVIC_InitStructure); 49 } 50 void USART_Send_Byte(USART_TypeDef* pUSARTx,uint8_t ch) /* 发送一个字节数据 */ 51 { 52 53 USART_SendData(pUSARTx,ch);/* 发送一个字节的数据 */ 54 55 while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);/* 等待发送寄存器为空 */ 56 } 57 void USART_Send_String(USART_TypeDef* pUSARTx,char *str) /* 发送一个字符串 */ 58 { 59 unsigned int i=0; 60 do 61 { 62 USART_Send_Byte(pUSARTx,*(str+i)); 63 }while(*(str+i)!='\0'); 64 while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET); /* 等待发送寄存器为空 */ 65 } 66 /* 重定向c库函数printf到串口,重定向后可使用printf函数 */ 67 int fputc(int ch, FILE *f) 68 { 69 USART_SendData(USARTx, (uint8_t) ch);/* 发送一个字节数据到串口 */ 70 while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); /* 等待发送完毕 */ 71 return (ch); 72 } 73 /* 重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数 */ 74 int fgetc(FILE *f) 75 { 76 while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);/* 等待串口输入数据 */ 77 return (int)USART_ReceiveData(USARTx); 78 }
bsp_USART.c
4)FreeRTOS配置文件(根据项目功能修改配置参数)
1 /* 2 FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. 3 All rights reserved 4 5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 7 This file is part of the FreeRTOS distribution. 8 9 FreeRTOS is free software; you can redistribute it and/or modify it under 10 the terms of the GNU General Public License (version 2) as published by the 11 Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 13 *************************************************************************** 14 >>! NOTE: The modification to the GPL is included to allow you to !<< 15 >>! distribute a combined work that includes FreeRTOS without being !<< 16 >>! obliged to provide the source code for proprietary components !<< 17 >>! outside of the FreeRTOS kernel. !<< 18 *************************************************************************** 19 20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 link: http://www.freertos.org/a00114.html 24 25 *************************************************************************** 26 * * 27 * FreeRTOS provides completely free yet professionally developed, * 28 * robust, strictly quality controlled, supported, and cross * 29 * platform software that is more than just the market leader, it * 30 * is the industry's de facto standard. * 31 * * 32 * Help yourself get started quickly while simultaneously helping * 33 * to support the FreeRTOS project by purchasing a FreeRTOS * 34 * tutorial book, reference manual, or both: * 35 * http://www.FreeRTOS.org/Documentation * 36 * * 37 *************************************************************************** 38 39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 the FAQ page "My application does not run, what could be wrong?". Have you 41 defined configASSERT()? 42 43 http://www.FreeRTOS.org/support - In return for receiving this top quality 44 embedded software for free we request you assist our global community by 45 participating in the support forum. 46 47 http://www.FreeRTOS.org/training - Investing in training allows your team to 48 be as productive as possible as early as possible. Now you can receive 49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 Ltd, and the world's leading authority on the world's leading RTOS. 51 52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 licenses offer ticketed support, indemnification and commercial middleware. 62 63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 engineered and independently SIL3 certified version for use in safety and 65 mission critical applications that require provable dependability. 66 67 */ 68 69 70 #ifndef FREERTOS_CONFIG_H 71 #define FREERTOS_CONFIG_H 72 73 #include "stm32f10x.h" 74 #include "bsp_usart.h" 75 76 77 //针对不同的编译器调用不同的stdint.h文件 78 #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) 79 #include <stdint.h> 80 extern uint32_t SystemCoreClock; 81 #endif 82 83 //断言 84 #define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int) 85 #define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__) 86 87 /************************************************************************ 88 * FreeRTOS基础配置配置选项 89 *********************************************************************/ 90 /* 置1:RTOS使用抢占式调度器;置0:RTOS使用协作式调度器(时间片) 91 * 92 * 注:在多任务管理机制上,操作系统可以分为抢占式和协作式两种。 93 * 协作式操作系统是任务主动释放CPU后,切换到下一个任务。 94 * 任务切换的时机完全取决于正在运行的任务。 95 */ 96 #define configUSE_PREEMPTION 1 97 98 //1使能时间片调度(默认式使能的) 99 #define configUSE_TIME_SLICING 1 100 101 /* 某些运行FreeRTOS的硬件有两种方法选择下一个要执行的任务: 102 * 通用方法和特定于硬件的方法(以下简称“特殊方法”)。 103 * 104 * 通用方法: 105 * 1.configUSE_PORT_OPTIMISED_TASK_SELECTION 为 0 或者硬件不支持这种特殊方法。 106 * 2.可以用于所有FreeRTOS支持的硬件 107 * 3.完全用C实现,效率略低于特殊方法。 108 * 4.不强制要求限制最大可用优先级数目 109 * 特殊方法: 110 * 1.必须将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1。 111 * 2.依赖一个或多个特定架构的汇编指令(一般是类似计算前导零[CLZ]指令)。 112 * 3.比通用方法更高效 113 * 4.一般强制限定最大可用优先级数目为32 114 * 一般是硬件计算前导零指令,如果所使用的,MCU没有这些硬件指令的话此宏应该设置为0! 115 */ 116 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 117 118 /* 置1:使能低功耗tickless模式;置0:保持系统节拍(tick)中断一直运行 119 * 假设开启低功耗的话可能会导致下载出现问题,因为程序在睡眠中,可用以下办法解决 120 * 121 * 下载方法: 122 * 1.将开发版正常连接好 123 * 2.按住复位按键,点击下载瞬间松开复位按键 124 * 125 * 1.通过跳线帽将 BOOT 0 接高电平(3.3V) 126 * 2.重新上电,下载 127 * 128 * 1.使用FlyMcu擦除一下芯片,然后进行下载 129 * STMISP -> 清除芯片(z) 130 */ 131 #define configUSE_TICKLESS_IDLE 0 132 133 /* 134 * 写入实际的CPU内核时钟频率,也就是CPU指令执行频率,通常称为Fclk 135 * Fclk为供给CPU内核的时钟信号,我们所说的cpu主频为 XX MHz, 136 * 就是指的这个时钟信号,相应的,1/Fclk即为cpu时钟周期; 137 */ 138 #define configCPU_CLOCK_HZ (SystemCoreClock) 139 140 //RTOS系统节拍中断的频率。即一秒中断的次数,每次中断RTOS都会进行任务调度 141 #define configTICK_RATE_HZ (( TickType_t )1000) 142 143 //可使用的最大优先级 144 #define configMAX_PRIORITIES (32) 145 146 //空闲任务使用的堆栈大小 147 #define configMINIMAL_STACK_SIZE ((unsigned short)128) 148 149 //任务名字字符串长度 150 #define configMAX_TASK_NAME_LEN (16) 151 152 //系统节拍计数器变量数据类型,1表示为16位无符号整形,0表示为32位无符号整形 153 #define configUSE_16_BIT_TICKS 0 154 155 //空闲任务放弃CPU使用权给其他同优先级的用户任务 156 #define configIDLE_SHOULD_YIELD 1 157 158 //启用队列 159 #define configUSE_QUEUE_SETS 0 160 161 //开启任务通知功能,默认开启 162 #define configUSE_TASK_NOTIFICATIONS 1 163 164 //使用互斥信号量 165 #define configUSE_MUTEXES 0 166 167 //使用递归互斥信号量 168 #define configUSE_RECURSIVE_MUTEXES 0 169 170 //为1时使用计数信号量 171 #define configUSE_COUNTING_SEMAPHORES 0 172 173 /* 设置可以注册的信号量和消息队列个数 */ 174 #define configQUEUE_REGISTRY_SIZE 10 175 176 #define configUSE_APPLICATION_TASK_TAG 0 177 178 179 /***************************************************************** 180 FreeRTOS与内存申请有关配置选项 181 *****************************************************************/ 182 //支持动态内存申请 183 #define configSUPPORT_DYNAMIC_ALLOCATION 1 184 //支持静态内存 185 #define configSUPPORT_STATIC_ALLOCATION 0 186 //系统所有总的堆大小 187 #define configTOTAL_HEAP_SIZE ((size_t)(36*1024)) 188 189 190 /*************************************************************** 191 FreeRTOS与钩子函数有关的配置选项 192 **************************************************************/ 193 /* 置1:使用空闲钩子(Idle Hook类似于回调函数);置0:忽略空闲钩子 194 * 195 * 空闲任务钩子是一个函数,这个函数由用户来实现, 196 * FreeRTOS规定了函数的名字和参数:void vApplicationIdleHook(void ), 197 * 这个函数在每个空闲任务周期都会被调用 198 * 对于已经删除的RTOS任务,空闲任务可以释放分配给它们的堆栈内存。 199 * 因此必须保证空闲任务可以被CPU执行 200 * 使用空闲钩子函数设置CPU进入省电模式是很常见的 201 * 不可以调用会引起空闲任务阻塞的API函数 202 */ 203 #define configUSE_IDLE_HOOK 0 204 205 /* 置1:使用时间片钩子(Tick Hook);置0:忽略时间片钩子 206 * 207 * 208 * 时间片钩子是一个函数,这个函数由用户来实现, 209 * FreeRTOS规定了函数的名字和参数:void vApplicationTickHook(void ) 210 * 时间片中断可以周期性的调用 211 * 函数必须非常短小,不能大量使用堆栈, 212 * 不能调用以”FromISR" 或 "FROM_ISR”结尾的API函数 213 */ 214 /*xTaskIncrementTick函数是在xPortSysTickHandler中断函数中被调用的。因此,vApplicationTickHook()函数执行的时间必须很短才行*/ 215 #define configUSE_TICK_HOOK 0 216 217 //使用内存申请失败钩子函数 218 #define configUSE_MALLOC_FAILED_HOOK 0 219 220 /* 221 * 大于0时启用堆栈溢出检测功能,如果使用此功能 222 * 用户必须提供一个栈溢出钩子函数,如果使用的话 223 * 此值可以为1或者2,因为有两种栈溢出检测方法 */ 224 #define configCHECK_FOR_STACK_OVERFLOW 0 225 226 227 /******************************************************************** 228 FreeRTOS与运行时间和任务状态收集有关的配置选项 229 **********************************************************************/ 230 //启用运行时间统计功能 231 #define configGENERATE_RUN_TIME_STATS 0 232 //启用可视化跟踪调试 233 #define configUSE_TRACE_FACILITY 0 234 /* 与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数 235 * prvWriteNameToBuffer() 236 * vTaskList(), 237 * vTaskGetRunTimeStats() 238 */ 239 #define configUSE_STATS_FORMATTING_FUNCTIONS 1 240 241 242 /******************************************************************** 243 FreeRTOS与协程有关的配置选项 244 *********************************************************************/ 245 //启用协程,启用协程以后必须添加文件croutine.c 246 #define configUSE_CO_ROUTINES 0 247 //协程的有效优先级数目 248 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) 249 250 251 /*********************************************************************** 252 FreeRTOS与软件定时器有关的配置选项 253 **********************************************************************/ 254 //启用软件定时器 255 #define configUSE_TIMERS 0 256 //软件定时器优先级 257 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1) 258 //软件定时器队列长度 259 #define configTIMER_QUEUE_LENGTH 10 260 //软件定时器任务堆栈大小 261 #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2) 262 263 /************************************************************ 264 FreeRTOS可选函数配置选项 265 ************************************************************/ 266 #define INCLUDE_xTaskGetSchedulerState 1 267 #define INCLUDE_vTaskPrioritySet 1 268 #define INCLUDE_uxTaskPriorityGet 1 269 #define INCLUDE_vTaskDelete 1 270 #define INCLUDE_vTaskCleanUpResources 1 271 #define INCLUDE_vTaskSuspend 1 272 #define INCLUDE_vTaskDelayUntil 1 273 #define INCLUDE_vTaskDelay 1 274 #define INCLUDE_eTaskGetState 1 275 #define INCLUDE_xTimerPendFunctionCall 0 276 //#define INCLUDE_xTaskGetCurrentTaskHandle 1 277 //#define INCLUDE_uxTaskGetStackHighWaterMark 0 278 //#define INCLUDE_xTaskGetIdleTaskHandle 0 279 280 281 /****************************************************************** 282 FreeRTOS与中断有关的配置选项 283 ******************************************************************/ 284 #ifdef __NVIC_PRIO_BITS 285 #define configPRIO_BITS __NVIC_PRIO_BITS 286 #else 287 #define configPRIO_BITS 4 288 #endif 289 //中断最低优先级 290 #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 291 292 //系统可管理的最高中断优先级 293 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 294 295 #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* 240 */ 296 297 #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) 298 299 300 /**************************************************************** 301 FreeRTOS与中断服务函数有关的配置选项 302 ****************************************************************/ 303 #define xPortPendSVHandler PendSV_Handler 304 #define vPortSVCHandler SVC_Handler 305 306 307 /* 以下为使用Percepio Tracealyzer需要的东西,不需要时将 configUSE_TRACE_FACILITY 定义为 0 */ 308 #if ( configUSE_TRACE_FACILITY == 1 ) 309 #include "trcRecorder.h" 310 #define INCLUDE_xTaskGetCurrentTaskHandle 1 // 启用一个可选函数(该函数被 Trace源码使用,默认该值为0 表示不用) 311 #endif 312 313 314 #endif /* FREERTOS_CONFIG_H */
FreeRTOSConfig.h
5)主函数程序文件
1 #include "stm32f10x.h" 2 3 //FreeRTOS相关头文件 4 #include "FreeRTOS.h" 5 #include "task.h" 6 7 //bsp硬件外设头文件 8 #include "bsp_LED.h" 9 #include "bsp_KEY.h" 10 #include "bsp_USART.h" 11 #include "stdio.h" 12 13 //任务句柄--------------------------------------------------------------------------------------- 14 static TaskHandle_t AppTaskCreate_Handle = NULL ; /*创建任务句柄*/ 15 static TaskHandle_t LED1_Task_Handle = NULL ; /* 创建LED任务句柄 */ 16 static TaskHandle_t KYE_Task_Handle = NULL ; /* 创建KEY任务句柄 */ 17 //全局变量--------------------------------------------------------------------------------------- 18 //函数声明--------------------------------------------------------------------------------------- 19 static void AppTaskCreate(void); /* 用于创建任务的函数 */ 20 static void LED1_Task(void* pvParameters); /* LED1_Task任务的实现 */ 21 static void KEY_Task(void* pvParameters); /* KEY_Task任务的实现 */ 22 static void BSP_Init(void); /* 初始化硬件外设 */ 23 24 int main(void) 25 { 26 BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ 27 BSP_Init(); 28 printf("这是一个FreeRTOS-多任务创建实验!\r\n"); 29 /* 创建 AppTaskCreate 任务 */ 30 xReturn = xTaskCreate((TaskFunction_t ) AppTaskCreate, /* 任务入口函数 */ 31 (const char* ) "AppTaskCreate", /* 任务名字 */ 32 (uint16_t ) 512, /* 任务栈大小 */ 33 (void* ) NULL, /* 任务入口函数参数 */ 34 (UBaseType_t ) 1, /* 任务的优先级 */ 35 (TaskHandle_t* ) &AppTaskCreate_Handle); /* 任务控制块指针 */ 36 /* 启动任务调度 */ 37 if (xReturn == pdPASS) 38 { 39 vTaskStartScheduler();/* 启动任务,开启调度 ,自动创建一个空闲任务 */ 40 } 41 else 42 { 43 return -1; 44 } 45 while(1); /* 正常不会执行到这里 */ 46 } 47 /*********************************************************************** 48 * @ 函数名 : BSP_Init 49 * @ 功能说明: 为了方便管理,所有的硬件初始化函数都放在BSP_Init中 50 * @ 参数 : 无 51 * @ 返回值 : 无 52 **********************************************************************/ 53 static void BSP_Init(void) 54 { 55 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); /* STM32中断优先级分为4,则用4bit来表示抢占优先级,范围为0-15 */ 56 LED_Init(); /* 初始化LED */ 57 KEY_Init(); /* 初始化KEY */ 58 USART_x_Init(); /* 初始化串口*/ 59 } 60 61 /*********************************************************************** 62 * @ 函数名 : AppTaskCreate 63 * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面 64 * @ 参数 : 无 65 * @ 返回值 : 无 66 **********************************************************************/ 67 static void AppTaskCreate(void) 68 { 69 BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ 70 taskENTER_CRITICAL(); /* 进入临界区 */ 71 /* 创建任务1 */ 72 xReturn = xTaskCreate((TaskFunction_t )LED1_Task, /* 任务入口函数 */ 73 (const char* )"LED1_Task", /* 任务名字 */ 74 (uint16_t )512, /* 任务栈大小 */ 75 (void* )NULL, /* 任务入口函数参数 */ 76 (UBaseType_t )2, /* 任务的优先级 */ 77 (TaskHandle_t* )&LED1_Task_Handle); /* 任务控制块指针 */ 78 if (pdPASS == xReturn) 79 { 80 printf("创建 LED1_Task 任务成功!\r\n"); 81 } 82 /* 创建任务2 */ 83 xReturn = xTaskCreate((TaskFunction_t )KEY_Task, /* 任务入口函数 */ 84 (const char* )"KEY_Task", /* 任务名字 */ 85 (uint16_t )512, /* 任务栈大小 */ 86 (void* )NULL, /* 任务入口函数参数 */ 87 (UBaseType_t )3, /* 任务的优先级 */ 88 (TaskHandle_t* )&KYE_Task_Handle); /* 任务控制块指针 */ 89 if (pdPASS == xReturn) 90 { 91 printf("创建 KEY_Task 任务成功!\r\n"); 92 } 93 vTaskDelete(AppTaskCreate_Handle); /* 删除 AppTaskCreate 任务 */ 94 taskEXIT_CRITICAL(); /* 退出临界区 */ 95 } 96 /********************************************************************** 97 * @ 函数名 : LED1_Task 98 * @ 功能说明: 实现LED灯的定时闪烁 99 * @ 参数 : 100 * @ 返回值 : 无 101 ********************************************************************/ 102 static void LED1_Task(void* pvParameters) 103 { 104 while(1) 105 { 106 LED2_ON; 107 vTaskDelay(500);/* 延时500个tick */ 108 LED2_OFF; 109 vTaskDelay(500); 110 } 111 } 112 /*********************************************************************** 113 * @ 函数名 : KEY_Task 114 * @ 功能说明: 实现了按键的检测,实现任务的挂起和恢复 115 * @ 参数 : 无 116 * @ 返回值 : 无 117 **********************************************************************/ 118 static void KEY_Task(void* pvParameters) 119 { 120 while(1) 121 { 122 if(Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON) 123 { 124 printf("挂起LED任务\n"); 125 vTaskSuspend(LED1_Task_Handle);/* 挂起 LED 任务 */ 126 } 127 if(Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON) 128 { 129 printf("恢复LED任务\n"); 130 vTaskResume(LED1_Task_Handle);/* 恢复 LED 任务! */ 131 } 132 vTaskDelay(20); 133 } 134 }
main.c
6)按下KEY1挂起任务,按下KEY2恢复任务,串口输出信息如下: