1187|0

2945

帖子

4

TA的资源

五彩晶圆(中级)

楼主
 

【米尔STM32MP135】TF-A编译与设备启动 [复制链接]

STM32MP135这款MPU的性能非常的好,很适合工业使用,而且ST公司比较大方,除了数据手册以外寄存器定义和编程手册都对普通用户开放,不像国产的某*志之类的厂家有用的资料对普通用户捂得严严实实的,甚至威胁谁要是公开其资料就会被起诉,这点我是十分的不理解,所以国内的ARM MPU芯片一直没有兴趣。这次测评米尔STM32MP135的芯片就有计划做些移植实验。本次的测试就是STM32MP135的移植实验。

STM32MP135的启动流程大致分三个阶段。大致为:

 

1、内置ROM启动,这个过程是使用MPU的内存工作的,就和单片机差不多,所以除了脚本的设置功能没有更高级的了,设置DDR初始化都没有,只是负责把FSBL代码读到CPU内部RAM中,这部分过程差不多MPU都是相似的。就是高级的手机的CPU也一样。这段ROM code为厂家内置,不可更改。

2、FSBL启动,这个是移植工程师需要编写的,这段代码也分两部分,First Stage为在内部RAM中执行的程序和后续的加载程序SSBL,第一阶段程序需要根据具体的硬件配置初始化,例如:串口、MMC内存、SD卡、等,最重要的DDR内存。本次实验就是测试的这段代码。最要的外设和DDR初始化以后,就是将Uboot等程序加载到内存,进行第三阶段启动。

3、SSBL阶段就是工作的程序了,通常这一阶段工作在DDR内存当中,例如:我们熟知的UBOOT程序,这其实整个系统就算进入到工作状态了,你其实都可以将UBOOT改成类似单片机的方式,或者写个什么简单的操作系统之类的。

4、uboot启动后通常都会加载linux内核,linux内核完全的推翻了UBOOT的内存布局和外设初始化,linux完全的接管整个系统。

从上述描述当中可以知道,不同阶段都外设有着不同的要求,每个阶段都有自己独立的系统要求,也就是互相没有什么关联,自己干自己的事,这就涉及到不同的阶段设备树也是不一样的,彼此可以独立。

我的测试主要参考了:Trusted Firmware-A (BL2)的内容,ST公司服务真是太赞了。

先去STMicroelectronics github上下载TF-A的代码,这里注意不要使用SDK包里的代码太旧,轻易出问题。理论上也可以去trustedfirmware官网上也是可以地,但是象我这样的水平就免了。

