风过空庭,字句正徐来。
关于关于本站关于我给我点钱
更多时间线友链文件服务wiki
联系写留言发邮件GitHub
© 2024-2026 yono. | RSS 订阅 | 站点地图 | | Stay hungry. Stay foolish.
Powered by Mix Space&
白い
.
| 粤 ICP 备2024284785号-1 |
正在被0人看爆
且听风定,再看句成。

GD32H7 的 MPU 备查——关于 0x0000 寻址区的配置

w3w
AI·GEN

关键洞察

GD32H7 的 MPU 备查——关于 0x0000 寻址区的配置

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • 旧的背景故事

    之前有过 GD32H7 打开网络功能的尝试,因为没有在最终工程产品中用到该芯片,仅作评估后封存。

    当时的现象是,完全采用与官方例程一模一样的库、外设配置、调用顺序、操作方法,只是我将官方的 keil 例程改为 cmake-gcc 工程。问题是官方例程编译烧录后一切正常,而我的工程编译后无论如何都无法 ping 通。

    我对 lwip 这个网络库、ETH 外设这块的了解实在有限,GD 支持也无法找到原因所在。

    原因

    总的来说,GD32H7 芯片需要以类似这样的配置方法,将 0x0000 开始的整个寻址区域,都设置 MPU 保护,作为背景设置,然后后续的 MPU 配置块再做实际配置。

    mpu_region_init_struct mpu_init_struct;
    /* disable MPU */
    ARM_MPU_Disable();
       
    mpu_init_struct.region_number       = MPU_REGION_NUMBER0;
    mpu_init_struct.region_base_address = 0x00000000U;
    mpu_init_struct.instruction_exec    = MPU_INSTRUCTION_EXEC_NOT_PERMIT;
    mpu_init_struct.access_permission   = MPU_AP_NO_ACCESS;
    mpu_init_struct.tex_type            = MPU_TEX_TYPE0;
    mpu_init_struct.access_shareable    = MPU_ACCESS_SHAREABLE;
    mpu_init_struct.access_cacheable    = MPU_ACCESS_NON_CACHEABLE;
    mpu_init_struct.access_bufferable   = MPU_ACCESS_NON_BUFFERABLE;
    mpu_init_struct.subregion_disable   = 0x87;
    mpu_init_struct.region_size         = MPU_REGION_SIZE_4GB;  
       
    mpu_region_config(&mpu_init_struct);
    mpu_region_enable();
    /* enable MPU */
    ARM_MPU_Enable(MPU_MODE_PRIV_DEFAULT);
    

    问题是如何产生的

    在 GD32H7 手册1.3 存储器映射上可见

    0x0000 0000~0x0007 FFFF 划归为 ITCM RAM(来自共享 RAM),但是这个区域又被划归为代码区域。我暂时不太理解其意图。总之就是在内核运行的过程中将该区域认为是 RAM 区,所以有读写可能。

    依据参考材料的说法,GD 官方勘误表或任何手册都没有描述这一点。当然官方例程很多时候也没有做到这一点,否则我此前改为 gcc 编译应当是一切正常。只有 ST 官方的甚至 touchgfx 这个图形库手册而非芯片手册中有这样的描述。

    M7处理器上,必须防止对外部存储器的推测性访问,否则可能引发高延迟或系统错误。 对于STM32H7R/S,这将影响访问内存的AXI主设备,并显著降低图形性能。 MPU可通过控制可访问的地址范围来防止推测性读取访问。 最简单的方法是使用包含整个内存区域的背景区域,通过将其设置为“强排序,永不执行”来限制访问。 背景区域应定义在默认区域ID-1中,因为所有其他区域的优先级都将高于此区域。 然后,应为需要访问的内存区域定义具有相应设置的其他MPU区域。 在STM32H7R/S上最多可定义16个区域。

    也就是这是一个 M7 内核原设计就有的缺陷,而我使用 stm32H7 只是 ST 官方做成芯片时使用某种手段规避了问题,或者甚至只是恰巧没有碰到。

    参考资料备查

    GD32H7移植NEXTDUO问题

    https://forum.anfulai.cn/forum.php?mod=viewthread&tid=125782&extra=

    GD32H757ZMT6 仅因 Flash/Load image 布局变化,程序运行稳定性就出现明显差异

    https://forum.anfulai.cn/forum.php?mod=viewthread&tid=131926&extra=