STM32 BootLoader 刷新项目 (十二) Option Byte之FLASH_OPTCR-命令0x58

STM32 BootLoader 刷新项目 (十二) Option Byte之FLASH_OPTCR-命令0x58

STM32F407芯片的OPTION Byte全面解析

STM32F407芯片是STMicroelectronics推出的一款功能强大的微控制器,广泛应用于工业控制、通信和消费电子等领域。其中,OPTION Byte(选项字节)是STM32系列芯片的重要配置功能,允许用户通过配置特定的寄存器,控制芯片的关键特性,例如启动模式、读保护和写保护等。

本文将分为8个章节,全面解析STM32F407芯片的OPTION Byte功能。


第一章:OPTION Byte 概述

1.1 什么是OPTION Byte?

OPTION Byte 是 STM32 系列芯片中一种特殊的配置区域,存储在片内闪存(Flash memory)中。它的主要作用是提供芯片启动、保护和工作模式等关键参数的配置选项。这些字节在系统启动时被加载到对应的配置寄存器中,影响芯片的行为。

1.2 OPTION Byte 的作用

OPTION Byte 的主要功能包括:

  1. 启动模式配置:选择芯片从主Flash、系统存储器或SRAM启动。
  2. 读保护(Read Out Protection, ROP):保护芯片中的数据不被非法读取。
  3. 写保护(Write Protection, WP):保护指定的Flash区域不被擦除或写入。
  4. BOR(Brown-Out Reset)电压等级:设置芯片的掉电检测电压等级。
  5. Watchdog配置:使能或禁止独立看门狗(IWDG)在芯片复位后启动。

Option Byte由最终用户根据应用需求进行配置。表14显示了这些字节在用户配置扇区内的组织结构。

image-20241128212547464

image-20241128212606075

image-20241128212713019

image-20241128212758865


1.3 Programming user option bytes

要在该扇区上执行任何操作,必须清除Flash选项控制寄存器(FLASH_OPTCR)中的选项锁定位(OPTLOCK)。为了允许清除此位,您需要按照以下步骤进行操作:

  1. 将Flash选项密钥寄存器(FLASH_OPTKEYR)中的OPTKEY1设置为0x0819 2A3B。

  2. 将Flash选项密钥寄存器(FLASH_OPTKEYR)中的OPTKEY2设置为0x4C5D 6E7F。

用户选项字节可以通过软件设置OPTLOCK位来防止不必要的擦除/编程操作。

Modifying user option bytes on STM32F405xx/07xx and STM32F415xx/17xx

要修改用户选项值,请按照以下顺序进行操作:

  1. 检查FLASH_SR寄存器中的BSY位,确保没有正在进行的Flash内存操作。
  2. 将所需的选项值写入FLASH_OPTCR寄存器。
  3. 在FLASH_OPTCR寄存器中设置选项启动位(OPTSTRT)。
  4. 等待BSY位被清除。
1.4 Write protections

FLASH_OPTCR 是 STM32F407 芯片中用于控制和配置 Option Byte 的关键寄存器。通过操作该寄存器,可以设置各种与芯片启动模式、安全性以及电压保护相关的功能。以下是对 FLASH_OPTCR 寄存器的详细介绍。

Flash存储器中最多可以保护24个用户扇区,以防止由于程序计数器上下文丢失而导致的不必要写操作。当FLASH_OPTCR或FLASH_OPTCR1寄存器中的非写保护nWRPi位(0 ≤ i ≤ 11)为低电平时,相应的扇区将无法被擦除或编程。因此,如果其中一个扇区受到写保护,则无法进行全片擦除。如果尝试对Flash存储器中受写保护部分(由写保护位、OTP部分锁定或永远不能被写入的ICP组成)进行擦除/编程操作,则会在FLASH_SR寄存器中设置写保护错误标志(WRPERR)。

image-20241128214504565

image-20241128214609809

image-20241128214622556


FLASH_OPTCR 寄存器定义

FLASH_OPTCR 是一个 32 位寄存器,其各位或各位段控制特定的 Option Byte 配置。

