stm32軟件編程的框架及注意事項——rtos篇


0、通常,嵌入式軟件(這里指單片機系統)的框架千變萬化,有帶rtos的,也有裸機的。

0.1、寫過帶系統的,也寫過裸機的,這里總結一下兩個類型的框架,記錄下自己的心得,主要是文字描述,框架圖可以后期添加。


1、freertos框架
1.1、使用標准庫,網上有很多一直教程,也有現成移植好的,如果自己使用,可以在config文件下,自己需要根據項目的大小進行系統的裁剪,這方面的教程有很多,官方的,原子的,野火的等等。

1.2、使用hal庫,可以直接使用freertos的中間件,在代碼中,cubemx其實已經把freertos的接口函數封裝了一遍,以至於和原來的freertos的接口函數不一樣的,但是實現的功能是一樣的,這個宗旨是不能變的。項目中通常采用1000hz的調度頻率。

但是使用的方法有些不一樣,比如延時函數等,這個可以參考stm32方面的教程,文檔名稱是《STM32 嵌入式操作系統介紹》(或《STM32RTOS培訓_嵌入式操作系統介紹》)這個文檔介紹了基本的使用方法。尤其是接口函數的使用。英文也有:

https://arm-software.github.io/CMSIS-FreeRTOS/General/html/index.html

1.3、在cubemx中,可以進行系統的裁剪,可以分配多少空間給任務,默認是128字(128×4個字節),最后可以看看還剩多少空間,根據項目的任務數量來具體分配,還有信號量隊列,互斥量,軟件定時器一般不怎么用,用的最多的是信號量(用於任務或中斷的同步),互斥量(臨界區的數據保護)。

1.4、開發中,首先要將信號量,任務先建立,沒有中斷的芯片驅動可以首先初始化。
如果外部芯片有中斷的,可以最后初始化,因為如果初始化后,芯片就會產生一個外部中斷,從而調用信號量,但是此時你卻沒有初始化信號量,從而導致死機,這個一定要注意!

1.5、可以使用一個開始任務,把外設初始化、任務創建放在里面,結束后,刪除自己即可。

1.6、中斷基本上使用信號量來同步,這個比標志位更方便,在任務中判斷信號量是否有新,無效則一直等待,也可以設置一個等待時間,一般都是一直等待,這樣任務可以掛起,不影響其他任務的運行,這個裸機是有區別的,而且不用清零標志位。

1.7、任務的周期不能太短,100ms基本上ok,50ms也行的,但是這個任務不能長期執行,否則將導致其他任務飢餓,得不到系統運行的時間。

1.8、任務里面盡量不要使用for循環,可以使用計數器的方式代替,比如一個周期只采樣一個通道,這個是比較好的方法,否則for循環會導致占用很多cpu資源,導致其他任務無法運行,或者一個任務,只執行了一半的程序。

1.9、任務基本上采用時間片的方式,其實就是將每個任務的優先級設置為一樣,這樣系統就會在1ms的時刻運行一次某個任務,下1ms運行下一個任務(就是任務切換),直到所有任務都各自運行了1ms,從頭開始運第一個任務。這樣基本上不用作臨界資源的保護動作。

假如,任務1的延時時間是100ms,程序需要運行30ms,任務2的延時時間是50ms,程序需要運行40ms。那么cpu先在前60ms,間隔運行任務1、任務2,每次運行1ms,60ms后,任務1已經運行完畢,進入掛起態。任務2繼續運行,運行到70ms后,任務2也運行完畢,進入掛起態,之后到80ms后重新運行任務2。

可以看看下面的示意圖。只說明了大概意思,時間點可能不准確,大家也可以提提意見。

  2、軟件框架:

通信方式使用tcp協議或者modbus協議。
tcp的物理介質是網線,要注意,交叉線和直連線。
modbus使用rs485的總線,使用rtu方式。

2.1總的框架是:應用邏輯使用java實現,在pc或高級的cpu處理器(可以跑linux這種),單片機實現底層的驅動。

2.2、上位機下發一條指令——>單片機串口接收到數據——>檢查數據合法性——>置位相關的標志位——>進行一次設備的操作——>清零相關的標志位——>結束

2.3、串口接收結合定時器的方法,modbus就是使用的這種,3.5T以上如沒有數據了,說明一幀數據已經結束。可以進行數據解析了。

2.4、使用標志位的目的是,命令來一次,我單片機只操作一次設備,眾所周知,rtos中單片機有好幾個死循環的,一直在運行的,因此標志位清零后,就達到了目的,以免頻繁的操作設備。有的需要自動控制的,那么,就要合理添加標志位,因此標志位的使用比較關鍵的,要好好規划。

3、另外一種用的較多的是狀態機的方法。
通常我們在使用按鍵的時候會使用狀態機的思想,狀態機的思想,我最先是在FPGA的課程中用到,后面就陸續在網上看到這單片機中也經常使用的。因此我在任務中,經常使用到,尤其是與外部設備進行通信的過程中。

3.1、一般串口通信我會分如下幾個步驟:

空閑態——這個狀態沒有任何發送和接收

接收態——數據正在接收,同時定時器在該狀態中,判斷是否已經有4ms的超時,超時了,立即轉為“完成態”,並觸發一個接收中斷,告知單片機可以處理數據解析,這個時刻可以鎖定串口不再接收新的數據,等完成處理,發送回上位機后(如果有必要這個步驟),再開啟接收的功能,這樣可以創造單片機有一個“數據解析處理”的單獨的時間,當然前提是:上位機只有接收到單片機的數據后,才能發送下一條數據。

3.2、當然還可以添加一些其他的狀態:
超時
數據幀錯誤
超載狀態
基本上6個狀態已經可以夠用了,比較健壯的。

3.3、同時還可以添加一個狀態機,用於描述一個通信狀態是否完成。我這里添加了一個事件的狀態機:
初始態——數據沒有發送、沒有接受
完成態——對應於串口的超時、數據幀錯誤、超載狀態、完成態,這樣可以告知單片機,一個時間已經完成,可以進行后續的工作。這個在我單片機要發送兩次串口任務中使用到,因為要發送兩次停機命令,有兩個歐姆龍溫控器(modbus控制)。

小結:rtos的框架,基本上使用任務+信號量+狀態機,就可以解決中小型的項目,而且有一個優點,任務之間耦合性較低,時間控制方面也是比較好的,基本上有的地方可以不用定時器了,編寫代碼更加省心,比如點led燈,在裸機里面,必須要使用定時器。

效率方便,代寫完裸機后,在進行總結一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM