串口控制臺建立這一節的主要有三個內容:
1.控制臺框架搭建
1.1控制臺的分類介紹:
1.1.1菜單型控制臺:就是選中設置好的數字或者字母選項后執行相應功能的控制臺:
例如剛進入uboot之后的界面,就是菜單型控制臺:
等待我們輸入命令,來執行相應的操作。例如上面,如果此時我們輸入1,就是進行Format the nand Flash的操作:
1.1.2解析型控制臺:在上面的菜單型控制臺里,選擇5:Exit to command line:后會出現:
就進入了解析型控制臺:
我們輸入help后,控制臺會去解析這一命令是不是該控制臺所支持的,如果是,它會去調用相應的help函數來運行。會列出這個uboot所在的解析型控制臺所支持的命令:
由于解析型控制臺實現起來會很復雜,今天就選擇相對簡單的菜單型控制臺,來實現一個相對簡單的自己的uboot控制臺。
菜單型控制臺:
可以看到一個菜單型控制臺,第一件事就是先把菜單打印出來,而且會循環打印,首先想到的就是使用printf來打印菜單信息。代碼:
上面就是uboot里的提示信息,根據用戶的選項來執行對應的功能函數,通過switch來選擇實現。上面就是菜單型框架。
在上面的菜單型控制臺的實現里,最主要的兩個函數是scanf和printf。
2. scanf和printf的實現
首先先實現printf函數,在實現一個函數的時候,第一考慮的是它的功能,printf的功能是打印信息的,printf在PC機里打印信息是打印到顯示器里的。然而在開發板里,printf的信息是打印到串口終端的。接著就是要了解該函數的參數。要了解它的參數需要在命令行執行:man 3 printf:
可以看到第一個就是我們的printf函數,只是它的參數是采用的變參的方式,變參用三個點表示,就是該函數的參數是不一定的。可以為零,可以為一個,可以為很多個。后面變參的形式由前面的const char *format來決定的。就是如果const char *format指定的是一個整形參數,那么。。。就得是整形參數,如果const char *format是字符型參數,那么。。。就得是字符型參數。
實現思路:將傳進來的參數轉化為字符串型的buffer,然后字符串型的buffer通過一個while循環,利用上一節實現的void putc(unsigned char ch)函數輸出到串口終端。
實現思路的難點是怎么把傳進來的參數轉化為字符串型的buffer。
1)在上一節的uboot工程里創建一個printf.c:
2)接著把printf.c加入到Makefile里面去:
3)printf.c的實現:(1)將變參轉化為字符串。(2)打印字符串到串口。
對于(2)打印字符串到串口。起始實現起來很方便,因為前面已經實現了putc()函數:
有難度的是(1)將變參轉化為字符串。這里需要用到C語言中已經實現好的一些宏。關于變參處理的一些宏(函數)。來幫我們完成。(1)將變參轉化為字符串。實現步驟:
上面就實現了將變參轉化為字符串。但是問題又來了。上面的三個宏(函數)又得我們實現,而且實現起來是非常復雜的,而且是很標準的。這里就可以采用移植的方法。
我們去實現這種嵌入式的軟件,并不是說,所有的代碼都需要自己去編寫。比如后面還有實現tftp,tftp還需要ip協議棧,對于ip協議棧,我們是無法實現的。所以就是在實現嵌入式的軟件的時候,很大時候需要做的是移植。
我們實現移植的地方有兩個,一個是Linux內核里,或是C庫。這里談到移植,對于現階段的我們來說,難度太大了。所以現在我們只要知道,這三個函數的功能是什么,和會使用這些從Linux內核提取好的一些文件,集成到自己的uboot工程里面使用就可以了。
下面是兩個提取好的文件目錄:
把這兩個文件夾拷貝到原先的工程目錄下:
接下來對工程文件夾下的Makefile進行如下修改:
修改前:
修改:
把printf.c放到lib文件夾下,在lib文件夾里一起編譯得lib.o,則需要包含lib/lib.o。所以把printf.o換成lib/lib.o.
然后,gboot.bin是用過gboot.elf得到的。
gboot.elf是通過鏈接上面的*.o文件得到的。
為了得到lib/lib.o則需要進入到lib文件夾進行編譯,make的結果是獲得all:
all是在lib文件夾下make后得到的文件:
還要進入lib文件夾進行clean:
最后修改的文件為:
lib下的Makefile:
頂層的Makefile為:
修改好了之后進行編譯make,會報下面的錯:
上面的ctype.c文件是在lib文件夾下的,這里報錯說明已經把lib文件夾下的文件已經用進了gboot.bin工程,只是報錯了。錯誤信息是在ctype.c有很多未定義的符號。接下來打開ctype.c,看看是怎么回事:
上面看到ctyp.c里使用了這些符號,make為什么會報這些符號沒定義呢?可以看到它包含了ctype.h頭文件,打開:
可以看到include/ctype.h里已經定義了這些符號了。可以看到ctype.h已經定義了這些符號。問題出在在編譯的時候,arm-linux-gcc這編譯器默認尋找頭文件的路徑,并沒有找到我們現在工程里include/ctype.h頭文件。這就需要我們在編譯的時候,指定編譯器arm-linux-gcc在編譯的時候除了要去默認路徑需找頭文件,還要去我們指定的路徑尋找頭文件。自己指定頭文件路徑是通過-I參數去指定尋找頭文件路徑。
打開lib目錄下的Makefile:
這里,我們需要在arm-linux-gcc命名后面加-I來指定還要需找頭文件的路徑。但是可以看到,已經有CFLAGS變量了,它就是來保存一些編譯的參數的。CFLAGS是在工程文件夾下的Makefile定義的:
打開頂層的Makefile加入CFLAGS的定義:
該CFLAGS變量的值是一個路徑,通過shell命令pwd獲得當前的相對路徑,包含該路徑下的include文件夾。為了底層的目錄能夠用到該文件,需要將變量export:
修改了之后,make,先前的問題解決了:
可以看到前面的問題解決了,但是又出現了新的問題:printf.c里的第3行的va_list沒有定義。打開printf.c:
上面這個類型va_list是在lib/vsprintf.h文件里定義的:
所以要解決這個錯誤,只需要將lib/vsprintf.h包含到printf.c即可解決:
加入之后編譯make,會有以下錯誤:
第一個警告,uart.c:29: warning: conflicting types for built-in function 'putc'然后打開uart.c的29行,發現根本沒有什么內斂函數。起始這是因為在Makefile里少了一個參數:-fno-builtin
再把該變量CFLAGS加到該Makefile里編譯c文件的地方:
重新編譯:
會發現警告沒了。又有錯誤。就是在編譯lib/lib.o的時候發現未定義的vaprintf。哦哦,這是我們的函數寫錯了,應該是vsprintf。修改之后:
修改后再make:還是原來的錯誤:
按照道理修改了之后應該是不會再出現這樣的錯誤的。再說現在工程里已經沒有vaprintf的影子。怎么還是這個錯誤。無論怎能make clea后make,還是那個錯誤。搞到無奈,求救百度,百度無解。最后make clean之后進入lib文件夾,發現lib文件夾里生成的東西沒有被清除。就在lib文件夾下進行make clean后退到原來工程目錄,make clean,奇跡出現了:
但是還是有一個錯誤,這是我們使用了為定義和實現的scanf函數導致的:
這是我們先把它注釋掉:
修改之后,重新編譯成功了:
生成了gboot.bin:
燒寫到開發板,發現串口終端的內容輸出了:
上面就實現了printf函數了,接下來就是實現scanf函數了。在Redhat 6.4執行命令:man 3 scanf:
可以看到返回值是int,第一個參數是const char *format,第二個參數還是變參。該函數實現的過程跟printf是相反的。Scanf函數是:1)先獲取輸入的字符串。2)獲得字符串進行格式轉換,傳遞給系統。實現代碼:
編譯成功:
到這里,printf和scanf都實現好了,編譯并燒寫到開發板:
可以看到我們要的輸入效果出現了。我們輸入1,沒有反應,輸入4,會輸出Error:wrong
Selection。在后面的操作里將實現switch選擇所對應的處理方法。到這里控制臺的基本搭建完成了。
3.程序結構的優化
可以看到,現在目錄下的文件已經很亂了,隨著工程的深入,文件會越來越多,為了管理的方便,這里,我們把有關設備驅動的C文件放到dev文件夾里:
這樣,我們的工程文件的布局就合理多了。當然,dev文件夾下也需要Makefile文件,從lib文件夾下拷貝過去再進行修改:
最后dev下的Makefile的內容為:
這樣就修改好了dev目錄下的Makefile,注意,我們頂層的Makefile也需要改:
做了上面的相應修改后,make:
到這里,我們的基本工程框架已經實現了,結構也比較合理了。為以后跟多功能的加入搭建好了平臺。
上一篇:15.210控制臺故障分析(解決問題的思路)
下一篇:13.Smart210串口驅動基于12的補充
推薦閱讀最新更新時間:2025-04-23 17:29



![<font color='red'>uboot</font> stage2 init_fnc_t *init_sequence[]代碼分析](https://6.eewimg.cn/news/statics/images/loading.gif)
設計資源 培訓 開發板 精華推薦
- 特斯拉:美國交付的Model Y/3電池包已實現100%美國生產
- 地平線與博世深化合作,攜手為多家車企提供輔助駕駛產品
- 強化中國市場戰略布局,德州儀器正靈活應對全球關稅挑戰
- Molex莫仕通過本地合作和創新加強支持中國汽車行業
- 貿澤開售Texas Instruments適用于高分辨率AR HUD的 全新DLP4620S-Q1 0.46"汽車數字微鏡器件
- ROHM推出高功率密度的新型SiC模塊,將實現車載充電器小型化!
- 用上車規級UFS 4.0,讓出行變得高效且可靠
- 車載測試技術解析:聚焦高帶寬、多通道同步采集與協議分析
- 傳統晶體管的極限!臺積電3nm N3P已量產
- 分析師稱H20出口管制毫無意義:對中國AI發展影響不大