OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 49328|回复: 66

STM32网络远程升级固件的IAP程序实现与解析 ---附亲测稳定能用的程序

  [复制链接]

16

主题

216

帖子

1

精华

高级会员

Rank: 4

积分
970
金钱
970
注册时间
2016-11-24
在线时间
156 小时
发表于 2017-6-27 15:22:54 | 显示全部楼层 |阅读模式
本帖最后由 lzq12 于 2017-6-27 15:22 编辑

          本文主要对STM32网络升级固件的IAP程序进行解析,也就是在STM32联网的情况下在浏览器上输入指定的IP地址(目前设置为192.168.1.101),然后在浏览器上输入用户名和密码,登陆后可以选择需要升级的bin文件进行固件升级。以下是目前该程序应用的硬件与软件环境:
         1.硬件:STM32F407(理论上STM32系列都可以),网卡芯片LAN8720,其他部分参考正点原子的STM32F407探索者开发板。
         2.软件:Keil5 ,LWIP1.4.1 主要是基于正点原子STM32F407探索者的第六十章网络通信实验程序与第五十五章串口IAP实验程序(这部分只用到了跳转和烧写FLASH程序)。
           说明:该程序与我之前编写的《STM32F407通过SD卡进行程序升级(把bin文件烧写到FLASH的方式)》程序整合起来就可以实现SD卡+网络升级,即可以通过SD卡进行程序升级,如果升级失败自动跳转 去进行网络升级,也可以直接进行网络升级。目前该程序可以应用在项目上,网络升级和SD卡升级均稳定无差错。该程序的网络升级大概需要15秒钟(从点击<上传>到程序升级成功)。
         STM32F407通过SD卡进行程序升级(把bin文件烧写到FLASH的方式)》本论坛的链接:http://www.openedv.com/forum.php?mod=viewthread&tid=90835                以下先对网络升级部分的操作步骤进行解说,后面再贴上各个C文件的程序。
一、网络升级的主要实现过程
       按住K1键开机,自动进入网络升级模式(进入网络升级模式的方法不一定是要按下K1,可以自己编写条件,比如SD卡升级失败后就进入网络升级模式),然后在浏览器上输入192.168.1.101登陆页面

登陆界面.jpg

        输入用户名和密码(用户名和密码都是admin)之后,点击<登陆>进入文件升级界面,选择升级的bin文件然后点击<上传>进行升级

选择升级文件界面.jpg
更新成功.jpg
             本程序已经通过测试,网络升级不会有错乱,程序中会对升级的bin文件的文件名与文件的合法性进行校验,其中网络IP、用户名、密码、文件名均可在程序里自行更改。
二、网页界面的HTML代码编写
          网页界面不是用他人那种把网页界面转成数组然后存放在程序里调用的方式,用的是直接编写HTML代码的方式,简单直观而且可以任意修改,登陆界面和文件升级界面都可以自己修改,可以看函数http_write_loginweb()和http_write_updatebinweb(),效果如上图的登陆界面和文件升级界面。
//用户和密码登陆WEB界面的HTML内容代码填充
voidhttp_write_loginweb(char *pbuff, int *ppos,int error)
{
      *ppos += sprintf(pbuff + *ppos,"<HTML><META HTTP-EQUIV = \"Pragma\"CONTENT=\"no-cache\">");
      http_write_script(pbuff,ppos,error);
      *ppos += sprintf(pbuff + *ppos,"<BODY onload=doLoad();>\r\n");
      *ppos += sprintf(pbuff + *ppos,"<FORM METHOD=POST ACTION=\"/checklogin.cgi\">");

      //添加WEB界面的内容
      *ppos += sprintf(pbuff + *ppos,"<strong>用户名</strong><input type=\"text\"size=\"20\" name=\"username\">");
      *ppos += sprintf(pbuff + *ppos,"<strong>密码</strong><input type=\"password\"size=\"20\" name=\"password\">");
      *ppos += sprintf(pbuff + *ppos,"<BR><input type=\"submit\" name=\"login\"value=\"登陆\">");

      *ppos += sprintf(pbuff + *ppos,"</FORM></BODY></HTML>");
}
//选择升级程序WEB界面的HTML内容代码填充
void http_write_updatebinweb(char *pbuff, int *ppos,int error)
{
  *ppos += sprintf(pbuff +*ppos, "<HTML><META HTTP-EQUIV = \"Pragma\"CONTENT=\"no-cache\">");
  http_write_script(pbuff,ppos,error);
  *ppos += sprintf(pbuff +*ppos, "<BODY onload=doLoad();>\r\n");
  *ppos += sprintf(pbuff +*ppos, "<FORM METHOD=POST enctype=\"multipart/form-data\"ACTION=\"/update.cgi\">");

  //添加WEB界面的内容
  *ppos += sprintf(pbuff +*ppos, "<TD><input name=\"upbin\"id=\"upbin\" type=\"file\"></TD>");
  *ppos += sprintf(pbuff +*ppos, "<TD> <INPUT name=\"subbin\"class=\"button\" id=\"subbin\" type=\"submit\"value=\"上传\"></TD>");
  *ppos += sprintf(pbuff +*ppos, "</FORM></BODY></HTML>");
}
网页界面还可以做得更美观,但这个就要学一些HTML编程了,由于对HTML不是特别熟练,所以对于HTML部分就不做过多解析了。关于网络解析部分,可以直接看httpd.chttpd_cgi_ssi.c
三、登陆界面的POST指令解析
         网络升级主要用到POST指令,这个需要先了解一下POST指令相关的内容,还有就是CGI的解析,也用到了POST指令下发数据,但和GET的CGI解析方法一样,关于SSI、CGI及GET和POST指令可以看我写的《STM32 网络通信Web Server中 SSI与CGI的应用解析》,本论坛链接:http://www.openedv.com/forum.php?mod=viewthread&tid=104581&extra=。用到CGI的部分主要是在输入用户名和密码之后,点击登陆时,会下发POST指令,这时需要对POST指令进行解析,该POST指令数据通过软件Wireshark来查看,首先打开Wireshark,选择本地连接

1.jpg



           然后在地址栏输入 ip.addr == 192.168.1.101,然后按右边的箭头开始接收数据[size=14.6667px]

2.jpg

          关于解析的过程就是把POST指令找出来,然后执行相应的程序,比如对比用户名和密码等。接下来先看输入用户名和密码,按下<登陆>之后,浏览器下发的POST指令数据:

POST.jpg

           POST指令很明显就是由字符串”POST /XXXXX.cgi”开头,而这个CGI现在是checklogin.cgi,这个可以看函数http_write_loginweb()里面的HTML代码,
"<FORMMETHOD=POST ACTION="/checklogin.cgi">",这个HTML的意思是该form表单是通过post指令的方式下发数据,并由checklogin.cgi进行响应(本人HTML也是很菜,目前就这么理解吧)。
           开启POST指令需要定义#defineLWIP_HTTPD_SUPPORT_POST   1
           然后编写接收和解析POST指令的三个函数:
