uboot源码——命令体系

以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除。

参考资料:http://www.cnblogs.com/biaohc/p/6394710.html


一、uboot命令体系基础

1、使用uboot命令

  • uboot启动后进入命令行环境,在此输入命令按回车结束,uboot会接收此命令,然后解析、执行。

2、uboot命令体系实现代码在哪里?

  • 实现代码在uboot/common/cmd_xxx.c中。
  • command.c、main.c也和命令有关。

3、每个uboot命令对应一个函数

  • 这是uboot实现命令体系的一种思路和方法。

4、argc&argv传给对应的函数,作为命令参数

(1)有些uboot的命令支持传递参数

  • 命令对应的函数接收的参数列表中一般有argc和argv;
  • 命令体系会把执行命令时的命令+参数(比如 md 30000000 10),以argc(这里为3)和argv(这里argv[0]=md,argv[1]=30000000,argv[2]=10)的方式传递给执行命令的函数。
(2)以help命令为例
  • help命令背后对应的函数名叫:do_help,在uboot/common/command.c的236行。
  • int do_help (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])


二、uboot命令解析和执行过程分析

1、uboot启动的第二阶段即start_armboot()函数,最后进入一个死循环,循环体就是main_loop。


2、main_loop函数执行一遍,就是一个获取命令、解析命令、执行命令的过程。




(1)readline函数作用

  • 输出x210 #;
  • 内部调用cread_line函数,此函数从securecrt中命令行中读取命令,并进行初步的处理;
  • ichar = getcmd_getch();这个函数是从串口中读取信息;如果读取到'\n'或者'\r'的话表示输入完成;
  • 之后的代码是处理键盘的特殊字符,详细解释见博客:http://blog.chinaunix.net/uid-30031530-id-5152127.html



(2)rc = run_command (lastcommand, flag)函数

  • 此函数进一步处理lastcommand中的字符串;
  • 调用process_macros函数,处理字符串中的转义字符;
  • 调用parse_line函数,统计argc、赋值argv;
  • 调用find_cmd命令查找相应命令返回命令的结构体指针;
  • (cmdtp->cmd) (cmdtp, flag, argc, argv)以函数指针的方式来执行命令函数;

命令的结构体


run_command函数




命令解释函数

  • 如parse_line函数把"md 30000000 10"解析成argv[0]=md,argv[1]=30000000,argv[2]=10;


命令查找函数

  • 本来可以把所有命令的结构体放在一个数组里或者一个链表里;
  • 但是uboot中用了一个新的方法,就是定义了一个专门的段来存放所有的命令结构体,这个段的起始地址和结束地址都放在连接脚本里。见下图:
  • 详细分析见博文http://blog.csdn.net/oqqhutu12345678/article/details/73251739




总结:uboot实现命令管理的思路

(1)填充1个结构体实例构成一个命令;

(2)给命令结构体实例附加特定段属性(用户自定义段),链接时将带有该段属性的内容链接在一起排列

  • 命令结构体彼此紧挨着,不会夹杂其他东西,也不会遗漏带有这种段属性的实例,但它们是乱序的;
  • 其实就是命令结构体的集合,有点像一个命令结构体数组。
(3)uboot重定位时将该段整体加载到DDR中。

(4)段起始地址和结束地址(定义在u-boot.lds中)决定了这些命令集的开始和结束地址。



附:

一、uboot中增加自定义命令

1、在已有的c文件中直接添加命令

(1)比如在uboot/common/command.c中添加一个命令,叫:mycmd。

(2)在已有的.c文件中添加命令比较简单,直接使用U_BOOT_CMD宏即可添加命令,给命令提供一个do_xxx的对应的函数。

(3)添加完成后要重新编译工程(make distclean; make x210_sd_config; make),然后烧录新的uboot去运行即可体验新命令。

(4)还可以在函数中使用argc和argv来验证传参。

2、自建一个c文件并添加命令