位段名称说明
[0]OPTLOCK选项锁位(Option Lock)
[1]OPTSTRT选项启动位(Option Start)
[2:3]BOR_LEV掉电复位电压等级(Brown-Out Reset Level)
[4]Reserved保留位
[5]WDG_SW独立看门狗模式选择(Software or Hardware IWDG)
[6]nRST_STOPSTOP模式复位禁用
[7]nRST_STDBYStandby模式复位禁用
[8:15]RDP读保护等级(Read Protection Level)
[16:27]WRP写保护配置(Write Protection for Flash Sectors)
[28:31]Reserved保留位

各字段详细解析
1. OPTLOCK(Option Lock) [0]
  • 说明:选项字节锁定位,用于保护 FLASH_OPTCR 寄存器不被意外修改。
    • 1:锁定 Option Byte。
    • 0:解锁 Option Byte。
  • 操作:需要先写入解锁密钥到 FLASH_OPTKEYR 寄存器,才能将此位清零解锁。
2. OPTSTRT(Option Start) [1]
  • 说明:选项启动位,用于触发 Option Byte 的写入操作。
    • 1:启动 Option Byte 写入。
    • 0:无操作。
  • 操作:在修改完 Option Byte 配置后,需将该位设置为 1 以启动写入。
3. BOR_LEV(Brown-Out Reset Level) [2:3]
  • 说明:配置 BOR 掉电复位的电压阈值。
    • 0000:BOR Level 0(最低电压复位,1.8V 至 2.1V)。
    • 0001:BOR Level 1(1.9V 至 2.4V)。
    • 0010:BOR Level 2(2.1V 至 2.7V)。
    • 0011:BOR Level 3(2.4V 至 2.9V)。
    • 其他值:保留。
  • 应用:在电源不稳定的场景中,可通过调整 BOR Level 确保 MCU 在电压异常时安全复位。
4. WDG_SW(Independent Watchdog Selection) [5]
  • 说明:独立看门狗模式选择。
    • 0:硬件模式(独立看门狗由硬件启动,不能由软件禁用)。
    • 1:软件模式(独立看门狗由软件启动,可以由软件控制)。
  • 应用:在安全关键场景中,硬件模式更可靠;而软件模式适合需要灵活控制的应用。
5. nRST_STOP(Stop Mode Reset Disable) [6]
  • 说明:STOP模式复位禁用。
    • 0:启用 STOP 模式下的复位。
    • 1:禁用 STOP 模式下的复位。
  • 应用:用于控制在进入 STOP 模式后,是否允许复位信号。
6. nRST_STDBY(Standby Mode Reset Disable) [7]
  • 说明:Standby模式复位禁用。
    • 0:启用 Standby 模式下的复位。
    • 1:禁用 Standby 模式下的复位。
  • 应用:与 nRST_STOP 类似,用于控制芯片在 Standby 模式的复位行为。
7. RDP(Read Protection Level) [8:15]
  • 说明:读保护等级。
    • 0xAA:无保护(Level 0)。
    • 0xBB:读保护(Level 1)。
    • 其他:高强度保护(Level 2,数据不可访问且不可恢复)。
  • 注意
    • 一旦进入 Level 2,芯片的 Flash 区域永久锁定。
    • 从 Level 1 回到 Level 0 需要擦除整个 Flash。
8. WRP(Write Protection) [16:27]
  • 说明:写保护设置,指定哪些 Flash 扇区受写保护。
  • :每个位对应一个扇区,1 表示受保护,0 表示不受保护。
  • 应用:在固件更新或调试时防止误擦写关键代码区域。

image-20241129081300295

使用 FLASH_OPTCR 的关键操作
1. 解锁 OPTION Byte

在写入 FLASH_OPTCR 之前,必须解锁 Option Byte:

FLASH->OPTKEYR = 0x08192A3B; // 解锁密钥1
FLASH->OPTKEYR = 0x4C5D6E7F; // 解锁密钥2
2. 配置 FLASH_OPTCR

修改寄存器中对应的字段。例如,启用读保护并设置 BOR 为 Level 3:

FLASH->OPTCR |= FLASH_OPTCR_RDP_0;       // 设置 RDP 为 Level 1
FLASH->OPTCR &= ~FLASH_OPTCR_BOR_LEV;    // 清除 BOR 配置
FLASH->OPTCR |= FLASH_OPTCR_BOR_LEV_2;   // 设置 BOR 为 Level 3
3. 启动写入

完成配置后,启动 Option Byte 写入:

FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT; // 启动写入
while (FLASH->SR & FLASH_SR_BSY);    // 等待操作完成
4. 锁定 OPTION Byte

写入完成后,重新锁定寄存器:

FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;

注意事项
  1. 配置不可逆性

    • 启用高强度读保护(RDP Level 2)后,Flash 数据无法访问且不可恢复。
    • 写保护或 RDP 配置的更改可能需要擦除整个芯片。
  2. 操作期间电源稳定

    • 写入 FLASH_OPTCR 时,如果电源中断可能导致芯片配置不完整,甚至不可用。
  3. 调试工具可能受限

    • 启用读保护或写保护后,调试接口(如 JTAG/SWD)可能受限或失效。

总结

FLASH_OPTCR 是 STM32F407 OPTION Byte 配置的核心寄存器,允许用户灵活控制芯片的关键功能。通过正确配置该寄存器,可以在安全性、电源稳定性和启动模式等方面大大增强 STM32 应用的可靠性。

第二章:OPTION Byte 的应用场景

1. 安全数据保护

在需要对数据高度保护的场景,例如密码存储或商业机密数据处理,启用读保护功能(ROP)可以有效防止未经授权的访问。

2. 启动模式选择

在嵌入式开发中,不同应用可能需要芯片从不同的存储介质启动。例如:

  • 开发阶段,可以选择从系统存储器启动,以便使用ST的内置Bootloader进行固件更新。
  • 生产阶段,可以配置从主Flash启动,以运行正式固件。
3. 固件更新保护

通过启用写保护功能(WP),开发者可以锁定Flash的某些区域,防止意外或恶意擦写,从而保护固件的完整性。

4. 电源稳定性管理

在电源波动较大的场景中,通过调整BOR电压等级,确保芯片在特定电压下安全复位,避免错误行为。


第三章:OPTION Byte 配置操作步骤

1. 确认配置需求

在更改OPTION Byte之前,确定需要配置的功能,例如启用读保护或调整BOR电压等级。

2. 解锁Flash控制器

在STM32F407中,OPTION Byte 存储在Flash中,因此需要解锁Flash控制器(Flash Control Register, FLASH_CR)以允许修改。

3. 修改OPTION Byte

通过操作特定寄存器(FLASH_OPTCR 或 FLASH_OPTCR1),将所需的配置值写入OPTION Byte。

4. 启动OPTION Byte 加载

配置完成后,触发重新加载以使更改生效。

5. 验证配置

通过读取相关寄存器,确认OPTION Byte的配置已成功应用。


第四章:代码实现(详细注释)Demo示例

以下代码展示如何配置STM32F407的OPTION Byte,以启用读保护和调整BOR电压等级。

#include "stm32f4xx.h"

// 函数声明
void Flash_Unlock(void);
void Configure_OPTION_Bytes(void);

int main(void) {
    // 解锁Flash控制器
    Flash_Unlock();
    
    // 配置OPTION Byte
    Configure_OPTION_Bytes();
    
    while (1) {
        // 主循环
    }
}

// 解锁Flash控制器函数
void Flash_Unlock(void) {
    if ((FLASH->CR & FLASH_CR_LOCK) != 0) {
        // 解锁KEY1
        FLASH->KEYR = 0x45670123;
        // 解锁KEY2
        FLASH->KEYR = 0xCDEF89AB;
    }
}

