【IAP】篇二 —— 基于RS485自定义协议实现可靠固件升级

RS485接口的IAP固件升级工具 RS485接口的IAP固件升级工具 文章目录RS485接口的IAP固件升级工具前言一、概述二、IAP技术原理三、IAP编程实现1.bootloader程序2.APP程序四、上位机的编写五、总结 前言 当我们采用MCU设计的电子产品在出售后、安装在野外、固件存在BUG时或客户需求有变动, 都需要对固件进行维护和升级。由于距离远且需频繁调试测试, 不可能每次都安装人手去现场升级固件, 势必会造成巨大的成本开销, 这是非常不利于企业发展的。因此, 需要对产品可进行远程升级固件, 而远程升级固件就要使用到 阅读详情

1. RS485固件升级为何需要自定义协议

在工业现场搞固件升级,最头疼的就是环境复杂。电磁干扰、线路老化、设备距离远,这些因素都可能导致数据传输出错。我当年第一次做RS485升级时就踩过坑,直接用Ymodem协议传固件,结果在电机启动的瞬间数据就错乱了,设备直接变砖。

RS485总线虽然抗干扰能力强,传输距离远,但本质上还是个半双工通信。这意味着我们需要自己管理数据流向,避免冲突。工业现场常见的变频器、电机驱动器都是干扰源,随便一个电磁脉冲就可能让数据包出错。

所以必须设计一套自定义协议,包含这几个核心要素:

  • 帧头帧尾标识:明确数据包的开始和结束
  • 长度字段:知道这个包有多长
  • 校验机制:确保数据没被干扰
  • 重传机制:出错后能自动恢复

我设计的协议格式是这样的:

0x91 | 0xAA*6 | 0xFF*6 | 数据长度(2字节) | 数据内容(n字节) | 校验和(2字节)

0x91是起始标志,连续6个0xAA表示ACK确认包,6个0xFF表示结束包。校验和用的是简单的累加和,实际项目中也可以用CRC16,更可靠。

2. 协议设计中的坑与解决方案

2.1 数据包设计要点

数据包不是越大越好。虽然RS485理论上可以传很长的包,但在工业环境下,小包更可靠。我一般把数据包控制在512字节以内,原因有三:

第一,小包传输时间短,受干扰概率低。一个大包传500ms,中间来个干扰就全完了。拆成10个50ms的小包,即使丢一个也能重传。

第二,内存占用小。嵌入式设备RAM有限,STM32F103只有20K内存,如果包太大,光接收缓冲区就占去一大半。

第三,响应及时。设备需要及时回复ACK,包太大就会阻塞通信。

校验机制要足够健壮。最初我用的是奇偶校验,发现根本扛不住工业干扰。后来改用16位校验和,效果好了很多。现在新项目都改用CRC16了,虽然计算量大点,但可靠性更高。

2.2 超时重传策略

超时重传是保证可靠性的关键。但超时时间设多久很有讲究:太短会误判,太长影响效率。

我的经验值是:

  • ACK等待超时:100-500ms,根据线路长度调整
  • 包间超时:2-5倍包传输时间
  • 总升级超时:5-10分钟,防止卡死

实现时要用状态机管理升级流程:

typedef enum {
    STATE_IDLE,          // 空闲状态
    STATE_WAIT_ACK,      // 等待ACK
    STATE_SENDING,       // 发送数据中
    STATE_END            // 升级结束
} upgrade_state_t;

每个状态都要有超时处理,超时后根据策略重试或退出。我一般设置3次重试,超过3次就认为升级失败。

3. 代码实现详解

3.1 串口与中断配置

RS485需要配置为半双工模式,关键是要控制DE引脚(数据使能)。发送时拉高,接收时拉低。这个时序一定要准,否则数据会冲突。

// USART1初始化配置
huart1.Instance = USART1;
huart1.Init.BaudRate = 250000;        // 工业常用波特率
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_2;  // 2停止位更可靠
huart1.Init.Parity = UART_PARITY_NONE; 
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_8;  // 8倍过采样抗干扰
HAL_UART_Init(&huart1);

// 使能接收中断
HAL_UART_Receive_IT(&huart1, &rx_byte, 1);

