项目收尾

Tutorial: 卓越工程师 Category: 嵌入式 Published: 2026-10-23 11:05:29 Views: 1 Likes: 0 Comments: 0

241.6 项目收尾

uint8_t tx_data[8] ={0}; /* 35C8T6_Send_Faker:定义并清零一帧 8 字节 CAN 发送缓冲区。 */
uint32_t ret,t=0; /* 保留课程源码:ret 在本函数中未使用,t 从 0 开始统计完整演示循环。 */
while (1) /* 主循环不断生成固定的仪表数据。 */
{ /* 开始一次完整的演示循环。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x0;		  Can_Send_Msg(0x0B4, 8,tx_data); /* 向 0x0B4 发送控制码 0x01、数值 0。 */
	tx_data[0]=0xAF;tx_data[1]=0x02;tx_data[2]=0x1; /* 准备控制码 0x02、状态值 1。 */
	Can_Send_Msg(0x0B4, 8,tx_data);HAL_Delay(400); /* 发送状态帧并等待 400 ms。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x0a;		Can_Send_Msg(0x0B4, 8,tx_data); /* 把控制码 0x01 的数值改为 10 并发送。 */
	tx_data[0]=0xAF;tx_data[1]=0x03;tx_data[2]=0x1; /* 准备控制码 0x03、状态值 1。 */
	Can_Send_Msg(0x0B4, 8,tx_data);HAL_Delay(400); /* 发送状态帧并等待 400 ms。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x14;		Can_Send_Msg(0x0B4, 8,tx_data); /* 把控制码 0x01 的数值改为 20 并发送。 */
	tx_data[0]=0xAF;tx_data[1]=0x04;tx_data[2]=0x1; /* 准备控制码 0x04、状态值 1。 */
	Can_Send_Msg(0x0B4, 8,tx_data);HAL_Delay(400); /* 发送状态帧并等待 400 ms。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x1E;		Can_Send_Msg(0x0B4, 8,tx_data); /* 把控制码 0x01 的数值改为 30 并发送。 */
	tx_data[0]=0xAF;tx_data[1]=0x05;tx_data[2]=0x1; /* 准备控制码 0x05、状态值 1。 */
	Can_Send_Msg(0x0B4, 8,tx_data);HAL_Delay(400); /* 发送状态帧并等待 400 ms。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x28;		Can_Send_Msg(0x0B4, 8,tx_data); /* 把控制码 0x01 的数值改为 40 并发送。 */
	tx_data[0]=0xAF;tx_data[1]=0x02;tx_data[2]=0x0; /* 准备控制码 0x02、状态值 0。 */
	Can_Send_Msg(0x0B4, 8,tx_data);HAL_Delay(400); /* 发送状态帧并等待 400 ms。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x32;		Can_Send_Msg(0x0B4, 8,tx_data); /* 把控制码 0x01 的数值改为 50 并发送。 */
	tx_data[0]=0xAF;tx_data[1]=0x04;tx_data[2]=0x0; /* 准备控制码 0x04、状态值 0。 */
	Can_Send_Msg(0x0B4, 8,tx_data);HAL_Delay(400); /* 发送状态帧并等待 400 ms。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x3C;		Can_Send_Msg(0x0B4, 8,tx_data); /* 把控制码 0x01 的数值改为 60 并发送。 */
	tx_data[0]=0xAF;tx_data[1]=0x03;tx_data[2]=0x0; /* 准备控制码 0x03、状态值 0。 */
	Can_Send_Msg(0x0B4, 8,tx_data);HAL_Delay(400); /* 发送状态帧并等待 400 ms。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x4B;		Can_Send_Msg(0x0B4, 8,tx_data); /* 把控制码 0x01 的数值改为 75 并发送。 */
	tx_data[0]=0xAF;tx_data[1]=0x05;tx_data[2]=0x0; /* 准备控制码 0x05、状态值 0。 */
	Can_Send_Msg(0x0B4, 8,tx_data);HAL_Delay(400); /* 发送状态帧并等待 400 ms。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x55;		Can_Send_Msg(0x0B4, 8,tx_data); /* 把控制码 0x01 的数值改为 85 并发送。 */
	tx_data[0]=0xAF;tx_data[1]=0x04;tx_data[2]=0x0; /* 再次准备控制码 0x04、状态值 0。 */
	Can_Send_Msg(0x0B4, 8,tx_data);HAL_Delay(400); /* 发送状态帧并等待 400 ms。 */
	tx_data[0]=0xAF;tx_data[1]=0x01;tx_data[2]=0x63;		Can_Send_Msg(0x0B4, 8,tx_data); /* 把控制码 0x01 的数值改为 99 并发送。 */
	tx_data[0]=0xAF;tx_data[1]=0x06;tx_data[2]=0x14;tx_data[3]=0x19;tx_data[4]=0x07;tx_data[5]=0x14; /* 准备控制码 0x06 及四个时间/日期字段。 */
	Can_Send_Msg(0x0B4, 8,tx_data); /* 发送时间/日期类数据帧;未重新赋值的字节沿用缓冲区现值。 */
	t++; /* 完成一整轮固定报文后,循环计数加 1。 */
	while(t>5); /* 当 t 增至 6 时进入忙等死循环,使主循环停在最后画面。 */
} /* 主循环正常情况下不会退出。 */