// 配置OPTION Byte函数
void Configure_OPTION_Bytes(void) {
    // 解锁OPTION Byte
    if ((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != 0) {
        FLASH->OPTKEYR = 0x08192A3B; // 解锁KEY1
        FLASH->OPTKEYR = 0x4C5D6E7F; // 解锁KEY2
    }
    
    // 修改OPTION Byte
    // 启用读保护(Level 1)
    FLASH->OPTCR |= FLASH_OPTCR_RDP_0; 

    // 配置BOR电压为Level 3(最严格)
    FLASH->OPTCR &= ~FLASH_OPTCR_BOR_LEV; // 清除BOR配置
    FLASH->OPTCR |= FLASH_OPTCR_BOR_LEV_2; // 设置BOR为Level 3
    
    // 启动OPTION Byte写入
    FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT;
    
    // 等待操作完成
    while ((FLASH->SR & FLASH_SR_BSY) != 0);
    
    // 锁定OPTION Byte
    FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
}
代码解析
  1. 解锁Flash控制器和OPTION Byte

    • STM32的Flash和OPTION Byte均受锁机制保护,需先解锁后才能修改。
  2. 设置读保护和BOR等级

    • 使用 FLASH_OPTCR 寄存器进行配置。
    • 读保护(RDP)设为 Level 1(禁止非法读取)。
    • BOR电压配置为 Level 3(最高复位电压)。
  3. 触发写入并等待完成

    • 设置 OPTSTRT 位后,硬件会自动将更改写入Flash。

第五章:使用OPTION Byte的注意事项

1. 配置的不可逆性

某些配置(如读保护启用)具有不可逆性。一旦启用,降低保护等级可能需要擦除整个芯片数据。

2. 注意芯片的电源状态

在配置OPTION Byte时,确保芯片电源稳定,否则可能导致写入失败或数据损坏。

3. 调试时的风险

调试过程中,不建议随意更改OPTION Byte,尤其是启用读保护后,调试接口可能失效。

4. 启用写保护的影响

启用写保护后,程序固件的某些部分将无法更新。需提前规划好保护区域。


总结

STM32F407芯片的OPTION Byte功能强大,提供了多种关键配置选项。在实际应用中,开发者需要根据需求谨慎配置,以确保芯片的安全性和稳定性。通过本教程的详细步骤和代码示例,相信您已经掌握了如何在STM32F407上高效使用OPTION Byte功能,为嵌入式项目提供强有力的支持。

下面我们开始介绍BootLoader的使能读写保护命令。

第六章:0x58命令介绍–使能读写保护

在本篇文章,我们的主要是介绍0x58的命令,这个命令主要是在BootLoader中使能Flash Sector的读写保护。

通过上位机发送8 Byte的数据,其中第1 Byte为整个数据的长度,第2Byte为指令码,第3 Byte为写入要保护Sector段,第4 Byte是保护模式,1是写保护,2是读写保护,5-8 Byte为前4 Byte的CRC校验值,上位机通过串口UART发送给下位机,下位机回复地址是否写入成功的标志。

image-20241128220737877

下面是发送命令过程中上位机与BootLoader之间的交互。

image-20241114230607647

第七章:使能读写保护-0x58 命令BootLoader程序设计

代码逻辑和功能解释
1. bootloader_uart_read_data() 函数
void bootloader_uart_read_data(void) 
{ 
    uint8_t rcv_len = 0; 
    printmsg_Host("BL_DEBUG_MSG: Receive CMD\n\r"); // 调试信息:接收命令 

    while (1) 
    { 
        // 点亮LED,表示进入命令处理
        HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET); 

        // 清空接收缓冲区
        memset(bl_rx_buffer, 0, 200); 

        // 步骤1:接收命令包的第一个字节(长度字段)
        HAL_UART_Receive(C_UART, bl_rx_buffer, 1, HAL_MAX_DELAY); 
        rcv_len = bl_rx_buffer[0]; 

        // 步骤2:根据长度字段接收剩余的命令包
        HAL_UART_Receive(C_UART, &bl_rx_buffer[1], rcv_len, HAL_MAX_DELAY); 

        // 步骤3:根据命令代码调用对应的命令处理函数
        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; 
            default: 
                // 如果命令无效,打印调试信息
                printmsg("BL_DEBUG_MSG: Invalid command code received from host \n"); 
                break; 
        } 
    } 
}

功能:

  • 这是引导程序的主要任务循环,负责接收主机通过 UART 发来的命令数据包并调用相应的处理函数。

逻辑解析:

  1. 命令接收:

    • 使用 HAL_UART_Receive 接收数据:
      • 首先接收数据包长度字段(bl_rx_buffer[0])。
      • 然后根据长度接收完整的命令数据包。
    • 通过命令码(bl_rx_buffer[1])解析当前命令。
  2. 命令分发:

    • 根据命令码,调用相应的处理函数:
      • BL_GET_VER 调用 bootloader_handle_getver_cmd()
      • BL_EN_RW_PROTECT 调用 bootloader_handle_en_rw_protect()
    • 如果命令码无效,则打印调试信息。

总结:
bootloader_uart_read_data() 是引导程序的任务调度中心,通过 UART 接收命令并分发到相应的处理逻辑。


