FreeRTOS移植——基于stm32f1

準(zhǔn)備

在移植之前,我們首先要獲取到FreeRTOS的官方的源碼包瘫拣。這里我們提供兩個(gè)下載鏈接:

一個(gè)是官網(wǎng):http://www.freertos.org/
另外一個(gè)是代碼托管網(wǎng)站:https://sourceforge.net/projects/freertos/files/FreeRTOS/

這里我們演示如何在代碼托管網(wǎng)站里面下載。打開網(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為了推廣自己爷肝,會(huì)給各種半導(dǎo)體廠商的評(píng)估板寫好完整的工程程序猾浦,這些程序就放在Demo這個(gè)目錄下,這部分Demo非常有參考價(jià)值灯抛。

demo目錄

Source文件夾

這里我們?cè)僦攸c(diǎn)分析下FreeRTOS/ Source文件夾下的文件金赦,①和③包含的是FreeRTOS的通用的頭文件和C文件,這兩部分的文件試用于各種編譯器和處理器对嚼,是通用的夹抗。需要移植的頭文件和C文件放在②portblle這個(gè)文件夾。

Source文件夾1

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)的源文件句葵。

Source文件夾2

移植過程

提取源碼

  1. 首先在我們的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文件夾下采驻。
  2. 打開FreeRTOS V9.0.0源碼审胚,在“FreeRTOSv9.0.0\FreeRTOS\Source”目錄下找到所有的‘.c文件’,將它們拷貝到我們新建的src文件夾中:
拷貝1
  1. 打開FreeRTOS V9.0.0源碼礼旅,在“FreeRTOSv9.0.0\FreeRTOS\Source\portable”目錄下找到“MemMang”文件夾與“RVDS”文件夾菲盾,將它們拷貝到我們新建的port文件夾中
拷貝2
  1. 打開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的源碼就提取完成奴璃。
拷貝3

添加到工程

添加FreeRTOSConfig.h文件
FreeRTOSConfig.h文件是FreeRTOS的工程配置文件瞳秽,因?yàn)镕reeRTOS是可以裁剪的實(shí)時(shí)操作內(nèi)核插龄,應(yīng)用于不同的處理器平臺(tái),用戶可以通過修改這個(gè)FreeRTOS內(nèi)核的配置頭文件來裁剪FreeRTOS的功能,所以我們把它拷貝一份放在user這個(gè)文件夾下面循集。
打開FreeRTOSv9.0.0源碼荣瑟,在“FreeRTOSv9.0.0\FreeRTOS\Demo”文件夾下面找到“CORTEX_STM32F103_Keil”這個(gè)文件夾世剖,雙擊打開杆怕,在其根目錄下找到這個(gè)“FreeRTOSConfig.h”文件,然后拷貝到我們工程的user文件夾下即可攒盈,等下我們需要對(duì)這個(gè)文件進(jìn)行修改抵拘。
創(chuàng)建工程分組
接下來我們?cè)趍dk里面新建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)存管理源碼文件。
添加完成后:

創(chuàng)建過程分組

** 添加頭文件路徑**
FreeRTOS的源碼已經(jīng)添加到開發(fā)環(huán)境的組文件夾下面驼侠,編譯的時(shí)候需要為這些源文件指定頭文件的路徑姿鸿,不然編譯會(huì)報(bào)錯(cuò)。FreeRTOS的源碼里面只有FreeRTOS\include和FreeRTOS\port\RVDS\ARM_CM3這兩個(gè)文件夾下面有頭文件泪电,只需要將這兩個(gè)頭文件的路徑在開發(fā)環(huán)境里面指定即可般妙。同時(shí)我們還將FreeRTOSConfig.h這個(gè)頭文件拷貝到了工程根目錄下的user文件夾下纪铺,所以u(píng)ser的路徑也要加到開發(fā)環(huán)境里面相速。

添加頭文件路徑

修改FreeRTOSConfig.h

FreeRTOSConfig.h是直接從demo文件夾下面拷貝過來的,該頭文件對(duì)裁剪整個(gè)FreeRTOS所需的功能的宏均做了定義鲜锚,有些宏定義被使能突诬,有些宏定義被失能,一開始我們只需要配置最簡單的功能即可芜繁。要想隨心所欲的配置FreeRTOS的功能旺隙,我們必須對(duì)這些宏定義的功能有所掌握,下面我們先簡單的介紹下這些宏定義的含義骏令,然后再對(duì)這些宏定義進(jìn)行修改蔬捷。

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include "stm32f10x.h"
#include "bsp_usart.h"


