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的补充

推荐阅读最新更新时间:2026-03-22 10:41

14. 串口控制台建立
串口控制台建立这一节的主要有三个内容: 1.控制台框架搭建 1.1控制台的分类介绍: 1.1.1菜单型控制台:就是选中设置好的数字或者字母选项后执行相应功能的控制台: 例如刚进入uboot之后的界面,就是菜单型控制台: 等待我们输入命令,来执行相应的操作。例如上面,如果此时我们输入1,就是进行Format the nand Flash的操作: 1.1.2解析型控制台:在上面的菜单型控制台里,选择5:Exit to command line:后会出现: 就进入了解析型控制台: 我们输入help后,控制台会去解析这一命令是不是该控制台所支持的,如果是,它会去调用相应的help函数来运行。会列出这个uboot
[单片机]
14. <font color='red'>串口</font><font color='red'>控制台</font>建立
迅为IMX6Q开发板非设备树uboot-修改默认环境变量
iTOP-iMX6 开发板烧写好之后,默认是 android 系统 9.7 寸屏幕的系统参数和屏幕参数。如下图。本文档主要介绍如何修改默认启动参数. ignore_js_op 70.1 重要的环境变量 比较重要的环境变量或者说经常使用的环境变量,已经在上图中的红色方框中。主要是:bootsystem、lcdtype 和 bootargs。这些参数都可以在 uboot 源码中进行设置。具体文件为:“iTOP-iMX6_android4.4.2/bootable/bootloader/uboot-imx/lib_arm/board.c”文件。 70.2 默认启动系统设置 默认启动系统参数是:bootsystem。打开“board.c
[单片机]
迅为IMX6Q开发板非设备树<font color='red'>uboot</font>-修改默认环境变量
uboot(基于IMX6ull)
一、U-Boot初次编译 1、首先在 Ubuntu 中安装 ncurses 库,否则编译会报错,安装命令如下:sudo apt-get install libncurses5-dev 2、解压官方Uboot:tar -vxjf uboot-imx-2016.03-2.1.0-g8b546e4.tar.bz2 3、编写编译脚本文件:xxx.sh #!/bin/bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- (加空格) mx6ull_14x14_ddr51
[单片机]
<font color='red'>uboot</font>(基于IMX6ull)
uboot总结:uboot配置和启动过程3(config.mk分析)
说明:文件位置:在uboot的目录下,文件名为:config.mk。是一个makefile文件,以后会被主Makefile调用。 它的主要作用的是: (1)具体的设置交叉编译工具链接(主Makefile中也有设置交叉编译工具链) (2)加载include/autoconfig.mk文件(这个文件是在主Makefile中生成的) (3)指定-Ttext链接地址 (4)makefile的推导规则 下面来具体的分析代码: 1、设置交叉编译工具链 2、加载autoconfig.mk文件,这个文件是在主Makefile中生成 3、设置链接地址,这个TEXT_BASE是在主Makefile中的x210_sd_config部分配
[单片机]
uboot总结:uboot配置和启动过程1(主Makefile分析)
说明:文件位置:在uboot的目录下,文件名为:Makefile 从文件的头部开始分析 1、24-29行,配置uboot的版本信息。 VERSION = 1 PATCHLEVEL = 3 SUBLEVEL = 4 EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) VERSION_FILE = $(obj)include/version_autogenerated.h 2、主机的环境信息(比如:我现在是虚拟机的Ubuntu10.04下开发的,就是i686,linux。) 3、配置为静默编译的设置(使用方法:m
[单片机]
[uboot] (第一章)uboot流程——概述
一、bootloader & uboot 1、bootloader的概念  Bootloader是在操作系统运行之前执行的一段小程序。而这段小程序的最终目的,正确地设置好软硬件环境,使之能够成功地引导操作系统。 2、bootloader的核心功能 bootloader的核心功能就是引导操作系统,部分工作如下 初始化部分硬件,包括时钟、内存等等 加载内核到内存上 加载文件系统、atags或者dtb到内存上 根据操作系统启动要求正确配置好一些硬件 启动操作系统 3、bootloader的monitor功能 上述2是bootloader的核心功能,也就是引导操作系统的功能。 但是部分bootloader还支持monitor
[单片机]
Linux内核分析:uboot与Linux内核机器码分析
1. uboot机器码 在uboot启动的start_armboot阶段,调用board_init函数初始化机器码。 int board_init(void) { .............................. gd- bd- bi_arch_number = MACH_TYPE_SMDKV210; gd- bd- bi_boot_params = PHYS_SDRAM_1 + 0x100;   return 0; } 在uboot启动内核时,将机器码传参至内核。 uboot源码中,也有一个/uboot/arch/arm/include/mach-types.h文件,该文件维护至该版本的u
[单片机]
tiny210V2 Uboot kernel filesystem 烧写和启动
1.sd启动 将u-boot镜像写入SD卡 将SD卡通过读卡器接上电脑(或直接插入笔记本卡槽),通过 cat /proc/partitions 找出SD卡对应的设备,我的设备节点是/dev/sdb. 执行下面的命令 $sudo dd iflag=dsync oflag=dsync if=tiny210-uboot.bin of=/dev/sdb seek=1 设置环境变量: setenv gatewayip 192.168.1.1 setenv ipaddr 192.168.1.102 setenv netmask 255.255.255.0 setenv serverip 192.168.1.10 saveenv 2.nand启
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved