娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

14. 串口控制臺建立

發布者:Mingyue1314最新更新時間:2024-11-04 來源: cnblogs關鍵字:串口控制臺  uboot 手機看文章 掃描二維碼
隨時隨地手機看文章

串口控制臺建立這一節的主要有三個內容:

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進行如下修改:

修改前:

修改:

  1. 把printf.c放到lib文件夾下,在lib文件夾里一起編譯得lib.o,則需要包含lib/lib.o。所以把printf.o換成lib/lib.o.

  2. 然后,gboot.bin是用過gboot.elf得到的。

  1. gboot.elf是通過鏈接上面的*.o文件得到的。

  1. 為了得到lib/lib.o則需要進入到lib文件夾進行編譯,make的結果是獲得all:

all是在lib文件夾下make后得到的文件:

  1. 還要進入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:

到這里,我們的基本工程框架已經實現了,結構也比較合理了。為以后跟多功能的加入搭建好了平臺。


關鍵字:串口控制臺  uboot 引用地址:14. 串口控制臺建立

上一篇:15.210控制臺故障分析(解決問題的思路)
下一篇:13.Smart210串口驅動基于12的補充

推薦閱讀最新更新時間:2025-04-23 17:29

uboot啟動第一階段
s5pv210的irom代碼讀取sd(mmc通道3)中的16kB(uboot第一階段代碼)到iram的0xd0020010中校驗通過后開始執行 第一條指令位于cpu/s5pc11x/start.S 1   _start: b reset(第57行) 2  第149行設置CPU位svc模式禁止irq和fiq 3  200~204設置cache 4  209~211設置TLB和icache 5  216~221設置cp15的c1禁止mmu和cache 6  225~227讀啟動信息(CORTEXA8將啟動信息保留在0xE0000004中) 7  243~278將我們設置的啟動標志保存在寄存器中 8  284~286設置棧 9  2
[單片機]
uboot啟動過程理解
對于2440而言,啟動的方式不多。一般就是外界一個NAND FLASH ,2440內部有個NAND FLASH Controller,會自動把NAND FLASH的前4K拷貝到2440的片內SRAM。2440這個片內SRAM就是所謂的 Stepping Stone剛好也是4K。 在制作啟動代碼時,就是uboot。一般會把uboot分為兩個部分,一般就會叫做BL1和BL2。 BL1和BL2兩者相加就是整個uboot。這兩個部分各有分工。 為了符合2440的特點,BL1的大小會被設置為4K,這4K需要完成的任務有: 1、配置好內存(對于2440來說,內存就是SDRAM)。 2、配置好內存后,將整個uboot搬運到SDRAM
[單片機]
<font color='red'>uboot</font>啟動過程理解
uboot在s3c2440上的移植(5)
一、移植環境 主 機:VMWare--Fedora 9 開發板:Mini2440--64MB Nand,Kernel:2.6.30.4 編譯器:arm-linux-gcc-4.3.2.tgz u-boot:u-boot-2009.08.tar.bz2 二、移植步驟 9)實現u-boot對yaffs/yaffs2文件系統下載的支持。 注意:此篇對Nand的操作是基于MTD架構方式,在“u-boot-2009.08在2440上的移植詳解(三)”中講到過。 通常一個Nnad Flash存儲設備由若干塊組成,1個塊由若干頁組成。一般128MB以下容量的Nand Flash芯片,一頁大小為528B,被依次分為2個256B的主數據區
[單片機]
移植uboot到mini2440(一)
出來半年了,感覺學到的關于技術方面的東西很少很少,更多的是對軟件大環境和行業有了更多的了解,為了鞏固以前學過的知識和學習新的知識,我決定移植一個uboot到我的mini2440開發板上。 一、準備工作:包括兩方面,一方面是知識儲備,也即是移植uboot前必須清楚明白的一些基本原理和常識。另一方面是搭建環境。 首先 知識儲備,uboot是什么?U-Boot 是bootloader的一種,是 Das U-Boot 的簡稱,其含義是 Universal Boot Loader,是遵循 GPL 條款的開放源碼項目。最早德國 DENX 軟件工程中心的 Wolfgang Denk 基于 8xxROM 和 FADSR
[單片機]
移植<font color='red'>uboot</font>到mini2440(一)
3.移植uboot-使板卡支持nor、nand
在上一章,我們添加了nor,nand啟動后,uboot啟動出如下圖所示: 上面的Flash: *** failed *** 是屬于uboot第二階段函數board_init_r()里的代碼, 代碼如下所示(位于arch/arm/lib/board.c): /*第二階段*/ void board_init_r(gd_t *id, ulong dest_addr) //gd uboot重定位地址 { ... ...   puts( Flash: );            //打印flash:   flash_size = flash_init(); //初始化nor_flash  
[單片機]
3.移植<font color='red'>uboot</font>-使板卡支持nor、nand
uboot stage2 init_fnc_t *init_sequence[]代碼分析
 今天總算是把uboot stage2看完了,哎,感受太深了一句話:看完了這些代碼,才知道什么叫代碼~~  uboot第二階段代碼是用C寫的,本來以為可以比第一階段的匯編好理解,畢竟對C更熟悉一點。可剛開始進入start_armboot()函數一看,就 了~~哎,學習不到家啊~~ 所以,現在還不敢大談對第二階段有多理解吧,只是簡單記一下,大概理解的。  本著理解代碼高于一切的原則,順著start_armboot()函數執行順序讀下去。前面的還是比較好理解的,現在就講講init_fnc_t *init_sequence 吧。  在init_fnc_t *init_sequence 定義前有這樣一行:typedef int (in
[單片機]
<font color='red'>uboot</font> stage2 init_fnc_t *init_sequence[]代碼分析
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 淮滨县| 肇东市| 合水县| 东城区| 昆山市| 元朗区| 平顶山市| 华宁县| 上栗县| 德令哈市| 温宿县| 湘乡市| 青河县| 柘荣县| 江达县| 正镶白旗| 丰都县| 福海县| 启东市| 北流市| 裕民县| 徐水县| 保康县| 平湖市| 保山市| 工布江达县| 兰考县| 马山县| 留坝县| 和田县| 体育| 松溪县| 邓州市| 来凤县| 炉霍县| 平安县| 车险| 黄山市| 丹阳市| 海城市| 交城县|