当前位置: 首页 > news >正文

uboot自定义命令

uboot自定义命令

  U-Boot 是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括PPC、ARM、AVR32、MIPS、x86、68k、Nios与MicroBlaze。这也是一套在GNU通用公共许可证之下发布的自由软件。
  U-Boot本质是一个裸机程序,是一种普遍用于嵌入式系统中的开源的Bootloader,作用是用来引导操作系统,以及给开发人员提供测试调试工具。主要负责基本硬件初始化,导启动内核启动。
  U-Boot命令众多,通过uboot命令可完成系统环境变量设置。U-Boot本质就是一份裸机程序,这样可以在U-Boot命令下调试一些硬件设备问题。U-Boot命令行也是可以实现自动补全功能。

1.uboot命令格式分析

  uboot命令存放在uboot目录下的common目录下。
  do_help命令功能实现如下:

extern cmd_tbl_t  __u_boot_cmd_bdinfo;
extern cmd_tbl_t  __u_boot_cmd_showvar;

int do_help(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
//	return _do_help(&__u_boot_cmd_start,
//			&__u_boot_cmd_end - &__u_boot_cmd_start,
//			cmdtp, flag, argc, argv);
	return _do_help(&__u_boot_cmd_bdinfo,
			&__u_boot_cmd_showvar - &__u_boot_cmd_bdinfo + 1,
			cmdtp, flag, argc, argv);
}

U_BOOT_CMD(
	help,	CONFIG_SYS_MAXARGS,	1,	do_help,
	"print command description/usage",
	"\n"
	"	- print brief description of all commands\n"
	"help command ...\n"
	"	- print detailed usage of 'command'"
);

/* This does not use the U_BOOT_CMD macro as ? can't be used in symbol names */
cmd_tbl_t __u_boot_cmd_question_mark Struct_Section = {
	"?",	CONFIG_SYS_MAXARGS,	1,	do_help,
	"alias for 'help'",
#ifdef  CONFIG_SYS_LONGHELP
	""
#endif /* CONFIG_SYS_LONGHELP */
};

U_BOOT_CMD为命令参数传递:
  help 命令标志符;
  CONFIG_SYS_MAXARGS命令传递的最大参数个数;
  1命令重复执行次数;
  do_help命令实现函数;
  “alias for ‘help’”命令用法说明;
  最后一个参数为命令用法详细说明;
int do_help(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])函数参数说明:
  cmd_tbl_t * cmdtp结构体指针。

struct cmd_tbl_s {
	char		*name;		/* 命令名字*/
	int		maxargs;	/*命令传递的最大参数个数*/
	int		repeatable;	/*命令重复执行次数*/
	/*命令功能实现函数*/
	int		(*cmd)(struct cmd_tbl_s *, int, int, char * const []);
	char		*usage;		/*命令基本用法说明*/
#ifdef	CONFIG_SYS_LONGHELP
	char		*help;		/*命令详细用法说明*/
#endif
#ifdef CONFIG_AUTO_COMPLETE
	/* do auto completion on the arguments */
	int		(*complete)(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]);
#endif
};

  argc 命令传入的参数个数,和main函数argc相同;
  argv 存放命令参数内容,和main函数argv相同;

2.tiny4412下编写uboot命令控制蜂鸣器

2.1 tiny4412开发板beep硬件接口

在这里插入图片描述
在这里插入图片描述

2.2 GPD0端口寄存器地址

在这里插入图片描述
  配置寄存器:GPD0CON_ADDR = 0x1140_0000 + 0x00A0
在这里插入图片描述
  数据寄存器:GPD0DAT_ADDR = 0x1140_0000 + 0x00A4

2.3 参考help命令模板实现beep命令

#include <common.h>
#include <command.h>

/*蜂鸣器*/
#define GPD0_CON *((volatile unsigned int *)0x114000A0)//控制寄存器
#define GPD0_DAT *((volatile unsigned int *)0x114000A4)//数据寄存器

