STM32 BootLoader 刷新项目 (五) 获取软件版本号-命令0x51

STM32 BootLoader 刷新项目 (五) 获取软件版本号-命令0x51

下面我们来讲解第一个指令,获取软件版本号命令-0x51.

在BootLoader中获取软件版本号的操作有多个重要的作用,具体如下:

  1. 版本管理

    • 识别当前版本:通过获取软件版本号,可以识别当前运行的固件版本。这对于调试、维护和升级都是至关重要的。
    • 追踪更新:版本号能够帮助开发团队和用户追踪软件的更新历史,确保每次升级都是有计划和可追溯的。
  2. 兼容性检查

    • 与硬件兼容性:在一些情况下,不同的软件版本可能对硬件有不同的要求。BootLoader可以根据版本号决定是否继续启动或提示用户进行升级。
    • 与其他软件模块兼容性:某些软件模块可能只有在特定版本的固件上才能正常运行。通过检查版本号,BootLoader可以确保所有模块的兼容性。
  3. 固件升级管理

    • 升级条件判断:在执行固件升级时,BootLoader可以根据当前版本号决定是否需要进行升级,或者是否需要强制进行某些重要升级。
    • 回滚机制:如果新的固件版本出现问题,BootLoader可以通过版本号识别和恢复到之前的稳定版本。
  4. 日志记录和故障诊断

    • 问题追踪:在记录系统日志和诊断故障时,版本号是一个关键参考信息。它可以帮助开发者快速定位问题所在版本,进而更有效地进行修复。
    • 客户支持:在提供客户支持时,通过获取软件版本号,可以更准确地了解客户正在使用的版本,从而提供更有针对性的支持和解决方案。
  5. 安全性

    • 固件验证:在某些安全敏感的应用中,BootLoader需要验证固件的完整性和来源。版本号可以作为验证过程的一部分,确保固件未被篡改或替换。
    • 防止回滚攻击:通过检查版本号,可以防止系统被降级到存在已知漏洞的老版本,从而提高系统的整体安全性。

总的来说,BootLoader中获取软件版本号的操作在版本管理、兼容性检查、升级管理、故障诊断和安全性等方面都起着至关重要的作用,是确保嵌入式系统稳定、可靠和安全运行的重要手段。

前面我们讲过了整个BootLoader的方案、架构以及协议,下面我们来具体讲解每一个命令该如何编程。

下面我们来讲解第一个指令,获取软件版本号命令-0x51.

主机发送命令码BootLoader回复备注
BL_GET_VER0x51BootLoader版本号(1 byte)从MCU中读BootLoader的版本号

下面是上位机的命令菜单:

image-20240713104433991

输入1,则通过上位机发送指令:发送的数据为0x05, 0x51, 0xe7, 0xe9, 0xab, 0x7c.

启动第一个字节,为接下来要发送数据的长度,即为5个字节,第二个字节为0x51,即为上面获取软件版本号的指令,后四位为前两位的CRC校验位。

image-20240714162041966

BL_GET_VER指令为获取软件版本号:

image-20240714102542277

下面是用Python写的上位机代码:

def decode_menu_command_code(command):ret_value = 0data_buf = []for i in range(255):data_buf.append(0)if(command  == 0 ):print("\n   Exiting...!")raise SystemExitelif(command == 1):print("\n   Command == > BL_GET_VER")COMMAND_BL_GET_VER_LEN              = 6data_buf[0] = COMMAND_BL_GET_VER_LEN-1 data_buf[1] = COMMAND_BL_GET_VER crc32       = get_crc(data_buf,COMMAND_BL_GET_VER_LEN-4)crc32 = crc32 & 0xffffffffdata_buf[2] = word_to_byte(crc32,1,1) data_buf[3] = word_to_byte(crc32,2,1) data_buf[4] = word_to_byte(crc32,3,1) data_buf[5] = word_to_byte(crc32,4,1) Write_to_serial_port(data_buf[0],1)for i in data_buf[1:COMMAND_BL_GET_VER_LEN]:Write_to_serial_port(i,COMMAND_BL_GET_VER_LEN-1)ret_value = read_bootloader_reply(data_buf[1])

