OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2259|回复: 1

uboot成功移植到STM32F103ZET6(二)

[复制链接]

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
12477
金钱
12477
注册时间
2015-11-5
在线时间
2140 小时
发表于 2019-12-18 18:36:35 | 显示全部楼层 |阅读模式
接上一贴:uboot成功移植到STM32F103ZET6(一)
http://www.openedv.com/forum.php ... 1&fromuid=42498
(出处: OpenEdv-开源电子网)

软件平台:IAR for ARM 7.70
硬件主板:浩宇电子STM32F103ZET6最小系统板
STM32库:HAL库
uboot版本:1.1.6
参考uboot代码:TQ2440开发板

上一篇文章我们讲到了移植需要准备的工程,并且最后分析了下uboot移植到STM32的目的和面临的问题。
这篇文章开始着手从源代码一步一步分析问题并给出本渣找到的解决方案。
接下来先分析board.c文件。

第一步:
uboot在第一阶段的末尾通过一条指令“ldr pc, _start_armboot”来跳转到start_armboot()函数,该函数在board.c实现。
先解决上篇文章最后提到的第一个问题,在start_armboot()启动时要先保存板级信息结构指针gd的值(gd_t结构体的起始物理地址),
计算原理是将重定位后的uboot映像起始地址减去堆空间大小再减去gd_t结构体大小即可,图示如下:
图片1.png
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
在上篇文章我们提及过,由于MDK或IAR已经帮我们完成了第一阶段的工作,因此本渣把
板级信息结构体指针gd直接以全局变量的方式定义了(board.c),并没有以通用寄存器R8来存放:
图片2.png
上篇文章提到的第二个问题,也与该指针相关。按照原设计uboot的全局变量空间是事先已经确定下来的,必须放在堆空间前面。
但是本渣并不希望把代码做重定向,否则仿真会失效!那怎么处理这个问题好呢?这个重要变量占据的内存其实并不大,也就36个字节,
完全可以在单片机内定义。本渣为了不新建多余的全局变量,直接在堆里面申请了,包括bd结构体的内存空间也一并搞定!
图片3.png
这里可能有人会杠,认为内存堆初始化在gd初始化后面才调用,因此不能用malloc来为gd申请内存堆空间。没错,原设计的确是内存堆
初始化在后,不过别忘了我们现在移植的平台是IAR或MDK,可以直接使用C库的内存堆管理,uboot的内存堆初始化可以直接注释掉:
图片4.png


第二步:
在全局变量gd初始化完毕后,接下来是调用各个后台初始化相关函数:
图片5.png
uboot把所有初始化相关函数统一存放到函数指针数组init_sequence
TQ2440需要初始化CPU、中断、SDRAM等,但是在STM32上暂时用不上,所以本渣屏蔽了没用的初始化函数。
图片6.png
本渣觉得在board_init里初始化一些后续用到的底层硬件比较合理,因此把NOR Flash初始化放这里面来了:
图片7.png


第三步:
接下来是比较重要的几个初始化,第一个是环境变量的重定位(含初始化),第二个是设备列表初始化(目前只有控制台用到),
第三个是控制台初始化。至于USB初始化,本渣目前还没移植USB的库,后续再补上。
图片8.png
环境变量和控制台涉及的内容太多,这两个就放到后续再详细讲。
我们可以看到start_armboot()在执行完一堆初始化之后,最终是跳到main_loop()来循环执行。


第四步:
接下来分析main_loop.c文件(在uboot里是main.c,为了避免冲突本渣斗胆改文件名了)。分析main_loop()的源码可知,首先从环境变量
里获取bootdelay的值,这是主板上电后的倒计时数值(单位:秒)。如果在倒计时内用户按下了空格键,则会判断是否从NOR Flash启动,
如果是则进入到某个菜单选项,否则直接启动Linux。由于我们用不到Linux,所以本渣屏蔽了相关的功能,只保留了菜单选项。
TQ2440开发板在这个菜单里面提供了修改一些系统参数的功能,本渣目前还没需要修改什么参数,后续有需要的话再修改这个菜单吧:
图片9.png
run_command()是uboot人机交互的核心组成,接下来就详细说下uboot的命令行功能。
接着往下看代码,人机交互是一个死循环:
图片10.png
人机交互功能看上去很高大上,实际上就是串口的输入输出控制。以前有不少人移植过uboot的命令行功能到MCU上,
网上资料很多,有兴趣的读者可以自行搜索相关资料。本渣大概解释下人机交互最重要的2个函数:
int readline (const char *const prompt)
int run_command (const char* cmd, int flag)
其中readline()负责从串口读取命令字符串,而run_command()则负责解析命令字符串。
由于这两个函数涉及的内容太多,本篇文章不作过多的解释,本渣在源代码里有详细解释这些函数,
如有解释不清楚的可以在论坛上提问,本渣能解答的一定尽量解答。

下篇文章详细解释命令制作与存储,敬请期待吧!^_^
uboot成功移植到STM32F103ZET6(二).pdf (366.75 KB, 下载次数: 18)
拿来长岛冰茶换我半晚安睡
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

1127

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1656
金钱
1656
注册时间
2019-8-15
在线时间
102 小时
发表于 2019-12-18 19:10:19 | 显示全部楼层
帮顶                                                              
成功没有捷径
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-21 12:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表