使用Air720H 进行OTA升级,下载数据异常

发布于 2020-02-11 21:13:49
    本帖最后由 面码1314 于 2020-2-11 21:14 编辑


采用4G模块Air720H 通过HTTP进行下载固件升级。未采用webclient组件,采用了AT指令的形式。


1.使用串口调试助手和Air720H通信

通过AT指令成功获取到 HTTP服务器上的固件。具体如下:

1.png
通过AT指令 AT+HTTPACTION=0 获取到了整个固件的大小字节 +HTTPACTION: 0,200,92240 固件一共92240字节。

通过AT指令 AT+HTTPREAD=0,100 获取固件的起始的前100个字节,而 RBLk??^app2.0.000010203040506070809`?荱{qa苎餲噗?%2? 就是获取到的固件前100字节。

串口调试助手和Air720H通信测试正常。

2. 使用AT组件在程序中进行通信

经过一系列AT指令设置Air720H后,都是成功的。

最后两个AT指令 分别为获取固件大小 和 下载固件 运行结果如下:
2.png

通过 1 可以知道成功获取到了固件大小 +HTTPACTION: 0,200,92240 获取到固件大小为92240字节 (和 串口调试助手测试的一致)。

通过 2 可以看出向 服务器请求获取固件的前100字节 。

第3个圈 是这次请求返回的所有数据 。
正常情况下 第3行应该是 固件的前100字节的数据。但是可以看出返回的数据是 06070809 而不是之前使用串口调试助手返回的 RBLk??^app2.0.000010203040506070809`?荱{qa苎餲噗?%2? 的数据。 感觉返回的数据是其中的一段。

以下是上面两个命令AT指令的代码部分

   resp = at_create_resp(200, 4, rt_tick_from_millisecond(5000));                /* 创建响应结构体*/
/*获取HTTP 状态码, 由远端服务器响应 200确定(OK)
获取请求下载总大小 */
/* AT+HTTPACTION=0 GET 开始

OK

+HTTPACTION: 0,200,92240
*/
if (at_exec_cmd(resp,"AT+HTTPACTION=0") != RT_EOK)
{
LOG_E("AT+HTTPACTION=0, send commands failed , response error or timeout !");
return -RT_ETIMEOUT;
}
/*提取固件的大小*/
resp__buf_data=at_resp_get_line_by_kw(resp,"+HTTPACTION:");
at_resp_parse_line_args(resp, 4,"+HTTPACTION: %d,%d,%d", &num1, &resp_status, &file_size);
LOG_I("%d,%d,%d",num1, resp_status, file_size);

/*HTTP 服务器响应状态是否正确*/
if (resp_status != 200)
{
LOG_E("webclient GET request failed, response(%d) error.", resp_status);
ret = -RT_ERROR;
}
at_delete_resp(resp); /*删除响应结构体*/

resp = at_create_resp(1024, 0, rt_tick_from_millisecond(4000)); /* 创建响应结构体*/
if(resp == NULL)
{
LOG_E(" create HTTP resp no memory");
}

/*请求下载固件的前100字节*/
if (at_exec_cmd(resp,"AT+HTTPREAD=0,100") != RT_EOK)
{
LOG_E("AT+HTTPACTION=0, send commands failed , response error or timeout !");
return -RT_ETIMEOUT;
}
resp__buf_data=at_resp_get_line_by_kw(resp,"+HTTPREAD:");
LOG_I("%s",resp__buf_data);
if(resp__buf_data==RT_NULL)
{
LOG_E("no +HTTPREAD:");
}

/* 按行数循环打印接收到的响应数据 */
{
const char *line_buffer = RT_NULL;

LOG_D("Response buffer");
for(rt_size_t line_num = 1; line_num <= resp->line_counts; line_num++)
{
if((line_buffer = at_resp_get_line(resp, line_num)) != RT_NULL)
{
LOG_E("line %d buffer : %s", line_num, line_buffer);
}
else
{
LOG_E("Parse line buffer error!");
}
}
}



其中还遇到了另外一个问题, 在请求下载固件AT指令前如果先进行了 对 download 分区擦除下载分区 。那么将会出现以下情况。
3.png

可以看到 依然获取到了待下载固件文件的大小 并找到了download分区,并成功擦除了分区
但是从最后的打印数据来看 似乎没有自己想要的固件数据 ,甚至可以说什么返回数据都没。

这部分代码如下 ,仅仅在 获取云端固件大小 和 下载固件两个操作中间加上了 一段擦除download分区。
   resp = at_create_resp(200, 4, rt_tick_from_millisecond(5000));		/* 创建响应结构体*/
/*获取HTTP 状态码, 由远端服务器响应 200确定(OK)
获取请求下载总大小 */
/* AT+HTTPACTION=0 GET 开始

OK

+HTTPACTION: 0,200,92240
*/
if (at_exec_cmd(resp,"AT+HTTPACTION=0") != RT_EOK)
{
LOG_E("AT+HTTPACTION=0, send commands failed , response error or timeout !");
return -RT_ETIMEOUT;
}
/*提取固件的大小*/
resp__buf_data=at_resp_get_line_by_kw(resp,"+HTTPACTION:");
at_resp_parse_line_args(resp, 4,"+HTTPACTION: %d,%d,%d", &num1, &resp_status, &file_size);
LOG_I("%d,%d,%d",num1, resp_status, file_size);

/*HTTP 服务器响应状态是否正确*/
if (resp_status != 200)
{
LOG_E("webclient GET request failed, response(%d) error.", resp_status);
ret = -RT_ERROR;
}
at_delete_resp(resp); /*删除响应结构体*/

/************************添加擦除 下载分区代码 ***************************/

// /*获取总共固件大小 合理性检测*/
rt_kprintf("http file_size:%d\n",file_size);
if (file_size == 0)
{
LOG_E("Request file size is 0!");
ret = -RT_ERROR;
}
else if (file_size < 0)
{
LOG_E("webclient GET request type is chunked.");
ret = -RT_ERROR;
}
/* 获取下载分区信息并删除下载分区数据 */
/* Get download partition information and erase download partition data */
if ((dl_part = fal_partition_find("download")) == RT_NULL)
{
LOG_E("Firmware download failed! Partition (%s) find error!", "download");
ret = -RT_ERROR;
}

LOG_I("Start erase flash (%s) partition!", dl_part->name);

/* 擦除下载分区 */
if (fal_partition_erase(dl_part, 0, file_size) < 0)
{
LOG_E("Firmware download failed! Partition (%s) erase error!", dl_part->name);
ret = -RT_ERROR;
}
LOG_I("Erase flash (%s) partition success!", dl_part->name);

buffer_read = rt_malloc(HTTP_OTA_BUFF_LEN); /*申请4k存储空间*/
if (buffer_read == RT_NULL)
{
LOG_E("No memory for http ota!");
ret = -RT_ERROR;
}
memset(buffer_read, 0x00, HTTP_OTA_BUFF_LEN);

LOG_I("OTA file size is (%d)", file_size);

/************************添加擦除 下载分区代码结束段 ***************************/

resp = at_create_resp(1024, 0, rt_tick_from_millisecond(4000)); /* 创建响应结构体*/
if(resp == NULL)
{
LOG_E(" create HTTP resp no memory");
}

/*请求下载固件的前100字节*/
if (at_exec_cmd(resp,"AT+HTTPREAD=0,100") != RT_EOK)
{
LOG_E("AT+HTTPACTION=0, send commands failed , response error or timeout !");
return -RT_ETIMEOUT;
}
resp__buf_data=at_resp_get_line_by_kw(resp,"+HTTPREAD:");
LOG_I("%s",resp__buf_data);
if(resp__buf_data==RT_NULL)
{
LOG_E("no +HTTPREAD:");
}

/* 按行数循环打印接收到的响应数据 */
{
const char *line_buffer = RT_NULL;

LOG_D("Response buffer");
for(rt_size_t line_num = 1; line_num <= resp->line_counts; line_num++)
{
if((line_buffer = at_resp_get_line(resp, line_num)) != RT_NULL)
{
LOG_E("line %d buffer : %s", line_num, line_buffer);
}
else
{
LOG_E("Parse line buffer error!");
}
}
}




各位网友帮我提提意见,接下来我应该如何调试

查看更多

关注者
0
被浏览
721
26 个回答
面码1314
面码1314 2020-02-11
    本帖最后由 面码1314 于 2020-2-11 22:28 编辑


继续测试发现,突然想起之前重新使用 ENV后忘了改串口缓存大小
修改 打印串口大小 RT_SERIAL_RB_BUFSZ = 2048
自己用于AT指令的客户端 串口大小已经设置为 5632
int at_client_uart2_init(void)
{
#define AT_CLIENT_RECV_BUFF_LEN 5632 /*串口2接收缓存*/
#define AIR720_UART "uart2"
rt_int32_t error_num = 0;
error_num=at_client_init(AIR720_UART, AT_CLIENT_RECV_BUFF_LEN); /*配置at客户端*/
return error_num;
}
INIT_DEVICE_EXPORT(at_client_uart2_init); /*外设驱动类自动初始化*/


接着继续调试测试 ,发现加上 对download分区的擦除代码后,AT指令获取服务器固件数据有了。
但是 只有开头的3个字母 RBL 恰好是固件未乱码数据部分的开头 RBLk??^app2.0.000010203040506070809`?荱{qa苎餲噗?%2?

4.png

同时还发现个问题 ,此条AT指令响应结构体设置的为


resp = at_create_resp(1024, 0, rt_tick_from_millisecond(4000));


意思是,在未超时的情况下,只有收到 OK 或者 ERROR 才会认为接收完毕。 但是最后打印的所有接收数据缺没有 OK 或ERROR。


现在我就觉得是不是数据乱码的问题导致的。

测试: 上传了一个文件文件 进行下载打印前100字节

5.png

下载 结果如下
6.png
通过1知道了文本 大小126字节
通过2知道 成功下载了前100字节
通过3知道 得到了响应的OK



难道真的是数据格式的问题? 如果是接下来应该怎么办呢

面码1314
面码1314 2020-02-11
继续调试

  /*请求下载固件的前100字节*/
if (at_exec_cmd(resp,"AT+HTTPREAD=0,100") != RT_EOK)
{
LOG_E("AT+HTTPACTION=0, send commands failed , response error or timeout !");
return -RT_ETIMEOUT;
}
resp__buf_data=at_resp_get_line_by_kw(resp,"RBL");
LOG_I("%s",resp__buf_data);
if(resp__buf_data==RT_NULL)
{
LOG_E("no RBL");
}
ulog_hexdump(LOG_TAG, 16, (rt_uint8_t *)resp__buf_data, 100);
使用 ulog_hexdump(LOG_TAG, 16, (rt_uint8_t *)resp__buf_data, 100); 将 数据进行16进制的形式打印。


得到了如下数据
7.png

使用UltraEdit 以十六进制 打开源文件 对比

8.png

一致诶 。数据没错

明天继续搞 下载进去看行不行,看能升级不

fhqmcu
fhqmcu 认证专家 2020-02-14
没有详细看完,太多了。在使用AT指令读取下载固件的不能使用正常的at指令发送,接收应答的方式,这是因为固件中数据变成了AT指令的应答,固件什么数据都有,比如是OK, ERROR,\r,\n这样的数据,这些数据会导致AT模块代码分析AT指令的应答时产生错误,你的问题原因出在这里。
告诉你修改的方法。读取固件代码的函数中只发送AT指令,等待一个信号, 对于这条AT指令的返回的数据,使用的urc数据的方式处理,参考模块底层驱动代码中模块接收TCP连接数据时,处理接收数据的方法来实现,接收到数据后发送一个信号给等待信号的函数。
面码1314
面码1314 2020-02-14
fhqmcu 发表于 2020-2-14 17:18
没有详细看完,太多了。在使用AT指令读取下载固件的不能使用正常的at指令发送,接收应答的方式,这是因为固 ...


感谢你提供的解决办法。
;P确实遗漏了关于固件里面什么数据都可能存在的情况。
面码1314
面码1314 2020-02-16
fhqmcu 发表于 2020-2-14 17:18
没有详细看完,太多了。在使用AT指令读取下载固件的不能使用正常的at指令发送,接收应答的方式,这是因为固 ...


感谢提供的思路和解决方案。已经成功解决之前遇到过的有时无论怎么升级都不能成功的问题。现在测试,已经可以稳定连续升级10个版本了。:lol:lol
yc985055
yc985055 2020-04-10
楼主,你好!我也是用STM32F1+Air720H来做升级的。 1.片内(512K)分区#define FAL_PART_TABLE \
{ \

{FAL_PART_MAGIC_WROD, "bl", "onchip_flash", 0, 32 * 1024, 0}, \

{FAL_PART_MAGIC_WROD, "app", "onchip_flash", 32*1024, 196 * 1024, 0}, \

{FAL_PART_MAGIC_WROD, "download", "onchip_flash", 228*1024 , 196 * 1024, 0}, \
}
升级前先用仿真器烧录bootloader和app初始版本。
升级过程如下:
1.用仿真器烧录bootloader(未加密)和app的初始版本,
2.然后程序启动http下载升级文件到download区域.
下载前: if ((dl_part = fal_partition_find("download")) == RT_NULL)
{
rt_kprintf("find download partion fail!\r\n");

}
else
{
if (fal_partition_erase(dl_part, 0, 196 * 1024) < 0)
{
rt_kprintf("erase download partion fail!\r\n");
}
}
下载过程中(写入文件): fal_partition_write(dl_part, (uint32_t)(http_size_conts * HTTP_SIZE_PER_PKT), pDataBuf, dataLen);
3.下载完成,系统复位。

rt_hw_cpu_reset();

目前是升级失败的,问题如下:
1.首次烧录的app文件需要通过rt_ota_packaging_tool处理后再用仿真器烧录吗?
2.fal_partition_write和fal_partition_erase是否能直接用stm32_flash_wirte和stm32_flash_erase来替换。
3.升级失败的可能原因是?
小小李sunny
小小李sunny 2020-04-10
yc985055 发表于 2020-4-10 11:11
楼主,你好!我也是用STM32F1+Air720H来做升级的。 1.片内(512K)分区#define FAL_PART_TABLE ...


1.用调试器烧录APP文件时,不用处理,跟平常烧写一样,不过要确保烧录地址正确;
3.你得贴出来升级失败的日志是啥才能查原因啊。
yc985055
yc985055 2020-04-11
小小李sunny 发表于 2020-4-10 12:17
1.用调试器烧录APP文件时,不用处理,跟平常烧写一样,不过要确保烧录地址正确;
3.你得贴出来升级失败的 ...


开始是数据没有写入到download(内部flash-0x39000) ,后来修改http下载,确定下载到download位置(0x39000)的数据是正确并且完整(对比了升级文件rtthread.bin)。但重启cpu没有覆盖现有的app.。 估计是bootloader里面没有把download拷贝到app位置,原因还在查。在反复读这篇文档,看是不是哪个步骤没设置对. https://www.rt-thread.org/document/site/application-note/system/rtboot/an0028-rtboot/
yc985055
yc985055 2020-04-11
补充描述一下:我是用官方链接生成的bootloader。然后烧录自己的app, 在app程序里面用air720下载升级文件到download,下载完成后立即复位mcu。 按理bootloader应该自动判断比较app<->download中的数据,决定是否需要更新。 如果再不找不到原因,只用自己找bootloader代码修改了。
面码1314
面码1314 2020-04-11
yc985055 发表于 2020-4-11 16:52
补充描述一下:我是用官方链接http://iot.rt-thread.com生成的bootloader。然后烧录自己的app, 在app程序里 ...


我没有采用官网的http例程下载,我是直接使用的AIr720H的HTTP的AT指令集进行下载的。
yc985055
yc985055 2020-04-12
面码1314 发表于 2020-4-11 22:07
我没有采用官网的http例程下载,我是直接使用的AIr720H的HTTP的AT指令集进行下载的。 ...


我也是用HTTP的AT指令集进行下载升级文件的。上面描述中提到的官方参考是生成bootloader过程。 1. 先ST-LINK烧录官方生成的bootloader. 2.用keil5下载我的应用程序到app指令区别。3. app中运行http把升级文件下载到download区域(升级文件已保存成功) 4. 然后重启mcu.我以为download中的程序会自动覆盖app中的, 结果没有。 因为bootloader是官方面的,所以不清楚bootloader中执行到哪步失败的。
yc985055
yc985055 2020-04-12
面码1314 发表于 2020-4-11 22:07
我没有采用官网的http例程下载,我是直接使用的AIr720H的HTTP的AT指令集进行下载的。 ...


我开始怀疑download中数据有错误。还特意在应用程序中读了108K的数据区打印显示,确实是完整的升级文件。
yc985055
yc985055 2020-04-12
面码1314 发表于 2020-4-11 22:07
我没有采用官网的http例程下载,我是直接使用的AIr720H的HTTP的AT指令集进行下载的。 ...


对了,像我们这样通过4g模块http下载。 menuconfig中的选项 Enable HTTP/HTTPS OTA选项可以不用打开吧? 方便加微信联系一下吗,18979508245(微信同号). 之前我做过其它项目的升级,过程我是清楚的,只是现在用了官方的bootloader,没有源码。不知道在bootloader中是怎么判断的,为什么没有执行从download中拷贝数据到app中。:( 先谢谢了!
zmmfly
zmmfly 2020-04-12
我用的ML302的模块,加上at_socket,用http_ota会出现获取http头时直接传输整个文件过来的问题,自己把http_ota改成用Range获取大小,然后Range分片下载解决的;

另外,bl中只要版本号不小于原有固件且CRC校验通过就会替换app分区,但是如果下载到download分区的数据CRC校验不通过,就不会替换app分区的内容,我是将at串口改为非DMA模式解决的,可能是DMA模式下接收不完整导致的
yc985055
yc985055 2020-04-12
zmmfly 发表于 2020-4-12 10:42
我用的ML302的模块,加上at_socket,用http_ota会出现获取http头时直接传输整个文件过来的问题,自己把http ...


升级文件都是rt_ota_packaging_tool生成的。我分别试过两种试试,AES打开或关闭,都一样。版本号是大于当前app中的版本。 至于你说的CRC校验问题,不清楚bl中是怎么校验的,我看download分区中的数据应该是正确的。 请教一下:第一次下载到app中的应用程序,需要用rt_ota_packaging_tool生成吗?
zmmfly
zmmfly 2020-04-12
yc985055 发表于 2020-4-12 11:13
升级文件都是rt_ota_packaging_tool生成的。我分别试过两种试试,AES打开或关闭,都一样。版本号是大于当 ...


[I]Verify 'download' partition(fw ver: 1.0.29, timestamp: 1586663416) success.
[I]OTA firmware(app) upgrade(1.0.28->1.0.29) startup.
[E]Verify downloaded firmware hash (calc.hash: 558ef7d6 != hdr.hash: c8b3c3d3) failed.
[E]OTA upgrade failed! Download data copy to partition(app) error!
[E]OTA upgrade failed!
[I]Verify 'app' partition(fw ver: 1.0.28, timestamp: 1586609590) success.


像这样就是crc错误;
第一次下载不用生成,直接keil中下载就可以,但是得注意把flash起始地址改为app分区的起始地址
yc985055
yc985055 2020-04-12
    本帖最后由 yc985055 于 2020-4-12 16:00 编辑


zmmfly 发表于 2020-4-12 11:55
像这样就是crc错误;
第一次下载不用生成,直接keil中下载就可以,但是得注意把flash起始地址改为app分 ...

1. 你贴出来的那6行没看到。 至于你提到的app下载地址我已经改过keil5中的link.sct文件,内容如下:
LR_IROM1 0x08008000 0x00080000 { ; load region size_region
ER_IROM1 0x08008000 0x00080000 { ; load address = execution address。 我的app地址是32K-bootloader之后的196K。(0x08008000-0x08039000) 2.担心自己AT下载文件错误,还对升级数据在存储前做了校验计算,每次下载后,得到的总校验值相同。所以判断数据存储确实没错。下面我再贴一些代码
/***************************************************************************************************
* @fn hw_upgrade_start(void)
*
* @brief erase flash
*
* @param
*
* @return none
****************************************************************************************************/
#include "fal.h"
const struct fal_partition *dl_part = RT_NULL;
static void hw_upgrade_start(void)
{

dl_part = fal_partition_find("download");
if (dl_part != RT_NULL)
{
if (fal_partition_erase(dl_part, 0, (rt_uint32_t)0x31000) < 0)
{
rt_kprintf("erase download partition error\r\n");
}
}

//stm32_flash_erase ((rt_uint32_t)INT_FLASH_DOWNLOAD_ADDR, 196 * 1024);

http_size_bytes = 0;
http_size_conts = 0;
http_size_conts_max = 0;
u16UdpCrc = 0;
}

/***************************************************************************************************
* @fn void hw_upgrade_data_save(rt_uint8_t *pDataBuf, rt_uint16_t dataLen)
*
* @brief save upgrade data to flash
*
* @param
*
* @return none
****************************************************************************************************/
static void hw_upgrade_data_save(rt_uint8_t *pDataBuf, rt_uint16_t dataLen)
{
rt_uint16_t tempU16 = 0;
tempU16 = dataLen;

//if (dataLen == stm32_flash_write((rt_uint32_t)INT_FLASH_DOWNLOAD_ADDR + (rt_uint32_t)(http_size_conts * HTTP_SIZE_PER_PKT), pDataBuf, dataLen))

if (dataLen == fal_partition_write(dl_part, (rt_uint32_t)(http_size_conts * HTTP_SIZE_PER_PKT), pDataBuf, dataLen))
{
http_size_conts++;
}

//计算校验,最后两字节是校验值,不参与运算
rt_kprintf("http_size_conts is-%d!!! %02x %02x\r\n", http_size_conts, pDataBuf[tempU16 - 2], pDataBuf[tempU16 - 1]);
if (tempU16 < HTTP_SIZE_PER_PKT)
{
tempU16 -= 2;
}
for (rt_uint16_t i = 0; i < tempU16; i++)
{
u16UdpCrc = hw_udp_pkt_run_poly(u16UdpCrc, pDataBuf
    );
    if (i < 32)
    {
    rt_kprintf("%02x ", pDataBuf
      );
      }
      }
      }

      #define
          INT_FLASH_DOWNLOAD_ADDR 0x39000

      我也用stm32_flash_erase ((rt_uint32_t)INT_FLASH_DOWNLOAD_ADDR, 196 * 1024); 和

      stm32_flash_write((rt_uint32_t)INT_FLASH_DOWNLOAD_ADDR + (rt_uint32_t)(http_size_conts * HTTP_SIZE_PER_PKT), pDataBuf, dataLen))擦除和写入过,也不是行。

yc985055
yc985055 2020-04-12
    本帖最后由 yc985055 于 2020-4-12 15:44 编辑


zmmfly 发表于 2020-4-12 11:55
像这样就是crc错误;
第一次下载不用生成,直接keil中下载就可以,但是得注意把flash起始地址改为app分 ...

如下是我串口打印信息:(http_size_bytes:升级文件总大小 http_size_conts:当前发送的第n个包 http_size_conts_max:总包数。 并且我打印了每个包的起始32字节数据, 也打印了校验值)
通过校验值来判断存储数据是否正确。

http_size_bytes 115682 http_size_conts:109 http_size_conts_max:113


http_size_conts is-110!!! bd 5c

0a a9 37 8c 2e b4 17 8a d0 e7 8d 9c ea b7 3d 3d ec 20 56 67 c8 8d cd ef a6 ad 58 27 91 12 65 9a
air_cur_status is 28

http_size_bytes 115682 http_size_conts:110 http_size_conts_max:113

http_size_conts is-111!!! 77 55

a4 9a cc a4 b0 3c 17 ab f3 18 51 d9 68 49 5e 4a e3 26 d1 29 cd 29 40 1d 9f 78 5a 53 73 b6 b4 6c
air_cur_status is 28

http_size_bytes 115682 http_size_conts:111 http_size_conts_max:113

http_size_conts is-112!!! 24 c0

69 01 6a 48 98 9b 63 3d ed 0b 7a 53 20 9e cd e5 a3 ba d4 ab b6 1e 29 25 25 01 73 af aa 49 1e 6c
air_cur_status is 28

http_size_bytes 115682 http_size_conts:112 http_size_conts_max:113


http_size_conts is-113!!! c9 53

23 b0 61 c8 47 ef 7e e8 dd e7 95 c5 be 2d 42 9d 3f bf 4c 50 27 d6 e6 eb f6 8a dd 1c 19 f7 2c 8b u16UdpCrc value is 6aeb


air_cur_status is 29


Powered by RT-Thread.
V0.9.2 build Apr 10 2020

[D/FAL] (fal_flash_init:63) Flash device | onchip_flash | addr: 0x08000000 | len: 0x00080000 | blk_size: 0x00000800 |initialized finish.
[I/FAL] =====OOOOOOOOOOOOOOO21乸artition 黙ble ====================[0?
[I/FAL] | name | flash_dev | offset | length |沎0m
[I/FAL] -------------------------------------------------------------
[I/FAL] | app | onchip_flash | 0x00008000 | 0x000310? |
[I/FAL] | download | o頲hip_flash | 0x00039000 | 竫00031000 ?[0m
[I/FAL] =========OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO?j5
[I/FAL] RT-Thread Flash Abstraction 靉yY.B擦.4.0) initialize success.
[I/FAL] System initialization successful.
[I]RT-Thread OTA package(V0.2.1) initialize success.
[E]Get firmware header occur CRC32(calc.crc: 048935b8 != hdr.info_crc32: b368a8鉧) error on 蛛贡絽憹 partition!
[E]Get OTA download partition firmware header failed!
[E]Get firmware header occur CRC32(calc.crc:?b93c5c8 != hdr.info_crc32: ffffffff) error on 'app' partition!
[I]Begin to exY?Wⅰ晛program on app partition.
[I/FAL] Find user firmware at app partition 0x08008000 successfully.
[I/FAL] Bootloader jumps to user firmware now.

\ | /
- RT - Thread Operating System
/ | \ 4.0.2 build Apr 12 2020
2006 - 2019 Copyright by rt-thread team

[D/FAL] (fal_flash_init:61)
Flash device | onchip_flash | addr: 0x08000000 | len: 0x00080000 | blk_size: 0x00000800 |initialized finish.
[I/FAL] ==================== FAL partition table ====================
[I/FAL] | name | flash_dev | offset | length |
[I/FAL] -------------------------------------------------------------
[I/FAL] | bl | onchip_flash | 0x00000000 | 0x00008000 |
[I/FAL]皘 app | onchip_flash | 0x00008000 | 0x00031000 |
[I/FAL] | download | onchip_flash | 0x00039000 | 0x00031000 |
[I/FAL] =============================================================
[I/FAL] RT-Thread Flash Abstraction Layer (V0.4.0) initialize success.
The current software version is :1.0.1

rt_hw_adc_register() failed

wdt device register success.
面码1314
面码1314 2020-04-12
yc985055 发表于 2020-4-12 08:15
我也是用HTTP的AT指令集进行下载升级文件的。上面描述中提到的官方参考是生成bootloader过程。 1. 先ST-L ...


我不是很明白现在你卡在了什么地方,我说下我在其中遇到的结果问题
1. 正如前面所说,如果直接使用AT指令下载,靠\r\n进行判断响应,因为固件信息中可能就会存在这样的数据干扰了判断。可以使用上面网友提供的一种方法解决
2. 检查自己串口接收的buf是不是足够大,因为我记得那个参数每次重新配置后,都会重新生成。
3. nable HTTP/HTTPS OTA选项都不用打开的
yc985055
yc985055 2020-04-12
    本帖最后由 yc985055 于 2020-4-12 16:37 编辑


面码1314 发表于 2020-4-12 16:03
我不是很明白现在你卡在了什么地方,我说下我在其中遇到的结果问题
1. 正如前面所说,如果直接使用AT指令 ...

我下载文件后,复位没任何提示。所以郁闷不知哪里配置不正确,问题出在何处。
串口RX-Buf 1.5K足够大,否则也接收显示不了httpread收到每个包1K数据。 1. 片内分区32K(boot)+196K(app)+196K(download) +其它参数区。 2. 擦除,及写入数据我也验证正确。
面码1314
面码1314 2020-04-12
yc985055 发表于 2020-4-12 16:33
我下载文件后,复位没任何提示。所以郁闷不知哪里配置不正确,问题出在何处。
串口RX-Buf 1.5K足够大,否 ...


有没有尝试过使用Ymodem 方式升级固件,使用 Xshell 终端,如果这样可以成功的话,可以排除固件上的错误和自己分区设置等等的错误情况
yc985055
yc985055 2020-04-12
    本帖最后由 yc985055 于 2020-4-12 19:07 编辑


面码1314 发表于 2020-4-12 18:07
有没有尝试过使用Ymodem 方式升级固件,使用 Xshell 终端,如果这样可以成功的话,可以排除固件上的错误 ...

没有,倒是提醒我了。明天用Xshel通过Ymodem试下。
小小李sunny
小小李sunny 2020-04-12
yc985055 发表于 2020-4-12 15:41
如下是我串口打印信息http_size_bytes:升级文件总大小 http_size_conts:当前发送的第n个包 http_siz ...

应该是你的download 区的数据有问题,不是正确的升级包 .rbl文件。CRC校验不通过,所以BootLoader无法去对比app区和download区的软件版本,也就没有去搬运download区到app区。
微信截图_20200412214643.png
小小李sunny
小小李sunny 2020-04-12
小小李sunny 发表于 2020-4-12 21:56
应该是你的download 区的数据有问题,不是正确的升级包 .rbl文件。CRC校验不通过,所以BootLoader无法去 ...


建议如果用ymodem_ota方式验证 打包工具生成的rbl文件没问题的话。就还是得查你download区的擦写操作是不是那各环节出错了,导致写入的文件不正确。
yc985055
yc985055 2020-04-13
小小李sunny 发表于 2020-4-12 22:07
建议如果用ymodem_ota方式验证 打包工具生成的rbl文件没问题的话。就还是得查你download区的擦写操作是不 ...


刚试了下,YMODEM_OTA下载升级没问题。升级后能显示正常版本,说明我的升级文件是可以的。 我找ymodem_ota的源码看下,对比自己存储数据有什么区别。
yc985055
yc985055 2020-04-14
面码1314 发表于 2020-4-12 18:07
有没有尝试过使用Ymodem 方式升级固件,使用 Xshell 终端,如果这样可以成功的话,可以排除固件上的错误 ...

都是这两个函数惹的祸:
resp = at_create_resp(HTTP_SIZE_PER_PKT + 56, 5, rt_tick_from_millisecond(300));
at_resp_get_line(httpReadResp, line_num)
我的升级包总共112 * 1024字节的包,其中第100个包中有个0x0D 0x0A, 开始 at_create_resp(HTTP_SIZE_PER_PKT + 56, 4, rt_tick_from_millisecond(300));0x0D 0x0A后面的数据全变成0x00 0x00 0x00. 后面我改为at_create_resp(HTTP_SIZE_PER_PKT + 56, 5, rt_tick_from_millisecond(300));返回时取数据,它又把0x0D 0x0A转换成0x0D 0x00啦,这样数据校验还是不过。 总之是使用这两个函数时. 数据区存在0x0D 0x0A搞出来的问题。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友