大理水控初始版本
diff --git a/supwisdom/sp_upgrade.c b/supwisdom/sp_upgrade.c
new file mode 100644
index 0000000..6f2fdb8
--- /dev/null
+++ b/supwisdom/sp_upgrade.c
@@ -0,0 +1,416 @@
+#include "sp_msgpack.h"
+#include "sp_flash.h"
+#include "sp_util.h"
+#include "sp_display.h"
+#include "sp_communicate.h"
+#include "sp_upgrade.h"
+
+extern uint16 crc_table[];
+
+#pragma pack(push)
+#pragma pack(1)
+typedef struct
+{
+ uint32 file_size;
+ uint8 file_crc[2];
+ uint8 file_md5[16];
+} sp_upgrade_info_t;
+#pragma pack(pop)
+
+/*
+**************************************************************************************************************
+* CRC У Ñé
+* Ãè Êö: УÑéÒ»´®charÊý¾ÝµÄCRC
+*
+* Êä Èë: CPU_CHAR *str - ҪУÑéÊý¾ÝµÄÖ¸Õë
+* CPU_INT16U size - ҪУÑéÊý¾ÝµÄ³¤¶È
+* CPU_INT08U mode - УÑéµÄģʽ
+* 1: Ϊ¸Ã´®Êý¾ÝÔö¼ÓCRCУÑé ͬʱ·µ»ØÐ£ÑéµÄCRCÖµ
+* 0: ¸Ã´®Êý¾ÝÊÇ·ñͨ¹ýУÑé ·µ»ØÐ£ÑéµÄCRCÖµ
+* ·µ »Ø:
+*
+* ×¢ Òâ:
+*
+**************************************************************************************************************
+*/
+//CRCʹÓÃ
+typedef struct
+{
+ uint8 L;
+ uint8 H;
+} INT_08BIT_2;
+
+typedef union
+{
+ uint16 Int16Bit;
+ INT_08BIT_2 Int08Bit;
+} INT_16BIT_08BIT;
+
+uint16 AH_CRC_Verify(uint8 str[], uint16 size, uint8 mode)
+{
+ uint32 i;
+ INT_16BIT_08BIT crc;
+ INT_16BIT_08BIT y;
+
+ crc.Int16Bit = 0;
+ for(i = 0 ; i < size ; i++)
+ {
+ y.Int16Bit = crc_table[ str[ i ] ^ crc.Int08Bit.H ];
+ y.Int08Bit.H ^= crc.Int08Bit.L;
+ crc.Int16Bit = y.Int16Bit;
+ }
+ if(mode == 1)
+ {
+ str[ i++ ] = y.Int08Bit.H ;
+ str[ i ] = y.Int08Bit.L ;
+ }
+ return(crc.Int16Bit);
+}
+
+static uint16 update_upgrade_mark(uint32 CheckSum, uint32 size)
+{
+ uint16 ret,i;
+ uint8 buff[18] = { 0x5a,0x4b,0x3c,0x2d,0x1e,0x0f } ;
+
+ //дÉý¼¶Êý¾Ý³É¹¦Ð´ÈëFLASH±ê¼Ç, ºÍУÑéÂë, ÓÐЧ´úÂ볤¶ÈдÈëÊý¾ÝFLASH
+ memcpy(buff+6, (unsigned char*)&(CheckSum), 4) ; //УÑéºÍ
+ memcpy(buff+10,(unsigned char*)&(size) ,4) ; //Êý¾Ý³¤¶È
+ AH_CRC_Verify(buff, 14, 1);
+
+ for(i = 0; i<5; i++)
+ {
+ ret = sp_flash_erase(DEF_IapMarkAddr);
+ if(ret)
+ {
+ continue;
+ }
+ ret = sp_flash_write(DEF_IapMarkAddr, buff, 16);
+ if(!ret)
+ {
+ break;
+ }
+ }
+ if(i >= 5)
+ {
+ return 1;
+ }
+ return 0;
+}
+/**********************************************************************************************
+º¯ÊýÃû³Æ: U32 APP_IapDataSumCheck( U32 staaddr, U32 len, U08 mode )
+º¯Êý×÷ÓÃ: ¶Á³öFLASHÖеÄÊý¾Ý£¬²¢ÐγÉУÑé
+º¯ÊýÊäÈë: staaddr - ¿ªÊ¼µØÖ·
+ len - Êý¾Ý³¤¶È
+ mode - УÑéģʽ 0 È¡·´ºÍУÑé 1 ÆÕͨºÍУÑé
+º¯ÊýÊä³ö: ÎÞ
+º¯Êý·µ»ØÖµ: 0 ³É¹¦ ÆäËûʧ°Ü
+**********************************************************************************************/
+uint32 do_APP_IapDataSumCheck(uint32 staaddr, uint32 len, uint8 mode)
+{
+ uint32 Sum;
+ uint32 app_len, checksize, size;
+ uint16 rcode, i;
+ uint8 buffer[1024];//IAP_MAXLEN
+
+ app_len = len;
+ checksize = 0;
+ Sum = 0;
+ while(checksize < app_len)
+ {
+ if(len < 1024)
+ {
+ size = len;
+ }
+ else
+ {
+ size = 1024;
+ }
+
+ for(i=0; i<5; i++)
+ {
+ rcode = sp_flash_read((staaddr + checksize), buffer, size);
+ if(!rcode)
+ {
+ break;
+ }
+ }
+
+ if(mode == 0)
+ {
+ for(i = 0; i < size; i++)
+ {
+ Sum += ((~buffer[i]) & 0xFF); //еÄÊÇÈ¡·´ºÍ
+ }
+ }
+ else
+ {
+ for(i = 0; i < size; i++)
+ {
+ Sum += buffer[i]; //ÀϵÄÊÇÖ±½ÓºÍ
+ }
+ }
+ checksize += size;
+ len -= size;
+ }
+
+ return (Sum);
+}
+static uint8 get_file_info(sp_pos_t* pos, sp_upgrade_info_t* upgradeinfo)
+{
+ uint8 ret;
+ uint8 size;
+ char temp[32];
+ sp_protocol_request_t req;
+ sp_protocol_response_t resp;
+ cw_pack_context pack;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+
+ sp_flash_read(ADDR_UPGRADE_UPINFO,(uint8*)upgradeinfo,sizeof(sp_upgrade_info_t));
+
+ /*¶ÁÈ¡Îļþ³¤¶ÈºÍCRC*/
+ sp_protocol_req_init(&req,SP_CMD_UPGRADE);
+ sp_pack_init(&pack,req.data,sizeof(req.data));
+ cw_pack_map_size(&pack,5);
+
+ sp_pack_put_bin(&pack,PK_BIN_DEVPHYID, pos->devphyid, sizeof(pos->devphyid));
+ sp_pack_put_int(&pack,PK_INT_SEQNO ,0xFFFF);
+ sp_pack_put_str(&pack,PK_STR_DEVTYPE, DEV_TYPE);
+ sp_pack_put_str(&pack,PK_STR_VERSION, PRO_VERSION);
+ sp_pack_put_bin(&pack,PK_BIN_SOFT_MD5,upgradeinfo->file_md5,16);
+
+ req.datalen += sp_pack_length(&pack);
+ ret = sp_comm_call(pos, &req, &resp, COMM_WAIT_TIME);
+ if(!ret)
+ {
+ sp_unpack_init(&unpack,resp.data,resp.datalen);
+ //erase
+ sp_flash_erase(ADDR_UPGRADE_UPINFO);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ // 4 byte file_length,2 crc
+ if(IS_KEY(PK_INT_FILESIZE,field.key))
+ {
+ upgradeinfo->file_size = (uint32)field.val.intval;
+ }
+ else if(IS_KEY(PK_BIN_FILECRC,field.key))
+ {
+ if(field.strlen != 2)
+ {
+ sprintf(temp,"CRC³¤¶È=%d",field.strlen);
+ disp_hint_info_two(pos, "Éý¼¶Ê§°Ü",temp,DELAY_TIME3s);
+ return 1;
+ }
+ MEMCPY(upgradeinfo->file_crc,field.val.binval,field.strlen);
+ }
+ else if(IS_KEY(PK_BIN_SOFT_MD5,field.key))
+ {
+ MEMCPY(upgradeinfo->file_md5,field.val.binval,field.strlen);
+ }
+ }
+ }
+ else
+ {
+ disp_server_errmsg(pos, "Éý¼¶Ê§°Ü",resp.data,resp.datalen);
+ }
+ return ret;
+}
+static uint8 download_file(sp_pos_t* pos)
+{
+ uint8 ret;
+ uint8 timeout_trycnt = 0;
+ uint8 sameseq_trycnt = 0;
+ uint8 data_len = 0;
+ uint16 seqno = 0;
+ uint16 resp_seqno = 0;
+ uint32 offset = 0;
+ uint8 endflag = 0;
+ uint8 size;
+ char temp[32];
+ uint8 buf[128];
+ sp_protocol_request_t req;
+ sp_protocol_response_t resp;
+ cw_pack_context pack;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+
+ for(offset = ADDR_UPGRADE_BEGIN; offset < ADDR_UPGRADE_END; offset +=DEF_FLASH_PageSize)
+ {
+ sp_flash_erase(offset);
+ }
+ offset = 0;
+ while(1)
+ {
+ sp_feed_dog();
+ sp_protocol_req_init(&req,SP_CMD_UPGRADE);
+ sp_pack_init(&pack,req.data,sizeof(req.data));
+ cw_pack_map_size(&pack,2);
+
+ sp_pack_put_bin(&pack,PK_BIN_DEVPHYID, pos->devphyid, sizeof(pos->devphyid));
+ sp_pack_put_int(&pack,PK_INT_SEQNO,seqno);
+
+ req.datalen += sp_pack_length(&pack);
+ ret = sp_comm_call(pos, &req,&resp, COMM_WAIT_TIME);
+ if(!ret)
+ {
+ timeout_trycnt = 0;//success reset
+ sp_unpack_init(&unpack,resp.data,resp.datalen);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ if(IS_KEY(PK_INT_SEQNO,field.key))
+ {
+ resp_seqno = (uint32)field.val.intval;
+ }
+ else if(IS_KEY(PK_INT_FLAG,field.key))
+ {
+ if(0 == MEMCMP("end",field.val.strval,field.strlen))
+ {
+ // ÎļþÏÂÔØÍê³É
+ endflag = 1;
+ }
+ }
+ else if(IS_KEY(PK_BIN_FILEDATA,field.key))
+ {
+ data_len = field.strlen;
+ if(data_len > sizeof(buf))
+ {
+ sprintf(temp,"´íÎ󳤶È=%d",data_len);
+ disp_hint_info_two(pos, "Éý¼¶Ê§°Ü",temp,DELAY_TIME3s);
+ return 1;
+ }
+ MEMCLEAR(buf,sizeof buf);
+ MEMCPY(buf,field.val.binval,data_len);
+ }
+ }
+
+ if(resp_seqno != seqno +1)
+ {
+ if(10 < sameseq_trycnt)
+ {
+ return 1;
+ }
+ ++sameseq_trycnt;
+ continue;
+ }
+ sameseq_trycnt = 0;
+
+ ++seqno;
+ snprintf(temp,sizeof temp,"seqno = %04d",seqno);
+ disp_hint_info_two(pos, "ÕýÔÚÉý¼¶...",temp,0);
+
+ sp_flash_write(ADDR_UPGRADE_BEGIN+offset,buf,data_len);
+ if(endflag)
+ {
+ return 0;
+ }
+
+ offset += (uint32)data_len;
+ if(ADDR_UPGRADE_BEGIN + offset >= ADDR_UPGRADE_END)
+ {
+ disp_hint_info(pos, "ÏÂÔØÎļþ¹ý´ó",DELAY_TIME3s);
+ return 1;
+ }
+ }
+ else
+ {
+ if(3 < timeout_trycnt)
+ {
+ disp_hint_info(pos, "ÏÂÔØÎļþ³¬Ê±",DELAY_TIME3s);
+ return 1;
+ }
+ Delay_ms(DELAY_TIME1s);
+ ++timeout_trycnt;
+ }
+ }
+}
+static uint8 check_file_and_upgrade(sp_pos_t* pos, sp_upgrade_info_t* upgradeinfo)
+{
+ uint16 ret;
+ uint8 crc[2];
+ uint8 temp_crc[2];
+ uint8 buf[128];
+ uint32 sumcrc;
+
+ uint32 page_index = 0;
+ uint32 page_num = (upgradeinfo->file_size-1)/sizeof(buf) + 1;
+ while(1)
+ {
+ if(page_num == page_index +1)
+ {
+ sp_flash_read(ADDR_UPGRADE_BEGIN +page_index*sizeof(buf),buf,
+ sizeof buf);
+ memcpy(temp_crc,crc,2);
+ if(upgradeinfo->file_size%sizeof(buf) == 0)
+ {
+ sp_protocol_crc_init(buf,sizeof(buf),temp_crc,crc);
+ }
+ else
+ {
+ sp_protocol_crc_init(buf,upgradeinfo->file_size%sizeof(buf),temp_crc,crc);
+ }
+ if(0 == MEMCMP(upgradeinfo->file_crc,crc,2))
+ {
+ sp_flash_write(ADDR_UPGRADE_UPINFO,(uint8*)upgradeinfo,sizeof(sp_upgrade_info_t));
+
+ sumcrc = do_APP_IapDataSumCheck(ADDR_UPGRADE_BEGIN,upgradeinfo->file_size,0);
+ /*Éý¼¶ºó,boot »á²Á³ý¸ÃÒ³¼Ç¼ */
+ //¸üбê־λÖÃλ
+ ret = update_upgrade_mark(sumcrc,upgradeinfo->file_size);
+ if(ret)
+ {
+ disp_hint_info_two(pos, "Éý¼¶Ê§°Ü","¸üбê־ʧ°Ü",DELAY_TIME2s);
+ return 1;
+ }
+ else
+ {
+ disp_hint_info_two(pos, "ÕýÔÚÉý¼¶","ÇëÎð¶Ïµç",DELAY_TIME2s);
+ sp_reset();
+ return 0;
+ }
+ }
+ else
+ {
+ disp_hint_info(pos, "ÎļþУÑé´íÎó",DELAY_TIME3s);
+ return 1;
+ }
+ }
+ else
+ {
+ sp_flash_read(ADDR_UPGRADE_BEGIN+page_index*sizeof(buf),buf,sizeof buf);
+ if(0 == page_index)
+ {
+ sp_protocol_crc(buf,sizeof buf,crc);
+ }
+ else
+ {
+ memcpy(temp_crc,crc,2);
+ sp_protocol_crc_init(buf,sizeof buf,temp_crc,crc);
+ }
+ ++page_index;
+ }
+ }
+}
+void sp_manual_upgrade(sp_pos_t* pos)
+{
+ uint8 ret;
+ sp_upgrade_info_t upgradeinfo;
+
+ disp_hint_info_two(pos, "ÕýÔÚÉý¼¶..","Îð¶Ïµç!!",0);
+ MEMCLEAR(&upgradeinfo,sizeof upgradeinfo);
+ ret = get_file_info(pos, &upgradeinfo);
+ if(ret)
+ {
+ return;
+ }
+ ret = download_file(pos);
+ if(ret)
+ {
+ return;
+ }
+ check_file_and_upgrade(pos, &upgradeinfo);
+}
+