目标:

车辆ECU需要更新软件,通过OBD口实现,通过CAN总线实现,编程语言是CAPL。

刷写流程基于ISO15765-3;应用层基于UDS(ISO14229)诊断协议;TP层基于ISO15765-2;数据链路层和物理层基于ISO11898

实现:

1.图形用户界面使用CANoe自带的panel来实现,用户可以选取刷写文件,ECU的地址等信息,这些信息通过环境变量被程序访问,环境变量在CANDB++中编辑生成。

2.软件架构:

刷写工具解析s19 app,如果没有s19 app,那么可以使用HexView将HEX,BIN等app转成s19文件

依据ISO15765-3编写刷写流程代码,将app数据扔给应用层

应用层是基于UDS编写的,应用层在将数据扔给TP层

TP层将数据扔给数据链路层

数据链路层将数据扔给物理层,数据通过CAN总线被ECU接收

代码:

工作保密原因,只贴出UDS层的代码,秘钥也删了

[cpp] view plaincopy
  1. includes{
  2. }
  3. variables{
  4. char gECU[7]="Tester";
  5. int     useExtendedId=0;                                      //use standard Id
  6. long    useFC=1;                                             //use flow control
  7. long    bs=8;                                                //block size of FC
  8. long    stmin=20;                                            //set STmin to 10 ms
  9. dword   tester_address=0x7c1;                               //tester address
  10. dword   target_ecu_address=0x7c9;                           //BCM address
  11. char    wait_rsp_text_event[18]="response received";        //used to wait for response
  12. const int BUFFER_SIZE_2048=0x2048;
  13. const int BUFFER_SIZE_1024=0x1024;
  14. const int LENGTH_4=4;
  15. byte      rxBuffer[BUFFER_SIZE_2048];                          //receive buffer
  16. long      rxBufferLen=0;                                       //receive buffer length
  17. dword     timeout=5000;
  18. dword     min_request_distance=50;                            //minum distance between two request
  19. dword     dist_request = 10;
  20. char      gDebugBuffer[255];
  21. }
  22. /*
  23. read fault memory
  24. */
  25. int read_fault_memory(byte _sub_func,byte _status_mask){
  26. byte request[3]={0x19,0x02,0x09};
  27. rxBufferLen=0;
  28. request[1]=_sub_func;request[2]=_status_mask;
  29. OSEKTL_DataReq(request,elcount(request));
  30. return wait_server_response(request,timeout);
  31. }
  32. /*
  33. sessionControl
  34. */
  35. int session_control(byte _session_type){
  36. byte request[2]={0x10,0x01};
  37. request[1]=_session_type;
  38. OSEKTL_DataReq(request,elcount(request));
  39. return wait_server_response(request,timeout);
  40. }
  41. /*
  42. reset
  43. */
  44. int reset(byte reset_type){
  45. byte request[2]={0x11,0x01};
  46. request[1]=reset_type;
  47. OSEKTL_DataReq(request,elcount(request));
  48. return wait_server_response(request,timeout);
  49. }
  50. /*
  51. securityAccess
  52. */
  53. int security_access(byte security_level,byte seed_szie,char ecu_name[]){
  54. //actual size of Seed & Key Arrays depends on ECU
  55. byte      gSeedArray[2];
  56. dword     gSeedArraySize   = 4;
  57. char      gVariant[9]    = "Variant1";
  58. char      gOption[7]     = "option";
  59. dword     gMaxKeyArraySize = 4;
  60. dword     gActualSize  = 0;
  61. byte      request_seed[2]={0x27,0x01};
  62. byte      send_key[6]={0x27,0x02,0xAA,0xAA,0xAA,0xAA};
  63. byte      const_secu_flash[4]={};           //security const number for level flash for BCM
  64. byte      const_secu_level1[4]={};          //security const number for level 1 for BCM
  65. byte      const_secu_flash_rfcm[4]={};           //security const number for level flash for BCM
  66. byte      seed[4]={0xAA,0xAA,0xAA,0xAA};                       //store the seed received from server
  67. byte      _key[4]={0xAA,0xAA,0xAA,0xAA};                       //store the key generated by tester
  68. int       i=0;
  69. request_seed[ 1 ] = security_level;send_key[ 1 ] = security_level + 0x01;
  70. OSEKTL_DataReq(request_seed,elcount(request_seed));
  71. if(wait_server_response(request_seed,timeout)!=0){
  72. write("fail to retrive seed while unlocking ECU");
  73. return -1;
  74. }
  75. for(i=0;i<seed_szie;++i){
  76. seed[i]=rxBuffer[i+2];
  77. }
  78. gSeedArraySize = seed_szie;gMaxKeyArraySize = seed_szie;
  79. //generate_key(const_secu_flash_rfcm,seed,_key);
  80. diagSetTarget(ecu_name);
  81. DiagGenerateKeyFromSeed(seed, gSeedArraySize, security_level, gVariant, gOption, _key, gMaxKeyArraySize, gActualSize);
  82. for(i=0;i<gActualSize;++i){
  83. send_key[i+2]=_key[i];
  84. }
  85. OSEKTL_DataReq(send_key,2+gActualSize);
  86. return wait_server_response(send_key,timeout);
  87. }
  88. _Diag_GetError (char buffer[])
  89. {
  90. //called if error in DiagGenerateKeyFromSeed occurs
  91. snprintf(gDebugBuffer,elcount(gDebugBuffer),"%s", buffer);
  92. write("CALLBACK %s", gDebugBuffer);
  93. }
  94. /*
  95. routineControl
  96. */
  97. int routine_control(byte _routine_control_type,byte _routine_id[],byte data_record[],int data_record_length){
  98. byte request[BUFFER_SIZE_1024];
  99. int index=0;
  100. request[0]=0x31;
  101. request[1]=_routine_control_type;
  102. request[2]=_routine_id[0];
  103. request[3]=_routine_id[1];
  104. for(index=0;index<data_record_length;++index){
  105. request[index+4]=data_record[index];
  106. }
  107. OSEKTL_DataReq(request,data_record_length+4);
  108. return wait_server_response(request,timeout);
  109. }
  110. /*
  111. generate key according to the received seed
  112. */
  113. void generate_key(byte const_secu[],byte seed_secu_flash[],byte securityKey[]){
  114. byte key1_secu_flash[4]={0x00,0x00,0x00,0x00};
  115. byte key2_secu_flash[4]={0x00,0x00,0x00,0x00};
  116. int i=0;
  117. byte tmp=0x00;
  118. for(i=0;i<4;++i){
  119. key1_secu_flash[i]=seed_secu_flash[i]^const_secu[i];
  120. }
  121. for(i=0;i<2;++i){
  122. tmp=seed_secu_flash[i];
  123. seed_secu_flash[i]=seed_secu_flash[3-i];
  124. seed_secu_flash[3-i]=tmp;
  125. }
  126. for(i=0;i<4;++i){
  127. key2_secu_flash[i]=seed_secu_flash[i]^const_secu[i];
  128. }
  129. for(i=0;i<4;++i){
  130. securityKey[i]=key1_secu_flash[i]+key2_secu_flash[i];
  131. }
  132. }
  133. /*
  134. communicationControl
  135. */
  136. int communication_control(byte _control_type,byte _communication_type){
  137. byte request[3]={0x28,0x00,0x00};
  138. request[1]=_control_type;request[2]=_communication_type;
  139. OSEKTL_DataReq(request,elcount(request));
  140. return wait_server_response(request,timeout);
  141. }
  142. /*
  143. controlDTCSetting
  144. */
  145. int control_dtc_setting(byte _DTC_setting_type){
  146. byte request[2]={0x85,0x00};
  147. request[1]=_DTC_setting_type;
  148. OSEKTL_DataReq(request,elcount(request));
  149. return wait_server_response(request,timeout);
  150. }
  151. /*
  152. tester Present
  153. */
  154. int tester_present(byte sub_function){
  155. byte request[2]={0x3e,0x00};
  156. request[1]=sub_function;
  157. OSEKTL_DataReq(request,elcount(request));
  158. return wait_server_response(request,timeout);
  159. }
  160. /*
  161. writeDataByID
  162. */
  163. int write_data_by_id(byte did[],byte _data_record[],int _data_record_length){
  164. byte request[256];
  165. int i=0,_did_length=2;
  166. request[0]=0x2E;
  167. for(i=0;i<_did_length;++i){
  168. request[1+i]=did[i];
  169. }
  170. for(i=0;i<_data_record_length;++i){
  171. request[1+_did_length+i]=_data_record[i];
  172. }
  173. OSEKTL_DataReq(request,1+_did_length+_data_record_length);
  174. return wait_server_response(request,timeout);
  175. }
  176. /*
  177. requestDownload
  178. */
  179. int request_download(byte _memory_address[],int _memory_address_length,byte _memory_size[],int __memory_size_length){
  180. byte request[256];
  181. int i=0;
  182. request[0]=0x34;request[1]=0x00;request[2]=0x44;
  183. for(i=0;i<_memory_address_length;++i){
  184. request[3+i]=_memory_address[i];
  185. }
  186. for(i=0;i<__memory_size_length;++i){
  187. request[3+_memory_address_length+i]=_memory_size[i];
  188. }
  189. OSEKTL_DataReq(request,3+_memory_address_length+__memory_size_length);
  190. return wait_server_response(request,timeout);
  191. }
  192. /*
  193. tansferData
  194. */
  195. int transfer_data(byte _block_sequence,byte _upload_data[],int _upload_data_length){
  196. byte request[BUFFER_SIZE_2048];
  197. int i=0 , status = 0;
  198. request[0]=0x36;request[1]=_block_sequence;
  199. for(i=0;i<_upload_data_length;++i){
  200. request[2+i]=_upload_data[i];
  201. }
  202. OSEKTL_DataReq(request,_upload_data_length+2);
  203. status = wait_server_response(request,timeout);
  204. return status;
  205. }
  206. /*
  207. requstTransferExit
  208. */
  209. int request_transfer_exit(){
  210. byte request[1]={0x37};
  211. OSEKTL_DataReq(request,elcount(request));
  212. return wait_server_response(request,timeout);
  213. }
  214. int read_data_by_id(byte did[]){
  215. byte request[3]={0x22,0x00,0x00};
  216. request[1]=did[0];
  217. request[2]=did[1];
  218. OSEKTL_DataReq(request,elcount(request));
  219. return wait_server_response(request,timeout);
  220. }
  221. OSEKTL_FirstFrameIndication( long sourceadr, long destadr, long rxCount )
  222. {
  223. /* Print message to write window */
  224. //write("CAPL: %s: FF indication called, SA= 0x%02lx, TA= 0x%02lx, RxCount = %ld (AE=%d)", gECU, sourceadr, destadr, rxCount, OSEKTL_GetRecentAE());
  225. }
  226. //error handle
  227. OSEKTL_ErrorInd(int error)
  228. {
  229. switch (error)
  230. {
  231. case 1:     write("----CAPL: Error (%d): Timeout while waiting for CF", error);     break;
  232. case 2:     write("----CAPL: Error (%d): Timeout while waiting for FC", error);     break;
  233. case 3:     write("----CAPL: Error (%d): Wrong Sequence Number", error);            break;
  234. case 4:     write("----CAPL: Error (%d): TP_DLL busy", error);                      break;
  235. case 5:     write("----CAPL: Error (%d): Unexpected PDU", error);stop();                   break;
  236. case 6:     write("----CAPL: Error (%d): Timeout while waiting for Tx-Ack", error); break;
  237. case 7:     write("----CAPL: Error (%d): WFT Overrun", error);                      break;
  238. case 8:     write("----CAPL: Error (%d): Buffer overflow", error);                  break;
  239. case 9:     write("----CAPL: Error (%d): Wrong parameter", error);                      break;
  240. default:    write("----CAPL: Error (%d): unknown error", error);                    break;
  241. }
  242. }
  243. //request confirm
  244. OSEKTL_DataCon(long status)
  245. {
  246. if (status != 0)
  247. {
  248. //write("CAPL: %s: data sent using normal addressing", gECU);
  249. }
  250. else
  251. {
  252. write("----CAPL: %s: tx error, status is %d", gECU, status);
  253. }
  254. }
  255. OSEKTL_DataInd( long rxCount )
  256. {
  257. dword glhandle=0;
  258. /* Get received data */
  259. OSEKTL_GetRxData( rxBuffer, 4095 );
  260. rxBufferLen=rxCount;
  261. //signal response received
  262. TestSupplyTextEvent(wait_rsp_text_event);
  263. }
  264. //process will suspend for tTime ms to wait for response
  265. int wait_server_response(byte request[],dword _tTime){
  266. long status=0;
  267. int result=0;
  268. long flag=5;
  269. flag=2;result=0;status=0;
  270. //loop while response pending
  271. while(flag>=0)
  272. {
  273. status=testWaitForTextEvent(wait_rsp_text_event,_tTime);
  274. if(status<0){
  275. write("service %x:fail to wait server response",request[0]);
  276. return -1;
  277. }else if(status==0){
  278. write("service %x:timeout while waiting for server\'s response",request[0]);
  279. return -1;
  280. }
  281. result=checkResponse(request);
  282. if(result==-3){
  283. write("response pending");
  284. flag=5;
  285. }
  286. if(result==-2){
  287. write("Warning:unexpected positive response");
  288. flag--;
  289. }
  290. if(result==-1){
  291. write("service %x:negative response received",request[0]);
  292. break;
  293. }
  294. if(result==0){
  295. //write("positive response received\n");
  296. break;
  297. }
  298. }
  299. if(result<0){
  300. msgBeep(5);
  301. return -1;
  302. }
  303. return 0;
  304. }
  305. /*
  306. check response
  307. return 0 if positive response received
  308. otherwise return -1,-2,-3,0
  309. */
  310. int checkResponse(byte request[]){
  311. if(rxBufferLen<=0){
  312. write("Error:empty response reveived\n");
  313. return -1;
  314. }
  315. else{
  316. if(rxBuffer[0]==request[0]+0x40){
  317. //write("positive response received\n");
  318. return 0;
  319. }else if(rxBuffer[0]!=0x7F&&rxBuffer[0]!=(rxBuffer[0]+0x40)){
  320. //unexpected positive response
  321. return -2;
  322. }
  323. else if(rxBuffer[0]==0x7F&&rxBuffer[1]==request[0]){
  324. if(rxBuffer[2]!=0x78)
  325. {
  326. //write("Error:negative response received\n");
  327. return -1;
  328. }else{
  329. //response pending
  330. return -3;
  331. }
  332. }
  333. }
  334. return 0;
  335. }