err_thttpd_post_begin(void *connection, const char *uri, const char *http_request,
                       u16_t http_request_len, intcontent_len, char *response_uri,
                       u16_t response_uri_len,u8_t *post_auto_wnd)
{
#ifLWIP_HTTPD_CGI
  int i = 0;
#endif
structhttp_state *hs = (struct http_state *)connection;
if(!uri || (uri[0] == '\0')) {
    return ERR_ARG;
}
hs->cgi_handler_index = -1;   // 此变量为本人自己在struct http_state 添加 用于保存CGI handler 索引为-1表示无CGI handler索引
hs->response_file = NULL; // 此变量为本人自己在struct http_state 添加 用于保存 CGI handler 处理完后返回的响应uri.
#ifLWIP_HTTPD_CGI
  if (g_iNumCGIs && g_pCGIs) {
    for (i = 0; i < g_iNumCGIs; i++) {
      if (strcmp(uri, g_pCGIs.pcCGIName) ==0) {
hs->cgi_handler_index = i; // 找到响应的 CGI handler 将其保存在cgi_handler_index 以便在httpd_post_receive_data中使用
         break;
       }
    }
  }
  if(i == g_iNumCGIs) {
    return ERR_ARG; // 未找到CGI handler
  }
#endif
  return ERR_OK;
}
#defineLWIP_HTTPD_POST_MAX_PAYLOAD_LEN    512//MEM2_MAX_SIZE//512
static char http_post_payload[LWIP_HTTPD_POST_MAX_PAYLOAD_LEN];//主要是存放参数值,如username=admin&password=admin&login=%B5%C7%C2%BD
static u32_thttp_post_payload_len = 0;
err_thttpd_post_receive_data(void *connection, struct pbuf *p)
{
    struct http_state *hs = (struct http_state*)connection;
    struct pbuf *q = p;
    int count;
    u32_t http_post_payload_full_flag = 0;
    while(q != NULL)  // 缓存接收的数据至http_post_payload
    {   
      if(http_post_payload_len + q->len<= LWIP_HTTPD_POST_MAX_PAYLOAD_LEN) {
          MEMCPY(http_post_payload+http_post_payload_len,q->payload, q->len);
          http_post_payload_len += q->len;
      }
      else { // 缓存溢出 置溢出标志位
        http_post_payload_full_flag = 1;
        break;
      }
      q = q->next;
    }
    pbuf_free(p); // 释放pbuf
    if(http_post_payload_full_flag) // 缓存溢出 则丢弃数据
    {
        http_post_payload_full_flag = 0;
        http_post_payload_len = 0;
        hs->cgi_handler_index = -1;
        hs->response_file = NULL;
    }
    else if(hs->post_content_len_left == 0){  // POST数据已经接收完毕则处理
        if(hs->cgi_handler_index != -1) {
            count = extract_uri_parameters(hs,http_post_payload);  // 解析
            hs->response_file =g_pCGIs[hs->cgi_handler_index].pfnCGIHandler(hs->cgi_handler_index,count, hs->params,
                                            hs->param_vals); // 调用解析函数
            http_post_payload_len = 0;
        }      
        else {
            hs->response_file = NULL;
            http_post_payload_len = 0;
        }
    }
    return ERR_OK;
}
voidhttpd_post_finished(void *connection, char *response_uri, u16_tresponse_uri_len)
{
      struct http_state *hs = (struct http_state*)connection;
    if(hs->response_file != NULL) {
        strncpy(response_uri,hs->response_file,response_uri_len); // 拷贝uri 用于给浏览器响应相应的请求
    }
}
             这三个函数有多种写法,基本思路就是把抽离出来后的数据,如username=admin&password=admin&login=%B5%C7%C2%BD,再把相应的数据存起来,比如把username存入hs->params[0]中,把admin存入hs->param_vals[0],具体看函数extract_uri_parameters()
四、文件升级界面的POST指令解析
          对下发升级文件数据的POST指令进行解析这部分用不到上面的三个函数,所以是在函数http_recv()里面直接对POST指令进行接收和解析。先看文件升级界面的HTML代码,该代码是函数http_write_updatebinweb()实现。
          在这个HTML中,FORM表单的代码和其他的不一样,这个要注意:<FORMMETHOD=POST enctype="multipart/form-data"ACTION="/update.cgi">其实就是添加了enctype="multipart/form-data"编码方式,这个主要是用于下发文件数据。
          在选择好文件之后,点击<上传>,浏览器就开始下发POST指令以及升级文件的数据。
          需要注意的是,#define PBUF_POOL_BUFSIZE       1600这个大小不能太小,因为一帧数据最大是1514,小于1514会导致接收到的数据出现错误。
            POST指令数据的解析可以分为三个步骤:
            第一步是接收到下发数据的POST指令,POST指令的数据开头为"POST/update.cgi",后面跟上一堆数据,这个可以通过软件Wireshark来查看[size=14.6667px]