通过读取上位机终端输入的“1”,知道是要获取软件版本号的命令,则按照规定先发送数据长度5,在发送命令指令0x51,在计算前两位的CRC值,总共6byte的数据发送给下位机。下位机收到数据按协议进行相应的解析。

下面通过bootloader_uart_read_data()函数,首先读出上位机发送过来的0x05,表示后续要接收5个字节的数据。后续则按5个字节的数据来接收数据。

之后收到的数据是: 0x51, 0xe7, 0xe9, 0xab, 0x7c.

通过switch语句,判断0x51,则进入bootloader_handle_getver_cmd(bl_rx_buffer),来回去软件版本号的函数。

void  bootloader_uart_read_data(void)
{uint8_t rcv_len=0;printmsg_Host("BL_DEBUG_MSG: Receive CMD\n\r");while (1){memset(bl_rx_buffer, 0, 200);//here we will read and decode the commands coming from host//first read only one byte from the host , which is the "length" field of the command packetHAL_UART_Receive(C_UART,bl_rx_buffer,1,HAL_MAX_DELAY);rcv_len= bl_rx_buffer[0];HAL_UART_Receive(C_UART,&bl_rx_buffer[1],rcv_len,HAL_MAX_DELAY);switch(bl_rx_buffer[1]){case BL_GET_VER:bootloader_handle_getver_cmd(bl_rx_buffer);break;default:printmsg("BL_DEBUG_MSG:Invalid command code received from host \n");break;}}}

进入到bootloader_handle_getver_cmd()函数来获取软件版本号,首先计算排除后四位CRC数据前面收到数据的CRC值。如果计算出CRC的值,在和之前上位机发送的CRC,如果正确则进行软件版本号。

/*Helper function to handle BL_GET_VER command */
void bootloader_handle_getver_cmd(uint8_t *bl_rx_buffer)
{uint8_t bl_version;// 1) verify the checksumprintmsg("BL_DEBUG_MSG:bootloader_handle_getver_cmd\n");//Total length of the command packetuint32_t command_packet_len = bl_rx_buffer[0]+1 ;//extract the CRC32 sent by the Hostuint32_t host_crc = *((uint32_t * ) (bl_rx_buffer+command_packet_len - 4) ) ;if (! bootloader_verify_crc(&bl_rx_buffer[0],command_packet_len-4,host_crc)){printmsg("BL_DEBUG_MSG:checksum success !!\n");// checksum is correct..bootloader_send_ack(bl_rx_buffer[0], 1);bl_version = get_bootloader_version();printmsg("BL_DEBUG_MSG:BL_VER : %d %#x\n",bl_version,bl_version);bootloader_uart_write_data(&bl_version,1);}else{printmsg("BL_DEBUG_MSG:checksum fail !!\n");//checksum is wrong send nackbootloader_send_nack();}
}

下面则通过HAL库中计算CRC的值。

/* This verifies the CRC of the given buffer in pData. */
uint8_t bootloader_verify_crc (uint8_t *pData, uint32_t len, uint32_t crc_host)
{uint32_t uwCRCValue = 0xff;for (uint32_t i=0 ; i < len ; i++){uint32_t i_data = pData[i];uwCRCValue = HAL_CRC_Accumulate(&hcrc, &i_data, 1);}/* Reset CRC Calculation Unit */__HAL_CRC_DR_RESET(&hcrc);if( uwCRCValue == crc_host){return VERIFY_CRC_SUCCESS;}return VERIFY_CRC_FAIL;
}

通过下面的函数返回软件版本号。

/* Just returns the macro value. */
uint8_t get_bootloader_version(void)
{return (uint8_t)BL_VERSION;
}

如果正确的传输,则发送ACK让上位机接收。

/* This function sends ACK if CRC matches along with "len to follow" */
void bootloader_send_ack(uint8_t command_code, uint8_t follow_len)
{//here we send 2 byte.. first byte is ack and the second byte is len valueuint8_t ack_buf[2];ack_buf[0] = BL_ACK;ack_buf[1] = follow_len;HAL_UART_Transmit(C_UART, ack_buf,2, HAL_MAX_DELAY);}

如果错误的话,则传输NACK给上位机传输。

/* This function sends NACK */
void bootloader_send_nack(void)
{uint8_t nack = BL_NACK;HAL_UART_Transmit(C_UART, &nack, 1, HAL_MAX_DELAY);
}

下面则为执行命令1,0x51命令,则正确返回软件版本号。

image-20240714162041966

至此,获取软件版本号命令0x51的整个流程已经梳理完成。

往期文章请参考:

STM32 BootLoader 刷新项目 (一) STM32CubeMX UART串口通信工程搭建

STM32 BootLoader 刷新项目 (二) 方案介绍

STM32 BootLoader 刷新项目 (三) 程序框架搭建及刷新演示

STM32 BootLoader 刷新项目 (四) 通信协议

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/49485.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无人机上磁航技术详解

磁航技术&#xff0c;也被称为地磁导航&#xff0c;是一种利用地球磁场信息来实现导航的技术。在无人机领域&#xff0c;磁航技术主要用于辅助惯性导航系统&#xff08;INS&#xff09;进行航向角的测量与校正&#xff0c;提高无人机的飞行稳定性和准确性。其技术原理是&#x…

vue3 + antd vue 纯前端 基于xlsx 实现导入excel 转 json,将json数据转换XLSX导出(模版下载)

一、导入 0、关键代码 // 安装插件 npm i xlsx/yarn add xlsx // 导入xlsx import * as XLSX from xlsx; 点击提交的时候才整理数据。上传的时候文件保存在 state.form.file[0] 中的 // 定义字段映射关系 const fieldMap {sheet2json: {技能名称: skill_name,技能等级: …

微服务实战系列之玩转Docker(六)

前言 刚进入大暑&#xff0c;“清凉不肯来&#xff0c;烈日不肯暮”&#xff0c;空调开到晚&#xff0c;还是满身汗。——碎碎念 我们知道&#xff0c;仓库可见于不同领域&#xff0c;比如粮食仓库、数据仓库。在容器领域&#xff0c;自然也有镜像仓库&#xff08;registry&…

代码随想录——零钱兑换Ⅱ(Leetcode518)

题目链接 完全背包 class Solution {public int change(int amount, int[] coins) {int[] dp new int[amount 1];dp[0] 1;for(int i 0; i < coins.length; i){for(int j coins[i]; j < amount; j){dp[j] dp[j - coins[i]];}}return dp[amount];} }本题为组合问题…

uni-app AppStore Connect上传拒绝汇总

1.Guideline 2.3.3 - Performance - Accurate Metadata 问题是图片不对&#xff0c;最好是自己截图&#xff0c;然后用香蕉云编 上传图片合成图片 2.Guideline 5.1.2 - Legal - Privacy - Data Use and Sharing 解决办法&#xff1a;在uniapp manifest.json找到 APP常用其他…

【软考】系统集成项目管理工程师【第二版】

&#x1f44a;重要通知&#x1f44a; &#x1f44a; 1. 2024年中考上半年取消&#xff0c;改下半年&#x1f44a; &#x1f44a; 2. 2024下半年 使用《系统集成项目管理工程师教程》第三版&#x1f44a; &#x1f44a; 3. 为了方便大家学习&#xff0c;博主正在整理第三版 &am…

使用uniapp开发小程序(基础篇)

本文章只介绍微信小程序的开发流程&#xff0c;如果需要了解其他平台的开发的流程的话&#xff0c;后续根据情况更新相应的文章,也可以根据uniapp官网的链接了解不同平台的开发流程 HBuilderX使用&#xff1a;https://uniapp.dcloud.net.cn/quickstart-hx.html 开发工具 开始…

# OpenCV 图像预处理—形态学:膨胀、腐蚀、开运算、闭运算 原理详解

文章目录 形态学概念膨胀使用膨胀操作来修复裂痕示例代码关键解析&#xff1a; 腐蚀使用腐蚀操作消除噪点示例代码&#xff1a; 开运算—先腐蚀后膨胀闭运算—先膨胀后腐蚀 形态学概念 首先看这两张图片 一张图周围有大大小小的噪音和彩点&#xff0c;另一张图片中字母有间隙&…

php连接sql server

php连接sqlserver有三种方式 一&#xff1a;odbc连接&#xff0c;废话不多说直接上代码,封装了一个单例 <?php /*** odbcServer.php* Author: Erekys*/namespace App\Model; class odbcServer{public static $server;public static $username;public static $password;pu…

基于jeecgboot-vue3的Flowable流程仿钉钉流程设计器-发送信息服务处理

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、因为仿钉钉设计器里发送消息处理是一个服务任务&#xff0c;所以要根据这个服务任务进行处理 2、这里目前只对消息进行处理&#xff0c;就是用websocket的发送方式 输入相应的内容&…

go语言Gin框架的学习路线(十)

目录 GORM的CRUD教程 查询 普通查询 定义 User 结构体 查询所有用户 查询第一个用户 总结 条件查询 内联条件 额外查询选项 高级查询 链式操作 Scopes 多个立即执行方法 GORM的CRUD教程 CRUD 是 "Create, Read, Update, Delete"&#xff08;创建、查询…

AIoTedge边缘物联网平台,开启智能物联新架构

边缘物联网平台是一种将计算能力、数据处理和应用服务部署在网络边缘的解决方案&#xff0c;旨在提高响应速度、降低带宽需求和增强数据安全。根据搜索结果&#xff0c;边缘物联网平台应具备以下功能&#xff1a; 云边协同&#xff1a; 云边一体架构&#xff0c;通过云端管理边…

【BUG】已解决:Downgrade the protobuf package to 3.20.x or lower.

Downgrade the protobuf package to 3.20.x or lower. 目录 Downgrade the protobuf package to 3.20.x or lower. 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身…

【昇腾AI创新大赛集训营南京站学习笔记】-Ascend算子开发课程

昇腾AI创新大赛训练营 14:00-14:30 基础知识-理论课 一、CANN 、达芬奇架构和算子 1.AI Core逻辑架构 达芬奇架构包含三部分&#xff1a; 1&#xff09;计算类&#xff1a;矩阵计算单元&#xff08;两个矩阵扔进去相乘&#xff09;、向量计算单元、标量计算单元 2&#xff09;控…

基于单片机控制的变压器油压油温故障检测

摘 要 在电力系统的运行中&#xff0c;通过对其核心设备变压器的故障进行检测&#xff0c;以此能够及时、准确的发现变压器的故障&#xff0c;基于单片机控制的变压器油压油温的故障检测的方法&#xff0c;利用压力传感器、温度传感器对变压器的油压、油温进行采集并送入单片机…

vCenter 错误提示 “目标主机上的vmotion接口未配置”

vCenter 错误提示 “目标主机上的vmotion接口未配置” VMware 使用 vCenter 迁移 虚拟机报错 “目标主机上的 vMotion 接口未配置”&#xff0c;配置启用 vMotion 的步骤如下&#xff1a; &#xff08;END&#xff09;

leetcode3098. 求出所有子序列的能量和

官解 class Solution(object):# 定义常量mod int(1e9 7) # 模数&#xff0c;用于防止结果溢出inf float(inf) # 无穷大&#xff0c;用于初始化时的特殊值def sumOfPowers(self, nums, k):n len(nums) # 数组长度res 0 # 用于存储最终结果# 三维动态规划表&#xff0c;…

Nacos-2.4.0最新版本docker镜像,本人亲自制作,部署十分方便,兼容postgresql最新版本17和16,奉献给大家了

基于Postgresql数据库存储的nacos最新版本2.4.0,采用docker镜像安装方式 因业务需要,为了让nacos支持postgresql,特意花了两天时间修改了源码,然后制作了docker镜像,如果你也在找支持postgresql的nacos最新版本,恭喜你,你来的正好~ nacos-2.4.0 postgresql的数据库脚本…

Apache SeaTunnel快速入门及原理和实践(一)

一、概述 主要从以下6个方面进行&#xff1a; 对数据集成做一个简单的概括对 SeaTunnel 做简单的介绍介绍 SeaTunnel 当前的原理和架构演进对当前市面上一些比较常见的数据集成工具进行对比&#xff0c;来解读一下现在市面上已经有了那么多数据集成工具&#xff0c;为什么我们…

Django Web框架——01

目录 文章目录 目录 Django框架的介绍起源&现状Django的安装 创建Django项目创建项目的指令Django项目的目录结构settings.py 文件介绍 URL 介绍URL定义Django如何处理一个URL对应的请求视图函数(view) Django 路由配置path() 函数path转换器 re_path()函数 HTTP协议的请求…