进入arm-trusted-firmware目录,查看一下fdts下的dts文件,找到stm32mp135f-dk.dts文件,复制一份。编辑文件

  • // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  • /*
  • * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
  • * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  • */
  • /dts-v1/;
  • #include <dt-bindings/clock/stm32mp13-clksrc.h>
  • #include "stm32mp135.dtsi"
  • #include "stm32mp13xf.dtsi"
  • #include "stm32mp13-ddr3-1x4Gb-1066-binF.dtsi"
  • #include "stm32mp13-pinctrl.dtsi"
  • / {
  • model = "STMicroelectronics STM32MP135F-DK Discovery Board";
  • compatible = "st,stm32mp135f-dk", "st,stm32mp135";
  • aliases {
  • serial0 = &uart4;
  • serial1 = &usart1;
  • serial2 = &uart8;
  • serial3 = &usart2;
  • };
  • chosen {
  • stdout-path = "serial0:115200n8";
  • };
  • memory@c0000000 {
  • device_type = "memory";
  • reg = <0xc0000000 0x20000000>;
  • };
  • vin: vin {
  • compatible = "regulator-fixed";
  • regulator-name = "vin";
  • regulator-min-microvolt = <5000000>;
  • regulator-max-microvolt = <5000000>;
  • regulator-always-on;
  • };
  • v3v3_ao: v3v3_ao {
  • compatible = "regulator-fixed";
  • regulator-name = "v3v3_ao";
  • regulator-min-microvolt = <3300000>;
  • regulator-max-microvolt = <3300000>;
  • regulator-always-on;
  • };
  • };
  • &bsec {
  • board_id: board_id@f0 {
  • reg = <0xf0 0x4>;
  • st,non-secure-otp;
  • };
  • };
  • &cpu0 {
  • cpu-supply = <&vddcpu>;
  • };
  • &hash {
  • status = "okay";
  • };
  • &i2c4 {
  • pinctrl-names = "default";
  • pinctrl-0 = <&i2c4_pins_a>;
  • i2c-scl-rising-time-ns = <185>;
  • i2c-scl-falling-time-ns = <20>;
  • clock-frequency = <400000>;
  • status = "okay";
  • pmic: stpmic@33 {
  • compatible = "st,stpmic1";
  • reg = <0x33>;
  • status = "okay";
  • regulators {
  • compatible = "st,stpmic1-regulators";
  • buck1-supply = <&vin>;
  • buck2-supply = <&vin>;
  • buck3-supply = <&vin>;
  • buck4-supply = <&vin>;
  • ldo1-supply = <&vin>;
  • ldo4-supply = <&vin>;
  • ldo5-supply = <&vin>;
  • ldo6-supply = <&vin>;
  • vref_ddr-supply = <&vin>;
  • pwr_sw1-supply = <&bst_out>;
  • pwr_sw2-supply = <&v3v3_ao>;
  • vddcpu: buck1 {
  • regulator-name = "vddcpu";
  • regulator-min-microvolt = <1250000>;
  • regulator-max-microvolt = <1250000>;
  • regulator-always-on;
  • regulator-over-current-protection;
  • };
  • vdd_ddr: buck2 {
  • regulator-name = "vdd_ddr";
  • regulator-min-microvolt = <1350000>;
  • regulator-max-microvolt = <1350000>;
  • regulator-always-on;
  • regulator-over-current-protection;
  • };
  • vdd: buck3 {
  • regulator-name = "vdd";
  • regulator-min-microvolt = <3300000>;
  • regulator-max-microvolt = <3300000>;
  • regulator-always-on;
  • st,mask-reset;
  • regulator-over-current-protection;
  • };
  • vddcore: buck4 {
  • regulator-name = "vddcore";
  • regulator-min-microvolt = <1250000>;
  • regulator-max-microvolt = <1250000>;
  • regulator-always-on;
  • regulator-over-current-protection;
  • };
  • vdd_adc: ldo1 {
  • regulator-name = "vdd_adc";
  • regulator-min-microvolt = <3300000>;
  • regulator-max-microvolt = <3300000>;
  • };
  • vdd_usb: ldo4 {
  • regulator-name = "vdd_usb";
  • regulator-min-microvolt = <3300000>;
  • regulator-max-microvolt = <3300000>;
  • };
  • vdd_sd: ldo5 {
  • regulator-name = "vdd_sd";
  • regulator-min-microvolt = <3300000>;
  • regulator-max-microvolt = <3300000>;
  • regulator-boot-on;
  • };
  • v1v8_periph: ldo6 {
  • regulator-name = "v1v8_periph";
  • regulator-min-microvolt = <1800000>;
  • regulator-max-microvolt = <1800000>;
  • };
  • vref_ddr: vref_ddr {
  • regulator-name = "vref_ddr";
  • regulator-always-on;
  • };
  • bst_out: boost {
  • regulator-name = "bst_out";
  • };
  • v3v3_sw: pwr_sw2 {
  • regulator-name = "v3v3_sw";
  • regulator-active-discharge = <1>;
  • regulator-always-on;
  • };
  • };
  • };
  • };
  • &iwdg1 {
  • timeout-sec = <32>;
  • status = "okay";
  • };
  • &pka {
  • status = "okay";
  • };
  • &pwr_regulators {
  • vdd-supply = <&vdd>;
  • vdd_3v3_usbfs-supply = <&vdd_usb>;
  • };
  • &rcc {
  • st,clksrc = <
  • CLK_MPU_PLL1P
  • CLK_AXI_PLL2P
  • CLK_MLAHBS_PLL3
  • CLK_CKPER_HSE
  • CLK_RTC_LSE
  • CLK_SDMMC1_PLL4P
  • CLK_SDMMC2_PLL4P
  • CLK_STGEN_HSE
  • CLK_USBPHY_HSE
  • CLK_I2C4_HSI
  • CLK_USBO_USBPHY
  • CLK_I2C12_HSI
  • CLK_UART2_HSI
  • CLK_UART4_HSI
  • CLK_SAES_AXI
  • >;
  • st,clkdiv = <
  • DIV(DIV_AXI, 0)
  • DIV(DIV_MLAHB, 0)
  • DIV(DIV_APB1, 1)
  • DIV(DIV_APB2, 1)
  • DIV(DIV_APB3, 1)
  • DIV(DIV_APB4, 1)
  • DIV(DIV_APB5, 2)
  • DIV(DIV_APB6, 1)
  • DIV(DIV_RTC, 0)
  • >;
  • st,pll_vco {
  • pll2_vco_1066Mhz: pll2-vco-1066Mhz {
  • src = <CLK_PLL12_HSE>;
  • divmn = <2 65>;
  • frac = <0x1400>;
  • };
  • pll3_vco_417Mhz: pll3-vco-417Mhz {
  • src = <CLK_PLL3_HSE>;
  • divmn = <1 33>;
  • frac = <0x1a04>;
  • };
  • pll4_vco_600Mhz: pll4-vco-600Mhz {
  • src = <CLK_PLL4_HSE>;
  • divmn = <1 49>;
  • };
  • };
  • /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 266, R = 533 (DDR) */
  • pll2:st,pll[url=home.php?mod=space&uid=490]@1[/url] {
  • compatible = "st,stm32mp1-pll";
  • reg = <1>;
  • st,pll = <&pll2_cfg1>;
  • pll2_cfg1: pll2_cfg1 {
  • st,pll_vco = <&pll2_vco_1066Mhz>;
  • st,pll_div_pqr = <1 1 0>;
  • };
  • };
  • /* VCO = 417.8 MHz => P = 209, Q = 24, R = 209 */
  • pll3:st,pll@2 {
  • compatible = "st,stm32mp1-pll";
  • reg = <2>;
  • st,pll = <&pll3_cfg1>;
  • pll3_cfg1: pll3_cfg1 {
  • st,pll_vco = <&pll3_vco_417Mhz>;
  • st,pll_div_pqr = <1 16 1>;
  • };
  • };
  • /* VCO = 600.0 MHz => P = 50, Q = 10, R = 100 */
  • pll4:st,pll@3 {
  • compatible = "st,stm32mp1-pll";
  • reg = <3>;
  • st,pll = <&pll4_cfg1>;
  • pll4_cfg1: pll4_cfg1 {
  • st,pll_vco = <&pll4_vco_600Mhz>;
  • st,pll_div_pqr = <11 59 5>;
  • };
  • };
  • };
  • &rng {
  • status = "okay";
  • };
  • &saes {
  • status = "okay";
  • };
  • &sdmmc1 {
  • pinctrl-names = "default";
  • pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_clk_pins_a>;
  • disable-wp;
  • st,neg-edge;
  • bus-width = <4>;
  • vmmc-supply = <&vdd_sd>;
  • status = "okay";
  • };
  • &uart4 {
  • pinctrl-names = "default";
  • pinctrl-0 = <&uart4_pins_a>;
  • status = "okay";
  • };
  • &uart8 {
  • pinctrl-names = "default";
  • pinctrl-0 = <&uart8_pins_a>;
  • status = "disabled";
  • };
  • &usart1 {
  • pinctrl-names = "default";
  • pinctrl-0 = <&usart1_pins_a>;
  • uart-has-rtscts;
  • status = "disabled";
  • };

  这其中对于米尔的板子有个坑,就是i2c4设置,这个设置的引脚和板子的定义有冲突,如果直接使用,就会是这样地

 