//針對(duì)不同的編譯器調(diào)用不同的stdint.h文件
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
    #include <stdint.h>
    extern uint32_t SystemCoreClock;
#endif

//斷言
#define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int)
#define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__)

/************************************************************************
 *               FreeRTOS基礎(chǔ)配置配置選項(xiàng) 
 *********************************************************************/
/* 置1:RTOS使用搶占式調(diào)度器;置0:RTOS使用協(xié)作式調(diào)度器(時(shí)間片)
 * 
 * 注:在多任務(wù)管理機(jī)制上榔袋,操作系統(tǒng)可以分為搶占式和協(xié)作式兩種周拐。
 * 協(xié)作式操作系統(tǒng)是任務(wù)主動(dòng)釋放CPU后,切換到下一個(gè)任務(wù)凰兑。
 * 任務(wù)切換的時(shí)機(jī)完全取決于正在運(yùn)行的任務(wù)妥粟。
 */
#define configUSE_PREEMPTION                      1

//1使能時(shí)間片調(diào)度(默認(rèn)式使能的)
#define configUSE_TIME_SLICING                  1       

/* 某些運(yùn)行FreeRTOS的硬件有兩種方法選擇下一個(gè)要執(zhí)行的任務(wù):
 * 通用方法和特定于硬件的方法(以下簡稱“特殊方法”)。
 * 
 * 通用方法:
 *      1.configUSE_PORT_OPTIMISED_TASK_SELECTION 為 0 或者硬件不支持這種特殊方法吏够。
 *      2.可以用于所有FreeRTOS支持的硬件
 *      3.完全用C實(shí)現(xiàn)勾给,效率略低于特殊方法。
 *      4.不強(qiáng)制要求限制最大可用優(yōu)先級(jí)數(shù)目
 * 特殊方法:
 *      1.必須將configUSE_PORT_OPTIMISED_TASK_SELECTION設(shè)置為1锅知。
 *      2.依賴一個(gè)或多個(gè)特定架構(gòu)的匯編指令(一般是類似計(jì)算前導(dǎo)零[CLZ]指令)播急。
 *      3.比通用方法更高效
 *      4.一般強(qiáng)制限定最大可用優(yōu)先級(jí)數(shù)目為32
 * 一般是硬件計(jì)算前導(dǎo)零指令,如果所使用的售睹,MCU沒有這些硬件指令的話此宏應(yīng)該設(shè)置為0旅择!
 */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION         1                       
                                                                        
/* 置1:使能低功耗tickless模式;置0:保持系統(tǒng)節(jié)拍(tick)中斷一直運(yùn)行
 * 假設(shè)開啟低功耗的話可能會(huì)導(dǎo)致下載出現(xiàn)問題侣姆,因?yàn)槌绦蛟谒咧?可用以下辦法解決
 * 
 * 下載方法:
 *      1.將開發(fā)版正常連接好
 *      2.按住復(fù)位按鍵生真,點(diǎn)擊下載瞬間松開復(fù)位按鍵
 *     
 *      1.通過跳線帽將 BOOT 0 接高電平(3.3V)
 *      2.重新上電沉噩,下載
 *    
 *          1.使用FlyMcu擦除一下芯片,然后進(jìn)行下載
 *          STMISP -> 清除芯片(z)
 */
#define configUSE_TICKLESS_IDLE                                                 0   

/*
 * 寫入實(shí)際的CPU內(nèi)核時(shí)鐘頻率柱蟀,也就是CPU指令執(zhí)行頻率川蒙,通常稱為Fclk
 * Fclk為供給CPU內(nèi)核的時(shí)鐘信號(hào),我們所說的cpu主頻為 XX MHz长已,
 * 就是指的這個(gè)時(shí)鐘信號(hào)畜眨,相應(yīng)的,1/Fclk即為cpu時(shí)鐘周期术瓮;
 */
#define configCPU_CLOCK_HZ                        (SystemCoreClock)

