硬汉嵌入式论坛

 找回密码
 立即注册
查看: 409|回复: 7
收起左侧

[以太网] 怎么使用硬汉STM32H743的开发板上的网口实现程序升级

[复制链接]

6

主题

14

回帖

32

积分

新手上路

积分
32
QQ
发表于 2026-2-25 09:16:47 | 显示全部楼层 |阅读模式
首先祝大家开工大吉,其次领导给我分配新任务在STM32H743上用网口实现程序升级,想问大家我可以学习哪些资料,或者安富莱有哪些历程可以参考吗
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121543
QQ
发表于 2026-2-25 09:57:44 | 显示全部楼层
网口没有提供直接的例子,间接的做了很多
1、使用FTP升级
(1)下这个综合模板例子,做了FTP例子。你可以将固件先更新到SD卡
https://forum.anfulai.cn/forum.p ... &highlight=V4.0
  (2)   此贴了SD卡固件更新

BSP视频教程第18期:基于NAND,eMMC,SD卡和U盘的BootLoader实战,带CRC完整性校验(2022-06-16)
https://forum.anfulai.cn/forum.php?mod=viewthread&tid=113053

2、之前做了个wifi的,以太网同理

DSP视频教程第9期:基于Matlab的WiFi无线固件升级玩法(2022-07-02)
https://forum.anfulai.cn/forum.php?mod=viewthread&tid=113546
回复

使用道具 举报

6

主题

14

回帖

32

积分

新手上路

积分
32
QQ
 楼主| 发表于 2026-2-25 10:13:32 | 显示全部楼层
eric2013 发表于 2026-2-25 09:57
网口没有提供直接的例子,间接的做了很多
1、使用FTP升级
(1)下这个综合模板例子,做了FTP例子。你可以 ...

好的,感谢硬汉哥
回复

使用道具 举报

5

主题

232

回帖

247

积分

高级会员

积分
247
发表于 2026-2-25 11:27:05 | 显示全部楼层
网口的话,可以使用tcp通信,然后自己写个上位机软件,把固件通过通信协议,一块块的发送给STM32。
一般还需要一个nor flash来保存这个固件。
然后STM32里面的程序也要分成2个,一个Bootloader,一个是正常的app。有的还使用双备份app2。这样避免升级失败还能回滚。
网口只是一个数据传输的途径,常见的还有串口等。
可以先研究硬汉的ftp例子,之后熟悉了,再根据情况去改成领导喜欢的
回复

使用道具 举报

6

主题

86

回帖

104

积分

初级会员

积分
104
发表于 2026-2-25 15:36:10 | 显示全部楼层
先用网口把固件接收存入某个介质里,然后重启进入bootloader,从介质读取固件写入flash,然后运行.
回复

使用道具 举报

6

主题

14

回帖

32

积分

新手上路

积分
32
QQ
 楼主| 发表于 2026-2-26 09:13:57 | 显示全部楼层
honami520 发表于 2026-2-25 11:27
网口的话,可以使用tcp通信,然后自己写个上位机软件,把固件通过通信协议,一块块的发送给STM32。
一般还 ...

想问一下我现在看了例程”V7-079_串口bootloader设计“,想法是把这个例程.c文件移植到网口通讯中,把其中的串口接收接口改成网口接收接口,不知道我的想法是否正确
以下是这个例程的.c文件
/*
*********************************************************************************************************
*
*        模块名称 : 串口方式固件升级
*        文件名称 : demo_uart_update.c
*        版    本 : V1.0
*        说    明 : 串口方式固件升级
*
*        修改记录 :
*                版本号   日期         作者        说明
*                V1.0    2022-06-15   Eric2013    正式发布
*
*        Copyright (C), 2022-2030, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/
#include "bsp.h"


/*
*********************************************************************************************************
*                                                函数
*********************************************************************************************************
*/
/* 仅允许本文件内调用的函数声明 */
static void JumpToApp(void);

/*
*********************************************************************************************************
*                                               宏定义
*********************************************************************************************************
*/
#define AppAddr  0x08100000    /* APP地址 */


/*
*********************************************************************************************************
*                                               变量
*********************************************************************************************************
*/
__IO uint32_t uwCRCValue;
__IO uint32_t uwExpectedCRCValue;
__IO uint32_t uwAppSize;

uint8_t buf[1024];
uint32_t RecCount = 0;
uint32_t RecCount0 = 0;
uint32_t RecSize = 0;
uint8_t RecCplt = 0;
uint32_t filesize = 0;

