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;
|
||
}
|