//RTOS系統(tǒng)節(jié)拍中斷的頻率康聂。即一秒中斷的次數(shù),每次中斷RTOS都會(huì)進(jìn)行任務(wù)調(diào)度
#define configTICK_RATE_HZ                        (( TickType_t )1000)

//可使用的最大優(yōu)先級(jí)
#define configMAX_PRIORITIES                      (32)

//空閑任務(wù)使用的堆棧大小
#define configMINIMAL_STACK_SIZE                ((unsigned short)128)
  
//任務(wù)名字字符串長度
#define configMAX_TASK_NAME_LEN                 (16)

 //系統(tǒng)節(jié)拍計(jì)數(shù)器變量數(shù)據(jù)類型胞四,1表示為16位無符號(hào)整形恬汁,0表示為32位無符號(hào)整形
#define configUSE_16_BIT_TICKS                  0                      

//空閑任務(wù)放棄CPU使用權(quán)給其他同優(yōu)先級(jí)的用戶任務(wù)
#define configIDLE_SHOULD_YIELD                 1           

//啟用隊(duì)列
#define configUSE_QUEUE_SETS                      1    

//開啟任務(wù)通知功能,默認(rèn)開啟
#define configUSE_TASK_NOTIFICATIONS    1   

//使用互斥信號(hào)量
#define configUSE_MUTEXES                           1    

//使用遞歸互斥信號(hào)量                                            
#define configUSE_RECURSIVE_MUTEXES         1   

//為1時(shí)使用計(jì)數(shù)信號(hào)量
#define configUSE_COUNTING_SEMAPHORES       1

/* 設(shè)置可以注冊(cè)的信號(hào)量和消息隊(duì)列個(gè)數(shù) */
#define configQUEUE_REGISTRY_SIZE               10                                 
                                                                       
#define configUSE_APPLICATION_TASK_TAG        0                       
                      

/*****************************************************************
              FreeRTOS與內(nèi)存申請(qǐng)有關(guān)配置選項(xiàng)                                               
*****************************************************************/
//支持動(dòng)態(tài)內(nèi)存申請(qǐng)
#define configSUPPORT_DYNAMIC_ALLOCATION        1    
//支持靜態(tài)內(nèi)存
#define configSUPPORT_STATIC_ALLOCATION                 0                   
//系統(tǒng)所有總的堆大小
#define configTOTAL_HEAP_SIZE                   ((size_t)(36*1024))    


/***************************************************************
             FreeRTOS與鉤子函數(shù)有關(guān)的配置選項(xiàng)                                            
**************************************************************/
/* 置1:使用空閑鉤子(Idle Hook類似于回調(diào)函數(shù))辜伟;置0:忽略空閑鉤子
 * 
 * 空閑任務(wù)鉤子是一個(gè)函數(shù)氓侧,這個(gè)函數(shù)由用戶來實(shí)現(xiàn),
 * FreeRTOS規(guī)定了函數(shù)的名字和參數(shù):void vApplicationIdleHook(void )导狡,
 * 這個(gè)函數(shù)在每個(gè)空閑任務(wù)周期都會(huì)被調(diào)用
 * 對(duì)于已經(jīng)刪除的RTOS任務(wù)约巷,空閑任務(wù)可以釋放分配給它們的堆棧內(nèi)存。
 * 因此必須保證空閑任務(wù)可以被CPU執(zhí)行
 * 使用空閑鉤子函數(shù)設(shè)置CPU進(jìn)入省電模式是很常見的
 * 不可以調(diào)用會(huì)引起空閑任務(wù)阻塞的API函數(shù)
 */
#define configUSE_IDLE_HOOK                     0      

/* 置1:使用時(shí)間片鉤子(Tick Hook)旱捧;置0:忽略時(shí)間片鉤子
 * 
 * 
 * 時(shí)間片鉤子是一個(gè)函數(shù)独郎,這個(gè)函數(shù)由用戶來實(shí)現(xiàn),
 * FreeRTOS規(guī)定了函數(shù)的名字和參數(shù):void vApplicationTickHook(void )
 * 時(shí)間片中斷可以周期性的調(diào)用
 * 函數(shù)必須非常短小枚赡,不能大量使用堆棧氓癌,
 * 不能調(diào)用以”FromISR" 或 "FROM_ISR”結(jié)尾的API函數(shù)
 */
 /*xTaskIncrementTick函數(shù)是在xPortSysTickHandler中斷函數(shù)中被調(diào)用的。因此标锄,vApplicationTickHook()函數(shù)執(zhí)行的時(shí)間必須很短才行*/