(1)在uboot/common目录下新建一个命令文件,叫cmd_xjh.c(对应的命令名就叫xjh,对应的函数就叫do_xjh函数),然后在c文件中使用U_BOOT_CMD宏,定义命令对应的函数。注意头文件包含不要漏掉。

(2)在uboot/common/Makefile中添加上xjh.o,目的是让Make在编译时把cmd_xjh.c编译链接进去。

(3)重新编译烧录。重新编译步骤是:make distclean; make x210_sd_config; make


二、creat_line函数

static int cread_line(const char *const prompt, char *buf, unsigned int *len)
{unsigned long num = 0;unsigned long eol_num = 0;unsigned long rlen;unsigned long wlen;char ichar;int insert = 1;int esc_len = 0;int rc = 0;char esc_save[8];while (1) {rlen = 1;
#ifdef CONFIG_BOOT_RETRY_TIMEwhile (!tstc()) {    /* while no incoming data */if (retry_time >= 0 && get_ticks() > endtime)return (-2);    /* timed out */}
#endifichar = getcmd_getch();if ((ichar == '\n') || (ichar == '\r')) {putc('\n');break;}/** handle standard linux xterm esc sequences for arrow key, etc.*/if (esc_len != 0) {if (esc_len == 1) {if (ichar == '[') {esc_save[esc_len] = ichar;esc_len = 2;} else {cread_add_str(esc_save, esc_len, insert,&num, &eol_num, buf, *len);esc_len = 0;}continue;}switch (ichar) {case 'D':    /* <- key */ichar = CTL_CH('b');esc_len = 0;break;case 'C':    /* -> key */ichar = CTL_CH('f');esc_len = 0;break;    /* pass off to ^F handler */case 'H':    /* Home key */ichar = CTL_CH('a');esc_len = 0;break;    /* pass off to ^A handler */case 'A':    /* up arrow */ichar = CTL_CH('p');esc_len = 0;break;    /* pass off to ^P handler */case 'B':    /* down arrow */ichar = CTL_CH('n');esc_len = 0;break;    /* pass off to ^N handler */default:esc_save[esc_len++] = ichar;cread_add_str(esc_save, esc_len, insert,&num, &eol_num, buf, *len);esc_len = 0;continue;}}switch (ichar) {case 0x1b:if (esc_len == 0) {esc_save[esc_len] = ichar;esc_len = 1;} else {puts("impossible condition #876\n");esc_len = 0;}break;case CTL_CH('a'):BEGINNING_OF_LINE();break;case CTL_CH('c'):    /* ^C - break */*buf = '\0';    /* discard input */return (-1);case CTL_CH('f'):if (num < eol_num) {getcmd_putch(buf[num]);num++;}break;case CTL_CH('b'):if (num) {getcmd_putch(CTL_BACKSPACE);num--;}break;case CTL_CH('d'):if (num < eol_num) {wlen = eol_num - num - 1;if (wlen) {memmove(&buf[num], &buf[num+1], wlen);putnstr(buf + num, wlen);}getcmd_putch(' ');do {getcmd_putch(CTL_BACKSPACE);} while (wlen--);eol_num--;}break;case CTL_CH('k'):ERASE_TO_EOL();break;case CTL_CH('e'):REFRESH_TO_EOL();break;case CTL_CH('o'):insert = !insert;break;case CTL_CH('x'):case CTL_CH('u'):BEGINNING_OF_LINE();ERASE_TO_EOL();break;case DEL:case DEL7:case 8:if (num) {wlen = eol_num - num;num--;memmove(&buf[num], &buf[num+1], wlen);getcmd_putch(CTL_BACKSPACE);putnstr(buf + num, wlen);getcmd_putch(' ');do {getcmd_putch(CTL_BACKSPACE);} while (wlen--);eol_num--;}break;case CTL_CH('p'):case CTL_CH('n'):{char * hline;esc_len = 0;if (ichar == CTL_CH('p'))hline = hist_prev();elsehline = hist_next();if (!hline) {getcmd_cbeep();continue;}/* nuke the current line *//* first, go home */BEGINNING_OF_LINE();/* erase to end of line */ERASE_TO_EOL();/* copy new line into place and display */strcpy(buf, hline);eol_num = strlen(buf);REFRESH_TO_EOL();continue;}
#ifdef CONFIG_AUTO_COMPLETEcase '\t': {int num2, col;/* do not autocomplete when in the middle */if (num < eol_num) {getcmd_cbeep();break;}buf[num] = '\0';col = strlen(prompt) + eol_num;num2 = num;if (cmd_auto_complete(prompt, buf, &num2, &col)) {col = num2 - num;num += col;eol_num += col;}break;}
#endifdefault:cread_add_char(ichar, insert, &num, &eol_num, buf, *len);break;}}*len = eol_num;buf[eol_num] = '\0';    /* lose the newline */if (buf[0] && buf[0] != CREAD_HIST_CHAR)cread_add_to_hist(buf);hist_cur = hist_add_idx;return (rc);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461659.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XMPP文件传输(XEP-0096协议说明)

XMPP XEP-0096协议是XMPP中的文件传输协议。 关于文件传输&#xff0c;在xmpp协议中有不少协议可以实现&#xff0c;而XEP-0096协议是其中非常简单的一个协议。由于邮件被删&#xff0c;我的代码demo丢失&#xff0c;因此只能在这里给大家讲一下其中的逻辑实现&#xff0…

uboot源码——环境变量

以下内容源于朱有鹏嵌入式课程的学习&#xff0c;如有侵权&#xff0c;请告知删除。 参考资料&#xff1a;http://www.cnblogs.com/biaohc/p/6398515.html。 一、uboot的环境变量基础 1、环境变量的作用 在不改变源码、不用重新编译的情况下&#xff0c;可以通过设置环境变量…

Linq To Sql进阶系列 -目录导航

博客园CLR基础研究团队|CLR团队精品系列|C# 3.0专题 [Linq To Sql进阶系列] 目录导航 1 Linq To Sql进阶系列&#xff08;一&#xff09;-从映射讲起 本系列&#xff0c;或多或少&#xff0c;直接或间接依赖入门系列知识。但&#xff0c;依然追求独立成章。因本文作者水平有限&…

uboot源码——mmc驱动分析

以下内容源于朱有鹏《物联网大讲坛》课程的学习&#xff0c;以及博客http://www.cnblogs.com/biaohc/p/6409197.html的学习整理&#xff0c;如有侵权&#xff0c;请告知删除。 一、uboot与linux驱动 1、uboot是裸机程序 狭义的驱动的概念&#xff1a;操作系统中用来具体操控硬…

RDIFramework.NET(.NET快速开发框架) 答客户问(2014-02-23)

1、框架的部署安装&#xff0c;服务器端和客户端 答&#xff1a;开发版以上版本支持SOA模式&#xff0c;也即真正的面向服务端的模式&#xff0c;在实际使用过程中&#xff0c;可根据项目的实际需要&#xff0c;来选择性的进行部署&#xff08;直连模式或SOA模式&#xff09;&a…

I2C通信——I2C通信的基础介绍

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除 。 参考博客 SPI、I2C、UART&#xff08;即串口&#xff09;三种串行总线详解_天糊土的博客-CSDN博客_串口总线 s5pv210 I2C通信详解 - biaohc - 博客园 嵌入式常用技术概览之IIC(I2C)_C_XianRen的博…

IBM SOA[ESB,BPM,Portal等]基础架构图解

最近公司对众多的异构系统进行SOA化&#xff0c;产品选型为IBM的Websphere系列产品的WMB&#xff0c;BPM&#xff0c;Portal&#xff0c;LDAP等技术&#xff0c;根据具体的描述&#xff0c;连猜带蒙的画了个系统协作图&#xff0c;有不对的地方欢迎大家拍砖....谢谢。 SOA详细技…

css3图标悬停导航菜单

纯css3制作的图标悬停导航菜单&#xff0c;包含9中不同的悬停风格&#xff0c;干净大气。转载于:https://blog.51cto.com/jimanyu/1362823

I2C通信——S5PV210的I2C通信简单案例

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考内容 I2C子系统详解3——I2C总线驱动层代码分析_天糊土的博客-CSDN博客 一、S5PV210的I2C控制器 1、为什么需要控制器&#xff1f; 通信双方通过时序协调工作&#xff0c;但是时序比较复杂而…

POJ 2718

题意&#xff1a;给出最多10个数字&#xff0c;将它们划分为两个整数&#xff0c;求差异值最小的值&#xff08;除非只有一位数&#xff0c;否则不允许出现先导0&#xff09; 题解&#xff1a;很显然如果总共有n个数&#xff0c;必然有一个整数长n/2,另一个长n-n/2&#xff0c;…

HDUOJ---1879 继续畅通工程

继续畅通工程 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11473 Accepted Submission(s): 5026 Problem Description省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通&#xff08;但不一…

动态载入树 (ASP+数据库)

ASPACCESS 在数据量达100万条记录下&#xff0c;载入速度仍然惊人.... // 网上转载. 忘了作者... : ) //********************** Index.asp ************************// 1<%LANGUAGE"VBSCRIPT"CODEPAGE"936"%>2<%OptionExplicit%>3<htm…

ADC——S5PV210的ADC的理论与操作

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 s5pv210 AD转换 - biaohc - 博客园 一、ADC的相关概念 1、量程&#xff08;模拟量的输入范围&#xff09; ADC只能输入电压信号&#xff0c;其他种类的模拟信号要经过传感器的转换&#x…

【洛谷 2661】信息传递

题目描述 有 nn 个同学&#xff08;编号为 11 到 nn &#xff09;正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象&#xff0c;其中&#xff0c;编号为 ii 的同学的信息传递对象是编号为 T_iTi​ 的同学。 游戏开始时&#xff0c;每人都只知道自己的生日。之…

kernel移植——从三星官方内核开始移植

以下内容源于朱有鹏嵌入式课程的学习&#xff0c;如有侵权&#xff0c;请告知删除。 一、内核移植初体验 1、获取三星官方的内核源码包 三星SMDKV210开发板附带的光盘里有内核源码包&#xff1a;下载地址。 2、构建移植环境 &#xff08;1&#xff09;Windows下建立SI工程&…

Android中实时视频传输(摄像头实时视频传输)解决方案二

为什么80%的码农都做不了架构师&#xff1f;>>> 1、使用FFMpeg进行视频采集&#xff0c;使用Live555进行RTP传输&#xff0c;使用VideoView进行播放。 csdn提到&#xff1a;重载FrameSource&#xff0c;写一个服务类&#xff0c;可以从FrameSource的派生类读取帧数…

定时器——S5PV210定时器的理论与操作

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、定时器简介 1、定时器的含义 定时器作为SoC的外设&#xff0c;主要用来实现定时执行代码的功能&#xff0c;它相对SoC而言&#xff0c;就像闹钟相对于人的意义一样。定时器内部的计数器每隔一个…

uboot的移植——DM9000移植的理论基础

以下内容源于朱有鹏嵌入式课程的学习&#xff0c;如有侵权请告知删除。 一、网卡相关的基本知识 1、DM9000网卡芯片和SoC的连接 如上图所示&#xff0c;DM9000网卡芯片是通过SROM总线接口&#xff0c;或者说SROM控制器接入SoC的。下面分别介绍SROM控制器、DM9000网卡芯片的相关…

javascript深入浅出

第一章 数据类型 1&#xff0c;六种数据类型&#xff1a;原始类型&#xff08;number&#xff0c;string&#xff0c;boolean&#xff0c;null&#xff0c;undefined&#xff09; object对象&#xff08;Function Array Date&#xff09; 2&#xff0c;隐式转换&#xff1a;Na…

网络通信基础常识

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 1、网络通信属于进程间通信 进程间通信的一种方法是使用套接字socket&#xff0c;网络通信其实就是位于网络中不同主机上面的2个进程之间的通信。 2、网络通信的层次 网络通信的层次&#xff0c;即…