车辆ECU需要更新软件相关推荐

  1. 中国固件更新软件被指盗取用户数据 遭美手机厂商替换

    据外媒报道,美国廉价Android手机制造商Blu周五表示,公司将把被指盗取用户数据的中国固件更新软件替换成谷歌批准的软件. 安全公司Kryptowire在上月披露,一款固件更新应用能够监控用户通讯, ...

  2. Ubuntu 16.04更新软件提示需要安装不能信任的软件包 http://archive.ubuntukylin.com:10006/ubuntukylin xenial InRelease

    刚才用 Ubuntu 16.04更新软件时提示"需要安装不能信任的软件包","这个动作需要从没有授权的软件源来安装软件包", 赋予权限执行仍然无法安装,上网查了 ...

  3. ubuntu 更新软件

    ubuntu 更新软件 sudo apt-get update 获得最近的软件包的列表,列表中包括一些包的更新,比如这个包是否更新过,在换源后一定要做. sudo apt-get upgrade 这里 ...

  4. 英伟达驱动更新记录_N卡驱动更新软件(NVIDIA GeForce Experience) v3.16.0.122 官方版

    NVIDIA GeForce Experience显卡驱动更新软件可以帮助你检查计算机的geforce驱动程序,并且将其更新到最新的版本.更新显卡驱动有利于更稳定流畅的运行游戏. 功能介绍 1.让驱动 ...

  5. yum 更新_CentOS7 - 使用yum-cron自动更新软件

    使用yum-cron自动更新软件 我们知道保持在任何安全警报和应用重要更新之上的重要性,但确保CentOS系统上的所有软件都得到更新可能是一项繁琐而耗时的任务,尤其是当您管理的不仅仅是 一台服务器. ...

  6. 解决 Ubuntu 无法更新软件问题

    有时会遇到能 ping 通外网,但是无法更新软件的情况. 如: 正在读取软件包列表... 有错误!?? 解决方法如下: sudo apt-get clean cd /var/lib/apt sudo ...

  7. 织梦文章批量更新软件

    简介: 织梦文章批量更新软件适用于织梦网站的站长用户,能够帮助用户自动更新网站上面的文章,站长往往需要在网站中大量更新文章以保证网站的点击量,有时需要大量的时间去更新非常浪费时间,通过这款软件能够快速 ...

  8. Linux学习笔记---更新软件源

    在安装或者更新软件的时候,系统默认会从官方网站上下载数据.但是官方网站都是在国外,访问速度非常慢. 为了使软件下载速度更快,可以将软件源的下载地址由国外改到国内,这样软件在更新或者下载的时候速度就会快 ...

  9. linux 更新软件源

    更新软件源: root权限: leafpad /etc/apt/sources.list 然后添加以下较快的源: deb http://http.kali.org/kali kali main non ...

  10. iPhone 无法更新软件

    iPhone不是最新的iOS 操作系统在软件更新时候可能会遇到无法更新的情况,大多是因为App Store 的条款变更了,没有及时收到条款更新提醒. 解决办法如下: 首先在App Store中注销当前 ...

