STM32MP157开发板调试笔记

发布者:TranquilJourney最新更新时间:2025-02-28 来源: cnblogs关键字:开发板  调试笔记 手机看文章 扫描二维码
随时随地手机看文章

一、前言

最近在ODYSSEY-STM32MP157C板子上移植arm-trusted-firmware、u-boot以及linux(其实这个开发板官方是有提供完整的系统镜像的,重新移植的原因主要是官方镜像没有使用TF-A,而是使用Uboot-SPL替代TF-A作为FSBL启动)。本以为之前在另一块stm32mp157板子上面移植过这些东西所以应该问题不大,但是由于硬件设计的差异仍然是遇到了一些问题。最后还是花费了些时间解决问题,故写这篇笔记用来记录各环节遇到的问题及解决过程。


二、Trusted Firmware A (TF-A)

版本:arm-trusted-firmware-2.2-stm32mp-r2.3


1、问题

ST官方的开发板都是使用芯片的I2C4驱动PMIC,而这块开发板是用的I2C2接口,本以为将设备树中驱动PMIC节点的i2c4部分改为i2c2,然后添加上i2c2的pinctrl信息就可以了。然而并非如此,会报如下错误:


PANIC at PC : 0x2ffeeab3


Exception mode=0x00000016 at: 0x2ffeeab3

2、原因

I2C4或I2C6被定义为安全外设,而I2C2为非安全外设。


在源码drivers/st/pmic/stm32mp_pmic.c中PMIC初始化函数调用如下:


void initialize_pmic(void)

    --> initialize_pmic_i2c() //从设备树获取pmic的i2c节点信息并初始化

    --> register_non_secure_pmic()

    --> stm32mp_register_non_secure_periph_iomem(i2c_handle.i2c_base_addr)

    --> register_periph_iomem(base, SHRES_NON_SECURE)

由于在函数register_periph_iomem中没有定义I2C_BASE导致进入panic()函数。


3、解决方法

在文件plat/st/stm32mp1/stm32mp1_def.h中定义I2C2_BASE:


#define I2C2_BASE U(0x40013000)

然后修改文件plat/st/stm32mp1/stm32mp1_shared_resources.c中的函数register_periph_iomem如下:


case UART8_BASE:

case IWDG2_BASE:

case I2C2_BASE: //添加非安全外设I2C2

/* Allow drivers to register some non-secure resources */

VERBOSE('IO for non-secure resource 0x%xn',

(unsigned int)base);

if (state != SHRES_NON_SECURE) {

panic();

}


return;


default:

panic();

break;

三、U-Boot

版本:u-boot-2020.01-stm32mp-r2.2


1、问题

移植完成第一次进入u-boot首先出现如下提示:


invalid MAC address in OTP 00:00:00:00:00:00

Net:

Error: ethernet@5800a000 address not set.

No ethernet found.


设置ethaddr环境变量即可:


env set ethaddr 14:16:0B:0B:11:31

上面这个倒是不算问题,重点是接下来遇到的问题。在执行dhcp命令时遇到如下错误:


STM32MP> dhcp

EQOS_DMA_MODE_SWR stuckFAILED: -110STM32MP>

这显然是网卡有问题。


2、原因

查看硬件原理图以太网部分发现和ST官方的DK2开发板有些不同。官方开发板的千兆以太网(RGMII)的125MHZ时钟来自PHY芯片,而我手上这块开发板的设计默认是需要由MPU内部RCC提供125MHZ时钟。除此之外,PHY地址硬件设计上也不相同,需要修改。

image

image

在STM32MP157参考手册(RM0436)中的Figure 83对以太网时钟有详细的描述


image

由上图可知若要使用RCC作为125MHZ时钟来源则需要配置SYSCFG寄存器的ETH_CLK_SEL字段,除此之外还需要选择使用RCC的pll4_p_ck或是pll3_q_ck作为具体时钟来源(我选择的是PLL4P)。既然知道了问题所在,接下来就是修改代码适配硬件。


3、解决方法

首先是时钟部分的改动。因为使用了TF-A所以U-Boot配置为trusted模式,修改u-boot源码中的时钟配置是无效的,需要修改TF-A中的时钟配置。主要就是配置PLL4P输出125MHZ时钟,关于PLL的详细信息需要查阅参考手册(RM0436)的第10章RCC(Reset and clock control)的PLL章节。

