当前位置:   article > 正文

STM32 TCP实现OTA

STM32 TCP实现OTA

芯片:stm32f407

开发平台:stm32cubeide

上位机开发平台:visual studio 2017

1. FLASH分配

将flash划分为四个部分:

        bootloader:        0x8000000-0x800ffff

        app1:                0x8010000-0x805ffff

        app2:                0x8060000-0x80affff

        parameters:      0x80e0000-0x80fffff

        其中,bootloader程序为启动程序,app1是当前运行程序,app2为准备升级程序,parameters存储程序相关参数。

2. BOOTLOADER

        在app2中用最后一段flash地址0x80dfff0来存储升级标志Upgrade_Flag,比如有新程序下载到app2中,则0x80dfff0中数据为0xaaaaaa,如果为其他则表示没有新程序,开机后bootloader首先运行,启动后检测Upgrade_Flag是否为0xaaaaaa:

        如果是,则将app2中的程序拷贝到app1中,然后重置标志位Upgrade_Flag为0xffffffff且跳转到app1起始地址0x8010000开始执行新的程序;

        如果否,则直接跳转到app1起始地址0x8010000开始运行程序;

        bootloader主要代码如下:

  1. #define IAP_ADDRESS 0x8000000 //
  2. #define APP1_ADDRESS 0x8010000 //
  3. #define APP1_ADDRESS_END 0x805FFFF //
  4. #define APP2_ADDRESS 0x8060000 //
  5. #define APP2_ADDRESS_END 0x80AFFFF //
  6. #define PARA_ADDRESS 0x80E0000 //
  7. #define UPGRADE_ADDRESS 0x80DFFF0 //
  8. pFunction Jump_To_Application;
  9. uint32_t JumpAddress;
  10. pFunction Jump_To_Application;
  11. void Jump_To_APP()
  12. {
  13. uint32_t JumpAddress;
  14. printf("jump to app: %#x\r\n", APP1_ADDRESS);
  15. //HAL_DeInit();
  16. __disable_irq();
  17. if(((*(__IO uint32_t*)APP1_ADDRESS)&0x2ffe0000)==0x20020000)
  18. {
  19. /* Jump to user application */
  20. JumpAddress = *(__IO uint32_t*) (APP1_ADDRESS + 4);
  21. Jump_To_Application = (pFunction) JumpAddress;
  22. //printf("jump %#x success \r\n",APP1_ADDRESS);
  23. /* Initialize user application's Stack Pointer */
  24. __set_MSP(*(__IO uint32_t*) APP1_ADDRESS);
  25. Jump_To_Application();
  26. }
  27. else
  28. {
  29. printf("error [0x%08x]\r\n",(*(volatile uint32_t*)APP1_ADDRESS));
  30. }
  31. }
  32. uint8_t u8_Code_Buff[2048];//2k
  33. uint16_t Num=0;
  34. uint8_t NotUpgrade[4]={0xff,0xff,0xff,0xff};
  35. uint8_t Upgrade[4]={0xaa,0xaa,0xaa,0xaa};
  36. uint32_t Upgrade_Flag;
  37. void Copy_APP2_to_APP1(void)
  38. {
  39. if(((*(__IO uint32_t*)APP2_ADDRESS)&0x2ffe0000)!=0x20020000)
  40. {
  41. printf("invalid app in address [0x%08x]\r\n",APP2_ADDRESS);
  42. return;
  43. }
  44. MEM_IF_IniT();
  45. uint32_t APP1_Addr;
  46. uint32_t APP2_Addr;
  47. APP1_Addr=APP1_ADDRESS;
  48. APP2_Addr=APP2_ADDRESS;
  49. MEM_If_Erase(APP1_ADDRESS,APP1_ADDRESS_END);
  50. printf("Erase app1 flash\r\n");
  51. for(int i=0;i<150;i++)//copy 150*2k=300k, max size of app is 300k
  52. {
  53. printf("APP1_Addr = %x\r\n",APP1_Addr);
  54. printf("APP2_Addr = %x\r\n",APP2_Addr);
  55. MEM_If_Read(u8_Code_Buff,APP2_Addr,2048);
  56. HAL_Delay(10);
  57. MEM_If_Write_Byte(u8_Code_Buff,APP1_Addr,2048);
  58. HAL_Delay(10);
  59. APP1_Addr+=0x800;
  60. APP2_Addr+=0x800;
  61. memset(u8_Code_Buff,0,sizeof(u8_Code_Buff));
  62. Num=i;
  63. if(1)
  64. {
  65. printf("Successfully copied page %d\r\n",Num);
  66. }
  67. else
  68. {
  69. printf("Copy failed page %d\r\n",Num);
  70. }
  71. }
  72. MEM_If_Erase(UPGRADE_ADDRESS,UPGRADE_ADDRESS);
  73. MEM_If_Write_Byte(NotUpgrade,UPGRADE_ADDRESS,sizeof(NotUpgrade));
  74. MEM_IF_DeInit();
  75. }
  76. int main(void)
  77. {
  78. /* USER CODE BEGIN 1 */
  79. //SCB->VTOR = FLASH_BASE | 0x40000;
  80. /* USER CODE END 1 */
  81. /* MCU Configuration--------------------------------------------------------*/
  82. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  83. HAL_Init();
  84. /* USER CODE BEGIN Init */
  85. /* USER CODE END Init */
  86. /* Configure the system clock */
  87. SystemClock_Config();
  88. /* USER CODE BEGIN SysInit */
  89. /* USER CODE END SysInit */
  90. /* Initialize all configured peripherals */
  91. MX_GPIO_Init();
  92. MX_USART1_UART_Init();
  93. /* USER CODE BEGIN 2 */
  94. printf("\r\n");
  95. printf("*****************************************\r\n");
  96. printf("* luckyzjian's ISP *\r\n");
  97. printf("* *\r\n");
  98. printf("* www.cdxcjc.com *\r\n");
  99. printf("* *\r\n");
  100. printf("* Version: v%d.%d.%d *\r\n",version_board,version_year,version_no);
  101. printf("* *\r\n");
  102. printf("* 026-82598116 *\r\n");
  103. printf("*****************************************\r\n");
  104. printf("************ flash table ***************\r\n");
  105. printf("*bootloader : %#x -------- %#x******\r\n",IAP_ADDRESS,APP1_ADDRESS-1);
  106. printf("*APP1 : %#x -------- %#x******\r\n",APP1_ADDRESS,APP1_ADDRESS_END);
  107. printf("*APP2 : %#x -------- %#x******\r\n",APP2_ADDRESS,APP2_ADDRESS_END);
  108. printf("*PRIVATE PARA: %#x -------- %#x******\r\n",PARA_ADDRESS,PARA_ADDRESS+0X1FFFF);
  109. printf("*****************************************\r\n");
  110. TM1629_init();
  111. Upgrade_Flag=*(__IO uint32_t*)(UPGRADE_ADDRESS);
  112. printf("Upgrade_Flag = 0x%x\r\n",Upgrade_Flag);
  113. if(0xaaaaaaaa==Upgrade_Flag)
  114. {
  115. printf("there is new app in address: %x\r\n",APP2_ADDRESS);
  116. printf("copy new app in address: %x to address: %x\r\n",APP2_ADDRESS,APP1_ADDRESS);
  117. TM1629_printRow1("-----",ShowType_Right);
  118. TM1629_printRow2("-ISP-",ShowType_Right);
  119. TM1629_DISPLAY();
  120. Copy_APP2_to_APP1();
  121. printf("copy finished\r\n",APP2_ADDRESS,APP1_ADDRESS);
  122. printf("------%#x\r\n",(APP1_ADDRESS+4)&0XFF000000);
  123. if(((APP1_ADDRESS+4)&0xff000000)==0x08000000)
  124. {
  125. printf("jump APP1 running");
  126. Jump_To_APP(APP1_ADDRESS);
  127. }
  128. }
  129. else
  130. {
  131. printf("there is no new app in address: %x\r\n",APP2_ADDRESS);
  132. printf("------%#x\r\n",(APP1_ADDRESS+4)&0xff000000);
  133. if(((APP1_ADDRESS+4)&0xff000000)==0x08000000)
  134. {
  135. printf("jump APP1 running\r\n");
  136. Jump_To_APP(APP1_ADDRESS);
  137. }
  138. }
  139. /* USER CODE END 2 */
  140. /* Infinite loop */
  141. /* USER CODE BEGIN WHILE */
  142. while (1)
  143. {
  144. /* USER CODE END WHILE */
  145. /* USER CODE BEGIN 3 */
  146. }
  147. /* USER CODE END 3 */
  148. }

