RT-Thread设备框架学习感悟
前面幾周跟著野火的教程從0到1實現了RT-Thread的內核,對RT-Thread的調度機制和線程、定時器的底層實現有了總體的了解。后面還需進一步對齊實現細節進行探索,但大致先了解其框架,后面再進行細致的了解。在學習新知識時,最重要的是思維模式的轉變。先了解其大致框架,再深入去了解細節。有些人(就是我,后來太痛苦終于悟了)學一個新知識,剛上來就從頭到尾一個字一個字仔細看,生怕錯過什么重要的內容,搞不懂關鍵點就立馬停下來去查,一查發現哇!解釋內容這么多,看解釋的時候又發現有不懂得地方,又停下來去查,如此一環套一環,何時是個頭。而且這樣學習的結果就是學一個新知識很快就會筋疲力盡,覺得自己什么都不懂,自信心受到打擊,從而陷入對自己的深深懷疑之中,最后很可能放棄學習(這種學習方式就像C語言中函數的遞歸調用,一層套一層,層層套娃,很容易導致棧空間不夠用,最后造成程序崩潰。在陳正沖老師的《C語言深度剖析》中,就建議盡量不要使用遞歸,如果要使用一定要注意遞歸調用的深度和對應使用的棧空間)!其實你想想看,這些知識是前人付出多少心血才總結出來的,哪可能會讓你一上來就搞得門兒清?除非你天賦異稟異于常人。因此在學習新知識的時候,先了解其大概,不求甚解,遇到了問題先保持疑問,帶著疑問繼續學下去。動手做起來再說,做的好不好,完不完美那是另一回事,先做,在做的過程中逐漸完善。有些人總是思前想后覺得要考慮的周到,完美再去做,這也沒錯,但是你考慮的就會和實際情況一模一樣嗎?在做中學習,諸葛亮舌戰群儒說筆下雖有千言,而心中實無一策。我們也要做到不能心中雖有千言,而手上絲毫不動。很多問題其實在你學習后面的知識的過程中就自然而然的解決了。還記得去年學習Linux,對Linux的驅動開發、應用開發學的是一知半解,云里霧里。那時還在學習RT-Thread,學了一段時間Linux之后回過頭再看RT-Thread發現好多在學習RT-Thread的疑問自然懂了。這就是當你接觸了一個高等級的知識后,再回過頭去看低等級的知識時發現就豁然開朗了。
比如在深入學習STM32時,你就會發現main函數并不是上電就開始運行的第一個函數,在main函數之前,在startup_xxx.S文件中(基于執行效率的考慮,使用匯編語言編寫),系統做了好多事情,如完成堆和棧的內存分配等,最后在跳轉到用戶main函數運行。假使這個時候你發現匯編語言好像你什么都不會,對ARM的架構也不是很了解,然后買了本匯編語言和ARM-Cortex內核權威指南吭哧吭哧的開始讀,希望能先解決掉這兩個不懂得內容,你就會發現你看的時候實際上會碰到更多不懂得知識。假使你真的堅持住了,學完了這兩本書,肯定你的知識層次會提高很多,但同時和你一塊的人早都跑遠了。因此,在實際學習新知識時,先了解個大概,后面再去進行細節的完善,當你有一個整個框架的時候再將細節逐漸補齊就會發現是水到渠成。
學習嵌入式的知識更要學會嵌入式的知識過于龐雜,硬件、協議、軟件,這每一個都是大部頭,如果心里沒有規劃,遇到什么都想去搞明白、研究透徹,那學來學去就忘記自己究竟想學什么了。確定自己學習的主線,先將該主線補齊,再去深入研究該主線上的分支。
當設計一個產品時,需要使用單片機還是Linux取決于硬件成本和軟件成本,而不是一味的根據個人喜好去選擇高性能的或套件更完善的,嵌入式中沒有最好的,只有最合適的(此處可以參照清華大學曾鳴老師的《嵌入式ARM微控制器》,該課程邏輯清晰,值得反復刷)。因此,既要學會使用MCU跑裸機或RTOS用于一些低端的設備,也要學會Linux用于要求較高的場合。
在上層軟件對底層硬件的操作上,單片機和Linux的實現沒有太大的區別:
在單片機程序中沒有程序分層的概念,應用程序和驅動程序混著寫,至少沒有明確的界限,很可能一個人就包攬了從硬件設計、模塊調試(針對各模塊進行驅動程序開發,如開發SPI、I2C器件的通訊程序,對外留出調用接口)、功能實現(應用程序開發,即使用接口對外圍器件進行操作,程序實現各個功能模塊的相互配合,從而實現既定功能)的全部內容,一般小公司都這么干,講究全能型,什么活都能干,不需要有規范的標準,反正能搞出來,能以最短的時間實現既定的功能需求就是最好的。
Linux程序中驅動程序和應用程序進行了分層,驅動程序訪問寄存器,應用程序只能通過驅動程序實現對寄存器的訪問,而不能直接去操作寄存器。為什么要設計成應用分層有以下原因?
- 保證程序運行的安全性
Linux系統比較復雜,龐大,因此其中應用程序很多。如果在軟件程序中開發對底層寄存器的訪問,那軟件的設計不良可能會導致程序運行崩潰。因此在Linux系統中,將對底層寄存器訪問的重要工作交給驅動程序去完成(系統認為驅動程序比較靠譜,只相信驅動程序的話,一般驅動程序開發需要即懂硬件又懂軟件,從而才能設計出可靠的驅動程序,一般該工作由驅動工程師完成)
- 保證應用程序的可移植性
驅動程序是和底層硬件直接打交道的,因此驅動程序和硬件之間是強相關的。在A款芯片上開發的驅動程序想在B款芯片上面使用就要修改,因此只要硬件有改動,就需要檢查驅動程序是否也需要針對硬件的改動作出修改。而軟件程序是和驅動程序打交道的,具體點來說是和驅動程序的調用接口打交道的。只要驅動程序提供的調用接口不變,底層硬件如何改變,應用程序是不會care的,也是不需要作任何修改的。這樣做的好處就是,在需要將A款芯片上的程序移植到B款芯片上的時候,只需要根據硬件的變化修改驅動程序,應用程序不需要修改。
- 程序分層易于團隊協作
不像單片機程序,Linux項目一般規模比較大,一個人很難全套都搞定,因此就需要分工協作。將程序分為驅動程序和應用程序有利于團隊協作,具體點就是做應用程序的只需關心如何實現業務邏輯,做驅動程序的只需要關心如何能提供對硬件操作的接口。舉例假如要做一個人臉識別項目,有擅長做圖像處理的,只要能給到他圖像,他就能進行圖像分析,具體你這個圖像是用什么拍的,他是不關心的。而不同攝像頭的硬件操作可能是存在差異的,因此使用哪款硬件,驅動工程師就需要針對硬件進行驅動程序的更改。
?
前面對RT-Thread的內核通過從0到1的實現已經有了大概的認識,接下來學習RT-Thread的設備驅動框架,和Linux的驅動樹進行類比,其實RT-Thread的很多設計思想和具體實現都有借鑒Linux的設計,好的東西當然大家都要借鑒!因此,學習RT-Thread設備驅動框架又會促進對Linux的設備樹的理解。白巖松說過,學習就是這樣一個相互作用的過程,當你還不知道你學的知識有什么用的時候,堅持學就完事了。你不知道有什么用是因為你讀的書還太少,當你讀的書多了,學的知識多了,這些點才會被連起來,到時候就不是零零散散,而會成勢。
RT-Thread的設備管理框架如上圖所示,可以將以上分為應用層、驅動層、硬件層。RT-Thread的設計思想借鑒了Linux的應用層和驅動層設計理念,因此其設備框架和Linux非常相似,也許以后RT-Thread會引入設備樹?
【應用層】應用層只需關心業務邏輯,而不需要關心底層硬件
【驅動層】對應用層提供接口使其可以間接的使用硬件,從而搭建起了應用層和硬件層之間的橋梁,驅動層未實現的硬件驅動應用層無法調用。
【硬件層】具體的硬件,可配置其內部的寄存器實現硬件功能的定制
可以這樣去理解,【硬件層】是一堆原材料,【驅動層】是一個工匠,他可以將這些原材料打造成各種各樣的工具,【應用層】是人,他只能使用工匠打造好的工具而不能直接去使用原材料。
應用層通過驅動層實現對硬件層設備的訪問,驅動層程序的升級更改并不會影響應用層大程序。以此可以實現驅動層程序和應用層程序的低耦合,可獨立進行開發。
要使用一個設備,要首先將其注冊到I/O設備管理器中,讓系統知道其的存在。設備被創建之后需要實現其對硬件的操作方法。根據設備功能的不同,可以選擇實現部分操作方法或全部操作方法。
當設備被注冊到I/O設備管理器之后,用戶應用程序通過I/O設備管理器的接口來訪問硬件設備。具體映射關系如下:
應用程序需要對硬件進行操作時可以按照如下步驟:
或寫設備rt_size_t?rt_device_write(rt_device_t?dev, rt_off_t?pos,const?void* buffer, rt_size_t?size);或控制設備rt_err_t?rt_device_control(rt_device_t?dev, rt_uint8_t?cmd, void* arg);。
5、關閉設備rt_err_t?rt_device_open(rt_device_t?dev, rt_uint16_t?oflags);。打開設備和關閉設備一般需成對使用,因為打開設備會對打開設備次數加1,關閉設備會對打開的設備次數減1。如果不成對使用,則很可能設備并不會被完全關閉。例如調用了2次打開設備后調用1次關閉設備,實際上此時設備并未被關閉,仍是處于打開狀態,只有當設備打開次數減為0時才會真正關閉設備。
?
需要注意的是,只有官方提供的BSP包才可以使用ENV工具進行配置。RT-Thread官方已經對主流芯片和開發板進行BSP包支持,因此在實際的項目使用中,我們可以先找自己項目使用的芯片對應的BSP包,再使用ENV工具對內核和功能組件進行配置,使用ENV下載軟件包,生成MDK項目工程,在此基礎之上進行項目開發。
ENV工具是針對全功能版本的RT-Thread源碼進行配置的工具,因此不適用于使用RT-Thread Nano的版本。ENV工具常用的命令也沒有幾條,用幾遍就記住了,記不住搜一下就出來了。
當使用ENV工具在配置工程后重新創建工程時,會發現調試選項會恢復成默認的。針對此問題,在《嵌入式實時操作系統 RT-Thread設計與實現》P193有說明,可以雙擊打開BSP中的template.uvprojx工程,直接修改其中的調試選項,如此使用Scons命令生成的新工程也會包含對模板文件中的修改。
?
RTT學習--制作BSP2https://blog.csdn.net/weixin_42381351/article/details/91127709
參考如上這篇文章將RT-Thread完整版移植到STM32F105芯片上。
?
總結
以上是生活随笔為你收集整理的RT-Thread设备框架学习感悟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: koa --- 自制简易的koa-ro
- 下一篇: koa --- nunjucks