:beers: UDS_S32K144_Bootloader 
/*
* ___ ___ ___ ___ _____ ___ ___
* _____ / /\ / /\ ___ / /\ / /\ / /::\ / /\ / /\
* / /::\ / /::\ / /::\ / /\ / /::\ / /::\ / /:/\:\ / /:/_ / /::\
* / /:/\:\ / /:/\:\ / /:/\:\ / /:/ ___ ___ / /:/\:\ / /:/\:\ / /:/ \:\ / /:/ /\ / /:/\:\
* / /:/~/::\ / /:/ \:\ / /:/ \:\ / /:/ /__/\ / /\ / /:/ \:\ / /:/~/::\ /__/:/ \__\:| / /:/ /:/_ / /:/~/:/
* /__/:/ /:/\:| /__/:/ \__\:\ /__/:/ \__\:\ / /::\ \ \:\ / /:/ /__/:/ \__\:\ /__/:/ /:/\:\ \ \:\ / /:/ /__/:/ /:/ /\ /__/:/ /:/___
* \ \:\/:/~/:/ \ \:\ / /:/ \ \:\ / /:/ /__/:/\:\ \ \:\ /:/ \ \:\ / /:/ \ \:\/:/__\/ \ \:\ /:/ \ \:\/:/ /:/ \ \:\/:::::/
* \ \::/ /:/ \ \:\ /:/ \ \:\ /:/ \__\/ \:\ \ \:\/:/ \ \:\ /:/ \ \::/ \ \:\/:/ \ \::/ /:/ \ \::/~~~~
* \ \:\/:/ \ \:\/:/ \ \:\/:/ \ \:\ \ \::/ \ \:\/:/ \ \:\ \ \::/ \ \:\/:/ \ \:\
* \ \::/ \ \::/ \ \::/ \__\/ \__\/ \ \::/ \ \:\ \__\/ \ \::/ \ \:\
* \__\/ \__\/ \__\/ \__\/ \__\/ \__\/ \__\/
*/
:warning: 特别注意
本工程代码仅作学习用途,不可用于实际量产环境,尚存在许多已知 BUG,可自行调试解决 或 付费获取技术支持
联系方式:
:e-mail: e-mail: [email protected]
:book: 简介
S32K1xx 的 CAN 接 周立功 USBCANFD-100U-mini,使用 ZCANPRO 软件的 ECU刷新 功能进行测试。在加载相应的安全访问算法 DLL 文件 :package: [UDS_SecurityAccess][UDS_SecurityAccess] 之后,通过相应的 UDS 服务将 :package: [UDS_S32K144_FlashDriver][UDS_S32K144_FlashDriver] 的 hex 文件下载至 :package: [UDS_S32K144_Bootloader][UDS_S32K144_Bootloader] 在链接文件中为其预先指定起始地址的 RAM 空间中,并通过 Flash Driver 内实际包含的相应的 Flash 驱动函数的相对偏移量以及驱动函数本身来计算相应驱动函数的入口点在 RAM 内的偏移地址后,再通过函数指针的方式调用相应的编程、擦写、校验等 Flash API 以实现将 :package: [UDS_S32K144_APP][UDS_S32K144_APP] 烧写至 Flash 的 APP 片区,最终实现 ECU刷新 的整个 APP 更新流程。
:file_folder: ZCANPRO_RefreshFlow_S32K144.zflash 为可被 ZCANPRO 的 ECU刷新 功能所加载的 UDS 刷新流程文件。
:warning: 注意:S32K144-EVB 开发板需要 12V 独立供电,CAN Transceiver 方可正常工作。
:game_die: 已做通用性适配,目前一套代码理论同时支持多个型号,已测试 S32K144 和 S32K118 可以同时支持。
![Pic_ZCANPRO_ECU_Refresh][Pic_ZCANPRO_ECU_Refresh]
:link: 关联工程
- :package: [UDS_SecurityAccess][UDS_SecurityAccess]
- :package: [UDS_S32K144_Bootloader][UDS_S32K144_Bootloader]
- :package: [UDS_S32K144_FlashDriver][UDS_S32K144_FlashDriver]
- :package: [UDS_S32K144_APP][UDS_S32K144_APP]
:gear: 硬件 & 软件 需求
硬件需求
- S32K144-EVB
- J-Link
- USBCANFD-100U-mini
- 12V External Power Supply
软件需求
- S32 Design Studio for ARM Version 2.2
- ZCANPRO
- J-Flash
:warning: 注意
![Pic_ZCANPRO_ECU_Refresh_Note_ProgramSession][Pic_ZCANPRO_ECU_Refresh_Note_ProgramSession]
![Pic_ZCANPRO_ECU_Refresh_Note_ResetECU][Pic_ZCANPRO_ECU_Refresh_Note_ResetECU]
:warning: 特别注意
< :ok_hand: 已解决 > 关于 S32K144 APP 工程 调用 Flash_EraseFlashDriverInRAM() 会导致程序卡死的问题进行说明记录:
- 根据 Ozone 调试得知,实际现象为出现
HardFault , HFSR 寄存器 FORCED 位被置 1,所以可以判断由其它 Fault 异常提升而来,实际为 UsageFault , INVSTATE 位被置 1,如下图所示:
- ![LinkSetting_ForUsageFault_00][LinkSetting_ForUsageFault_00]
- 由于程序卡死的位置并不是每次都在同一位置,故初期的排查非常困难。由于同样的代码,在
S32K118 APP 工程 中被调用时,并不会产生该问题,所以需要从两个不同芯片的工程的不同之处寻找原因。经过比对,初步判断与两芯片的链接文件空间分配有关联,具体为两个芯片的 Flash Driver 所占用的 RAM 地址空间不同。其中,在 S32K144 的 Bootloader 工程 中,m_flash_driver 地址空间在 APP 工程 中会与 m_data 地址空间合并,从 Bootloader 跳转至 APP 时,会先调用 Reset_Handler 汇编函数,此汇编函数会进行相关初始化之后再跳转到 main 函数,其中在初始化时,会调用 init_data_bss() 函数,此函数其中的一个工作就是将位于 ROM 中(即 m_interrupts 地址空间内)的中断向量表拷贝到 RAM 中(即 m_data 地址空间内)的起始地址处,此时,如若在 APP 工程 中尝试调用 Flash_EraseFlashDriverInRAM() ,会对 0x1FFF8000 起始地址处连续 0x800 个字节的内容进行清零操作,而 0x1FFF8000 ~ 0x1FFF8800 地址空间段已经完全属于 m_data ,如若再执行 Flash_EraseFlashDriverInRAM() 则会将 RAM 中的中断向量表擦除,导致中断响应出现异常,故最终会导致程序卡死,详细配合以下截图进行分析。
- ![LinkSetting_ForUsageFault_01][LinkSetting_ForUsageFault_01]
- ![LinkSetting_ForUsageFault_02][LinkSetting_ForUsageFault_02]
- 解决方法有两种:APP 工程中一律不调用
Flash_EraseFlashDriverInRAM() 或将链接文件内 m_flash_driver 的地址空间从 m_data_2 地址空间的后半段进行划分。
- 但经过评估,显然前者为更恰当的解决方法,因为在 APP 工程中,已不存在
m_flash_driver 地址空间,此时就算在 Bootloader 中将 m_data_2 的后半段空间划分给 m_flash_driver ,在 APP 工程中再对该片空间进行自行清零的操作是不妥的,因为 m_data_2 会用于存放 customSectionBlock、 bss、 heap、 stack, 此时如若再在 APP 中调用 Flash_EraseFlashDriverInRAM() ,同样有可能会将这些数据清零。
:detective: UDS(Unified Diagnostic Services,统一诊断服务)
:page_with_curl: UDS 协议说明
UDS(Unified Diagnostic Services,统一诊断服务)诊断协议是 ISO 15765 和 ISO 14229 定义的一种汽车通用诊断协议,位于 OSI 模型中的应用层,它可在不同的汽车总线(例如CAN、LIN、Flexray、Internet、K-line)上实现。UDS协议的应用层定义是 ISO 14229-1,目前大部分汽车厂商均采用 UDS on CAN 的诊断协议。
![UDS_OSI_Model][UDS_OSI_Model]
:triangular_flag_on_post: UDS 术语概要
| 缩写 |
英文全称 |
中文含义 |
| UDS |
Unified Diagnostic Services |
统一诊断服务 |
| OBD |
On-Board Diagnostics |
车载诊断系统 |
| WWH-OBD |
World-wide Harmonized OBD |
全球统一的重型发动机的车载诊断系统 |
| DoCAN |
Diagnostic Communication Over CAN |
基于CAN的诊断通信 |
| OSI |
Open System Interconnection |
开放式系统互联 |
| ECU |
Electronic Control Unit |
电子控制单元 |
| SID |
Service ID |
诊断服务标识符 |
| Sub-Function |
Sub-Function |
子服务,诊断服务包含的子功能 |
| DTC |
Diagnostic Trouble Code |
诊断故障码 |
| NRC |
Negative Response Code |
负响应码 |
| FTB |
Fault Type Byte |
故障类型字节 |
| PCI |
Protocol Control Information |
协议控制信息 |
| SF |
Single Frame |
单帧 |
| FF |
First Frame |
首帧 |
| CF |
Consecutive Frame |
连续帧 |
| FC |
Flow Control Frame |
流控帧 |
| DL |
Data Length |
数据长度 |
| FF_DL |
First Frame Data Length |
首帧数据长度 |
| SN |
Sequence Number |
序号 |
| SPN |
Suspect Parameter Number |
可疑参数序号 |
| FS |
Flow Status |
流控制状态 |
| BS |
Block Size |
块的大小 |
| STmin |
Separation Time Minimum |
最小间隔时间 |
| CTS |
Continue to Send |
继续发送 |
| FMI |
Failure Mode Indicator |
失效模式指示 |
| Mtype |
Message Type |
信息类型 |
| Indication |
Indication Service Primitive |
指示服务原语 |
| Confirm |
Confirm Service Primitive |
确认服务原语 |
| N_AE |
Network Address Extension |
网络层扩展地址 |
| N_AI |
Network Address Information |
网络层地址信息 |
| N_Ar |
Network Layer Timing Parameter Ar |
网络层定时参数 Ar |
| N_As |
Network Layer Timing Parameter As |
网络层定时参数 As |
| N_Br |
Network Layer Timing Parameter Br |
网络层定时参数 Br |
| N_Bs |
Network Layer Timing Parameter Bs |
网络层定时参数 Bs |
| N_Cr |
Network Layer Timing Parameter Cr |
网络层定时参数 Cr |
| N_Cs |
Network Layer Timing Parameter Cs |
网络层定时参数 Cs |
| N_ChangeParameter |
Network Layer Service Name |
网络层的服务名称 |
| N_Data |
Network Data |
网络层数据 |
| N_PCI |
Network Protocol Control Information |
网络层协议控制信息 |
| N_PCItype |
Network Protocol Control Information Type |
网络层协议控制信息类型 |
| N_PDU |
Network Protocol Data Unit |
网络层协议数据单元 |
| N_SDU |
Network Service Data Unit |
网络层服务数据单元 |
| N_SA |
Network Source Address |
网络层源地址 源地址 -> 诊断仪 |
| N_TA |
Network Target Address |
网络层目标地址 目标地址 -> ECU |
| N_TAtype |
Network Target Address Type |
网络层目标地址类型 |
| N_USData |
Network Layer Unacknowledged Segmented Data Transfer Service Name |
网络层未确认分段数据传输服务名称 |
| NW |
Network |
网络层 |
| NWL |
Network Layer |
网络层 |
| UDS_PHYSREQ_CANID |
Physical Address |
物理寻址 - 单播通讯,同一总线上每个 ECU 的物理寻址 CAN ID 互不相同,只有一个 ECU 会接收处理 |
| UDS_FUNCREQ_CANID |
Functional Address |
功能寻址 - 多播通讯,同一总线上所有 ECU 的功能寻址 CAN ID 都相同,所有具备诊断功能的 ECU 都会接收并处理 |
| UDS_RESPOND_CANID |
Response Address |
响应地址 - 由 ECU 发送,诊断仪接收,各 ECU 互不相同 |
:earth_asia: UDS 网络层概述
网络层最主要的目的就是 把数据转换成能适应 CAN 总线规范的单一数据帧,从而进行传输。 如果将要传输的报文长度超过了 CAN 数据帧的长度,则需要将报文信息进行拆分后传输,每次至多可以传输4095个字节长度的报文。
所有的网络层服务都具有相同的通用结构。为了定义这种服务,需要定义三种类型的服务原语:
- 请求服务(Request):用于向网络层传递控制报文信息及要发送的数据,应用于更高层或应用层。如诊断仪向 ECU 发出数据。
- 指示服务(Indication):用于向更高层或应用层传递状态信息及接收到的数据,应用于网络层。如 ECU 收到了诊断仪的数据,传至应用层。
- 确认服务(Confirm):被网络层使用,用于向更高层或应用层传递状态信息。如诊断仪收到了 ECU 方面的数据。
具体说来,Indication 前端应该执行的是底层传入数据的处理函数,即读取 PDU 信息,这一帧具体是 SF、FC、CF 还是 FF。若满足条件,继续向上,即应用层传递。
具体说来,Confirm 和 Indication 很像的是都是从网络层向应用层传递信息,有何区别呢?
在代码的处理中,Confirm 的前端应向底层外发 Tx 数据或超时处理函数,反馈的信息不需要包含数据。而 Indication 传递的信息则分为两种,一种包含真实数据,另一种不包含。
:earth_asia: UDS 网络层协议数据单元 N_PDU
网络层协议数据单元(N_PDU,Network Protocol Data Unit)包含 N_AI,N_PCI,N_Data。即地址信息,协议控制信息和数据。
| 参数名称 |
缩写 |
描述 |
| 寻址信息 |
N_AI |
隐含源地址、目的地址和寻址方式信息 |
| 协议控制信息 |
N_PCI |
标识网络层帧类型 |
| 数据 |
N_Data |
包含应用层协议控制信息和数据 |
网络层协议数据单元(N_PDU)有四种类型,即单帧(SF)、首帧(FF)、连续帧(CF)、流控制帧(FC),用于建立对等实体间的通信。
:earth_asia: UDS 网络层协议控制信息 N_PCI
:warning: 注意
本网络传输层的报文格式为:ISO 15765-2 2004
而在 ISO 15765-2 2016 中,单帧 SF 用第 2 字节存放长度 DL,首帧 FF 用第 3 ~ 6 字节存放长度 DL,故本协议栈尚不支持 ISO 15765-2 2016
ISO 15765-2 定义了一种 CAN 帧分割的网络传输层通信协议,该协议对 CAN 帧的 Byte0 - Byte2 进行了定义,由此产生了单帧(SF)、首帧(FF)、连续帧(CF)、流控帧(FC)。当发送端需要发送数据时,网络传输层会做如下处理,如果数据能用一帧 CAN 报文传输完则封装为单帧传输,否则就需要涉及到首帧、连续帧和流控帧。
单帧:用于发送小于等于 7 字节的数据,如下图所示,Byte0 高 4bit 为 0 的是单帧,Byte0 低 4bit 为报文有效字节数。Byte1-Byte7 为数据(包括无效的填充字节,填充数据可为任意值,通常为 AA 或 55)。比如应用层需要发送数据 [10 03],经过网络传输层封装,最终发送至总线的实际数据为 [02 10 03 AA AA AA AA AA]
多帧:当需要发送的数据字节数大于 7 字节,需要用到首帧、连续帧和流控帧的多帧传输方式
![UDS_PCI_Frame][UDS_PCI_Frame]
接收者通过 Flow Control Frame(流控帧)的机制,告知发送者自己有多大的接收能力。(其实就是每两个 FC 之间允许连续发送多少个 CF,每两个 CF 之间的时间不能过快)
其中:
DL:有效数据的长度,不包括 PCIbyte,具体定义见 network_layer_private.h
- UDS_SF_DL_MAX = 7 (单帧 DL 取值最大 7 字节)
- UDS_FF_DL_MIN = 8 (首帧 DL 取值最小 8 字节)
- UDS_FF_DL_MAX = 4095 (首帧 DL 取值最大 4095 (0xFFF)字节)
SN:连续帧的序列号 0 ~ 15,FF 帧没有 SN 域,但是它“算” CF 帧的序列号0,所以第一帧 CF 帧的 SN = 1
FS:表示发送方是否可以继续传输消息,0表示可以继续发送 Continue To Send(CTS),1表示等待发送 Wait(WT),2表示数据溢出 Overflow(OVFLW),一次发送的数据大于接收方所能接收的量
BS:接收方一次能接收的数据最大量,BS = 0,再无 FC 帧,CF 帧可无限制发送
STmin:表示两个连续帧之间的最小时间间隔,参照图1中的定义
:earth_asia: UDS 网络层时间控制分析
网络层定时参数定义了N_As、N_Ar、N_Bs、N_Br、N_Cs、N_Cr六个参数。
- N_As 超时:发送方没有及时发送 N_PDU。
- N_Ar 超时:接收方没有及时发送 N_PDU。
- N_Bs 超时:发送方没有接收到流控帧。
- N_Br 超时:接收方没有发出流控帧。
- N_Cr 超时:接收方没有收到连续帧。
- N_Cs:即STmin,发送两个连续帧需要等待的最短时间。
s = 发送者,r = 接收者
| 定时参数 |
方向 |
解释 |
| N_As |
发送方→接收方 |
首帧和连续帧在数据链路层传播的时间 |
| N_Ar |
接收方→发送方 |
流控帧在数据链路层传播的时间 |
| N_Bs |
发送方→接收方 |
接收方收到首帧时发出的 ACK 响应,与自己(发送方)收到流控帧的间隔时间 |
| N_Br |
接收方→发送方 |
自己(接收方)收到首帧,与自己开始发出流控帧的间隔时间 |
| N_Cs |
发送方→接收方 |
自己(发送方)收到流控帧,或是连续帧送达时产生的 ACK 响应,与自己开始发出新连续帧的间隔时间 |
| N_Cr |
接收方→发送方 |
自己(接收方)收到连续帧,到下一次自己收到连续帧的间隔时间 |
:id: UDS 汽车诊断协议(ISO 14229)所有服务以及对应服务支持的否定响应代码 NRC
下表将 ISO 14229-Part 1:Specification and requirements 中信息进行整理,梳理了 UDS 汽车诊断协议所有服务以及对应服务支持的否定响应代码 NRC:
| 序号 |
服务类型 |
SID |
服务名 |
描述 |
默认会话 |
非默认会话 |
支持的负响应码 (NRC_) |
| 1 |
诊断和通信管理功能单元 Diagnostic and Communication Management functional unit |
0x10 |
诊断会话控制 DiagnosticSessionControl service |
The client requests to
control a diagnostic session with a server(s). |
X |
X |
0x12 |
0x13 |
|
0x22 |
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
0x11 |
电控单元复位 ECUReset service |
The client forces the
server(s) to perform a reset. |
X |
X |
0x12 |
0x13 |
|
0x22 |
|
|
0x33 |
|
|
|
|
|
|
|
|
|
| 3 |
0x27 |
安全访问 SecurityAccess
service |
The client requests to
unlock a secured server(s). |
不适用 not applicable
|
X |
0x12 |
0x13 |
|
0x22 |
0x24 |
0x31 |
|
0x35 |
0x36 |
0x37 |
|
|
|
|
|
|
| 4 |
0x28 |
通信控制 CommunicationControl
service |
The client controls the
setting of communication parameters in the server (e.g.,communication baudrate). |
不适用 not applicable
|
X |
0x12 |
0x13 |
|
0x22 |
|
0x31 |
|
|
|
|
|
|
|
|
|
|
| 5 |
0x3E |
诊断设备在线,会话保持(ZLG ZCANPRO)TesterPresent
service |
The client indicates to the
server(s) that it is still present. |
X |
X |
0x12 |
0x13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
0x83 |
访问时序参数 AccessTimingParameter
service |
The client uses this service
to read/modify the timing parameters for an active communication. |
不适用 not applicable
|
X |
0x12 |
0x13 |
|
0x22 |
|
0x31 |
|
|
|
|
|
|
|
|
|
|
| 7 |
0x84 |
安全数据传输 SecuredDataTransmission service |
The client uses this service
to perform data transmission with an extended data link security. |
不适用 not applicable
|
X |
|
0x13 |
|
|
|
|
|
|
|
|
0x38-0x4F |
|
|
|
|
|
| 8 |
0x85 |
诊断故障码设置控制 ControlDTCSetting
service |
The client controls the
setting of DTCs in the server. |
不适用 not applicable
|
X |
0x12 |
0x13 |
|
0x22 |
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
0x86 |
事件响应 ResponseOnEvent
service |
The client requests to setup
and/or control an event mechanism in the server. |
Xa |
X |
0x12 |
0x13 |
|
0x22 |
|
0x31 |
|
|
|
|
|
|
|
|
|
|
| 10 |
0x87 |
链路控制 LinkControl
service |
The client requests control
of the communication baudrate. |
不适用 not applicable
|
X |
0x12 |
0x13 |
|
0x22 |
0x24 |
0x31 |
|
|
|
|
|
|
|
|
|
|
| 11 |
数据传输功能单元 Data Transmission functional unit |
0x22 |
按标识符ID读取数据 ReadDataByIdentifier
service |
The client requests to read
the current value of a record identified by a provided dataIdentifier. |
Xb |
X |
|
0x13 |
0x14 |
0x22 |
|
0x31 |
0x33 |
|
|
|
|
|
|
|
|
|
| 12 |
0x23 |
按地址读取内容 ReadMemoryByAddress
service |
The client requests to read
the current value of the provided memory range. |
Xc |
X |
|
0x13 |
|
0x22 |
|
0x31 |
|
|
|
|
|
|
|
|
|
|
| 13 |
0x24 |
按标识符ID读取换算数据 ReadScalingDataByIdentifier service |
The client requests to read
the scaling information of a record identified by a provided dataIdentifier. |
Xb |
X |
|
0x13 |
|
0x22 |
|
0x31 |
0x33 |
|
|
|
|
|
|
|
|
|
| 14 |
0x2A |
按周期性标识符ID读取数据 ReadDataByPeriodicIdentifier service |
The client requests to
schedule data in the server for periodic transmission. |
不适用 not applicable
|
X |
|
0x13 |
|
0x22 |
|
0x31 |
0x33 |
|
|
|
|
|
|
|
|
|
| 15 |
0x2C |
动态定义数据标识符ID DynamicallyDefineDataIdentifier service |
The client requests to
dynamically define data Identifiers that may subsequently be read by the readDataByIdentifier
service. |
Xd |
X |
0x12 |
0x13 |
|
0x22 |
|
0x31 |
0x33 |
|
|
|
|
|
|
|
|
|
| 16 |
0x2E |
按标识符ID写入数据 WriteDataByIdentifier
service |
The client requests to write
a record specified by a provided dataIdentifier. |
Xb |
X |
|
0x13 |
|
0x22 |
|
0x31 |
0x33 |
|
|
|
|
|
|
0x72 |
|
|
| 17 |
0x3D |
按地址写内存 WriteMemoryByAddress service |
The client requests to
overwrite a provided memory range. |
Xc |
X |
|
0x13 |
|
0x22 |
|
0x31 |
0x33 |
|
|
|
|
|
|
0x72 |
|
|
| 18 |
存储数据传输功能单元 Stored Data Transmission functional unit |
0x14 |
清除诊断信息 ClearDiagnosticInformation Service |
Allows the client to clear
diagnostic information from the server (including DTCs,captured |
README 内容过长,已截取前 64 KB。完整内容请前往 GitHub 仓库查看。
评论