欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4869|回復: 0
收起左側

FreeRTOS移植到STM32F103步驟與注意事項

[復制鏈接]
ID:280543 發表于 2018-1-29 01:49 | 顯示全部樓層 |閱讀模式
前言:
由于之前聽過太多人抱怨移植FreeRTOS到STM32有各種各樣的問題,小燈經過一年多對FreeRTOS的研究并在公司產品中應用,多少有些心得,接下來就由小燈以最新版的FreeRTOS為例一步一步移植到STM32F103上,并提醒大家某些需要注意的事項。本文檔為非正式技術文檔,故排版會有些凌亂,希望大家能提供寶貴意見以供小燈參考改進。
下面先以IAR移植為例,說明移植過程中的諸多注意事項,最后再以MDK移植時不再重復說明,所以還是建議大家先花些時間看IAR的移植過程,哪怕你不使用IAR,最好也注意下那一大堆注意事項!


一、從官網下載最新版的FreeRTOS源碼
下面的網址是官方最新源碼的下載地址:
https://sourceforge.net/projects/freertos/files/latest/download?source=files
目前官方提供的最新版本是v9.0.0, FreeRTOS源碼在解壓目錄下的路徑為
FreeRTOS_V9.0.0rc2FreeRTOSSource


FreeRTOS組織為了搶用戶也是拼了命的,不信你打開Demo文件夾看看,里面提供了FreeRTOS在各種單片機上已經移植好的工程,如果建工程時遇到什么問題,可以參考下這些Demo。
不過小燈現在著重于自己動手移植FreeRTOS,考慮到原子哥@正點原子的用戶比較多,絕大多數習慣了使用MDK來開發STM32,因此小燈分別以IAR和MDK兩種使用比較廣泛的開發環境來移植FreeRTOS。說到IAR和MDK,不得不提的是小燈自從用了IAR之后就果斷放棄了MDK,相信很多人有這個經歷,哈哈!

在開始移植FreeRTOS之前,先介紹下FreeRTOS的源碼:
132304mo601ofz6uq0yvq6.png
FreeRTOS的源碼比較少,源文件也遠沒有UCOS多,不過麻雀雖小五臟俱全,FreeRTOS的短小精悍也是最令小燈著迷的,雖然缺少了很多組成部分,例如GUI、網絡協議棧、文件系統等,不過這些統統都不是問題,因為完全可以移植第三方的組件!
一不小心牛逼又吹大了,哈哈!回歸正題,FreeRTOS的源碼核心部分是tasks.c和list.c,其余的幾個文件功能都是可選的,例如軟件定時器、隊列、協程等等,小燈就不介紹了,有興趣的話可以到官網上看介紹。include文件夾里面的文件是操作系統相關的頭文件,而portable這個文件夾有些奇葩,先看看里面有啥:
132304februi5bl5uei6ui.png
這里的文件幾乎都是與平臺相關的,如果你要刪掉這里的文件時就必須小心了,因為不是所有文件都能刪除的。
注意文件夾MemMang,里面存放的是FreeRTOS自帶的內存管理方案的源文件:
132304psxzxfaz54lurmxs.png
關于內存管理方案的選擇,小燈以后再跟大家討論,現在只需要知道這些文件不能刪就好。

接下來看看IAR文件夾的內容,里面都是跟單片機底層相關的,由于我們以STM32F103為例,因此只需要保留ARM_CM3文件夾即可,其余可選擇性刪除。ARM_CM3文件夾里只有幾個文件,這幾個文件是操作系統最最底層的部分:
132304okjvkknmat66rmtt.png

接下來再看看Keil文件夾的內容,里面只有一個文件,文件提示See-also-the-RVDS-directory,意思是讓我們參照RVDS目錄下的文件。其實我們以MDK建工程時,就是拿RVDS目錄下的文件來替代的,因此我們應該把RVDS目錄下的文件拷貝到Keil目錄下,跟上面IAR文件夾一樣我們只拷貝ARM_CM3文件夾即可:
132305rshju8hj1sutb41i.png

到這里我們可以把其他無用的文件統統刪掉了,portable目錄下只保留下面幾個文件夾的文件即可:
132305e9g7csb9jvj9c4c3.png
現在已經把源碼整理好了,接下來就開始移植工作吧!