升级的第一帧POST指令.jpg

          找到这个POST指令头之后,接着找"boundary="这个字符串,这个字符串后面跟着39个字符”---------------------------------7e17132213f8”(长度和字符有可能是变化的),后面的39个字符是用来判断下发的文件数据的截止位置(我们叫它B),我们把这些字符串先叫boundarystring。接下来还要找"Content-Length: "这个字符串,这个字符串后面的数据是指接下来还要接收的数据量,也就是总的数据量:361774。当然这个总数据量不等于升级文件的数据量,所以才需要boundarystring来判断。
            接下来是找"octet-stream"字符串,这个字符串后面跟着的就是升级文件的真正数据了,所以这个是用来判断接收文件数据的起始位置,我们叫它A
[size=14.6667px]

升级的第二帧POST指令.jpg

            那么第一步可以说完成了,我们需要找到真正的升级文件的数据可以理解为找到A和B之间的数据,并且把这些数据收集起来。

升级的最后一帧POST指令.jpg


         所以第二步就是把文件数据收集起来放到数组mem2base[],这个数组是存于外部SRAM中。
         第三步就是把数组mem2base[]里面的数据进行校验,然后把数据烧写入FLASH中。
         以上三步的实现过程可以看httpd.c里面的函数http_recv()

           按照以上的思路,只要把SD卡升级的部分加上,那就可以实现SD卡+网络升级,具体的工程文件就不贴上来了,就贴几个主要的C文件。感兴趣的朋友还可以对W25Q128这个FLASH芯片进行系统文件升级,原理是一样,16M的文件升级也是稳定无误。目前经过测试这个网络升级程序能够稳定运行,15秒左右就能升级完毕,而且对W25Q128升级16M系统文件也完全没有问题(程序上稍加修改就可以),2分钟左右就能升级完成。

STM32 网络远程升级固件的IAP程序实现与解析.zip

30.57 KB, 下载次数: 3451

主要的C文件

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
358
金钱
358
注册时间
2015-11-8
在线时间
52 小时
发表于 2018-2-27 23:59:02 | 显示全部楼层
精神可嘉,分析透彻!

但是给你个建议,这种WEB方式更新固件只适合设备数量少的场合,几百台设备要升级能把你累死在现场。
其次虽然端口映射可以实现穿透内网,但是在项目上基本上不可行,因为客户不会让你去动他们的路由器,你让客户给你映射一堆端口一般网管也不会配合你,客户越大越难实施。
最后WEB方式占用空间较大,浪费空间。且设备要一直后台运行WEB服务,影响效率。
最最后,你要考虑BIN文件的安全性,不做加密发布出去,别人抄板下载你的BIN就能直接销售了。
回复 支持 3 反对 1

使用道具 举报

16

主题

216

帖子

1

精华

高级会员

Rank: 4

积分
970
金钱
970
注册时间
2016-11-24
在线时间
156 小时
 楼主| 发表于 2017-6-28 08:56:52 | 显示全部楼层

目前只在局域网测试,外网没有机会试,哪位有机会可以试试外网反馈一下
回复 支持 反对

使用道具 举报

14

主题

1592

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
2622
金钱
2622
注册时间
2014-7-17
在线时间
350 小时
发表于 2017-6-28 09:19:33 | 显示全部楼层
赞!!!!
回复 支持 反对

使用道具 举报

16

主题

216

帖子

1

精华

高级会员

Rank: 4

积分
970
金钱
970
注册时间
2016-11-24
在线时间
156 小时
 楼主| 发表于 2017-6-28 10:05:20 | 显示全部楼层
yklstudent 发表于 2017-6-28 10:01
你板子IP可以通过外网访问????????

我的这个还机会没试过,不过据说其他项目的STM32板子是可以通过外网访问的
回复 支持 反对

使用道具 举报

30

主题

158

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1525
金钱
1525
注册时间
2015-11-11
在线时间
163 小时
发表于 2017-6-28 12:07:29 | 显示全部楼层
好东西,试试
好好学习
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2017-6-14
在线时间
4 小时
发表于 2017-6-28 13:05:54 | 显示全部楼层
谢谢!
回复 支持 反对

使用道具 举报

16

主题

216

帖子

1

精华

高级会员

Rank: 4

