第2章:学习正点原子开发板-stm32mp157-uboot移植

第2章:学习正点原子开发板-stm32mp157-uboot移植

1. uboot移植需要

首先,我们需要下载官方的原厂包(即BSP包),

u-boot-stm32mp-2020.01-r0

进入到u-boot-stm32mp-2020.01-r0里面,里面包含了许多.patch,Makefile.sdk和uboot源码压缩包,和tf-a一样,patch包的作用是给当前的uboot打补丁。

2. uboot移植的操作

接下来是解压u-boot-stm32mp-2020.01-r0.tar.gz文件

tar -vxf u-boot-stm32mp-2020.01-r0.tar.gz

解压完成以后,进入解压文件,然后打补丁

cd u-boot-stm32mp-2020.01/ //进入 uboot 源码目录
for p in ls -1 ../*.patch;do patch -p1 < $p;done //打补丁

这里需要注意一些符号。在以上操作完成之后,若感觉操作路径太长,则可以拷贝到短一点的路径中,便于操作。拷贝指令为

cp 源路径 目标路径 -rf

在顶层Makefile中设置ARCH和CROSS_COMPILE,如下图所示:
在这里插入图片描述
因为我们是参考ST官方的 STM32MP1 EVK 开发板,所以我们可以试着试用官方的设备树文件,看看哪些会报错,需要修改,这点很重要,可以节约我们大部分时间。

make stm32mp15_trusted_defconfig make DEVICE_TREE=stm32mp157d-ev1 all -j8

uboot 编译成功,生成了 u-boot.bin 和 u-boot.stm32,u-boot.bin 包含了设备树(dtb),也就是将 uboot 镜像和设备树打包在了一起。其中 u-boot.stm32 是在 u-boot.bin前面添加了 256 字节头部信息的可执行文件,是要烧写到开发板里面的。

注意:我们在向板子下载程序时,试用的也是uboot,为了排除我们自己移植的系统无法正常使用DDR,所有在烧写系统时,我们需要正电原子提供移植好的uboot,我们移植的系统改名为my-u-boot.stm32;
注意修改tsv文件,修改内容如下:
在这里插入图片描述
从图中可以看出,将系统烧写到的地址为0x00080000,一切准备就绪,烧写程序到EMMC中,拨动开关,启动,看结果:
在这里插入图片描述
一看fail,全是stpmic1_read的错误,接下来我们将围绕这些问题进行移植。
创建默认配置文件,我们使用官方的defconfig文件,将文件stm32mp15_trusted_defconfig复制一下,

cd configs //进入 uboot 的 configs 目录
cp stm32mp15_trusted_defconfig stm32mp15_atk_trusted_defconfig //拷贝

对应的设备树也复制一些,我们将在复制的文件中进行操作。

cd arch/arm/dts/ //进入 uboot 设备树目录 cp stm32mp157d-ed1.dts
stm32mp157d-atk.dts //复制.dts cp stm32mp15xx-edx.dtsi
stm32mp157d-atk.dtsi //复制.dtsi cp stm32mp157a-ed1-u-boot.dtsi
stm32mp157d-atk-u-boot.dtsi //复制.dtsi

打开 stm32mp157d-atk.dts 文件,要修改一下其中的一个头文件引用,stm32mp157d-atk.dts默认头文件引用如下:

14行 #include “stm32mp15xx-edx.dtsi”
修改为我们刚才复制的文件stm32mp15d-atk.dtsi

结果如图所示:在这里插入图片描述

修改电源管理设置

打开 创建的 stm32mp157d-atk-u-boot.dtsi 这个文件,将文件中的21~22行,26~31行和51~53行都删除,删除之后如图所示:
在这里插入图片描述
接着修改 stm32mp157d-atk.dtsi 文件,将文件中 90~104 行的 adc 节点、114~125 行的 dac 节点以及 143~298 行的i2c4 节点全部删除掉,删除以后如图 ,主要是删除电池管理的那部分:在这里插入图片描述
继续修改stm32mp157d-atk.dtsi 文件,将 led 和 sd_switch 这两个节点都删除掉,然后在文件的根节点中添加电源管理配置,将
下面的代码添加58行处:代码如下:

vddcore: regulator-vddcore {
compatible = "regulator-fixed";
regulator-name = "vddcore";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
v3v3: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "v3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};

v1v8_audio: regulator-v1v8-audio {
compatible = "regulator-fixed";
regulator-name = "v1v8_audio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};

vdd: regulator-vdd {
compatible = "regulator-fixed";
regulator-name = "vdd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
 };

vdd_usb: regulator-vdd-usb {
compatible = "regulator-fixed";
regulator-name = "vdd_usb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};

在其中分别添加了vddcore、v3v3、v1v8_audio、vdd 和 vdd_usb节点,和tf-a配置的差不多。
接下来修改TF卡和EMMC配置,在 stm32mp157d-atk.dtsi 文件继续修改,找到sdmmc1和sdmmc2这两个节点,修改其中的内容为如图所示内容:
在这里插入图片描述
现在开始编译uboot,我们先测试前面的内容是否移植成功,则注释掉USB_OTG的电源配置,在这里插入图片描述
在编译uboot之前,添加我们修改的设备树文件,打开 arch/arm/dts/Makefile文件,找到“dtb-$(CONFIG_STM32MP15x)”配置项,然后在此配置项中加入“stm32mp157d-atk.dtb”添加完成如图所示:在这里插入图片描述
开始编译,操作指令如下:

make distclean
make stm32mp15_atk_trusted_defconfig
make DEVICE_TREE=stm32mp157d-atk all

在编译成功之后会出现以下信息,对应的文件也会生成。
在这里插入图片描述
我们将编译成功u-boot.stm32(注意修改名字my-u-boot.stm32)文件烧写到板子上。上电开机如下:
在这里插入图片描述
可以从图中看出,网络驱动还存在问题。USB_OTG也存在问题。那接下来就修改网络驱动。打开 stm32mp157d-atk.dtsi 文件,将如下所示的 ethernet0 节点加添加到最后面:

&ethernet0 {
status = "okay";
pinctrl-0 = <&ethernet0_rgmii_pins_a>;
pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
pinctrl-names = "default", "sleep";
phy-mode = "rgmii-id";
max-speed = <1000>;
phy-handle = <&phy0>;

mdio0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
phy0: ethernet-phy@0 {
reg = <0>;
};
};
};

开发板的网络PHY芯片被更换为国产裕太电子的YT8511芯片,所以我们需要找到该芯片的驱动源代码,路径在
1、程序源码→8、模块驱动源码→1、YT8511 驱动源码→uboot 下修改方法→phy.c此文件中内容兼容RTL8211和YT8511。用修改后的phy.c文件替换掉uboot下的/drivers/net/phy/phy.c 文件即可设备树无需做任何修改,直接编译即可。注意,正点原子 V1.2 版本核心板上使用的 RTL8211,其 PHY 地址为 0X01。V1.3 以后的
核心板使用 YT8511,其 PHY 地址为 0X00,因此在设备树里面需要修改 PHY 地址为 0X00。但是这样修改以后会导致 YT8511 和RTL8211 的设备树不兼容,需要多编写一份设备树,导致出厂设备树过多。因此为了一个设备树兼容 YT8511 和 RTL8211,正点原子团队修改了 phy.c 文件中的 phy_connect 函数,直接给定 YT8511 的地址为 0X00,也就是不受设备树控制,如下图所示:在这里插入图片描述
编译测试,测试结果如下:在这里插入图片描述
但其中还是会出现“No ethernet found.”错误,这是因为 uboot 启动的
时候获取不到 MAC 地址,我们只需要设置一些地址相关的环境变量即可,配置命令如下,这里面参考自己的环境进行修改:

setenv ipaddr 192.168.1.250 //开发板 IP 地址 setenv ethaddr
00:04:9f:04:d2:35 //开发板网卡 MAC 地址 setenv gatewayip 192.168.1.1
//开发板默认网关 setenv netmask 255.255.255.0 //开发板子网掩码 setenv serverip
192.168.1.249 //服务器地址,也就是 Ubuntu 地址 saveenv

这是网络可以正常运行了,接下来修改USB_OTG设备树
添加 usb_phy_tuning 子节点。

usb_phy_tuning: usb-phy-tuning {
st,hs-dc-level = <2>;
st,fs-rftime-tuning;
st,hs-rftime-reduction;
st,hs-current-trim = <15>;
st,hs-impedance-trim = <1>;
st,squelch-level = <3>;
st,hs-rx-offset = <2>;
st,no-lsfs-sc;
 };

添加结果如下所示:
在这里插入图片描述
添加 STUSB1600 I2C 子节点
正点原子 STM32MP157 开发板上的 USB OTG 接口类型为 Type-C,使用 STUSB1600 芯片来实现此接口功能,STUSB1600 有一个 I2C 接口,此 I2C 接口用来配置芯片,因此我们还需要在设备树中添加 STUSB1600 相关的 I2C 节点内容。将如下内容添加到 stm32mp157d-atk.dtsi 的最后面

&i2c1 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c1_pins_a>;
pinctrl-1 = <&i2c1_pins_sleep_a>;
i2c-scl-rising-time-ns = <100>;
i2c-scl-falling-time-ns = <7>;
status = "okay";
/delete-property/dmas;
/delete-property/dma-names;

stusb1600@28 {
compatible = "st,stusb1600";
reg = <0x28>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpiog>;
pinctrl-names = "default";
pinctrl-0 = <&stusb1600_pins_a>;
status = "okay";
vdd-supply = <&vin>;

connector {
compatible = "usb-c-connector";
label = "USB-C";
power-role = "dual";
power-opmode = "default";

port {
con_usbotg_hs_ep: endpoint {
remote-endpoint = <&usbotg_hs_ep>;
};
};
};
};
};

添加结果如下:
在这里插入图片描述
添加usb接口相关节点
继续向 stm32mp157d-atk.dtsi 文件添加 USB 接口相关节点内容,内容如下:

&usbh_ehci {
phys = <&usbphyc_port0>;
status = "okay";
};

&usbotg_hs {
phys = <&usbphyc_port1 0>;
phy-names = "usb2-phy";
usb-role-switch;
status = "okay";

port {
usbotg_hs_ep: endpoint {
remote-endpoint = <&con_usbotg_hs_ep>;
};
};
};

&usbphyc {
status = "okay";
};

上述代码中有三个节点 usbh_ehci、usbotg_hs 和 usbphyc,其中 usbotg_hs 默认就有,我们在前面将其屏蔽掉了
在这里插入图片描述
在 stm32mp157d-atk-u-boot.dtsi 文件中添加 usbotg_hs 节点,最后,我们需要在 stm32mp157d-atk-u-boot.dtsi 文件里面添加 usbotg_hs 节点,节点内容如下所示:

&usbotg_hs {
u-boot,force-b-session-valid;
hnp-srp-disable;
/* TEMP: force peripheral for USB OTG */
dr_mode = "peripheral";
};

