<?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[BOOT流程及注意事项]]></title><description><![CDATA[<h1><strong>前言</strong></h1>
<p dir="auto">Bootloader （引导加载程序）是嵌入式系统上电启动后运行的第一段代码。它常驻在 Flash 的最前面（一般从 0x0 地址开始），通常需要被永久保护、绝对不允许被修改。在汽车电子领域，boot loader扮演者非常重要的角色，其作用主要体现在以下方面：</p>
<ol>
<li>防止固件被非法篡改，提高ECU的安全性；</li>
<li>很多场景需要OTA升级，而boot loader提供了更新软件的能力；</li>
<li>隔离底层硬件和上层业务。<br />
本文以YTM32B1系列微控制器（基于 ARM Cortex-M0+/M33/M7 内核） 为例，介绍汽车嵌入式 Boot 的流程。</li>
</ol>
<h1><strong>Boot loader跳转本质</strong></h1>
<p dir="auto">Boot 跳转 App 的本质不是调用某个函数，而是把 CPU 的启动上下文切换到 App 的向量表，让 App 像刚上电复位后启动一样运行。其中，有两个最关键的东西：MSP 和 Reset_Handler。<br />
所以 Boot 要做的事情可以概括为：</p>
<ol>
<li>确认 App 镜像存在且合法；</li>
<li>关闭 Boot 自己已经打开的中断和外设影响；</li>
<li>关闭 SysTick；</li>
<li>清除 NVIC 使能与挂起；</li>
<li>把向量表重定位到 App 首地址；</li>
<li>把 MSP 切换为 App 向量表中的初始栈顶；</li>
<li>跳转到 App 的 Reset_Handler；</li>
</ol>
<h1><strong>标准跳转流程</strong></h1>
<ol>
<li>上电运行Boot<br />
芯片复位后，CPU 默认从 0x0000_0000 取向量表，因此通常先进入 BootLoader。<br />
Boot 可以先完成以下事情：</li>
</ol>
<ul>
<li>时钟初始化</li>
<li>看门狗处理</li>
<li>升级标志检查</li>
<li>固件校验</li>
<li>通信升级<br />
如果无需升级，只需要运行App，直接执行跳转。</li>
</ul>
<ol start="2">
<li>跳转前的收尾工作</li>
</ol>
<ul>
<li>关闭全局中断<br />
SDK调用INT_SYS_DisableIRQGlobal()，MCAL可在特权模式下调用SuspendAllInterrupts()来关闭全局中断。<br />
ps：调用"Sys_GoToSupervisor()"进入特权模式。</li>
<li>关闭Systick</li>
</ul>
<pre><code>SysTick-&gt;CTRL = 0U;
SysTick-&gt;LOAD = 0U;
SysTick-&gt;VAL  = 0U;
</code></pre>
<ul>
<li>关闭所有 NVIC 中断使能</li>
</ul>
<pre><code>NVIC-&gt;ICER[(((uint32_t)IRQn) &gt;&gt; 5UL)] = (uint32_t)(1UL &lt;&lt; (((uint32_t)IRQn) &amp; 0x1FUL));
NVIC-&gt;ICPR[(((uint32_t)IRQn) &gt;&gt; 5UL)] = (uint32_t)(1UL &lt;&lt; (((uint32_t)IRQn) &amp; 0x1FUL));
</code></pre>
<p dir="auto">NVIC属于的寄存器是异步寄存器，有写缓冲延迟，而Cortex-M是流水线架构，需要加上如下两句</p>
<pre><code>__DSB();（数据同步屏障）
__ISB();（指令同步屏障）
</code></pre>
<p dir="auto">在不清楚当前开启了哪些中断或开启的中断较多时，可以使用循环将所有bit都清一遍，对于Cortex-M0+内核：</p>
<pre><code> NVIC-&gt;ICER[0] = 0xFFFFFFFFUL;
 __DSB();
 __ISB();
</code></pre>
<p dir="auto">Cortex-M33内核：</p>
<pre><code>for (uint8_t i = 0; i &lt; 15U; i++) {
    NVIC-&gt;ICER[i] = 0xFFFFFFFFUL;
}
__DSB();
__ISB();
</code></pre>
<ul>
<li>清掉所有 NVIC 挂起位</li>
</ul>
<pre><code>NVIC-&gt;ICPR[0] = 0xFFFFFFFFUL;
__DSB();
__ISB();
for (uint8_t i = 0; i &lt; 15U; i++) {
    NVIC-&gt;ICPR[i] = 0xFFFFFFFFUL;
}
__DSB();
__ISB();
</code></pre>
<ul>
<li>关闭所有外设</li>
</ul>
<ol start="3">
<li>重定位向量表</li>
</ol>
<pre><code>SCB-&gt;VTOR = app_addr;
__DSB();
__ISB();
</code></pre>
<ol start="4">
<li>设置 MSP 并跳转复位入口</li>
</ol>
<pre><code>__set_MSP(app_msp);
__DSB();
__ISB();
app_entry();
</code></pre>
<p dir="auto">其中，</p>
<pre><code>app_msp = *(volatile uint32_t *)addr，app_entry = (pFunction)app_reset，
</code></pre>
<h1><strong>关键注意事项</strong></h1>
<ol>
<li>Boot和App空间一定不能重叠，划分地址时需要注意；</li>
<li>跳转前检查栈顶地址是否合法；</li>
<li>下载App需要修改Flash起始地址；</li>
<li>进入 App 后，应该按正常冷启动流程重新初始化。</li>
</ol>
<h1><strong>代码参考</strong></h1>
<p dir="auto">Uds Fbl demo合集<br />
<a href="https://cloud.ytm32.cn/s/vBECk?path=%2F03_Fbl%20demo" rel="nofollow ugc">https://cloud.ytm32.cn/s/vBECk?path=%2F03_Fbl demo</a></p>
<h1><strong>常见问题总结</strong></h1>
<p dir="auto"><a href="https://forum.ytmicro.com/topic/18/le-bootloader%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB?_=1758613536259">https://forum.ytmicro.com/topic/18/le-bootloader问题汇总?_=1758613536259</a></p>
]]></description><link>https://forum.ytmicro.com/topic/1960/boot流程及注意事项</link><generator>RSS for Node</generator><lastBuildDate>Wed, 20 May 2026 04:41:25 GMT</lastBuildDate><atom:link href="https://forum.ytmicro.com/topic/1960.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 19 May 2026 10:06:37 GMT</pubDate><ttl>60</ttl></channel></rss>