#include "gd32f10x.h" #include "boot.h" #include "main.h" #include "delay.h" #include "fmc.h" #include "w25q32.h" #include <stdio.h> #include "ota_message.h" #include "ec800m.h" #include "usart.h" #define APP_PROGRAMMER_BLOCK 2 //������W25Q32�д�ŵ�λ�� load_a load_A; /** * @brief ��strstr�����ҳ��ֽ������е�ָ���ַ�λ��,���û�з���NULL * * @param strs �ֽ����� * @param str ָ���ַ��� * @param first �ֽ�����ƫ���� * @param len �ֽ����鳤�� * @return char* ָ���ַ���ַ,���û�з���NULL */ static char* find_string(char *strs, char *str,int first, int len) { int i = 0; char *start = NULL; strs = strs + first; while(i < len){ start = strstr(strs, str); if(start != NULL){ break; } i++; strs++; } if(i == len + 1){ return NULL; } return start; } /** * @brief �ȴ��������ļ��������ķ������� * * @param data �����������ݸ��Ƶ�data������ * @param timeout ��ʱʱ�� * @param datalen ��Ҫ���Ƶ������ֽڳ��� * @return int �ɹ��ظ��Ƶ��ֽڳ��ȣ�ʧ�ܷ���-1 */ int WaitForReadData(uint8_t* data,int timeout,int datalen) { uint32_t len = 0; bool timeoutFlag = false; if (timeout >= 0) { timeoutFlag = true; } while (1) { Delay_Ms(50); if ((UART0_RX_STAT > 0) && (find_string((char *)&UART0_RX_BUF, "\r\nOK\r\n",datalen, sizeof(UART0_RX_BUF)))) { UART0_RX_STAT = 0; // char *p = strstr((char *)&UART0_RX_BUF, "CONNECT "); // if (p) // { // p += 8; // sscanf(p, "%u\r", &len); // ��ȡ���� // if(len == datalen) // { // p = strchr(p, '\n') + 1; // �������� memcpy(data,(char *)&UART0_RX_BUF,datalen); Clear_DMA_Buffer(); return datalen; // } // else // { // Clear_DMA_Buffer(); // return len; // } } timeout -= 50; if (timeoutFlag == true && timeout <= 0) { Clear_DMA_Buffer(); return -1; } } } //����bootloader���� void BootLoader_Brance(uint32_t app_byte) { GD32_EraseFlash(GD32_A_START_PAGE,GD32_A_PAGE_NUM);//����A��ԭ�г��� /* ��UFS:otaDATA.txt */ EC800MSendCmd(CLOSE_otaDATA_FILE,strlen(CLOSE_otaDATA_FILE)); WaitResponse("QFCLOSE",1000); EC800MSendCmd(OPEN_otaDATA_FILE,strlen(OPEN_otaDATA_FILE)); if(WaitResponse("QFOPEN:", 2000) == 0) return; for(uint8_t i=0;i<app_byte/1024;i++) //1KBдһ�� { uint8_t app_programmer[1024]; memset(app_programmer,0,1024); // uint32_t addr=APP_PROGRAMMER_BLOCK*64*1024+i*1024; //����w25q32�еĵ�ַ // W25Q32_Read(app_programmer,addr,1024); while(1) { task_fwdgt_reload(); int x = 0; EC800MSendCmd(READ_otaDATA_FILE,strlen(READ_otaDATA_FILE)); Delay_Ms(200); //��Ҫ��200ms�ӳ� x = WaitForReadData(app_programmer,2000,1024); // if((x != 1024) && (x != -1)) // { // char* SEEK_otaDATA_FILE = ""; // sprintf(SEEK_otaDATA_FILE,"AT+QFSEEK=1,%d,2\r\n",x); // EC800MSendCmd(SEEK_otaDATA_FILE,strlen(SEEK_otaDATA_FILE)); //�����Ļ��ļ�ָ������ƫ��1024���ֽ� // } // else if(x == 1024) { break; } } GD32_WriteFlash(GD32_A_SADDR+i*1024,(uint32_t *)&app_programmer,1024); //�����������ݰ�ҳд������ Delay_Ms(50); } //������1024���ݵ���д�� if(app_byte % 1024 != 0) { uint32_t startAddress=(app_byte/1024)*1024; uint8_t app_programmer[1024]; memset(app_programmer,0,1024); // uint32_t addr=APP_PROGRAMMER_BLOCK*64*1024+(app_byte/1024)*1024; //����w25q32�еĵ�ַ // W25Q32_Read(app_programmer,addr,app_byte%1024); while(1) { task_fwdgt_reload(); int x = 0; EC800MSendCmd(READ_otaDATA_FILE,strlen(READ_otaDATA_FILE)); Delay_Ms(200); //��Ҫ��200ms�ӳ� x = WaitForReadData(app_programmer,2000,app_byte % 1024); // if(x != (app_byte % 1024) && (x != -1)) // { // char* SEEK_otaDATA_FILE = ""; // sprintf(SEEK_otaDATA_FILE,"AT+QFSEEK=1,%d,2\r\n",x); // EC800MSendCmd(SEEK_otaDATA_FILE,strlen(SEEK_otaDATA_FILE)); //�����Ļ��ļ�ָ������ƫ�ƶ�ȡ�ֽ��� // } // else if(x == (app_byte % 1024)) { break; } } GD32_WriteFlash(GD32_A_SADDR+(app_byte/1024)*1024,(uint32_t *)&app_programmer,app_byte % 1024); Delay_Ms(50); } // ����UFS�ļ� while(1) { EC800MSendCmd(CLOSE_otaDATA_FILE,strlen(CLOSE_otaDATA_FILE)); if(WaitResponse("OK", 2000) == 1) { break; } } Delay_Ms(50); clear_ota_message_config_block(); LOAD_A(GD32_A_SADDR); } /*-------------------------------------------------*/ /*������������SP */ /*�� ����addr��ջ��ָ���ʼֵ */ /*����ֵ���� */ /*-------------------------------------------------*/ __asm void MSR_SP(uint32_t addr) { MSR MSP, r0 BX r14 } /*-------------------------------------------------*/ /*����������ת��A�� */ /*�� ����addr��A������ʼ��ַ */ /*����ֵ���� */ /*-------------------------------------------------*/ void LOAD_A(uint32_t addr) { if((*(uint32_t *)addr>=0x20000000)&&(*(uint32_t *)addr<=0x20017FFF)){ MSR_SP(*(uint32_t *)addr); load_A = (load_a)*(uint32_t *)(addr+4); BootLoader_Clear(); load_A(); }else ; } /*-------------------------------------------------*/ /*�����������B��ʹ�õ����� */ /*�� ������ */ /*����ֵ���� */ /*-------------------------------------------------*/ void BootLoader_Clear(void) { gpio_deinit(GPIOA); gpio_deinit(GPIOB); }