#define configUSE_TICK_HOOK                     0           

//使用內(nèi)存申請(qǐng)失敗鉤子函數(shù)
#define configUSE_MALLOC_FAILED_HOOK            0 

/*
 * 大于0時(shí)啟用堆棧溢出檢測(cè)功能顽铸,如果使用此功能 
 * 用戶必須提供一個(gè)棧溢出鉤子函數(shù),如果使用的話
 * 此值可以為1或者2料皇,因?yàn)橛袃煞N棧溢出檢測(cè)方法 */
#define configCHECK_FOR_STACK_OVERFLOW          0   


/********************************************************************
          FreeRTOS與運(yùn)行時(shí)間和任務(wù)狀態(tài)收集有關(guān)的配置選項(xiàng)   
**********************************************************************/
//啟用運(yùn)行時(shí)間統(tǒng)計(jì)功能
#define configGENERATE_RUN_TIME_STATS           0             
 //啟用可視化跟蹤調(diào)試
#define configUSE_TRACE_FACILITY                      0    
/* 與宏configUSE_TRACE_FACILITY同時(shí)為1時(shí)會(huì)編譯下面3個(gè)函數(shù)
 * prvWriteNameToBuffer()
 * vTaskList(),
 * vTaskGetRunTimeStats()
*/
#define configUSE_STATS_FORMATTING_FUNCTIONS    1                       
                                                                        
                                                                        
/********************************************************************
                FreeRTOS與協(xié)程有關(guān)的配置選項(xiàng)                                                
*********************************************************************/
//啟用協(xié)程谓松,啟用協(xié)程以后必須添加文件croutine.c
#define configUSE_CO_ROUTINES                     0                 
//協(xié)程的有效優(yōu)先級(jí)數(shù)目
#define configMAX_CO_ROUTINE_PRIORITIES       ( 2 )                   


/***********************************************************************
                FreeRTOS與軟件定時(shí)器有關(guān)的配置選項(xiàng)      
**********************************************************************/
 //啟用軟件定時(shí)器
#define configUSE_TIMERS                            1                              
//軟件定時(shí)器優(yōu)先級(jí)
#define configTIMER_TASK_PRIORITY               (configMAX_PRIORITIES-1)        
//軟件定時(shí)器隊(duì)列長度
#define configTIMER_QUEUE_LENGTH                10                               
//軟件定時(shí)器任務(wù)堆棧大小
#define configTIMER_TASK_STACK_DEPTH          (configMINIMAL_STACK_SIZE*2)    

/************************************************************
            FreeRTOS可選函數(shù)配置選項(xiàng)                                                     
************************************************************/
#define INCLUDE_xTaskGetSchedulerState       1                       
#define INCLUDE_vTaskPrioritySet                 1
#define INCLUDE_uxTaskPriorityGet                1
#define INCLUDE_vTaskDelete                        1
#define INCLUDE_vTaskCleanUpResources          1
#define INCLUDE_vTaskSuspend                       1
#define INCLUDE_vTaskDelayUntil                  1
#define INCLUDE_vTaskDelay                         1
#define INCLUDE_eTaskGetState                      1
#define INCLUDE_xTimerPendFunctionCall       1
//#define INCLUDE_xTaskGetCurrentTaskHandle       1
//#define INCLUDE_uxTaskGetStackHighWaterMark     0
//#define INCLUDE_xTaskGetIdleTaskHandle          0


/******************************************************************
            FreeRTOS與中斷有關(guān)的配置選項(xiàng)                                                 
******************************************************************/
#ifdef __NVIC_PRIO_BITS
    #define configPRIO_BITS             __NVIC_PRIO_BITS
#else
    #define configPRIO_BITS             4                  
#endif
//中斷最低優(yōu)先級(jí)
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15     

//系統(tǒng)可管理的最高中斷優(yōu)先級(jí)
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5 

#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )    /* 240 */