中断接收处理要注意效率。我见过有人在中断里做复杂处理,结果丢数据丢得厉害。正确做法是在中断里只收数据,放到缓冲区,在主循环中解析。

// 中断接收回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1) {
        // 简单放入缓冲区,立即重新开启接收
        ring_buf_put(&rx_ring, rx_byte);
        HAL_UART_Receive_IT(huart, &rx_byte, 1);
    }
}

3.2 数据包解析实现

数据包解析要用状态机,逐字节处理。首先找帧头0x91,找到后读长度字段,然后收数据,最后校验。

// 数据包解析状态机
typedef enum {
    STATE_SYNC,      // 同步状态,找0x91
    STATE_LEN_H,     // 读长度高字节
    STATE_LEN_L,     // 读长度低字节
    STATE_DATA,      // 读数据内容
    STATE_CHECK_H,   // 读校验和高字节
    STATE_CHECK_L    // 读校验和低字节
} parse_state_t;

void parse_packet(uint8_t byte)
{
    static parse_state_t state = STATE_SYNC;
    static uint16_t data_len = 0;
    static uint16_t data_index = 0;
    static uint32_t checksum = 0;
    static uint8_t data_buf[MAX_PACKET_SIZE];
    
    switch(state) {
        case STATE_SYNC:
            if(byte == 0x91) {
                state = STATE_LEN_H;
                checksum = byte;
            }
            break;
            
        case STATE_LEN_H:
            data_len = byte << 8;
            checksum += byte;
            state = STATE_LEN_L;
            break;
            
        // 其他状态处理...
    }
}

校验通过后,要把数据写入Flash。这里要注意Flash写入前必须先擦除,而且要以页为单位擦除。

3.3 数据发送与ACK处理

发送数据包要封装成协议格式,计算校验和。发送前控制RS485为发送模式,发送完切回接收模式。

void send_packet(uint8_t *data, uint16_t len)
{
    // 切换到发送模式
    HAL_GPIO_WritePin(RS485_DE_GPIO_Port, RS485_DE_Pin, GPIO_PIN_SET);
    delay_us(10);  // 等待稳定
    
    // 构造协议包
    uint8_t packet[MAX_PACKET_SIZE];
    packet[0] = 0x91;  // 帧头
    packet[1] = (len >> 8) & 0xFF;  // 长度高字节
    packet[2] = len & 0xFF;         // 长度低字节
    memcpy(&packet[3], data, len);   // 数据内容
    
    // 计算校验和
    uint32_t sum = 0;
    for(int i = 0; i < len + 3; i++) {
        sum += packet[i];
    }
    packet[len+3] = (sum >> 8) & 0xFF;
    packet[len+4] = sum & 0xFF;
    
    // 发送
    HAL_UART_Transmit(&huart1, packet, len + 5, HAL_MAX_DELAY);
    
    // 切回接收模式
    delay_us(10);
    HAL_GPIO_WritePin(RS485_DE_GPIO_Port, RS485_DE_Pin, GPIO_PIN_RESET);
}

ACK处理要有超时机制。发送后启动定时器,在规定时间内没收到ACK就重发。

// 等待ACK,带超时
uint8_t wait_for_ack(uint32_t timeout_ms)
{
    uint32_t start_time = HAL_GetTick();
    while(HAL_GetTick() - start_time < timeout_ms) {
        if(ack_received) {
            ack_received = 0;
            return 1;
        }
        // 处理其他任务,避免死等
        background_tasks();
    }
    return 0;  // 超时
}

4. Flash操作关键细节

4.1 Flash分区规划

Flash分区是IAP的基础,分不好后面全白搭。我的经验是:

  • Bootloader放在开头,大小留足余量(至少16K)
  • 主程序区放当前运行的程序
  • 备份区放新下载的程序
  • 标志区放升级标志和系统配置

具体分区表如下:

分区名称起始地址大小用途
Bootloader0x0800000016K引导程序
Flag Area0x080040004K标志位和配置
Main APP0x0800500064K主程序区
Backup APP0x0801500064K备份程序区

标志区用来记录升级状态,我一般用几个关键标志:

  • 升级标志:是否需要升级
  • 校验标志:程序是否完整
  • 版本信息:当前程序版本