二、IAR下移植FreeRTOS
事先說明下,小燈使用的IAR版本是
132305n17wiyfjbbgzxyey.png
關于IAR下如何創建STM32基礎工程,小燈就偷下懶不介紹了,這入門級的知識還是交給賣開發板的人來傳播吧,小燈就以自己平常用的簡單工程為例:
132305sjqp0fyqmjpuyzjj.png
工程當中只有一個LED.c是小燈額外添加的,小燈一直停留在跑燈的水平,習慣用LED來觀察現象,希望各位大神莫怪。工程源碼結構如下:
132305ygvw0uwzvuulttha.png
其中FreeRTOS文件夾下就是FreeRTOS的源碼:
132644y2mt0q5s1qamoomx.png

接下來在工程里面添加FreeRTOS文件:
132306fattapx5iri00pa0.png
文件清單如下:
FreeRTOS        asks.c
FreeRTOSlist.c
FreeRTOSportableIARARM_CM3port.c
FreeRTOSportableIARARM_CM3portasm.s
FreeRTOSportableMemMangheap_4.c

這時有人可要問為何沒有把FreeRTOS的所有文件都添加進去,原因我上面提過了,FreeRTOS的核心部分是tasks.c和list.c,其余的幾個文件是可選部分,在此小燈就先不添加這些可選部分以簡化我們的工程。小燈建議大家使用內存管理的方案四heap_4.c,因為該方案具有內存塊碎片合并功能,比heap_2.c的最優內存塊分配方案要穩定很多,這是小燈經過很長時間測試對比出來的,公司的產品也是一直使用heap_4.c,穩定性無懈可擊!

接下來非常重要的一步就是添加頭文件路徑:
132306wn2nv7s0a4ndk72u.png
頭文件路徑如下:
$PROJ_DIR$..SourceFreeRTOSinclude
$PROJ_DIR$..SourceFreeRTOSportableIARARM_CM3

好了這時我們可以嘗試編譯下整個工程了,編譯結果提示缺少了個頭文件:
132306mojbo7fy5mbg56yy.png
FreeRTOS組織也真是奇葩,居然連這么重要的文件都不提供在源碼里面!!!前面提醒過大家,新建工程時碰到問題一定要參考官方提供的Demo,既然Demo是一堆成品的工程,那么里面絕對有我們所需的這個FreeRTOSConfig.h
我們就選擇打開DemoCORTEX_STM32F103_IAR下的這個工程吧,果不其然里面真的有我們需要的這個頭文件:
132306te2iunni9rh2rr2i.png

把這文件放哪里好呢,這是一直糾結小燈的問題,官方直接把這文件放在工程目錄下,但這么重要的配置文件這么隨便放似乎不太好吧。在小燈看來,這個文件的重要性和打開的概率絕不比FreeRTOS內核文件低,所以還是把它放在源碼里面比較合理:
132307y0s3qi3tk0qqxt7q.png
在C/C++ Compiler下添加頭文件路徑
$PROJ_DIR$..SourceFreeRTOS

還有一個地方一定要十分注意,因為操作系統的最最底層的幾個文件也需要用到FreeRTOSConfig.h頭文件,而底層文件是用匯編來寫的,因此必須在Assembler下添加FreeRTOSConfig.h頭文件路徑:
132307go1zao47jfokngo7.png

好了再編譯一次:
132307r8ne6vr82f4hhtn4.png
0個錯誤0個警告,程序員最歡喜的莫過于看見這個結果了,哈哈!