int do_beep(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	/*蜂鸣器*/
	GPD0_CON&=0xfffffff0;//清除当前GPD0_0的配置
	GPD0_CON|=0x00000001;//设置为输出模式
	//beep on 或者 beep off
	if(argc!=2)
	{
		printf("格式:beep on/off\n");
		return 0;
	}
	if(strcmp(argv[1],"on")==0)//开蜂鸣器
	{
		GPD0_DAT|=1<<0;//开蜂鸣器
	}
	else if(strcmp(argv[1],"off")==0)//关蜂鸣器
	{
		GPD0_DAT&=~(1<<0);//关蜂鸣器
	}	
	return 0;
}

U_BOOT_CMD(
	beep,	CONFIG_SYS_MAXARGS,	1,	do_beep,
	"beep <on/off>",
	"\n"
	"beep用法\n"
	"开蜂鸣器:beep on\n"
	"关蜂鸣器:beep_off"
);

2.4 程序编译

  1. 将cmd_beep.c拷贝到u_boot目录下的common目录下

[wbyq@wbyq common]$ cp /mnt/hgfs/ubuntu/cmd_beep.c ./ 

  2. 修改common目录下的Makefile文件。

[wbyq@wbyq common]$ vim  Makefile 

在这里插入图片描述
  3.在uoot顶层目录下执行make,重新编译uboot

[wbyq@wbyq uboot_tiny4412-sdk1506]$ make

  4.烧写uboot

[wbyq@wbyq uboot_tiny4412-sdk1506]$ cd sd_fuse/
[wbyq@wbyq tiny4412]$ sudo ./sd_fusing.sh /dev/sdb

  beep命令编写成功。
在这里插入图片描述
  5. beep命令运行测试

TINY4412 # beep
格式:beep on/off
TINY4412 # ? beep
flag=0
beep - beep <on/off>

Usage:
beep 
beep用法
开蜂鸣器:beep on
关蜂鸣器:beep_off
TINY4412 # beep on
TINY4412 # beep off

3.分析uboot保存环境变量位置

  在Linux操作系统启动前,uboot需要完成系统环境变量配置。在uboot目录下有tiny4412.h中保存的系统的默认环境变量参数。
在这里插入图片描述
  1.当我们修改了系统环境变量,执行了saveenv命令后,则环境变量将写入到磁盘中,接下来我们将分析一下uboot源码中环境变量写入磁盘的扇区位置。
  在uboot命令中,并没有直接脚cmd_save.c的函数,因此,我们可以根据saveenv命令执行后的提示信息来分析。在uboot命令行下执行saveenv命令时,会看到有输出提示信息,这样我们可以直接在uboot工程中搜索一下输出信息的位置。

TINY4412 # save
Saving Environment to SMDK bootable device...
done

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  2.接下来跳入saveenv函数,查看一下该函数执行过程。
在这里插入图片描述

  当我们跳到定义处时会看到有多重位置,要想准确跳转到正确位置,我们可以再查找参考saveenv命令的后半段提示信息赋值位置。
在这里插入图片描述
在这里插入图片描述
  3.经过查找参考我们发现,后半段提示信息的定义位置是在env_auto.c中,而我们saveenv函数右键跳到定义处时在env_auto.c中也有定义,说明我们要跳转的文件即为env_atuo.c文件。
  在 saveenv函数中,并没有看到有关于mmc写扇区的函数,说明我们还需要进一步跳转到对应的子函数中去分析。
在这里插入图片描述
  4.我们可以再次根据saveenv命令的打印提示,在最后还会打印“done”这个信息,这样我们就可以更新这个信息,对当前函数中的三个子函数进行分析,看下哪一个子函数中有这个字符串的打印。经过查看代码可知最终调用的函数即为saveenv_movinand()函数。
在这里插入图片描述
  5.再次跳到movi_write_env()函数中查看一下写入到mmc中的地址。
