在STM32F401上移植uC/OS的一個小問題 [原創]

helesheng 2021-08-15 15:21:02 阅读数:724

本文一共[544]字,预计阅读时长:1分钟~
stm32f401 stm 移植 uc os

STM32F401xx是意法半導體新推出的Cortex-M4內核的MCU,相較於已經非常流行的STM32F407xx和STM32F427xx等相同內核的MCU而言,其特點是功耗僅為128uA/MHz,且存在64pin封裝的小封裝器件。我設計一款新產品使用了STM32F401xx,想把自己熟悉的uC/OS-II實時操作系統移植到這款MCU上。懶得從底層開始從頭移植,偷懶從原子的“探索者”開發板移植的uC/OS-II開始修改。完成後在板子上一跑,發現系統時鐘總存在約5%的偏差。仔細搜索代碼後才發現,問題在把原子的uC/OS-II移植直接用在STM32F401上時的一個小bug,把發現問題的過程和解决辦法分享給大家。

以下原創內容歡迎網友轉載,但請注明出處:http://cnblogs.com/helesheng

一、把探索者開發板移植的uC/OS-II用在STM32F401xx上

原子的探索者開發板使用了STM32F407ZG,其內核是和32F401xx 相同的Cortex-M4,外設也基本相同。簡單地將原子在探索者開發板上移植的uC/OS-II工程中的Device修改為STM32F401RC,編譯後發現大量的預定義找不到。想到可能是代錶處理器的預定義的宏沒有修改,在Option中的C/C++頁中,將Preprocessor Symbols改為代錶401的“STM32F401xx,USE_STDPERIPH_DRIVER”,直接編譯通過,心中一陣竊喜。

圖1 修改預定義

二、uC/OS-II系統時鐘偏差的小問題

運行之前在其它款STM32上寫的uC/OS-II程序,開始一切順利,但隨後用示波器仔細分析各個任務內部及相互間的時間關系時,發現總存在+5%左右的時間誤差,即實際系統時鐘的周期只有理論系統時鐘的95%左右。以每秒系統節拍數OS_TICKS_PER_SEC設置為200為例,每個OSTimeDly(1);的任務延遲僅為4750us。

開始以為是原子編寫的延遲函數void delay_ms(u16 nms);的問題,仔細閱讀代碼後發現,這個函數只是在調用系統延遲函數OSTimeDly();的基礎之上,將無法由系統延遲實現的us級延遲改由硬延遲實現。雖然我個人非常不贊同這種做法,因為這會造成uC/OS-II時間調度的盲區,從而影響uC/OS-II系統的實時性。但這不至於造成系統時鐘的偏差,繼續查找問題的原因。

既然調用系統延遲函數OSTimeDly的過程沒有問題,那麼只可能是系統時鐘本身出了問題。Cortex-M內核的uC/OS移植都會用了SysTick定時器的中斷構建系統時鐘,因此在SysTick上找原因。打開MDK,連接自制的STM32F401電路板和仿真器,進入Debug模式,運行程序,讓uC/OS完成初始化配置,然後暫停程序;在外設(peripheral)菜單中找到SysTick定時器,界面如下圖所示。

 

圖2 System tick定時器狀態監視器

其中重裝寄存器中的值為0xC350,即50_000,仔細一想發現有問題——STM32F401的主頻為84MHz,那要達到200Hz的系統時鐘,無論如何都不可能把System Tick的初值配置為50_000啊!於是開始查找uC/OS移植代碼中配置System Tick的部分,原來在探索者開發板移植代碼中初始化延遲函數delay_init();中。看看原子的代碼。

圖3 delay_init();函數原來的代碼

原子的代碼簡潔清晰,將System Tick的時鐘配置為AHB時鐘的1/8,在計算System Tick的初值。其中紅圈中的一句是計算AHB時鐘的八分之一,為後續計算定時器初始值做准備。但進一步仔細查看後發現變量SYSCLK中存放的AHB時鐘數是以MHz作為單比特的,對STM32F401xx而言,就是84。84無法整除8,而賦值語句左邊的變量reload卻是int型變量,從而導致了紅圈中的一句計算誤差。這樣即使後一句將reload的單比特切換回了Hz,也無法挽回前一句無法整除造成的計算誤差。而這真是uC/OS系統時鐘誤差5%的真正原因!對這兩句進行簡單修改——現將SYSCLK折算為以Hz為單比特,即可保證足够的計算精度。

圖4 修改過的delay_init();函數代碼

修改過後,uC/OS的系統時鐘又恢複了原有的准確性。

究其原因並不是原子探索者開發板移植的uC/OS的問題,因為探索者采用的STM32F407ZG運行在168MHz,能够整除8,不存在這個問題。這裏給大家展示這個過程,一是給大家在STM32F401上移植uC/OS做些探索,二是分享一下嵌入式調試和查找問題的點滴思路和心得。

 

版权声明:本文为[helesheng]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/08/20210815152050541u.html