社区首页
技术讨论创新帖
全部新帖
资料区
社区活动
联系管理员
★ 社区积分制度
★ 新手必读
★ 申请版主★
请
登录
后使用快捷导航
没有帐号?
注册
首页
|
电子技术
|
嵌入式
模拟电子
单片机
电源管理
传感器
半导体
电子应用
|
工业控制
物联网
汽车电子
网络通信
医疗电子
手机便携
测试测量
安防电子
家用电子
机器人
新能源
电子头条
|
社区
|
论坛
测评
博客
大学堂
|
下载
|
下载中心
电路图
精品文集
电路图
|
参考设计
|
Datasheet
|
活动
|
直播
datasheet
datasheet
文章
搜索
登录
注册
中文
En
论坛
切换旧版
电子工程世界-论坛
»
论坛
›
电子技术交流
›
国产芯片交流
›
飞凌全志T527开发板U-Boot添加自定义菜单
返回列表
发新帖
回复
阅
504
|
回
1
aleksib
当前离线
纯净的硅(中级)
最后登录
2025-1-6
在线时间
40 小时
威望
998分
芯积分
511分
(兑换)
E金币
0枚
(兑换)
(兑换)
好友
0
aleksib
287
帖子
0
TA的资源
纯净的硅(中级)
+ 好友
私信
楼主
发表于2024-7-15 09:46
只看该作者
飞凌全志T527开发板U-Boot添加自定义菜单
[复制链接]
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://bbs.aw-ol.com/assets/uploads/files/1719493229545-f45322ef-1664-412b-b7a3-65855d79ebc2-8f951346f411a737513456c04543703-resized.jpg) 有趣的是,板子上电,按任意键进入U-Boot会自动列出一个功能菜单,有切换屏幕等功能: ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://bbs.aw-ol.com/assets/uploads/files/1719493617420-6b76d7f1-f33c-4d7c-8dc0-3d751d5fc0cd-image.png) 基于此,本文将分析如何在U-Boot添加自定义菜单。 **一、实验环境介绍** 硬件:飞凌OK-T527开发板 软件:全志Longan SDK(U-Boot版本2018) 说明:本次实验不限制平台,请参考实际情况阅读。 **二、目标** 本文主要分析U-Boot在程序中的执行顺序,又如何在U-Boot阶段调起菜单?相信大家都试过,在U-Boot倒数结束前按任意按键后,会进入U-Boot命令行模式。 这里先留一个问题:如何做到按键按下后,调启的是自己的U-Boot菜单,而不再是进入命令行模式? **三、U-Boot如何自动调起菜单** U-Boot的入口程序文件是 **
/common/main.c**,入口函数**main_loop()**: ``` /*
/common/main.c */ ... /* We come here after U-Boot is initialised and ready to process commands */ /* 在U-Boot初始化并准备好处理命令之后,我们来到这里。 */ void main_loop(void) { const char *s; bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); #ifdef CONFIG_VERSION_VARIABLE env_set("ver", version_string);/* set version variable */ #endif /* CONFIG_VERSION_VARIABLE */ cli_init(); //命令初始化有关,初始化 hush shell 相关的变量 run_preboot_environment_command(); //获取环境变量 perboot 的内容 #if defined(CONFIG_UPDATE_TFTP) update_tftp(0UL, NULL, NULL); #endif /* CONFIG_UPDATE_TFTP */ s = bootdelay_process(); //此函数会读取环境变量 bootdelay 和 bootcmd 的内容 if (cli_process_fdt(&s)) cli_secure_boot_cmd(s); autoboot_command(s); //开启倒计时,并在倒计时结束前检测是否有按键按下 cli_loop(); //命令行处理函数(即进入U-Boot命令行) panic("No CLI available"); } ``` 关键函数是**autoboot_command()**,该函数的实现在 **
/common/autoboot.c**: ``` /*
/common/autoboot.c */ ... void autoboot_command(const char *s) { debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "
"); if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { // 倒计时过程中,没有按键按下 #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) int prev = disable_ctrlc(1); /* disable Control C checking */ #endif run_command_list(s, -1, 0); // 倒计时结束后,启动内核 #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) disable_ctrlc(prev); /* restore Control C checking */ #endif } #ifdef CONFIG_MENUKEY if (menukey == CONFIG_MENUKEY) { s = env_get("menucmd"); if (s) run_command_list(s, -1, 0); } #endif /* CONFIG_MENUKEY */ } ``` 进入 **autoboot_command()** 后,先看第一个if: ``` void autoboot_command(const char *s) { ... if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) ... } ``` 这里有三个条件: ● **stored_bootdelay != -1**:stored_bootdelay是倒数的总时间,就是常见的3秒、5秒不等; ● **s**:传进来的参数s不能为空; ● **!abortboot(stored_bootdelay)**:该函数会从stored_bootdelay开始倒计时,期间判断是否有按键按下。函数实现如下,倒计时过程中若检测到按键按下,则令abort=1。无按键按下,则abort=0。最后返回abort。 ``` /*
/common/autoboot.c */ ... static 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); #endif /* * Check if key already pressed */ if (tstc()) { /* we got a key press */ (void) getc();/* consume input */ puts("\b\b\b 0"); abort = 1; /* don't auto boot */ } while ((bootdelay > 0) && (!abort)) { --bootdelay; /* delay 1000 ms */ ts = get_timer(0); do { 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); } while (!abort && get_timer(ts) < 1000); printf("\b\b\b%2d ", bootdelay); } putc('\n'); return abort; } ... ``` 刚刚说了,**abortboot()** 函数执行期间有按键按下的话,**abortboot()** 会返回1,那就不会进入第一个if,程序会接着往下运行直至该函数运行结束。**autoboot_command()** 结束后继续返回到**main_loop()**,随后立刻执行**cli_loop()**,进入我们所熟悉的U-Boot命令行模式。 ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://bbs.aw-ol.com/assets/uploads/files/1719495045144-7c739c2a-c80b-4925-b5fc-951173f5fb78-image.png) 至此,就实现了U-Boot倒数期间,有按键按下,则进入U-Boot的命令行模式。 现在继续回到第一个if: ``` /*
/common/autoboot.c */ void autoboot_command(const char *s) { ... if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { // 倒计时过程中,没有按键按下 #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) int prev = disable_ctrlc(1); /* disable Control C checking */ #endif run_command_list(s, -1, 0); // 倒计时结束后,启动内核 #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) disable_ctrlc(prev); /* restore Control C checking */ #endif } ... } ``` 如果在autoboot倒计时结束前,一直没有按键按下呢?那 **abortboot()** 最后会返回0,第一个if的三个条件全部满足。进入if,**run_command_list()** 执行一系列命令后,启动内核。注意,这里的现象是直接启动内核,**run_command_list()** 后的程序不再执行。 解析到这里,我们得出一个结论:在autoboot倒计时中,如果有按键按下的话,会进入U-Boot的命令行模式。无按键按下则在倒计时结束后直接启动内核。 那现在可以回答第一个问题,如何做到按下按键后,是自启动U-Boot菜单,而不是进入U-Boot命令行呢?答案是在执行cli_loop()之前,我们可以在autoboot检测到按键按下后,调用run_command()函数执行menu命令,从而调起菜单。 ``` void autoboot_command(const char *s) { debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "
"); if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) int prev = disable_ctrlc(1); /* disable Control C checking */ #endif run_command_list(s, -1, 0); #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) disable_ctrlc(prev); /* restore Control C checking */ #endif } //在此处启动菜单 run_command("menu", 0); #ifdef CONFIG_MENUKEY if (menukey == CONFIG_MENUKEY) { s = env_get("menucmd"); if (s) run_command_list(s, -1, 0); } #endif /* CONFIG_MENUKEY */ } ``` **四、U-Boot添加自定义命令** 难道通过 **run_command()** 执行menu命令后,菜单就自己出来了?这是一个理所当然的猜想。实际上U-Boot根本不认识menu命令: ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://bbs.aw-ol.com/assets/uploads/files/1719495382061-609ad0a8-dbdb-4e12-b3a0-7d5886c4c9f0-image.png) 接下来看看如何添加U-Boot命令,参考一下别人的代码: ``` /*
/board/BuS/eb_cpu5282/eb_cpu5282.c */ int do_brightness(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rcode = 0; ulong side; ulong bright; switch (argc) { case 3: side = simple_strtoul(argv[1], NULL, 10); bright = simple_strtoul(argv[2], NULL, 10); if ((side >= 0) && (side <= 3) && (bright >= 0) && (bright <= 1000)) { vcxk_setbrightness(side, bright); rcode = 0; } else { printf("parameters out of range\n"); printf("Usage:\n%s\n", cmdtp->usage); rcode = 1; } break; default: printf("Usage:\n%s\n", cmdtp->usage); rcode = 1; break; } return rcode; } U_BOOT_CMD( bright, 3, 0, do_brightness, "here is uboot mymenu\n", "here is uboot mymenu, make in 2024-05-15\n" ); ``` 先看最底下的**U_BOOT_CMD**,这是一个宏,用来添加U-Boot命令: ``` /*
/include/command.h */ #define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \ U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL) ``` ● **_name**:命令的名字 ● **_maxargs**:添加的命令最多有几个参数 ● **_rep**:是否重复(1重复,0不重复),指在U-Boot命令行按下Enter键的时候,重复执行上次的命令 ● **_cmd**:执行函数(即执行该命令后,运行哪个函数) ● **_usage**:短帮助信息 ● **_help**:长帮助信息 再来看看执行函数**do_brightness**的声名: ``` int (*cmd)(struct cmd_tbl_s *cmdtp, int flag, int argc, char *const argv[]); ``` ● **cmdtp**:Table entry describing the command (see above). ● **flag**:A bitmap which may contain the following bit ○ CMD_FLAG_REPEAT- The last command is repeated. ○ CMD_FLAG_BOOTD- The command is called by the bootd command. ○ CMD_FLAG_ENV - The command is called by the run command. ● **argc**:执行命令时,传入的参数数量 ● **argv**:传入的参数 **五、实践** 下面,添加一个U-Boot菜单,不过只作打印,没有实际功能。 在 **
/drivers** 下创建一个名为**mymenu**的文件夹: ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://bbs.aw-ol.com/assets/uploads/files/1719495902868-36675d20-81f2-4cdd-bca7-b96f7060954d-image.png) 在**mymenu**文件夹下创建**mymenu.c**,内容如下: ``` #include
#include
#include
#include
#include
static int do_mymenu(struct cmd_tbl_s *cmdtp, int flag, int argc, char *const argv[]) { printf("\n======== Title ========\n"); printf("== [1] xxxxxx\n"); printf("== [2] xxxxxx\n"); printf("== [3] xxxxxx\n"); printf("== [4] xxxxxx\n"); printf("=========================\n\n"); return 0; } U_BOOT_CMD( menu, 1, 1, do_mymenu, "here is uboot menu\n", "here is uboot menu, make in 2024-06-27\n" ); ``` 还需在**mymenu**文件夹下创建一个Makefile文件,内容如下: ``` obj-y += mymenu.o ``` 最后修改 **
/drivers/** 下的Makefile,在结尾加上如下内容,表示要编译mymenu路径下的文件: ``` ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),) obj-y += mymenu/ endif ``` ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://bbs.aw-ol.com/assets/uploads/files/1719496211586-a316bdca-70e6-4150-83dc-2003e98addd2-image.png) 编译U-Boot,更新U-Boot,重启单板,在U-Boot倒计时结束前,按任意按键就进入我们自定义的菜单: ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://bbs.aw-ol.com/assets/uploads/files/1719497489598-b1c26ea8-400f-4a58-8108-5f4939100cda-image.png) 剩下的菜单程序编写就是根据实际功能来开发了。
此帖出自
国产芯片交流论坛
最新回复
lugl4313820
分享了Uboot的编译,更新,感谢分享
详情
回复
发表于 2024-7-19 08:29
点赞
关注
(0)
回复
分享
扫一扫,分享给好友
复制链接分享
链接复制成功,分享给好友
举报
提升卡
变色卡
千斤顶
lugl4313820
lugl4313820
当前离线
版主
最后登录
2025-1-24
在线时间
171 小时
威望
12392分
芯积分
11149分
(兑换)
E金币
868枚
(兑换)
(兑换)
好友
25
7003
帖子
11
TA的资源
版主
+ 好友
私信
沙发
发表于2024-7-19 08:29
只看该作者
分享了Uboot的编译,更新,感谢分享
此帖出自
国产芯片交流论坛
回复
举报
返回列表
发新帖
回复
您需要登录后才可以回帖
登录
|
注册
发表回复
回帖后跳转到最后一页
活动
更多>>
有奖直播 | ADI 超低功耗 MCU MAX326xx 系列介绍
走近 AI 重磅新品 STM32N6,解锁在 MCU 部署高性能、节能型边缘 AI!答题有好礼~还有开发板等你拿!
Microchip 直播|多相降压电源控制技术的发展与探讨 报名中!
安世半导体智能工业应用探索站,闯关赢好礼!
24年年终盘点来啦!精选强推:原创、测评、拆解、视频、资料
PI 电源小课堂:集成式半桥驱动IC BridgeSwitch 2, 助力高效永磁同步电机逆变器的设计
Microchip喊你探索dsPIC33A 芯片,70份好礼等你赢!
【瓜分2500元红包】票选2024 DigiKey “感知万物,乐享生活”创意大赛人气作品TOP3!
开源项目
更多>>
LT1170HVIT、-28/5A 负升压稳压器的典型应用
LT6656BIS6-2.5、2.5V ADC 电压基准和桥式激励电源的典型应用
AM6TW-2424SH35Z 24V 6瓦双输出DC-DC转换器的典型应用
用于 FPGA 解决方案的 FX2LP MCU 开发系统
LTC3815IUFE 1.2V/6A 2MHz 降压稳压器的典型应用电路
LTC2992HMS 双向 30V 至 300V 高侧功率监视器的典型应用
NCP300LSN33T1 3.3V 窗口电压检测器的典型应用
使用 ROHM Semiconductor 的 BD4958 的参考设计
5V-12V|3.3V
LT8580 的典型应用 - 具有 1A、65V 开关、软启动和同步功能的升压/SEPIC/反相 DC/DC 转换器
随便看看
【RainbowLink USB 协议转换器】+12V升压带负载能力
12V他写的是800mA的电流输出,我带了一个微型的隔膜泵,12V电压的。测试其带负载还能工作吗。[attach]883888[/attach]实测,只要不是先给板子上电,在给泵上电,串口数据都是可以传输的,同时上电都是正常工作的状态。[attach]883889[/attach]这个升压他们通 ...
EEWorld邀你来拆解(18期)-----索尼打印模块拆解
【RainbowLink USB 协议转换器】+串口对串口进行MODBUS通信
uint16和unsigned int 的问题
wince ocx控件注册问题
U-BOOT下使用bootm引导内核方法
cc2530红外接收有没有大神知道的
EMI/EMC--原理与应对详解(一)
查找数据手册?
搜索
EEWorld Datasheet 技术支持
热门标签
源代码
单片机
放大器
TI
ST
电源
分立器件
传感器
测试测量
模拟
三相数字相位表
太阳能逆变器
可变电感器
施克传感器
标准热电偶
HLP-M变频器
层间绝缘
压电陶瓷
报警电路
射频卡
相关文章
更多>>
汇顶科技 2024 年业绩亮眼,展现强劲发展韧性
尽管今年芯片行业竞争异常激烈,但汇顶科技正在通过持续创新与多元化,实现了业绩大幅增长。根据其近日发布的 2024 年年度业绩预告表明,归属于母公司所有者的净利润却迎来了爆发式增长,预计在 55000
谷歌母公司:美国AI难保证对华领先 不少方面是落后
1月23日消息,美国对中国的芯片封锁现在看来是失败的,至少现实是这样。 谷歌母公司Alphabet总裁兼首席投资官鲁斯·波拉特(Ruth Porat)周二表示,在人工智能(AI)开发竞赛中,美国未必
消息称三星电子砍半晶圆代工部门 2025 年设备投资预算,陡降至 5 万亿韩元
1 月 23 日消息,韩媒 SEDaily 当地时间 21 日表示,根据三星电子晶圆代工业务制定的年度计划,该部门今年的设备投资预算将仅剩 5 万亿韩元(IT之家备注:当前约 253.55 亿元人民
史上最佳表现:SK 海力士 2024 年营业利润 23.5 万亿韩元
宇树发布“踢足球”机器人G1-Comp,网友:国足有救了
消息称iPhone 17 Air后置单摄像头 电池也小于另外3款
2025年,AI要大干特干:特朗普怒拼5000亿美元
日媒分析中国汽车零部件企业竞争力排行:比亚迪第一
三星电子否认重新设计 1b DRAM,力求提升性能和良率
韩国系统半导体市占率急剧下降!2027年将跌至1.6%
新帖速递
STM32和无源蜂鸣器播放声音的问题
车规级AECQ200介绍,混合铝电解电容器的选择
嵌入式教程_DSP技术_DSP实验箱操作教程:2-28 搭建轻量级WEB服务器实验
OPA847IDBVR运放器国产替代
AG32VF407测试UART
【得捷电子Follow Me第二期】第一章 收到货物的分享
请问这个红外接收头是什么型号?能用哪个型号代替?谢谢
出售全新未拆封ZYNQ 7Z020 FPGA核心板
用在锂电池供电的水表设置上的LORA模块,当有100块水表集中安装在一个楼道内时,节能
请问一下,当某个端口被设置为 RX0后,这个端口的输入输出方向还有必要设置吗
今年怎么这么难,比疫情时还难,三十了面临失业好迷茫
请教稳压管测试问题
【小华HC32F448测评】关于小华半导体的UART中断发送和PRINTF构造和重定向
【BIGTREETECH PI开发板】 HDMI输出测试
【BIGTREETECH PI开发板】+08.音频测试(zmj)
开发板申请:拥有 AI 加持的 STM32N6570-DK 免费试用 !
申请时间:即日起-3月2日
查看 »
安世半导体智能工业应用探索站,闯关赢好礼!
点击页面内“开始探索”按钮,填写并提交表单;
请根据序号依次完成3个安世半导体智能工业应用的探索,并根据给出的资料完成共计9题(每个应用3题),答对5题以上的玩家即可获得抽奖资格;
每人仅有一次参与答题的机会,请慎重作答,活动结束后,我们将抽取30位玩家赠送礼品。
查看 »
Microchip 直播|多相降压电源控制技术的发展与探讨 报名中!
直播主题:多相降压电源控制技术的发展与探讨
直播时间:2025年2月25日(星期二)上午10:30-11:30
快来报名!
查看 »
回帖赢好礼 | 关于无线技术的那些事儿
【活动时间】即日起—2025年1月31日
【活动好礼】50元京东卡
查看 »
答题赢好礼,PI电源小课堂第3期来啦!
本期内容:集成式半桥驱动IC BridgeSwitch 2, 助力高效永磁同步电机逆变器的设计
活动时间:即日起-2月28日
看视频答题即可赢取京东卡!
查看 »
Microchip喊你探索 dsPIC33A 芯片,70份好礼等你赢!
活动时间:即日起-1月26日
活动奖励:随身Wi-Fi、家用多功能电烤箱、20000mAh充电宝、50元京东卡
查看 »
DigiKey应用探索站重磅上线!潮流应用,硬核技术探秘,N多干货,一站get!
当月好物、热门技术资源、潮流应用技术、特色活动、DigiKey在线实用工具,干货多多~
查看 »
本周精选下载推荐:电源管理基础Dummies
本周小编给大家带来一本超简单、超干货的电子书——《电源管理基础Dummies》!内容深入浅出,排版舒服简洁,分分钟能get到电源管理最核心的知识内容。
查看 »
关闭
站长推荐
1
/8
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
电信业务审批[2006]字第258号函
京公网安备 11010802033920号
Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复
返回顶部
返回列表
论坛首页
版块列表
专业技术中心
TI技术论坛
ST传感器与低功耗无线技术论坛
ADI参考电路
DigiKey得捷技术专区
ADI · 世健工业技术
电子技术交流
边缘AI
嵌入式系统
单片机
国产芯片交流
电机控制
FPGA/CPLD
模拟电子
电源技术
无线连接
传感器
PCB设计
综合技术交流
下载中心专版
大学堂专版
测评中心专版
行业应用
汽车电子
机器人开发
工业自动化与控制
能源基础设施
医疗电子
消费电子
创意与实践
电子竞赛
DIY/开源硬件专区
淘e淘
创意市集
休息一下
聊聊、笑笑、闹闹
工作这点儿事
为我们提意见&公告
EEWorld颁奖专区
信息发布
最新帖子
最新帖子
最新回复
精华
消灭零回复
测评中心
活动中心
积分兑换
E金币兑换
芯积分
厂商专区
TI技术论坛
ST传感器与低功耗无线技术论坛