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

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

文章目录

  • STM32 BootLoader 刷新项目 (四) 通信协议
    • 1. 通信流程
    • 2. 支持指令
    • 3. 通信流程
    • 4. 指令结构
    • 5. 操作演示

前面几章节,我们已经介绍了BootLoader的整体程序框架,方案设计,以及STM32CubdeMX的配置操作。下面切入整个BootLoader项目的核心内容,通信协议。

我理解的通信协议,其实就是双方提前约定好的暗号。比如说到了提前约定好的地方,一个人逢人便说:“天王盖地虎”。只有懂他暗号对接的人才知道,这是他要找的人,另外一个人就回:”小鸡炖蘑菇“。至此,这两个便通过暗号,传达到了他们配对的信息。

所以,在我们进入到BootLoader模式的时候,必须得发送Host主机端和从机定义好的协议进行通讯,二者才能执行正确的行为。

1. 通信流程

下图便是整个通信的流程,显示主机通过UART发送命令指令,从机收到主机发送的命令,如果是正确的命令,则回复ACK,错误的话则回复NACK,然后在回复之后从机会回复多少字节数据。然后再回复结果。

image-20240714102347637

2. 支持指令

下面是整个Customer BootLoader支持的指令,其中比较重要的是0x55(BL跳转固定地址),0x56(指定擦除扇区),0x57(在不同内存写数据)。后续将详细介绍整个Customer BootLoader的方案实现和代码实现。

主机发送命令码BootLoader回复备注
BL_GET_VER0x51BootLoader版本号(1 byte)从MCU中读BootLoader的版本号
BL_GET_HELP0x52所有支持的命令码(10 bytes)列出BootLoader支持的所有命令
BL_GET_CID0x53Chip identification number(2 bytes)读芯片的识别号
BL_GET_RDP_STATUS0x54返回芯片读保护等级(1 byte)读行骗Flash的读保护等级
BL_GO_TO_ADDR0x55返回成功或错误(1 byte)BL跳转固定地址
BL_FLASH_ERASE0x56返回成功或错误(1 byte)指定擦除扇区
BL_MEM_WRITE0x57返回成功或错误(1 byte)在不同内存写数据
BL_EN_R_W_PROTECT0x58返回成功或错误(1 byte)使能读/写保护
BL_MEM_READ0x59主机请求的内存内容长度TO DO
BL_READ_SECTOR_STATUS0x5A所有Sector状态读所有扇区的保护状态
BL_OTP_READ0x5BOTP contentsTO DO
BL_DIS_R_W_PROTECT0x5C返回成功或错误(1 byte)该命令用于禁用用户Flash的不同扇区的读写保护功能。该命令将保护状态恢复为默认状态。

下图是上位机的操作界面,是由Python脚本进行编写的,执行脚本后,先输入和开发板对应的串口号,进行连接。然后可以看到支持的指令,通过输入相应的数字,即可向从机发送相应的命令。

image-20240713104433991

3. 通信流程

下面我们来介绍一下,BootLoader通信协议的命令组成,首先第一个字节为接下来要发送数据的长度,第二个字节是命令,第3-6字节为四个字节的CRC校验码。

当从机收到数据后,先收第一字节数据,得到接下来发送数据的长度,然后更具接收数据的长度,在确定接下来应该接收多少字节的数据。将收到的数据解析,第一个字节(除掉一开始收到的长度位)为命令,通过swich case指令,来判断应该执行哪种命令的操作。代码如下图所示:

    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 packet
    	HAL_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;

            case BL_GET_HELP:
                bootloader_handle_gethelp_cmd(bl_rx_buffer);
                break;

            case BL_GET_CID:
                bootloader_handle_getcid_cmd(bl_rx_buffer);
                break;

            case BL_GET_RDP_STATUS:
                bootloader_handle_getrdp_cmd(bl_rx_buffer);
                break;

            case BL_GO_TO_ADDR:
                bootloader_handle_go_cmd(bl_rx_buffer);
                break;

            case BL_FLASH_ERASE:
                bootloader_handle_flash_erase_cmd(bl_rx_buffer);
                break;

            case BL_MEM_WRITE:
                bootloader_handle_mem_write_cmd(bl_rx_buffer);
                break;

            case BL_EN_RW_PROTECT:
                bootloader_handle_en_rw_protect(bl_rx_buffer);
                break;

            case BL_MEM_READ:
                bootloader_handle_mem_read(bl_rx_buffer);
                break;

            case BL_READ_SECTOR_P_STATUS:
                bootloader_handle_read_sector_protection_status(bl_rx_buffer);
                break;

            case BL_OTP_READ:
                bootloader_handle_read_otp(bl_rx_buffer);
                break;

			case BL_DIS_R_W_PROTECT:
				bootloader_handle_dis_rw_protect(bl_rx_buffer);
				break;

            default:
            	printmsg("BL_DEBUG_MSG:Invalid command code received from host \n");
            	break;
    	}
    }

