STM32移植FreeRTOS(1)

行者&無疆發表於2020-11-03

"STM32F103VET6<_>FreeRTOS"

1、專案功能實現

1)LED燈定時閃爍

2)KEY按鍵檢測

3)FreeRTOS任務建立

4)串列埠輸出程式執行狀態

2、軟體程式碼實現

1)LED燈初始化程式碼

STM32移植FreeRTOS(1)
 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
STM32移植FreeRTOS(1)
 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按鍵初始化程式碼

STM32移植FreeRTOS(1)
 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
STM32移植FreeRTOS(1)
 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串列埠初始化

STM32移植FreeRTOS(1)
 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
STM32移植FreeRTOS(1)
 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配置檔案(根據專案功能修改配置引數)

STM32移植FreeRTOS(1)
  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)主函式程式檔案

STM32移植FreeRTOS(1)
  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恢復任務,串列埠輸出資訊如下:

相關文章