2. bootloader_handle_en_rw_protect(uint8_t *pBuffer) 函数
void bootloader_handle_en_rw_protect(uint8_t *pBuffer) 
{ 
    uint8_t status = 0x00; 
    printmsg("BL_DEBUG_MSG: bootloader_handle_endis_rw_protect\n"); // 调试信息:处理读写保护命令 

    // 计算命令包的总长度
    uint32_t command_packet_len = bl_rx_buffer[0] + 1; 

    // 提取主机发送的CRC32校验码
    uint32_t host_crc = *((uint32_t *)(bl_rx_buffer + command_packet_len - 4)); 

    // 步骤1:校验CRC是否正确
    if (!bootloader_verify_crc(&bl_rx_buffer[0], command_packet_len - 4, host_crc)) 
    { 
        printmsg("BL_DEBUG_MSG: checksum success !!\n"); // CRC校验成功 

        // 发送ACK响应主机
        bootloader_send_ack(pBuffer[0], 1); 

        // 步骤2:配置Flash扇区的读写保护
        status = configure_flash_sector_rw_protection(pBuffer[2], pBuffer[3], 0); 

        printmsg("BL_DEBUG_MSG: flash erase status: %#x\n", status); // 打印保护配置状态 

        // 步骤3:将配置状态返回给主机
        bootloader_uart_write_data(&status, 1); 
    } 
    else 
    { 
        printmsg("BL_DEBUG_MSG: checksum fail !!\n"); // CRC校验失败 

        // 如果校验失败,发送NACK
        bootloader_send_nack(); 
    } 
}

功能:

  • 解析和处理 BL_EN_RW_PROTECT 命令,用于对闪存扇区进行读写保护的启用。

逻辑解析:

  1. 解析命令数据包:

    • 计算数据包总长度:command_packet_len = bl_rx_buffer[0] + 1
    • 提取数据包中的 CRC 校验值(末尾 4 字节)。
  2. 校验数据完整性:

    • 调用 bootloader_verify_crc 对数据包进行 CRC 校验:
      • 如果校验成功:
        • 调用 bootloader_send_ack() 发送 ACK。
        • 调用 configure_flash_sector_rw_protection() 配置扇区保护。
        • 返回操作状态。
      • 如果校验失败:
        • 调用 bootloader_send_nack() 发送 NACK。
  3. 处理闪存保护配置:

    • 从数据包中解析 pBuffer[2]pBuffer[3],确定扇区选择和保护模式。

总结:
bootloader_handle_en_rw_protect() 负责解析 BL_EN_RW_PROTECT 命令,实现对闪存扇区的读写保护配置,并通过 CRC 校验确保命令数据的完整性。


3. configure_flash_sector_rw_protection(uint8_t sector_details, uint8_t protection_mode, uint8_t disable) 函数
uint8_t configure_flash_sector_rw_protection(uint8_t sector_details, uint8_t protection_mode, uint8_t disable)
{
    // Flash选项控制寄存器地址
    volatile uint32_t *pOPTCR = (uint32_t*) 0x40023C14;

    if(disable)
    {
        // 禁用所有扇区的读写保护

        // 解锁选项字节配置
        HAL_FLASH_OB_Unlock();

        // 等待Flash完成当前操作
        while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET);

        // 清除OPTCR寄存器的第31位以禁用保护
        *pOPTCR &= ~(1 << 31);

        // 将所有与扇区相关的保护位设置为1(无保护)
        *pOPTCR |= (0xFF << 16);

        // 设置OPTSTRT位以启动选项字节编程
        *pOPTCR |= (1 << 1);

        // 等待Flash完成当前操作
        while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET);

        // 锁定选项字节配置
        HAL_FLASH_OB_Lock();

        return 0;
    }

    if(protection_mode == (uint8_t) 1)
    {
        // 设置仅写保护

        // 解锁选项字节配置
        HAL_FLASH_OB_Unlock();

        // 等待Flash完成当前操作
        while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET);

        // 清除OPTCR寄存器的第31位
        *pOPTCR &= ~(1 << 31);

        // 设置写保护,修改相应扇区的位(sector_details指定了具体的扇区)
        *pOPTCR &= ~(sector_details << 16);

        // 设置OPTSTRT位以启动选项字节编程
        *pOPTCR |= (1 << 1);

        // 等待Flash完成当前操作
        while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET);

        // 锁定选项字节配置
        HAL_FLASH_OB_Lock();
    }
    else if (protection_mode == (uint8_t) 2)
    {
        // 设置读写保护

        // 解锁选项字节配置
        HAL_FLASH_OB_Unlock();

        // 等待Flash完成当前操作
        while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET);

        // 设置OPTCR寄存器的第31位以启用读写保护
        *pOPTCR |= (1 << 31);

        // 配置选定扇区的读写保护
        *pOPTCR &= ~(0xff << 16);
        *pOPTCR |= (sector_details << 16);

        // 设置OPTSTRT位以启动选项字节编程
        *pOPTCR |= (1 << 1);

        // 等待Flash完成当前操作
        while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET);

        // 锁定选项字节配置
        HAL_FLASH_OB_Lock();
    }

    return 0;
}