/*
*********************************************************************************************************
*        函 数 名: DemoUartUpdate
*        功能说明: 串口烧录
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void DemoUartUpdate(void)
{
        uint8_t cmd;
        uint8_t ucStatus = 0;  /* 状态机标志 */
        uint32_t SectorCount = 0;
        uint32_t SectorRemain = 0;
        uint32_t i;
    uint32_t TotalSize = 0;
        uint8_t ucState;
       
       
        bsp_StartAutoTimer(0, 500);        /* 启动1个500ms的自动重装的定时器 */
       
        while (1)
        {
                /* 判断定时器超时时间 */
                if (bsp_CheckTimer(0))       
                {            
                        /* 每隔500ms 进来一次 */  
                        bsp_LedToggle(2);
                }

                if (comGetChar(COM1, &cmd))        /* 从串口读入一个字符(非阻塞方式) */
                {
                        switch (ucStatus)
                        {
                                case 0:
                                        /* 开始传输固件命令 **************/
                                        if(cmd == '$')
                                        {
                                                RecCplt = 0;
                                                ucStatus = 1;        
                                        }
                                       
                                        /* 传输完成命令 **************/
                                        if(cmd == '#')
                                        {
                                                RecCount = 0;
                                                RecCplt = 1;
                                                JumpToApp();
                                        }
                                       
                                        /* 接收固件大小命令 */
                                        if(cmd == '*')
                                        {
                                                ucStatus = 3;
                                        }
                                        break;
                                       
                                /* 设置每帧传输字节数,默认设置的224字节 */
                                case 1:
                                        RecSize = cmd;
                                        ucStatus = 2;
                                        break;
                                /* 将接收到的数据编程到内部Flash */
                                case 2:
                                        buf[RecCount0] = cmd;
                                       
                                        /* 接收够224个数据 */
                                        if(RecCount0 == (RecSize - 1))
                                        {
                                                ucStatus = 0;
                                                RecCount0 = 0;
                                               
                                                /* 编程内部Flash, */
                                                ucState = bsp_WriteCpuFlash((uint32_t)(AppAddr + TotalSize),  (uint8_t *)buf, RecSize);
                                                TotalSize += RecSize;
                                               
                                                /* 如果返回非0,表示编程失败 */
                                                if(ucState != 0)
                                                {
                                                        /* 返回0x60,表示编程失败 */
                                                        comSendChar(COM1, 0x60);
                                                }
                                               
                                                /* 返回0x30,表示编程成功 */
                                                comSendChar(COM1, 0x30);
                                        }
                                        else
                                        {
                                                RecCount++;
                                                RecCount0++;
                                                comSendChar(COM1, 0x70);
                                        }
                                        break;
                                       
                                /* 根据接收到的文件大小,擦除相应大小的扇区 */
                                case 3:
                                        buf[RecCount0] = cmd;
                                       
                                        if(RecCount0 == 3)
                                        {
                                                ucStatus = 0;
                                                RecCount0 = 0;
                                                filesize = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
                                                uwAppSize = filesize;
                                                SectorCount = filesize/(128*1024);
                                                SectorRemain = filesize%(128*1024);       
                                               
                                                for(i = 0; i < SectorCount; i++)
                                                {
                                                        bsp_EraseCpuFlash((uint32_t)(AppAddr + i*128*1024));
                                                }
                                               
                                                if(SectorRemain)
                                                {
                                                        bsp_EraseCpuFlash((uint32_t)(AppAddr + i*128*1024));
                                                }
                                               
                                                /* 返回0x30,表示擦除成功 */
                                                comSendChar(COM1, 0x30);
                                        }
                                        else
                                        {
                                                RecCount0++;
                                        }
                                        break;
                        }
                }
        }
}

/*
*********************************************************************************************************
*        函 数 名: JumpToApp
*        功能说明: 跳转到应用JumpToApp
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
static void JumpToApp(void)
{
        uint32_t i=0;
        void (*AppJump)(void);         /* 声明一个函数指针 */
   
    /* 关闭全局中断 */
        DISABLE_INT();
   
    /* 设置所有时钟到默认状态,使用HSI时钟 */
        HAL_RCC_DeInit();
   
        /* 关闭滴答定时器,复位到默认值 */
        SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;

        /* 关闭所有中断,清除所有中断挂起标志 */
        for (i = 0; i < 8; i++)
        {
                NVIC->ICER=0xFFFFFFFF;
                NVIC->ICPR=0xFFFFFFFF;
        }       

        /* 使能全局中断 */
        ENABLE_INT();

        /* 跳转到应用程序,首地址是MSP,地址+4是复位中断服务程序地址 */
        AppJump = (void (*)(void)) (*((uint32_t *) (AppAddr + 4)));

        /* 设置主堆栈指针 */
        __set_MSP(*(uint32_t *)AppAddr);
       
        /* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
        __set_CONTROL(0);

        /* 跳转到系统BootLoader */
        AppJump();

        /* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
        while (1)
        {

        }
}

/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
[/mw_shl_code]
回复

使用道具 举报

4

主题

165

回帖

177

积分

初级会员

积分
177
发表于 2026-2-26 09:52:47 | 显示全部楼层
参考ST sbsfu来实现升级,用MDK 8.2自带的FTP server上传即可
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121543
QQ
发表于 2026-2-27 09:02:54 | 显示全部楼层
fhs 发表于 2026-2-26 09:13
想问一下我现在看了例程”V7-079_串口bootloader设计“,想法是把这个例程.c文件移植到网口通讯中,把其 ...

也可以的,没问题。

回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-3-14 10:07 , Processed in 0.216587 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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