4.2 Flash读写操作

Flash写操作有严格限制:必须先擦后写,只能由1变0。擦除是以页为单位的,不同型号STM32页大小不同。

// Flash页擦除
void flash_erase_page(uint32_t page_address)
{
    HAL_FLASH_Unlock();  // 必须先解锁
    
    FLASH_EraseInitTypeDef erase_init;
    erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
    erase_init.PageAddress = page_address;
    erase_init.NbPages = 1;
    
    uint32_t page_error;
    HAL_FLASH_Erase(&erase_init, &page_error);
    
    HAL_FLASH_Lock();  // 操作完上锁
}

// Flash写入,按字(32位)写入
void flash_write_word(uint32_t address, uint32_t data)
{
    HAL_FLASH_Unlock();
    HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data);
    HAL_FLASH_Lock();
}

写数据时要注意对齐。STM32 Flash编程要求32位对齐,所以最好一次写4字节。如果数据长度不是4的倍数,要补0对齐。

// 写入数据,自动处理对齐
void flash_write_data(uint32_t address, uint8_t *data, uint32_t len)
{
    uint32_t words = (len + 3) / 4;  // 计算需要写的字数
    uint32_t buffer[words];
    
    // 数据复制到缓冲区,补0对齐
    memset(buffer, 0, words * 4);
    memcpy(buffer, data, len);
    
    // 逐字写入
    for(uint32_t i = 0; i < words; i++) {
        flash_write_word(address + i * 4, buffer[i]);
    }
}

4.3 升级标志位管理

升级标志位很重要,它告诉Bootloader是否需要升级。标志位要放在独立页,避免被误擦除。

我一般这样设计标志位:

#define UPDATE_FLAG_ADDR 0x08004000
#define UPDATE_FLAG_VALUE 0xAA55AA55

// 设置升级标志
void set_update_flag(void)
{
    flash_erase_page(UPDATE_FLAG_ADDR);
    flash_write_word(UPDATE_FLAG_ADDR, UPDATE_FLAG_VALUE);
}

// 检查升级标志
uint8_t check_update_flag(void)
{
    uint32_t flag = *(__IO uint32_t*)UPDATE_FLAG_ADDR;
    return (flag == UPDATE_FLAG_VALUE);
}

// 清除升级标志
void clear_update_flag(void)
{
    flash_erase_page(UPDATE_FLAG_ADDR);
    flash_write_word(UPDATE_FLAG_ADDR, 0xFFFFFFFF);
}

5. Bootloader设计与跳转

5.1 Bootloader工作流程

Bootloader是系统启动的第一个程序,它的主要任务是:

  1. 初始化基本硬件
  2. 检查升级标志
  3. 如果需要升级,从备份区拷贝程序到主程序区
  4. 跳转到主程序

流程图如下:

上电 → 硬件初始化 → 检查升级标志 → 
有升级标志? → 是 → 拷贝程序 → 清除标志 → 跳转主程序
                ↓
                否 → 直接跳转主程序

关键代码结构:

int main(void)
{
    // 基本硬件初始化
    HAL_Init();
    SystemClock_Config();
    UART_Init();
    Flash_Init();
    
    // 检查升级标志
    if(check_update_flag()) {
        // 执行升级操作
        copy_backup_to_main();
        verify_program();
        clear_update_flag();
    }
    
    // 跳转到主程序
    jump_to_app(MAIN_APP_ADDRESS);
    
    while(1);  // 正常情况下不会执行到这里
}

5.2 程序跳转关键技术

程序跳转不是简单的函数调用,需要完成以下步骤:

  1. 禁用所有中断
  2. 设置主堆栈指针(MSP)
  3. 设置程序计数器(PC)
  4. 重新初始化向量表
void jump_to_app(uint32_t app_address)
{
    // 禁用所有中断
    __disable_irq();
    
    // 检查栈顶地址是否合法
    uint32_t msp = *(__IO uint32_t*)app_address;
    if((msp & 0x2FF00000) != 0x20000000) {
        // 栈地址不合法,不跳转
        return;
    }
    
    // 设置主堆栈指针
    __set_MSP(msp);
    
    // 设置向量表偏移
    SCB->VTOR = app_address;
    
    // 获取复位地址并跳转
    uint32_t reset_handler = *(__IO uint32_t*)(app_address + 4);
    ((void(*)())reset_handler)();
    
    // 跳转后不会返回
}

