那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于STM32F103系統(tǒng)的FreeRTOS程序移植

冬至子 ? 來源:月月望歸鳥 ? 作者:K.Fire ? 2023-11-10 11:03 ? 次閱讀

1

FreeRTOS移植及配置

在程序中,移植了正點(diǎn)原子的基于STM32的FreeRTOS程序,編寫了自己的內(nèi)存管理程序malloc.c,程序主要結(jié)構(gòu)如下:

圖片

FreeRTOS_CORE中是FreeRTOS的核心文件,包括與協(xié)程有關(guān)的croutine.c,與事件組有關(guān)的event_groups.c,與列表有關(guān)的list.c,與隊(duì)列有關(guān)的queue.c,與任務(wù)有關(guān)的tasks.c,與定時(shí)器時(shí)鐘有關(guān)的timers.c。

FreeRTOS_PORTABLE中是與FreeRTOS內(nèi)存管理有關(guān)的文件,包括port.c和heap_4.c,port.c中主要包含一些與中斷有關(guān)的函數(shù),heap_4.c上一篇文章有詳細(xì)介紹,與內(nèi)存分配釋放有關(guān)。

在FreeRTOSConfig.h文件中,對FreeRTOS的很多參數(shù)進(jìn)行了配置,用戶可以修改其中的文件對程序參量進(jìn)行配置并對程序功能進(jìn)行選擇使用。

先聲明了一個(gè)斷言,方便提示用戶,當(dāng)程序出錯(cuò)時(shí)在FreeRTOS的那個(gè)程序哪一行出錯(cuò)。

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

然后是與任務(wù)調(diào)度算法相關(guān)的配置選項(xiàng),主要的是configUSE_PREEMPTION和configUSE_TIME_SLICING,不過一般都開啟,置1就行。

/***************************************************************************************************************/
/*                                           調(diào)度算法配置選項(xiàng)                                                  */
/***************************************************************************************************************/
#define configUSE_PREEMPTION          1                       //1使用搶占式內(nèi)核,0使用協(xié)程
#define configUSE_TIME_SLICING          1            //1使能時(shí)間片調(diào)度(默認(rèn)是使能的),同等優(yōu)先級是否交替執(zhí)行
#define configUSE_PORT_OPTIMISED_TASK_SELECTION  1                       //1啟用特殊方法(使用硬件方法)來選擇下一個(gè)要運(yùn)行的任務(wù)
                                                                        //一般是硬件計(jì)算前導(dǎo)零指令,如果所使用的
                                                                        //MCU沒有這些硬件指令的話此宏應(yīng)該設(shè)置為0!
#define configUSE_TICKLESS_IDLE          0                       //1啟用低功耗tickless模式

然后是基礎(chǔ)配置選項(xiàng),重要的幾個(gè)是configUSE_QUEUE_SETS、configCPU_CLOCK_HZ、configTICK_RATE_HZ、configMAX_TASK_NAME_LEN、configUSE_16_BIT_TICKS,其他保持默認(rèn),configCPU_CLOCK_HZ要改成我們單片機(jī)的時(shí)鐘頻率,這里使用了代碼定義的量SystemCoreClock,configTICK_RATE_HZ時(shí)鐘節(jié)拍頻率設(shè)置為1000,也就是周期為1ms,任務(wù)名字字符串長度configMAX_TASK_NAME_LEN如果你創(chuàng)建任務(wù)時(shí)的命名很長,需要改一下,configUSE_16_BIT_TICKS使用的時(shí)鐘位數(shù),需要和單片機(jī)一致,STM32為32位,這里需要將這個(gè)宏定義為0。

/***************************************************************************************************************/
/*                                        FreeRTOS基礎(chǔ)配置配置選項(xiàng)                                               */
/***************************************************************************************************************/
#define configUSE_QUEUE_SETS          1                       //為1時(shí)啟用隊(duì)列
#define configCPU_CLOCK_HZ            (SystemCoreClock)       //CPU頻率
#define configTICK_RATE_HZ            (1000)                  //時(shí)鐘節(jié)拍頻率,這里設(shè)置為1000,周期就是1ms
#define configMAX_PRIORITIES          (32)                    //可使用的最大優(yōu)先級
#define configMINIMAL_STACK_SIZE        ((unsigned short)130)   //空閑任務(wù)使用的堆棧大小
#define configMAX_TASK_NAME_LEN          (20)                    //任務(wù)名字字符串長度

