实现基于UDS LIN诊断协议的本地OTA升级

本文详细描述了如何通过UDSLIN诊断协议在MCU上实现本地OTA升级,涉及升级时序、协议帧定义、MCU端和PC端的具体步骤,以及CRC校验等关键环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、目标
在上篇文章LIN诊断实现MCU本地OTA升级_lin ota-CSDN博客中已经基于LIN诊断协议实现了通过PC端上位机对MCU进行本地的OTA升级,但是没有完全按照UDS协议实现。本篇将在上篇文章的基础上进行改进,实现基于UDS LIN诊断协议的本地OTA升级。本篇文章对实现的目的、需要用到的第三方工具、LIN诊断帧请查看LIN诊断实现MCU本地OTA升级_lin ota-CSDN博客 博客相应章节,本文不再赘述。本文对升级协议、MCU端升级过程以及PC端升级过程做详细说明。

二、升级协议

2.1 升级时序如下图所示

2.2 升级协议诊断帧数据定义

(1)切换扩展会话:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x100x03\\\\
切换到扩展会话:0x10(会话控制) ; 0x03(扩展会话)
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x500x03\\\\
(2)读取软件版本:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x030x220xFB0x88\\\
通过ID读取数据:  0x22(通过ID读取); 0xFB88(自定义读取软件版本号的DID) 。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x060x620xFB0x88XXYYZZ
软件版本号:XX.YY.ZZ
(3)停用DTC存储功能:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x850x02\\\\
停用DTC存储功能:  0x85(故障码控制设置);0x02(停止故障码存储)  。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020xC50x02\\\\
(4)切换到编程会话:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x100x02\\\\
切换到编程会话:0x10(会话控制) ; 0x02(编程会话)。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x500x02\\\\
(5)安全访问请求种子:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x270x01\\\\
安全访问请求种子:  0x27(安全访问);0x01(请求种子)  。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x670x01XXXXXXXX
XX XX XX XX为获取的安全种子
(6)安全访问验证秘钥:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x060x270x02YYYYYYYY
安全访问验证key:  0x27(安全访问);0x02(验证key)   YY YY YY YY:为获取的安全访问种子经过算法转换后的key 。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x670x02\\\\
(7)检查刷写条件:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x040x310x010x020x03\\
检查刷写前条件:  0x31(例程控制);0x01(启动例程);0x0203(自定义RID表示检查电压状态) 。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x040x710x010x020x03\\
(8)擦除升级分区:
PC端请求byte1(NAD)byte2(PCI)byte3(LEN)byte4(SID)byte5byte6byte7byte8
首帧MCU节点地址0x100x0d0x310xff0x000x000x44
续帧1MCU节点地址0x21XXXXXXXXYYYY
续帧2MCU节点地址0x22YYYY\\\\
擦除升级分区:  0x31(例程控制);0x01(启动例程);0xff00(自定义RID表示擦除升级分区);0x44(地址4字节,大小4字节);XX XX XX XX(4字节擦除起始地址);YY YY YY YY(4字节擦除分区大小) 。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x040x710x010xff0x00\\
(9)请求下载:
PC端请求byte1(NAD)byte2(PCI)byte3(LEN)byte4(SID)byte5byte6byte7byte8
首帧MCU节点地址0x100x0b0x340x000x44XXXX
续帧1MCU节点地址0x21XXXXYYYYYYYY
请求数据:  0x34(请求下载);0x00(没有压缩和加密算法);0x44(地址4字节,大小4字节);XX XX XX XX(4字节擦除起始地址);YY YY YY YY(4字节擦除分区大小) 。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x040x740x200x000x42\\
0x20(包长度2字节表示);0x0042(一包66字节,包括SID+包序号,也就是实际一包数据64字节)
(10)升级包数据指令:
PC端请求byte1(NAD)byte2(PCI)byte3(LEN)byte4(SID)byte5byte6byte7byte8
首帧MCU节点地址0x100x420x360x01D1D2D3
续帧1MCU节点地址0x21D4D5D6D7D8D9
续帧2MCU节点地址0x22D10D11D12D13D14D15
续帧3MCU节点地址0x23D16D17D18D19D20D21
续帧4MCU节点地址0x24D22D23D24D25D26D27
续帧5MCU节点地址0x25D28D29D30D31D32D33
续帧6MCU节点地址0x26D34D35D36D37D38D39
续帧7MCU节点地址0x27D40D41D42D43D44D45
续帧8MCU节点地址0x28D46D47D48D49D50D51
续帧9MCU节点地址0x29D52D53D54D55D56D57
续帧10MCU节点地址0x2AD58D59D60D61D62D63
续帧11MCU节点地址0x2BD64\\\\\
传输第1包数据:  0x36(传输数据);0x01(数据包序列号);D1~D64(64字节升级包数据),最后一包数据如果没有64字节则用0xFF填充 
MCU端应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x760x01\\\\
(11)传输退出:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x010x37\\\\\
请求传输退出:  0x37(传输退出)  。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x010x77\\\\\
(12)检查数据包完整性:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x060x310x010x020x02校验码高8位校验码低8位
检查升级数据包完整性:  0x31(例程控制);0x01(启动例程);0x0202(自定义RID表示检查数据包是否完整) ; crc_h/l(2字节CRC校验值)。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x040x710x010x020x02\\
(13)重启MCU指令:
PC端请求byte1(NAD)byte2(PCI)byte3(SID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x110x03\\\\
ECU复位:  0x11(复位); 0x03(软件复位)  。
MCU端肯定应答byte1(NAD)byte2(PCI)byte3(RSID)byte4byte5byte6byte7byte8
单帧MCU节点地址0x020x510x03\\\\
说明:byte6字节为错误码定义,参照升级错误码定义。

三、MCU端升级流程

MCU端flash分区如上图所示,boot为启动分区,app1为A分区,也是app启动运行的分区,app2为B分区,用于升级过程接收保存升级包数据的备份分区,data flash分区为用户数据保存区域和升级标志等信息保存区域。

MCU端接收升级数据包并写入B分区并累加CRC校验码,当升级包接收完成后计算的CRC校验码和PC端发送过来的校验码一致的话说明接收的数据包是完整的,写入升级标志置位、包总数和CRC等信息,并重启MCU。Boot启动时读取升级标志,包总数和CRC校验值,判断升级标志是否置位,如果置位则读取B分区内容并计算CRC校验值,如果计算的CRC校验值和保存的CRC校验值一致说明B分区数据完整无误。擦除A分区数据内容,将B分区数据拷贝到A分区。跳转到A分区运行。

四、PC端升级过程

上位机提供了本地OTA升级功能。用户可以在没有烧写工具的情况下通过LIN升级APP软件,升级界面如下图1所示。

其中“升级节点探测”功能是为了探测可升级的节点地址,为后续升级使用。如果探测到可升级的MCU节点,将在“探测节点地址列表”中显示。

在“节点地址”所在的编辑框直接填写节点地址。然后点击“加载升级文件”按钮选则需要升级的bin文件,Bin文件信息将在旁边的矩形框中显示。点击“开始升级”按钮开始进行升级。如果升级过程中出现错误,比如CRC校验错误等,可以再次点击“开始升级”按钮进行升级,升级过程比较慢,大概需要两三分钟。当所有的升级包都发送成功后会弹出对话框提示用户是否需要写入升级标志并重启MCU,如果用户点击取“取消”按钮,升级包数据仅仅保存在B分区,并不会更新到A分区,升级过程实际并没有完成。用户点击“确定”按钮才真正重启MCU将B分区数据拷贝到A分区,并从A分区启动运行程序。

注:有需要MCU UDS LIN协议栈及上位机程序欢迎咨询。 

<think>好的,我现在需要帮助用户了解如何通过LIN通信协议进行OTA升级。首先,我需要回顾一下LIN通信的基本知识。LIN(Local Interconnect Network)是一种低成本的车载网络协议,通常用于控制车窗、座椅等低速率设备。相比CAN总线,LIN的带宽较低,但成本更低,适合对实时性要求不高的场景。 用户提到OTA升级,也就是空中升级,这通常需要可靠的传输机制。LIN的传输速率一般在20kbps以下,可能不适合大文件传输,但或许可以通过分块传输或压缩来克服。接下来,我需要考虑OTA升级的一般流程,通常包括进入Bootloader模式、数据传输、校验和激活新软件等步骤。 根据引用[2],ECU在Bootloader模式下需要维持会话,这可能涉及到诊断会话控制(Diagnostic Session Control)服务,比如切换到编程会话。同时,LIN诊断协议可能基于ISO 14229(UDS)的简化版本,但需要确认LIN是否支持UDS或者有自己的诊断规范。 用户提供的引用[1]提到LIN诊断刷写的实现,可能涉及到LIN的传输层协议如何分段数据包。LIN的帧结构包括头(Header)和响应(Response),其中头由主节点发送,包含同步间隔、同步字段和标识符。响应部分由从节点发送,包含数据。在刷写过程中,主节点可能需要发送诊断指令,从节点响应并执行操作。 接下来需要思考具体步骤:首先让ECU进入Bootloader模式,可能需要发送特定指令,比如通过诊断请求切换会话模式。然后进行安全访问(Security Access)来解锁刷写权限。接着传输数据,可能需要使用传输层协议处理长消息的分包,比如使用ISO-TP类似的机制,但针对LIN的带宽进行优化。传输完成后进行校验,如CRC校验,最后激活新软件。 需要注意的是,LIN的带宽限制可能导致传输时间较长,因此需要优化数据包大小和重传机制。此外,错误处理机制也很重要,比如检测到传输错误时如何重发数据包。引用[1]和[2]都提到了Bootloader模式下的操作,确保ECU在该模式下正确响应指令是关键。 最后,生成相关问题时要覆盖用户可能感兴趣的方面,如LIN与CAN在OTA中的区别、安全机制、优化传输的方法以及诊断协议的具体应用。</think>### LIN通信协议下的OTA升级实现方式 #### 1. **LIN通信基础与限制** LIN总线是单主多从结构的低成本网络,最大速率19.2kbps,数据帧长度固定为2/4/8字节[^1]。其物理层采用单线传输,适用于车门、座椅等低速率场景。由于带宽限制,OTA升级需通过**分块传输**和**数据压缩**优化效率。 #### 2. **OTA升级流程** 1. **进入Bootloader模式** 通过发送诊断指令$10 02$(切换至编程会话),使ECU从应用模式跳转至Bootloader模式[^2]。 ```python # 示例:LIN诊断请求切换会话 send_lin_frame(0x3C, [0x02, 0x10, 0x02]) # 目标地址0x3C,服务10子功能02 ``` 2. **安全访问认证** 使用$27$服务进行安全密钥交换(如种子-密钥机制),示例: $$种子请求 \rightarrow 27\ 01 \quad 响应 \rightarrow 67\ 01\ [种子]$$ $$密钥发送 \rightarrow 27\ 02\ [密钥] \quad 响应 \rightarrow 67\ 02$$ 3. **数据传输与校验** - **分段传输**:LIN传输层协议将长数据拆分为8字节帧,使用$34$服务(上传/下载)逐块发送。 - **流控制**:通过$31$服务(Routine Control)控制传输节奏。 - **CRC校验**:每帧数据附加CRC16校验码,错误时触发重传。 4. **软件激活与复位** 完成传输后发送$11 01$(ECU复位指令),激活新固件并重启。 #### 3. **关键优化技术** - **差分升级**:仅传输差异数据(如bsdiff算法),减少传输量。 - **双Bank存储**:保留旧版本固件,升级失败可回滚。 - **超时重试**:设置ACK响应超时阈值(通常100-500ms),自动重发丢失帧。 --- ###
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值