积分
970
金钱
970
注册时间
2016-11-24
在线时间
156 小时
 楼主| 发表于 2017-7-4 09:58:31 | 显示全部楼层

试过之后,要是碰到什么BUG,记得也分享一下哈
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
108
金钱
108
注册时间
2014-5-20
在线时间
23 小时
发表于 2017-11-28 17:38:27 | 显示全部楼层
楼主你的工程生成的文件有多大呢,单独SD IAP的话,BIN文件可以,但是加上LWIP后,BIN文件还是很大的啊!
回复 支持 反对

使用道具 举报

42

主题

297

帖子

0

精华

高级会员

Rank: 4

积分
994
金钱
994
注册时间
2016-7-22
在线时间
318 小时
发表于 2017-12-13 12:53:45 | 显示全部楼层
lzq12 发表于 2017-6-28 08:56
目前只在局域网测试,外网没有机会试,哪位有机会可以试试外网反馈一下

来来来 我帮你
回复 支持 反对

使用道具 举报

42

主题

297

帖子

0

精华

高级会员

Rank: 4

积分
994
金钱
994
注册时间
2016-7-22
在线时间
318 小时
发表于 2017-12-13 12:55:03 | 显示全部楼层
lzq12 发表于 2017-6-28 10:05
我的这个还机会没试过,不过据说其他项目的STM32板子是可以通过外网访问的

通过路由器做端口映射就好了
回复 支持 反对

使用道具 举报

15

主题

118

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3059
金钱
3059
注册时间
2015-12-20
在线时间
299 小时
发表于 2017-12-19 09:57:04 | 显示全部楼层
好东西啊,赞一个!
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2017-9-22
在线时间
8 小时
发表于 2017-12-27 14:45:18 | 显示全部楼层
是用POST到设备的服务器,设备再解析吗?那设备的IP怎么连,设备的IP只是路由器映射出来的吧,求教
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2017-9-22
在线时间
8 小时
发表于 2017-12-27 14:48:03 | 显示全部楼层
hi我歌月徘徊 发表于 2017-12-13 12:55
通过路由器做端口映射就好了


是用POST到设备的服务器,设备再解析吗?那设备的IP怎么连,设备的IP只是路由器映射出来的吧,求教,我的设备是可以通过路由器连外网的,如果要升级只能设备去访问一个固定IP了吗
回复 支持 反对

使用道具 举报

42

主题

297

帖子

0

精华

高级会员

Rank: 4

积分
994
金钱
994
注册时间
2016-7-22
在线时间
318 小时
发表于 2017-12-28 10:09:21 | 显示全部楼层
SL2101 发表于 2017-12-27 14:48
是用POST到设备的服务器,设备再解析吗?那设备的IP怎么连,设备的IP只是路由器映射出来的吧,求教,我 ...

加个Q聊 778575669
回复 支持 反对

使用道具 举报

6

主题

315

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1665
金钱
1665
注册时间
2018-1-29
在线时间
159 小时
发表于 2018-2-26 05:46:39 | 显示全部楼层
感谢大神分享代码!
回复 支持 反对

使用道具 举报

95

主题

549

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3293
金钱
3293
注册时间
2016-1-7
在线时间
541 小时
发表于 2018-3-2 09:25:28 | 显示全部楼层
感谢分享!
回复 支持 反对

使用道具 举报

6

主题

119

帖子

0

精华

高级会员

Rank: 4

积分
712
金钱
712
注册时间
2015-11-26
在线时间
139 小时
发表于 2018-3-2 10:53:17 | 显示全部楼层
我做过http get方法进行远程升级   GPRS和lan都做过    服务端后台远程推送升级   设备收到推送后会自动下载 自动完成升级   可以实现大批量同时升级
回复 支持 反对

使用道具 举报

19

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
358
金钱
358
注册时间
2015-11-8
在线时间
52 小时
发表于 2018-3-5 17:20:25 | 显示全部楼层
hanzixi_angel 发表于 2018-3-2 10:53
我做过http get方法进行远程升级   GPRS和lan都做过    服务端后台远程推送升级   设备收到推送后会自动下 ...

设备在内网,服务器推送,端口映射?
回复 支持 反对