在編寫系統任務前,有必要對配置文件FreeRTOSConfig.h進行檢查。FreeRTOSConfig.h里面幾乎都是一些宏定義,關于這些宏定義的具體用法,可以在官網上查閱:http://www.freertos.org/a00110.html
小燈只以其中幾個比較重要的參數作特別說明,下面以小燈修改過的FreeRTOSConfig.h為例作為說明:
132307mzssssu0beu0su0y.png
(1)定義系統底層相關的函數
132308owhs5ypcjyfd6ks8.png
其中SVC中斷時操作系統啟動時進入的中斷,而PendSV中斷手動切換任務時進入的中斷,SysTick中斷不用我多說了,@正點原子的基礎例程幾乎都使用這個定時器定時,在這里SysTick是作為操作系統的心臟。由于FreeRTOS對這幾個中斷的名稱做了自己的定義,因此必須要重定義這幾個函數才能正常進入中斷,但這么做又會跟ST提供的stm32f10x_it.c文件當中定義的中斷相沖突,因此必須將stm32f10x_it.c下對應的幾個中斷服務函數屏蔽掉,否則編譯會提示函數重定義:
132308bjjz6vsgy77kj1sj.png
(2)修改系統可屏蔽的中斷優先級閾值
FreeRTOS提供的可屏蔽中斷優先級閾值是191,對應的十六進制數是0xBF:
#define configMAX_SYSCALL_INTERRUPT_PRIORITY         191
由于STM32F103的優先級分組只有4個位,而CM3的優先級是以MSB對齊的,也就是說STM32F103的優先級寄存器只有最高4位有效,低四位是無效的。當操作系統進入臨界區時,會把上面的可屏蔽中斷優先級閾值寫入BASEPRI寄存器以屏蔽部分中斷:
132308vhe41gu087bexbud.png
因此當進入臨界區時,優先級對應0xB~0xF的中斷均被屏蔽,而優先級處于0xB前面的中斷不受影響。這個跟CM0有區別,也是最值得注意的地方。
上述的基礎知識不是小燈要重點提的,對CM3的優先級不熟悉的朋友建議查閱《Cortex-M3權威指南》,接下來才是小燈要重點提的。由于使用@正點原子的開發板的用戶比較多,很多人直接把FreeRTOS移植到原子哥的工程下,然后出現了各種各樣的詭異問題,一直無解。其中一個非常嚴重的問題就是小燈上面提及到的中斷屏蔽的問題,下面小燈就這個問題進行一個簡單的分析,先貼上@正點原子的部分代碼:
133238gvmt44h4mvptth07.png
這是原子哥最常用的中斷優先級分組方式,采用分組方式2,2位搶占優先級2位亞優先級。但是在移植FreeRTOS時必須要修改成優先級分組方式4:
133238rbnw6mzrmbxw5pgr.png
把STM32的優先級分組的4個位均設成搶占優先級,也就是說完全放棄亞優先級。為何要這么設置?其實這得怪FreeRTOS機構里面被驢踢過的逗逼,這些逗逼為了自己省事,直接默認不使用亞優先級,下面讓大家見識下這群逗逼的解釋:
133238x22uyuez729pygg7.png
不過站在他們的角度來思考,其實我們也應該給他們那么一丁點兒理解,畢竟他們采取了一個比較簡單的方法來獲取不同廠商的單片機的有效優先級位數,算法是通過對優先級寄存器組的某一個寄存器寫入0xFF,然后再讀出來看實際上有多少位寫入成功,然后根據實際的有效位數來重設優先級分組寄存器的分組方式(上面提到的分組方式4)。有興趣的可以研究下他們的算法,代碼截圖在下面:
133239obrgzbppgrbbor6m.png

不知不覺越扯越遠了,回歸正題,到底為何要重設可屏蔽的中斷優先級閾值,我們重新把思路理一下。根據STM32的中斷優先級的設計,只有高4位有效,還有FreeRTOS默認將4個優先級位均劃分為搶占優先級。由于FreeRTOS官方提供的中斷優先級閾值是191(對應實際的0xB),也就是11~15的優先級均可被操作系統屏蔽。但我們實際使用時設置的中斷優先級一般不會使用到11打后的,例如@正點原子的基礎例程里面使用最多的1~3,所以我們必須要修改這個值,否則我們要重新修改所有底層驅動的優先級。
那么怎么修改比較合理?這個就得看實際應用需要了,其實使用宏configMAX_SYSCALL_INTERRUPT_PRIORITY來屏蔽部分中斷是比較合理的,相對于CM3,CM0沒有中斷優先級閾值寄存器,只能簡單粗暴的開啟全局中斷和關閉全局中斷。操作系統在執行十分重要的工作時一般不能打斷這個工作,尤其是這時在中斷里面調用了操作系統的API函數,這都會嚴重影響系統的穩定性。小燈對configMAX_SYSCALL_INTERRUPT_PRIORITY的理解是,這個數值打后的所有中斷均劃入操作系統管理,而這個數值打前的中斷則歸由用戶自己管理,但用戶必須十分小心地處理這些中斷,用戶可以使用這些中斷來處理一些跟操作系統無關的工作。這純屬個人理解,如有錯誤之處還請大家指出,小燈會盡快修改!