image

在TF-A源码设备树的rcc节点中添加如下代码配置PLL4时钟频率:


&rcc {

    ......

    /* VCO = 750.0 MHz => P = 125, Q = 62.5, R = 62.5 */

pll4: st,pll@3 {

compatible = 'st,stm32mp1-pll';

reg = <3>;

cfg = < 3 124 5 11 11 PQR(1,1,1) >;

};

    ......

};

cfg中参数含义如下:


cfg =

因此按照上述参数计算各部分时钟频率结果如下:


F(ref_ck) = HSE / (DIVM + 1)


Using the PLLs in integer mode


For the PLL3 and PLL4, the VCO frequency (FVCO) is given by the following expression:


F(VCO) = F(ref_ck) x (DIVN + 1)


And the frequency at the output of the post-dividers is given by with y = P, Q or R:


F(pll_y_ck) = F(VCO) / (DIVy + 1)


VCO = HSE / (DIVM + 1) * (DIVN + 1) = 24MHZ / (3 + 1) * (124 + 1) = 750MHZ

PLL4P = P = VCO / (DIVP + 1) = 750MHZ / (5 + 1) = 125MHZ

PLL4Q = VCO / (DIVQ + 1) = 750MHZ / (11 + 1) = 62.5MHZ

PLL4R = VCO / (DIVR + 1) = 750MHZ / (11 + 1) = 62.5MHZ 

这样就得到了期望的125MHZ时钟。接着还需要将Ethernet的时钟选为PLL4P,在rcc节点修改如下内容:


&rcc {

    ......

    st,pkcs = <

......

-       CLK_ETH_DISABLED //删除这个

+ CLK_ETH_PLL4P //添加这个

......

>;

    ......

};

至此,千兆以太网125MHZ时钟频率就配置好了。接下来需要修改的就是u-boot源码的设备树中ethernet0节点内容,主要是修改时钟选择部分的内容。根据手册可知选择RCC作为千兆以太网125 MHz时钟需要将寄存器SYSCFG_PMCSETR的ETH_CLK_SEL位配置为1:

image

在源码drivers/net/dwc_eth_qos.c文件中eqos_probe_resources_stm32函数会调用board_interface_eth_init函数(文件路径board/st/stm32mp1/stm32mp1.c)根据设备树内容配置该寄存器该位,如下:


/* eth init function : weak called in eqos driver */

int board_interface_eth_init(struct udevice *dev,

     phy_interface_t interface_type)

{

u8 *syscfg;

u32 value;

bool eth_clk_sel_reg = false;

......

/* Gigabit Ethernet 125MHz clock selection. */

eth_clk_sel_reg = dev_read_bool(dev, 'st,eth_clk_sel');

......

syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);

......

switch (interface_type) {

......

case PHY_INTERFACE_MODE_RGMII:

case PHY_INTERFACE_MODE_RGMII_ID:

case PHY_INTERFACE_MODE_RGMII_RXID:

case PHY_INTERFACE_MODE_RGMII_TXID:

if (eth_clk_sel_reg)

value = SYSCFG_PMCSETR_ETH_SEL_RGMII |

SYSCFG_PMCSETR_ETH_CLK_SEL;

else

value = SYSCFG_PMCSETR_ETH_SEL_RGMII;

debug('%s: PHY_INTERFACE_MODE_RGMIIn', __func__);

break;

......

}


/* clear and set ETH configuration bits */

writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII |

       SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL,

       syscfg + SYSCFG_PMCCLRR);

writel(value, syscfg + SYSCFG_PMCSETR);


return 0;

}

因此需要在设备树ethernet0节点下添加st,eth_clk_sel(文件路径arch/arm/dts/stm32mp151.dtsi)如下:


ethernet0: ethernet@5800a000 {

......

    st,eth_clk_sel;

......

};

但是只是这么做还不够,进入u-boot会提示如下:


Net:   No phy clock provided -61eth0: ethernet@5800a000

根据提示可以定位到代码位置在drivers/net/dwc_eth_qos.c的eqos_probe_resources_stm32函数中:


