<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[YTM32B1HA0 Cache预取偶发造成IBUSERR（及MPU 推荐配置）]]></title><description><![CDATA[<blockquote>
<p dir="auto"><strong>建议：将 MPU Region 0 配置为覆盖全 4 GB 地址空间的 non-cacheable 背景区，并采用 <code>AP_NONE + XN</code> 作为默认拒绝策略；再使用更高编号的 Region 显式开放实际需要访问的内存。下文MPU配置只针对于SDK，MCAL中MPU默认配置和下文一致，无需修改。</strong></p>
</blockquote>
<h2>1. 问题背景</h2>
<p dir="auto">在已知案例中，系统使能 Cache 后偶发 <code>IBUSERR</code>（Instruction Bus Error）；分析怀疑 Cache 预取访问越过有效区域并触及 CUS_NVR 或 其他未开放的NVR区域。将相关 NVR 区域显式配置为 non-cacheable，或关闭 MPU 的特权默认内存映射（<code>PRIVDEFENA = 0</code>）后，问题未再复现。</p>
<p dir="auto"><img src="https://yt-static-main.oss-cn-shanghai.aliyuncs.com/nodebb/8/1a3f2e83-e3fe-4cd6-beba-6cba98066d10.png" alt="IBUSERR 故障现场，BFSR.IBUSERR 置位" class=" img-fluid img-markdown" /><br />
上述现象用于说明配置风险，不代表所有 <code>IBUSERR</code> 都由同一原因引起。实际故障仍应结合 <code>CFSR</code>、<code>HFSR</code>、<code>BFAR</code>、<code>MMFAR</code> 和异常现场进一步确认。</p>
<p dir="auto">ARMv7-M 在 MPU 未覆盖区域可使用默认内存映射；其中部分地址范围具有 Cache 属性。如果使能 <code>PRIVDEFENA</code>，特权访问可能继续使用这些默认属性，导致未显式配置的地址仍可被访问。</p>
<p dir="auto"><img src="https://yt-static-main.oss-cn-shanghai.aliyuncs.com/nodebb/8/7b2133b0-a679-4586-aaed-50bb00e36979.png" alt="ARMv7-M 默认内存映射及 Cache 属性" class=" img-fluid img-markdown" /></p>
<h2>2. 推荐配置原则</h2>
<ol>
<li><strong>Region 0 覆盖全 4 GB 地址空间</strong>：基址为 <code>0x00000000</code>，大小为 <code>4 GB</code>。</li>
<li><strong>Region 0 默认禁用 Cache</strong>：配置为 Strongly-Ordered，<code>TEX=0</code>、<code>C=0</code>、<code>B=0</code>。</li>
<li><strong>Region 0 默认禁止访问和执行</strong>：配置 <code>AP_NONE</code> 和 <code>XN=1</code>。因此它不只是一个 non-cacheable 区域，也是所有未授权地址的兜底拒绝区。</li>
<li><strong>有效内存使用更高编号 Region 覆盖</strong>：MPU 区域重叠时，编号更高的 Region 优先。例如 Region 7/8 可覆盖 Region 6 的部分地址，提供 non-cacheable 映射。</li>
<li><strong>配置前清除全部 Region</strong>：根据 <code>MPU-&gt;TYPE</code> 获取硬件实现的 Region 数量并逐个清除，避免 Bootloader 或前序代码留下的高编号 Region 覆盖当前配置。</li>
<li><strong>关闭特权默认内存映射</strong>：调用 <code>ARM_MPU_Enable(0U)</code>，确保 <code>MPU_CTRL.PRIVDEFENA=0</code>，未被白名单 Region 开放的地址不得访问。</li>
<li><strong>先配置 MPU，再使能 Cache</strong>：避免在内存属性尚未确定时产生 Cache 行填充或预取。</li>
</ol>
<blockquote>
<p dir="auto"><strong>注意：</strong> 如果把 Region 0 改为 <code>AP_FULL</code>，虽然仍可设置 non-cacheable，但会失去“未配置地址默认禁止访问”的白名单保护效果，建议使用白名单控制更精确。</p>
</blockquote>
<h2>3. Region 配置摘要</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Region</th>
<th>地址和大小</th>
<th>内存属性</th>
<th>访问/执行属性</th>
<th>用途</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td><code>0x00000000</code>, 4 GB</td>
<td>Strongly-Ordered, non-cacheable</td>
<td>No Access, XN</td>
<td>全地址空间背景区</td>
</tr>
<tr>
<td>1</td>
<td><code>0x00000000</code>, 32 KB</td>
<td>Normal, non-cacheable</td>
<td>Full Access, executable</td>
<td>ITCM</td>
</tr>
<tr>
<td>2</td>
<td><code>0x02000000</code>, 2 MB</td>
<td>Normal, Write-Through</td>
<td>Full Access, executable</td>
<td>PFlash</td>
</tr>
<tr>
<td>3</td>
<td><code>0x06000000</code>, 256 KB</td>
<td>Shareable Device</td>
<td>Full Access, XN</td>
<td>DFlash</td>
</tr>
<tr>
<td>4</td>
<td><code>0x10000000</code>, 16 KB</td>
<td>Device</td>
<td>Privileged RW, XN</td>
<td>NVR0</td>
</tr>
<tr>
<td>5</td>
<td><code>0x10020000</code>, 16 KB</td>
<td>Device</td>
<td>Privileged RW, XN</td>
<td>NVR1</td>
</tr>
<tr>
<td>6</td>
<td><code>0x20000000</code>, 512 KB</td>
<td>Normal, WBWA</td>
<td>Full Access, executable</td>
<td>SRAM 主区域</td>
</tr>
<tr>
<td>7</td>
<td><code>0x20000000</code>, 128 KB</td>
<td>Normal, non-cacheable, shareable</td>
<td>Full Access, executable</td>
<td>DTCM，覆盖 Region 6</td>
</tr>
<tr>
<td>8</td>
<td><code>0x20020000</code>, 64 KB</td>
<td>Normal, non-cacheable</td>
<td>Full Access, executable</td>
<td>OCRAM non-cacheable 区</td>
</tr>
<tr>
<td>9</td>
<td><code>0x40000000</code>, 2 MB</td>
<td>Device</td>
<td>Privileged RW, XN</td>
<td>APB 外设</td>
</tr>
<tr>
<td>10</td>
<td><code>0x67000000</code>, 128 B</td>
<td>Device, non-shareable</td>
<td>Full Access, executable</td>
<td>QSPI RX Buffer</td>
</tr>
<tr>
<td>11</td>
<td><code>0xE0000000</code>, 1 MB</td>
<td>Device, non-shareable</td>
<td>Privileged RW, XN</td>
<td>PPB</td>
</tr>
</tbody>
</table>
<h2>4. MPU 参考配置</h2>
<pre><code class="language-c">void MPU_Config(void)
{
    uint32_t region;
    uint32_t region_count;

    ARM_MPU_Disable();

    /* Clear all implemented regions to remove any previous MPU configuration. */
    region_count = (MPU-&gt;TYPE &amp; MPU_TYPE_DREGION_Msk) &gt;&gt; MPU_TYPE_DREGION_Pos;
    for (region = 0U; region &lt; region_count; ++region)
    {
        ARM_MPU_ClrRegion(region);
    }

    /* Region 0: 4GB background, strongly-ordered, no access, XN */
    MPU-&gt;RBAR = ARM_MPU_RBAR(0, 0x00000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(1, ARM_MPU_AP_NONE, 0, 0, 0, 0, 0,
                             ARM_MPU_REGION_SIZE_4GB);

    /* Region 1: ITCM 0x00000000 32KB, Normal non-cacheable, RWX */
    MPU-&gt;RBAR = ARM_MPU_RBAR(1, 0x00000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0,
                             ARM_MPU_REGION_SIZE_32KB);

    /* Region 2: PFlash 0x02000000 2MB, Normal write-through, RWX */
    MPU-&gt;RBAR = ARM_MPU_RBAR(2, 0x02000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0,
                             ARM_MPU_REGION_SIZE_2MB);

    /* Region 3: DFlash 0x06000000 256KB, Shareable device, XN */
    MPU-&gt;RBAR = ARM_MPU_RBAR(3, 0x06000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(1, ARM_MPU_AP_FULL, 0, 1, 0, 1, 0,
                             ARM_MPU_REGION_SIZE_256KB);

    /* Region 4: NVR0 0x10000000 16KB, Device, privileged RW, XN */
    MPU-&gt;RBAR = ARM_MPU_RBAR(4, 0x10000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(1, ARM_MPU_AP_PRIV, 0, 0, 0, 1, 0,
                             ARM_MPU_REGION_SIZE_16KB);

    /* Region 5: NVR1 0x10020000 16KB, Device, privileged RW, XN */
    MPU-&gt;RBAR = ARM_MPU_RBAR(5, 0x10020000U);
    MPU-&gt;RASR = ARM_MPU_RASR(1, ARM_MPU_AP_PRIV, 0, 0, 0, 1, 0,
                             ARM_MPU_REGION_SIZE_16KB);

    /* Region 6: SRAM 0x20000000 512KB, Normal WBWA, RWX */
    MPU-&gt;RBAR = ARM_MPU_RBAR(6, 0x20000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 5, 0, 0, 1, 0,
                             ARM_MPU_REGION_SIZE_512KB);

    /* Region 7: DTCM 0x20000000 128KB, Normal non-cacheable shareable, RWX */
    MPU-&gt;RBAR = ARM_MPU_RBAR(7, 0x20000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0,
                             ARM_MPU_REGION_SIZE_128KB);

    /* Region 8: OCRAM 0x20020000 64KB, Normal non-cacheable, RWX */
    MPU-&gt;RBAR = ARM_MPU_RBAR(8, 0x20020000U);
    MPU-&gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0,
                             ARM_MPU_REGION_SIZE_64KB);

    /* Region 9: APB 0x40000000 2MB, Device, privileged RW, XN */
    MPU-&gt;RBAR = ARM_MPU_RBAR(9, 0x40000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(1, ARM_MPU_AP_PRIV, 0, 0, 0, 1, 0,
                             ARM_MPU_REGION_SIZE_2MB);

    /* Region 10: QSPI RX buffer 0x67000000 128B, Device non-shareable, RWX */
    MPU-&gt;RBAR = ARM_MPU_RBAR(10, 0x67000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0,
                             ARM_MPU_REGION_SIZE_128B);

    /* Region 11: PPB 0xE0000000 1MB, Device non-shareable, privileged RW, XN */
    MPU-&gt;RBAR = ARM_MPU_RBAR(11, 0xE0000000U);
    MPU-&gt;RASR = ARM_MPU_RASR(1, ARM_MPU_AP_PRIV, 2, 0, 0, 0, 0,
                             ARM_MPU_REGION_SIZE_1MB);

    /*
     * DefaultMapEn = FALSE: MPU_CTRL.PRIVDEFENA remains 0.
     * RunHFNMIEn = FALSE: MPU_CTRL.HFNMIENA remains 0.
     * ARM_MPU_Enable() enables MemManage faults through SCB-&gt;SHCSR.
     */
    ARM_MPU_Enable(0U);
}
</code></pre>
<h2>5. 集成检查项</h2>
<ul>
<li>确认芯片实现的 MPU Region 数量满足配置需求，可读取 <code>MPU-&gt;TYPE</code> 核对。</li>
<li>确认每个 Region 的基址按 Region 大小对齐，大小为 MPU 支持的 2 的幂。</li>
<li>对照芯片 Memory Map 和链接脚本，覆盖所有 CPU 会访问的代码、数据、启动区、外设、NVR、外部存储及别名地址。</li>
<li>禁用 MPU 后先清除硬件实现的全部 Region，再写入当前配置，避免残留的高编号 Region 取得更高优先级。</li>
<li>保持 Region 0 为最低编号；需要覆盖其属性的有效区域使用更高编号。</li>
<li>NVR、外设寄存器和其他不允许 Cache 的区域必须显式配置为 Device、Strongly-Ordered 或合适的 Normal non-cacheable 类型。</li>
<li>DMA 缓冲区应使用 non-cacheable 区域，或严格执行 Cache clean/invalidate；不能只依赖 Region 0。</li>
<li>根据最小权限原则复核 <code>AP</code> 和 <code>XN</code>。数据区通常应设置 <code>XN</code>，只读程序 Flash 通常不应开放不必要的写权限。</li>
<li>在 MPU 配置完成后再使能 I-Cache/D-Cache；修改运行中的内存属性前后按 CMSIS/芯片手册要求执行 Cache 维护及 <code>DSB</code>/<code>ISB</code>。</li>
<li>若应用确实需要在 HardFault、NMI 中使用 MPU 白名单外的地址，应单独评估 <code>HFNMIENA</code>，不要直接照搬示例。</li>
</ul>
<h2>6. 验证建议</h2>
<p dir="auto">完成配置后，至少执行以下验证：</p>
<ol>
<li><strong>启动验证</strong>：系统可正常完成启动，向量表、启动代码、栈、堆和所有初始化访问均被白名单覆盖。</li>
<li><strong>功能验证</strong>：覆盖 Flash/NVR 擦写、外设访问、DMA、QSPI、通信和低功耗唤醒等实际场景。</li>
<li><strong>负向验证</strong>：在受控测试中访问一个未开放地址，应触发 MemManage Fault，而不是继续采用默认内存属性访问。</li>
<li><strong>稳定性验证</strong>：在客户实际负载、编译优化等级和工作温度下进行长时间压力测试，确认 <code>CFSR.IBUSERR</code>、<code>PRECISERR</code>、<code>IMPRECISERR</code> 等故障位不再出现。</li>
</ol>
<h2>7. 结论</h2>
<p dir="auto">Region 0 建议统一配置为覆盖全 4 GB 的 non-cacheable、No Access、XN 背景区，并关闭 <code>PRIVDEFENA</code>。这种白名单方式可以避免未显式配置区域继承 ARM 默认内存映射和 Cache 属性；具体可访问、可执行及可缓存范围由更高编号 Region 精确开放。</p>
]]></description><link>https://forum.ytmicro.com/topic/2219/ytm32b1ha0-cache预取偶发造成ibuserr-及mpu-推荐配置</link><generator>RSS for Node</generator><lastBuildDate>Sat, 29 Aug 2026 06:01:33 GMT</lastBuildDate><atom:link href="https://forum.ytmicro.com/topic/2219.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 28 Aug 2026 09:25:17 GMT</pubDate><ttl>60</ttl></channel></rss>