所以必须修改自己的设备树文件,

这里我使用了STM32CubMX工具生成设备树,

 

主要是系统时钟,和DDR3设置

 

DDR3的设置

 

生成代码,好像很轻松是吧,但是别高兴的太早,这个工具生成的代码是编译不过去地,编译不过去地!

那有什么用呢?用处就是可以给你参考地。

其实主要是引脚设置,

  • /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
  • /*
  • * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
  • * Author: STM32CubeMX code generation for STMicroelectronics.
  • */
  • /* For more information on Device Tree configuration, please refer to
  • * https://wiki.st.com/stm32mpu/wiki/Category:Device_tree_configuration
  • */
  • /dts-v1/;
  • #include <dt-bindings/pinctrl/stm32-pinfunc.h>
  • #include <dt-bindings/clock/stm32mp13-clksrc.h>
  • #include "stm32mp13-mx.dtsi"
  • #include "stm32mp135.dtsi"
  • #include "stm32mp13xd.dtsi"
  • #include "stm32mp13-ddr.dtsi"
  • #include "stm32mp13-mydts-pinctrl.dtsi"
  • /* USER CODE BEGIN includes */
  • /* USER CODE END includes */
  • / {
  • model = "STMicroelectronics custom STM32CubeMX board - openstlinux-5.15-yocto-kirkstone-mp1-v22.11.23";
  • compatible = "st,stm32mp135d-mydts-mx", "st,stm32mp135";
  • memory@c0000000 {
  • device_type = "memory";
  • reg = <0xc0000000 0x10000000>;
  • /* USER CODE BEGIN memory */
  • /* USER CODE END memory */
  • };
  • /* USER CODE BEGIN root */
  • /* USER CODE END root */
  • clocks {
  • /* USER CODE BEGIN clocks */
  • /* USER CODE END clocks */
  • clk_hsi: clk-hsi {
  • clock-frequency = <64000000>;
  • /* USER CODE BEGIN clk_hsi */
  • /* USER CODE END clk_hsi */
  • };
  • clk_lse: clk-lse {
  • status = "disabled";
  • /* USER CODE BEGIN clk_lse */
  • /* USER CODE END clk_lse */
  • };
  • clk_hse: clk-hse {
  • clock-frequency = <24000000>;
  • /* USER CODE BEGIN clk_hse */
  • /* USER CODE END clk_hse */
  • };
  • clk_i2sin: clk-i2sin {
  • status = "disabled";
  • /* USER CODE BEGIN clk_i2sin */
  • /* USER CODE END clk_i2sin */
  • };
  • };
  • }; /*root*/
  • &pinctrl {
  • uart4_pins_mx: uart4_mx-0 {
  • pins1 {
  • pinmux = <STM32_PINMUX('A', 15, AF8)>; /* UART4_RX */
  • bias-disable;
  • };
  • pins2 {
  • pinmux = <STM32_PINMUX('A', 9, AF8)>; /* UART4_TX */
  • bias-disable;
  • drive-push-pull;
  • slew-rate = <2>;
  • };
  • };
  • /* USER CODE BEGIN pinctrl */
  • /* USER CODE END pinctrl */
  • };
  • &bsec{
  • status = "okay";
  • /* USER CODE BEGIN bsec */
  • /* USER CODE END bsec */
  • };
  • &rcc{
  • status = "okay";
  • /* USER CODE BEGIN rcc */
  • /* USER CODE END rcc */
  • st,clksrc = <
  • CLK_MPU_HSI
  • CLK_AXI_HSI
  • CLK_MLAHBS_HSI
  • CLK_CKPER_DISABLED
  • CLK_STGEN_HSI
  • CLK_UART4_PCLK1
  • >;
  • st,clkdiv = <
  • DIV(DIV_MPU, 1)
  • DIV(DIV_AXI, 0)
  • DIV(DIV_MLAHB, 0)
  • DIV(DIV_APB1, 0)
  • DIV(DIV_APB2, 0)
  • DIV(DIV_APB3, 0)
  • DIV(DIV_APB4, 0)
  • DIV(DIV_APB5, 0)
  • DIV(DIV_APB6, 0)
  • >;
  • st,pll_vco {
  • /* USER CODE BEGIN rcc_st-pll_vco */
  • /* USER CODE END rcc_st-pll_vco */
  • };
  • };
  • &uart4{
  • pinctrl-names = "default";
  • pinctrl-0 = <&uart4_pins_mx>;
  • status = "okay";
  • /* USER CODE BEGIN uart4 */
  • /* USER CODE END uart4 */
  • };
  • /* USER CODE BEGIN addons */
  • /* USER CODE END addons */

