前言
我為什么會寫移植呢,因?yàn)槭枪娞栍幸粋€(gè)兄弟想要我寫一份移植的教程,所以應(yīng)它要求我就寫了一篇。
準(zhǔn)備
在移植之前,我們首先要獲取到FreeRTOS的官方的源碼包。這里我們提供兩個(gè)下載鏈接:
一個(gè)是官網(wǎng):http://www.freertos.org/
另外一個(gè)是代碼托管網(wǎng)站:https://sourceforge.net/projects/freertos/files/FreeRTOS/
打開網(wǎng)站鏈接之后,我們選擇FreeRTOS的最新版本V9.0.0(2016年),盡管現(xiàn)在FreeRTOS的版本已經(jīng)更新到V10.0.1了,但是我們還是選擇V9.0.0,因?yàn)閮?nèi)核很穩(wěn)定,并且網(wǎng)上資料很多,因?yàn)閂10.0.0版本之后是亞馬遜收購了FreeRTOS之后才出來的版本,主要添加了一些云端組件,我們本書所講的FreeRTOS是實(shí)時(shí)內(nèi)核,采用V9.0.0版本足以。
簡單介紹FreeRTOS
FreeRTOS包含Demo例程和內(nèi)核源碼(比較重要,我們就需要提取該目錄下的大部分文件)。
Source文件夾里面包含的是FreeRTOS內(nèi)核的源代碼,我們移植FreeRTOS的時(shí)候就需要這部分源代碼;
Demo 文件夾里面包含了FreeRTOS官方為各個(gè)單片機(jī)移植好的工程代碼,F(xiàn)reeRTOS為了推廣自己,會給各種半導(dǎo)體廠商的評估板寫好完整的工程程序,這些程序就放在Demo這個(gè)目錄下,這部分Demo非常有參考價(jià)值。
在這里插入圖片描述
Source文件夾
這里我們再重點(diǎn)分析下FreeRTOS/ Source文件夾下的文件,①和③包含的是FreeRTOS的通用的頭文件和C文件,這兩部分的文件試用于各種編譯器和處理器,是通用的。需要移植的頭文件和C文件放在②portblle這個(gè)文件夾。
在這里插入圖片描述
portblle文件夾,是與編譯器相關(guān)的文件夾,在不同的編譯器中使用不同的支持文件。①中的KEIL就是我們就是我們使用的編譯器,其實(shí)KEIL里面的內(nèi)容跟RVDS里面的內(nèi)容一樣,所以我們只需要③RVDS文件夾里面的內(nèi)容即可,里面包含了各種處理器相關(guān)的文件夾,從文件夾的名字我們就非常熟悉了,我們學(xué)習(xí)的STM32有M0、M3、M4等各種系列,F(xiàn)reeRTOS是一個(gè)軟件,單片機(jī)是一個(gè)硬件,F(xiàn)reeRTOS要想運(yùn)行在一個(gè)單片機(jī)上面,它們就必須關(guān)聯(lián)在一起。MemMang文件夾下存放的是跟內(nèi)存管理相關(guān)的源文件。
在這里插入圖片描述
移植過程
提取源碼
-
首先在我們的STM32裸機(jī)工程模板根目錄下新建一個(gè)文件夾,命名為“FreeRTOS”,并且在FreeRTOS文件夾下新建兩個(gè)空文件夾,分別命名為“src”與“port”,src文件夾用于保存FreeRTOS中的核心源文件,也就是我們常說的‘.c文件’,port文件夾用于保存內(nèi)存管理以及處理器架構(gòu)相關(guān)代碼,這些代碼FreeRTOS官方已經(jīng)提供給我們的,直接使用即可,在前面已經(jīng)說了,F(xiàn)reeRTOS是軟件,我們的開發(fā)版是硬件,軟硬件必須有橋梁來連接,這些與處理器架構(gòu)相關(guān)的代碼,可以稱之為RTOS硬件接口層,它們位于FreeRTOS/Source/Portable文件夾下。
-
打開FreeRTOS V9.0.0源碼,在“FreeRTOSv9.0.0\\FreeRTOS\\Source”目錄下找到所有的‘.c文件’,將它們拷貝到我們新建的src文件夾中,
在這里插入圖片描述
-
打開FreeRTOS V9.0.0源碼,在“FreeRTOSv9.0.0\\FreeRTOS\\Source\\portable”目錄下找到“MemMang”文件夾與“RVDS”文件夾,將它們拷貝到我們新建的port文件夾中
在這里插入圖片描述
-
打開FreeRTOS V9.0.0源碼,在“FreeRTOSv9.0.0\\ FreeRTOS\\Source”目錄下找到“include”文件夾,它是我們需要用到FreeRTOS的一些頭文件,將它直接拷貝到我們新建的FreeRTOS文件夾中,完成這一步之后就可以看到我們新建的FreeRTOS文件夾已經(jīng)有3個(gè)文件夾,這3個(gè)文件夾就包含F(xiàn)reeRTOS的核心文件,至此,F(xiàn)reeRTOS的源碼就提取完成。
在這里插入圖片描述
添加到工程
添加FreeRTOSConfig.h文件
FreeRTOSConfig.h文件是FreeRTOS的工程配置文件,因?yàn)镕reeRTOS是可以裁剪的實(shí)時(shí)操作內(nèi)核,應(yīng)用于不同的處理器平臺,用戶可以通過修改這個(gè)FreeRTOS內(nèi)核的配置頭文件來裁剪FreeRTOS的功能,所以我們把它拷貝一份放在user這個(gè)文件夾下面。
打開FreeRTOSv9.0.0源碼,在“FreeRTOSv9.0.0\\FreeRTOS\\Demo”文件夾下面找到“CORTEX_STM32F103_Keil”這個(gè)文件夾,雙擊打開,在其根目錄下找到這個(gè)“FreeRTOSConfig.h”文件,然后拷貝到我們工程的user文件夾下即可,等下我們需要對這個(gè)文件進(jìn)行修改。
創(chuàng)建工程分組
接下來我們在mdk里面新建FreeRTOS/src和FreeRTOS/port兩個(gè)組文件夾,其中FreeRTOS/src用于存放src文件夾的內(nèi)容,F(xiàn)reeRTOS/port用于存放port\\MemMang文件夾 與port\\RVDS\\ARM_CM3文件夾的內(nèi)容。
然后我們將工程文件中FreeRTOS的內(nèi)容添加到工程中去,按照已經(jīng)新建的分組添加我們的FreeRTOS工程源碼。
在FreeRTOS/port分組中添加MemMang文件夾中的文件只需選擇其中一個(gè)即可,我們選擇“heap_4.c”,這是FreeRTOS的一個(gè)內(nèi)存管理源碼文件。
添加完成后:
在這里插入圖片描述
** 添加頭文件路徑**
FreeRTOS的源碼已經(jīng)添加到開發(fā)環(huán)境的組文件夾下面,編譯的時(shí)候需要為這些源文件指定頭文件的路徑,不然編譯會報(bào)錯。FreeRTOS的源碼里面只有FreeRTOS\\include和FreeRTOS\\port\\RVDS\\ARM_CM3這兩個(gè)文件夾下面有頭文件,只需要將這兩個(gè)頭文件的路徑在開發(fā)環(huán)境里面指定即可。同時(shí)我們還將FreeRTOSConfig.h這個(gè)頭文件拷貝到了工程根目錄下的user文件夾下,所以user的路徑也要加到開發(fā)環(huán)境里面。
在這里插入圖片描述
修改FreeRTOSConfig.h
FreeRTOSConfig.h是直接從demo文件夾下面拷貝過來的,該頭文件對裁剪整個(gè)FreeRTOS所需的功能的宏均做了定義,有些宏定義被使能,有些宏定義被失能,一開始我們只需要配置最簡單的功能即可。要想隨心所欲的配置FreeRTOS的功能,我們必須對這些宏定義的功能有所掌握,下面我們先簡單的介紹下這些宏定義的含義,然后再對這些宏定義進(jìn)行修改。
1#ifndef FREERTOS_CONFIG_H
2#define FREERTOS_CONFIG_H
3
4#include "stm32f10x.h"
5#include "bsp_usart.h"
6
7
8//針對不同的編譯器調(diào)用不同的stdint.h文件
9#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
10 #include <stdint.h>
11 extern uint32_t SystemCoreClock;
12#endif
13
14//斷言
15#define vAssertCalled(char,int) printf("Error:%s,%d\\r\\n",char,int)
16#define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__)
17
18/************************************************************************
19 * FreeRTOS基礎(chǔ)配置配置選項(xiàng)
20 *********************************************************************/
21/* 置1:RTOS使用搶占式調(diào)度器;置0:RTOS使用協(xié)作式調(diào)度器(時(shí)間片)
22 *
23 * 注:在多任務(wù)管理機(jī)制上,操作系統(tǒng)可以分為搶占式和協(xié)作式兩種。
24 * 協(xié)作式操作系統(tǒng)是任務(wù)主動釋放CPU后,切換到下一個(gè)任務(wù)。
25 * 任務(wù)切換的時(shí)機(jī)完全取決于正在運(yùn)行的任務(wù)。
26 */
27#define configUSE_PREEMPTION 1
28
29//1使能時(shí)間片調(diào)度(默認(rèn)式使能的)
30#define configUSE_TIME_SLICING 1
31
32/* 某些運(yùn)行FreeRTOS的硬件有兩種方法選擇下一個(gè)要執(zhí)行的任務(wù):
33 * 通用方法和特定于硬件的方法(以下簡稱“特殊方法”)。
34 *
35 * 通用方法:
36 * 1.configUSE_PORT_OPTIMISED_TASK_SELECTION 為 0 或者硬件不支持這種特殊方法。
37 * 2.可以用于所有FreeRTOS支持的硬件
38 * 3.完全用C實(shí)現(xiàn),效率略低于特殊方法。
39 * 4.不強(qiáng)制要求限制最大可用優(yōu)先級數(shù)目
40 * 特殊方法:
41 * 1.必須將configUSE_PORT_OPTIMISED_TASK_SELECTION設(shè)置為1。
42 * 2.依賴一個(gè)或多個(gè)特定架構(gòu)的匯編指令(一般是類似計(jì)算前導(dǎo)零[CLZ]指令)。
43 * 3.比通用方法更高效
44 * 4.一般強(qiáng)制限定最大可用優(yōu)先級數(shù)目為32
45 * 一般是硬件計(jì)算前導(dǎo)零指令,如果所使用的,MCU沒有這些硬件指令的話此宏應(yīng)該設(shè)置為0!
46 */
47#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
48
49/* 置1:使能低功耗tickless模式;置0:保持系統(tǒng)節(jié)拍(tick)中斷一直運(yùn)行
50 * 假設(shè)開啟低功耗的話可能會導(dǎo)致下載出現(xiàn)問題,因?yàn)槌绦蛟谒咧?可用以下辦法解決
51 *
52 * 下載方法:
53 * 1.將開發(fā)版正常連接好
54 * 2.按住復(fù)位按鍵,點(diǎn)擊下載瞬間松開復(fù)位按鍵
55 *
56 * 1.通過跳線帽將 BOOT 0 接高電平(3.3V)
57 * 2.重新上電,下載
58 *
59 * 1.使用FlyMcu擦除一下芯片,然后進(jìn)行下載
60 * STMISP -> 清除芯片(z)
61 */
62#define configUSE_TICKLESS_IDLE 0
63
64/*
65 * 寫入實(shí)際的CPU內(nèi)核時(shí)鐘頻率,也就是CPU指令執(zhí)行頻率,通常稱為Fclk
66 * Fclk為供給CPU內(nèi)核的時(shí)鐘信號,我們所說的cpu主頻為 XX MHz,
67 * 就是指的這個(gè)時(shí)鐘信號,相應(yīng)的,1/Fclk即為cpu時(shí)鐘周期;
68 */
69#define configCPU_CLOCK_HZ (SystemCoreClock)
70
71//RTOS系統(tǒng)節(jié)拍中斷的頻率。即一秒中斷的次數(shù),每次中斷RTOS都會進(jìn)行任務(wù)調(diào)度
72#define configTICK_RATE_HZ (( TickType_t )1000)
73
74//可使用的最大優(yōu)先級
75#define configMAX_PRIORITIES (32)
76
77//空閑任務(wù)使用的堆棧大小
78#define configMINIMAL_STACK_SIZE ((unsigned short)128)
79
80//任務(wù)名字字符串長度
81#define configMAX_TASK_NAME_LEN (16)
82
83 //系統(tǒng)節(jié)拍計(jì)數(shù)器變量數(shù)據(jù)類型,1表示為16位無符號整形,0表示為32位無符號整形
84#define configUSE_16_BIT_TICKS 0
85
86//空閑任務(wù)放棄CPU使用權(quán)給其他同優(yōu)先級的用戶任務(wù)
87#define configIDLE_SHOULD_YIELD 1
88
89//啟用隊(duì)列
90#define configUSE_QUEUE_SETS 1
91
92//開啟任務(wù)通知功能,默認(rèn)開啟
93#define configUSE_TASK_NOTIFICATIONS 1
94
95//使用互斥信號量
96#define configUSE_MUTEXES 1
97
98//使用遞歸互斥信號量
99#define configUSE_RECURSIVE_MUTEXES 1
100
101//為1時(shí)使用計(jì)數(shù)信號量
102#define configUSE_COUNTING_SEMAPHORES 1
103
104/* 設(shè)置可以注冊的信號量和消息隊(duì)列個(gè)數(shù) */
105#define configQUEUE_REGISTRY_SIZE 10
106
107#define configUSE_APPLICATION_TASK_TAG 0
108
109
110/*****************************************************************
111 FreeRTOS與內(nèi)存申請有關(guān)配置選項(xiàng)
112*****************************************************************/
113//支持動態(tài)內(nèi)存申請
114#define configSUPPORT_DYNAMIC_ALLOCATION 1
115//支持靜態(tài)內(nèi)存
116#define configSUPPORT_STATIC_ALLOCATION 0
117//系統(tǒng)所有總的堆大小
118#define configTOTAL_HEAP_SIZE ((size_t)(36*1024))
119
120
121/***************************************************************
122 FreeRTOS與鉤子函數(shù)有關(guān)的配置選項(xiàng)
123**************************************************************/
124/* 置1:使用空閑鉤子(Idle Hook類似于回調(diào)函數(shù));置0:忽略空閑鉤子
125 *
126 * 空閑任務(wù)鉤子是一個(gè)函數(shù),這個(gè)函數(shù)由用戶來實(shí)現(xiàn),
127 * FreeRTOS規(guī)定了函數(shù)的名字和參數(shù):void vApplicationIdleHook(void ),
128 * 這個(gè)函數(shù)在每個(gè)空閑任務(wù)周期都會被調(diào)用
129 * 對于已經(jīng)刪除的RTOS任務(wù),空閑任務(wù)可以釋放分配給它們的堆棧內(nèi)存。
130 * 因此必須保證空閑任務(wù)可以被CPU執(zhí)行
131 * 使用空閑鉤子函數(shù)設(shè)置CPU進(jìn)入省電模式是很常見的
132 * 不可以調(diào)用會引起空閑任務(wù)阻塞的API函數(shù)
133 */
134#define configUSE_IDLE_HOOK 0
135
136/* 置1:使用時(shí)間片鉤子(Tick Hook);置0:忽略時(shí)間片鉤子
137 *
138 *
139 * 時(shí)間片鉤子是一個(gè)函數(shù),這個(gè)函數(shù)由用戶來實(shí)現(xiàn),
140 * FreeRTOS規(guī)定了函數(shù)的名字和參數(shù):void vApplicationTickHook(void )
141 * 時(shí)間片中斷可以周期性的調(diào)用
142 * 函數(shù)必須非常短小,不能大量使用堆棧,
143 * 不能調(diào)用以”FromISR" 或 "FROM_ISR”結(jié)尾的API函數(shù)
144 */
145 /*xTaskIncrementTick函數(shù)是在xPortSysTickHandler中斷函數(shù)中被調(diào)用的。因此,vApplicationTickHook()函數(shù)執(zhí)行的時(shí)間必須很短才行*/
146#define configUSE_TICK_HOOK 0
147
148//使用內(nèi)存申請失敗鉤子函數(shù)
149#define configUSE_MALLOC_FAILED_HOOK 0
150
151/*
152 * 大于0時(shí)啟用堆棧溢出檢測功能,如果使用此功能
153 * 用戶必須提供一個(gè)棧溢出鉤子函數(shù),如果使用的話
154 * 此值可以為1或者2,因?yàn)橛袃煞N棧溢出檢測方法 */
155#define configCHECK_FOR_STACK_OVERFLOW 0
156
157
158/********************************************************************
159 FreeRTOS與運(yùn)行時(shí)間和任務(wù)狀態(tài)收集有關(guān)的配置選項(xiàng)
160**********************************************************************/
161//啟用運(yùn)行時(shí)間統(tǒng)計(jì)功能
162#define configGENERATE_RUN_TIME_STATS 0
163 //啟用可視化跟蹤調(diào)試
164#define configUSE_TRACE_FACILITY 0
165/* 與宏configUSE_TRACE_FACILITY同時(shí)為1時(shí)會編譯下面3個(gè)函數(shù)
166 * prvWriteNameToBuffer()
167 * vTaskList(),
168 * vTaskGetRunTimeStats()
169*/
170#define configUSE_STATS_FORMATTING_FUNCTIONS 1
171
172
173/********************************************************************
174 FreeRTOS與協(xié)程有關(guān)的配置選項(xiàng)
175*********************************************************************/
176//啟用協(xié)程,啟用協(xié)程以后必須添加文件croutine.c
177#define configUSE_CO_ROUTINES 0
178//協(xié)程的有效優(yōu)先級數(shù)目
179#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
180
181
182/***********************************************************************
183 FreeRTOS與軟件定時(shí)器有關(guān)的配置選項(xiàng)
184**********************************************************************/
185 //啟用軟件定時(shí)器
186#define configUSE_TIMERS 1
187//軟件定時(shí)器優(yōu)先級
188#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1)
189//軟件定時(shí)器隊(duì)列長度
190#define configTIMER_QUEUE_LENGTH 10
191//軟件定時(shí)器任務(wù)堆棧大小
192#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2)
193
194/************************************************************
195 FreeRTOS可選函數(shù)配置選項(xiàng)
196************************************************************/
197#define INCLUDE_xTaskGetSchedulerState 1
198#define INCLUDE_vTaskPrioritySet 1
199#define INCLUDE_uxTaskPriorityGet 1
200#define INCLUDE_vTaskDelete 1
201#define INCLUDE_vTaskCleanUpResources 1
202#define INCLUDE_vTaskSuspend 1
203#define INCLUDE_vTaskDelayUntil 1
204#define INCLUDE_vTaskDelay 1
205#define INCLUDE_eTaskGetState 1
206#define INCLUDE_xTimerPendFunctionCall 1
207//#define INCLUDE_xTaskGetCurrentTaskHandle 1
208//#define INCLUDE_uxTaskGetStackHighWaterMark 0
209//#define INCLUDE_xTaskGetIdleTaskHandle 0
210
211
212/******************************************************************
213 FreeRTOS與中斷有關(guān)的配置選項(xiàng)
214******************************************************************/
215#ifdef __NVIC_PRIO_BITS
216 #define configPRIO_BITS __NVIC_PRIO_BITS
217#else
218 #define configPRIO_BITS 4
219#endif
220//中斷最低優(yōu)先級
221#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
222
223//系統(tǒng)可管理的最高中斷優(yōu)先級
224#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
225
226#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* 240 */
227
228#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
229
230
231/****************************************************************
232 FreeRTOS與中斷服務(wù)函數(shù)有關(guān)的配置選項(xiàng)
233****************************************************************/
234#define xPortPendSVHandler PendSV_Handler
235#define vPortSVCHandler SVC_Handler
236
237
238/* 以下為使用Percepio Tracealyzer需要的東西,不需要時(shí)將 configUSE_TRACE_FACILITY 定義為 0 */
239#if ( configUSE_TRACE_FACILITY == 1 )
240#include "trcRecorder.h"
241#define INCLUDE_xTaskGetCurrentTaskHandle 1 // 啟用一個(gè)可選函數(shù)(該函數(shù)被 Trace源碼使用,默認(rèn)該值為0 表示不用)
242#endif
243
244
245#endif /* FREERTOS_CONFIG_H */
修改stm32f10x_it.c
SysTick中斷服務(wù)函數(shù)是一個(gè)非常重要的函數(shù),F(xiàn)reeRTOS所有跟時(shí)間相關(guān)的事情都在里面處理,SysTick就是FreeRTOS的一個(gè)心跳時(shí)鐘,驅(qū)動著FreeRTOS的運(yùn)行,就像人的心跳一樣,假如沒有心跳,我們就相當(dāng)于“死了”,同樣的,F(xiàn)reeRTOS沒有了心跳,那么它就會卡死在某個(gè)地方,不能進(jìn)行任務(wù)調(diào)度,不能運(yùn)行任何的東西,因此我們需要實(shí)現(xiàn)一個(gè)FreeRTOS的心跳時(shí)鐘,F(xiàn)reeRTOS幫我們實(shí)現(xiàn)了SysTick的啟動的配置:在port.c文件中已經(jīng)實(shí)現(xiàn)vPortSetupTimerInterrupt()函數(shù),并且FreeRTOS通用的SysTick中斷服務(wù)函數(shù)也實(shí)現(xiàn)了:在port.c文件中已經(jīng)實(shí)現(xiàn)xPortSysTickHandler()函數(shù),所以移植的時(shí)候只需要我們在stm32f10x_it.c文件中實(shí)現(xiàn)我們對應(yīng)(STM32)平臺上的SysTick_Handler()函數(shù)即可。FreeRTOS為開發(fā)者考慮得特別多,PendSV_Handler()與SVC_Handler()這兩個(gè)很重要的函數(shù)都幫我們實(shí)現(xiàn)了,在在port.c文件中已經(jīng)實(shí)現(xiàn)xPortPendSVHandler()與vPortSVCHandler()函數(shù),防止我們自己實(shí)現(xiàn)不了,那么在stm32f10x_it.c中就需要我們注釋掉PendSV_Handler()與SVC_Handler()這兩個(gè)函數(shù)了。
1//void SVC_Handler(void)
2//{
3//}
4
5//void PendSV_Handler(void)
6//{
7//}
8
9extern void xPortSysTickHandler(void);
10
11//systick中斷服務(wù)函數(shù)
12void SysTick_Handler(void)
13{
14 #if (INCLUDE_xTaskGetSchedulerState == 1 )
15 if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
16 {
17 #endif /* INCLUDE_xTaskGetSchedulerState */
18 xPortSysTickHandler();
19 #if (INCLUDE_xTaskGetSchedulerState == 1 )
20 }
21 #endif /* INCLUDE_xTaskGetSchedulerState */
22}
創(chuàng)建任務(wù)
這里,我們創(chuàng)建一個(gè)單任務(wù),任務(wù)使用的棧和任務(wù)控制塊是在創(chuàng)建任務(wù)的時(shí)候FreeRTOS動態(tài)分配的。
任務(wù)必須是一個(gè)死循環(huán),否則任務(wù)將通過LR返回,如果LR指向了非法的內(nèi)存就會產(chǎn)生HardFault_Handler,而FreeRTOS指向一個(gè)死循環(huán),那么任務(wù)返回之后就在死循環(huán)中執(zhí)行,這樣子的任務(wù)是不安全的,所以避免這種情況,任務(wù)一般都是死循環(huán)并且無返回值的。
并且每個(gè)任務(wù)循環(huán)主體中應(yīng)該有阻塞任務(wù)的函數(shù),否則就會餓死比它優(yōu)先級更低的任務(wù)?。?!
1/* FreeRTOS頭文件 */
2#include "FreeRTOS.h"
3#include "task.h"
4/* 開發(fā)板硬件bsp頭文件 */
5#include "bsp_led.h"
6
7static void AppTaskCreate(void);/* AppTask任務(wù) */
8
9 /* 創(chuàng)建任務(wù)句柄 */
10static TaskHandle_t AppTask_Handle = NULL;
11
12int main(void)
13{
14 BaseType_t xReturn = pdPASS;/* 定義一個(gè)創(chuàng)建信息返回值,默認(rèn)為pdPASS */
15
16 /* 開發(fā)板硬件初始化 */
17 BSP_Init();
18
19 /* 創(chuàng)建AppTaskCreate任務(wù) */
20 xReturn = xTaskCreate((TaskFunction_t )AppTask, /* 任務(wù)入口函數(shù) */
21 (const char* )"AppTask",/* 任務(wù)名字 */
22 (uint16_t )512, /* 任務(wù)棧大小 */
23 (void* )NULL,/* 任務(wù)入口函數(shù)參數(shù) */
24 (UBaseType_t )1, /* 任務(wù)的優(yōu)先級 */
25 (TaskHandle_t* )&AppTask_Handle);/* 任務(wù)控制塊指針 */
26 /* 啟動任務(wù)調(diào)度 */
27 if(pdPASS == xReturn)
28 vTaskStartScheduler(); /* 啟動任務(wù),開啟調(diào)度 */
29 else
30 return -1;
31
32 while(1); /* 正常不會執(zhí)行到這里 */
33}
34
35static void AppTask(void* parameter)
36{
37 while (1)
38 {
39 LED1_ON;
40 vTaskDelay(500); /* 延時(shí)500個(gè)tick */
41 LED1_OFF;
42 vTaskDelay(500); /* 延時(shí)500個(gè)tick */
43 }
44}
-
源代碼
+關(guān)注
關(guān)注
96文章
2943瀏覽量
66618 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
483瀏覽量
61915 -
Source
+關(guān)注
關(guān)注
0文章
17瀏覽量
9778
發(fā)布評論請先 登錄
相關(guān)推薦
評論