下图为整个Customer BootLoader运行的整个过程:

BootLoader_Flow

4. 指令结构

下图展示了BootLoader支持的所有指令结构:

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

image-20240714102542277

image-20240714162041966

可以看到上图,发送的数据为0x05, 0x51, 0xe7, 0xe9, 0xab, 0x7c.

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

下面为了更清晰的指导整个协议发送过程的逻辑,展示了获取软件版本号的代码,如下所示:

/**************Implementation of Boot-loader Command Handle functions *********/

/*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 checksum
	printmsg("BL_DEBUG_MSG:bootloader_handle_getver_cmd\n");

	//Total length of the command packet
	uint32_t command_packet_len = bl_rx_buffer[0]+1 ;

	//extract the CRC32 sent by the Host
	uint32_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 nack
        bootloader_send_nack();
    }
}

当CRC校验位没有问题,则发送ACK,并且发送软件版本号,否则发送NACK。

BL_GET_HELP:获取帮助

image-20240714102528030

image-20240714162801126

下面的命令后续文章再一一讲解:
image-20240714102613163

image-20240714102625964

image-20240714102640901

image-20240714102653304

image-20240714102705943

image-20240714102716603

image-20240714102728108

image-20240714102738998

image-20240714102751460

5. 操作演示

下面打开上位机,连接上位机和开发板连接的串口,根据显示的指令,进行相应的操作。

image-20240713104433991

下面我们展示一下读取版本号的功能,输入1,获取版本号为0x10.

image-20240713104633571

下面我们在试一个刷新命令。下面是录制的一整个执行的流程。

BootLoader串口刷新

如果大家有什么疑问,请随时私信联系我。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kafka基本原理|特性

Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统 它的最大的特性就是可以实时的处理大量数据以满足各种需求场景…

等保五级分类详解:从自主保护到专控保护的全方位信息安全

等保,即信息安全等级保护,是一项旨在保障电子信息系统安全的重要标准。根据系统所承载的信息重要性和可能遭受的损害程度,等保将信息系统划分为五个不同的安全等级。每个等级都有其特定的安全要求和测评周期,以确保不同规模和类型…

ES13的4个改革性新特性

1、类字段声明 在 ES13 之前,类字段只能在构造函数中声明, ES13 消除了这个限制 // 之前 class Car {constructor() {this.color = blue;this.age = 2

大气热力学(8)——热力学图的应用之一(气象要素求解)

本篇文章源自我在 2021 年暑假自学大气物理相关知识时手写的笔记,现转化为电子版本以作存档。相较于手写笔记,电子版的部分内容有补充和修改。笔记内容大部分为公式的推导过程。 文章目录 8.1 复习斜 T-lnP 图上的几种线8.1.1 等温线和等压线8.1.2 干绝热…

一个老程序员对小浣熊 AI 办公助手的使用体验

我是一个老程序员,今年 42 岁,仍然在一线编程领域工作。 2022 年底以 ChatGPT 为代表的 AI 工具席卷整个业界后,我也使用了不少能提高办公效率的 AI 工具。比如程序员的好帮手,来自微软的 Copilot. 这款名叫小浣熊的 AI 办公工具…

Web 性能入门指南-1.2 分析在线零售 Web 性能及优化方向

让顾客满意是零售业成功的秘诀。事实证明,提供快速、一致的在线体验可以显著提高零售商关心的每项指标——从转化率和收入到留存率和品牌认知度。 本文大纲: 页面速度影响在线零售业务数据 如何将您的网站速度与竞争对手进行比较 性能优化入门&#xf…

怎样在 PostgreSQL 中优化对复合索引的选择性?

🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会!📚领书:PostgreSQL 入门到精通.pdf 文章目录 怎样在 PostgreSQL 中优化对复合索引的选择性一、理解复合索引的概念二、选择性的重要性三、优化复合索…

神经网络识别数字图像案例

学习资料:从零设计并训练一个神经网络,你就能真正理解它了_哔哩哔哩_bilibili 这个视频讲得相当清楚。本文是学习笔记,不是原创,图都是从视频上截图的。 1. 神经网络 2. 案例说明 具体来说,设计一个三层的神经网络。…

采用自动微分进行模型的训练

自动微分训练模型 简单代码实现: import torch import torch.nn as nn import torch.optim as optim# 定义一个简单的线性回归模型 class LinearRegression(nn.Module):def __init__(self):super(LinearRegression, self).__init__()self.linear nn.Linear(1, 1) …

链接追踪系列-07.logstash安装json_lines插件

进入docker中的logstash 容器内: jelexbogon ~ % docker exec -it 7ee8960c99a31e607f346b2802419b8b819cc860863bc283cb7483bc03ba1420 /bin/sh $ pwd /usr/share/logstash $ ls bin CONTRIBUTORS Gemfile jdk logstash-core modules tools x-pack …

如何预防最新的baxia变种勒索病毒感染您的计算机?

引言 在当今数字化时代,网络安全威胁层出不穷,其中勒索病毒已成为企业和个人面临的重大挑战之一。近期,.baxia勒索病毒以其高隐蔽性和破坏性引起了广泛关注。本文将详细介绍.baxia勒索病毒的特点、传播方式,并给出相应的应对策略…

2024-07-15 Unity插件 Odin Inspector3 —— Button Attributes

文章目录 1 说明2 Button 特性2.1 Button2.2 ButtonGroup2.3 EnumPaging2.4 EnumToggleButtons2.5 InlineButton2.6 ResponsiveButtonGroup 1 说明 ​ 本章介绍 Odin Inspector 插件中有关 Button 特性的使用方法。 2 Button 特性 2.1 Button 依据方法,在 Inspec…

YOLOv8训练自己的数据集(超详细)

一、准备深度学习环境 本人的笔记本电脑系统是:Windows10 YOLO系列最新版本的YOLOv8已经发布了,详细介绍可以参考我前面写的博客,目前ultralytics已经发布了部分代码以及说明,可以在github上下载YOLOv8代码,代码文件夹…

力扣经典题目之->移除值为val元素的讲解,的实现与讲解

一:题目 博主本文将用指向来形象的表示下标位的移动。 二:思路 1:两个整形,一个start,一个end,在一开始都 0,即这里都指向第一个元素。 2:在查到val之前,查一个&…

昇思25天学习打卡营第12天|MindSpore 助力下的 GPT2:数据集加载处理及模型全攻略

环境配置 %%capture captured_output 此乃 Jupyter Notebook 中的一个魔法命令,其作用在于捕获后续单元格中的输出,并将之存储于变量 captured_output 当中,而非直接于输出区域予以显示。如此一来,便可隐匿某些可能存在的输出信息…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(九)-无人机服务区分离

引言 本文是3GPP TR 22.829 V17.1.0技术报告,专注于无人机(UAV)在3GPP系统中的增强支持。文章提出了多个无人机应用场景,分析了相应的能力要求,并建议了新的服务级别要求和关键性能指标(KPIs)。…

小程序里面使用vant ui中的vant-field组件,如何使得输入框自动获取焦点

//.wxml <van-fieldmodel:value"{{ userName }}"placeholder"请输入学号"focus"{{focusUserName}}"/>// .js this.setData({focusUserName: true});vant-field

钡铼ARMxy控制器在智能网关中的应用

随着IoT物联网技术的飞速发展&#xff0c;智能网关作为连接感知层与网络层的枢纽&#xff0c;可以实现感知网络和通信网络以及不同类型感知网络之间的协议转换。钡铼技术的ARMxy系列控制器凭借其高性能、低功耗和高度灵活性的特点&#xff0c;在智能网关中发挥了关键作用&#…

RPC与服务的注册发现

文章目录 1. 什么是远程过程调用(RPC)?2. RPC的流程3. RPC实践4. RPC与REST的区别4.1 RPC与REST的相似之处4.2 RPC与REST的架构原则4.3 RPC与REST的主要区别 5. RPC与服务发现5.1 以zookeeper为服务注册中心5.2 以etcd为服务注册中心 6. 小结参考 1. 什么是远程过程调用(RPC)?…

大语言模型诞生过程剖析

过程图如下 &#x1f4da; 第一步&#xff1a;海量文本的无监督学习 得到基座大模型&#x1f389; &#x1f50d; 原料&#xff1a;首先&#xff0c;我们需要海量的文本数据&#xff0c;这些数据可以来自互联网上的各种语料库&#xff0c;包括书籍、新闻、科学论文、社交媒体帖…