#define configUSE_16_BIT_TICKS          0                       //系統(tǒng)節(jié)拍計(jì)數(shù)器變量數(shù)據(jù)類型,
                                                                        //1表示為16位無符號整形,0表示為32位無符號整形
#define configIDLE_SHOULD_YIELD          1                       //為1時(shí)空閑任務(wù)放棄CPU使用權(quán)給其他同優(yōu)先級的用戶任務(wù)
#define configUSE_TASK_NOTIFICATIONS            1                       //為1時(shí)開啟任務(wù)通知功能,默認(rèn)開啟
#define configUSE_MUTEXES            1                       //為1時(shí)使用互斥信號量
#define configQUEUE_REGISTRY_SIZE        8                       //不為0時(shí)表示啟用隊(duì)列記錄,具體的值是可以
                                                                        //記錄的隊(duì)列和信號量最大數(shù)目。
#define configCHECK_FOR_STACK_OVERFLOW      0                       //大于0時(shí)啟用堆棧溢出檢測功能,如果使用此功能
                                                                        //用戶必須提供一個(gè)棧溢出鉤子函數(shù),如果使用的話
                                                                        //此值可以為1或者2,因?yàn)橛袃煞N棧溢出檢測方法。
#define configUSE_RECURSIVE_MUTEXES        1                       //為1時(shí)使用遞歸互斥信號量
#define configUSE_MALLOC_FAILED_HOOK      0                       //1使用內(nèi)存申請失敗鉤子函數(shù)
#define configUSE_APPLICATION_TASK_TAG      0                       //1為每個(gè)任務(wù)分配一個(gè)“標(biāo)簽”值,標(biāo)簽鉤子函數(shù)
#define configUSE_COUNTING_SEMAPHORES      1                       //為1時(shí)使用計(jì)數(shù)信號量

然后是與內(nèi)存申請有關(guān)配置選項(xiàng),一般保持默認(rèn)就行,系統(tǒng)總堆大小可能需要微調(diào)。

/***************************************************************************************************************/
#define configSUPPORT_DYNAMIC_ALLOCATION        1                       //支持動(dòng)態(tài)內(nèi)存申請
#define configTOTAL_HEAP_SIZE          ((size_t)(20*1024))     //系統(tǒng)所有總的堆大小

然后是與鉤子函數(shù)有關(guān)的配置選項(xiàng),我們不需要使用鉤子函數(shù),也不建議初學(xué)者用,因?yàn)榭臻e任務(wù)的鉤子函數(shù)需要寫的很高效率盡量不阻塞。

#define configUSE_IDLE_HOOK            0                       //1,使用空閑鉤子;0,不使用
#define configUSE_TICK_HOOK            0                       //1,使用時(shí)間片鉤子;0,不使用

與運(yùn)行時(shí)間和任務(wù)狀態(tài)收集有關(guān)的配置選項(xiàng) ,這部分主要與調(diào)試代碼有關(guān),測一下代碼運(yùn)行時(shí)間,觀察效率等。

/***************************************************************************************************************/
/*                                FreeRTOS與運(yùn)行時(shí)間和任務(wù)狀態(tài)收集有關(guān)的配置選項(xiàng)                                 */
/***************************************************************************************************************/
#define configGENERATE_RUN_TIME_STATS                  0                               //為1時(shí)啟用運(yùn)行時(shí)間統(tǒng)計(jì)功能
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()        ConfigureTimeForRunTimeStats()  //定時(shí)器3提供時(shí)間統(tǒng)計(jì)的時(shí)基,頻率為10K,即周期為100us
#define portGET_RUN_TIME_COUNTER_VALUE()            FreeRTOSRunTimeTicks          //獲取時(shí)間統(tǒng)計(jì)時(shí)間值

#define configUSE_TRACE_FACILITY                1                       //為1啟用可視化跟蹤調(diào)試
#define configUSE_STATS_FORMATTING_FUNCTIONS          1                       //與宏configUSE_TRACE_FACILITY同時(shí)為1時(shí)會(huì)編譯下面3個(gè)函數(shù)

與協(xié)程有關(guān)的配置選項(xiàng),保持默認(rèn),我們用不到協(xié)程。

