264 lines
8.4 KiB
C
264 lines
8.4 KiB
C
|
#include "drv_misc.h"
|
|||
|
|
|||
|
#include "bsp_boot.h"
|
|||
|
#include "bsp_head.h"
|
|||
|
#include "bsp_flash.h"
|
|||
|
|
|||
|
#include "kit_data.h"
|
|||
|
#include "kit_time.h"
|
|||
|
#include "kit_debug.h"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/********************************************************************************
|
|||
|
*具备强刷功能,时间可配
|
|||
|
*检验固件大小
|
|||
|
*连续n次复位异常,停留在boot中
|
|||
|
*升级模式3中:1.不升级,直接跳到应用程序
|
|||
|
2.app升级,不写备份区,直接写应用区
|
|||
|
3.OTA模式需要写备份区
|
|||
|
*********************************************************************************/
|
|||
|
|
|||
|
/***********备份区起始开辟32字节空间**********
|
|||
|
+-------+-------+----------+----------+--------+
|
|||
|
| head1 | head2 | 固件长度 | 升级时间 | 预留 |
|
|||
|
| 4B | 4B | 4B | 4B | 16B |
|
|||
|
+-------+-------+----------+----------+--------+
|
|||
|
**********************************************/
|
|||
|
#define APP_CFG_BOOT_FW_LENGTH_OFFSET 8u
|
|||
|
#define APP_CFG_BOOT_FW_UPDATE_TIME_OFFSET 12u
|
|||
|
#define APP_CFG_BOOT_FW_DATA_OFFSET 32u
|
|||
|
|
|||
|
static kit_ret_e boot_write_data(BootItem *item);
|
|||
|
|
|||
|
static kit_ret_e boot_write_data(BootItem *item)
|
|||
|
{
|
|||
|
uint8_t tmp;
|
|||
|
uint16_t data_len;
|
|||
|
uint32_t start_addr = 0;
|
|||
|
kit_ret_e res = kKit_Ret_Ok;
|
|||
|
|
|||
|
//校验不过重新请求改包,不算错误
|
|||
|
if((item != NULL) && (kit_check_crc16(item->buf_addr, item->buf_len) == 0))
|
|||
|
{
|
|||
|
//校验第一包数据的产品编号和地址
|
|||
|
if(item->pack_idx == 0)
|
|||
|
{
|
|||
|
if((*((uint32_t *)item->buf_addr) != item->app_start_addr)
|
|||
|
|| (*((uint16_t *)&item->buf_addr[2 + 4 + item->product_num_offset]) != item->product_num))
|
|||
|
{
|
|||
|
return kKit_Ret_Error;
|
|||
|
}
|
|||
|
}
|
|||
|
data_len = item->buf_len - 4 - 2 - 2; // 减去地址 数据长度 CRC
|
|||
|
//数据先写入备份区
|
|||
|
start_addr = item->back_up_addr + APP_CFG_BOOT_FW_DATA_OFFSET + item->rcv_firmware_len;
|
|||
|
|
|||
|
item->rcv_firmware_len += data_len;
|
|||
|
//每一包数据必须4字节对齐,TODO必须是最后一包
|
|||
|
tmp = data_len % 4;
|
|||
|
if(tmp != 0)
|
|||
|
{
|
|||
|
data_len += (4 - tmp);
|
|||
|
}
|
|||
|
|
|||
|
res = bsp_flash_write_data_u32(item->flash_item, start_addr, item->buf_addr + 6, data_len);
|
|||
|
//校验写入flash数据是否正确
|
|||
|
if((res == kKit_Ret_Ok) && (kit_is_buf_same((void *)start_addr, (void *)(item->buf_addr + 6), data_len) == false))
|
|||
|
{
|
|||
|
//如果写入失败,擦除从新开始升级
|
|||
|
res = bsp_flash_erase_page(item->flash_item, item->back_up_addr, item->firmware_len + APP_CFG_BOOT_FW_DATA_OFFSET);
|
|||
|
item->pack_idx = 0;
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
item->pack_idx++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
uint16_t bsp_boot_get_pack_idx(BootItem *item)
|
|||
|
{
|
|||
|
uint16_t res = 0;
|
|||
|
if(item != NULL)
|
|||
|
{
|
|||
|
res = item->pack_idx;
|
|||
|
}
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
void bsp_boot_set_cmd(BootItem *item, BootCmd cmd, uint8_t* buf, uint16_t len)
|
|||
|
{
|
|||
|
KIT_ASSERT_PARAM(cmd < kBootCmd_End);
|
|||
|
if((item != NULL) && (cmd < kBootCmd_End))
|
|||
|
{
|
|||
|
item->cmd = cmd;
|
|||
|
|
|||
|
if(item->cmd == kBootCmd_Erase)
|
|||
|
{
|
|||
|
item->firmware_len = READ_LT_INT32U_BY_CONST_POS(buf, 0);
|
|||
|
}
|
|||
|
else if(item->cmd == kBootCmd_SndFrame)
|
|||
|
{
|
|||
|
item->buf_len = len;
|
|||
|
item->buf_addr = buf;
|
|||
|
}
|
|||
|
else if(item->cmd == kBootCmd_UpdateRes)
|
|||
|
{
|
|||
|
item->update_time = READ_LT_INT32U_BY_CONST_POS(buf, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void bsp_boot_poll(BootItem *item)
|
|||
|
{
|
|||
|
kit_ret_e res;
|
|||
|
|
|||
|
if((item != NULL) && (item->ans_call != NULL))
|
|||
|
{
|
|||
|
if(item->cmd == kBootCmd_Reboot)
|
|||
|
{
|
|||
|
item->buf_len = 0;
|
|||
|
item->pack_idx = 0;
|
|||
|
item->is_token = false;
|
|||
|
item->rcv_firmware_len = 0;
|
|||
|
item->cmd = kBootCmd_None;
|
|||
|
|
|||
|
item->step = kBootStep_WaitErase;
|
|||
|
item->ans_call(item, kBootCmd_Reboot, kKit_Ret_Ok);
|
|||
|
}
|
|||
|
else if(item->cmd == kBootCmd_Quit)
|
|||
|
{
|
|||
|
item->step = kBootStep_None;
|
|||
|
item->ans_call(item, kBootCmd_Quit, kKit_Ret_Ok);
|
|||
|
}
|
|||
|
else if(item->cmd == kBootCmd_Token)
|
|||
|
{
|
|||
|
item->is_token = true;
|
|||
|
item->ans_call(item, kBootCmd_Token, kKit_Ret_Ok);
|
|||
|
}
|
|||
|
|
|||
|
switch (item->step)
|
|||
|
{
|
|||
|
case kBootStep_None:
|
|||
|
|
|||
|
break;
|
|||
|
case kBootStep_WaitErase:
|
|||
|
if(item->cmd == kBootCmd_Erase)
|
|||
|
{
|
|||
|
res = bsp_flash_erase_page(item->flash_item, item->back_up_addr, item->firmware_len + APP_CFG_BOOT_FW_DATA_OFFSET);
|
|||
|
if (res == kKit_Ret_Ok)
|
|||
|
{
|
|||
|
item->step = kBootStep_RvdData;
|
|||
|
}
|
|||
|
if(item->is_token == true)
|
|||
|
{
|
|||
|
item->ans_call(item, kBootCmd_Erase, res);
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
case kBootStep_RvdData:
|
|||
|
if(item->cmd == kBootCmd_SndFrame)
|
|||
|
{
|
|||
|
res = boot_write_data(item);
|
|||
|
if(item->is_token == true)
|
|||
|
{
|
|||
|
kit_time_dly_ms(10);
|
|||
|
item->ans_call(item, kBootCmd_SndFrame, res);
|
|||
|
}
|
|||
|
}
|
|||
|
else if(item->cmd == kBootCmd_UpdateRes)
|
|||
|
{
|
|||
|
if((item->rcv_firmware_len == item->firmware_len)
|
|||
|
&& (kit_check_crc16((uint8_t *)(item->back_up_addr + APP_CFG_BOOT_FW_DATA_OFFSET), item->rcv_firmware_len) == 0))
|
|||
|
{
|
|||
|
res = kKit_Ret_Ok;
|
|||
|
drv_flash_write_u32(item->flash_item, item->back_up_addr + APP_CFG_BOOT_FW_LENGTH_OFFSET, item->rcv_firmware_len);
|
|||
|
drv_flash_write_u32(item->flash_item, item->back_up_addr + APP_CFG_BOOT_FW_UPDATE_TIME_OFFSET, item->update_time);
|
|||
|
bsp_head_set_status(item->flash_item, item->back_up_addr, kHeadStatus_Start);
|
|||
|
item->step = kBootStep_UpdateEnd;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
res = kKit_Ret_CheckErr;
|
|||
|
}
|
|||
|
kit_time_dly_ms(10);
|
|||
|
item->ans_call(item, kBootCmd_UpdateRes, res);
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case kBootStep_UpdateEnd:
|
|||
|
if(item->cmd == kBootCmd_UpdateEnd)
|
|||
|
{
|
|||
|
//必须复位,直接跳转后使用的堆栈是PSP,导致软件复位
|
|||
|
drv_misc_reset_mcu();
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
item->cmd = kBootCmd_None;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//固件长度> BOOT_SPACE_SIZE - 16 异常
|
|||
|
//固件长度为0xFFFFFFFF表示未下载完成断电,无需搬运直接跳到应用程序
|
|||
|
//固件长度不为0xFFFFFFFF,表示固件已经下载到备份区,可能未搬运、可能搬运未完成
|
|||
|
bool bsp_boot_move_firmware(BootItem *item, uint32_t start_addr, uint32_t max_len)
|
|||
|
{
|
|||
|
bool res = false;
|
|||
|
uint16_t crc;
|
|||
|
uint32_t tmp, data = 0xFFFFFFFF;
|
|||
|
|
|||
|
if(item != NULL)
|
|||
|
{
|
|||
|
drv_flash_read_u32(item->flash_item, item->back_up_addr + APP_CFG_BOOT_FW_LENGTH_OFFSET, &data);
|
|||
|
KIT_ASSERT_PARAM(data < (max_len - APP_CFG_BOOT_FW_DATA_OFFSET));
|
|||
|
KIT_DEBUG_PRINTF("GUIDE:need update\r\n");
|
|||
|
if((data < (max_len - APP_CFG_BOOT_FW_DATA_OFFSET)) && (kit_check_crc16((uint8_t *)(item->back_up_addr + APP_CFG_BOOT_FW_DATA_OFFSET), data) == 0))
|
|||
|
{
|
|||
|
bsp_flash_erase_page(item->flash_item, start_addr, data);
|
|||
|
tmp = data;
|
|||
|
if(data % 4 != 0)
|
|||
|
{
|
|||
|
tmp += 4 - (data % 4);
|
|||
|
}
|
|||
|
bsp_flash_write_data_u32(item->flash_item, start_addr, (uint8_t *)(item->back_up_addr + APP_CFG_BOOT_FW_DATA_OFFSET), tmp);
|
|||
|
|
|||
|
crc = kit_check_crc16((uint8_t *)start_addr, data);
|
|||
|
KIT_ASSERT_PARAM(crc == 0);
|
|||
|
//todo
|
|||
|
if(crc == 0)
|
|||
|
{
|
|||
|
bsp_head_set_status(item->flash_item, item->back_up_addr, kHeadStatus_Finsih);
|
|||
|
res = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
KIT_DEBUG_PRINTF("GUIDE:crc err\r\n");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
uint32_t bsp_boot_get_update_time(BootItem *item)
|
|||
|
{
|
|||
|
uint32_t tmp = 0;
|
|||
|
|
|||
|
if((drv_flash_read_u32(item->flash_item, item->back_up_addr + APP_CFG_BOOT_FW_UPDATE_TIME_OFFSET, &tmp) != kKit_Ret_Ok)
|
|||
|
|| (tmp == 0xFFFFFFFF))
|
|||
|
{
|
|||
|
tmp = 0;
|
|||
|
}
|
|||
|
return tmp;
|
|||
|
}
|