使用道具 举报

1

主题

42

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
320
金钱
320
注册时间
2017-7-5
在线时间
96 小时
发表于 2018-3-5 18:16:05 | 显示全部楼层
谢谢分享~~~~~~~~~~有空慢慢学习~~~~
回复 支持 反对

使用道具 举报

6

主题

119

帖子

0

精华

高级会员

Rank: 4

积分
712
金钱
712
注册时间
2015-11-26
在线时间
139 小时
发表于 2018-3-6 10:56:31 | 显示全部楼层
lg75 发表于 2018-3-5 17:20
设备在内网,服务器推送,端口映射?

设备在内网外网无所谓  只要能连上外网就行   http嘛  推送是通过mqtt
回复 支持 反对

使用道具 举报

19

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
358
金钱
358
注册时间
2015-11-8
在线时间
52 小时
发表于 2018-3-7 08:36:09 | 显示全部楼层
hanzixi_angel 发表于 2018-3-6 10:56
设备在内网外网无所谓  只要能连上外网就行   http嘛  推送是通过mqtt

学无止境,请教一下,如果是服务器主动“推送”,那发起升级请求的应该是服务器吧,所以我才会问端口映射的问题,按照你的回复,我觉得应该是设备方首先发起请求,服务器收到后再应答才对吧?
回复 支持 反对

使用道具 举报

6

主题

119

帖子

0

精华

高级会员

Rank: 4

积分
712
金钱
712
注册时间
2015-11-26
在线时间
139 小时
发表于 2018-3-7 11:17:22 | 显示全部楼层
lg75 发表于 2018-3-7 08:36
学无止境,请教一下,如果是服务器主动“推送”,那发起升级请求的应该是服务器吧,所以我才会问端口映射 ...

主动方在于服务器   设备端只是接收推送并执行升级  至于端口映射问题都是服务端解决的 具体解决方案不太清楚  可以用花生壳自己映射一下   我们是企业服务器  用的也是第三方的
回复 支持 反对

使用道具 举报

20

主题

169

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1012
金钱
1012
注册时间
2017-7-27
在线时间
162 小时
发表于 2018-3-30 10:17:40 | 显示全部楼层
楼主想问一下跳转的过程有关闭所有外部中断吗?我只有关闭所有外部中断才可以正常跳转,但是这样的话APP里面所有外部中断都打不开了???
回复 支持 反对

使用道具 举报

37

主题

595

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1572
金钱
1572
注册时间
2017-7-17
在线时间
308 小时
发表于 2018-4-10 14:25:11 | 显示全部楼层
本帖最后由 candylife9 于 2019-11-6 09:42 编辑

我觉得,单片机的二进制代码都很小,一两秒的时间就可以下完了,什么协议无所谓。
回复 支持 反对

使用道具 举报

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
108
金钱
108
注册时间
2017-7-7
在线时间
35 小时
发表于 2018-4-27 17:21:56 | 显示全部楼层
ZAN赞赞   谢谢分享
回复 支持 反对

使用道具 举报

3

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
443
金钱
443
注册时间
2016-7-11
在线时间
84 小时
发表于 2018-5-14 10:59:23 | 显示全部楼层
有调通的吗?为什么我进入登录界面然后输入密码在checklogin.cgi就卡死了 啊
回复 支持 反对

使用道具 举报

12

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2013-10-27
在线时间
34 小时
发表于 2018-5-14 18:12:02 | 显示全部楼层
正需要,试试看
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2018-5-15
在线时间
1 小时
发表于 2018-5-15 18:59:38 | 显示全部楼层
你好,能不能给我发一份你的网络IAP完整的工程文件?我想系统的学习一下。974370320@qq.com
回复 支持 反对

使用道具 举报

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
发表于 2018-6-21 10:52:27 | 显示全部楼层
挺厉害的,网络iap应用在什么场景呢
回复 支持 反对

使用道具 举报

10

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
362
金钱
362
注册时间
2018-5-14
在线时间
46 小时
发表于 2018-8-1 16:58:40 | 显示全部楼层
好贴 码下来 有空试试
行至水穷处 坐看云起时
回复 支持 反对