至此,uboot 下的 USB OTG 就已经修改完成,重新编译 uboot 并烧写,然后使用 ums 命令
测试,看看能不能将 EMMC 模拟成 U 盘,挂载到电脑上,命令如下:
做到这里,保存修改的文件,编译和拷贝。把 STM32MP157D-ATK 开发板的 USB_OTG 接口连接到电脑里,重启开发板,接着运行以下命令:

ums 0 mmc 1

则此时电脑上会出现一个盘,不要格式化,只能在linux中挂载。
使能boot和bootd命令
ST 官方 uboot 默认并没有使能 boot 和 bootd 这两个命令,这两个命令的实现源文件为cmd/bootm.c,我们来看bootm.c文件,其中有一个宏定义,用来使能boot和bootd命令。如图所示:
在这里插入图片描述
那么就需要定义宏CONFIG_CMD_BOOT,打开 include/configs/stm32mp1.h,然后在后面添加如下宏定义:在这里插入图片描述
重新编译uboot,使用?boot和?bootd看是否有信息,有则表示驱动成功。在这里插入图片描述
LCD驱动修改
uboot 也是支持 LCD 显示的,但是要进行相应的设置,主要是设置屏幕背光、屏幕时序参数这些,这些直接在设备树里面修改即可。打开 stm32mp157d-atk.dts 文件,在里面添加 LCD 相关节点信息,首先在根节点“/”下添加 panel_backlight 和 panel_rgb 这两个节点,节点内容如
下:

