#include "iap.h" #include "crc.h" #include "flash.h" #include "delay.h" #include "usart1.h" #include "uart5.h" #include "ymodem.h" #include "string.h" iapfun jump2app; extern USART_TypeDef * IAP_Port; #define SEPERATE "\r\n***********************wisefarm bootloader***********************\r\n\r\n" #define WELCOME "Wisefarm bootloader start.....\r\n" #define END "Wisefarm bootloader end.....\r\n" #define VERSION "Version: MFGW2.0\r\n" #define RUN_POINT "App will be running.....\r\n" #define INPUT_PONIT "Press down key \"B\" at least 2S to s in bootloader\r\n" #define CUTDOWN_PONIT "Run application after %d second(s)......\r\n" uint8_t Run_Flash_App(u32 appxaddr) { if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法. { display_bootloader_exit_information(); jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) jump2app(); //跳转到APP. return 1; } else { return 0; } } void display_bootloader_extry_information(void) { GPIO_ResetBits(ARM_LED1_Port,ARM_LED1_Pin); GPIO_ResetBits(ARM_LED2_Port,ARM_LED2_Pin);//GPIOF9,F10设置高,灯灭 GPIO_ResetBits(ARM_LED3_Port,ARM_LED3_Pin);//GPIOF9,F10设置高,灯灭 GPIO_ResetBits(ARM_LED4_Port,ARM_LED4_Pin);//GPIOF9,F10设置高,灯灭 printf(SEPERATE); printf(WELCOME); printf(VERSION); } void display_bootloader_exit_information(void) { GPIO_SetBits(ARM_LED1_Port,ARM_LED1_Pin); GPIO_SetBits(ARM_LED2_Port,ARM_LED2_Pin);//GPIOF9,F10设置高,灯灭 GPIO_SetBits(ARM_LED3_Port,ARM_LED3_Pin);//GPIOF9,F10设置高,灯灭 GPIO_SetBits(ARM_LED4_Port,ARM_LED4_Pin);//GPIOF9,F10设置高,灯灭 printf(RUN_POINT); printf(END); printf(SEPERATE); } uint8_t uart_boot_detect(void) { uint8_t retry_cnt=0; char buf_rx5[20]={0}; char buf_rx1[20]={0}; printf(INPUT_PONIT); for(retry_cnt=0;retry_cnt 0) { if (uart5_read_byte((uint8_t *)&buf_rx5[i]) == 1) { i++; if(i>20) { i=0; } if((strcmp(buf_rx5,"BBBBBBBBBBBBBBBBBBBB"))==0) { IAP_Port=UART5; return LOCAL_BOOT_FROM_UART5; } } if (usart1_read_byte((uint8_t *)&buf_rx1[j]) == 1) { j++; if(i>20) { i=0; } if((strcmp(buf_rx1,"BBBBBBBBBBBBBBBBBBBB"))==0) { IAP_Port=USART1; return LOCAL_BOOT_FROM_USART1; } } } } return LOCAL_BOOT_NONE; } void uart_boot(void) { uint32_t ret =0; printf("Enter bootloader......\r\n"); if(IAP_Port==USART1) { printf("Port:USART1\tbaudrate:115200\t\tformat:N-8-1\r\n"); } else { printf("Port:UART5\tbaudrate:115200\t\tformat:N-8-1\r\n"); } printf("please send file to device in y-modem!\r\n"); printf("Waiting:"); ret = Ymodem_Receive(buf_1k,APP_LOAD_ADDR); printf("\r\n"); if(ret >0) { printf("Received file name:\t\t\t\t%s\r\n",FileName); printf("Received file length:\t\t\t\t%s\r\n",file_size); } else { printf("Failure of ymodem receive!\r\n"); assert_param(0); } load_process(); } void load_process(void) { uint32_t flag =0; printf("Fireware detected,now loading...\r\n"); printf("Erasing!\t\t\t\t\t"); if(0 == STM_FLASH_Erase(APP_RUN_ADDR)) { printf("failure\r\n"); assert_param(0); } if(0 == STM_FLASH_Erase(FLAG_BASE_ADDR)) { printf("failure\r\n"); assert_param(0); } printf("success\r\n"); printf("Programing !\t\t\t\t\t"); if(1 == STMFLASH_Write(APP_RUN_ADDR,(uint32_t *)APP_LOAD_ADDR,STM_FLASH_Get_Block_Size(APP_RUN_ADDR))) { printf("failure!\r\n"); assert_param(0); } flag =BOOTLOADER_RUN; if(1 == STMFLASH_Write(FLAG_BASE_ADDR,&flag,4)) { printf("failure!\r\n"); assert_param(0); } printf("success\r\n"); app_run(); } void app_run(void) { if(0==Run_Flash_App(APP_RUN_ADDR)) { printf("Run app failure!the firmware may be damaged!\r\n"); uart_boot(); } }