IMX6ULL学习笔记_Boot和裸机篇(1)--- SEGGER Embedded Studio 和 Uboot 环境搭建
项目开源链接以及作者信息
项 | 参数 |
---|---|
github主页 | https://github.com/snqx-lqh |
github项目地址 | https://github.com/snqx-lqh/IMX6ULL_LearningRecord |
gitee项目地址 | https://gitee.com/snqx-lqh/IMX6ULL_LearningRecord |
作者 VX | Qinghua_Li7 |
📖 欢迎交流 如果对你有帮助,希望可以帮我点个赞👍和收藏,谢谢
基础环境
硬件环境:正点原子IMX6ULL MINI板 V1.7 EMMC板
程序说明:为方便开发,程序使用 BootLoader + APP 的方式开发。使用BootLoader来进行升级,前期不将 BootLoader 作为开发重点,所以先使用 UBoot 作为我们的 BootLoader 后续可能会使用自写的 BootLoader 。所以先使用正点原子的教程给板子的 EMMC或者SD卡 下载一个 Uboot。方便实现在线程序升级和运行。随便烧一个就行,不用自己去编译,下载它自带的就可以了。等下做说明。
裸机程序编写软件:SEGGER Embedded Studio V8.24 。 为了在Windows环境下编译裸机开发,所以使用 SES 的软件编写。
本文代码路径
本文的代码将存放在开源项目的:02_Firmware\01_CodeWithoutOS\01_ProjectDemo中。
下载 Uboot 程序
主要是需要板子上有个能启动的程序。SD卡或者EMMC都行,只要能让板子启动起来就行。使用正点原子的下载工具。但是我们只下载Uboot,不下载其他的,如果你是使用的EMMC的话,它本身里面就有了出厂的Uboot这些程序,理论上就可以不用咋管了。
【全量烧写】SD 卡使用正点原子出厂工具烧写
1、如果图省事,我们可以直接把Uboot、Linux内核和文件系统全量烧写到SD卡中,找到正点原子改版的mfgtools。不要找到NXP原厂那个了,那个还要自己改。
2、将 USB 插到 USBOTG 上,并且将启动方式调整到 USB 启动。
3、根据你的板子配置选择合适的脚本烧写。
4、插上SD卡打开脚本并上电,会发现软件检测到板子,记得SD卡需要格式化,然后点击 Start 就等着。它下的内容比较多,可能要等一会,中间可能会弹出几秒的无设备连接,也比较正常,等一会就好了。下载完成后,显示done。
5、将电源关闭,引脚调整到SD卡启动,然后连接到串口,使用串口调试助手查看结果。
6、开机后我们一直回车,串口调试助手自己选择合适的,我这里使用的是 SecureCRT,因为他能发送各种协议的文本。开机后,就能发现Uboot打印了,回车就会进入 UBoot 命令行了,就可以操控 Uboot 的相关指令了。
7、可以尝试一下复位后不回车,就会发现我们会一直进入到内核程序中。
【仅Uboot烧写】SD 卡使用正点原子出厂工具烧写Uboot
1、我们还可以只烧写 Uboot 。打开烧写工具中的烧写ucl2.xml。使用文本文件打开。
2、会发现中间有 3 个 List ,每个的内容会详细描述每个启动方式怎么烧写,我们先看 SD 卡的。
3、可以看每个命令前面的注释,比如创建分区,烧写分区什么的。
4、我们只保留Uboot相关的,其他的直接注释。也就是从 burn logo
开始,SD 卡下面的 那些CMD 全部注释,你要是嫌麻烦,也可以直接删除,但是建议你备份一个,因为你后面肯定还有要学烧写全部的需求。
5、然后我们再去烧写 SD 卡,就和上面全量烧写的步骤一样了。只下载Uboot的话,就比较快。然后我们调整到SD卡启动,然后打开串口调试助手。你会发现你就算不回车,也进入不了Kernel,因为压根就没Kernel。
【全量烧写-Uboot烧写】EMMC 用正点原子出厂工具烧写
其实和SD卡的步骤一样的,只是在选择启动方式的时候,需要选择 EMMC 的启动方式,还有就是那个烧写脚本后缀需要选择带 EMMC的而不是带SD卡的。
然后只烧写UBoot的话,就得记着修改 ucl2.xml 中 EMMC 的部分,把该状态下除了烧写Uboot的其他内容全部去掉。
SEGGER ES 编写代码环境搭建
1、SEGGER Embedded Studio官网下载一个这个软件。根据你的操作系统选择软件,我们用 Windows。至于安装傻瓜式默认,只需要中间安装路径选择一个比较合适的位置。
2、打开软件,我们新建一个工程
3、选择建立一个新的解决方案
4、选择Cotex-A的解决方案,因为我们用的IMX是Cotex-A并且选择一个路径名和工程名。
5、在选择目标设备中,我们搜索我们的芯片型号
6、编译环境默认。
7、添加程序,默认
8、配置方案,也默认
9、全部配置好后,就会生成工程。SEGGER_Flash_ARM.icf 是链接文件,main是编译文件,.s的是启动文件。
icf文件中我们改一点东西,主要就是链接地址改成自己想要的位置。不改变原来的设计,我们自己定义一段区域。不然的话,他是全部链接到内部RAM的地址,和QSPI的Flash地址,我们的板子会跑不起来的。
/****************** 改1前 *********************/
define region FLASH = FLASH1;
define region RAM = RAM1;
/****************************************************//****************** 改1后 *********************/
define region FLASH2 = [from 0x87800000 to 0x87FFFFFF];
define region RAM2 = [from 0x80000000 to 0x8003FFFF];define region FLASH = FLASH2;
define region RAM = RAM2;
/****************************************************/
11、为了生成bin文件,我们右键工程,点配置。
12、在linker中,将输出配置成bin
13、右键工程就可以Build。也可以快捷键F7。
14、可以看到Output中就会有bin文件,也是我们最后需要烧写的文件。
14、我们写一个基本的LED翻转驱动,使用正点原子的例程,并且烧写。先在Source目录下建立BSP文件夹,然后建立两个文件。当然,你也可以其他地方建立。
15、工程中,右键文件夹,新建文件夹分类。建立BSP文件夹,并且把刚刚的两个文件加进去。
16、因为有了新的文件夹,所以工程还需要能够找到文件夹路径。右键项目option,配置Preprocessor的User Include Dir
17、点击后面几个点,然后把自己的路径加上去。每行用,号隔开,我这里使用的是相对路径,然后要添加的文件夹路径是你外面文件的路径,不是工程里面的路径。是实际的文件路径。
18、源码如下。分别是 bsp_led.c
和bsp_led.h
和main.c
// bsp_led.c
#include "bsp_led.h"
#include <stdint.h>void clk_enable(void)
{CCM_CCGR0 = 0xffffffff;CCM_CCGR1 = 0xffffffff;CCM_CCGR2 = 0xffffffff;CCM_CCGR3 = 0xffffffff;CCM_CCGR4 = 0xffffffff;CCM_CCGR5 = 0xffffffff;CCM_CCGR6 = 0xffffffff;
}void led_init(void)
{SW_MUX_GPIO1_IO03 = 0x5; /* 复用为GPIO1_IO03 */SW_PAD_GPIO1_IO03 = 0X10B0; GPIO1_GDIR = 0X0000008; /* GPIO1_IO03设置为输出 */GPIO1_DR = 0X0;
}void led_on(void)
{GPIO1_DR &= ~(1<<3);
}void led_off(void)
{GPIO1_DR |= (1<<3);
}void delay_short(volatile unsigned int n)
{while(n--){}
}void delay(volatile unsigned int n)
{while(n--){delay_short(0x7ff);}
}// bsp_led.h
#ifndef BSP_LED_H
#define BSP_LED_H/* * CCM相关寄存器地址 */
#define CCM_CCGR0 *((volatile unsigned int *)0X020C4068)
#define CCM_CCGR1 *((volatile unsigned int *)0X020C406C)#define CCM_CCGR2 *((volatile unsigned int *)0X020C4070)
#define CCM_CCGR3 *((volatile unsigned int *)0X020C4074)
#define CCM_CCGR4 *((volatile unsigned int *)0X020C4078)
#define CCM_CCGR5 *((volatile unsigned int *)0X020C407C)
#define CCM_CCGR6 *((volatile unsigned int *)0X020C4080)/* * IOMUX相关寄存器地址 */
#define SW_MUX_GPIO1_IO03 *((volatile unsigned int *)0X020E0068)
#define SW_PAD_GPIO1_IO03 *((volatile unsigned int *)0X020E02F4)/* * GPIO1相关寄存器地址 */
#define GPIO1_DR *((volatile unsigned int *)0X0209C000)
#define GPIO1_GDIR *((volatile unsigned int *)0X0209C004)
#define GPIO1_PSR *((volatile unsigned int *)0X0209C008)
#define GPIO1_ICR1 *((volatile unsigned int *)0X0209C00C)
#define GPIO1_ICR2 *((volatile unsigned int *)0X0209C010)
#define GPIO1_IMR *((volatile unsigned int *)0X0209C014)
#define GPIO1_ISR *((volatile unsigned int *)0X0209C018)
#define GPIO1_EDGE_SEL *((volatile unsigned int *)0X0209C01C)void clk_enable(void);
void led_init(void);
void led_on(void);
void led_off(void);
void delay_short(volatile unsigned int n);
void delay(volatile unsigned int n);#endif// main.c
#include "bsp_led.h"int main(void) {clk_enable(); /* 使能所有的时钟 */led_init(); /* 初始化led */while(1) /* 死循环 */{ led_off(); /* 关闭LED */delay(50000); /* 延时大约500ms */led_on(); /* 打开LED */delay(50000); /* 延时大约500ms */}return 0;
}
19,然后编译就可以得到bin文件了。
下载程序
我们现在有 Uboot 和 bin程序了,那我们就可以使用 Uboot 的相关指令下载程序了。先启动Uboot
先选择我们要控制的设备,要么SD卡要么EMMC,选择一个就可以了,我这里用SD卡
mmc dev 0 #控制SD卡
mmc dev 1 #控制EMMC
然后我们使用xmode协议把我们刚生成的bin文件传输到DDR内存中,我们把代码放到 0x87800000 中 。
loadx 0x87800000
然后uboot会启动xmode协议接收,我们在SecureCRT中选择 Xmode 协议发送。并选择文件。
发送完成后,会给你说发送的文件大小,这里是484Byte。
=> loadx 0x87800000
## Ready for binary (xmodem) download to 0x87800000 at 115200 bps...
CCCCCCCCCC
Starting xmodem transfer. Press Ctrl+C to cancel.
Transferring Project.bin...100% 484 bytes 484 bytes/sec 00:00:01 0 Errors ## Total Size = 0x000001e4 = 484 Bytes
我们可以把他写入到SD卡中。
# 写入指令 mmc write addr blk# cnt
# addr 是要写入 MMC 中的数据在 DRAM 中的起始地址,blk 是要写入 MMC 的块起始地址
# (十六进制),cnt 是要写入的块大小,一个块为 512 字节。
# 800是我随便想的地址,这个地址,肯定没有覆盖uboot,我们这里只有484个字节写一个块就行。
mmc write 0x87800000 0x800 1
然后我们可以直接启动程序
go 0x87800000
复位之后,可以把写入到 0x800 区域的 代码读出来放到0x87800000再跑
mmc dev 0 #控制SD卡
mmc read 0x87800000 0x800 1
go 0x87800000