跳转前一定要检查栈顶地址的合法性。STM32的RAM通常从0x20000000开始,所以栈顶地址应该在这个范围内。如果地址不合法,说明程序可能损坏,不能跳转。

5.3 异常处理机制

工业设备最怕升级变砖,所以异常处理一定要周全。我设计的异常处理包括:

电源异常处理:升级过程中断电是最危险的。我的做法是在升级开始时设置一个"升级中"标志,升级完成后清除。如果Bootloader发现这个标志被设置,说明上次升级中断了,需要恢复。

#define UPGRADE_IN_PROGRESS_FLAG 0x08004010

void handle_power_failure(void)
{
    if(check_upgrade_in_progress_flag()) {
        // 上次升级被中断,需要恢复
        if(verify_backup_area() == SUCCESS) {
            copy_backup_to_main();
            clear_upgrade_flags();
        } else {
            // 备份区校验失败,无法恢复
            enter_recovery_mode();
        }
    }
}

通信超时处理:升级过程中通信中断要能检测到并超时退出。我一般设置总升级超时时间为10分钟,超时后重启设备。

数据校验失败:每个数据包都要校验,校验失败要求重发。连续多个包校验失败则认为通信质量太差,退出升级。

6. 实战调试技巧

6.1 常见问题排查

做RS485升级最常遇到的问题是通信失败。排查步骤:

第一查硬件:用示波器看RS485波形,确认电平转换正常,DE控制信号时序正确。

第二查接线:RS485必须要接终端电阻,A/B线不能接反。我遇到过因为线序接反导致通信不稳定的情况。

第三查配置:波特率、数据位、停止位、校验位这些配置一定要两端一致。工业设备常用250000bps,2停止位。

第四查干扰:在电机、变频器附近通信时,很容易受干扰。可以尝试降低波特率,或者增加屏蔽措施。

6.2 性能优化建议

内存优化:嵌入式设备内存有限,要精心设计缓冲区大小。我的经验是:

  • 接收缓冲区:不小于最大包长的2倍
  • 发送缓冲区:足够存放一个完整数据包
  • 临时缓冲区:用于Flash操作和数据处理

速度优化:RS485波特率不是越高越好。工业现场长距离传输时,高波特率反而容易出错。我的建议:

  • 距离<50米:可用500Kbps
  • 50-100米:用250Kbps
  • 100-500米:用115200bps
  • 500米:用9600bps

可靠性优化:重要数据要多次确认。我一般重要指令发3遍,收到任意一个就算成功。数据包要有序列号,避免重复处理。

6.3 测试验证方法

升级功能一定要充分测试,我总结了一套测试方法:

边界测试:测试最小和最大固件大小,测试包长为0和最大包长的情况。

异常测试:模拟各种异常情况:

  • 断电测试:升级过程中随机断电
  • 干扰测试:在设备旁开关电机、变频器
  • 网络测试:模拟网络延迟、丢包

压力测试:连续升级100次,统计成功率。我要求工业级应用要达到99.9%的成功率。

兼容性测试:测试不同版本间的升级兼容性,包括向前兼容和向后兼容。

最后一定要做现场测试,实验室环境再好也模拟不了真实的工业现场。我去过一个钢厂,现场电磁干扰比实验室强几十倍,很多问题都是在现场才暴露出来的。

记得第一次在现场成功升级时的那种成就感,几十台设备同时升级,看着进度条一个个走完,所有设备都正常启动运行,那种感觉比中了彩票还高兴。工业现场升级就是这样,准备工作做得越充分,实际操作就越顺利。

基于RS485的IAP固件升级方案设计与实现 本文详细介绍了基于RS485的IAP固件升级方案设计与实现,重点解析了RS485总线在工业环境中的优势及IAP技术原理。通过bootloader开发、APP程序改造、通信协议设计等实战指南,帮助工程师实现远程设备固件升级,有效降低维护成本。方案特别适用于MCU设备的远程维护和固件更新。 阅读详情

相关推荐