本节是整个专题的收尾:整理最终工程和固件,演示离线合并烧录、串口联调与经 CAN 的 IAP 升级,并回顾项目怎样写进简历。上面的源码来自 35C8T6_Send_Faker/Core/Src/main.c,它只为录制界面效果生成固定测试数据,不属于最终交付工程。

一、最终版本代码

1.1 项目框图

系统由三块 STM32F1 开发板组成:

  • STM32F103ZET6 仪表盘主控:驱动 LCD 和 LVGL 界面,接收 CAN 数据;其 Flash 中同时存在 Bootloader、配置区和一个 APP。
  • STM32F103C8T6 数据模拟器:模拟整车控制器或其他 ECU,从 USART2 接收 PC 下发的测试指令,再把仪表数据封装为 CAN 报文;USART1 主要打印日志。
  • STM32F103C8T6 USB 升级桥:从 USART2 接收升级命令与 YMODEM 固件,经 CAN/ISO-TP 转发给 ZET6 Bootloader;USART1 主要打印升级日志。

因此,数据演示链路是“PC 串口→数据 C8T6→CAN→ZET6→LVGL”,升级链路是“PC/YMODEM→升级 C8T6→CAN/ISO-TP→ZET6 Bootloader→内部 Flash”。课程口头称其为 OTA,但当前实现需要 PC、USB 串口和有线 CAN,严格说是经 CAN 的在系统升级/IAP 演示,并不包含无线链路。

1.2 汽⻋仪表盘项目硬件清单

需要一块 ZET6 开发板、两块 C8T6 开发板、三只 CAN 收发器、LCD、USB 转串口连接以及 ST-Link。三只收发器的 CANH 接在同一总线上,CANL 也接在同一总线上,并确保各板共地。实际布线还应在总线两个物理末端各放一只约 120 Ω 终端电阻;不能简单地给每个节点都并一只终端电阻。

视频中“必须用数据线供电”是一次故障经验,不是协议要求。真正要保证的是电源电压、供电电流、地参考和接插件可靠:C8T6 板供电不稳会造成复位、串口丢字或 CAN 通信异常。排查时先测 5 V/3.3 V、电源纹波与共地,再检查 USB 线和杜邦线,不要只凭“换线后好了”判断根因。

1.2.1 汽⻋仪表盘项目硬件清单

课程资源中的综合演示视频用于先建立全局认识:屏幕上的车速/状态灯由 CAN 报文驱动,升级后界面从汽车仪表盘 APP 切换为温湿度 APP。观看时应把每个现象对应到具体节点和数据方向,而不是只记住操作按钮。

建议在接线前先画出三张表:电源与地、每块板的 UART 端口、每个 CAN 节点的收发器与终端位置。这样同时插入五个串口时,仍能明确每个窗口属于哪块板、哪一路 UART。

1.2.2 具备ota功能的汽⻋仪表盘设计

ZET6 是仪表盘主控;两个 C8T6 分别承担数据模拟和升级桥接。LCD 驱动从标准库工程移植到 HAL 工程,并通过 SPI 传输等调整提高刷新表现;LVGL 负责控件、动画和页面显示。数据 C8T6 模拟车内其他控制器,通过 CAN ID 0x0B4 发送时间、指针和状态灯等业务数据。