/***************************************************************************************************************/
/*                                FreeRTOS與協(xié)程有關(guān)的配置選項(xiàng)                                                  */
/***************************************************************************************************************/
#define configUSE_CO_ROUTINES               0                       //為1時(shí)啟用協(xié)程,啟用協(xié)程以后必須添加文件croutine.c
#define configMAX_CO_ROUTINE_PRIORITIES         ( 2 )                   //協(xié)程的有效優(yōu)先級數(shù)目

與軟件定時(shí)器有關(guān)的配置選項(xiàng),F(xiàn)reeRTOS自帶軟件定時(shí)器,但是我們一般也用不到,STM32中有硬件定時(shí)器-滴答定時(shí)器,用這個(gè)就行。

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

FreeRTOS可選函數(shù)配置選項(xiàng),這些以INCLUDE_開頭的宏定義,主要是一些函數(shù)的開關(guān),比如第一個(gè)INCLUDE_xTaskGetSchedulerState,設(shè)置為1意味著,使用TaskGetSchedulerState這個(gè)函數(shù)。

/***************************************************************************************************************/
/*                                FreeRTOS可選函數(shù)配置選項(xiàng)                                                      */
/***************************************************************************************************************/
#define INCLUDE_xTaskGetSchedulerState          1           //獲取任務(wù)調(diào)度狀態(tài)           
#define INCLUDE_vTaskPrioritySet            1      //任務(wù)優(yōu)先級設(shè)置
#define INCLUDE_uxTaskPriorityGet            1      //獲取任務(wù)優(yōu)先級
#define INCLUDE_vTaskDelete                1      //刪除任務(wù)
#define INCLUDE_vTaskCleanUpResources          1      //清理任務(wù)占用資源
#define INCLUDE_vTaskSuspend              1      //暫停任務(wù)
#define INCLUDE_vTaskDelayUntil              1      //掛起任務(wù),固定時(shí)間周期
#define INCLUDE_vTaskDelay                1      //掛起任務(wù),延時(shí)一段時(shí)間
#define INCLUDE_eTaskGetState              1      //獲取任務(wù)狀態(tài)
#define INCLUDE_xTimerPendFunctionCall          1      //暫停狀態(tài)喚起

FreeRTOS與中斷有關(guān)的配置選項(xiàng),用不著,也不用深究。

/***************************************************************************************************************/
/*                                FreeRTOS與中斷有關(guān)的配置選項(xiàng)                                                  */
/***************************************************************************************************************/
#ifdef __NVIC_PRIO_BITS
  #define configPRIO_BITS           __NVIC_PRIO_BITS
#else
  #define configPRIO_BITS           4                  
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY      15                      //中斷最低優(yōu)先級
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY  5                       //系統(tǒng)可管理的最高中斷優(yōu)先級
#define configKERNEL_INTERRUPT_PRIORITY     ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY < < (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY   ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY < < (8 - configPRIO_BITS) )

最后是與中斷服務(wù)函數(shù)有關(guān)的配置選項(xiàng),只不過做了兩個(gè)重命名。

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

2

使用隊(duì)列進(jìn)行任務(wù)間的同步與互斥

原來的程序是STM32裸機(jī)開發(fā),程序是順序執(zhí)行,可能使用中斷,對于電池電量收集、IMU數(shù)據(jù)采集、超聲波檢測等功能都是順序執(zhí)行,采用頻率控制各個(gè)“進(jìn)程”,即在while循環(huán)中使用函數(shù)獲取程序當(dāng)前時(shí)間,減去上一時(shí)刻時(shí)間,當(dāng)差值大于某一值時(shí),運(yùn)行相應(yīng)函數(shù),如下圖所示。

圖片

而在改進(jìn)后的程序中,采用實(shí)時(shí)系統(tǒng),使用多線程的方式管理這些功能,為每個(gè)功能創(chuàng)建一個(gè)任務(wù)(線程),根據(jù)任務(wù)調(diào)度機(jī)制運(yùn)行,如下圖所示。

圖片

并為各個(gè)任務(wù)設(shè)置優(yōu)先級,move_base是最基本的移動(dòng)任務(wù)優(yōu)先級最高。

圖片

