|
[ZEPHYR]SDMMC2 Clock Initialization Failure on M4 Core (PLL2R Frequency Mismatch) 問題詢問 問題背景說明 我目前在 STM32H747I-DISCO(Zephyr RTOS)上,嘗試在 Cortex-M4 啟用 SDMMC2。 專案基於標準範例 rpmsg_service,採用 M7/M4 雙核心架構。 在 SDMMC2 driver 初始化階段,系統持續回報 時鐘初始化錯誤。 檢查後發現: M7 核心實際設定的 PLL2 輸出頻率,與 M4 核的 DTS overlay 所預期的頻率不一致(在M7中確認設定數值正確)。 錯誤現象與診斷結果 啟動時出現: stm32_sdmmc: Failed to enable SDMMC domain clock stm32_sdmmc: failed to init clocks 程式內以 HAL 量測: PLL2_R = 64 MHz(實際) 但 M4 的 DTS overlay 中 PLL2 參數為: div-m = 5, mul-n = 96, div-r = 10, HSE=25 MHz 計算結果為 48 MHz(預期) → 實際 64 MHz vs DTS 48 MHz 的時鐘衝突,導致 SDMMC 初始化失敗。 系統環境 Board: stm32h757i_eval Base Sample: rpmsg_service(延伸加入 SDMMC2 / FDCAN) Zephyr 版本: 0.17.2 主要待確認問題
在ZEPHYR PROJECT GITHUB有一些Oerlay 設定: https://github.com/zephyrproject-rtos/zephyr/discussions/100423 |
STM32H743 以太网 为什么需要设置在0x30040000才能使用
可以使用Manage Runtime Environment工具创建基于标准库的工程吗?
DMAMUX 使用内部外设Request Event(不使用TIM12和LPTIM)
LSM6DSLTR 请问这个料有没最好替代料!!!
STM32H743 的ADC线性校准问题
关于使用STM32CubeIDE for vscode配置freertos的问题
NUCLEO-H7S3L8开发板,操作板载FLASH出错,无法进入APP
H743 ulpi phy 引脚配置
STM32H747XG下载一次仿真器就检测不到,运行不能正常
——STM32H747XG下载一次仿真器就检测不到,运行不能正常 原理图是否有问
微信公众号
手机版
[md]你好: 我看目前sdmmc_stm32.c 內已經有
stm32_sdmmc_clock_enable()內已經採用clock_control_get_rate, 目前也是卡住在這邊無法獲取正確的clock, m4 overlay中也已經移除pll2相關clock設定但是目前看起來還是讀取異常問題 看起來M7/M4所讀取道的系統時鐘差異蠻多導致。Starting stm32h747i_disco with CPU frequency: 400 MHz
m7 PLL1_P: 400000000 Hz
m7 PLL1_Q: 200000000 Hz
m7 PLL1_R: 400000000 Hz
m7 PLL2_P: 240000000 Hz
m7 PLL2_Q: 120000000 Hz
m7 PLL2_R: 48000000 Hz
UART device 'serial@40007c00' is ready.
Msg Service [master] demo started
_id=0
Starting stm32h747i_disco with CPU frequency: 200 MHz
m4 PLL1_P: 128000000 Hz
m4 PLL1_Q: 64000000 Hz
m4 PLL1_R: 128000000 Hz
m4 PLL2_P: 76800000 Hz
m4 PLL2_Q: 38400000 Hz
m4 PLL2_R: 15360000 Hz
PLL2_R = 64000000
[00:00:10.019,000] [1;31m<err> stm32_sdmmc: Failed to enable SDMMC domain clock [0m
[00:00:10.019,000] [1;31m<err> stm32_sdmmc: failed to init clocks[0m
✅ 解决方案(推荐做法)
✅ 1. M4 侧 DTS 中不要写死 PLL 参数
你应该移除 M4 DTS 中所有与 PLL2 相关的配置 ,只保留对 SDMMC2 的
clocks = <&rcc STM32_CLOCK_BUS_SDMMC2 ...>的引用,不要指定频率 。&sdmmc2 { clocks = <&rcc STM32_CLOCK_BUS_SDMMC2 0xXXXXXXXX>; status = "okay"; /* 不要写 clock-frequency = <48000000>; 或其他频率 */ };✅ 2. 使用
clock-controlAPI 动态获取时钟频率Zephyr 提供了
clock_control_get_rate()API,你可以在 SDMMC 驱动初始化前调用它,动态获取 SDMMC 域的实际时钟频率 ,而不是依赖 DTS 写死值。示例代码(在 SDMMC 驱动初始化前):
``
include <zephyr/drivers/clock_control.h>
include <zephyr/drivers/clock_control/stm32_clock_control.h>
const struct device *clk_dev = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); uint32_t clk_rate;
clock_control_get_rate(clk_dev, (clock_control_subsys_t)&sdmmc2_clk_cfg, &clk_rate); LOG_INF("SDMMC2 domain clock rate: %u Hz", clk_rate);
✅ 3. 修改 SDMMC 驱动以使用实际时钟频率
Zephyr 的
stm32_sdmmc驱动默认会尝试根据 DTS 中的clock-frequency来配置 SDMMC 的时钟分频器。 你需要补丁驱动 ,让它使用clock_control_get_rate()获取的实际频率,而不是 DTS 写死值。✅ 4. 补丁建议(Zephyr 驱动层)
在
drivers/sdmmc/stm32_sdmmc.c中,找到sdmmc_clock_init()函数,修改如下:uint32_t clk_rate; clock_control_get_rate(dev_data->clock_dev, (clock_control_subsys_t)&dev_config->pclken, &clk_rate); /* 用 clk_rate 而不是 DTS 中的 clock-frequency */✅ 5. 额外建议:M7 启动完成后通知 M4
你可以在 M7 的 Zephyr 应用中,等 PLL2 配置完成后再启动 M4 核 ,确保 M4 启动时时钟已稳定。
✅ 6. 参考 Zephyr 社区讨论
你提到的 GitHub 讨论 zephyrproject-rtos/zephyr#100423 中,已有开发者提出类似问题 ,并最终通过:
clock_control_get_rate()动态获取频率