前言
本文基于野火 FreeRTOS 教程,內(nèi)容是關(guān)于 FreeRTOS 官方代碼的移植的注意事項(xiàng),并將野火例程中 STM32F103RC 代碼移植到 STM32F103C8。
一、FreeRTOS V9.0.0 源碼的獲取
- 兩個(gè)下載鏈接:
官 網(wǎng)
代碼托管
二、源碼文件夾內(nèi)容簡介
- Source:內(nèi)核源碼,我們需要的主要內(nèi)容
- 根目錄:這里的 C 文件都是由 C 語言編寫的,所以在各種單片機(jī)上是通用的
- include:上述 C 文件的頭文件
- portable:存放不同編譯器和不同板子使用的接口文件(大部分使用匯編編寫,為了適配不同的板子)
- KEIL:存放 port.c 接口文件,portmacro.h 是其頭文件
- MemMang:存放內(nèi)存管理相關(guān)文件,主要是動(dòng)態(tài)內(nèi)存(堆)的配置,我們使用第四個(gè)
- Demo:一些官方的例程(FreeRTOS 不只可以用在 STM32 上,其他單片機(jī)上也可以使用,這些例程中有專門為 STM32F1系列寫的配置,也需要移植)
所謂移植,本意是將代碼適配我們需要使用的單片機(jī),也就是軟件得和硬件相匹配的過程。
但是在這里,和硬件相匹配的接口文件 port.c 已經(jīng)由官方寫好了,我們需要的只是將這些文件放入我們的 keil 工程中,實(shí)際上是使用官方的移植的過程。
詳細(xì)的工程添加文件過程,請(qǐng)查看野火的教程。
三、FreeRTOSConfig.h 文件內(nèi)容部分說明
在 FreeRTOSConfig.h
中,有如下這些代碼:
/******************************************************************
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) )
首先我們先捋清楚一個(gè)概念, FreeRTOS 是在 STM32 原有的架構(gòu)上實(shí)現(xiàn)的,也就是說,我們?cè)诳紤] FreeRTOS 的各種細(xì)節(jié)的時(shí)候不能忘記 STM32 裸機(jī)的各種細(xì)節(jié)。比如裸機(jī)上的優(yōu)先級(jí)分配等等。
-
configLIBRARY_LOWEST_INTERRUPT_PRIORITY:用于配置 STM32 的中斷最低優(yōu)先級(jí),這里配置為 15,也就是總共有 0 - 15 共 16 個(gè)優(yōu)先級(jí)。
注意,這里說的 STM32 的中斷優(yōu)先級(jí)和 FreeRTOS 的中斷優(yōu)先級(jí)不同,注意區(qū)分。
STM32 的中斷優(yōu)先級(jí):Cortex 內(nèi)核的各種優(yōu)先級(jí),越小優(yōu)先級(jí)越高
FreeRTOS 的中斷優(yōu)先級(jí):在 STM32 的中斷優(yōu)先級(jí)上實(shí)現(xiàn)的任務(wù)優(yōu)先級(jí),越大優(yōu)先級(jí)越高 -
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY:用于配置 FreeRTOS 可以管理的最高的中斷優(yōu)先級(jí)。這里配置為 5,結(jié)合上面 STM32 的中斷優(yōu)先級(jí)配置共 15 級(jí),那么意味著 FreeRTOS 可以管理的 STM32 的中斷優(yōu)先級(jí)為 5 - 15,而0 - 4 FreeRTOS 就管不了。
Q:那為什么 FreeRTOS 要對(duì) STM32 的優(yōu)先級(jí)進(jìn)行管理呢?
A:很重要的一點(diǎn)是前幾篇文章提到過的臨界段的保護(hù)。
還記得嗎,由于 FreeRTOS 的并發(fā)性,F(xiàn)reeRTOS 需要確保執(zhí)行一些代碼的時(shí)候不能被中斷打斷,很常見的就是對(duì)共享資源的訪問,比如全局變量的修改。在訪問共享資源前我們需要先屏蔽中斷,修改完畢后再開啟,這就是臨界端的保護(hù),也就是 FreeRTOS 要對(duì) STM32 的中斷進(jìn)行管理的原因。
這里貼上臨界段保護(hù)的文章:臨界段保護(hù)
四、移植到 STM32F103C8
由于野火的例程中并沒有 STM32F1C8T6 這個(gè)芯片,所以我們只能自己移植。
STM32 不同的芯片的命名表示如下:
我們使用 STM32F1RC 這個(gè)芯片進(jìn)行移植??梢钥吹?C 表示 256K 字節(jié)的閃存,而 C8T6 只有 64K 字節(jié)。移植主要是根據(jù)不同的閃存容量進(jìn)行配置的。
根據(jù)不同容量,有 ld、md、hd 三種縮寫:
我們需要把 RC 中所有的 hd 都修改為 md進(jìn)行移植。
移植分為基礎(chǔ)的編譯器移植設(shè)置和針對(duì) FreeRTOS 的代碼修改兩個(gè)步驟:
1. 基礎(chǔ)設(shè)置
① 編譯器的設(shè)置
-
點(diǎn)擊工程配置選項(xiàng)
-
修改芯片,選擇 STM32F1C8
-
晶振頻率的修改
-
定義從 STM32F10X_HD 修改為 STM32F10X_MD
② 啟動(dòng)文件的修改
這個(gè)啟動(dòng)文件就是在執(zhí)行 main 函數(shù)之前執(zhí)行的一個(gè)文件。
需要從 startup_stm32f10x_hd.s
換為 startup_stm32f10x_md.s
- 從組中移除 hd 啟動(dòng)文件:
- 添加 md 啟動(dòng)文件(一般在項(xiàng)目目錄下就有)(…\Libraries\CMSIS\startup):
- 如果項(xiàng)目工程下沒有,可以打開 KEIL 的安裝目錄,在
C:\Keil\ARM\PACK\Keil\STM32F1xx_DFP\2.2.0\Device\Source\ARM
這個(gè)路徑下找
至此,基礎(chǔ)設(shè)置已經(jīng)全部設(shè)置好了,但是如果我們此刻進(jìn)行編譯,可能會(huì)出現(xiàn)空間不足的錯(cuò)誤。如下:
..\..\Output\Fire_FreeRTOS.axf: Error: L6406E: No space in execution regions with .ANY selector matching heap_4.o(.bss).
..\..\Output\Fire_FreeRTOS.axf: Error: L6406E: No space in execution regions with .ANY selector matching startup_stm32f10x_md.o(STACK).
..\..\Output\Fire_FreeRTOS.axf: Error: L6406E: No space in execution regions with .ANY selector matching tasks.o(.bss).
..\..\Output\Fire_FreeRTOS.axf: Error: L6406E: No space in execution regions with .ANY selector matching tasks.o(.data).
..\..\Output\Fire_FreeRTOS.axf: Error: L6406E: No space in execution regions with .ANY selector matching heap_4.o(.data).
..\..\Output\Fire_FreeRTOS.axf: Error: L6406E: No space in execution regions with .ANY selector matching system_stm32f10x.o(.data).
..\..\Output\Fire_FreeRTOS.axf: Error: L6406E: No space in execution regions with .ANY selector matching stm32f10x_rcc.o(.data).
..\..\Output\Fire_FreeRTOS.axf: Error: L6406E: No space in execution regions with .ANY selector matching port.o(.data).
..\..\Output\Fire_FreeRTOS.axf: Error: L6406E: No space in execution regions with .ANY selector matching stdout.o(.data).
..\..\Output\Fire_FreeRTOS.axf: Error: L6407E: Sections of aggregate size 0x9770 bytes could not fit into .ANY selector(s).
Not enough information to list image symbols.
Not enough information to list load addresses in the image map.
Finished: 2 information, 0 warning and 10 error messages.
"..\..\Output\Fire_FreeRTOS.axf" - 10 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed: 00:00:02
這是由于 FreeRTOS 中對(duì)于容量的配置出錯(cuò),接著往下看。
2. FreeRTOS 的代碼修改
打開 FreeRTOSConfig.h
文件進(jìn)行配置,找到這個(gè)宏定義,它的作用是在 FreeRTOS 中定義系統(tǒng)可用的整個(gè)堆的大小,如果設(shè)置得太大了就會(huì)出現(xiàn)上文所說的空間不足的報(bào)錯(cuò)。
原來設(shè)置的大小是 ((size_t)(36*1024)) ,這里的 size_t 是 unsigned int,也就是 4 個(gè)字節(jié),在 STM32 中是 1 個(gè)字的大小。
#define configTOTAL_HEAP_SIZE ((size_t)(36*1024))
修改為 ((size_t)(10*1024)) 即可,也就是 10K 字的大小:
//系統(tǒng)所有總的堆大小
#define configTOTAL_HEAP_SIZE ((size_t)(10*1024))
這樣,我們所有的修改就完成了,嘗試編譯吧!文章來源:http://www.zghlxwxcb.cn/news/detail-670756.html
后記
如果您覺得本文寫得不錯(cuò),可以點(diǎn)個(gè)贊激勵(lì)一下作者!
如果您發(fā)現(xiàn)本文的問題,歡迎在評(píng)論區(qū)或者私信共同探討!
共勉!文章來源地址http://www.zghlxwxcb.cn/news/detail-670756.html
到了這里,關(guān)于【學(xué)習(xí)日記】【FreeRTOS】FreeRTOS 移植到 STM32F103C8的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!