使用道具 举报

4

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2018-6-27
在线时间
45 小时
发表于 2018-8-2 16:02:51 | 显示全部楼层
用这样的方式,更新STM32中的FLASH数据应该比较方便
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2018-7-11
在线时间
11 小时
发表于 2018-8-2 17:06:29 | 显示全部楼层
感谢分享 学习了
回复 支持 反对

使用道具 举报

42

主题

297

帖子

0

精华

高级会员

Rank: 4

积分
994
金钱
994
注册时间
2016-7-22
在线时间
318 小时
发表于 2018-8-25 14:21:30 | 显示全部楼层
请教楼主
)Y[GT$SH8KPWDHJS3S`X7KC.png

问题1:串口调试助手明明收到多个包,为何wireshark只显示一个呢?但是数据长度是对的。看楼主的截图 好像也只有一个包啊~~
问题2:在详细阅读了楼主的httpd.c文件后
发现 Content-Length: 285705\r\n  这个字段 就是实际bin文件大小啊,但是楼主却声明了 ContentSize = Parse_Content_Length(data, p->tot_len);//查找"Content-Length: "这个字符串,并且得出数据大小,该数据为后面需要接收的数据大小(不是升级文件的大小),我在http_recv函数中加了打印,每次收到一个升级文件包的时候都有打印这个字段 是一个定值,看一下我的bin文件属性 大小 278 KB (285,412 字节),占用空间 280 KB (286,720 字节) 和我抓包抓到的Content-Length: 285705\r\n 都有出入 不知以那个为准?
问题3:判断bin文件的最后一包 ,不太明白
原文:通过"boundary="这个字符串 这个字符串后面跟着39个字符”---------------------------------7e17132213f8”(长度和字符有可能是变化的),后面的39个字符是用来判断下发的文件数据的截止位置(我们叫它B),我们把这些字符串先叫boundarystring
根据楼主的截图 在数据的开始 boundary=---------------------------------7e17132213f8,在数据包的结束的时候发现了7e17132213f8这个标志,所以代表bin文件完整的发送完成了,对吧?
观察下我的数据包中,数据开始boundary=----WebKitFormBoundaryzqrobIiHdQpRe6v8\r\n
2}AME4}}IVB3~KB`@WF{{~G.png
数据包的结束
~WY79_UL0Z3%1OC)OP}]H_O.png
好像没什么问题,但是到最后输出的错误代码
else if(TotalReceived > ContentSize)//接收的数据统计 > 大于了文件的大小(ContentSize字段)
{
        printf("bin文件更新失败!\r\n");

}
在文件的2435行
else if ((DataFlag ==1)&&(BrowserFlag==1))//第2包需要去找到升级文件的数据地址(地址偏移)
这个if里面的代码从来没有执行过,感觉有点疑惑,不知是不是导致最后问题的原因。

代码都是楼主的,我只是增加了一些printf函数方便分析,但是最后出的问题 希望楼主帮助分析下
0_~2OH@7V_J%OGC$PU4Y}KJ.png
回复 支持 反对

使用道具 举报

37

主题

595

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1572
金钱
1572
注册时间
2017-7-17
在线时间
308 小时
发表于 2018-9-29 22:57:54 | 显示全部楼层
本帖最后由 candylife9 于 2019-11-6 09:44 编辑

可以啊,我自己也录制了一个STM32战舰V3开发板做的FTP远程升级代码的视频,带演示的,卤煮可以参考,https://sharing-iot.com/course/detail/63.html。祝楼主成功
回复 支持 反对

使用道具 举报

12

主题

76

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
231
金钱
231
注册时间
2018-6-15
在线时间
33 小时
发表于 2018-10-15 14:18:59 | 显示全部楼层
楼主,我现在也正在弄这块内容,能否分享下详细的工程资料参考下,感激  931641616@qq.com
回复 支持 反对

使用道具 举报

0

主题

91

帖子

0

精华

初级会员

Rank: 2