/*  Get ETH_CLK clocks (optional) */

ret = clk_get_by_name(dev, 'eth-ck', &eqos->clk_ck);

if (ret)

    pr_warn('No phy clock provided %d', ret);

因此在设备树ethernet0添加eth-ck如下:


ethernet0: ethernet@5800a000 {

......

    clock-names = 'stmmaceth',

        'mac-clk-tx',

        'mac-clk-rx',

+       'eth-ck', //添加这行

        'ethstp';

    ......

    st,eth_clk_sel;

......

};

但是但是,这么做依旧不够,修改后u-boot执行dhcp命令报错如下:


STM32MP> dhcp

stm32mp1_clk_get_id: clk id 112 not found

clk_enable(clk_ck) failed: -22eqos_start_clks() failed: -22FAILED: -22STM32MP>

因为添加了时钟名后还需要添加对应的时钟节点,因此在设备树ethernet0节点添加ETHCK_K如下:


ethernet0: ethernet@5800a000 {

......

    clock-names = 'stmmaceth',

        'mac-clk-tx',

        'mac-clk-rx',

        'eth-ck',

        'ethstp';

    clocks = <&rcc ETHMAC>,

        <&rcc ETHTX>,

        <&rcc ETHRX>,

+       <&rcc ETHCK_K>, //添加这行

        <&rcc ETHSTP>;

    st,eth_clk_sel;

......

};

最后还得修改phy地址以及添加phy复位引脚(需和硬件设计一致),否则会有如下报错提示:


地址错误:


STM32MP> dhcp

Could not get PHY for ethernet@5800a000: addr 0

phy_connect() failedFAILED: 0

复位引脚缺失错误


Net:   gpio_request_by_name(phy reset) not provided -2eth0: ethernet@5800a000

修改如下:


ðernet0 {

......

mdio0 {

......

phy0: ethernet-phy@7 {

reg = <7>; //phy地址

            reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; //phy复位引脚

};

};

};

复位操作在源码drivers/net/dwc_eth_qos.c函数eqos_probe_resources_stm32匹配设备树,函数eqos_start_resets_stm32执行。


以上修改完成后重新编译u-boot启动后执行网络操作命令就正常了:


STM32MP> dhcp

ethernet@5800a000 Waiting for PHY auto negotiation to complete........... done

BOOTP broadcast 1

BOOTP broadcast 2

BOOTP broadcast 3

BOOTP broadcast 4

DHCP client bound to address 192.168.10.85 (2875 ms)

STM32MP>

四、Linux Kernel

版本:linux-5.4-stm32mp-r2.4


1、问题

既然U-Boot部分网络有问题,那么在Linux中也会有同样的问题。但是在linux中只做u-boot中的改动网络仍然无法正常工作,会报如下错误:


root@arm:~# [  316.042400] stm32-dwmac 5800a000.ethernet eth0: no phy at addr -1

[  316.047061] stm32-dwmac 5800a000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)

[  316.124044] stm32-dwmac 5800a000.ethernet eth0: no phy at addr -1

[  316.128703] stm32-dwmac 5800a000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)

[  316.186944] stm32-dwmac 5800a000.ethernet eth0: no phy at addr -1

[  316.191693] stm32-dwmac 5800a000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)

[  316.242397] stm32-dwmac 5800a000.ethernet eth0: no phy at addr -1

[  316.247066] stm32-dwmac 5800a000.ethernet eth0: stmmac_open: Cannot attach to PHY (error: -19)

2、原因

在Linux设备树的ethernet0节点还需要添加一些phy芯片信息(这个板子是KSZ9031)并且要配置相关的驱动。


3、解决方法

make menuconfig


Linux/arm 5.4.192 Kernel Configuration

Device Drivers  ---> 

[*] Network device support  ---> 

-*-   PHY Device support and infrastructure  --->

   <*>   Micrel PHYs

完整的ethernet0设备树内容如下:


