linux 自定义组合按键进入uboot 命令行模式

本文介绍如何在U-Boot中通过修改代码实现稳定的组合键启动方式,避免因环境干扰导致的误操作,确保嵌入式系统的可靠启动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

  uboot源代码中是只要串口中输入任意的字符uboot就进入命令模式。在嵌入式设备中,这是个不太稳定的方式。嵌入式设备一般使用的环境比较复杂,所受的干扰了比较大,系统启动的时候串口易受到干扰而导致误触发输入字符,这样设备就进入了uboot的命令行模式,最终导致系统不能自动启动。为了降低这种干扰,软件端可以设置uboot组合按键进入uboot,这样误触发的概率就降低了。

    如果要设置组合按键,需要修改的是/common/main.c 文件。函数原型如下:

abortboot 源函数

static __inline__ int abortboot(int bootdelay)
{
	int abort = 0;

#ifdef CONFIG_MENUPROMPT
	printf(CONFIG_MENUPROMPT);
#else
	printf("Hit any key to stop autoboot: %2d ", bootdelay);
#endif


#if defined CONFIG_ZERO_BOOTDELAY_CHECK
	/*
	 * Check if key already pressed
	 * Don't check if bootdelay < 0
	 */
	if (bootdelay >= 0) {
		if (tstc()) {	/* we got a key press	*/
			(void) getc();  /* consume input	*/
			puts ("\b\b\b 0");
			abort = 1;	/* don't auto boot	*/
		}
	}
#endif

	while ((bootdelay > 0) && (!abort)) {
		int i;

		--bootdelay;
	
		/* delay 100 * 10ms */
		for (i=0; !abort && i<100; ++i) {
			if (tstc()) {	/* we got a key press	*/
				abort  = 1;	/* don't auto boot	*/
				bootdelay = 0;	/* no more delay	*/
# ifdef CONFIG_MENUKEY
				menukey = getc();
# else
				(void) getc();  /* consume input	*/
# endif
				break;
			}
			udelay(10000);
		}

		printf("\b\b\b%2d ", bootdelay);
	}

	putc('\n');

#ifdef CONFIG_SILENT_CONSOLE
	if (abort)
		gd->flags &= ~GD_FLG_SILENT;
#endif

	return abort;
}

函数解析

    这里涉及到两个函数tstc()和getc()函数,他们的功能如下:

详细函数内容可以参看uboot文档:https://casper.berkeley.edu/svn/trunk/roach/sw/uboot/doc/README.console

如果要修改成CTRL+C/c uboot 才进入命令模式,可以按下面这种方式修改:

修改后的abortboot函数

static __inline__ int abortboot(int bootdelay)
{
	int abort = 0;
	unsigned long ts;

#ifdef CONFIG_MENUPROMPT
	printf(CONFIG_MENUPROMPT);
#else
	//printf("Hit any key to stop autoboot: %2d ", bootdelay);
	printf("Press 'ctrl+C/c' to stop autoboot: %2d ", bootdelay);
#endif

#if 0
#if defined CONFIG_ZERO_BOOTDELAY_CHECK
	/*
	 * Check if key already pressed
	 * Don't check if bootdelay < 0
	 */
	if (bootdelay >= 0) {
		if (tstc()) {	/* we got a key press	*/
			(void) getc();  /* consume input	*/
			puts ("\b\b\b 0");
			abort = 1;	/* don't auto boot	*/
		}
	}
#endif
#endif
	while ((bootdelay > 0) && (!abort)) {
		int i;

		--bootdelay;
#if 0	
		/* delay 100 * 10ms */
		for (i=0; !abort && i<100; ++i) {
			if (tstc()) {	/* we got a key press	*/
				abort  = 1;	/* don't auto boot	*/
				bootdelay = 0;	/* no more delay	*/
# ifdef CONFIG_MENUKEY
				menukey = getc();
# else
				(void) getc();  /* consume input	*/
# endif
				break;
			}
			udelay(10000);
		}
#else
        /* delay 1000 ms */
        ts = get_timer(0);
        do {
            if (tstc()) {   /* we got a key press   */
                if(0x03 == getc()){                   
                    abort  = 1;     /* don't auto boot      */
                    bootdelay = 0;  /* no more delay        */

# ifdef CONFIG_MENUKEY
                    menukey = getc();
# else
                    (void) getc();  /* consume input        */
# endif
                    break;
                    }
                }
                udelay(10000);
        } while (!abort && get_timer(ts) < 1000);

#endif
		printf("\b\b\b%2d ", bootdelay);
	}

	putc('\n');

#ifdef CONFIG_SILENT_CONSOLE
	if (abort)
		gd->flags &= ~GD_FLG_SILENT;
#endif

	return abort;
}

    我使用#if 0 来区分源码和修改后的代码。这里需要注意下面这几行代码:

                if(0x03 == getc()){                   
                    abort  = 1;     /* don't auto boot      */
                    bootdelay = 0;  /* no more delay        */

# ifdef CONFIG_MENUKEY
                    menukey = getc();
# else
                    (void) getc();  /* consume input        */
# endif
                    break;
                    }
                }

    CTRL+C的ASCII控制符是03,所以直接用了if(0x03 == getc())来判断是否有输入CTRL+C 组合按键。下面是部分ASCII控制码对照表,可以根据自己的需求设置不同的组合按键。

ASCII控制对照表

十进制十六进制控制字符转义字符说明Ctrl + 下列字母
000NUL\0Null character(空字符)@
101SOHStart of Header(标题开始)A
202STXStart of Text(正文开始)B
303ETXEnd of Text(正文结束)C
404EOTEnd of Transmission(传输结束)D
505ENQEnquiry(请求)E
606ACKAcknowledgment(收到通知/响应)F
707BEL\aBell(响铃)G
808BS\bBackspace(退格)H
909HT\tHorizontal Tab(水平制表符)I
100ALF\nLine feed(换行键)J
110BVT\vVertical Tab(垂直制表符)K
120CFF\fForm feed(换页键)L
130DCR\rCarriage return(回车键)M
140ESOShift Out(不用切换)N
150FSIShift In(启用切换)O
1610DLEData Link Escape(数据链路转义)P
1711DC1Device Control 1(设备控制1) /XON(Transmit On)Q
1812DC2Device Control 2(设备控制2)R
1913DC3Device Control 3(设备控制3) /XOFF(Transmit Off)S
2014DC4Device Control 4(设备控制4)T
2115NAKNegative Acknowledgement(拒绝接收/无响应)U
2216SYNSynchronous Idle(同步空闲)V
2317ETBEnd of Trans the Block(传输块结束)W
2418CANCancel(取消)X
2519EMEnd of Medium(已到介质末端/介质存储已满)Y
261ASUBSubstitute(替补/替换)Z
271BESC\eEscape(溢出/逃离/取消)[
281CFSFile Separator(文件分割符)\
291DGSGroup Separator(分组符)]
301ERSRecord Separator(记录分隔符)^
311FUSUnit Separator(单元分隔符)_
3220SPWhite space[Space]
1277FDELDelete(删除)?

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li_wen01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值