#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )


/****************************************************************
            FreeRTOS與中斷服務(wù)函數(shù)有關(guān)的配置選項(xiàng)                         
****************************************************************/
#define xPortPendSVHandler  PendSV_Handler
#define vPortSVCHandler     SVC_Handler


/* 以下為使用Percepio Tracealyzer需要的東西,不需要時(shí)將 configUSE_TRACE_FACILITY 定義為 0 */
#if ( configUSE_TRACE_FACILITY == 1 )
#include "trcRecorder.h"
#define INCLUDE_xTaskGetCurrentTaskHandle               1   // 啟用一個(gè)可選函數(shù)(該函數(shù)被 Trace源碼使用践剂,默認(rèn)該值為0 表示不用)
#endif


#endif /* FREERTOS_CONFIG_H */

修改stm32f10x_it.c

SysTick中斷服務(wù)函數(shù)是一個(gè)非常重要的函數(shù)鬼譬,F(xiàn)reeRTOS所有跟時(shí)間相關(guān)的事情都在里面處理,SysTick就是FreeRTOS的一個(gè)心跳時(shí)鐘逊脯,驅(qū)動(dòng)著FreeRTOS的運(yùn)行优质,就像人的心跳一樣,假如沒有心跳,我們就相當(dāng)于“死了”巩螃,同樣的演怎,F(xiàn)reeRTOS沒有了心跳,那么它就會(huì)卡死在某個(gè)地方避乏,不能進(jìn)行任務(wù)調(diào)度爷耀,不能運(yùn)行任何的東西,因此我們需要實(shí)現(xiàn)一個(gè)FreeRTOS的心跳時(shí)鐘拍皮,F(xiàn)reeRTOS幫我們實(shí)現(xiàn)了SysTick的啟動(dòng)的配置:在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í)候只需要我們?cè)趕tm32f10x_it.c文件中實(shí)現(xiàn)我們對(duì)應(yīng)(STM32)平臺(tái)上的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ù)了。

//void SVC_Handler(void)
//{
//}

//void PendSV_Handler(void)
//{
//}

extern void xPortSysTickHandler(void);

//systick中斷服務(wù)函數(shù)
void SysTick_Handler(void)
{   
    #if (INCLUDE_xTaskGetSchedulerState  == 1 )
      if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
      {
    #endif  /* INCLUDE_xTaskGetSchedulerState */  
        xPortSysTickHandler();
    #if (INCLUDE_xTaskGetSchedulerState  == 1 )
      }
    #endif  /* INCLUDE_xTaskGetSchedulerState */
}

創(chuàng)建任務(wù)

這里宅荤,我們創(chuàng)建一個(gè)單任務(wù)屑迂,任務(wù)使用的棧和任務(wù)控制塊是在創(chuàng)建任務(wù)的時(shí)候FreeRTOS動(dòng)態(tài)分配的浸策。
任務(wù)必須是一個(gè)死循環(huán)冯键,否則任務(wù)將通過LR返回,如果LR指向了非法的內(nèi)存就會(huì)產(chǎn)生HardFault_Handler庸汗,而FreeRTOS指向一個(gè)死循環(huán)惫确,那么任務(wù)返回之后就在死循環(huán)中執(zhí)行,這樣子的任務(wù)是不安全的蚯舱,所以避免這種情況改化,任務(wù)一般都是死循環(huán)并且無返回值的。
并且每個(gè)任務(wù)循環(huán)主體中應(yīng)該有阻塞任務(wù)的函數(shù)枉昏,否則就會(huì)餓死比它優(yōu)先級(jí)更低的任務(wù)3赂亍!兄裂!

/* FreeRTOS頭文件 */
#include "FreeRTOS.h"
#include "task.h"
/* 開發(fā)板硬件bsp頭文件 */
#include "bsp_led.h"

static void AppTaskCreate(void);/* AppTask任務(wù) */

 /* 創(chuàng)建任務(wù)句柄 */
static TaskHandle_t AppTask_Handle = NULL;