ZET6 的 Bootloader 与 APP 分区使应用能够被替换。演示把 APP_Car.bin 更新为 APP_DHT11.bin,证明“接收镜像→写入 APP 区→重新启动新 APP”这条链路可运行。它证明的是课堂拓扑中的升级功能;若用于产品,还需补充镜像长度边界、版本策略、完整性/真实性校验、掉电恢复、失败回滚和安全启动等机制。

1.3 任务信息资源导图组件库

最终目录是 uint3code/36666666last,其中五个工程与三块 MCU 的关系如下:

工程目标 MCU作用
29C8T6_Send_OK数据 C8T6接收 PC 测试命令,向 CAN 发送仪表数据
31usb_tool升级 C8T6接收升级命令/YMODEM 镜像,经 ISO-TP 转发
32Car_APPZET6汽车仪表盘 APP
33DHT11_APPZET6温湿度 APP,用作升级后的另一应用
34BootloaderZET6判断升级标志、接收镜像、写 APP 区并跳转

32Car_APP 与 33DHT11_APP 是两个可替换的 APP,不会同时执行;34Bootloader 则长期保留在 ZET6 的低地址区。固件目录中的实际文件为 Bootloader.bin(16,704 字节)、info.bin(12 字节)、APP_Car.bin(320,012 字节)和 APP_DHT11.bin(310,132 字节)。

1.4 固件整合软件

1.4.1 固件整合软件的使用方法

36666666last/固件/固件打包程序/main.exe 用于把几个带不同目标地址的 BIN 转成一个 Intel HEX。它解决的是首次生产或完整恢复时需要分别选择多个 BIN、反复填写地址的问题;在线升级时仍然只发送单独的 APP BIN。

该工具是课程随附的 Windows 可执行程序。使用前应保留原始 BIN 和版本记录,并在烧录工具中核对生成 HEX 的地址范围;不能只因为程序提示“打包成功”就认为映像一定正确。

1.4.2 固件打包程序的使用

选择 Bootloader.bin 作为 Boot BIN,选择 APP_Car.bin 或 APP_DHT11.bin 作为 APP BIN。工具读取文件后,根据界面填写的起始地址,把各段转换为带地址记录的 HEX;勾选中间配置区使能时,还会把 info.bin 放入配置区。

这不是把两个文件无间隔地做二进制拼接。BIN 本身只保存连续字节,不含装载地址;Intel HEX 的每条记录含地址信息,所以一个 HEX 能表示 Flash 中相隔的多个区域。

1.4.3 固件打包的地址设置

本项目的地址必须和 Bootloader、APP 链接脚本及配置读写代码一致:

内容起始地址说明
Bootloader0x08000000MCU Flash 起点
info.bin/升级标志区0x08006000Bootloader 与 APP 之间的配置页
APP0x08008000两个 APP 都按此地址链接并重定位向量表

视频演示时教师明确说界面里的地址写错、最终版会修正;转录中的“800830”也是识别错误。这里应填写 0x08008000,不能照抄视频中错误值。地址错位时,即使烧录成功,Bootloader 也无法从约定位置取得 APP 的初始栈指针和复位入口。

1.4.4 固件打包后的输出文件

点击打包后会生成 output.hex,不是原稿误写的“has 文件”。其中可以同时包含 0x08000000、0x08006000 和 0x08008000 三段记录;空洞无需在文件中实际填充大量 0xFF。

课程所给 ZET6 为 512 KiB Flash,末地址为 0x08080000,所以 APP 区容量为 0x08080000 - 0x08008000 = 0x78000,即 491,520 字节。两个课程 APP 均小于这个上限,但正式打包仍应检查“起始地址 + 镜像长度”没有越界。

1.4.5 固件烧录过程

把 ST-Link 接到 ZET6,在 STM32 ST-LINK Utility 中连接目标、打开 output.hex 并执行 Program/Start。HEX 已携带地址,通常无需像 BIN 那样另填起始地址。烧录后应执行以下验证,而不只观察指针是否重新转动:

  1. 复位后先看到 Bootloader 日志,再成功跳转 APP。
  2. APP 界面与所选镜像一致,CAN 数据能够持续更新。
  3. 读取或校验 Flash,确认三段内容位于预定地址。
  4. 再做一次 CAN/IAP 升级,确认完整链路没有因首次烧录而掩盖问题。

