int main(void)
{
    int i = 0;
  /* MCU配置*/
  /* 重置所有外设, 初始化Flash接口和Systick. */
  HAL_Init();
  /* 系统时钟配置 */
  SystemClock_Config();
  /* 初始化所有已配置的外设 */
  MX_GPIO_Init();
  MX_USART6_UART_Init();
 
  usart6.initialize(115200);      //初始化串口波特率 115200
  usart6.printf("\x0c");          //清屏
  usart6.printf("\033[1;32;40m"); //设置终端字体为绿色    
 
  LED_GREEN_ON;
  if(ARM_KEY_STATE == KEY_UP){    //按键松开状态直接跳向应用程序
        goto start;
    }
    while(1){                      //按键按下,进入升级状态
        if(i++ == 5000000){
            //串口发送字符C
            usart6.send_byte('C');
            i = 0;
        }    
        if(usart6.receive_buffer[0] == SOH){
            break;
        }
    }
  while (1)
  {
        if(usart6.receive_ok_flag == 1){
            usart6.receive_ok_flag = 0;
            LED_GREEN_OFF;
            xmodem.process();
            if(usart6.receive_buffer[0] == EOT){
                usart6.send_byte(ACK);  
                //读保护
                for(i = 0; i < 100000; i ++); 
                HAL_FLASH_Lock();
                //发送文件成功,绿灯亮
                LED_BLUE_OFF;
                LED_RED_OFF;
                LED_GREEN_ON;
                while(1);
            }   
        }   
  }
    start:
    //测试用户代码是否从APPLICATION_ADDRESS被编程
        if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000){ 
            //跳转至用户程序
            JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
            Jump_To_Application = (pFunction) JumpAddress;
            //初始化用户程序的堆栈指针
            __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
            //跳转至应用程序
            Jump_To_Application();
        }else{        
            led_trade();
        }   
}
 
 
static int process(void)
{
/* 128 for XModem  + 3 head chars + 2 crc + nul */ 
    unsigned char xbuff[140]; 
 
    int i = 0;
    int cnt;
    unsigned long int * p;
 
    if(usart6.receive_buffer[0] == SOH){//接收到有效数据帧头
        xbuff[0]=usart6.receive_buffer[0];
        for(i=0;i<133;i++){//接收一帧数据
            xbuff[i+1]=usart6.receive_buffer[i+ 1];
        }
        if((xbuff[1]==(uint8_t)~xbuff[2])&&((packetno % 256) == xbuff[1])//包序号无误
            &&(crc16.check(&xbuff[3], 128) == (xbuff[131] << 8 | xbuff[132]))){//CRC校验无误
                if(packetno == 1){
                    LED_BLUE_ON;
                    HAL_FLASH_Unlock();
                    for(cnt = FLASH_SECTOR_2;cnt < FLASH_SECTOR_11;cnt ++){
                        FLASH_Erase_Sector(cnt,OB_BOR_LEVEL3);  
                    }
                    LED_BLUE_OFF;
                    p = (unsigned long int *)&xbuff[3];
                    for(cnt = 0;cnt < 32;cnt++){
                        HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,APPLICATION_ADDRESS + (cnt * 4),*(p + cnt));            
                    }
                    packetno++;
                    usart6.send_byte(ACK);
                    return 0;
                }
            packetno++;
            p = (unsigned long int *)&xbuff[3];
            for(cnt = 0;cnt < 32;cnt++){
                HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,APPLICATION_ADDRESS + (packetno - 2) * 128 + (cnt * 4),*(p + cnt));            
            }
            usart6.send_byte(ACK);
        }
        else{//要求重发
            for(cnt = FLASH_SECTOR_2;cnt < FLASH_SECTOR_11;cnt ++){
                FLASH_Erase_Sector(cnt,OB_BOR_LEVEL3);  
            }
            led_trade();
        }
    }
    return 0;
}