精华内容
下载资源
问答
  • 实现网络升级stm32 实现协议为tftp http,可以远程升级
  • STM32网络升级app程序

    2017-07-17 11:04:49
    STM32 网络APP示例,采用W5500作为网络的硬件接口,通过网络实现远程升级
  • 说明:该程序与我之前编写的《STM32F407通过SD卡进行程序升级(把bin文件烧写到FLASH的方式)》程序整合起来就可以实现SD卡+网络升级,即可以通过SD卡进行程序升级,如果升级失败自动跳转 去进行网络升级,也可以...
  • 源:STM32+IAP方案 实现网络升级应用固件 IAR + STM32固件库 启动文件startup_stm32f10x_hd.s功用及注释
    展开全文
  • 在上一篇中,介绍了基于移远BC28的STM32+NB-IOT的OTA案例分享,以移远BC28+STM32L053C8为例,来演示如何利用艾拉比的差分技术通过NB网络升级STM32的APP固件,详见:基于移远BC28的STM32+NB-IOT的OTA案例分享 ...

    STM32L452RE的差分升级能力构建

    STM32单片机
    在上一篇中,介绍了基于移远BC28的STM32+NB-IOT的OTA案例分享,以移远BC28+STM32L053C8为例,来演示如何利用艾拉比的差分技术通过NB网络升级STM32的APP固件,详见:基于移远BC28的STM32+NB-IOT的OTA案例分享

    本案例将展示,在STM32L452RE这颗MCU上如何将艾拉比的差分升级功能,移植入STM32L452RE的bootloader中,从而使STM32L452RE能够拥有差分升级的能力。

    差分升级的原理:

    差分算法的基本思想是求解新文件和老文件的差的最优解,并使用压缩算法生成差分包;升级时就可以在老文件的基础上应用差分包进行升级。用形象的图像表达如下:

    艾拉比一直致力于差分算法的研究和开发,并且独创了一种对差分中间数据混合打包压缩的技术。目前,艾拉比在该领域已经有三项国家发明专利。

    艾拉比算法特点:

    1. 自适应确定差分方向。
    2. 对于生成的中间数据使用艾拉比的 “整数数组的混合打包压缩技术”。
    3. 差分包体积小,比公开算法得到的差分包小30~90%。
    4. 升级速度快,升级的速度是公开算法的2至3倍。
    5. 资源消耗少,Lite版算法最低要求RAM 2KB。

    代码移植:

    我们通过STM32CubeMX生成STM32L452RE-Nucelo这个工程代码,然后我们在KEIL中打开这个工程。

    1. C文件移植:

    在STM32L452RE-Nucelo工程目录下新建Abup/HAL文件目录,abup_bl_main.c,adups_bl_main.c,adups_bl_flash.c,abup_hal_flash.c,abup_hal_uart.cabup_hal.c

    1. 库文件移植:

    1)添加默认库;2)选择库的版本;3)选择默认库脚本。

    1. 头文件路径添加:

    将…\Abup\inc,…\Abup\Wosun\inc,…\Abup\Wosun\inc\lzma, …\Abup\lusun\inc, …\Abup\inc\BL头文件路径加入项目工程头文件路径中。

    1. 代码的修改:

    main.c中添加如下代码

    1. 代码空间的配置:

    配置需同ABUP_FLASH_BASE_ADDR、ABUP_BL_SIZE等宏一致。

    差分包的制作:

    在代码移植完成后,我们需要制作差分包,并验证这个差分包是否能够升级成功。我们使用的是艾拉比的在线差分工作来这个差分包

    1.在KEIL中配置自动生成制作差分包使用的软件包

    abup.bat参数说明:第一个是生成bin工具目录,第二个是压缩工具目录,第三个是编译文件夹,生成压缩包名为:版本号_日期_时间.zip

    2.登录到艾拉比的差分工具,将目标版本和源版本两个软件包提交给查分工具,制作生成差分包。

    验证差分包:

    在差分包制作成功后,我们将差分包通过设备的联网能力下载到设备上,下载完成后软重启设备,进入Bootloader开始升级。

    同时我们也可以在串口工具中看到整个Bootloader运行升级程序的过程。

    当串口工具中打印出Update Suss后,表明升级成功。通过一系列工作我们也成功的为STM32L452RE构建了差分升级能力。

    特别感谢:艾拉比物联网研发部研发总监赵星和高级工程师沈瑞,对本篇文章做出的贡献!

    展开全文
  • 包含STM32F407LWIP+TFTP的IAP程序,应用程序APP,上位机软件。 文档说明:查找我的资源。
  • 使用STM32+W5500 OTA升级,一定会使用到服务器,可以考虑自己搭建一个,因为我并不是搞这一块的,但是觉得这个写的挺不错的,也挺简单的,所以上传了。
  • 本帖最后由 lzq12 于 2017-6-27 15:22 编辑本文主要对STM32网络升级固件的IAP程序进行解析,也就是在STM32联网的情况下在浏览器上输入指定的IP地址(目前设置为192.168.1.101),然后在浏览器上输入用户名和密码,登陆...

    本帖最后由 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 (7.73 KB, 下载次数: 22)

    2017-6-27 14:28 上传

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

    选择升级文件界面.jpg (6.32 KB, 下载次数: 30)

    2017-6-27 14:29 上传

    更新成功.jpg (19.53 KB, 下载次数: 25)

    2017-6-27 14:29 上传

    本程序已经通过测试,网络升级不会有错乱,程序中会对升级的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,"");

    http_write_script(pbuff,ppos,error);

    *ppos += sprintf(pbuff + *ppos,"

    \r\n");

    *ppos += sprintf(pbuff + *ppos,"

    ");

    //添加WEB界面的内容

    *ppos += sprintf(pbuff + *ppos,"用户名");

    *ppos += sprintf(pbuff + *ppos,"密码");

    *ppos += sprintf(pbuff + *ppos,"");

    *ppos += sprintf(pbuff + *ppos,"

    ");

    }

    //选择升级程序WEB界面的HTML内容代码填充

    void http_write_updatebinweb(char *pbuff, int *ppos,int error)

    {

    *ppos += sprintf(pbuff +*ppos, "");

    http_write_script(pbuff,ppos,error);

    *ppos += sprintf(pbuff +*ppos, "

    \r\n");

    *ppos += sprintf(pbuff +*ppos, "

    ");

    //添加WEB界面的内容

    *ppos += sprintf(pbuff +*ppos, "

    ");

    *ppos += sprintf(pbuff +*ppos, "

    ");

    *ppos += sprintf(pbuff +*ppos, "

    ");

    }网页界面还可以做得更美观,但这个就要学一些HTML编程了,由于对HTML不是特别熟练,所以对于HTML部分就不做过多解析了。关于网络解析部分,可以直接看httpd.c和httpd_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 (31.05 KB, 下载次数: 19)

    2017-6-27 14:36 上传

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

    2.jpg (24.98 KB, 下载次数: 16)

    2017-6-27 14:37 上传

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

    POST.jpg (202.58 KB, 下载次数: 25)

    2017-6-27 14:38 上传

    POST指令很明显就是由字符串”POST /XXXXX.cgi”开头,而这个CGI现在是checklogin.cgi,这个可以看函数http_write_loginweb()里面的HTML代码,

    "",这个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表单的代码和其他的不一样,这个要注意:其实就是添加了enctype="multipart/form-data"编码方式,这个主要是用于下发文件数据。

    在选择好文件之后,点击,浏览器就开始下发POST指令以及升级文件的数据。

    需要注意的是,#define PBUF_POOL_BUFSIZE       1600这个大小不能太小,因为一帧数据最大是1514,小于1514会导致接收到的数据出现错误。

    POST指令数据的解析可以分为三个步骤:第一步是接收到下发数据的POST指令,该POST指令的数据开头为"POST/update.cgi",后面跟上一堆数据,这个可以通过软件Wireshark来查看[size=14.6667px]

    升级的第一帧POST指令.jpg (219.08 KB, 下载次数: 21)

    2017-6-27 15:00 上传

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

    [size=14.6667px]

    升级的第二帧POST指令.jpg (192.26 KB, 下载次数: 15)

    2017-6-27 15:00 上传

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

    升级的最后一帧POST指令.jpg (169.47 KB, 下载次数: 18)

    2017-6-27 15:01 上传

    所以第二步就是把文件数据收集起来放到数组mem2base[],这个数组是存于外部SRAM中。

    第三步就是把数组mem2base[]里面的数据进行校验,然后把数据烧写入FLASH中。

    以上三步的实现过程可以看httpd.c里面的函数http_recv()。

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

    展开全文
  • 文档介绍。 程序请查找我的资源。
  • STM32远程升级基本思路

    千次阅读 2019-12-20 19:02:53
    STM32远程升级基本思路 开发环境:IAR for ARM 8.30.1 MCU:STM32F103RCT6 存储介质:w25q32 1.实现思路 1.需要一个bootloader程序和APP程序 2.APP程序通过网络或者串口等方式将要升级的代码写到spiFlash中约定的...

    STM32远程升级基本思路


    • 开发环境:IAR for ARM 8.30.1
    • MCU:STM32F103RCT6
    • 存储介质:w25q32

    1.实现思路

    1.需要一个bootloader程序和APP程序
    2.APP程序通过网络或者串口等方式将要升级的代码写到spiFlash中约定的位置,然后重启
    3.bootloader判断spiFlash中是否有文件需要更新,有就将文件更新到stm32的内部Flash的App区域,然后跳 转到APP,否则直接跳转

    2.知识储备

    STM32闪存模块组织

    stm32F103RCT6属于大容量型产品,ROM:256K,RAM:48K,页大小为2k,闪存分为三个块:

    • 主存储器:页大小为2K,256K也就是128页
    • 信息块:分为两个部分:
      • 系统存储器(存放启动程序代码,ST出厂固化,不可更改,用于ISP编程)
      • 用户选项字节(Option Bytes,可以用它设置读写保护,硬件看门狗使能啥的)
    • 闪存存储器接口寄存器:操作stm32内部Flash要用到这些寄存器;

    在这里插入图片描述

    启动配置

    在这里插入图片描述
    ● 从主闪存存储器启动:主闪存存储器被映射到启动空间(0x0000 0000)
    ● 从系统存储器启动:系统存储器被映射到启动空间(0x0000 0000)
    ● 从内置SRAM启动:只能在0x2000 0000开始的地址区访问SRAM

    3.Bootloader和App的工程设置

    Bootloader和App公用RAM,占用不同ROM空间,16K给Bootloader,240K给App

    • Bootloader:
      • Vector Table Start:0x0800 0000
      • ROM:0x0800 0000 ~ 0x0800 4000
      • RAM:0x0800 0000 ~ 0x0800 BFFF
      • CSTACK: 0x400
      • Heap: 0x0
    • App:
      • Vector Table Start:0x0800 4000
      • ROM:0x0800 4000 ~ 0x0803 FFFF
      • RAM:0x0800 0000 ~ 0x0800 BFFF
      • CSTACK: 0x400
      • Heap: 0x0
        App程序中还要注意到的地方:修改中断向量偏移VECT_TAB_OFFSET,偏移量就是bootloader程序大小
        在这里插入图片描述

    4.Bootloader程序编写

    话不多说,下面就是代码:

    • 头文件
    #define FLASH_MAX_ADDR                      (0x0803FFFFU)  //MCU的Flash最大地址
    
    #ifndef FLASH_PAGE_SIZE
      #define FLASH_PAGE_SIZE                   (0x800U)       //MCU的Flash的页大小,大容量的为2K,其他是1K
    #endif
    
    #define APP_BASEADDR                        (0x08004000U)  //升级程序地址
    
    
    #define APP_PAGE_NUM                        ((FLASH_MAX_ADDR-APP_BASEADDR)/FLASH_PAGE_SIZE+1)
    
    #define SPIFLASHBUF_MAX_LEN                 (0x1000U)  //spi flash最大缓冲4096字节
    
    • C文件
    void JumpToApplication(void)
    {
      typedef  void (*pFunction)(void);
      pFunction Jump_To_Application;
      u32 JumpAddress;    
      
      /* Test if user code is programmed starting from address "ApplicationAddress" */
      if (((*(__IO uint32_t*)APP_BASEADDR) & 0x2FFE0000 ) == 0x20000000)
      {
        
        DBG_LOG("----[Boot]Jump to Application!!!\r\n");
        LED_ALL_OFF();
        __disable_irq();
        
        /* Jump to user application */
        JumpAddress = *(__IO uint32_t*) (APP_BASEADDR + 4);
        Jump_To_Application = (pFunction) JumpAddress;
        /* Initialize user application's Stack Pointer */
        __set_MSP(*(__IO uint32_t*) APP_BASEADDR);
        Jump_To_Application();
      }
      else
      {
        DBG_LOG("----[Boot]Application Address is ERROR!!!\r\n");
        LED_ALL_ON();
      }    
    }
    
    union {
      u32 stm32[SPIFLASHBUF_MAX_LEN/4];
      u8  spi[SPIFLASHBUF_MAX_LEN];
    }Flash;
    
    void Boot_Initializes(void)
    {
    
      u16 i,j;
      
      u32 update_file_mark;
      
      u32 writeFlashData;
     
      HAL_StatusTypeDef status;
      
      FLASH_EraseInitTypeDef f;
      
    	f.TypeErase = FLASH_TYPEERASE_PAGES;
    	f.PageAddress = APP_BASEADDR;
    	f.NbPages = APP_PAGE_NUM;
    
      //1.判断spi flash DFU区是否有文件需要升级
      SFlash_Read(SECTOR_ADDR(SECTOR_DFU_START),(u8 *)&update_file_mark,4);
      
      if(update_file_mark == 0xFFFFFFFF){
        DBG_LOG("[Boot] No Firmware Need to Update."); 
        LED_ON(ERR);
        JumpToApplication();
        return;
      }
      //有文件需要升级
      DBG_LOG("[Boot] New Firmware Exist! Update Beginning..."); 
      
      //2.Flash解锁
      status = HAL_FLASH_Unlock();
      
      if(status != HAL_OK){
        DBG_LOG("[Boot] FLASH Unlock Failed."); 
        LED_ON(ERR);
        return;
      }
      DBG_LOG("[Boot] FLASH Unlock Ok."); 
      
      DBG_LOG("[Boot] Ready to Erase Flash ..."); 
      //3.擦除Flash
      status = HAL_FLASHEx_Erase(&f,&writeFlashData);
      
      if(status != HAL_OK){
        DBG_LOG("[Boot] Flash Erase Failed."); 
        LED_ON(ERR);
        return;
      }
      DBG_LOG("[Boot] Flash Erase OK."); 
      
      
      //4.从SPIFlash中读出数据然后copy到内部Flash中
      for(i = 0;i < (APP_PAGE_NUM / 2);i++){
        
        SFlash_Read(SECTOR_ADDR(SECTOR_DFU_START) + SPIFLASHBUF_MAX_LEN*i, Flash.spi, SPIFLASHBUF_MAX_LEN);
        
        DBG_LOG("[Boot] Write Flash Progress:%d%%",(i*100/(APP_PAGE_NUM / 2)) ); 
        
        LED_TOGGLE(WIFI);
        
        for(j = 0;j < (SPIFLASHBUF_MAX_LEN/4);j++){
          //注意基地址是在变化的
          HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, APP_BASEADDR+SPIFLASHBUF_MAX_LEN*i+4*j, Flash.stm32[j]);
        }    
      }
      
      DBG_LOG("[Boot] Write Flash Progress:100%%");
      DBG_LOG("[Boot] Program Complete!!!");
      
      //5.Flash上锁
      HAL_FLASH_Lock();  
      
      //6.跳转到用户程序区
      JumpToApplication();
      
    }
    
    
    
    展开全文
  • STM32IAP固件升级

    千次阅读 2016-02-22 14:08:19
    前段时间在弄stm32基于GMS的固件升级,在网上查了很多资料,知道个大概。现在把我遇到的一些问题记录下来,和大家一起分享。 第一次写技术博客,高手勿喷!!!! stm32IAP可以说分为两部分:bootloader+APP(我们...
  • STM32F030 IAP 升级

    千次阅读 2018-12-20 11:52:22
    IAP在线升级可以是芯片更新程序脱离烧录器等专用工具,可以使用串口、网络等外部通用通信方式来达到升级的目的,方便后续程序升级更新。   STM32F0系列是M0内核,与STM32F1和F4系列有一点不一样,因为在F0系列...
  • stm32 以太网 LWIP TFTP IAP 远程升级

    万次阅读 2016-11-19 10:27:06
    本例采用的PHY层芯片是DP83848,相当于物理层,STM32F107自带的MAC层相当于数据链路层,而LWIP协议栈提供的就是网络层、传输层的功能,应用层是需要我们自己根据自己想要的功能去实现的。升级程序由bootloader和APP...
  • 调试测试一切OK,该资源在淘宝上被盗版售卖,对此行为深恶痛觉,请不要在淘宝上进行购买,坑你没商量,本源码已经测试调试OK,请放心下载使用
  • STM32F4 SD卡升级流程

    2020-05-13 11:34:26
    STM32F4 SD卡升级流程 bootloader的实现 1、bootloader与APP的Flash分布: APP程序存储区 0x8010000 数据存储区 0x800FC00 Bootloader存储区 0x8000000 MD5校对(16字节校对码) 文件格式 自己创建一个.ini...
  • STM32网络远程升级固件的IAP程序实现与解析 ---附亲测稳定能用的程序 ...  本文主要对STM32网络升级固件的IAP程序进行解析,也就是在STM32联网的情况下在浏览器上输入指定的IP地址(目前设置为192.168.1...

空空如也

空空如也

1 2 3 4 5
收藏数 99
精华内容 39
关键字:

网络升级stm32