1. 程式人生 > >freeRTOS V10.0.1移植到STM32F407標準庫 - 環境Keil5

freeRTOS V10.0.1移植到STM32F407標準庫 - 環境Keil5

org 其中 需要 eno port ask sig ESS tick

  最近因為工作需要用到FreeRTOS,其實開始本人內心是拒絕的因為自己只學習過UCOSIII還沒實際上過什麽大又復雜的工程,但是誰讓FreeRTOS他是Free的呢公司成本考慮肯定是不會選擇USOS的,這個道理就像公司內心深處不想給你漲工資一樣。好了跑偏了言歸正傳,既然要用自然是要熟悉一下這個實時操作的內核的工作過程了,說道到裏想起來自己當初學USOC時是把代碼幾乎進行了逐行的走讀,最後因為各種原因都沒能實際使用最後還是忘記了,所以我建議對於這一類的操作系統的學習還是重在API函數的用法學習上,不需要太對代碼集體實現細節進行研究,時間成本高有這個時間建議移植一個系統進行一些應用實踐是最有實際效果的。因此我現在就在踐行自己的經驗移植FreeRTOS到板子上學習,實際項目是用的STMF107系列的但是無奈手頭上暫時只有F407,其實都是一樣的,所以廢話不多說了開始移植實操。

查找資料

通過網上查閱各位大神牛人的博客最後選擇了如下兩個文檔:

1.FreeRTOS中文實用教程,這是英文原文下載地址http://www.FreeRTOS.org

2,STM32F429+FreeRTOS開發手冊,這是原子哥的開源電子網上都可以下來,最後再補充一下FreeRTOS源碼的下載地址https://jaist.dl.sourceforge.net/project/freertos/FreeRTOS/V10.0.1/FreeRTOSv10.0.1.exe

開始行動

1.找一個標準庫的實例這裏我也用的是原子哥的F407的標準工程,然後解壓後的文件我們只用留下Source\portable如下的代碼因為我移植的工程是keil5的所以留下keil,但是這個文件夾其實沒什麽用(對於我下載到的版本)。其中RVDS文件夾下也只留下的目標板相關的ARM_CM4F 因為FreeRTOS這個版本已經支持F4的FPU

技術分享圖片

到此源碼處理完畢了接下來就是將源碼加入到標準工程中去,註意將SYSTEM下的delay.c從工程刪除。然後編譯出現如下錯誤

技術分享圖片

此時就要用到FreeRTOS的一些demo程序找到官方對於407的移植工程FreeRTOSv10.0.1\FreeRTOS\Demo\CORTEX_M4F_STM32F407ZG-SK下的FreeRTOSConfig.h拷貝到工程中。在編譯又將看到如下錯誤

技術分享圖片

打開FreeRTOSConfig.h可以看到這樣一段代碼

#ifdef __ICCARM__
    #include <stdint.h>
    extern uint32_t SystemCoreClock;
#endif

現在需要將其改成如下部分就可以去除這個錯誤

#if defined (__ICCARM__)||defined(__CC_ARM)||defined(__GNUC__)
    #include <stdint.h>
    extern uint32_t SystemCoreClock;
#endif

然後再編譯就會發現新的錯誤:

Build target ‘Template‘
compiling main.c...
compiling croutine.c...
compiling event_groups.c...
compiling list.c...
compiling queue.c...
compiling stream_buffer.c...
compiling tasks.c...
compiling timers.c...
compiling port.c...
linking...
..\OBJ\Template.axf: Error: L6200E: Symbol SVC_Handler multiply defined (by port.o and stm32f4xx_it.o).
..\OBJ\Template.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by port.o and stm32f4xx_it.o).
..\OBJ\Template.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by port.o and stm32f4xx_it.o).
Not enough information to list image symbols.
Not enough information to list the image map.
Finished: 2 information, 0 warning and 3 error messages.
"..\OBJ\Template.axf" - 3 Error(s), 0 Warning(s).
Target not created

  提示三個函數有重復定義,其中SysTick_Handler再FreeRTOS中被重新定義成系統心跳處理中斷函數,PendSV_Handler,SVC_Handler也被在FreeRTOS中重新定義用於任務切換,所以需要註釋掉stm32F4xxx_it.c中的這三個中斷函數。接著編譯錯誤如下

