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

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

二、LIN和CAN诊断的区别

LIN诊断是通过节点地址(NAD)进行寻址,而CAN诊断是通过物理地址进行寻址。LIN诊断响应地址即为节点地址。而CAN响应的物理地址需要约定好。比如定义CAN诊断物理地址为0x700,MCU响应地址为0x701。

从发送格式上,LIN诊断帧(单帧)的PDU 单元包括:NAD+PCI+SID+D1~D5

而CAN诊断帧(单帧)的PDU单元包括:PCI+SID+D1~D6

可以比较直观的看出CAN诊断帧比LIN诊断帧在PDU单元数据上少了NAD的定义,因为物理地址可作为ID发送,不需要单独的节点地址定义。

三、升级协议

3.1 升级时序如下图所示

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

(1)切换扩展会话:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x100x03\\\\\
切换到扩展会话:0x10(会话控制) ; 0x03(扩展会话)
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x500x03\\\\\
(2)读取软件版本:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x030x220xFB0x88\\\\
通过ID读取数据:  0x22(通过ID读取); 0xFB88(自定义读取软件版本号的DID) 。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x060x620xFB0x88XXYYZZ\
软件版本号:XX.YY.ZZ
(3)停用DTC存储功能:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x850x02\\\\\
停用DTC存储功能:  0x85(故障码控制设置);0x02(停止故障码存储)  。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020xC50x02\\\\\
(4)切换到编程会话:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x100x02\\\\\
切换到编程会话:0x10(会话控制) ; 0x02(编程会话)。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x500x02\\\\\
(5)安全访问请求种子:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x270x01\\\\\
安全访问请求种子:  0x27(安全访问);0x01(请求种子)  。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x670x01XXXXXXXX\
XX XX XX XX为获取的安全种子
(6)安全访问验证秘钥:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x060x270x02YYYYYYYY\
安全访问验证key:  0x27(安全访问);0x02(验证key)   YY YY YY YY:为获取的安全访问种子经过算法转换后的key 。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x670x02\\\\\
(7)检查刷写条件:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x040x310x010x020x03\\\
检查刷写前条件:  0x31(例程控制);0x01(启动例程);0x0203(自定义RID表示检查电压状态) 。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x040x710x010x020x03\\\
(8)擦除升级分区:
PC端请求byte1(PCI)byte2(LEN)byte3(SID)byte4byte5byte6byte7byte8
首帧0x100x0d0x310xff0x000x000x44XX
续帧10x21XXXXXXYYYYYYYY
擦除升级分区:  0x31(例程控制);0x01(启动例程);0xff00(自定义RID表示擦除升级分区);0x44(地址4字节,大小4字节);XX XX XX XX(4字节擦除起始地址);YY YY YY YY(4字节擦除分区大小) 。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x040x710x010xff0x00\\\
(9)请求下载:
PC端请求byte1(PCI)byte2(LEN)byte3(SID)byte4byte5byte6byte7byte8
首帧0x100x0b0x340x000x44XXXXXX
续帧10x21XXYYYYYYYY\\
请求数据:  0x34(请求下载);0x00(没有压缩和加密算法);0x44(地址4字节,大小4字节);XX XX XX XX(4字节擦除起始地址);YY YY YY YY(4字节擦除分区大小) 。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x040x740x200x000x42\\\
0x20(包长度2字节表示);0x0042(一包66字节,包括SID+包序号,也就是实际一包数据64字节)
(10)升级包数据指令:
PC端请求byte1(PCI)byte2(LEN)byte3(SID)byte4byte5byte6byte7byte8
首帧0x100x420x360x01D1D2D3D4
续帧10x21D5D6D7D8D9D10D11
续帧20x22D12D13D14D15D16D17D18
续帧30x23D19D20D21D22D23D24D25
续帧40x24D26D27D28D29D30D31D32
续帧50x25D33D34D35D36D37D38D39
续帧60x26D40D41D42D43D44D45D46
续帧70x27D47D48D49D50D51D52D53
续帧80x28D54D55D56D57D58D59D60
续帧90x29D61D62D63D64\\\
传输第1包数据:  0x36(传输数据);0x01(数据包序列号);D1~D64(64字节升级包数据),最后一包数据如果没有64字节则用0xFF填充 
MCU端应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x760x01\\\\\
(11)传输退出:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x010x37\\\\\\
请求传输退出:  0x37(传输退出)  。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x010x77\\\\\\
(12)检查数据包完整性:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x060x310x010x020x02校验码高8位校验码低8位\
检查升级数据包完整性:  0x31(例程控制);0x01(启动例程);0x0202(自定义RID表示检查数据包是否完整) ; crc_h/l(2字节CRC校验值)。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x040x710x010x020x02\\\
(13)重启MCU指令:
PC端请求byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧0x020x110x03\\\\\
ECU复位:  0x11(复位); 0x03(软件复位)  。
MCU端肯定应答byte1(PCI)byte2(SID)byte3byte4byte5byte6byte7byte8
单帧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升级功能。用户可以在没有烧写工具的情况下通过CAN升级APP软件,升级界面如下图1所示。

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

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

注:有需要整套代码,包括MCU UDS LIN协议栈及上位机程序欢迎咨询。  

  • 18
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值