ethernet0: ethernet@5800a000 {

    compatible = 'st,stm32mp1-dwmac', 'snps,dwmac-4.20a';

    reg = <0x5800a000 0x2000>;

    reg-names = 'stmmaceth';

    interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,

    <&exti 70 IRQ_TYPE_LEVEL_HIGH>;

    interrupt-names = 'macirq',

    'eth_wake_irq';

    clock-names = 'stmmaceth',

                'mac-clk-tx',

                'mac-clk-rx',

+               'eth-ck', //添加这行

                'ethstp';

    clocks = <&rcc ETHMAC>,

            <&rcc ETHTX>,

            <&rcc ETHRX>,

+           <&rcc ETHCK_K>, //添加这行

            <&rcc ETHSTP>;

+   st,eth-clk-sel; //添加这行

    st,syscon = <&syscfg 0x4>;

    snps,mixed-burst;

    snps,pbl = <2>;

    snps,en-tx-lpi-clockgating;

    snps,axi-config = <&stmmac_axi_config_0>;

    snps,tso;

    power-domains = <&pd_core>;

    status = 'disabled';


    stmmac_axi_config_0: stmmac-axi-config {

        snps,wr_osr_lmt = <0x7>;

        snps,rd_osr_lmt = <0x7>;

        snps,blen = <0 0 0 0 16 8 4>;

    };

};