烧写期间屏幕停顿只能说明 CPU 被调试器暂停或 Flash 正在改写;烧写后恢复显示是一个现象,不足以单独证明每个分区都正确。

1.4.6 固件整合软件与ST-link的连接

占用 ST-Link 的是已经连接目标的 STM32 ST-LINK Utility,并非固件打包程序。若此时 Keil 下载提示 ST-LINK connect error,先在 Utility 中点击断开连接图标,再由 Keil 建立会话;同一只探针通常不能被两个程序同时独占。

切换 ST-Link 到另一块板之前,核对目标 MCU 和工程。视频中探针当时接在 ZET6,而打开的是 C8T6 升级器工程,因此即使释放占用,也不能把错误目标当成可安全下载的对象。

1.4.7 固件整合软件中的代码示例

35C8T6_Send_Faker 从数据发送工程派生,主循环就是本文开头的源码。它绕过 PC 指令,直接按固定顺序向 0x0B4 发送控制帧,让指针和状态灯自动变化,便于录制静态、动态素材。

文件名和视频把它称为“Faker/造假代码”。从工程方法看,更准确的名称是测试数据发生器或演示桩。允许使用的前提是明确标注模拟数据,不把画面当成真实传感器、真实车辆或完整系统测试的证据。

1.4.8 固件整合软件中的代码示例-造假部分

代码每次先设置 tx_data[0]=0xAF,再用 tx_data[1] 选择业务字段、tx_data[2] 写值,最后调用 Can_Send_Msg(0x0B4, 8, tx_data)。数值字段依次变为 0、10、20、30、40、50、60、75、85、99,同时穿插若干状态开关,形成可见动画。

要注意,数组只在全局初始化时整体清零,后续很多报文只改前几个字节,未改的尾部字节会沿用上一帧。接收端当前只取约定字段,所以演示仍可工作;严谨做法应在每种报文发出前明确初始化完整载荷,但精校笔记不改写课程源码。

1.4.9 固件整合软件中的代码示例-造假部分-烧录

烧录该工程前,把 ST-Link 接到承担“数据模拟器”角色的 C8T6,并确认 Keil 目标也是 C8T6。烧录后,固定报文不再依赖串口命令,会直接驱动仪表盘动画。

源码中每轮有 9 次 HAL_Delay(400),一轮约 3.6 秒;t 从 0 开始,完成第 6 轮后变成 6,才满足 t>5。所以真实行为是运行六个完整循环后停住,并非原稿所说“改变五次”。

1.4.10 固件整合软件中的代码示例-造假部分-复位

while(t>5); 是没有超时、没有退出条件的忙等死循环。它会把主线程永久困住;中断没有被显式关闭,部分中断仍可能运行,但主循环不会再发送下一轮业务报文,仪表盘便保持最后收到的状态。

按 C8T6 的复位键后,t 重新变为 0,动画又运行约六轮。这个技巧只用于录屏编排。正式测试应使用可重复的测试脚本、明确的开始/停止命令和日志时间戳,避免把人为复位剪辑成设备自主恢复。

1.4.11 固件整合软件中的代码示例-造假部分-动态演示

综合联调共有五个串口窗口:两个 C8T6 各有 USART1、USART2,共四个;ZET6 另有一个日志串口。角色分工如下:

  • 数据 C8T6:USART1 打印日志;USART2 接收 PC 的业务测试帧。
  • 升级 C8T6:USART1 打印升级/CAN 日志;USART2 接收升级命令和 YMODEM 文件。
  • ZET6:串口打印 Bootloader 或 APP 日志。

串口号由 Windows 枚举决定。视频中的 COM4、COM8、COM9、COM11、COM12 只适用于教师当时的电脑,不能写死为项目配置。

1.4.12 固件整合软件中的串口设置

先建立五个串口会话并排布窗口,再逐个选择当前电脑实际出现的 COM 端口。波特率、数据位、停止位和校验方式必须与对应工程一致;在没有确认参数前,不要把乱码直接归因于接触不良。

同一个串口不能同时被普通串口助手与 Xshell 打开。普通指令联调完成后,进入 YMODEM 前要关闭占用升级 USART2 的旧会话。