功能:

  • 通过修改 FLASH 选项控制寄存器(OPTCR)实现对闪存扇区的读写保护配置。

逻辑解析:

  1. 参数解析:

    • sector_details:扇区选择(通过每个位表示不同扇区)。
    • protection_mode:保护模式:
      • 1 表示仅写保护。
      • 2 表示读写保护。
    • disable:是否禁用所有保护。
  2. 禁用保护:

    • 解锁选项字节(HAL_FLASH_OB_Unlock())。
    • 清除保护位:
      • 清除 OPTCR 寄存器的第 31 位。
      • 设置扇区保护位为默认值(所有扇区解除保护)。
    • 启动保护配置(设置 OPTSTRT 位)。
    • 等待操作完成(检查 FLASH_FLAG_BSY 标志)。
  3. 写保护:

    • 解锁选项字节。
    • 清除第 31 位,表示启用写保护模式。
    • 修改目标扇区的保护位。
    • 设置 OPTSTRT 位,启动保护配置。
  4. 读写保护:

    • 解锁选项字节。
    • 设置第 31 位,表示启用读写保护模式。
    • 修改目标扇区的保护位。
    • 设置 OPTSTRT 位,启动保护配置。

总结:
configure_flash_sector_rw_protection() 实现了对闪存扇区保护配置的底层操作,包括禁用保护、写保护和读写保护的具体实现,直接操控 STM32 的 FLASH 寄存器。


综合总结
  1. 任务调度:
    • bootloader_uart_read_data() 是主任务函数,负责接收主机命令并调用对应处理逻辑。
  2. 命令解析:
    • bootloader_handle_en_rw_protect() 是特定命令处理函数,用于启用闪存扇区保护,包含数据解析、CRC 校验及状态返回。
  3. 硬件操作:
    • configure_flash_sector_rw_protection() 是底层函数,通过直接操作 FLASH 控制寄存器完成保护配置。

通过以上函数协同工作,STM32 引导程序能够接收主机命令并对闪存扇区实现灵活的保护管理。

第八章:BootLoader实战操作

下面是上位机的命令菜单,通过在终端调用Python脚本,然后在终端输入下位机连接的串口号,即可进入命令界面,目前可支持如下命令:

image-20240713104433991

下面选择命令9,输入要保护的Flash的段,向下位机发送信息。

image-20241201090151204

下面判断Flash保护是否成功,发送命令11,读出保护状态,发现Secotr 3,4,5处于写保护状态Write Protection。

image-20241201090320570

下面输入命令13,关闭所有的段保护

image-20241201090430382

在一次判断段保护状态,输入命令11,发现读写保护状态,发现所有保护状态处于No Protection,发现之前的命令13成功。

image-20241201090549140

第九章. 系列文章

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

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

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

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

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

STM32 BootLoader 刷新项目 (六) 获取帮助-命令0x52

STM32 BootLoader 刷新项目 (七) 获取芯片ID-0x53

STM32 BootLoader 刷新项目 (八) 读取Flash保护ROP-0x54

STM32 BootLoader 刷新项目 (九) 跳转指定地址-命令0x55

[STM32 BootLoader 刷新项目 (十) Flash擦除-命令0x56](STM32 BootLoader 刷新项目 (十) Flash擦除-命令0x56-CSDN博客)

STM32 BootLoader 刷新项目 (十一) Flash写操作-命令0x57

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

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

相关文章

