#include "iap.h" #include "usart.h" #include "crc.h" #include "flash.h" #include "delay.h" #include "usart1.h" #include "uart5.h" iapfun jump2app; //跳转到应用程序段 //appxaddr:用户代码起始地址. void Run_Flash_App(u32 appxaddr) { if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法. { jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) jump2app(); //跳转到APP. } } /**************************************************** * @brief: 通过RS485接口,本地下载固件 * @param: * @retva: * @note: ******************************************************/ uint8_t Success[] = "FireWare Check Success\r\n"; uint8_t Fail[] = "FireWare Check Fail\r\n"; uint8_t Incorrect[] = "Input Command Incorrect\r\n"; uint8_t Manual_Labal[] = "CMD Description\r\n"; uint8_t Manual_Start[] = "START Start Up Transmit FireWare\r\n"; uint8_t Manual_Ack[] = "ACK: Confirm The FireWare\r\n"; uint8_t Manual_Cancel[] = "CANCEL Cancel The Update Program\r\n"; uint8_t Manual_Line[] = "\r\n*******************************************\r\n"; uint8_t Ok[] = "OK\r\n"; void Local_Update(void) { Clear_Uart5_Cache(); uint16_t crc = 0xFFFF; uint32_t handle; delay_ms(70); Uart5_Send(Manual_Line,sizeof(Manual_Line)); delay_ms(70); Uart5_Send(Manual_Labal,sizeof(Manual_Labal)); delay_ms(70); Uart5_Send(Manual_Start,sizeof(Manual_Start)); delay_ms(70); Uart5_Send(Manual_Ack,sizeof(Manual_Ack)); delay_ms(70); Uart5_Send(Manual_Cancel,sizeof(Manual_Cancel)); delay_ms(70); Uart5_Send(Manual_Line,sizeof(Manual_Line)); while(1) { if(UART_FINISH) { if(strncmp((char *)UART_RX_BUF,"ACK",sizeof("ACK")) == 0) //确认数据 { Uart5_Send(Ok,sizeof(Ok)); handle = BOOTLOADER_RUN; STMFLASH_Write(FLAG_BASE_ADDR,(uint32_t *)&handle,4); } else if(strncmp((char *)UART_RX_BUF,"START",sizeof("START")) == 0) //启动传输 { Uart5_Send(Ok,sizeof(Ok)); Clear_Uart5_Cache(); UART_FINISH = false; while(UART_FINISH != true); printf("receive %d Bytes msg\r\n",&UART_RX_CNT); Uart5_Send(Ok,sizeof(Ok)); crc = GenerateCRC16(UART_RX_BUF,UART_RX_CNT-2); printf("CACL = %x\r\n",crc); if(crc == ((UART_RX_BUF[UART_RX_CNT-2] << 8 ) | UART_RX_BUF[UART_RX_CNT-1])) { STMFLASH_Write(APP_RUN_ADDR,(uint32_t *)UART_RX_BUF,UART_RX_CNT - 2); Uart5_Send(Success,sizeof(Success)); } else { Uart5_Send(Fail,sizeof(Fail)); } printf("CRC = %x\r\n",crc); } else if(strncmp((char *)UART_RX_BUF,"CANCEL",sizeof("CANCEL")) == 0 ) //返回 { Uart5_Send(Ok,sizeof(Ok)); break; } else { Uart5_Send(Incorrect,sizeof(Incorrect)); } Clear_Uart5_Cache(); UART_FINISH = false; UART5_Mode(RS485_READ); } } } /****************************************************** * @brief: 检测是否有触发本地升级 * @param: * @retva: * @note: ********************************************************/ uint8_t Update[] = "Enter Local Update\r\n"; void Detection_Update(void) { uint8_t i ; for(i=0;i