最新文章

  1. 聊聊 SpringCloud 中的父子容器
  2. 解决在VS(winform)程序中无法在调试时修改代码的问题(也就是“编辑并继续”功能无效)...
  3. CodeForces - 1360G A/B Matrix(最大流)
  4. C/C++学习之路: STL
  5. fpga初始化错误_FPGA低温启动失败
  6. UI控件之UISlider
  7. java8 function 多线程安全_Java8新特性_传统时间格式化的线程安全问题
  8. 《演讲之禅》迷你书免费下载 每小时30000美元的秘诀
  9. Math详解大全,数学类
  10. 电磁兼容EMC标准 CISPR 22:EN 55022
  11. 基于人脸识别的学生签到打卡系统用户使用指南
  12. 基于mt7621架构路由器编译auditord(生成ipk包)
  13. 数据库增删改查的基本语法
  14. lempel ziv算法c语言,数学之路-python计算实战(4)-Lempel-Ziv压缩(2)(示例代码)
  15. 三星大规模生产3nm芯片?预计明年就能流通各大手机厂商手中
  16. springmvc接收请求参数(springmvc教程二)
  17. matlab合并数据,matlab使用小技巧——数据的拆分与合并
  18. 海阔凭鱼跃 天高任鸟飞-大上海,人人都向往的城市
  19. 对于anaconda安装的一个小感悟 。
  20. IDM trust Keycloak

热门文章

  1. jupyter 使用nginx进行代理的nginx配置文件
  2. Windows Server 2008 R2 C盘空间不足解决方法
  3. 7. 文件和数据格式化
  4. 基于MATLAB的激光光斑图像处理算法
  5. MATLAB寻找高斯光束光斑中心
  6. 自动驾驶 Apollo 源码分析系列,感知篇(三):红绿灯检测和识别
  7. 计算机DVD驱动禁用怎么恢复,设备管理器中找不到dvd驱动器 怎么恢复 - 驱动管家...
  8. nodejs打开默认浏览器
  9. 最新版火车头织梦内容发布规则_火车头采集 - 织梦图集发布模块的制作
  10. ICE的Timer和TimerTask