概述
程序运行中经常需要软复位(大白话:让开发板像电脑一样"重启",程序从头再跑一遍):参数修改后重启生效、异常后恢复、OTA(空中升级,大白话:像手机系统更新一样通过网络升级固件)升级后进入新固件等。复位有 上电复位(POR,大白话:相当于拔掉电源再插上,一切重新初始化,最彻底) 与 系统复位(大白话:只重启软件、不走完整断电流程,速度更快)两种方式。本教程基于官方 helloworld 示例,演示倒计时后调用 bl_sys_reset_por() 触发软件复位,重启后程序从头执行。
用大白话讲:软件复位就像电脑的"重启"——手机卡了你长按电源键重启,程序改了设置也要重启才生效。开发板也一样:运行中调用复位函数,程序立刻从头执行,和手动按开发板上的复位键效果类似,只是由代码控制、不用动手。
本教程基于安信可官方 SDK(Ai-Thinker-Open/Ai-Thinker-WB2,版本
release_bl_iot_sdk_1.6.40)的官方示例applications/get-started/helloworld编写,代码可在本地 SDK 中直接找到。
打开终端,进入官方 helloworld 示例工程目录:
cd ~/Ai-Thinker-WB2/applications/get-started/helloworld
说明:
cd是"进入目录"的命令,~表示你的用户主目录。这条命令进入 helloworld 示例工程,后面所有make命令都要在这个目录里执行;如果提示No such file or directory(没有这个目录),说明路径不对,见文末 FAQ。
打开 helloworld/main.c,本步完整代码已移至文末,见:
📜 完整代码 — 位于本页「完整代码」章节,默认折叠,点击展开,与官方示例(
applications/get-started/helloworld/helloworld/main.c)完全一致。
代码要点:
| 代码 | 作用 |
|---|---|
bl_sys_reset_por() |
模拟重新上电复位;不调用它程序就不会重启,这是本教程的核心 |
vTaskDelay(1000 / portTICK_PERIOD_MS) |
延时 1 秒再继续;没有它倒计时会瞬间跳完看不清 |
printf("Restarting now.\r\n") |
复位前打印提示;让你确认"马上要重启了",便于观察 |
💡 官方还有 系统复位
bl_sys_reset_system()(软复位,不复位外部复位逻辑)。两种方式对应用通常无差别:都会重新启动固件,main重新执行。
在工程目录执行编译:
make -j8
说明:
make是"编译工程"的命令,把源代码翻译成开发板能运行的机器码;-j8表示用 8 个核心并行编译,更快。
编译成功后生成固件 build_out/helloworld.bin(固件:编译后烧进开发板的程序,相当于开发板的"操作系统+你的程序")。
开发板保持 USB 连接,确认串口设备号后执行烧录:
make flash p=/dev/ttyUSB0 b=921600
说明:
make flash是"烧录"命令,把编译好的固件下载进芯片(烧录:把程序写进芯片的过程);p=/dev/ttyUSB0是串口设备号,要换成你电脑上实际的串口(Windows 下形如COM3),b=921600是烧录波特率(传输速度)。
⏳ 烧录过程中按提示长按开发板 EN 键进入下载模式,等待进度条完成即烧录成功。若一直卡在等待或报串口打不开,见文末 FAQ。
烧录完成后开发板自动重启运行,打开串口助手(波特率 921600)观察日志:
Hello World.
Restarting in 10 seconds...
Restarting in 9 seconds...
...
Restarting in 0 seconds...
Restarting now.
Hello World. ← 复位后从头开始
Restarting in 10 seconds...
...
每 1 秒打印一次倒计时,10 秒后打印 Restarting now.,开发板立即自动重启,再次从 Hello World. 开始新一轮倒计时,周而复始。
💡 进阶验证:把
bl_sys_reset_por()换成bl_sys_reset_system()重新编译烧录,观察行为差异——两者都会重启固件,系统复位不经过完整 POR 流程,复位更快。
✅ 预期结果:打印
Restarting now.后开发板立即重启、再次出现Hello World.和倒计时,即验证成功。若只打印了一次Hello World.后日志停滞、没有倒计时,说明程序没跑起来或复位没生效,见文末 FAQ。
代码执行流程
例程从启动到运行的完整流程如下(图中的循环箭头表示反复执行):
本文 API 汇总
vTaskDelay(ms)
让当前任务挂起指定毫秒数,期间让出 CPU 给其他任务(本教程用于复位前倒计时)。
参数:
ms:延时毫秒数,可选值:任意非负整数(内部经pdMS_TO_TICKS换算为系统节拍)
返回值:无
完整代码
以下为 helloworld/main.c 完整源码,与官方示例(applications/get-started/helloworld/helloworld/main.c)完全一致:
📜 点击展开 helloworld/main.c 完整代码
/*
* @Author: xuhongv@yeah.net xuhongv@yeah.net
* @Date: 2022-10-03 15:02:19
* @LastEditors: xuhongv@yeah.net xuhongv@yeah.net
* @LastEditTime: 2022-10-08 14:55:16
* @FilePath: \bl_iot_sdk_for_aithinker\applications\get-started\helloworld\helloworld\main.c
* @Description: Hello world
*/
#include <stdio.h>
#include <string.h>
#include <FreeRTOS.h>
#include <task.h>
#include <blog.h>
#include "bl_sys.h"
void main(void)
{
printf("Hello World.\r\n");
for (int i = 10; i >= 0; i--)
{
printf("Restarting in %d seconds...\r\n", i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("Restarting now.\r\n");
bl_sys_reset_por();
}常见问题与踩坑提示
⚠️ 调用复位 API 后系统卡死(无反应)
原因:在中断上下文或任务锁(关中断)状态下调用复位
解决:复位 API 在普通任务中调用;中断里复位需先延后到任务处理(如通过队列通知任务复位)
⚠️ 复位后无法再次启动(需要重新上电)
原因:固件损坏或复位原因寄存器被误改,POR 无法恢复
解决:重新烧录固件;确认固件 OTA 校验通过(升级失败会自动回滚,不会反复重启)
⚠️ 反复复位导致 WiFi 连接失败
原因:复位间隔过短,WiFi 驱动/射频尚未释放,重连过快失败
解决:复位前延时 1~2 秒(官方倒计时即为此考虑);业务上使用「首次复位后等待 + 重试」机制
⚠️ 想复位但不想重新初始化外设
原因:main 重新执行会重新初始化全部外设
解决:若只需恢复某模块,用 vTaskDelete + 重新创建任务替代整机复位;确有跨复位数据需求用 Flash 保存
⚠️ 串口打不开 / 找不到 /dev/ttyUSB0
原因:USB 转串口驱动未装、串口被占用,Linux 下还可能是没有访问权限
解决:Linux 用 lsusb 确认设备被识别,sudo chmod 666 /dev/ttyUSB0 或把用户加入 dialout 组后重试;Windows 在设备管理器查看 COM 口并安装 CH340/CP210x 驱动
⚠️ 烧录一直卡在等待 / 提示找不到芯片
原因:未进入下载模式、数据线只能充电不能传数据,或波特率不对
解决:烧录时长按 EN 键直到进度条出现;换一根能传数据的数据线;确认 p= 串口号与 b=921600 无误
⚠️ cd 报错 No such file or directory / 找不到 Makefile
原因:没进入示例工程目录就执行了 make,或 SDK 安装路径与教程不同
解决:先 cd ~/Ai-Thinker-WB2/applications/get-started/helloworld 再执行 make;若 ~/Ai-Thinker-WB2 不存在,用 find ~ -name "Ai-Thinker-WB2" 找到 SDK 实际位置
运行自检
串口输出 Restarting now. 后开发板立即自动重启并再次打印 Hello World.,即软件复位验证通过。
遇到问题?
如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