在这里插入图片描述
在这里插入图片描述
  6.在这个函数中即为实现环境变量写入作用,再次跳到movi_write()函数中查看一下这个函数参数作用。
在这里插入图片描述
  可以看到,movi_write()函数参数作用分别为:mmc设备编号、写入mmc的起始扇区、写入的扇区个数、写入的环境变量内容。
  我们可以在这个函数中加入printf函数打印一下写入的扇区地址和扇区数量。然后再重新编译uboot,烧写到SD卡中再次启动查看效果。

TINY4412 # save
Saving Environment to SMDK bootable device...
start=1025,blkcnt=32
done
TINY4412 # 

  重新执行save命令,可以看到环境变量写入的起始位置为第1025个扇区,连续写入了32个扇区。至此,环境变量的写入扇区位置分析完毕。

4.清除mmc中保存的环境变量

  要清除已经写入的环境变量,我们只需要将mmc中第1025个扇区的数据破坏掉即可。

4.1 通过命令清空环境变量

  我们可以使用mmc命令,写入一段无效数据到第1025个扇区中即可。

TINY4412 # mmc write 0 40008000 401 32
MMC write: dev # 0, block # 1025, count 50 ... 50 blocks written: OK

  将40008000地址中的内容写入到设备0的第1025个扇区,连续写32个扇区。

4.2 编写环境变量清空命令

#include <common.h>
#include <command.h>
#include <mmc.h>

int do_clenenv(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	mmc_init(find_mmc_device(0));/*mmc初始化*/
    movi_write_env(virt_to_phys((ulong)0x40008000));/*写入环境变量*/
	return 0;
}

U_BOOT_CMD(
	cleanenv,	CONFIG_SYS_MAXARGS,	1,	do_clenenv,
	"clean 清空系统环境变量",
	"\n"
	"clean用法:clean\n"
	"清空环境变量"
);

相关文章:

  • 数据库Day004
  • [JavaWeb学习] tomcat简介、安装及项目部署
  • json-c 理解记录
  • 实践分享!GitLab CI/CD 快速入门
  • LabVIEW中的数据通信方法
  • 排序链表,
  • ESP32-arduino,超好玩的定时器!
  • Python selenium 页面滚动
  • 【FPGA教程案例69】硬件开发板调试9——通过ila在线调试DDS,并通过HDMI接口在显示器上显示正弦波形
  • MeterSphere专题之: 配套的浏览器插件:chrome-extensions
  • 【FPGA教程案例70】硬件开发板调试10——vivado程序固化详细操作步骤
  • 计算机毕业设计ssm青年志愿者社团管理36uiu系统+程序+源码+lw+远程部署
  • 数据结构————树
  • 【操作系统】 第二章 —— 系统调用 中断 异常
  • 移动端测试
  • Google 是如何开发 Web 框架的
  • [译]CSS 居中(Center)方法大合集
  • 《Java编程思想》读书笔记-对象导论
  • CODING 缺陷管理功能正式开始公测
  • django开发-定时任务的使用
  • EOS是什么
  • iOS编译提示和导航提示
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • MD5加密原理解析及OC版原理实现
  • Netty源码解析1-Buffer
  • Rancher-k8s加速安装文档
  • Sublime text 3 3103 注册码
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • win10下安装mysql5.7
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 搭建gitbook 和 访问权限认证
  • 坑!为什么View.startAnimation不起作用?
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 使用parted解决大于2T的磁盘分区
  • 微信小程序:实现悬浮返回和分享按钮
  • 我感觉这是史上最牛的防sql注入方法类
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • ​虚拟化系列介绍(十)
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #if 1...#endif
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (离散数学)逻辑连接词
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (全注解开发)学习Spring-MVC的第三天
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)iOS字体
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • ***利用Ms05002溢出找“肉鸡
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET Core 中的路径问题
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)