panel_backlight: panel-backlight {
compatible = "gpio-backlight";
gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>;
default-on;
status = "okay";
};

panel_rgb: panel-rgb {
compatible = "simple-panel";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&ltdc_pins_b>;
pinctrl-1 = <&ltdc_pins_sleep_b>;
backlight = <&panel_backlight>;
status = "okay";

port {
panel_in_rgb: endpoint {
remote-endpoint = <&ltdc_ep0_out>;
};
};

display-timings {
native-mode = <&timing0>; /* 时序信息 */
timing0: timing0 { /* 7 寸 寸 1024*600 分辨率 */
clock-frequency = <51200000>; /* LCD 像素时钟,单位 Hz */
hactive = <1024>; /* LCD X 轴像素个数 */
vactive = <600>; /* LCD Y 轴像素个数 */
hfront-porch = <160>; /* LCD hfp 参数 */
hback-porch = <140>; /* LCD hbp 参数 */
hsync-len = <20>; /* LCD hspw 参数 */
vback-porch = <20>; /* LCD vbp 参数 */
vfront-porch = <12>; /* LCD vfp 参数 */
vsync-len = <3>; /* LCD vspw 参数 */
};
};
};

第 1~6 行,panel_backlight 为 LCD 的背光控制节点,主要指定 LCD 背光 IO 所使用的引脚,正点原子的 STM32MP157 开发板 LCD 背光引脚为 PD13。
第 8~38 行,panel_rgb 为 RGB LCD 节点,指定了 LTDC 接口所使用的 IO、屏幕时序参数等。第 11~12 行指定 LTDC 接口的 IO,ltdc_pins_b 和 ltdc_pins_sleep_b 定义在 stm32mp15-pinctrl.dtsi 文件中。第 22~35 行的 display-timings 是非常重要的 LCD 时序参数,不同的屏幕其时序参数不同,这里演示的是正点原子 7 寸 1024600 分辨率的。正点原子有 4 款 RGB 接口屏幕,分别为 4.3 寸 480272 和 800480 分辨率、7 寸 800480 和 1024*600 分辨率,这款屏幕时序参数如表
屏幕型号 参数 值 值 单位
ATK4342
水平显示区域 480 tCLK
HSPW(thp) 1 tCLK
HBP(thb) 40 tCLK
HFP(thf) 5 tCLK
垂直显示区域 272 th
VSPW(tvp) 1 th
VBP(tvb) 8 th
VFP(tvf) 8 th
像素时钟 9 MHz
ATK4384
水平显示区域 800 tCLK
HSPW(thp) 48 tCLK
HBP(thb) 88 tCLK
HFP(thf) 40 tCLK
垂直显示区域 480 th
VSPW(tvp) 3 th
VBP(tvb) 32 th
VFP(tvf) 13 th
像素时钟 31 MHz
ATK7084
水平显示区域 800 tCLK
HSPW(thp) 1 tCLK
HBP(thb) 46 tCLK
HFP(thf) 210 tCLK
垂直显示区域 480 th
VSPW(tvp) 1 th
VBP(tvb) 23 th
VFP(tvf) 22 th
像素时钟 33.3 MHz
ATK7016
水平显示区域 1024 tCLK
HSPW(thp) 20 tCLK
HBP(thb) 140 tCLK
HFP(thf) 160 tCLK
垂直显示区域 600 th
VSPW(tvp) 3 th
VBP(tvb) 20 th
VFP(tvf) 12 th
像素时钟 51.2 MHz

如图所示:
在这里插入图片描述
最后还需要在 stm32mp157d-atk.dts 文件里面向 ltdc 节点追加一些内容,内容如下:

&ltdc {
status = "okay";
pinctrl-names = "default";
port {
#address-cells = <1>;
#size-cells = <0>;

ltdc_ep0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_in_rgb>;
};
};

在这里插入图片描述
从 从 EMMC 启动 Linux
从EMMC启动也就是将编译出来的Linux镜像文件uImage和.dtb设备树文件保存在EMMC中,uboot 从 EMMC 中读取这两个文件并启动,这个是我们产品最终的启动方式。首先 EMMC里面要先存放 Linux 镜像文件 uImage 和.dtb 设备树,但是我们前面新建的 FlashLayout 文件并没有烧写 uImage 和.dtb,所以我们需要修改一下 FlashLayout 文件,加入 uImage 和.dtb 烧写命令。由于我们还没有移植 Linux 系统,所以 uImage 和.dtb 就先使用正点原子出厂系统提供的,路径为:开发板光盘→8、系统镜像→2、出厂系统镜像→1、STM32CubeProg 烧录固件包→atk-image-bootfs.ext4 。atk-image-bootfs.ext4 是 ext4 格式的打包文件,因为 STM32CubeProgrammer软件要求将 uImage 和.dtb 打包在一起,格式为 ext4。atk-image-bootfs.ext4 里面的文件如图在这里插入图片描述
将文件烧写到板子中,tsv的配置如下
在这里插入图片描述
在烧写程序之后,开启板子,然后在uboot中参看uImage等是否烧写入文件。
在这里插入图片描述
最后我们配置开机自启命令。命令如下:

setenv bootcmd ‘ext4load mmc 1:2 c2000000 uImage;ext4load mmc 1:2
c4000000 stm32mp157d- atk.dtb;bootm c2000000 - c4000000’ saveenv boot

注意:此时还没有根文件系统,所以内核启动之后会报错。
从网络启动 Linux 系统
命令如下:

setenv bootcmd ‘tftp c2000000 uImage;tftp c4000000
stm32mp157d-atk.dtb;bootm c2000000 - (有空格) c4000000’ saveenv
boot

启动结果如下:在这里插入图片描述
LCD测试
在烧写程序时,开发板的lcd会显示一下内容:
在这里插入图片描述
bmp 命令显示测试
使用uboot下的bmp命令在LCD上显示一张bmp图片,如图所示:
在这里插入图片描述
bmp info < imageAddr >
bmp info 命令用于显示 BMP 图片信息,imageAddr 就是 BMP 图片在 RAM 中的起始地址。
bmp display
命令用于显示 bmp 图片,imageAddr 是要显示的 BMP 图片在 RAM 中的起始地址,[x,y]用于指定 BMP 图片左上角在屏幕上的显示坐标。

tftp c0000000 test.bmp //下载 bmp 图片
bmp info c0000000 //显示图片信息

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

bmp display c0000000 0 0 //显示 bmp 图片

在这里插入图片描述

以上就是uboot的整个移植过程,可能其中内容存在很多不足,有什么不妥地方请联系。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值