Matlab 绘制雷达图像完全案例和官方教程(亲测)

首先上官方教程链接 polarplothttps://ww2.mathworks.cn/help/matlab/ref/polarplot.html 上实例 % 定义角度向量和径向向量 theta linspace(0, 2*pi, 5); r1 [1, 2, 1.5, 2.5, 1]; r2 [2, 1, 2.5, 1.5, 2];% 绘制两个雷达图 polarplot(theta, r1, r-, LineWidth, 2); hold …

【C/C++】内存管理详解:从new/delete到智能指针的全面解析

文章目录 更多文章C/C中的传统内存管理方式new和delete运算符malloc和free函数传统内存管理的弊端 智能指针的崛起智能指针的定义与作用C11引入的标准智能指针 详解C标准智能指针std::unique_ptr特点使用方法适用场景 std::shared_ptr特点使用方法适用场景 std::weak_ptr特点使…

Python实现2048小游戏

2048是一个单人益智游戏&#xff0c;目标是移动和合并数字&#xff0c;以达到2048。 1. 实现效果 Python实现2048小游戏 2. 游戏规则 简单地理解一下规则 基本规则&#xff1a; 4x4棋盘&#xff0c;每个格可包含一个2的倍数的数字&#xff0c;初始时为空&#xff0c;表示0。…

Wireshark常用功能使用说明

此处用于记录下本人所使用 wireshark 所可能用到的小技巧。Wireshark是一款强大的数据包分析工具&#xff0c;此处仅介绍常用功能。 Wireshark常用功能使用说明 1.相关介绍1.1.工具栏功能介绍1.1.1.时间戳/分组列表概况等设置 1.2.Windows抓包 2.wireshark过滤器规则2.1.wiresh…

像素流送api ue多人访问需要什么显卡服务器

关于像素流送UE推流&#xff0c;在之前的文章里其实小芹和大家聊过很多&#xff0c;不过今天偶然搜索发现还是有很多小伙伴&#xff0c;在搜索像素流送相关的问题&#xff0c;搜索引擎给的提示有这些。当然这些都是比较短的词汇&#xff0c;可能每个人真正遇到的问题和想获取的…

基于Vue3+Element Plus 实现多表单校验

使用场景 表单校验在日常的开发需求中是一种很常见的需求&#xff0c;通常在提交表单发起请求前校验用户输入是否符合规则&#xff0c;通常只需formRef.value.validate()即可校验&#xff0c;但是&#xff0c;例如一些多步骤表单、动态表单、以及不同的用户角色可能看到不同的表…

ONVIF协议网络摄像机客户端使用gsoap获取RTSP流地址GStreamer拉流播放

什么是ONVIF协议 ONVIF&#xff08;开放式网络视频接口论坛&#xff09;是一个全球性的开放式行业论坛&#xff0c;旨在促进开发和使用基于物理IP的安全产品接口的全球开放标准。 ONVIF规范的目标是建立一个网络视频框架协议&#xff0c;使不同厂商生产的网络视频产品完全互通。…

【Datawhale组队学习】模型减肥秘籍:模型压缩技术6——项目实践

NNI (Neural Network Intelligence) 是由微软开发的一个开源自动化机器学习&#xff08;AutoML&#xff09;库&#xff0c;用于帮助研究人员和开发人员高效地进行机器学习实验。它提供了一套丰富的工具来进行模型调优、神经网络架构搜索、模型压缩以及自动化的超参数搜索。 1…

通讯专题4.1——CAN通信之计算机网络与现场总线

从通讯专题4开始&#xff0c;来学习CAN总线的内容。 为了更好的学习CAN&#xff0c;先从计算机网络与现场总线开始了解。 1 计算机网络体系的结构 在我们生活当中&#xff0c;有许多的网络&#xff0c;如交通网&#xff08;铁路、公路等&#xff09;、通信网&#xff08;电信、…

【51单片机】程序实验910.直流电机-步进电机

主要参考学习资料&#xff1a;B站【普中官方】51单片机手把手教学视频 前置知识&#xff1a;C语言 单片机套装&#xff1a;普中STC51单片机开发板A4标准版套餐7 码字不易&#xff0c;求点赞收藏加关注(•ω•̥) 有问题欢迎评论区讨论~ 目录 程序实验9&10.直流电机-步进电机…

