发布于: 2025-5-3最后更新: 2025-8-15字数 2237阅读时长 6 分钟

type
status
date
slug
summary
tags
category
icon
password
学习链接

原理

STM32F103C8T6:SRAM 20KB (起始地址:0x2000 0000)
FLASH 64KB (地址:0x0800 0000 - 0x0800 FFFF)
32位:4字节(Byte) 映射成地址【十六进制】0x0000 0000 - 0xFFFF FFFF
【二进制】2^32=4,294,967,296个地址,一个地址代表1bit,总共可以映射4Gb
在现代计算机体系中,内存寻址都是`字节寻址`,因此,一个32位的系统理论上可以拥有 4,294,967,296 个不同的地址,所以代表4,294,967,296Byte(字节),即4GB。一个32位系统,其理论上最大可以寻址的内存空间是 4 GB (GigaBytes)。

概述

notion image
作用:
1.没有OTA时,A区直接跳转B区
2.给B区更新程序
3.串口IAP(本地串口升级)
4.在线平台升级时,设置version保存在eeprom
5.使用W25Q64,不同任务切换

Step1.串口

总体方案:DMA + 空闲中断
notion image
关系:
|- IN OUT END 三个指针
|- 以结构体mark为元素的数组,单个元素指向单次串口传输的开头与结尾
|- 存放数据的缓冲区
简要概述:
1.END指针始终指向数组的结尾,作为边界,防止IN END数组越界
2.在空闲中断中,将end指针指向数据的结尾,start指针移动指向下一组数据的开始并告诉给DMA
3.IN类似写入,控制结构体数组
 

实际操作

串口空闲中断+DMA+缓冲区重新整理
notion image
1.关于缓冲区和结构体指针数组,首先都要防止数组越界。可抽象成环形缓冲区。
关于缓冲区主要判断缓冲区大小够不够下一次传输(buffer_size),如果不够则回卷
结构体数组判断IN/OUT指针的值是否等于END指针的值,等于则进行回卷
2.IN为写入,OUT为读取,初始化时都指向结构体数组的起始地址,如果IN=OUT说明没有写入值。
3.DMA单次传输完成,根据DMA函数计算出规定的(buffer_size)剩余的大小,可以得出当前写入的字节,从而确定IN[i].end和IN[i].start指向的位置,并根据这些值判断是否进行回卷。
1.初始化GPIO,USART(DMA+空闲中断),NVIC,DMA
code
2.初始化IN OUT END 指针指向特定位置,并将计数置0。
code
3.核心流程
4.测试读取(printf重定向+缓冲区读取)
code

代码地址(usart_dama)

 

Step2.W25Q64&内部flash

特别注意:SPI的收与发是同时进行的,意味着在一些SPI外设,发送寄存器指令后,本次接收到的是无效数据,下一次接收到的才是目标数据。

W25Q64

结构:总大小8MB → 128块(64KB/块) → 16扇区(4KB/扇) → 16页(256B/页)
命令表:
notion image
从表中可以看出擦除是以 扇区扇区为单位进行擦除的,而写入是以 为单位写入。
每个地址对应一个字节(Byte),地址计算如下:
块地址: blockID * 64 * 1024
扇地址:sectorID * 4 * 1024
页地址:pageID * 256
核心:
1.先擦除,后写入:Flash 存储器的特性决定了只能将 1 改为 0,不能直接将 0 改为 1。因此,在写入新数据前,必须先将对应的存储区域擦除。擦除后,该区域的所有位都将变为 1 (即 0xFF)。 2.写使能 (Write Enable):W25Q64 为了防止误操作,规定在执行任何“擦除”或“写入”命令之前,都必须先发送一个“写使能”命令 (0x06)。 3.等待忙碌状态结束:无论是擦除还是写入,都需要一定的时间来完成(擦除尤其耗时)。在此期间,芯片会处于“忙碌”状态。必须通过读取状态寄存器,等待“BUSY”标志位变为 0 后,才能进行下一步操作。

单片机内部FLASH

ps:此模块在数据手册没有对应章节,需要查阅官方FLASH编程手册
pm0075-stm32f10xxx-flash-memory-microcontrollers.pdf
与操作外部 SPI Flash 需要发送指令不同,操作 STM32 内部 Flash 是通过直接读写内部的闪存接口寄存器 (FPEC) 来完成的。库函数(如 FLASH_ErasePage)已经封装好了这些复杂的操作。
其标准流程可以概括为 “解锁 -> 擦除 -> 写入 -> 锁定”。

步骤

Step 1: 解锁 Flash (Unlock) 目的:为了防止程序意外修改 Flash 内容(尤其是程序代码区),Flash 控制器在默认情况下是锁定的,禁止任何擦除和写入操作。 操作:在进行任何写/擦操作之前,必须先调用 FLASH_Unlock() 来解除保护。
 
Step 2: 擦除页面 (Erase Page) 原则:先擦除,后写入。Flash 只能从 1 变为 0,不能从 0 变为 1。擦除操作会将指定区域的所有位都置为 1 (即 0xFFFFFFFF)。 单位:内部 Flash 的最小擦除单位是 页 (Page)。对于 STM32F103 系列,一页通常是 1KB(小容量型号)或 2KB(大容量型号)。stm32f103c8t6则是64Kflash,一页1KB。 操作: 等待就绪:擦除操作需要时间。在发送擦除命令前,必须通过 while(FLASH_GetStatus() == FLASH_BUSY); 来等待上一个操作完成,确保 Flash 控制器处于空闲状态。 执行擦除:调用 FLASH_ErasePage(Page_Address),传入要擦除的页的起始地址。
 
Step 3: 写入数据 (Program) 单位:对于 STM32F1 系列,写入的基本单位是 字 (Word, 32位) 或 半字 (Half-Word, 16位)。 操作: 等待就绪:与擦除一样,每次写入前都必须用 while(FLASH_GetStatus() == FLASH_BUSY); 等待 Flash 控制器空闲。 执行写入:调用 FLASH_ProgramWord(Address, Data),传入要写入的绝对地址和32位数据。
 
Step 4: 锁定 Flash (Lock) 目的:操作完成后,为了安全起见,应重新锁定 Flash,防止后续代码意外改动。 操作:调用 FLASH_Lock()。
 
Step 5: 读取数据 (Read) 特点:读取 Flash 不需要任何特殊操作! 操作:STM32 的 Flash 和 RAM 一样,是统一编址的。只需要知道数据的绝对地址,就可以像读取一个普通变量或数组一样,通过指针直接读取。

代码地址(w25q64&flash)

 

Step3.构建BootLoader程序

 

Loading...
扩展-ARM Cortex-M3M4 Processor

扩展-ARM Cortex-M3M4 Processor


从提问中获取知识

Lazy loaded image从提问中获取知识