Files

507 lines
16 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include "FreeRTOS.h"
#include "chip.h"
#include "board.h"
#include "serial.h"
#include "sysinfo.h"
#include "conversation_protocol.h"
#include "sfud.h"
#include "ota_update.h"
#include "updatefile.h"
#include "romfile.h"
#include "animation.h"
#include "ff_stdio.h"
#include "awtk.h"
#include "ota_protocol.h"
#include "data_port.h"
#if DEVICE_TYPE_SELECT != EMMC_FLASH
#include "ff_sfdisk.h"
#endif
typedef enum {
UART_FRAME_START,
UART_FRAME_FILEINFO,
UART_FRAME_FILEXFER,
UART_FRAME_FINISH,
} eUartFrameType;
typedef enum {
UUP_STATE_IDLE,
UUP_STATE_START,
UUP_STATE_GET_FILEINFO,
UUP_STATE_FILE_TFR,
UUP_STATE_END,
} eUartUpdateState;
#define UUP_ACK_OK 1
#define UUP_ACK_FAIL 0
#define UUP_MAX_FILE_SIZE 0x1000000
#define UUP_RX_FRAME_NUM 16
#define UUP_MAX_LOADER_SIZE STEPLDR_MAX_SIZE//0x10000
static int uup_status = UUP_STATE_IDLE;
static int uup_file_type = 0;
static int uup_file_size = 0;
static int uup_packet_num = 0;
static int uup_rev_packet = 0;
// static int uup_rev_len = 0;
// static char uup_filename[32];
// static FF_FILE *uup_file = NULL;
#define UUP_PACKET_SIZE 128
#define UUP_MAX_FRAME_LEN (UUP_PACKET_SIZE + 16)
#define UUP_PACKET_A27_SIZE 4096
#define UUP_MAX_FRAME_A27_LEN (UUP_PACKET_A27_SIZE + 16)
#define UUP_RX_FRAME_NUM 16
#define BYTESPERPAGE 256
#define PAGESPERSECTORS 16
#define UUP_BUF_SIZE (BYTESPERPAGE * PAGESPERSECTORS)
#define IMAGE_RW_SIZE 0x10000
#define NEW_APPLDR_CHECKSUM_OFFSET 0x14
#define AMT630_BIN_OFFSET 0x41000
#define BOOTANIM_BIN_OFFSET 0x501000
#define ROM_BIN_OFFSET 0x701000//0x801000
#define NEW_APPFOOSET 0xb01000
#define AMT630_BIN_MAX_SIZE 0x4c0000
#define BOOTANIM_BIN_MAX_SIZE 0x200000//文件限制2M大小
#define ROM_BIN_MAX_SIZE 0x4c0000
// // 32M FLASH
// #define AMT630_BIN_OFFSET 0x41000
// #define BOOTANIM_BIN_OFFSET 0x741000
// #define ROM_BIN_OFFSET 0xb41000
// #define NEW_APPFOOSET 0x17F0000
// #define AMT630_BIN_MAX_SIZE 0x700000
static uint32_t uup_app_offset;
static uint32_t uup_burn_offset;
static unsigned char uup_buf[4096];
static unsigned int uup_buf_len = 0;
static unsigned int checksum = 0,calc_checksum = 0xffffffff;
extern void wifi_uup_send_ack(int type, int ret);
extern int timeout;
void wifi_uup_ota_update(uint8_t *framebuf, size_t len)
{
int frametype = framebuf[0];
uint8_t *buf = framebuf + 1;
unsigned int framelen;
unsigned int packetnum;
sfud_flash *sflash = sfud_get_device(0);
SysInfo *sysinfo = GetSysInfo();
switch (frametype) {
case UART_FRAME_START:
vTaskDelay(10);
printf("start sfud erase flash .\n");
light_off();
//擦除flash
uup_app_offset = NEW_APPFOOSET;
uup_burn_offset = uup_app_offset;
printf("erase add %X , size %X .\r\n",uup_app_offset,AMT630_BIN_MAX_SIZE);
vTaskDelay(50);
if(sfud_erase(sflash, uup_app_offset, AMT630_BIN_MAX_SIZE)==SFUD_SUCCESS){
printf("UART_FRAME_START sfud erase ok.\n");
vTaskDelay(50);
wifi_uup_send_ack(frametype, UUP_ACK_OK);
}else{
vTaskDelay(50);
printf("UART_FRAME_START sfud erase fail.\n");
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
}
uup_status = UUP_STATE_START;
break;
case UART_FRAME_FILEINFO:
if (uup_status != UUP_STATE_START && uup_status != UUP_STATE_GET_FILEINFO) {
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
uup_file_type = buf[0];
if (uup_file_type > UPFILE_TYPE_LNCHEMMC) {
printf("Rev wrong file type %d.\n", uup_file_type);
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
uup_packet_num = (buf[1] << 16) | (buf[2] << 8) | buf[3];
uup_file_size = 128 * uup_packet_num;
if(uup_file_type == UPFILE_TYPE_ANIMATION){//动画文件限制
if (uup_file_size > BOOTANIM_BIN_MAX_SIZE) {
printf("animo Rev wrong file size.\n");
printf("uup_file_size = 0x%x ,uup_packet_num = 0x%x .\n",uup_file_size,uup_packet_num);
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
}else if(uup_file_type == UPFILE_TYPE_RESOURCE){//资源文件限制
if (uup_file_size > ROM_BIN_MAX_SIZE) {
printf("rom Rev wrong file size.\n");
printf("uup_file_size = 0x%x ,uup_packet_num = 0x%x .\n",uup_file_size,uup_packet_num);
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
}else{
if (uup_file_size > AMT630_BIN_MAX_SIZE) {
printf("app Rev wrong file size.\n");
printf("uup_file_size = 0x%x ,uup_packet_num = 0x%x .\n",uup_file_size,uup_packet_num);
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
}
printf("uup_file_size = 0x%x .\n",uup_file_size);
uup_packet_num = uup_packet_num/32;
Set_sys_plan(uup_packet_num);
printf("uup_packet_num = %d .\r\n",uup_packet_num);
uup_rev_packet = 0;
wifi_uup_send_ack(frametype, UUP_ACK_OK);
uup_status = UUP_STATE_GET_FILEINFO;
calc_checksum = 0xffffffff;
break;
case UART_FRAME_FILEXFER:
if (uup_status != UUP_STATE_GET_FILEINFO && uup_status != UUP_STATE_FILE_TFR) {
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
packetnum = buf[0];
if ((uup_rev_packet & 0xff) != packetnum) {
printf("Wrong packet number.\n");
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
if (uup_rev_packet==0) { //第一条数据保存其crc校验码
if (uup_file_type == UPFILE_TYPE_APP) {//代码文件
unsigned int magic = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24);
if (magic != UPFILE_APP_MAGIC) {
printf("Wrong app file magic.\n");
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
unsigned char *tmp = buf + 1 + NEW_APPLDR_CHECKSUM_OFFSET;
checksum = tmp[0] | (tmp[1] <<8) | (tmp[2] << 16) | (tmp[3] << 24);
}else if (uup_file_type == UPFILE_TYPE_ANIMATION) {//动画文件
BANIHEADER *header = (BANIHEADER *)&buf[1];
if (header->magic != MKTAG('B', 'A', 'N', 'I')) {
printf("Wrong animation file magic.\n");
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
checksum = header->checksum;
}else if (uup_file_type == UPFILE_TYPE_RESOURCE) {//资源文件
RomHeader *header = (RomHeader *)&buf[1];
if (header->magic != MKTAG('R', 'O', 'M', 'A')) {
printf("Wrong resource file magic.\n");
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
checksum = header->checksum;
}
printf(" file_type = %d ,No1.checksum = 0x%x\n",uup_file_type,checksum);
}
framelen = len - 2;
//printf("framelen = %d ,uup_packet_num =%d ,uup_rev_packet = %d \n",framelen,uup_packet_num,uup_rev_packet);
/* only last frame size is less than UUP_PACKET_SIZE */
if (framelen > UUP_PACKET_A27_SIZE ||
(framelen < UUP_PACKET_A27_SIZE && uup_rev_packet < (uup_packet_num-1))) { //UUP_PACKET_A27_SIZE
printf("Wrong packet len.\n");
printf("uup_rev_packet = %d, uup_packet_num = %d \n",uup_rev_packet,(uup_packet_num-1));
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
memcpy(uup_buf + uup_buf_len, buf+1, framelen);
uup_buf_len += framelen;
uup_rev_packet++;
//wifi_uup_send_ack(frametype, UUP_ACK_OK);
if (uup_buf_len == UUP_BUF_SIZE) {
if(uup_rev_packet==1)
printf("plan = %d,pace = %d.\n",uup_packet_num,uup_rev_packet);
// //最后一包数据待擦写完成后回复
// if(uup_packet_num == uup_rev_packet){
// sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
// wifi_uup_send_ack(frametype, UUP_ACK_OK);
// Set_sys_pace(uup_rev_packet);
// }else{
wifi_uup_send_ack(frametype, UUP_ACK_OK);
Set_sys_pace(uup_rev_packet);
sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
// }
if (uup_rev_packet == 1){//UUP_BUF_SIZE/UUP_PACKET_SIZE) {
if (uup_file_type == UPFILE_TYPE_APP) {//代码文件
unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET);
*tmp = 0;
}else if (uup_file_type == UPFILE_TYPE_ANIMATION) {//动画文件
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
pheader->checksum = 0;
}else if (uup_file_type == UPFILE_TYPE_RESOURCE) {//资源文件
RomHeader *pheader = (RomHeader *)uup_buf;
pheader->checksum = 0;
}
}
calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和
uup_buf_len =0;
uup_burn_offset += UUP_BUF_SIZE;
}else if (uup_buf_len > UUP_BUF_SIZE) {
printf("loader file is too large.\n");
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
uup_status = UUP_STATE_FILE_TFR;
break;
case UART_FRAME_FINISH:
// printf("finish.uup_buf_len = %d.\r\n",uup_buf_len);
if (uup_status != UUP_STATE_FILE_TFR && uup_status != UART_FRAME_FINISH) {
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
break;
}
if (!buf[0]) {
printf("update end with error!\n");
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
uup_status = UUP_STATE_END;
break;
}
framelen = len - 2;
if(uup_buf_len){//若最后一包数据不为0 则存数据并且继续计算校验和
//sfud_erase_write(sflash, uup_burn_offset, uup_buf_len, uup_buf);
sfud_write(sflash, uup_burn_offset, uup_buf_len, uup_buf);
//若数据为32 即首次的4k 那么将其置为0
if (uup_rev_packet <= 1){//< UUP_BUF_SIZE / UUP_PACKET_SIZE) {
printf("enter2 uup_rev_packet = %d \n",uup_rev_packet);
if (uup_file_type == UPFILE_TYPE_APP) {
unsigned int *checksum = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET);
*checksum = 0;
}else if (uup_file_type == UPFILE_TYPE_ANIMATION) {
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
pheader->checksum = 0;
}else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
RomHeader *pheader = (RomHeader *)uup_buf;
pheader->checksum = 0;
}
}
calc_checksum = xcrc32(uup_buf, uup_buf_len, calc_checksum);
Set_sys_pace(0);
Set_sys_upgrade(1);
}
printf("calc_checksum = 0x%X,checksum = 0x%X.\n",calc_checksum,checksum);
if (calc_checksum != checksum) {
printf("checksum error ! ! ! .\r\n");
// }else{
// printf("checksum ok .\r\n");
// }
printf("exit ota sj.\n");
Set_sys_power_on_self_test(100);
Set_sys_upgrade_Flag(2);
printf("UART3_Type_regression .\n");
extern void UART3_Type_regression(void);
UART3_Type_regression();
extern uint8_t wifi_ota_state;
extern uint8_t wifi_file_state;
wifi_ota_state = 0;
wifi_file_state = 0;
timeout = 0;
}else{
wifi_uup_send_ack(frametype, UUP_ACK_OK);
vTaskDelay(1000);
UART3_Modification_Type();
gpio_direction_output(WIFI_RESET_IO, 0);
printf("amt630h update ok!\n");
sysinfo->image_offset=0x40000;
sysinfo->reserved[9] = uup_file_type;
sysinfo->upgrade_flag=uup_buf_len;
sysinfo->upgrade_appsize=uup_file_size;
SaveSysInfo();
vTaskDelay(500);
printf("TaskDelay 500ms SaveSysInfo .\n");
wifi_flash_copy_demo();
wdt_cpu_reboot();
}
/*if (calc_checksum != checksum) {
printf("calc_checksum = 0x%02x,checksum = 0x%02x.\n",calc_checksum,checksum);
printf("whole crc check after burn fail!\n");
wifi_uup_send_ack(frametype, UUP_ACK_FAIL);
uup_rev_packet = 0;
checksum = 0;
calc_checksum = 0xffffffff;
uup_buf_len = 0;
framelen = 0;
break;
} else {
wifi_uup_send_ack(frametype, UUP_ACK_OK);
vTaskDelay(1000);
// UART3_Modification_Type();
printf("uap close .\r\n");
printf("test amt630h update ok!\n");
sysinfo->image_offset=0x40000;
sysinfo->reserved[9] = uup_file_type;
sysinfo->upgrade_flag=uup_buf_len;
sysinfo->upgrade_appsize=uup_file_size;
SaveSysInfo();
vTaskDelay(500);
printf("TaskDelay 500ms SaveSysInfo .\n");
flash_copy_demo();
wdt_cpu_reboot();
}*/
uup_rev_packet = 0;
checksum = 0;
calc_checksum = 0xffffffff;
uup_buf_len = 0;
framelen = 0;
uup_status = UUP_STATE_END;
break;
}
}
int wifi_flash_copy_demo(void)
{
uint32_t calchecksum,appchecksum,imageoff,new_appoffset,new_appsize;
int i;
uint8_t *buf;
sfud_flash *sflash = sfud_get_device(0);
printf("enter copy flash .\n");
new_appsize=uup_file_size; //根据串口升级的协议获取
new_appoffset = NEW_APPFOOSET; //升级的程序可以固定写在这个地址预留3M
if(uup_file_type == UPFILE_TYPE_APP){
imageoff = AMT630_BIN_OFFSET; //固定的 运行区固定地址
}else if(uup_file_type == UPFILE_TYPE_ANIMATION){
imageoff = BOOTANIM_BIN_OFFSET; //固定的 运行区固定地址
}else if(uup_file_type == UPFILE_TYPE_RESOURCE){
imageoff = ROM_BIN_OFFSET;
}
//imageoff = AMT630_BIN_OFFSET; //固定的 运行区固定地址
printf("copy flash init ok.\n");
Set_sys_plan((new_appsize/IMAGE_RW_SIZE)+1);
printf("new_appsize = %x ,start flash copy .\n",new_appsize);
// sfud_qspi_fast_read_enable(sfud_get_device(0), 1);
// printf("sfud_qspi_fast_read_enable ok.\n");
buf = pvPortMalloc(IMAGE_RW_SIZE);
if (!buf) {
printf("%s %d malloc %d bytes fail.\n", __FUNCTION__, __LINE__, IMAGE_RW_SIZE);
return -1;
}
printf("start copy flash ok.\n");
for(i=0;i<new_appsize/IMAGE_RW_SIZE;i++)
{
printf("i = %d start read .\r\n",i);
sfud_read(sflash, new_appoffset+IMAGE_RW_SIZE*i, IMAGE_RW_SIZE, buf);
// printf("start erase write .\r\n");
sfud_erase_write(sflash, imageoff+IMAGE_RW_SIZE*i, IMAGE_RW_SIZE, buf);
// printf("start erase write ok.\r\n");
timeout = 0;
Set_sys_pace(i+1);
if(i==0)
{
if (uup_file_type == UPFILE_TYPE_APP) {//代码文件
unsigned int *tmp = (unsigned int *)(buf + NEW_APPLDR_CHECKSUM_OFFSET);
appchecksum = *tmp;
*tmp = 0;
}else if (uup_file_type == UPFILE_TYPE_ANIMATION) {//动画文件
BANIHEADER *pheader = (BANIHEADER *)buf;
appchecksum = pheader->checksum;
pheader->checksum = 0;
}else if (uup_file_type == UPFILE_TYPE_RESOURCE) {//资源文件
RomHeader *pheader = (RomHeader *)buf;
appchecksum = pheader->checksum;
pheader->checksum = 0;
}
printf("file_type = %d. %X\r\n",uup_file_type,appchecksum);
calchecksum = xcrc32(buf, IMAGE_RW_SIZE, 0xffffffff);
printf("i=0 calchecksum = 0x%X.\n",calchecksum);
}
else
{
calchecksum = xcrc32(buf, IMAGE_RW_SIZE, calchecksum);
printf("i=%d ,r_add = 0x%X ,w_add = 0x%X , calchecksum = 0x%X.\n",i,new_appoffset+IMAGE_RW_SIZE*i,imageoff+IMAGE_RW_SIZE*i,calchecksum);
}
}
if(new_appsize%IMAGE_RW_SIZE)
{
uint32_t red_add,wri_add,size,count;
int k;
count = (new_appsize%IMAGE_RW_SIZE )/0x1000;
red_add = new_appoffset+new_appsize- new_appsize%IMAGE_RW_SIZE;
wri_add = imageoff+new_appsize- new_appsize%IMAGE_RW_SIZE;
size = 0x1000;
printf("count = %d .\n",count);
for(k=0;k<count;k++){
sfud_read(sflash, red_add, size, buf);
sfud_erase_write(sflash, wri_add, size, buf);
calchecksum = xcrc32(buf, size, calchecksum);
printf("k=%d ,calchecksum = 0x%X.\n",k,calchecksum);
red_add +=size;
wri_add +=size;
}
if(uup_buf_len){//若最后一包数据不满0x1000 则存数据并且继续计算校验和
sfud_read(sflash, red_add, uup_buf_len, buf);
sfud_erase_write(sflash, wri_add, uup_buf_len, buf);
calchecksum = xcrc32(buf, uup_buf_len, calchecksum);
printf("end calchecksum = 0x%X.\n",calchecksum);
}
}
printf("end flash copy.\n");
vPortFree(buf);
printf("calchecksum is 0x%X\r\n",calchecksum);
printf("appchecksum is 0x%X\r\n",appchecksum);
// if(calchecksum==appchecksum)
// {
printf("crc32 OK\r\n");
SysInfo *sysinfo = GetSysInfo();
if(uup_file_type == UPFILE_TYPE_APP)
sysinfo->app_size = new_appsize;
sysinfo->image_offset=0x40000;
sysinfo->upgrade_flag = 0;
sysinfo->upgrade_appsize =0;
sysinfo->reserved[9] = 0;
SaveSysInfo();
vTaskDelay(500);
wdt_cpu_reboot();
return 0;
// }
// else
// {
// printf("crc32 ERROR\r\n");
// SysInfo *sysinfo = GetSysInfo();
// if(uup_file_type == UPFILE_TYPE_APP)
// sysinfo->app_size = new_appsize;
// sysinfo->image_offset=0x40000;
// sysinfo->upgrade_flag = 0;
// sysinfo->upgrade_appsize =0;
// sysinfo->reserved[9] = 0;
// SaveSysInfo();
// vTaskDelay(500);
// wdt_cpu_reboot();
// return -1;
// }
}