基于UDS的BootLoader上位机源代码(C#)
基于UDS的BootLoader上位机源代码,支持ISO15765通信,支持PeakCAN , ZJG CAN等CAN卡, 支持S-record格式的二进制文件解析; 可二次开发或扩展应用。
基于UDS烧录的上位机源代码使用说明
总体说明
设备(CAN卡)操作
- 软件集成了PCAN USB的设备操作,硬件设备的操作参考了设备的官方例程,本软件中仅使用了设备启动和关闭,消息接收和发送相关的接口,及例程中的先关参数定义。
- 软件集成了周立功CAN设备操作
开发工具
本软件使用Visual Studio 2013集成IDE开发。
软件模块
软件工程说明
打开软件工程,软件工程下的文件目录如下图所示。
点击文件后缀名为*.csproj的文件启动工程,软件工程的结构如下图所示。
窗体界面
软件共有三个窗体界面:Form2为登录窗体界面,Form1为软件主窗体界面,Form3为解锁设置界面。
(1)Form2界面描述
Form2界面如下图所示。软件启动时会首先展示该界面。再输入正确的账号和密码后,会离开该界面进入主界面。
(2)Form1界面描述
Form1界面如下图所示,该界面包含了整个软件的所有功能。
界面上的“设置CAN设备”部分为CAN卡设置,用户可以切换页选择不同的设备,配置不同的设备参数,最后点击“启动设备”即可启动正确连接的CAN卡,如果启动失败会弹出错误提示弹窗。由PCAN的驱动可以共享,启动PCAN后,打开PCAN View或PCAN Explorer等软件仍然可以对本上位机已经启动的设备进行连接,连接的设备名称为PCAN Ligth USB 16…。
“升级设置”部分为软件升级的参数设置,用户可以通过“浏览”选择需要烧录的文件,可以通过文本框设置软件升级的参数:起始地址(烧录的起始地址),数据长度(烧录的数据量大小),填充码(MCU的Flash默认值),UDS的物理寻址ID,UDS的功能寻址ID,UDS的响应ID,以及ID的格式(标准帧/扩展帧ID格式)等信息。其中的保存设置按钮的作用是在设置好上述参数后,点击“保存设置”会将设置的参数保存到软件运行目录下的配置文件中,在下次启动软件时,软件会将上次设置你的参数导入,避免每次软件升级时都需要设置一遍参数。点击“开始升级”按钮,软件将开启进行软件升级。
空白部分为调试信息显示文本框,软件升级过程中将实时显示软件升级进行的步骤及信息提示。
(3)Form3界面描述
Form3界面用于使用明文烧录时进行密码解锁,界面如下
在文本框中输入密码即可解锁。
软件框架说明
- 多线程处理。软件升级的过程耗时较长,为不造成UI卡顿和假死,软件采用多线程处理。软件主要线程有软件升级线程和消息接收线程。软件升级线程使用backgroundworker创建,消息接收线程由system.Thread创建。
- 线程同步。软件升级线程和消息接收线程由用户编写的方法(见源代码说明部分)进行同步和事件通知。
- 模块化。不同功能模块的方法和参数封装在不同的类中。
- 软件升级线程由“开始升级”的按钮点击事件启动,消息接收线程也由“开始升级”的按钮点击事件启动,软件升级结束时,将结束消息接收线程。
软件工程文件列表
序号 | 文件名称 | 描述 |
---|---|---|
OpenDevice.cs | 该文件包含了CAN卡设备操作的方法和参数。 | |
PCANBasic.cs | 该文件来自PCAN的官方例程,包含了PCAN设备的参数和API接口声明 | |
LicenseModule.txt | 该文件为软件license的模板,用于读取license时进行关键字匹配
在license验证策略没有变更的情况下,请勿随意更改 |
|
UDS.cs | 该文件包含了CAN消息的发送接收,多帧处理,线程同步方法,UDS参数等。
该文件是真个软件中涉及UDS的核心文件。 该文件中的多包传输机制代码请勿随意更改。 |
|
Form1.cs | 软件主窗体设计器 | |
Form2.cs | 软件登录窗体设计器 | |
Form3.cs | 明文烧录时解锁设置的窗体设计器 | |
INIOperation.cs | I包含NI文件操作的接口 | |
LicenseAnalysis.cs | 包含license文件的处理方法,该文件在license认证策略没有变更的情况下请勿随意更改。 | |
Program.cs | 包含Main函数的工程默认文件 | |
SecurityAccess.cs | 包含软件升级时的安全算法代码 | |
SRecordProcess.cs | 包含s-record格式文件的处理方法源代码,和软件升级相关的一些全局参数。 |
软件详细说明
OpenDevice.cs文件说明
该文件包含了设备(can卡)操作的接口,以及和设备相关的一些参数定义。部分定义参考了CAN卡的官方例程。
1、枚举定义:DeviceOperationType,定义了设备操作的类型。
CAN_DEVICE_OPERATION_NONE 无操作
CAN_DEVICE_OPERATION_OPEN 打开设备
CAN_DEVICE_OPERATION_CLOSE 关闭设备
2、枚举定义:DeviceType,定义了设备类型
CAN_DEVICE_NONE 无类型
CAN_DEVICE_PCAN PCAN系列设备
CAN_DEVICE_ZLGCAN 周立功系列设备
3、静态类; PCAN_Local_Para ,定义了PCAN设备相关的参数
public static TPCANHandle m_PcanHandle; 设备句柄
public static TPCANBaudrate m_Baudrte; 波特率
public static TPCANType m_HwType; PCAN的类型
4、静态类:ZLGCAN_Local_Para,定义了周立功设备相关的参数
public static UInt32 zlg_devType; 设备类型
public static UInt32 zlg_devIndex; 设备索引
public static UInt32 zlg_devCanIndex; CAN通道索引
public static ZLGCAN.VCI_INIT_CONFIG zlg_devConfig; 设备参数配置
5、公共类:OpenDevice, 定义了CAN设备操作的接口,包括设备启动,设备反初始化等
PcanDeviceOperation方法说明 | ||
---|---|---|
方法名 | PcanDeviceOperation
该方法用于启动PCAN或关闭PCAN设备。 |
|
参数 | HwTypeStr | 表示设备类型的字符串 |
baudTypeIndex | 选择的波特率索引 | |
OptTyte | 枚举类型:CAN卡操作的类型,打开还是关闭 | |
其他 | PCAN的设备参数需要参考官方文档的描述,计算过程可参考PCAN的官方例程。
根据设备操作的类型,调用了PCAN在动态链接库中提供的Initialize和Uninitialize接口。 |
PCAN_ReInitial方法说明 | ||
---|---|---|
方法名 | PCAN_ReInitial
该方法用于重新初始化已经打开的PCAN设备。 |
|
参数 | ||
其他 | PCAN消息没有发送成功时可以进行重新启动,已清除未发送成功的消息和缓冲区。
调用了PCAN在动态链接库中提供的Initialize和Uninitialize接口。 |
ZLGCANDeviceOperation方法说明 | ||
---|---|---|
方法名 | ZLGCANDeviceOperation
该方法用于启动ZLGCAN或关闭ZLGCAN设备。 |
|
参数 | seltDevType | 设备类型的选择索引 |
seltDevIndex | 设备索引的选择索引号 | |
seltDevdevCanIndex | CAN通道的选择索引号 | |
seltDevCanBaudrate | 波特率的选择索引号 | |
DevOperationType | 枚举类型:CAN卡操作的类型,打开还是关闭 | |
其他 | ZLGCAN的设备参数需要参考官方文档的描述,计算过程可参考ZLGCAN的官方例程。
设备的启动流程也需参考官方文档或例程的设计,调用了ZLGCAN在动态链接库中提供的VCI_OpenDevice、VCI_InitCAN、VCI_StartCAN、VCI_CloseDevice接口。 |
ZLGCAN_ReInitial方法说明 | ||
---|---|---|
方法名 | ZLGCAN_ReInitial
该方法用于复位已经启动的ZLGCAN设备 |
|
参数 | ||
其他 | ZLGCAN的设备参数需要参考官方文档的描述,计算过程可参考ZLGCAN的官方例程。
调用了ZLGCAN在动态链接库中提供的VCI_ResetCAN和VCI_StartCAN接口。 |
PCANBasic.cs文件说明
该文件由PCAN的内容官方例程提供,包含了PCAN设备的参数和接口声明。本程序完全引用该文件,未做也无需做任何变更。
ZLGCAN.cs文件说明
该文件由ZLGCAN的内容官方例程提供,包含了ZLGCAN设备的参数和接口声明。本程序完全引用该文件,未做也无需做任何变更。
UDS.cs文件说明
该文件包含了UDs网络层的核心代码,包括网络层消息的接收和多包传输功能。
1、类SeedKey
包含了seed和key的定义,用于27服务时请求种子和保存key。
2、类SerialNumberFrame
包含了数据多包传输时消息帧的定义。
3、类Session
用于新建消息接收和发送类。
4、类DataToSend
用于保存发送诊断数据的属性。
5、类UDSReceiveFrame
用于保存接收的诊断数据的属性。
6、类UDSDataFrame
用于保存即将发送的UDS数据的属性,用在消息发送时。
7、静态类UDS_ID
包含UDS ID的定义和ID类型的定义。消息类型的定义都转换为了PCAN提供的ID类型枚举定义,在使用时需要注意。
8、静态类UserThreadProcess
该类用于线程同步处理,用于UDS消息的发送线程和接收线程。
相关变量 | |
ThreadBreak | Bool型变量,用于设置被阻塞(用延时模拟)的线程是否终止阻塞,true-终止阻塞 false-继续阻塞 |
DelayTime | 用于设置线程阻塞的时间,单位为毫秒 |
UserThreadWaitDelay方法说明 | ||
---|---|---|
方法名 | UserThreadWaitDelay
用于将阻塞的线程延长指定的阻塞时间。 |
|
参数 | addTime | 时间,毫秒 |
其他 |
UserThreadWaitCancel方法说明 | ||
---|---|---|
方法名 | UserThreadWaitCancel
用于取消线程的阻塞状态 |
|
参数 | ||
其他 | 如果线程未被阻塞,而先调用了该方法,则设置线程进入阻塞时,线程将立即终止阻塞。 |
UserThreadWait方法说明 | ||
---|---|---|
方法名 | UserThreadWait
用于设置线程的阻塞状态和阻塞时间 |
|
参数 | ms | 线程的阻塞时间,单位为毫秒 |
其他 | 如果线程未被阻塞,而先调用了该方法,则设置线程进入阻塞时,线程将立即终止阻塞。 |
9、类UDS
该类为UDS的核心代码,包含了UDS消息的接收和发送处理
相关变量 | |
N_PDU_TYPE_SF | 单帧消息的标识 |
N_PDU_TYPE_FF | 首帧消息的标识 |
N_PDU_TYPE_CF | 连续帧消息的标识 |
N_PDU_TYPE_FC | 流控帧消息的标识 |
INTERVAL | 发送间隔 |
session | 当前消息发送和接收的状态类 |
OK | 相关标识 |
ERROR | |
TIME_OUT | |
seedKey | Seed和key类的实例化,随UDS类实例化 |
maxNumberOfBlockLength | 多帧发送时的多包长度 |
sendOneFrame方法说明 | ||
---|---|---|
方法名 | sendOneFrame
消息发送接口,发送一帧消息 |
|
参数 | frame | UDSDataFrame类型的消息帧 |
其他 | 该方法为消息发送的接口,每调用一次发送一帧消息。
方法调用了PCAN和ZLGCAN设备的发送接口。消息发送时的处理按照PCAN和ZLGCAN提供的官方例程设计。 |
sendData方法说明 | ||
---|---|---|
方法名 | sendData
UDS数据的发送接口,实现单帧和多帧消息的发送 |
|
参数 | data | 数组,UDS消息的数据 |
canID | 发送的ID | |
idType | ID类型,需要转换成PCAN提供的枚举类型 | |
其他 | 该方法为UDS消息的发送接口,包含了单帧消息和多帧消息的发送机制。
数据多包传输时网络层的打包工作在在该接口中完成。 在发送多包的连续帧时由于PCAN和ZLGCAN的发送机制不同,代码上的处理也不同: PCAN通过重复调用发送接口即可快速发送连续帧; ZLGCAN需使用其多帧发送机制,将多帧消息同时发送。 |
sendAndReceive方法说明 | ||
---|---|---|
方法名 | sendAndReceive
UDS数据的发送接口,实现单帧和多帧消息的发送,以及UDS命令反馈判断 |
|
参数 | data | 数组,UDS消息的数据 |
canID | 发送的ID | |
idType | ID类型,需要转换成PCAN提供的枚举类型 | |
其他 | 该方法为UDS消息的发送接口,包含了单帧消息和多帧消息的发送机制。
数据多包传输时网络层的打包工作在在该接口中完成。 在发送多包的连续帧时由于PCAN和ZLGCAN的发送机制不同,代码上的处理也不同: PCAN通过重复调用发送接口即可快速发送连续帧; ZLGCAN需使用其多帧发送机制,将多帧消息同时发送。 |
hexToASCII方法说明 | ||
---|---|---|
方法名 | hexToASCII
将UDS反馈命令中的有效数据转换为ASCII码,返回ASCII的字符串 |
|
参数 | index | 数组索引 |
data | 数组 | |
其他 |
frmAmount方法说明 | ||
---|---|---|
方法名 | frmAmount
多包传输时计算消息的帧数 |
|
参数 | ||
data | 数组 | |
其他 |
senndFirstFrame方法说明 | ||
---|---|---|
方法名 | senndFirstFrame
多包传输时发送首帧 |
|
参数 | data | UDS待发送的 |
frame | 首帧消息帧 | |
其他 |
ReceiveDataProc方法说明 | ||
---|---|---|
方法名 | ReceiveDataProc
CAN消息的接收 |
|
参数 | ||
其他 | CAN消息的接收接口,包含了对UDS反馈消息处理。
该方法由Thread线程调用 |
startReceivedThread方法说明 | ||
---|---|---|
方法名 | startReceivedThread
启动CAN消息接收线程 |
|
参数 | ||
其他 | 该方法创建一个消息接收线程。在软件升级时创建,在升级结束时线程终止 |
uds_entry_reporgMode方法说明 | ||
---|---|---|
方法名 | uds_entry_reporgMode
发送1002命令 |
|
参数 | id | CAN命令的ID |
idType | CAN ID的类型 | |
其他 | 该方法创建一个消息接收线程。在软件升级时创建,在升级结束时线程终止 |
Form1.cs文件说明
该文件包含了Form1窗体中的控件事件和软件升级流程方法。
相关变量及方法 | |
DeviceOperation | OpenDevice类的实例 |
udsPro | UDS类的实例 |
INI | INIOperation类的实例 |
bw_SwUpdate | BackgroundWorker类的实例 |
cl_red | Color类型 |
cl_blue | Color类型 |
MainWindow | 静态窗体,用于在静态方法中操作主船体 |
InvokeDelegate | 委托 |
radio_burnType_checked() | 烧录方式按钮的按下checked事件 |
InvokeMethod() | 主窗体中richtextbox文字设置方法,用于在委托中调用 |
dubugInfoDisplay() | 调试信息显示方法 |
UdsResponseData | 数组,用于保存接收到了UDS反馈命令,3个字节 |
UdsProgModeEntrySuccess | 标志位,用于1002命令的接收:Bit7-Bit4:接收到1002的响应;Bit3-Bit0:1-接收到积极响应 0-接收到消息响应 |
cmd_dect_1002 | Bool型的标志,判断是否检测1002命令的反馈 |
UdsReceivedDataProcess() | UDS消息接收处理,用于在接收线程中判断特定的响应命令。 |
CanDeviceCnntSuccess | CAN设备的连接状态 |
MainForm() | 窗体加载方法,由工程自动创建,在该方法中绑定了bw_SwUpdate的相关事件 |
MainForm_Load() | 窗体的Load方法,由工程自动创建,包含了初始化窗体信息,和读取INI文件配置信息的方法 |
but_CnntDevice_Click() | 设备启动按钮的click方法,由工程自动创建,在该方法中调用了设备启动接口 |
but_LoadFile_Click() | 烧录文件导入按钮的click方法,由工程自动创建 |
but_SaveInfo_Click() | 保存按钮的click方法,由工程自动创建 |
INIReadAllPara() | INI 配置文件读取的方法。 |
SwParaInit() | 软件参数初始化方法,主要用于软件升级时判断参数配置的情况 |
but_StartSwUpdate_Click() | 开始升级按钮的click方法,主要包含了初始化刷写参数,启动消息接收线程和启动UDS刷写线程 |
uds_sw_update_work() | bw_SwUpdate的dowork方法,包含了软件升级的流程 |
uds_sw_update_changed() | bw_SwUpdate的changed方法,主要用于刷写过程中进度条的显示 |
uds_sw_update_completed() | bw_SwUpdate的completed方法,升级线程结束时调用,主要关闭消息接收线程 |
rhtxt_DebugInfo_KeyDown() | Richtextbox的keydown事件, |
rhtxt_DebugInfo_TextChanged() | Richtextbox的TextChanged事件,用于调试信息变化时始终显示最新的信息 |
MainForm_FormClosed() | Form1的FormClosed |
chbx_idType_CheckedChanged() | Id类型按钮的checkedchanged事件,用于显示不同格式的CAN消息ID |
radbut_burnType_MouseDown() | 密文烧录的MouseDown事件 |
SelectedDeviceType | 设备类型枚举 |
Form2.cs文件说明
该文件主要包含了登录窗体的功能
相关变量及方法 | |
frm_Login() | 窗体初始化方法,由工程自动创建 |
but_login_Click() | 登录按钮事件 包含账户和密码识别及主窗体显示,由工程自动创建 |
linkLabel1_MouseClick() | 忘记密码链接的事件,由工程自动创建 |
frm_Login_Load | 窗体的Load事件,由工程自动创建 |
Form3.cs文件说明
该文件主要包含了切换明文/密文烧录时的解锁窗体的功能
相关变量及方法 | |
Form3 () | 窗体初始化方法,由工程自动创建 |
but_unlock_Click | 解锁按钮事件,由工程自动创建,包含密码识别 |
Form3_Load | 窗体的Load事件,由工程自动创建 |
INIOperation.cs文件说明
该文件主要包含INI文件操作的接口。Ini文件操作的接口需要调用系统API。
Writue方法说明 | ||
---|---|---|
方法名 | Writue
Ini文件写入方法 |
|
参数 | section | Ini文件的section |
key | Ini文件的键 | |
value | Ini文件的值 | |
其他 |
ReadValue方法说明 | ||
---|---|---|
方法名 | ReadValue
Ini文件读取方法,返回读取的字符串 |
|
参数 | section | Ini文件的section |
key | Ini文件的键 | |
其他 |
LicenseAnalysis.cs文件说明
该文件主要包含license文件的处理方法
各变量及接口的解释清查看详细代码注释。
License文件由注册机生成,需要保证license文件的解析方法和生成方法匹配。
Program.cs文件说明
该文件包含了程序入口。
Main方法中包含了license处理接口的调用,若无需处理license可以将相关语句屏蔽。
见代码注释。
SecurityAccess.cs文件说明
该文件包含了27服务中安全算法的接口
AccessAlgorithm—安全算法接口
需要保证上位机的安全算法和BootLoader软甲的安全算法一致。
SRecordProcess.cs
该文件包含Mot16格式的文件的处理方法及相关参数定义。
相关变量 | |
SourceFilePath | 烧录文件的路径 |
S19StartAddr_App | 应用程序的起始地址 |
S19DataLen_App | 应用程序的长度 |
S19DataRecord_App | 数组,有效的应用程序数据(以起始地址和长度开始的数据) |
SRecordDefaultCode | 芯片Flash的缺省码 |
SRecordAnalysis_app方法说明 | ||
---|---|---|
方法名 | SRecordAnalysis_app
Mot16文件解析,提取有效的应用程序数据。同时根据烧录格式进行解密 |
|
参数 | scrPath | 烧录文件路径 |
其他 |
StrToHexByte方法说明 | ||
---|---|---|
方法名 | StrToHexByte
将字符串转换为16进制数 返回16进制的数组 |
|
参数 | hexString | 字符串 |
其他 |
SRecordBlockSizeCal方法说明 | ||
---|---|---|
方法名 | SRecordBlockSizeCal
UDS数据下载时的块个数计算 |
|
参数 | s19record | 应用程序的有效数据,也是UDS下载的有效数据 |
s19maxDwsize | 块大小,该参数由34服务的反馈决定 | |
BlockSize | 数据下载时的块个数。 | |
其他 |