1.4.13 固件整合软件中的串口设置-窗口调整

多窗口排布只是提高可观察性。更可靠的做法是给窗口命名,例如“ZET6-log”“DATA-UART1”“DATA-UART2”“UPGRADE-UART1”“UPGRADE-UART2”,并保存会话参数。这样复现实验时不必依赖窗口位置记忆设备身份。

1.4.14 固件整合软件中的串口设置-窗口调整-打开串口

依次打开五个当前可用端口。若某端口打不开,先检查是否被 Keil 串口终端、另一串口助手或 Xshell 占用;若端口根本未出现,再检查 USB 转串口驱动、供电与线缆。

视频列出的 COM 号只能作为操作示例。重新插拔转换器后,Windows 也可能给同一硬件分配不同编号。

1.4.15 固件整合软件中的串口设置-窗口调整-打开串口-复位

识别端口的办法是一次只复位一块板,观察哪个窗口立即输出启动日志。先复位 ZET6,标记它的日志口;再分别复位升级 C8T6 和数据 C8T6,各自会有两个窗口响应。

35C8T6_Send_Faker 没有同步最终版的全部启动字符串,所以可能只显示简单的 C8T6 running。这也说明演示工程不能替代最终工程做接口验收。

1.4.16 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印

最终的 29C8T6_Send_OK 在启动时分别向两路串口输出 uart1:C8T6 ui data recv&send to zet6 和 uart2:C8T6 ui data recv&send to zet6,可以据此区分数据板的两个窗口。升级板也应通过自身日志识别,不能只凭 COM 号猜测。

把“复位后能打印”视为串口链路的第一层检查;下一步还要发送一条合法命令,确认接收、中断重装、协议解析和 CAN 转发都正常。

1.4.17 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录

若数据演示工程仍是 Faker 版本,应重新给数据 C8T6 烧录最终的 29C8T6_Send_OK。下载后再次复位并根据新日志重做端口映射,因为更换 USB 连接或重新枚举可能改变 COM 号。

烧录时应逐板确认“探针接到谁、Keil 打开的工程属于谁、下载算法匹配谁”,避免把通信故障和烧错目标混在一起排查。

1.4.18 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位

最终推荐的识别顺序是:连接全部硬件但一次只复位一块板;记录出现日志的窗口;给两个 C8T6 的 UART1/UART2 和 ZET6 日志口贴标签;最后再同时运行。若两路窗口都没有任何输出,先查该板供电和公共地;若只有一路没有输出,再查对应 TX/RX 与串口配置。

1.4.19 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据

综合实验没有新的协议,实质是把前面的小实验串起来:在数据 C8T6 的 USART2 发送日期或状态命令,在升级 C8T6 的 USART2 发送升级命令,观察两块 C8T6 的日志、ZET6 日志和屏幕结果。

原稿的“声音指令”是语音识别错误,应为升级指令;“窗口”多处也是“串口”的误识别。

1.4.20 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据-演示

数据演示可先发日期帧,再发安全带状态帧。每次只改变一个业务量,记录发送字节、数据 C8T6 的解析结果、CAN 发送结果和界面变化。这样即使屏幕没有变化,也能判断问题在串口、协议、CAN 还是 UI 映射。

复位后日期恢复为 APP 默认值是正常现象,因为课堂工程没有把这类运行数据持久化到 Flash;它不说明刚才的串口修改无效。

1.4.21 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据-演示-优化-指令

应在已经标记为“DATA-UART2”的窗口中,以十六进制模式发送前面课程定义的完整帧。不要把终端快捷键或文本输入当作二进制协议;发送后以日志中的解析结果和接收端显示共同确认。

视频先看到 Faker 留下的日期,再复位并发送真实串口命令,目的在于切回真实数据链路。学习时应清楚区分“固件默认值”“测试发生器固定值”和“本次串口命令值”。

1.4.22 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据-演示-优化-指令-接触不良

视频第一次发送日期后无变化,随后再次发送才成功,教师推测是移动 CAN 杜邦线造成接触不良。这个判断只能算线索,不能算已证实根因。因为同样现象也可能来自串口未按十六进制发送、端口选错、帧不完整、CAN 错误状态或接收代码尚未重装中断。