Qt支持RKMPP硬解的视频监控系统/性能卓越界面精美/实时性好延迟低/录像存储和回放/云台控制

一、前言 之前做的监控系统&#xff0c;已经实现了在windows上硬解码比如dxva2和d3d11va&#xff0c;后续又增加了linux上的硬解vdpau的支持&#xff0c;这几种方式都是跨系统的硬解实现方案&#xff0c;也是就是如果都是windows系统&#xff0c;无论X86还是ARM都通用&#xf…

Web API基本认知

作用和分类 作用&#xff1a;就是使用JS去操作html和浏览器 分类&#xff1a;DOM&#xff08;文档对象模型&#xff09;、BOM&#xff08;浏览器对象模型&#xff09; 什么是DOM DOM&#xff08;Document Object Model ——文档对象模型&#xff09;是用来呈现以及与任意 HTM…

Linux——自定义简单shell

shell 自定义shell目标普通命令和内建命令&#xff08;补充&#xff09; shell实现实现原理实现代码 自定义shell 目标 能处理普通命令能处理内建命令要能帮助我们理解内建命令/本地变量/环境变量这些概念理解shell的运行 普通命令和内建命令&#xff08;补充&#xff09; …

智能桥梁安全运行监测系统守护桥梁安全卫士

一、方案背景 桥梁作为交通基础设施中不可或缺的重要组成部分&#xff0c;其安全稳定的运行直接关联到广大人民群众的生命财产安全以及整个社会的稳定与和谐。桥梁不仅是连接两地的通道&#xff0c;更是经济发展和社会进步的重要纽带。为了确保桥梁的安全运行&#xff0c;桥梁安…

【Python网络爬虫笔记】5-(Request 带参数的get请求) 爬取豆瓣电影排行信息

目录 1.抓包工具查看网站信息2.代码实现3.运行结果 1.抓包工具查看网站信息 请求路径 url:https://movie.douban.com/typerank请求参数 页面往下拉&#xff0c;出现新的请求结果&#xff0c;参数start更新&#xff0c;每次刷新出20条新的电影数据 2.代码实现 # 使用网络爬…

新质驱动·科东软件受邀出席2024智能网联+低空经济暨第二届湾区汽车T9+N闭门会议

为推进广东省加快发展新质生产力&#xff0c;贯彻落实“百县千镇万村高质量发展工程”&#xff0c;推动韶关市新丰县智能网联新能源汽车、低空经济与数字技术的创新与发展&#xff0c;充分发挥湾区汽车产业链头部企业的带动作用。韶关市指导、珠三角湾区智能网联新能源汽车产业…

C#使用ExcelDataReader读取Xlsx文件为DataTable对象

创建控制台项目 在NuGet中安装ExcelDataReader.DataSet 3.7.0 创建一个xlsx文件 测试代码 读取xlsx文件内容&#xff0c;为一个DataTable对象。 读取xlsx时&#xff0c;xlsx文件不能被其他软件打开&#xff0c;否则会报“进程无法访问此文件”的错。 using ExcelDataRead…

“harmony”整合不同平台的单细胞数据之旅

其实在Seurat v3官方网站的Vignettes中就曾见过该算法&#xff0c;但并没有太多关注&#xff0c;直到看了北大张泽民团队在2019年10月31日发表于Cell的《Landscap and Dynamics of Single Immune Cells in Hepatocellular Carcinoma》&#xff0c;为了同时整合两类数据&#xf…

智慧银行反欺诈大数据管控平台方案(一)

智慧银行反欺诈大数据管控平台建设方案的核心在于通过整合先进的大数据技术和深度学习算法&#xff0c;打造一个全面、智能且实时的反欺诈系统&#xff0c;以有效识别、预防和应对各类金融欺诈行为。该方案涵盖数据采集、存储、处理和分析的全流程&#xff0c;利用多元化的数据…

基于 JNI + Rust 实现一种高性能 Excel 导出方案(上篇)

每个不曾起舞的日子,都是对生命的辜负。 ——尼采 一、背景:Web 导出 Excel 的场景 Web 导出 Excel 功能在数据处理、分析和共享方面提供了极大的便利,是许多 Web 应用程序中的重要功能。以下是一些典型的场景: 数据报表导出:在企业管理系统(如ERP、CRM)中,用户经常需…