ðernet0 {

status = 'okay';

pinctrl-0 = <ðernet0_rgmii_pins_a>;

pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>;

pinctrl-names = 'default', 'sleep';

[1] [2]
关键字:开发板  调试笔记 引用地址:STM32MP157开发板调试笔记

上一篇:STM32MP157移植Qt5.12.10
下一篇:ThreadX——IPC应用之消息队列

推荐阅读最新更新时间:2026-03-25 11:29

STM32MP157开发板调试笔记
一、前言 最近在ODYSSEY-STM32MP157C板子上移植arm-trusted-firmware、u-boot以及linux(其实这个开发板官方是有提供完整的系统镜像的,重新移植的原因主要是官方镜像没有使用TF-A,而是使用Uboot-SPL替代TF-A作为FSBL启动)。本以为之前在另一块stm32mp157板子上面移植过这些东西所以应该问题不大,但是由于硬件设计的差异仍然是遇到了一些问题。最后还是花费了些时间解决问题,故写这篇笔记用来记录各环节遇到的问题及解决过程。 二、Trusted Firmware A (TF-A) 版本:arm-trusted-firmware-2.2-stm32mp-r2.3 1、问题
[单片机]
<font color='red'>STM32MP157</font><font color='red'>开发板</font><font color='red'>调试</font><font color='red'>笔记</font>
STM32MP157 Linux系统移植开发篇12:Linux内核MIPI LCD驱动移植
本文章为《STM32MP157 Linux系统移植开发篇》系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板)。stm32mp157是ARM双核,2个A7核,1个M4核,A7核上可以跑Linux操作系统,M4核上可以跑FreeRTOS、RT-Thread等实时操作系统,STM32MP157开发板所以既可以学嵌入式linux,也可以学stm32单片机。针对FS-MP1A开发板,除了Linux系统移植篇外,还包括其他多系列教程,包括Cortex-A7开发篇、Cortex-M4开发篇、扩展板驱动移植篇、Linux应用开发篇、FreeRTOS系统移植篇、Linux驱动开发篇、硬件设计篇、人工智能机器
[单片机]
stm32mp157教程案例 STM32MP157移植LVGL
1 简介 LVGL(Light and Versatile Embedded Graphics Library)是一个免费开源的嵌入式图形库,界面美观, 内存占用低, 支持C和Python等开发方式。早在几年前它就表现得十分惊艳,现如今被越来越多的人喜爱。笔者之前是使用6版本在单片机上面运行,如今都已经更新到7版本多了,人往高处走,终究得跟上最新版本,于是便有了关于LVGL7版本在linux上移植的这件篇笔记。 本次教程使用的开发板是万象奥科的HD-STM32MP157-STY开发板。该开发板使用STM32MP1家族中是目前性能强劲,资源最为丰富的一款处理器STM32MP157DAA,双核ARM Cortex-A7 @800M
[单片机]
<font color='red'>stm32mp157</font>教程案例 <font color='red'>STM32MP157</font>移植LVGL
ARM应用调试思路、方法总结、笔记
一、应用调试1:使用strace命令来跟踪系统调用 二、应用调试2:使用GDB来调试应用程序 编译gdb,gdbserver tar xjf gdb-7.4.tar.bz2 cd gdb-7.4/ ./configure --target=arm-linux make 把arm-linux-gdb复制到/bin目录 cd gdb/gdbserver/ ./configure --host=arm-linux cp gdbserver /work/nfs_root/first_fs/bin 编译要调试的应用,编译时加上-g选项 调试: 1. 在ARM板上 gdbserver 192.168.1.17:2345 ./test_debu
[单片机]
W801单片机学习笔记——调试器的配置与使用(适用于W801和W806)
1.前言 在以往的Cortex-M内核单片机的开发中,最离不开的一个东西就是调试器,什么J-Link,ST-Link,DAP-Link等等,没了他们调试程序感觉浑身难受,效率直线下降。调试器就好比是战士的枪,W801单片机的开发当中怎么能够没有。与W801单片机配套的调试器叫做ICE,该调试器官方卖得很贵,不过大佬们已经攻克了下来,笔者用的ICE正是大佬们设计的ICE 记得给这位UP点赞打赏哦。 做好之后是这样的: 2.调试器设置 首先,打开工程的属性,并找到Debug页,如下图: 按照红色框中设置,并点击Settings... ,点击后如下图所示: 点击黄色框右下方的Update即可检查ICE是否与W801正
[单片机]
W801单片机学习<font color='red'>笔记</font>——<font color='red'>调试</font>器的配置与使用(适用于W801和W806)
MPU6500驱动调试笔记(STM32F407+SPI)
一、问题背景 本来最开始实验室使用MPU6050芯片,采集陀螺仪原始数据做生理信号采集,但算法发现用IIC接口采样率(200hz)达不到要求。故寻找同类型支持SPI协议的芯片去替代,发现了这块MPU6500,还便宜,就用起来。在读写寄存器费了些周折(每读一次数据寄存器需要短暂延时,不能spi连续读。写寄存器有100ms延时要求),算是记录下吧 二、注意事项 NOTE: 1、由datasheet P16页SPI时序图得:CPOL=1,CPHA=1;(多谢网友指正页码) 2、采样频率200hz,陀螺仪量程正负250dps,加速度量程正负2g,16bit输出; 三、源代码 /* *********************
[单片机]
MPU6500驱动<font color='red'>调试</font><font color='red'>笔记</font>(STM32F407+SPI)
AVRWARE++开发笔记4:调试III型测试板
本文只针对于初学者,高手请绕过! 本文介绍III型测试板焊接完成后的调试步骤。 1、上电前准备 III型测试板焊接完成后,首先应仔细检查整个电路板是否有漏焊、虚焊或短路的情况发生,检查无误后,用万用表的测量二极管通断档,对如下图所示电路的C2和C4进行短路测试,如果发生短路现象,切不可上电。 短路故障排除步骤: a、短路发生后,应首先检查C2、C4、C9和C11电容是否焊接正确,如果发生短焊现象,应重新焊接; b、检查P2是否焊接正确,如果发生短焊现象,应重新焊接; c、检查CH341T是否焊接正确,如果发生短焊现象,应重新焊接; d、检查ATMEGA168PA-AU是否焊接正确,如
[单片机]
AVRWARE++开发<font color='red'>笔记</font>4:<font color='red'>调试</font>III型测试板
STM32学习笔记之中断调试
1、 基本的GPIO配置,注意,因为需要用到普通IO口作为中断输入口,因此是用了IO口德复用功能,因此必须打开RCC_APB2Periph_AFIO时钟,负责复用IO无效。 2、 IO口复用功能映射 3、 嵌套中断向量配置 调试发现这几句话是必须要的,不然不能产生中断!!! NVIC_IRQChannel 这里的值需要注意一下,与固件库给出的值不符!!定义在stm32f103x.h头文件中。 4、 外部中断/事件配置 5、 在stm32f10x_it.c中添加中断处理函数,函数名称格式为(PPP代表中断名称) 函数名称在startup_stm32f10x_xx.s中寻找。 记得还需要在stm32f10x
[单片机]
STM32学习<font color='red'>笔记</font>之中断<font color='red'>调试</font>
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved