STM32F429上Zephyr与mcuboot运行详解
由于项目需要,对zephyr和mcuboot进行了初步学习,并基于stm32f429(用的是正点原子的阿波罗开发板)进行了一些实操,对这个过程进行一下记录。
搭建zephyr的开发环境
我这里是在Windows下进行开发的,这一步实际上跟着zephyr官方的指引走就没有问题。以下是简单记录。
- 安装chocolatey
- 以管理员身份运行命令行
- 使用chocolatey安装其他需要的工具(cmake,ninja,gperf,python311,git,dtc-msys2,wget,7zip)
- 安装west(这是专门给zephyr开发的工具)
- 使用west获取zephyr源码
- 使用west导出zephyr cmake package
- 安装其他需要的python依赖(zephyr中有文件记录了需要什么,pip3可以直接使用这个文件依次安装)
- 使用wget获取zephyr SDK(这里面是zephyr进行编译链接等操作要用到的工具)
- 解压它,并运行其中的setup.cmd进行安装
- 编译例程,使用west build命令进行,例子如下:
cd %HOMEPATH%\zephyrproject\zephyr
west build -b stm32f429i_disc1 .\samples\hello_world\ --build-dir build_1
其中stm32f429i_disc1这个是board, .\samples\hello_world\这个是要编译的例程,–build-dir build_1这里指定了编译过程和结果存放的路径是当前文件夹下的build_1文件夹(没有则会创建一个)
编译通过之后,会在zephyrproject\zephyr\build_1\zephyr目录下找到zephyr.bin和zephyr.hex这两个就是编出来的固件,不过这时的固件还不能直接烧录,因为板子配置不同
适配开发板
适配时,参考了有大佬在野火同mcu的开发板上进行移植的博客,主要是时钟问题,需要修改配置文件boards/arm/stm32f429i_disc1/stm32f429i_disc1_defconfig:
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=180000000
CONFIG_ARM_MPU=n
CONFIG_CLOCK_STM32_HSE_CLOCK=25000000
CONFIG_CLOCK_STM32_PLL_M_DIVISOR=25
CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=360
由于zephyr版本不同,具体到我这里,需要修改两个文件,配置文件和设备树文件:
boards/arm/stm32f429i_disc1/stm32f429i_disc1_defconfig:
CONFIG_ARM_MPU=n
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=180000000
CONFIG_CLOCK_STM32_HSE_CLOCK=25000000
boards/arm/stm32f429i_disc1/stm32f429i_disc1.dts
&pll {
div-m = <25>;
mul-n = <360>;
div-p = <2>;
div-q = <8>;
clocks = <&clk_hse>;
status = "okay";
};
再次编译之后的固件,就可以烧录进开发板,我这里用的是stm32 stlink utility烧录工具,运行结果如下:
添加MCUboot
例程跑起来之后,就要考虑添加MCUboot,由BOOT去引导app
MCUboot本身已经支持了zephyr;测试MCUboot一共需要三个固件;
MCUboot要求在zephyr的设备树中增加三个slot:
&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 DT_SIZE_K(128)>;
read-only;
};
slot0_partition: partition@20000 {
label = "image-0";
reg = <0x00020000 DT_SIZE_K(128)>;
};
slot1_partition: partition@40000 {
label = "image-1";
reg = <0x00040000 DT_SIZE_K(128)>;
};
scratch_partition: partition@60000 {
label = "image-scratch";
reg = <0x00060000 DT_SIZE_K(128)>;
};
}
进入\zephyrproject\bootloader\mcuboot\boot\zephyr目录,编译MCUboot:
west build -b stm32f429i_disc1
然后在当前目录下的build\zephyr目录中会找到zephyr.hex文件,烧录运行结果如下:
提示Unable to find bootable image是因为我们还没有app镜像可以加载;
加载app镜像
可以在当前目录下运行:
west build -b stm32f429i_disc1 ..\..\samples\zephyr\hello-world\ --build-dir build_1
编译MCUboot官方准备好的例程;编译通过之后可以在build_1\zephyr目录下找到zephyr.bin,这个bin是特殊的bin,它的开头前0x200个字节是空的,是需要签名才能被mcuboot识别;
python ..\..\scripts\imgtool.py sign --header-size 0x200 --align 8 --version 1.2 -S 0x20000 --key \..\..\root-rsa-2048.pem .\build_1\zephyr\zephyr.bin .\zephyr\build_1\zephyr\signed.bin
这样就签名成功了,获得了signed.bin;然后将这个bin烧录到板子上,烧录时也要注意,需要偏移,因为在设备树中规定了app镜像slot0会偏移0x20000个字节,因此烧录时也要偏移这么多去烧录:
烧录成功之后,运行结果如下:
到这里,就算是完成了让mcuboot引导app的工作
使用spi flash
由于项目中用的是spi-nand-flash,接下来就需要尝试使用它,我这里开发板上是spi-nor-flash接的是spi5接口,这时又需要修改设备树了:
原本我使用的这个stm32f429i_disc1板子的设备树配置中,spi5是配置好的,不过它被用来做spi屏幕接口了,需要把屏幕接口相关的配置屏蔽掉,主要是<dc,还有chosen节点中的// zephyr,display = &ili9341;,然后把原来的spi5节点中的ili9341也屏蔽掉,增加对w25q256(我开发板上的spiflash)的描述,同时把片选脚配置正确:
&spi5 {
pinctrl-0 = <&spi5_nss_pf6 &spi5_sck_pf7
&spi5_miso_pf8 &spi5_mosi_pf9>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&gpiof 6 GPIO_ACTIVE_LOW>;
w25q256fv: w25q256fv@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <40000000>;
size = <0x10000000>;
has-dpd;
t-enter-dpd = <4000>;
t-exit-dpd = <25000>;
jedec-id = [ef 40 19];
}
改好之后就可以编译了:
west build -b stm32f429i_disc1 .\samples\drivers\spi_flash
编译通过后,烧录运行如下:
添加文件系统
作者:xyjdwxzxxbw