1.4.23 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据-演示-优化-指令-接触不良-解决

排查应从可观测证据开始:检查三板电源与共地;轻拉接头确认机械连接;观察数据板是否打印收到的串口字节;查看 CAN 发送返回值及错误计数;确认 ZET6 是否收到 ID 0x0B4;最后检查 UI 是否处理对应控制码。重新插拔后还要重复同一条命令多次,确认故障不再出现。

1.4.24 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据-演示-优化-指令-接触不良-解决-安全带

安全带演示应发送课程协议中定义的安全带状态帧,并检查数据板返回的 OK 以及仪表盘图标是否变红。原稿“使用 Ctrl+C 发送”没有视频或源码依据,应删除;Ctrl+C 在多数终端中只是控制字符 0x03 或中断快捷键,并不天然代表安全带命令。

1.4.25 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据-演示-优化-指令-接触不良-解决-安全带-固件升级

升级时,在升级 C8T6 的 USART2 发送 AF 00 01 FA。C8T6 通过 CAN 请求当前 APP 设置升级标志并复位;ZET6 Bootloader 启动后确认升级状态,C8T6 才进入 YMODEM 接收流程并周期性输出字符 C。

看到 C 后关闭当前串口助手中占用该端口的会话,记下实际 COM 号,再让支持 YMODEM 的终端连接同一端口。字符 C 表示接收端请求使用 CRC 模式开始传输,并不是传输完成标志。

1.4.26 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据-演示-优化-指令-接触不良-解决-安全带-固件升级-Xshell-COM8-会话

在 Xshell 中复用或新建 SERIAL 会话,选择刚才记录的升级 USART2。视频使用 COM8,但实际端口以本机枚举为准。连接后若仍能看到连续的 C,说明 YMODEM 接收端仍在等待文件;若端口被占用,返回旧串口助手彻底关闭该会话后再连接。

1.4.27 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据-演示-优化-指令-接触不良-解决-安全带-固件升级-Xshell-COM8-会话-传输

在 Xshell 中选择“传输→YMODEM→用 YMODEM 发送”,选择单独的 APP 文件,例如 APP_DHT11.bin。原稿的“Web Modem”和“.b 文件”均是转录错误。不要发送合并后的 output.hex:课堂桥接流程接收的是 APP BIN,并按 APP 区偏移经 ISO-TP 写入。

传输期间不要复位、拔线或让另一个程序抢占串口。YMODEM 进度完成后,还要等待 C8T6 发出结束控制帧、ZET6 清除升级标志并启动新 APP。

1.4.28 固件整合软件中的串口设置-窗口调整-打开串口-复位-打印-烧录-复位-数据-演示-优化-指令-接触不良-解决-安全带-固件升级-Xshell-COM8-会话-传输-完成-串口

完成验证至少包括:YMODEM 报告成功;升级 C8T6 日志显示各批次已转发;ZET6 Bootloader 日志显示写入并结束;复位后进入目标 APP;目标界面和功能与所选 BIN 一致。只看进度条到 100% 不能证明 CAN 侧写 Flash 成功。

课程代码把 YMODEM 数据按 2 KiB 批次转发,末批按 2 KiB 补零写入,而且缺少完备的镜像长度、哈希或签名校验。这些限制应保留在实验结论里,不能把演示描述成可直接量产的升级方案。

1.4.29 固件整合软件项目回顾

本专题主线是 CAN、IAP 与 LVGL。CAN 部分从收发器、报文 ID 和过滤器走到多节点业务通信;IAP 部分从 Flash 分区、Bootloader 跳转、向量表重定位走到 YMODEM 与 ISO-TP 桥接;最后把两个 APP 放到同一启动框架中验证替换。

原稿中的“IP”应为 IAP。IAP 是 In-Application Programming,指设备在应用体系内更新非易失存储器;它与互联网协议 IP 不是同一概念。

1.4.30 固件整合软件项目回顾-LVGL使用与优化

图形部分经历 LCD 驱动验证、标准库到 HAL 工程的迁移、SPI 刷屏优化、LVGL 移植,再到温湿度风扇页面和汽车仪表盘页面。学习重点不是复制生成的 UI 文件,而是理解显示缓冲、刷新回调、周期 tick、输入设备和业务数据到控件的映射。