主要是#include "stm32mp13-mydts-pinctrl.dtsi"这个文件,这个文件的内容是根据板子的硬件设置地。这个文件我参考的是stm32mp13-pinctrl.dtsi文件

将里面的内容根据板子的情况修改地。就是冲突的引脚都去除了。这个文件我感觉很是不严谨。最后编译代码。

  • make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 STM32MP_SDMMC=1 STM32MP13=1 DTB_FILE_NAME=stm32mp135d-mydts-mx.dtb

这里也有个坑:如果你使用的是ST的编译SDK toolkit,使用unset LDFLAGS 关掉编译设置。就可以编译通过了,

编译完成,build/stm32mp1/release目录下生成文件:tf-a-stm32mp135d-dk.stm32

使用scp   tf-a-stm32mp135d-dk.stm32  root@192.168.1.105:~  拷贝到开发板当中,

  • dd if=<tf-a file>.stm32 of=/dev/<device partition> bs=1M conv=fdatasync

用DD命令工具,烧写到TF卡。

 

重启开发板

 

系统顺利进入到linux状态。

后记:这个测试我搞了好久,主要是设备树的设置,不断地出错。祝各位顺利。

此帖出自stm32/stm8论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
艾睿电子& Silicon Labs 有奖直播 | 全新蓝牙信道探测:从技术创新到实际应用
直播时间:3月12日(周三)上午10:00
直播奖励:多功能榨汁机、蓝牙音箱、手机支架

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表