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

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。