“帧率提高”若要写入报告或简历,应给出同一界面、同一硬件和同一测量方法下的优化前后数值;课程视频只展示了主观效果,不能据此写成未经测量的百分比提升。

1.4.31 固件整合软件项目回顾-数据传输与代码规范

数据传输部分把协议解析、CAN 收发和 UI 更新拆成函数,由主循环或回调组织调用。函数封装只是第一步,还要有清楚的输入输出、长度检查、错误返回、状态所有权和模块边界。否则把代码从 main() 移到函数里,并不会自动变得可靠。

1.4.32 固件整合软件项目回顾-数据传输与代码规范-UI代码封装-窗口接收

UART 接收从“一次等待 8 字节”改成单字节中断接收,再用状态机查找帧头、累计字段并检查帧尾。这样可以从连续字节流中重新同步,也不会因为一字节丢失而永久错位。关键要求是每次回调结束重新启动下一字节接收,并对索引做边界检查。

这里的“窗口接收”应为串口接收;“receive 八个字节改为 receive 一个字节”描述的是底层接收粒度,业务帧本身仍可由多个字节组成。

1.4.33 固件整合软件项目初衷与总结

项目把 CAN、IAP、LVGL 与已学过的 SPI、UART、DHT11、PWM、Flash 和中断串成一个可运行系统。真正的学习成果应是能够自己解释并复现以下问题:每帧从哪里来、为什么用这个 CAN ID、Bootloader 如何决定升级或跳转、APP 为什么必须链接到 0x08008000、升级中断电后会发生什么、界面数据如何抵达控件。

课程工程适合教学与作品集,但“接近企业应用”不等于已经满足车规量产要求。简历和面试中应明确它是个人/课程项目、使用的硬件和测试范围,以及自己实际完成和理解的部分。

1.5 简历撰写

可以把该项目写成三到四条“动作 + 技术 + 结果”,例如:

  • 基于 STM32F103ZET6、LVGL 与 SPI LCD 实现仪表盘界面,并将 CAN 0x0B4 业务报文映射到指针、时间和状态灯控件。
  • 设计 Bootloader + 配置区 + APP 的 Flash 布局,使 APP 从 0x08008000 运行,完成向量表重定位与启动跳转。
  • 使用 STM32F103C8T6 将 PC 侧 YMODEM 数据经 CAN ISO-TP 转发至 ZET6,完成汽车仪表盘 APP 与温湿度 APP 的有线升级演示。
  • 为 UART 字节流编写单字节中断接收与组帧逻辑,并通过多串口日志定位供电、端口占用和 CAN 接线问题。

只写自己能够现场画出流程、解释源码并复现实验的内容。若没有无线通信,不写“远程 OTA”;若没有做压力、掉电和安全测试,不写“高可靠/车规级”;若性能没有测量,不编造帧率或升级速度。

二、简历模板

2.1 个人信息

教育经历和奖项通常按时间倒序排列,最近的经历在前;与岗位高度相关的少量重要成果也可前置。学历从最高层级写起,学校、专业、时间和学位保持一致。

籍贯不是通用必填项,更不属于所谓“基本素质”。是否提供应看岗位、地区惯例和本人意愿;姓名、联系方式、求职方向、教育背景和与岗位有关的能力更重要。简历中避免填写身份证号、完整家庭住址等不必要的敏感信息。

2.2 实习经历

模板只能用于结构参考,不能直接复制内容。每条经历应写清任务背景、自己的动作、用到的技术和可核验结果,例如“定位了什么问题、修改了哪一层、怎样验证”。团队成果要准确说明个人贡献,避免把参与写成主导。

技术岗位可优先放与目标职位最相关的工作,删去空泛的“负责日常工作”“提升综合能力”。数字只有在来源可靠、口径清楚时才使用。

2.3 项目经历

项目描述应与仓库、演示和面试回答一致。建议准备一张系统框图、一张升级时序图和一份可复现实验步骤,同时能够说明当前局限与下一步改进。这样项目经历既展示结果,也能证明自己理解 CAN、IAP、LVGL 和调试过程。

本专题到这里完成最终整合。复习时按“硬件接线→最终工程→离线合并烧录→串口映射→数据命令→YMODEM/CAN 升级→结果验证”的顺序独立操作一次,才算把分散知识真正连成完整系统。