89
iap/iap.c
89
iap/iap.c
@@ -116,10 +116,60 @@ rt_err_t port_rx_ind(rt_device_t dev, rt_size_t size)
|
||||
|
||||
#define RT_BUF_SIZE (1024)
|
||||
|
||||
/*
|
||||
* 固件格式:
|
||||
*
|
||||
* 作用 & 说明
|
||||
* - 记录固件对应硬件 & 版本信息
|
||||
* - 简便起见,不包含校验信息
|
||||
*
|
||||
* index len desc
|
||||
* 0 4 'XYFC'
|
||||
* 4 4 固件信息长度
|
||||
* 8 N 固件信息 ('类型'-'版本')
|
||||
* 8+N M 固件数据
|
||||
*/
|
||||
static const char FIXED_HEAD[] = {'X', 'Y', 'F', 'C'};
|
||||
extern const char IAP_BIN_PREFIX[];
|
||||
|
||||
static int _check_head(const rt_uint8_t *buf, rt_size_t len)
|
||||
{
|
||||
if (len < 8)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(FIXED_HEAD); i++)
|
||||
{
|
||||
if (FIXED_HEAD[i] != buf[i])
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
rt_uint32_t real = *((const rt_uint32_t *)&buf[4]);
|
||||
rt_uint32_t want = rt_strlen(IAP_BIN_PREFIX);
|
||||
if (real <= want || len - 8 < real)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
|
||||
for(int i = 0; i < want; i++)
|
||||
{
|
||||
if (IAP_BIN_PREFIX[i] != buf[8 + i])
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
|
||||
return real + 8;
|
||||
}
|
||||
|
||||
struct custom_ctx {
|
||||
struct rym_ctx parent;
|
||||
int32_t file_size;
|
||||
int32_t w_index;
|
||||
int32_t recevied_head;
|
||||
const struct fal_partition *flash;
|
||||
rt_uint8_t ck_buffer[RT_BUF_SIZE];
|
||||
};
|
||||
@@ -167,11 +217,8 @@ static enum rym_code _rym_recv_begin(
|
||||
return RYM_CODE_CAN;
|
||||
}
|
||||
|
||||
if (fal_partition_erase(cctx->flash, 0, cctx->file_size) < 0)
|
||||
{
|
||||
return RYM_CODE_CAN;
|
||||
}
|
||||
cctx->w_index = 0;
|
||||
cctx->recevied_head = 0;
|
||||
|
||||
return RYM_CODE_ACK;
|
||||
}
|
||||
@@ -185,6 +232,23 @@ static enum rym_code _rym_recv_data(
|
||||
RT_ASSERT(cctx);
|
||||
RT_ASSERT(len <= RT_BUF_SIZE);
|
||||
|
||||
int offset = 0;
|
||||
if (cctx->recevied_head == 0)
|
||||
{
|
||||
offset = _check_head(buf, len);
|
||||
if (offset < 0)
|
||||
{
|
||||
return RYM_ERR_FILE;
|
||||
}
|
||||
|
||||
if (fal_partition_erase(cctx->flash, 0, cctx->file_size) < 0)
|
||||
{
|
||||
return RYM_CODE_CAN;
|
||||
}
|
||||
|
||||
cctx->recevied_head = 1;
|
||||
}
|
||||
|
||||
if (cctx->w_index >= cctx->file_size)
|
||||
{
|
||||
return RYM_CODE_ACK;
|
||||
@@ -195,22 +259,22 @@ static enum rym_code _rym_recv_data(
|
||||
len = cctx->file_size - cctx->w_index;
|
||||
}
|
||||
|
||||
if (fal_partition_write(cctx->flash, cctx->w_index, buf, len) <= 0)
|
||||
if (fal_partition_write(cctx->flash, cctx->w_index, &buf[offset], len - offset) <= 0)
|
||||
{
|
||||
return RYM_CODE_CAN;
|
||||
}
|
||||
|
||||
if (fal_partition_read(cctx->flash, cctx->w_index, cctx->ck_buffer, len) <= 0)
|
||||
if (fal_partition_read(cctx->flash, cctx->w_index, cctx->ck_buffer, len - offset) <= 0)
|
||||
{
|
||||
return RYM_CODE_CAN;
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
for (int i = 0; i < len - offset; i++)
|
||||
{
|
||||
if (cctx->ck_buffer[i] != buf[i])
|
||||
if (cctx->ck_buffer[i] != buf[i + offset])
|
||||
return RYM_CODE_CAN;
|
||||
}
|
||||
cctx->w_index += len;
|
||||
cctx->w_index += len - offset;
|
||||
|
||||
return RYM_CODE_ACK;
|
||||
}
|
||||
@@ -309,6 +373,8 @@ int iap_main_entry(void)
|
||||
return _iap_entry(RT_TRUE);
|
||||
}
|
||||
|
||||
#include "shell.h"
|
||||
|
||||
static int _iap_entry(rt_bool_t is_boot)
|
||||
{
|
||||
if (IapAppAddr && is_boot)
|
||||
@@ -316,6 +382,11 @@ static int _iap_entry(rt_bool_t is_boot)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((!IapAppAddr) && is_boot)
|
||||
{
|
||||
finsh_set_prompt("msh (IAP)");
|
||||
}
|
||||
|
||||
rt_err_t err = RT_EOK;
|
||||
struct custom_ctx *ctx = RT_NULL;
|
||||
rt_device_t console = rt_console_get_device();
|
||||
|
Reference in New Issue
Block a user