3. APP

APP程序因为是从0x08010000开始运行的,要注意修改如下两个地方

  1. /Core/Src/system_stm32f4xx.c中:
  2. #define VECT_TAB_OFFSET 0x00010000U /*!< Vector Table base offset field.
  3. This value must be a multiple of 0x200. */
  4. STM32F407ZGTX_FLASH.ld:
  5. MEMORY
  6. {
  7. CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
  8. RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
  9. FLASH (rx) : ORIGIN = 0x8010000, LENGTH = 320K
  10. }

程序通过TCP下载,因为我项目中已经有一套TCP的通讯接口,为了方便,便在原来的自定义接口协议中增加了下载程序的协议

通讯格式定义如下:

发送:
0x02起始码1
ADD地址1控制仪地址 0X80~0X8F 代表0~15号地址
CMD命令字节1
LB数据[DF]长度1
[DF]数据LB
CS校验码1=NOT(0x02+ADD+CMD+LB+[DF])+1
0X03结束码1
响应:
0x06起始码1
ADD地址1控制仪地址 0X80~0X8F 代表0~15号地址
CMD命令字节1
LB数据[DF]长度1
[DF]数据LB
CS校验码1=NOT(0x06+ADD+CMD+LB+[DF])+1
0X03结束码1

涉及下载的命令定义如下:

命令命令代码命令格式响应说明
开始下载固件0x510x02 ADD 0x51 0x02 [分包数量] CS  0x030x06 ADD 0x51  0x01 <STATUS> CS 0x03[分包数量],固件数据包按1000字节一个包进行分包,最后一包不足1000字节时,用0x00填充到1000字节,将总的分包数量在开始升级固件指令时写入
返回STATUS:
0X06 成功;
0x15 失败
写入固件0x520x02 ADD 0x52 [分包顺序][数据长度]{数据} CS 0x030x02 ADD 0x52 0x03 [分包顺序] <STATUS> CS 0x03[分包顺序][数据长度]《数据》三部分固定长度为1004个字节,其中:
[分包顺序]为两字节,代表该帧数据为整个固件包的第几包数据,从0开始计数;
[数据长度]为两字节,代表该包数据字节长度,应固定为1000字节;
《数据》为固件内容,当最后一包不足1000字节时,用0x00填充到1000字节
返回STATUS:
0X06 成功;
0x15 失败;
写入固件结束0x530x02 ADD 0x53 0x02 <CRCH>  <CRCL> CS 0x030x06 ADD 0x53 0x01 <STATUS> CS 0x03CRCH,CHRL组成固件全部数据的CRC16校验,下位机收到结束指令后,对整包数据进行CRC16校验,与该指令CRC校准字比对,如果比对成功,则标记为升级成功(向地址0x80DFFF0写入0xaaaaaa)
返回STATUS:
0X06 升级成功;
0x15 升级失败;
放弃写入固件0x5f0x02 ADD 0x5f 0x00 CS 0x030x06 ADD 0x5f 0x00 CS 0x03
  1. #define CLIENTMAX 5
  2. typedef struct
  3. {
  4. struct netconn *conn;
  5. uint8_t num;
  6. }tcp_client;
  7. typedef struct{
  8. struct netconn *client[CLIENTMAX+2];
  9. uint8_t state[CLIENTMAX+2];
  10. osThreadId client_taskid[CLIENTMAX+2];
  11. Controller_StatusDef realdatastatus[CLIENTMAX+2];
  12. }client_ad;
  13. client_ad clientad;
  14. uint8_t isIAPStart=0;
  15. uint16_t IAP_frameTotalCount=0;
  16. uint16_t IAP_frameCount=0;
  17. uint16_t IAP_frameSeq=0;
  18. uint16_t IAP_frameLength=0;
  19. uint16_t IAP_frameCRC=0x0000;
  20. uint8_t isIAPFinish=0;
  21. uint8_t isIAPSuccess=0;
  22. uint8_t NotUpgrade[4]={0xff,0xff,0xff,0xff};
  23. uint8_t Upgrade[4]={0xaa,0xaa,0xaa,0xaa};
  24. void svr_task(void const *arg);
  25. void processCmd(Controller_AckDataDef frame,Controller_AckDataDef* ackframe,uint8_t clientindex);
  26. osThreadDef(myTaskClient, tcp_server_thread, osPriorityNormal, CLIENTMAX, 1400);
  27. void MX_FREERTOS_Init(void) {
  28. osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 1024);
  29. defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
  30. osThreadDef(tcpmultiTask, svr_task, osPriorityNormal, 0, 1024);
  31. osThreadCreate(osThread(tcpmultiTask), NULL);
  32. clientad.state[CLIENTMAX]=1;
  33. clientad.realdatastatus[CLIENTMAX]=RealPass_Stop;
  34. comackframe.originaldata_data=comackdata;
  35. isCOMHasACK=0;
  36. }
  37. err_t client_init(void *arg,uint8_t* clientnumindex)
  38. {
  39. uint8_t clientnum; //?????? TCP client ????
  40. err_t err; //????(UCOSIII)
  41. uint8_t ifreceiveclient=0;
  42. for(clientnum=0;clientnum<CLIENTMAX;clientnum++) //???????????(????20????)
  43. {
  44. if(clientad.state[clientnum]==0) //???? clientnum ?????????0(???)
  45. {
  46. ifreceiveclient=1;
  47. break; //???? ???? ????????
  48. }
  49. }
  50. if(ifreceiveclient==0)
  51. {
  52. UsrLog("This no space to accept client");
  53. return 1;
  54. }
  55. *clientnumindex=clientnum;
  56. return ERR_OK; //??????
  57. }
  58. void svr_task(void const *arg)
  59. {
  60. err_t oserr;
  61. struct netconn *conn,*newconn;
  62. while(!isLWIPInitSuccess)
  63. osDelay(100);
  64. for(int i=0;i<CLIENTMAX;i++)
  65. {
  66. clientad.state[i]=0;
  67. clientad.realdatastatus[i]=RealPass_Stop;
  68. //clientad.iapstatus[i]=IAPStatus_app;
  69. }
  70. conn = netconn_new(NETCONN_TCP);
  71. netconn_bind(conn,IP_ADDR_ANY,sysParameterStruct._Para_ControlIP_PORT);
  72. netconn_listen(conn);
  73. sprintf((char*)iptxt, "%d", sysParameterStruct._Para_ControlIP_PORT);
  74. UsrLog("tcp start listen on port: %s",iptxt);
  75. while(1)
  76. {
  77. uint8_t clientnumindex=0;
  78. //if(get_clientindex(&clientnumindex) != ERR_OK)
  79. // osDelay(100);
  80. if(netconn_accept(conn,&newconn) == ERR_OK)
  81. {
  82. if(client_init((void *)newconn,&clientnumindex) != ERR_OK)
  83. {
  84. netconn_close(newconn);
  85. netconn_delete(newconn);
  86. }
  87. else
  88. {
  89. clientad.client[clientnumindex]=newconn;
  90. clientad.state[clientnumindex]=1;
  91. clientad.client_taskid[clientnumindex] = osThreadCreate(osThread(myTaskClient), (void *)clientnumindex);
  92. osDelay(100);
  93. if(clientad.client_taskid[clientnumindex]==NULL)
  94. {
  95. UsrLog("Failed to create the recv thread with id: %d",clientnumindex);
  96. }
  97. else
  98. {
  99. UsrLog("create the recv thread with id: %x",(int)(clientad.client_taskid[clientnumindex]));
  100. }
  101. }
  102. }
  103. osDelay(100);
  104. }
  105. }
  106. void tcp_server_thread(void const *arg)
  107. {
  108. err_t err;
  109. struct netbuf *clientrecvbuf;
  110. Controller_AckDataDef recvframe;
  111. Controller_AckDataDef ackframe;
  112. uint8_t recvdata[40];
  113. uint8_t ackdata[80];
  114. /*recv tcp data buf*/
  115. ackframe.originaldata_head=0x06;
  116. ackframe.originaldata_address=sysParameterStruct._Para_ControlEquiAddress;
  117. ackframe.originaldata_end=0x03;
  118. ackframe.originaldata_data=ackdata;
  119. ip_addr_t addr; u16_t port;
  120. uint8_t *app_flash_buf;
  121. /* get remote IP address and port*/
  122. uint8_t clientindex=(uint8_t)arg;
  123. if((err=netconn_getaddr(clientad.client[clientindex],&addr, &port, 0))==ERR_OK)
  124. {
  125. sprintf((char*)iptxt, "%d.%d.%d.%d:%d", (uint8_t)(addr.addr),(uint8_t)(addr.addr>>8),(uint8_t)(addr.addr>>16),(uint8_t)(addr.addr>>24),port);
  126. UsrLog("one client is connected:%s",iptxt);
  127. }
  128. uint8_t *data;
  129. u16_t len;
  130. while(1)
  131. {
  132. if((err=netconn_recv(clientad.client[clientindex],&clientrecvbuf))==ERR_OK)
  133. {
  134. do{
  135. netbuf_data(clientrecvbuf,&data,&len);
  136. //printf("recevie one frame: length=%d, data=0x%x--0x%x\r\n",len,data[0],data[len-1]);
  137. if(len>=6)
  138. {
  139. if(data[0]==0x02&&data[len-1]==0x03)
  140. {
  141. recvframe.originaldata_head=data[0];
  142. recvframe.originaldata_address=data[1];
  143. recvframe.originaldata_cmd=data[2];
  144. if(recvframe.originaldata_cmd==0x52)//app upload data frame:0x02 add 0x52 [frame seq] [frame len] {app data} cs 0x03
  145. {
  146. IAP_frameSeq=(uint16_t)((data[3]<<8)|data[4]);
  147. IAP_frameLength=(uint16_t)((data[5]<<8)|data[6]);
  148. app_flash_buf=data+7;
  149. printf("recevie one frame data: frame seq=%d, frame data length=%d\r\n",IAP_frameSeq,IAP_frameLength);
  150. uint8_t frameRight=1;
  151. if(isIAPStart)
  152. {
  153. if(IAP_frameSeq==IAP_frameCount&&IAP_frameSeq<IAP_frameTotalCount)
  154. {
  155. if(IAP_frameLength!=500)
  156. {
  157. printf("wrong frame length(%d), length should be 1000\r\n",IAP_frameLength);
  158. frameRight=0;
  159. }
  160. if(frameRight)
  161. {
  162. printf("valid frame data\r\n");
  163. uint32_t flashdestination=APP2_ADDRESS+500*IAP_frameSeq;
  164. MEM_IF_IniT();
  165. if (MEM_If_Write_Word(app_flash_buf,flashdestination,IAP_frameLength) == HAL_OK)
  166. {
  167. printf("write frame data seq(%d)(data:0x%x..) to flash(addr:0x%08x) success\r\n",IAP_frameSeq,*app_flash_buf,flashdestination);
  168. IAP_frameCount++;
  169. }
  170. else /* An error occurred while writing to Flash memory */
  171. {
  172. printf("write frame data seq(%d) to flash fail\r\n",IAP_frameSeq);
  173. frameRight=0;
  174. }
  175. MEM_IF_DeInit();
  176. }
  177. }
  178. else
  179. {
  180. frameRight=0;
  181. }
  182. }
  183. else
  184. {
  185. frameRight=0;
  186. }
  187. if(!frameRight)
  188. {
  189. printf("invalid frame data or process data fail\r\n");
  190. }
  191. uint8_t realdatalength=0;
  192. ackframe.originaldata_head=0x06;
  193. ackframe.originaldata_address=sysParameterStruct._Para_ControlEquiAddress;
  194. ackframe.originaldata_end=0x03;
  195. ackframe.originaldata_cmd=recvframe.originaldata_cmd;
  196. *(ackframe.originaldata_data+realdatalength)=IAP_frameSeq>>8;
  197. realdatalength++;
  198. *(ackframe.originaldata_data+realdatalength)=IAP_frameSeq;
  199. realdatalength++;
  200. *(ackframe.originaldata_data+realdatalength)=frameRight?0x06:0x15;
  201. realdatalength++;
  202. ackframe.originaldata_length=realdatalength;
  203. netconn_ack(&ackframe,clientad.client[clientindex]);
  204. }
  205. else
  206. {
  207. recvframe.originaldata_length=data[3];
  208. recvframe.originaldata_cs=data[len-2];
  209. recvframe.originaldata_end=data[len-1];
  210. if(recvframe.originaldata_length+6==len)
  211. {
  212. for(int i=0;i<recvframe.originaldata_length;i++)
  213. {
  214. recvdata[i]=data[4+i];
  215. }
  216. recvframe.originaldata_data=recvdata;
  217. processCmd(recvframe,&ackframe,clientindex);
  218. netconn_ack(&ackframe,clientad.client[clientindex]);
  219. continue;
  220. }
  221. }
  222. }
  223. }
  224. ackframe.originaldata_cmd=0xf3;
  225. ackframe.originaldata_length=0;
  226. netconn_ack(&ackframe,clientad.client[clientindex]);
  227. }
  228. while(netbuf_next(clientrecvbuf)>=0);
  229. netbuf_delete(clientrecvbuf);
  230. }
  231. else if(err==ERR_CLSD||err==ERR_RST)
  232. break;
  233. }
  234. if(clientad.state[clientindex]==1)
  235. {
  236. if((err=netconn_getaddr(clientad.client[clientindex],&addr, &port, 0))==ERR_OK)
  237. {
  238. sprintf((char*)iptxt, "%d.%d.%d.%d:%d", (uint8_t)(addr.addr),(uint8_t)(addr.addr>>8),(uint8_t)(addr.addr>>16),(uint8_t)(addr.addr>>24),port);
  239. UsrLog("one ramote is closed:%s",iptxt);
  240. }
  241. clientad.state[clientindex]=0;
  242. netconn_close(clientad.client[clientindex]);
  243. netconn_delete(clientad.client[clientindex]);
  244. vTaskDelete(clientad.client_taskid[clientindex]);
  245. }
  246. }
  247. void processCmd(Controller_AckDataDef frame,Controller_AckDataDef* ackframe,uint8_t clientindex)
  248. {
  249. //Controller_AckDataDef ackframe;
  250. ackframe->originaldata_head=0x06;
  251. ackframe->originaldata_address=sysParameterStruct._Para_ControlEquiAddress;
  252. ackframe->originaldata_end=0x03;
  253. ackframe->originaldata_cmd=frame.originaldata_cmd;
  254. ackframe->originaldata_length=0;
  255. uint8_t *databuf=ackframe->originaldata_data;
  256. uint8_t realdatalength=0;
  257. switch(frame.originaldata_cmd)
  258. {
  259. case 0x51://start download app
  260. printf("start download app\r\n");
  261. IAP_frameTotalCount=(uint16_t)(frame.originaldata_data[0] << 8 | frame.originaldata_data[1]);
  262. printf("app frames total count is %d\r\n",IAP_frameTotalCount);
  263. MEM_IF_IniT();
  264. if(MEM_If_Erase(APP2_ADDRESS,APP2_ADDRESS_END)!=HAL_OK)
  265. {
  266. printf("erase flash fail, abort app downloading\r\n");
  267. isIAPStart=false;
  268. *(databuf+realdatalength)=0x15;
  269. realdatalength++;
  270. ackframe->originaldata_length=realdatalength;
  271. }
  272. else
  273. {
  274. printf("erase flash from %#x to %#x, wait for frame transmitting\r\n",APP2_ADDRESS,APP2_ADDRESS_END);
  275. IAP_frameCount=0;
  276. isIAPStart=true;
  277. *(databuf+realdatalength)=0x06;
  278. realdatalength++;
  279. ackframe->originaldata_length=realdatalength;
  280. }
  281. MEM_IF_DeInit();
  282. break;
  283. case 0x53://finish download app
  284. printf("finish download app\r\n");
  285. uint16_t IAP_crc16=(uint16_t)(frame.originaldata_data[0] << 8 | frame.originaldata_data[1]);
  286. printf("receive app crc16 is %x\r\n",IAP_crc16);
  287. if(1)//(IAP_crc16==IAP_frameCRC)
  288. {
  289. printf("pass crc check, finish download app\r\n");
  290. MEM_IF_IniT();
  291. MEM_If_Erase(UPGRADE_ADDRESS,UPGRADE_ADDRESS);
  292. MEM_If_Write_Byte(Upgrade,UPGRADE_ADDRESS,sizeof(Upgrade));
  293. MEM_IF_DeInit();
  294. *(databuf+realdatalength)=0x06;
  295. realdatalength++;
  296. ackframe->originaldata_length=realdatalength;
  297. isIAPStart=false;
  298. }
  299. else
  300. {
  301. printf("crc check fail, finish download app\r\n");
  302. *(databuf+realdatalength)=0x15;
  303. realdatalength++;
  304. ackframe->originaldata_length=realdatalength;
  305. isIAPStart=false;
  306. }
  307. break;
  308. case 0x5f:
  309. printf("receive abort download app command\r\n");
  310. isIAPStart=false;
  311. IAP_frameCount=0;
  312. break;
  313. /*
  314. other cmd process...
  315. */
  316. default:break;
  317. }
  318. }

3. 上位机实现升级工具(C# winform)

    

 4. 实现效果

升级工具通过TCP与板卡进行通讯,之前版本是V20.2024.3

打开升级程序包bin文件

点击下载

开始下载,显示整片程序被分成399个包

下载完成,提示重启板卡完成升级

重启后,开始将程序从APP2拷贝到APP1

拷贝完成,跳转到APP1运行,程序已经更新成V20.2024.4

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号