linking...
..\OBJ\Template.axf: Error: L6218E: Undefined symbol pvPortMalloc (referred from event_groups.o).
..\OBJ\Template.axf: Error: L6218E: Undefined symbol vPortFree (referred from event_groups.o).
..\OBJ\Template.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o).
..\OBJ\Template.axf: Error: L6218E: Undefined symbol vApplicationStackOverflowHook (referred from tasks.o).
..\OBJ\Template.axf: Error: L6218E: Undefined symbol vApplicationTickHook (referred from tasks.o).
Not enough information to list image symbols.
Finished: 1 information, 0 warning and 5 error messages.
"..\OBJ\Template.axf" - 5 Error(s), 0 Warning(s).
Target not created

  其中是先關HOOK鉤子函數未定義錯,在FreeRTOSConfig.h中改為如下

#define configUSE_PREEMPTION                        1//調度器采用搶占式還是協程式
#define configUSE_IDLE_HOOK                            0//空閑任務鉤子函數
#define configUSE_TICK_HOOK                            0//時間片鉤子函數
#define configCPU_CLOCK_HZ                            ( SystemCoreClock )
#define configTICK_RATE_HZ                            ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES                        ( 5 )//最大任務優先級
#define configMINIMAL_STACK_SIZE                ( ( unsigned short ) 130 )
#define configTOTAL_HEAP_SIZE                        ( ( size_t ) ( 75 * 1024 ) )
#define configMAX_TASK_NAME_LEN                    ( 10 )//任務名最長
#define configUSE_TRACE_FACILITY                1
#define configUSE_16_BIT_TICKS                    0//系統節拍計數器
#define configIDLE_SHOULD_YIELD                    1//空閑任務是否會為同等優先級的任務讓出CPU使用權
#define configUSE_MUTEXES                                1
#define configQUEUE_REGISTRY_SIZE                8
#define configCHECK_FOR_STACK_OVERFLOW    0//堆棧溢出檢測
#define configUSE_RECURSIVE_MUTEXES            1//遞歸互斥信號量
#define configUSE_MALLOC_FAILED_HOOK        0//內存分配失敗鉤子函數
#define configUSE_APPLICATION_TASK_TAG    0
#define configUSE_COUNTING_SEMAPHORES        1
#define configGENERATE_RUN_TIME_STATS        0//運行時間統計功能

在運行編譯錯誤如下

linking...
..\OBJ\Template.axf: Error: L6218E: Undefined symbol pvPortMalloc (referred from event_groups.o).
..\OBJ\Template.axf: Error: L6218E: Undefined symbol vPortFree (referred from event_groups.o).
Not enough information to list image symbols.
Finished: 1 information, 0 warning and 2 error messages.
"..\OBJ\Template.axf" - 2 Error(s), 0 Warning(s).
Target not created

  這一部分是我前面忘記加入內存管理函數文件導致的,在\FreeRTOSv10.0.1\FreeRTOS\Source\portable\MemMang目錄下一共有5個內存管理的點C文件

技術分享圖片

在這裏我們選擇4結尾的管理方式,其中具體各個文件的管理方法是什麽暫時不求甚解。將heap_4.c加入到工程。編譯

Build target ‘Template‘
compiling heap_4.c...
linking...
Program Size: Code=19344 RO-data=424 RW-data=160 ZI-data=78936  
FromELF: creating hex file...
"..\OBJ\Template.axf" - 0 Error(s), 0 Warning(s).

  至此移植完成。具體配置後面再進行學習。https://github.com/Dazzingdusk/freeRTOS這裏有我自己移植成功後,自己寫的一消息對列的代碼,其中驅動部分使用的是原子哥的例子中的代碼。

freeRTOS V10.0.1移植到STM32F407標準庫 - 環境Keil5