积分
177
金钱
177
注册时间
2018-9-27
在线时间
15 小时
发表于 2018-10-16 09:54:03 | 显示全部楼层
谢谢搂猪分享
回复 支持 反对

使用道具 举报

12

主题

76

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
231
金钱
231
注册时间
2018-6-15
在线时间
33 小时
发表于 2018-10-18 16:00:00 | 显示全部楼层
楼主,上线了,请关注我下,急急急
回复 支持 反对

使用道具 举报

4

主题

116

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3799
金钱
3799
注册时间
2017-11-15
在线时间
314 小时
发表于 2018-10-19 09:19:53 | 显示全部楼层
lg75 发表于 2018-2-27 23:59
精神可嘉,分析透彻!

但是给你个建议,这种WEB方式更新固件只适合设备数量少的场合,几百台设备要升级 ...

传bin文件,产品里加上根据UID输入解锁码的功能是不是要好一点?
www.littlebutler.top
回复 支持 反对

使用道具 举报

8

主题

55

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2017-1-14
在线时间
48 小时
发表于 2018-10-23 20:56:17 | 显示全部楼层
都是大神!小白膜拜中....
回复 支持 反对

使用道具 举报

4

主题

35

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2013-9-4
在线时间
133 小时
发表于 2018-11-9 17:29:34 | 显示全部楼层
谢谢楼主的分享
努力工作,快乐生活
回复 支持 反对

使用道具 举报

1

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2019-4-27
在线时间
19 小时
发表于 2019-5-11 15:13:21 | 显示全部楼层
收藏一下随便看看别人的评论。虽然端口映射可以实现穿透内网,但是在项目上基本上不可行,因为客户不会让你去动他们的路由器,你让客户给你映射一堆端口一般网管也不会配合你,客户越大越难实施,WEB方式占用空间较大,浪费空间。且设备要一直后台运行WEB服务,影响效率。
回复 支持 反对

使用道具 举报

0

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2016-4-21
在线时间
70 小时
发表于 2019-6-3 14:26:13 | 显示全部楼层
感谢楼主分享,使用了你的http iap文件,已经提示更新工程,但遇到了问题,请教一下。提示更新成功后再网页中点重启后死机,debug跟踪到jump2app()调用后进入硬件错误中断,用jlink将app程序直接下载到板子上通过app引导可以正常运行。很奇怪的问题......httpd.c未做任何改动!
回复 支持 反对

使用道具 举报

5

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2017-7-28
在线时间
28 小时
发表于 2019-6-4 12:27:48 | 显示全部楼层
优秀。。。
回复 支持 反对

使用道具 举报

2

主题

474

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6077
金钱
6077
注册时间
2018-6-27
在线时间
524 小时
发表于 2019-7-5 15:38:21 | 显示全部楼层
学习学习,学习学习。
回复 支持 反对

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2019-6-5
在线时间
8 小时
发表于 2019-7-11 14:02:04 | 显示全部楼层
不错   很好
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2018-12-7
在线时间
14 小时
发表于 2019-10-1 15:12:34 | 显示全部楼层
感谢楼主分享,能否分享下详细的工程资料参考下,感激  1451594960@qq.com
回复 支持 反对

使用道具 举报

37

主题

595

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1572
金钱
1572
注册时间
2017-7-17
在线时间
308 小时
发表于 2019-11-6 09:13:54 | 显示全部楼层
感谢楼主码了这么多字,学习了。另外我自己使用原子哥的战舰开发板录制了一个STM32F103xE利用FTP服务器远程升级的视频,带演示和课程资料,很简洁,总共半小时不到,大家可以前往https://sharing-iot.com/course/detail/63.html,进行观看。
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2019-11-11
在线时间
9 小时
发表于 2020-3-18 09:30:20 | 显示全部楼层
想问下,如果成本考虑,没有外部sram,只有内部sram的情况下,但是大小又不够一次接收完整的包,该怎么处理??
回复 支持 反对

使用道具 举报

1

主题

14

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2020-3-19
在线时间
3 小时
发表于 2020-3-19 15:14:26 | 显示全部楼层
经典好文,感谢楼主分享,下载下来学习一下!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 09:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表