分析完configMAX_SYSCALL_INTERRUPT_PRIORITY的作用后,下面小燈提供一個參考值:
133239li6xrcrr4cw1c6iw.png
由于優先級寄存器是高四位有效,因此上述的屏蔽閾值實際上是0x1,也就是說優先級在1~15之間的中斷均可被操作系統屏蔽,而優先級0歸由用戶自己控制。值得注意的是configMAX_SYSCALL_INTERRUPT_PRIORITY的高四位絕對不能設為0,下面小燈給出0x0F的仿真結果:
133239biiephbfzn44flli.png 133239aicsmzkc4tttef6y.png
當configMAX_SYSCALL_INTERRUPT_PRIORITY設為0x0F時系統在進入臨界區時BASEPRI寄存器的值一直為0,沒有更新。下面給出0x1F時的仿真結果:
133239vrcpa4czczvzpnst.png
133240y0j52zx8jhp38tgw.png
當configMAX_SYSCALL_INTERRUPT_PRIORITY設為0x1F時系統在進入臨界區時BASEPRI寄存器的值更新為0x10,中斷優先級閾值寄存器起作用了!原因在上面也解釋過了,因為STM32F103的優先級寄存器是高四位有效的,對應的BASEPRI也是高四位能夠寫入而低四位無法寫入,而BASEPRI有一個特點——對它寫0會取消屏蔽所有中斷(相當于禁用了該寄存器),因此BASEPRI的高四位一定不能設為0,否則不會屏蔽任何中斷,這點注意下就好了。
(3)添加參數檢測功能
133520g1d5dryr7f8sdz17.png
該參數檢測功能是官方提供的一個參考,很多人為了省事不使用參數檢測,但小燈勸誡各位千萬不能干這蠢事!說了半天想必大家也累了,那么接下來就開始我們跑燈之旅吧!

下面就以LED創建兩個閃爍任務:
133520y6rlksoovvpsgvh5.png
133520yo5pfehaqeh8uooa.png
至于LED底層驅動代碼在工程里面提供了,在這不詳細解釋,讀者可自行修改。在main函數里首先設置中斷優先級分組方式4,然后創建2個LED任務,堆棧深度40個字(160字節)即可,然后啟動任務調度器,整個操作系統就能夠跑起來了。

重新編譯下工程,這時會提示有錯誤:
133521hqhb63oaqay33uqu.png
133521zu4fol6x7r4fg84f.png

接下來我們需要屏蔽這些編譯錯誤:
133521k6qcz6exq5bg63xx.png
在C/C++ Compiler的Diagostics里面添加Pa082,Pe191,Pe167
重新編譯一次:
133521b3oq33bbkvj1eqz1.png
編譯通過,下載到板子上后就能夠看到2個LED按照一定的頻率閃爍了!


三、MDK下移植FreeRTOS
由于在上面IAR移植過程中已經把需要注意的事項詳細,再次就不累述了,只給出移植過程。小燈使用的MDK版本是:
133522k3c3p1jxs4fsptco.png
至于MDK工程的新建,請參照@正點原子的教程資料,小燈就不搶原子哥風頭了,哈哈!

工程沿襲了小燈一貫的簡約作風:
133522jk0fof8zessgf99g.png

(1)添加FreeRTOS源文件:
133522fc02ezs2yc9q0cq9.png
源文件清單路徑如下:
FreeRTOS        asks.c
FreeRTOSlist.c
FreeRTOSportableKeilARM_CM3port.c
FreeRTOSportableMemMangheap_4.c
注意這里的FreeRTOSConfig.h的來源小燈在上面IAR移植里面已經詳細說明了,而且對FreeRTOSConfig.h里面的內容做了大篇幅的分析,讀者請自行翻查,在此不再累述。

(2)添加頭文件路徑:
133522xjefjer7iimy1f1e.png

(3)修改stm32f10x_it.c文件:
133927zrra9lr974ay4rer.png
至于為了要修改該文件,小燈在上面IAR移植里面已經詳細說明了,讀者請自行翻查,在此不再累述。

(4)創建兩個LED閃爍任務:
133927t441z11z64m6144p.png
133928d0rn23653klc5kxh.png
代碼的解釋在IAR移植里面已經詳細說明了,讀者請自行翻查,在此不再累述。

(5)編譯工程:
133522okpdh4ttpddphyhq.png
在MDK移植FreeRTOS相對來說順利很多,因為不會出現一大堆警告和錯誤。接下來下載到板子,效果跟IAR移植后一樣,2個LED按照預定的頻率閃爍!


總結:
FreeRTOS的移植難度并不大,只是有些地方需要注意,否則出問題了也完全找不出問題出在哪里。由于小燈習慣了使用IAR,習慣使用MDK的用戶如果看IAR的移植步驟可能會很不習慣,但兩者移植過程相仿,讀者只需要注意對應的事項就好。鑒于小燈水平有限,文檔難免會有出錯的地方,小燈也很希望各位能指出錯誤之處或提供寶貴意見,小燈會及時修改,不勝感激!


FreeRTOS的官方網址為:http://www.freertos.org
133933z1ufufaacvz5qlud.jpg

下載:
FreeRTOS工程.rar (631.66 KB, 下載次數: 31)
FreeRTOS移植到STM32F103步驟與注意事項.pdf (682.14 KB, 下載次數: 26)


回復

使用道具 舉報

無效樓層,該帖已經被刪除
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表