MAX_CARLINK_A270S/MXC_A27-PCB4.5-270S/app/moto/protocol/ota_protocol.c

546 lines
18 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"
int flash_copy_demo(void);
extern uint8_t bt_upgrade_flag;
#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 0x741000
#define ROM_BIN_OFFSET 0xb41000
#define NEW_APPFOOSET 0x17F0000
#define AMT630_BIN_MAX_SIZE 0x700000
/*
#define AMT630_BIN_OFFSET 0x41000
#define BOOTANIM_BIN_OFFSET 0x501000//0x341000
#define ROM_BIN_OFFSET 0x801000
#define NEW_APPFOOSET 0xb01000
#define AMT630_BIN_MAX_SIZE 0x4c0000
*/
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;
static void uup_send_ack(UartPort_t *uap, int type, int ret)
{
/*unsigned char buf[7] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00};
int i;
buf[4] = type;
buf[5] = ret;
for (i = 1; i < 6; i++)
buf[6] ^= buf[i];
iUartWrite(uap, buf, 7, pdMS_TO_TICKS(100));*/
unsigned char buf[8] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00, 0x00};
int i;
buf[5] = type;
buf[6] = ret;
if(ret == 0){
Set_sys_power_on_self_test(100);
Set_sys_return_demo(2);
Set_sys_plan(0);
Set_sys_pace(0);
bt_upgrade_flag = 0;
}
for (i = 1; i < 7; i++)
buf[7] ^= buf[i];
// printf("630->uart:");
// for(uint8_t j=0;j<8;j++){
// printf("%02x ",buf[j]);
// }
// printf("\n");
iUartWrite(uap, buf, 8, pdMS_TO_TICKS(100));
}
void uup_ota_update(UartPort_t *uap, 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();
//printf("uup_ota_update frametype =%d \n",frametype);
switch (frametype) {
case UART_FRAME_START:
printf("UART3_Modification_Type .\n");
UART3_Modification_Type();
vTaskDelay(10);
printf("start sfud erase flash .\n");
//擦除flash
uup_app_offset = NEW_APPFOOSET;
uup_burn_offset = uup_app_offset;
//uup_send_ack(uap, frametype, UUP_ACK_OK);
//Set_sys_power_on_self_test(150);
printf("erase add %X , size %X .\r\n",uup_app_offset,AMT630_BIN_MAX_SIZE);
if(sfud_erase(sflash, uup_app_offset, AMT630_BIN_MAX_SIZE)==SFUD_SUCCESS){
vTaskDelay(100);
printf("UART3_Type_regression .\n");
UART3_Type_regression();
vTaskDelay(100);
printf("UART_FRAME_START sfud erase ok.\n");
uup_send_ack(uap, frametype, UUP_ACK_OK);
}else{
vTaskDelay(100);
printf("UART3_Type_regression .\n");
UART3_Type_regression();
vTaskDelay(100);
printf("UART_FRAME_START sfud erase fail.\n");
uup_send_ack(uap, 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) {
uup_send_ack(uap, 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);
uup_send_ack(uap, 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_size > AMT630_BIN_MAX_SIZE) {
printf("Rev wrong file size.\n");
printf("uup_file_size = 0x%x ,uup_packet_num = 0x%x .\n",uup_file_size,uup_packet_num);
uup_send_ack(uap, 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;
uup_send_ack(uap, 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) {
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
break;
}
packetnum = buf[0];
if ((uup_rev_packet & 0xff) != packetnum) {
printf("Wrong packet number.\n");
//printf("buf 0 - 4 : 0x%x ,0x%x ,0x%x ,0x%x ,0x%x \n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
//printf("packetnum = 0x%x,uup_rev_packet = 0x%x \n",packetnum,uup_rev_packet);
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
break;
}
//printf("uup_rev_packet==0 ---------TURE\n");
//printf("uup_rev_packet %d.\n", uup_rev_packet);
if (uup_rev_packet==0) { //第一条数据保存其crc校验码
/*if (uup_file_type == UPFILE_TYPE_WHOLE) {
UpFileHeader *header = (UpFileHeader*)&buf[1];
if (header->magic != MKTAG('U', 'P', 'D', 'F')) {
printf("Wrong whole file magic.\n");
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
break;
}
checksum = header->checksum;
sysinfo->app_size = header->files[0].size;
printf("sysinfo->appsize = 0x%x", sysinfo->app_size);
}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");
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
break;
}
checksum = header->checksum;
} 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");
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
break;
}
checksum = header->checksum;
} else */
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");
uup_send_ack(uap, 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");
uup_send_ack(uap, 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");
uup_send_ack(uap, 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));
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
break;
}
memcpy(uup_buf + uup_buf_len, buf+1, framelen);
uup_buf_len += framelen;
uup_rev_packet++;
//uup_send_ack(uap, frametype, UUP_ACK_OK);
if (uup_buf_len == UUP_BUF_SIZE) {
printf("uup_rev_packet = %d , save_data.\n",uup_rev_packet);
uup_send_ack(uap, frametype, UUP_ACK_OK);
Set_sys_pace(uup_rev_packet);
//printf("addr=0x%x,size=%x\n",uup_burn_offset,framelen);
//sfud_erase_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
if (uup_rev_packet == 1){//UUP_BUF_SIZE/UUP_PACKET_SIZE) {
//printf("enter1 uup_rev_packet = %d \n",uup_rev_packet);
/*if (uup_file_type == UPFILE_TYPE_WHOLE) {
UpFileHeader *pheader = (UpFileHeader *)uup_buf;
pheader->checksum = 0;
} else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
RomHeader *pheader = (RomHeader *)uup_buf;
pheader->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_APP) {*/
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");
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
break;
}
/*memcpy(&uup_sysinfo, &buf[2], sizeof(SysInfo));
sfud_erase_write(sflash, uup_burn_offset, framelen, &buf[1]);//128字节写一次
uup_burn_offset += framelen;*/
uup_status = UUP_STATE_FILE_TFR;
break;
case UART_FRAME_FINISH:
if (uup_status != UUP_STATE_FILE_TFR && uup_status != UART_FRAME_FINISH) {
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
break;
}
if (!buf[0]) {
printf("update end with error!\n");
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
uup_status = UUP_STATE_END;
break;
}
framelen = len - 2;
//printf("finish calc_checksum =%x\n",calc_checksum);
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_WHOLE) {
UpFileHeader *pheader = (UpFileHeader *)uup_buf;
pheader->checksum = 0;
} else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
RomHeader *pheader = (RomHeader *)uup_buf;
pheader->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_APP) {*/
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;
}
}
printf("enter2 uup_buf_len =%d calc_checksum================0x%x\n",uup_buf_len,calc_checksum);
calc_checksum = xcrc32(uup_buf, uup_buf_len, calc_checksum);
Set_sys_pace(0);
Set_sys_upgrade(1);
}
/*if (calc_checksum != checksum) {
printf("checksum error ! ! ! .\r\n");
}else{
printf("checksum ok .\r\n");
}*/
if (calc_checksum != checksum) {
printf("calc_checksum = 0x%02x,checksum = 0x%02x.\n",calc_checksum,checksum);
printf("whole crc check after burn fail!\n");
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
uup_rev_packet = 0;
checksum = 0;
calc_checksum = 0xffffffff;
uup_buf_len = 0;
framelen = 0;
break;
} else {
uup_send_ack(uap, 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 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");
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
{
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);
printf("crc32 ERROR\r\n");
bt_upgrade_flag = 0;
return -1;
}
}