int main(void)
{   
  BaseType_t xReturn = pdPASS;/* 定義一個(gè)創(chuàng)建信息返回值句旱,默認(rèn)為pdPASS */

  /* 開發(fā)板硬件初始化 */
  BSP_Init();

   /* 創(chuàng)建AppTaskCreate任務(wù) */
  xReturn = xTaskCreate((TaskFunction_t )AppTask,  /* 任務(wù)入口函數(shù) */
                        (const char*    )"AppTask",/* 任務(wù)名字 */
                        (uint16_t       )512,  /* 任務(wù)棧大小 */
                        (void*          )NULL,/* 任務(wù)入口函數(shù)參數(shù) */
                        (UBaseType_t    )1, /* 任務(wù)的優(yōu)先級(jí) */
                        (TaskHandle_t*  )&AppTask_Handle);/* 任務(wù)控制塊指針 */ 
  /* 啟動(dòng)任務(wù)調(diào)度 */           
  if(pdPASS == xReturn)
    vTaskStartScheduler();   /* 啟動(dòng)任務(wù),開啟調(diào)度 */
  else
    return -1;  
  
  while(1);   /* 正常不會(huì)執(zhí)行到這里 */    
}

static void AppTask(void* parameter)
{   
    while (1)
    {
        LED1_ON;
        vTaskDelay(500);   /* 延時(shí)500個(gè)tick */
        LED1_OFF;     
        vTaskDelay(500);   /* 延時(shí)500個(gè)tick */             
    }
}

進(jìn)步始于交流
收獲源于分享
歡迎關(guān)注我的個(gè)人公眾號(hào)
"創(chuàng)客飛夢(mèng)空間"
更多干貨等你來


gzh
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晰奖,一起剝皮案震驚了整個(gè)濱河市谈撒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匾南,老刑警劉巖啃匿,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡溯乒,警方通過查閱死者的電腦和手機(jī)夹厌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裆悄,“玉大人尊流,你說我怎么就攤上這事〉瓢铮” “怎么了崖技?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長钟哥。 經(jīng)常有香客問我迎献,道長,這世上最難降的妖魔是什么腻贰? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任吁恍,我火速辦了婚禮,結(jié)果婚禮上播演,老公的妹妹穿的比我還像新娘冀瓦。我一直安慰自己,他們只是感情好写烤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布翼闽。 她就那樣靜靜地躺著,像睡著了一般洲炊。 火紅的嫁衣襯著肌膚如雪感局。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天暂衡,我揣著相機(jī)與錄音询微,去河邊找鬼。 笑死狂巢,一個(gè)胖子當(dāng)著我的面吹牛撑毛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播唧领,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼藻雌,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了疹吃?” 一聲冷哼從身側(cè)響起蹦疑,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎萨驶,沒想到半個(gè)月后歉摧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年叁温,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了再悼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡膝但,死狀恐怖冲九,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情跟束,我是刑警寧澤莺奸,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站冀宴,受9級(jí)特大地震影響灭贷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜略贮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一甚疟、第九天 我趴在偏房一處隱蔽的房頂上張望逃延。 院中可真熱鬧览妖,春花似錦、人聲如沸揽祥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盔然。三九已至桅打,卻和暖如春是嗜,著一層夾襖步出監(jiān)牢的瞬間愈案,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國打工鹅搪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留站绪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓丽柿,卻偏偏與公主長得像恢准,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子甫题,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 在C語言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,341評(píng)論 0 2
  • 一馁筐、Python簡介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡介】: Python 是一個(gè)...
    _小老虎_閱讀 5,744評(píng)論 0 10
  • 東野圭吾的又一本書。 這是我前兩天從圖書館借的書坠非。 花了兩天時(shí)間看完了這本書敏沉,是在從放寒假,一月開始到目前開...
    interested小小銳閱讀 288評(píng)論 0 0
  • 日子快要混不下去了,朋友推薦盟迟,準(zhǔn)備在微信上發(fā)發(fā)廣告秋泳,掙點(diǎn)勞務(wù)費(fèi),勉強(qiáng)湊活算微商吧攒菠。3天了迫皱,每天不辭辛苦,在...
    杜一一閱讀 325評(píng)論 0 2
  • 也許每個(gè)季節(jié)都有自己的使命辖众,它們將最好的極力呈現(xiàn)給人們卓起,希望能給人們的生活帶來激情和希望! 秋天凹炸,是金...
    蘇夏之閱讀 451評(píng)論 5 4