blob: 6d04a83887ffa460707f24182054af25cbc51410 [file] [log] [blame]
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08001#include "sp_msgpack.h"
2#include "sp_flash.h"
3#include "sp_util.h"
4#include "sp_display.h"
5#include "sp_communicate.h"
6#include "sp_upgrade.h"
7
8extern uint16 crc_table[];
9
10#pragma pack(push)
11#pragma pack(1)
12typedef struct
13{
14 uint32 file_size;
15 uint8 file_crc[2];
16 uint8 file_md5[16];
17} sp_upgrade_info_t;
18#pragma pack(pop)
19
20/*
21**************************************************************************************************************
22* CRC У Ñé
23* Ãè Êö: УÑéÒ»´®charÊý¾ÝµÄCRC
24*
25* Êä Èë: CPU_CHAR *str - ҪУÑéÊý¾ÝµÄÖ¸Õë
26* CPU_INT16U size - ҪУÑéÊý¾ÝµÄ³¤¶È
27* CPU_INT08U mode - УÑéµÄģʽ
28* 1: Ϊ¸Ã´®Êý¾ÝÔö¼ÓCRCУÑé ͬʱ·µ»ØÐ£ÑéµÄCRCÖµ
29* 0: ¸Ã´®Êý¾ÝÊÇ·ñͨ¹ýУÑé ·µ»ØÐ£ÑéµÄCRCÖµ
30* ·µ »Ø:
31*
32* ×¢ Òâ:
33*
34**************************************************************************************************************
35*/
36//CRCʹÓÃ
37typedef struct
38{
39 uint8 L;
40 uint8 H;
41} INT_08BIT_2;
42
43typedef union
44{
45 uint16 Int16Bit;
46 INT_08BIT_2 Int08Bit;
47} INT_16BIT_08BIT;
48
49uint16 AH_CRC_Verify(uint8 str[], uint16 size, uint8 mode)
50{
51 uint32 i;
52 INT_16BIT_08BIT crc;
53 INT_16BIT_08BIT y;
54
55 crc.Int16Bit = 0;
56 for(i = 0 ; i < size ; i++)
57 {
58 y.Int16Bit = crc_table[ str[ i ] ^ crc.Int08Bit.H ];
59 y.Int08Bit.H ^= crc.Int08Bit.L;
60 crc.Int16Bit = y.Int16Bit;
61 }
62 if(mode == 1)
63 {
64 str[ i++ ] = y.Int08Bit.H ;
65 str[ i ] = y.Int08Bit.L ;
66 }
67 return(crc.Int16Bit);
68}
69
70static uint16 update_upgrade_mark(uint32 CheckSum, uint32 size)
71{
72 uint16 ret,i;
73 uint8 buff[18] = { 0x5a,0x4b,0x3c,0x2d,0x1e,0x0f } ;
74
75 //дÉý¼¶Êý¾Ý³É¹¦Ð´ÈëFLASH±ê¼Ç, ºÍУÑéÂë, ÓÐЧ´úÂ볤¶ÈдÈëÊý¾ÝFLASH
76 memcpy(buff+6, (unsigned char*)&(CheckSum), 4) ; //УÑéºÍ
77 memcpy(buff+10,(unsigned char*)&(size) ,4) ; //Êý¾Ý³¤¶È
78 AH_CRC_Verify(buff, 14, 1);
79
80 for(i = 0; i<5; i++)
81 {
82 ret = sp_flash_erase(DEF_IapMarkAddr);
83 if(ret)
84 {
85 continue;
86 }
87 ret = sp_flash_write(DEF_IapMarkAddr, buff, 16);
88 if(!ret)
89 {
90 break;
91 }
92 }
93 if(i >= 5)
94 {
95 return 1;
96 }
97 return 0;
98}
99/**********************************************************************************************
100º¯ÊýÃû³Æ: U32 APP_IapDataSumCheck( U32 staaddr, U32 len, U08 mode )
101º¯Êý×÷ÓÃ: ¶Á³öFLASHÖеÄÊý¾Ý£¬²¢ÐγÉУÑé
102º¯ÊýÊäÈë: staaddr - ¿ªÊ¼µØÖ·
103 len - Êý¾Ý³¤¶È
104 mode - УÑéģʽ 0 È¡·´ºÍУÑé 1 ÆÕͨºÍУÑé
105º¯ÊýÊä³ö: ÎÞ
106º¯Êý·µ»ØÖµ: 0 ³É¹¦ ÆäËûʧ°Ü
107**********************************************************************************************/
108uint32 do_APP_IapDataSumCheck(uint32 staaddr, uint32 len, uint8 mode)
109{
110 uint32 Sum;
111 uint32 app_len, checksize, size;
112 uint16 rcode, i;
113 uint8 buffer[1024];//IAP_MAXLEN
114
115 app_len = len;
116 checksize = 0;
117 Sum = 0;
118 while(checksize < app_len)
119 {
120 if(len < 1024)
121 {
122 size = len;
123 }
124 else
125 {
126 size = 1024;
127 }
128
129 for(i=0; i<5; i++)
130 {
131 rcode = sp_flash_read((staaddr + checksize), buffer, size);
132 if(!rcode)
133 {
134 break;
135 }
136 }
137
138 if(mode == 0)
139 {
140 for(i = 0; i < size; i++)
141 {
142 Sum += ((~buffer[i]) & 0xFF); //еÄÊÇÈ¡·´ºÍ
143 }
144 }
145 else
146 {
147 for(i = 0; i < size; i++)
148 {
149 Sum += buffer[i]; //ÀϵÄÊÇÖ±½ÓºÍ
150 }
151 }
152 checksize += size;
153 len -= size;
154 }
155
156 return (Sum);
157}
158static uint8 get_file_info(sp_pos_t* pos, sp_upgrade_info_t* upgradeinfo)
159{
160 uint8 ret;
161 uint8 size;
162 char temp[32];
163 sp_protocol_request_t req;
164 sp_protocol_response_t resp;
165 cw_pack_context pack;
166 cw_unpack_context unpack;
167 unpack_field_t field;
168
169 sp_flash_read(ADDR_UPGRADE_UPINFO,(uint8*)upgradeinfo,sizeof(sp_upgrade_info_t));
170
171 /*¶ÁÈ¡Îļþ³¤¶ÈºÍCRC*/
172 sp_protocol_req_init(&req,SP_CMD_UPGRADE);
173 sp_pack_init(&pack,req.data,sizeof(req.data));
174 cw_pack_map_size(&pack,5);
175
176 sp_pack_put_bin(&pack,PK_BIN_DEVPHYID, pos->devphyid, sizeof(pos->devphyid));
177 sp_pack_put_int(&pack,PK_INT_SEQNO ,0xFFFF);
178 sp_pack_put_str(&pack,PK_STR_DEVTYPE, DEV_TYPE);
179 sp_pack_put_str(&pack,PK_STR_VERSION, PRO_VERSION);
180 sp_pack_put_bin(&pack,PK_BIN_SOFT_MD5,upgradeinfo->file_md5,16);
181
182 req.datalen += sp_pack_length(&pack);
183 ret = sp_comm_call(pos, &req, &resp, COMM_WAIT_TIME);
184 if(!ret)
185 {
186 sp_unpack_init(&unpack,resp.data,resp.datalen);
187 //erase
188 sp_flash_erase(ADDR_UPGRADE_UPINFO);
189 size = sp_unpack_map_size(&unpack);
190 while(size-- > 0)
191 {
192 sp_unpack_value(&unpack,&field);
193 // 4 byte file_length,2 crc
194 if(IS_KEY(PK_INT_FILESIZE,field.key))
195 {
196 upgradeinfo->file_size = (uint32)field.val.intval;
197 }
198 else if(IS_KEY(PK_BIN_FILECRC,field.key))
199 {
200 if(field.strlen != 2)
201 {
202 sprintf(temp,"CRC³¤¶È=%d",field.strlen);
203 disp_hint_info_two(pos, "Éý¼¶Ê§°Ü",temp,DELAY_TIME3s);
204 return 1;
205 }
206 MEMCPY(upgradeinfo->file_crc,field.val.binval,field.strlen);
207 }
208 else if(IS_KEY(PK_BIN_SOFT_MD5,field.key))
209 {
210 MEMCPY(upgradeinfo->file_md5,field.val.binval,field.strlen);
211 }
212 }
213 }
214 else
215 {
216 disp_server_errmsg(pos, "Éý¼¶Ê§°Ü",resp.data,resp.datalen);
217 }
218 return ret;
219}
220static uint8 download_file(sp_pos_t* pos)
221{
222 uint8 ret;
223 uint8 timeout_trycnt = 0;
224 uint8 sameseq_trycnt = 0;
225 uint8 data_len = 0;
226 uint16 seqno = 0;
227 uint16 resp_seqno = 0;
228 uint32 offset = 0;
229 uint8 endflag = 0;
230 uint8 size;
231 char temp[32];
232 uint8 buf[128];
233 sp_protocol_request_t req;
234 sp_protocol_response_t resp;
235 cw_pack_context pack;
236 cw_unpack_context unpack;
237 unpack_field_t field;
238
239 for(offset = ADDR_UPGRADE_BEGIN; offset < ADDR_UPGRADE_END; offset +=DEF_FLASH_PageSize)
240 {
241 sp_flash_erase(offset);
242 }
243 offset = 0;
244 while(1)
245 {
246 sp_feed_dog();
247 sp_protocol_req_init(&req,SP_CMD_UPGRADE);
248 sp_pack_init(&pack,req.data,sizeof(req.data));
249 cw_pack_map_size(&pack,2);
250
251 sp_pack_put_bin(&pack,PK_BIN_DEVPHYID, pos->devphyid, sizeof(pos->devphyid));
252 sp_pack_put_int(&pack,PK_INT_SEQNO,seqno);
253
254 req.datalen += sp_pack_length(&pack);
255 ret = sp_comm_call(pos, &req,&resp, COMM_WAIT_TIME);
256 if(!ret)
257 {
258 timeout_trycnt = 0;//success reset
259 sp_unpack_init(&unpack,resp.data,resp.datalen);
260 size = sp_unpack_map_size(&unpack);
261 while(size-- > 0)
262 {
263 sp_unpack_value(&unpack,&field);
264 if(IS_KEY(PK_INT_SEQNO,field.key))
265 {
266 resp_seqno = (uint32)field.val.intval;
267 }
268 else if(IS_KEY(PK_INT_FLAG,field.key))
269 {
270 if(0 == MEMCMP("end",field.val.strval,field.strlen))
271 {
272 // ÎļþÏÂÔØÍê³É
273 endflag = 1;
274 }
275 }
276 else if(IS_KEY(PK_BIN_FILEDATA,field.key))
277 {
278 data_len = field.strlen;
279 if(data_len > sizeof(buf))
280 {
281 sprintf(temp,"´íÎ󳤶È=%d",data_len);
282 disp_hint_info_two(pos, "Éý¼¶Ê§°Ü",temp,DELAY_TIME3s);
283 return 1;
284 }
285 MEMCLEAR(buf,sizeof buf);
286 MEMCPY(buf,field.val.binval,data_len);
287 }
288 }
289
290 if(resp_seqno != seqno +1)
291 {
292 if(10 < sameseq_trycnt)
293 {
294 return 1;
295 }
296 ++sameseq_trycnt;
297 continue;
298 }
299 sameseq_trycnt = 0;
300
301 ++seqno;
302 snprintf(temp,sizeof temp,"seqno = %04d",seqno);
303 disp_hint_info_two(pos, "ÕýÔÚÉý¼¶...",temp,0);
304
305 sp_flash_write(ADDR_UPGRADE_BEGIN+offset,buf,data_len);
306 if(endflag)
307 {
308 return 0;
309 }
310
311 offset += (uint32)data_len;
312 if(ADDR_UPGRADE_BEGIN + offset >= ADDR_UPGRADE_END)
313 {
zongqiang.zhangcb1f2692019-11-26 17:17:14 +0800314 disp_hint_info_two(pos,"Éý¼¶Ê§°Ü", "ÏÂÔØÎļþ¹ý´ó",DELAY_TIME3s);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800315 return 1;
316 }
317 }
318 else
319 {
320 if(3 < timeout_trycnt)
321 {
zongqiang.zhangcb1f2692019-11-26 17:17:14 +0800322 disp_hint_info_two(pos,"Éý¼¶Ê§°Ü", "ÏÂÔØÎļþ³¬Ê±",DELAY_TIME3s);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800323 return 1;
324 }
325 Delay_ms(DELAY_TIME1s);
326 ++timeout_trycnt;
327 }
328 }
329}
330static uint8 check_file_and_upgrade(sp_pos_t* pos, sp_upgrade_info_t* upgradeinfo)
331{
332 uint16 ret;
333 uint8 crc[2];
334 uint8 temp_crc[2];
335 uint8 buf[128];
336 uint32 sumcrc;
337
338 uint32 page_index = 0;
339 uint32 page_num = (upgradeinfo->file_size-1)/sizeof(buf) + 1;
340 while(1)
341 {
342 if(page_num == page_index +1)
343 {
344 sp_flash_read(ADDR_UPGRADE_BEGIN +page_index*sizeof(buf),buf,
345 sizeof buf);
346 memcpy(temp_crc,crc,2);
347 if(upgradeinfo->file_size%sizeof(buf) == 0)
348 {
349 sp_protocol_crc_init(buf,sizeof(buf),temp_crc,crc);
350 }
351 else
352 {
353 sp_protocol_crc_init(buf,upgradeinfo->file_size%sizeof(buf),temp_crc,crc);
354 }
355 if(0 == MEMCMP(upgradeinfo->file_crc,crc,2))
356 {
357 sp_flash_write(ADDR_UPGRADE_UPINFO,(uint8*)upgradeinfo,sizeof(sp_upgrade_info_t));
358
359 sumcrc = do_APP_IapDataSumCheck(ADDR_UPGRADE_BEGIN,upgradeinfo->file_size,0);
360 /*Éý¼¶ºó,boot »á²Á³ý¸ÃÒ³¼Ç¼ */
361 //¸üбê־λÖÃλ
362 ret = update_upgrade_mark(sumcrc,upgradeinfo->file_size);
363 if(ret)
364 {
365 disp_hint_info_two(pos, "Éý¼¶Ê§°Ü","¸üбê־ʧ°Ü",DELAY_TIME2s);
366 return 1;
367 }
368 else
369 {
370 disp_hint_info_two(pos, "ÕýÔÚÉý¼¶","ÇëÎð¶Ïµç",DELAY_TIME2s);
371 sp_reset();
372 return 0;
373 }
374 }
375 else
376 {
zongqiang.zhangcb1f2692019-11-26 17:17:14 +0800377 disp_hint_info_two(pos,"Éý¼¶Ê§°Ü", "ÎļþУÑé´íÎó",DELAY_TIME3s);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800378 return 1;
379 }
380 }
381 else
382 {
383 sp_flash_read(ADDR_UPGRADE_BEGIN+page_index*sizeof(buf),buf,sizeof buf);
384 if(0 == page_index)
385 {
386 sp_protocol_crc(buf,sizeof buf,crc);
387 }
388 else
389 {
390 memcpy(temp_crc,crc,2);
391 sp_protocol_crc_init(buf,sizeof buf,temp_crc,crc);
392 }
393 ++page_index;
394 }
395 }
396}
397void sp_manual_upgrade(sp_pos_t* pos)
398{
399 uint8 ret;
400 sp_upgrade_info_t upgradeinfo;
401
402 disp_hint_info_two(pos, "ÕýÔÚÉý¼¶..","Îð¶Ïµç!!",0);
403 MEMCLEAR(&upgradeinfo,sizeof upgradeinfo);
404 ret = get_file_info(pos, &upgradeinfo);
405 if(ret)
406 {
407 return;
408 }
409 ret = download_file(pos);
410 if(ret)
411 {
412 return;
413 }
414 check_file_and_upgrade(pos, &upgradeinfo);
415}
416