各個(gè)任務(wù)之間通過隊(duì)列進(jìn)行溝通,不然move_base任務(wù)的優(yōu)先級最高,則會(huì)一直執(zhí)行,其他任務(wù)得不到執(zhí)行時(shí)間。

圖片

在move_base任務(wù)中以電池電量采集任務(wù)的執(zhí)行為例:

圖片

代碼邏輯:當(dāng)執(zhí)行到這部分代碼時(shí),判斷電池隊(duì)列的句柄是否為NULL(之前創(chuàng)建了,所以不為空),然后使用xQueueReceive函數(shù)進(jìn)行隊(duì)列數(shù)據(jù)采集,從Battery_Queue隊(duì)列中將數(shù)據(jù)采集到Receive_vattery_volt變量中,剛開始采集時(shí),隊(duì)列中肯定是沒數(shù)據(jù)的,這是就會(huì)進(jìn)入隊(duì)列阻塞,阻塞時(shí)間為portMAX_DELAY直到隊(duì)列中有數(shù)據(jù),這時(shí)move_base任務(wù)則會(huì)掛起,低優(yōu)先級的任務(wù)會(huì)執(zhí)行,當(dāng)執(zhí)行到電池電量采集任務(wù)時(shí),向隊(duì)列中放入了數(shù)據(jù),move_base任務(wù)則會(huì)搶占,繼續(xù)執(zhí)行,然后將采集到的數(shù)據(jù)發(fā)給上位機(jī)

其他任務(wù)都是這個(gè)邏輯,使用這種方法的好處就是提高了我們程序的效率,使得STM32程序多線程執(zhí)行,并且提供了很多接口,方便用戶修改和閱讀。

3

總結(jié)

FreeRTOS在STM32F103上的移植完結(jié),整理來說FreeRTOS還是挺簡單的,不過很多知識(shí)沒用到我也就沒仔細(xì)學(xué),任務(wù)之間的同步互斥與溝通有很多方式,除了隊(duì)列還有信號量、互斥量等等,我只是選擇了最常用的一種。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 定時(shí)器
    +關(guān)注

    關(guān)注

    23

    文章

    3255

    瀏覽量

    115362
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    484

    瀏覽量

    62393
  • 上位機(jī)
    +關(guān)注

    關(guān)注

    27

    文章

    945

    瀏覽量

    55002
  • STM32F103
    +關(guān)注

    關(guān)注

    33

    文章

    479

    瀏覽量

    63872
  • 定時(shí)中斷
    +關(guān)注

    關(guān)注

    0

    文章

    19

    瀏覽量

    8607