保姆级教程:GD32+485实现无接触固件升级,告别烧录器(附避坑指南)

本文提供了一套基于GD32微控制器和RS-485接口实现工业级远程固件升级(OTA)的完整实战方案。通过IAP架构将Flash分区为Bootloader和App,详细讲解了内存规划、YMODEM协议传输、Bootloader代码实现、App工程配置以及关键调试技巧,帮助开发者告别传统烧录器,实现稳定可靠的无接触固件升级。

websocket5live的博客 265

rs485自定义通讯协议设计

基于的底层协议UART,我们设计其上一层,和modbus处于同一层,可以参考modbus的设计自定义我们自己的通信协议。可以实现一对多通信。可扩展网线转rs485通信。此描述只是简要的核心说明,具体示例参考测试用例功能码功能备注0x0000读取站号无数据段 响应帧 5A {STATION_ID} 00 FC FF0x0001设置站号1个字节 需要初始化0x0100传输图片数据字段前两个字节代表图片序列号。数据段最大长度256【序列号+数据】从00 00开始0x0101显示图片。

weixin_43356770的博客 1933

IAP板卡远程升级(串口网口都可)+Ymodem+AES对bin文件加密+pc软件+板卡相互烧录

还是决定记录一下,毕竟这个东西我也搞了挺久的,遇到一些棘手的,或者是因为我很粗心遇到的问题也和大家分享一下,。 板卡核心是 STM32F103RCT6,256kflash 前言 开始看这个远程升级的时候,我是一头雾水的,原子哥的教程里面也有说到过iap,有了一个大概的了解,我想不明白的是,通过串口下载的方式把hex文件下载到flash,和把bin文件下载到flash难道不是拉一根线,下载一个文件嘛,(初入职场的我并没有考虑到安全这个问题)如果直接将hex文件给到客户那边,风险是非常大...

那可真是太开心了的博客 5369

rs485自定义协议解释(RS485 是一个多点通信网络,支持多个设备在同一总线上。任何发送的消息都会被总线上所有设备接收,前提是这些设备都处于监听状态)(接收所有消息)

如果你正在使用自定义协议,且在协议设计中没有包括设备地址的概念,那么确实,主设备发送的任何消息在物理层面上可以被所有连接在同一 RS485 总线上的从设备接收到。从设备能否并如何处理这些消息完全取决于你的协议设计和从设备的固件逻辑。

Dontla的博客 1527

STM32F103/AT32F403 RS485(usart1) IAP升级

在很多应用场合,现场需要对固件代码进行升级但不便拆装设备,这时候可以采用485模式进行IAP升级,和usart iap升级代码部分是一样的,只是485电路要采用硬件自动切换收发,并且速率不能太快,实验19200bps下载速率正常。.........

shufawangzhang的博客 1642

STM32开发(六)STM32F103 通信 —— RS485 Modbus通信编程详解

本实验基于STM32F103开发,实现 通过RS-485实现Modbus通信。Modbus是主从方式通讯,不能同步进行通信,总线上每次只有一个数据进行传输。主机发送,从机应答,主机不发送,总线上就没有数据通讯。MODBUS 协议允许在各种网络体系结构内进行简单通信。

weixin_43564241的博客 5万+

STM32 IAP应用开发——通过串口/RS485实现固件升级(方式1)

IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。在应用编程(IAP)是用户的应用代码对片内Flash存储器进行擦除/编程的方法。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到数据存储区,从而实现固件升级。

ShenZhen_zixian的博客 1万+

UVM自学笔记3——项目之三——从零开始搭建ahb_sramc验证平台

创建如下所示的目录结构: 2.在tb的文件下:顶层的testbench如下:在tb中,第24行的代码将uvm宏相关的内容include进来,第26行的代码把uvm_pkg包导入进来,然后将agent相关的包(ahb_pkg/sram_pkg),testcase相关的包(uvm_ahb_sram_test_pkg)以及env相关的包(uvm_ahb_sram_env_pkg)都导入进来,在第38行和39行将接口以virtual interface的形式配置给ahb_agent和sramc_agent下

ZhangShuHuai11的博客 9469

STM32 IAP应用开发——通过串口/RS485实现固件升级(方式2)

IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。在应用编程(IAP)是用户的应用代码对片内Flash存储器进行擦除/编程的方法。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到数据存储区,从而实现固件升级。

ShenZhen_zixian的博客 1万+

【论文阅读】AU检测|《Deep Adaptive Attention for Joint Facial Action Unit Detection and Face Alignment》

摘要 本文旨在从大量没有人工标注的视频中学习用于面部动作单元检测的区分表示。受面部动作是面部肌肉运动这一事实的启发,论文将这些运动描述为不同帧中两幅面部图像之间的转换,并将其用作学习表示的自我监控信号。但是,在不受控制的情况下,这种转换是由面部动作和头部运动引起的。为了消除头部运动的影响,我们提出了一个双圈自动编码器(TCAE),它可以解开面部动作相关运动和头部运动相关运动。具体而言,TCAE被训练成分别将源面部的面部动作和头部姿态改变为目标面部的面部动作和头部姿态。我们的实验验证了TCAE解耦运动的能力。

Celine的博客 4550

手把手教你用Multisim仿真ADC接口电路(附峰值采样与电平抬升实战)

本文通过Multisim软件,手把手教学如何构建高保真ADC前端信号调理电路。核心实战内容包括峰值采样保持电路与电平抬升电路的设计、仿真与调试,旨在解决模拟信号接入ADC时遇到的幅度不匹配、负电压等问题,帮助电子设计者快速掌握关键接口电路的实现技巧。

ooo22的博客 254

【IAP】篇二 —— 自定义数据包传输协议实现固件升级

阅读本篇需要有bootloader和FLASH内存划分的知识,如果不了解可以看上一篇IAP篇一 —— FLASH内存划分 & Target设置 附Bootloader或者网上搜索。一、固件升级概念 及 传输信道在高级的应用开发中,产品发布后不是一成不变的,需要对产品不断的迭代升级,修正BUG,固件升级就是用来完成这个步骤的。固件升级将新的固件代码下载到设备的闪存中,并替换旧的代码。这个过程可以通过多种方式实现,如串口、USB、网络等。完成升级后,设备会重新启动并以新的固件版本运行。

weixin_63723467的博客 1473

基于决策树的英雄联盟比赛胜负预测(含完整代码)

在代码中设置随机种子(例如 RANDOM_SEED = 2024)的主要目的是为了确保每次运行代码时,随机过程的结果是一致的。通过绘制不同参数组合下的准确率图,直观地展示了参数对模型性能的影响,帮助读者更好地理解和选择合适的参数。通过设置相同的随机种子(伪随机数),可以确保每次运行代码时,随机数生成器生成的随机数序列是相同的。如果在开发过程中遇到问题,设置固定的随机种子可以帮助你更容易地定位问题,因为每次运行代码时的数据和结果都是一样的。在科学研究和实验中,结果的可重复性是非常重要的。

oisflo的博客 1919

(旧版)IAP升级:基于STM32F4系列标准库+Ymodem+RS485/RS232

如果是其他系列的,比如F1系列的就去找F1对应的例程,如果是HAL方式的就去找HAL库的,我这边只提供标准库的官方例程,需要官方例程的原因是因为官方例程中提供了非常重要的函数,就是Ymodem.c这个文件中的接收函数,其他的暂时都用不到,当然了,在文章的后面会详细的介绍官方例程的源码和使用以及Ymodem接收函数。我的源码最后会打包成一个Zip,提供一个连接供大家下载,但是目前还没有把例程和源码都整理好,等我整理好了之后我会在摘要当中提供我的源码连接(网盘方式)。2.有关Ymodem和IAP的基础知识。

2301_76504758的博客 3370

自动驾驶模拟器:基于 Python + Carla,在家也能训练一个“L4 级”自动驾驶 AI 模型

市面上有很多模拟器(AirSim, LGSVL),但 Carla 是目前学术界和工业界最主流的选择。画质强:基于 UE4,光影、天气(下雨、夕阳)极其逼真,这对训练视觉模型至关重要。API 爽:完全使用 Python 控制,对 AI 工程师极度友好。资产多:内置各种车辆、行人、交通信号灯、城市地图。编写 Python 代码,让车自己在城市里跑,通过摄像头看到路况,自己决定怎么打方向盘。通过 Carla,我们把价值数百万的自动驾驶测试场搬进了电脑。

BUG猿的博客 263

向华为学习——解读华为战略规划SP与业务计划BP流程【附全文阅读】

该方案针对大中型企业高管及战略团队,系统拆解华为SP(4-9月中长期规划)与BP(10-12月年度执行)双轨体系,形成"战略制定-业务设计-资源配置-绩效解码"闭环。SP侧重市场趋势分析、业务优先级与资源分配,BP细化KPI、预算及行动计划。通过价值树、战略解码等工具实现战略到部门/个人的目标分解,强化跨部门协同与过程管控。配套17份华为实战资料(包括战略管理、流程优化、销售组织建设等核心方法论),助力企业建立规范的战略执行体系,实现资源优化与绩效落地。

cdfunlove的博客 763

GD32F407实战:通过RS485与Ymodem协议实现远程IAP固件升级

本文详细介绍了基于GD32F407的远程IAP固件升级方案,通过RS485总线与Ymodem协议实现高效可靠的固件传输。文章涵盖Bootloader设计、Flash操作技巧、Ymodem协议优化及完整升级流程,适用于工业物联网场景,显著提升设备维护效率。

weixin_30642561的博客 333

华为OD机试双机位C卷:采购订单 (Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷 采购订单,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,并提供在线OJ模拟做题。华为OD机试真题【采购订单】

qq_45776114的博客 3532

STM32 IAP应用开发--bootloader升级程序

IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。在应用编程(IAP)是用户的应用代码对片内Flash存储器进行擦除/编程的方法。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到数据存储区,从而实现固件升级。

宁静致远的博客 3587

LiveBOS UploadFile.do 任意文件上传漏洞复现(XVE-2023-21708)

LiveBOS UploadFile.do 接口存在任意文件上传漏洞,未经身份验证的攻击者可通过该漏洞在服务器端任意执行代码,写入后门,获取服务器权限,进而控制整个web服务器。

0xSec 2415

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

基于STM32F407的串口IAP升级函数(RS485)

在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。

xiao9901han的博客 1516

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

工业现场IAP实战:基于STM32F4标准库与Ymodem协议的长距离RS485固件升级

本文详细介绍了基于STM32F4标准库与Ymodem协议的工业现场IAP固件升级方案,重点解决了RS485长距离通信、抗干扰设计和Bootloader开发等核心挑战。通过实战案例展示了如何实现稳定可靠的远程升级,大幅提升工业设备维护效率,适用于煤矿、污水处理等复杂工业场景。

weixin_42536058的博客 361

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

MCU固件在线升级系列合集

MCU固件在线升级系列合集,都是自己的一些经验分享

ShenZhen_zixian的博客 9862

STM32+USART协议RS485 IAP Bootloader 源码 Keil工程

STM32+USART协议RS485 IAP Bootloader 源码 Keil工程 【下载地址】STM32USART协议RS485IAPBootloader源码Keil工程 该项目为STM32微控制器提供了基于USART协议与RS485通信的IAP Bootloader源码,适用于Keil开发环境。通过此Bootlo...

gitblog_06782的博客 843

STM32 AT32 GD32 串口 IAP bootloader 远程升级 源码 RS485升级

完整代码已经扔在Github(地址防爬处理:github.com/某某某/uart_iap),包含STM32和GD32的适配版本。芯片上电先跑Bootloader,判断是否需要升级,需要的话通过串口接收新固件,写入指定地址后跳转到应用程序。特别是用RS485的时候,半双工通信的收发切换得处理利索。搞嵌入式最爽的时刻之一,就是半夜三点设备突然弹出升级提示,不用跑去现场就能把程序更了。今天咱们聊聊怎么在STM32、AT32、GD32这些国产替代满天飞的芯片上,用串口实现带远程升级的IAP方案。

2504_94289075的博客 1020
上一篇: 西门子S7-200 SMART与施耐德ATV变频器Modbus通讯实战:从接线到稳定运行的完整指南
下一篇: TI F28003x系列CANA总线调试:从晶振配置到GPIO释放的实战解析
kkk56
博客等级 码龄17年 71粉丝 1415原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值