收藏 人收藏

    評論

    相關(guān)推薦

    FreeRTOS移植STM32F103中的步驟

    目錄一、FreeRTOS的介紹二、將FreeRTOS移植STM32F103中的步驟1.前期準(zhǔn)備2.在MDK下移植
    發(fā)表于 08-24 07:26

    如何去完成STM32F103FreeRTOS操作系統(tǒng)移植

    如何去完成STM32F103FreeRTOS操作系統(tǒng)移植呢?有哪些操作步驟?
    發(fā)表于 11-26 06:40

    基于STM32F103FreeRTOS移植其代碼該如何去實(shí)現(xiàn)呢

    怎樣去移植基于STM32F103FreeRTOS系統(tǒng)呢?基于STM32F103FreeRTOS
    發(fā)表于 12-14 06:58

    基于STM32F103的振動(dòng)監(jiān)測系統(tǒng)設(shè)計(jì)

    基于STM32F103的振動(dòng)監(jiān)測系統(tǒng)設(shè)計(jì)。
    發(fā)表于 11-09 17:49 ?43次下載

    STM32F103芯片F(xiàn)FT程序

    STM32F103芯片使用DSP庫進(jìn)行FFT運(yùn)算的資料與程序
    發(fā)表于 06-07 16:30 ?109次下載

    STM32F103的振動(dòng)監(jiān)測系統(tǒng)設(shè)計(jì)

    STM32F103的振動(dòng)監(jiān)測系統(tǒng)設(shè)計(jì)
    發(fā)表于 09-28 14:45 ?49次下載
    <b class='flag-5'>STM32F103</b>的振動(dòng)監(jiān)測<b class='flag-5'>系統(tǒng)</b>設(shè)計(jì)

    盤古STM32F103開發(fā)板移植uCGUI教程

    盤古STM32F103開發(fā)板移植uCGUI教程
    發(fā)表于 09-29 09:21 ?21次下載
    盤古<b class='flag-5'>STM32F103</b>開發(fā)板<b class='flag-5'>移植</b>uCGUI教程

    stm32f103移植

    stm32f103移植
    發(fā)表于 10-27 09:03 ?43次下載
    <b class='flag-5'>stm32f103</b><b class='flag-5'>移植</b>

    STM32F103 CAN模板程序

    STM32F103 CAN模板程序
    發(fā)表于 11-09 11:08 ?84次下載
    <b class='flag-5'>STM32F103</b> CAN模板<b class='flag-5'>程序</b>

    基于STM32f103的FFT頻率測試程序下載

    基于STM32f103的FFT頻率測試程序下載
    發(fā)表于 08-02 10:07 ?168次下載

    TencentOS tiny 移植STM32F103全教程(基于標(biāo)準(zhǔn)庫)

    TencentOS tiny 移植STM32F103全教程(基于標(biāo)準(zhǔn)庫)
    發(fā)表于 11-23 18:06 ?16次下載
    TencentOS tiny <b class='flag-5'>移植</b>到<b class='flag-5'>STM32F103</b>全教程(基于標(biāo)準(zhǔn)庫)

    在GD32F103移植STM32F103代碼

    在GD32F103移植STM32F103代碼使用相同F(xiàn)LASH和管腳數(shù)量相同的芯片,例如GDF103C8T6移植
    發(fā)表于 12-02 15:21 ?23次下載
    在GD32<b class='flag-5'>F103</b><b class='flag-5'>移植</b><b class='flag-5'>STM32F103</b>代碼

    華為LiteOS系統(tǒng)移植STM32F103開發(fā)板(基于MDK環(huán)境)

    華為LiteOS系統(tǒng)移植STM32F103開發(fā)板(基于MDK環(huán)境)
    發(fā)表于 12-08 14:21 ?48次下載
    華為LiteOS<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>移植</b>到<b class='flag-5'>STM32F103</b>開發(fā)板(基于MDK環(huán)境)

    RT-Thread系統(tǒng)移植STM32f103

    RT-Thread系統(tǒng)移植STM32f103
    發(fā)表于 12-09 12:51 ?26次下載
    RT-Thread<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>移植</b>到<b class='flag-5'>STM32f103</b>

    FreeRTOS移植STM32F103步驟與注意事項(xiàng)

    FreeRTOS的研究并在公司產(chǎn)品中應(yīng)用,多少有些心得,接下來就由小燈以最新版的FreeRTOS為例一步一步移植STM32F103上,并提醒大家某些需要注意的事項(xiàng)。本文檔為非正式技
    發(fā)表于 12-27 18:39 ?7次下載
    <b class='flag-5'>FreeRTOS</b><b class='flag-5'>移植</b>到<b class='flag-5'>STM32F103</b>步驟與注意事項(xiàng)
    百合百家乐官网的玩法技巧和规则 | 去澳门百家乐官网娱乐城| 百家乐有没有破解之法| 网上百家乐官网赌法| 大发888下载安全的| 折式百家乐赌台| 桃源县| 海燕百家乐论| 波音百家乐官网现金网投注平台排名导航 | 易胜博百家乐官网作弊| 大发888资讯网| 巴西百家乐官网的玩法技巧和规则| 优博开户| 百家乐娱乐网真人娱乐网| 百家乐官网技术方式| 加多宝百家乐的玩法技巧和规则 | 明珠国际| 赌场百家乐的玩法技巧和规则| 申博百家乐官网有假吗| 龙虎斗游戏| 百家乐最新分析仪| 风水24龙| 百家乐官网最佳投注办法| 澳门博彩网站| 百家乐的奥秘| 新世纪百家乐官网的玩法技巧和规则| 阳曲县| 大发888娱乐场下载co| 百家乐网上投注作弊| 百家乐怎样玩的| 真人百家乐官网赌城| 安福县| 大发8881| 波音百家乐游戏| 百家乐官网赢家打法| 阿克| 大发888 3403| 游戏机百家乐庄闲| 福布斯百家乐官网的玩法技巧和规则| 博马百家乐官网娱乐城| 太阳城娱乐城去大丰收娱乐|