libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
LibXR::STM32Flash Class Reference

STM32 闪存驱动实现 / STM32 flash driver implementation. More...

#include <stm32_flash.hpp>

Inheritance diagram for LibXR::STM32Flash:
[legend]
Collaboration diagram for LibXR::STM32Flash:
[legend]

Public Member Functions

 STM32Flash (const FlashRegion *regions, size_t region_count, uint32_t start_address)
 构造闪存对象 / Construct flash object
 
 STM32Flash (const FlashRegion *regions, size_t region_count)
 用末尾两个扇区构造,供 DatabaseRaw 的主块和备份块使用 / Construct with the last two sectors, for the main and backup blocks of DatabaseRaw
 
ErrorCode Erase (size_t offset, size_t size) override
 擦除闪存的指定区域 / Erases a section of the flash memory.
 
ErrorCode Write (size_t offset, ConstRawData data) override
 向闪存写入数据 / Writes data to the flash memory.
 
- Public Member Functions inherited from LibXR::Flash
 Flash (size_t min_erase_size, size_t min_write_size, RawData flash_area)
 构造函数,初始化闪存属性。 Constructs a Flash object with specified properties.
 
virtual ErrorCode Read (size_t offset, RawData data)
 从闪存中读取数据 / Reads data from the flash memory.
 
size_t MinEraseSize () const
 获取最小可擦除块大小(字节)。 Returns the minimum erasable block size in bytes.
 
size_t MinWriteSize () const
 获取最小可写块大小(字节) / Returns the minimum writable block size in bytes.
 
size_t Size () const
 获取闪存存储区域的大小 / Returns the size of the flash memory area.
 

Static Public Attributes

static constexpr size_t MIN_WRITE_SIZE = STM32FlashMinWriteSize()
 最小写入单位(字节),由 HAL 的 FLASH_TYPEPROGRAM_* 宏确定;可直接作为 DatabaseRaw 的模板参数 / Minimum write unit in bytes, determined from the HAL FLASH_TYPEPROGRAM_* macros; usable directly as the DatabaseRaw template argument
 

Detailed Description

STM32 闪存驱动实现 / STM32 flash driver implementation.

Precondition
擦写调用及相关缓存控制由调用方串行化;等待期间 HAL tick 必须能推进。 The caller serializes erase/program calls and related cache control; the HAL tick must advance during waits.
Note
擦写期间暂时关闭相关缓存;进入擦写流程后,成功或失败返回均恢复缓存开关并锁定 Flash。 Related caches are temporarily disabled during erase/program operations. Once the operation starts, success and failure returns restore the original cache enable state and lock Flash.
扇区表须从 Flash 起始地址开始,按地址用若干段列出整片 Flash 的扇区或页;一段可以 跨 bank。擦除时按地址判断所在 bank,H5、H7 和使用 Page 字段的系列按 bank 内序号擦除, F2/F4/F7 按跨 bank 的扇区号擦除。不支持 bank 交换(SWAP_BANK、BFB2 等选项字节)。 The sector table must list the sectors or pages of the whole Flash in address order as runs, starting at the Flash base; a run may cross a bank boundary. Erase takes the bank from the address; H5, H7 and the families with a Page field erase by the number within the bank, F2/F4/F7 by the sector number across both banks. Bank swap (SWAP_BANK, BFB2 and similar option bytes) is not supported.

Definition at line 137 of file stm32_flash.hpp.

Constructor & Destructor Documentation

◆ STM32Flash() [1/2]

STM32Flash::STM32Flash ( const FlashRegion * regions,
size_t region_count,
uint32_t start_address )

构造闪存对象 / Construct flash object

Parameters
regions扇区表 / Sector table
region_count扇区表的段数 / Number of runs in the sector table
start_address存储区的起始地址,须正好是某个扇区的起点;存储区一直到 Flash 末尾 / Start address of the storage area; must be exactly the start of a sector; the area extends to the end of the Flash

Definition at line 123 of file stm32_flash.cpp.

125 : Flash(SectorSizeAt(regions, region_count, start_address), MIN_WRITE_SIZE,
126 {reinterpret_cast<void*>(start_address),
127 TableEnd(regions, region_count) - start_address}),
128 regions_(regions),
129 base_address_(start_address),
130 program_type_(DetermineProgramType()),
131 region_count_(region_count)
132{
133}
Flash(size_t min_erase_size, size_t min_write_size, RawData flash_area)
构造函数,初始化闪存属性。 Constructs a Flash object with specified properties.
Definition flash.cpp:7
static constexpr size_t MIN_WRITE_SIZE
最小写入单位(字节),由 HAL 的 FLASH_TYPEPROGRAM_* 宏确定;可直接作为 DatabaseRaw 的模板参数 / Minimum write unit in bytes,...

◆ STM32Flash() [2/2]

STM32Flash::STM32Flash ( const FlashRegion * regions,
size_t region_count )

用末尾两个扇区构造,供 DatabaseRaw 的主块和备份块使用 / Construct with the last two sectors, for the main and backup blocks of DatabaseRaw

Parameters
regions扇区表 / Sector table
region_count扇区表的段数 / Number of runs in the sector table

Definition at line 135 of file stm32_flash.cpp.

136 : STM32Flash(regions, region_count, SecondToLastSector(regions, region_count))
137{
138}
STM32Flash(const FlashRegion *regions, size_t region_count, uint32_t start_address)
构造闪存对象 / Construct flash object

Member Function Documentation

◆ Erase()

ErrorCode STM32Flash::Erase ( size_t offset,
size_t size )
overridevirtual

擦除闪存的指定区域 / Erases a section of the flash memory.

Parameters
offset要擦除的起始偏移地址 / The starting offset of the section to erase.
size要擦除的区域大小 / The size of the section to erase.
Returns
返回操作结果的错误码 / ErrorCode indicating success or failure.

Implements LibXR::Flash.

Definition at line 140 of file stm32_flash.cpp.

141{
142 if (size == 0)
143 {
144 return ErrorCode::ARG_ERR;
145 }
146
147 uint32_t start_addr = base_address_ + offset;
148 uint32_t end_addr = start_addr + size;
149
150 FlashOperationGuard operation;
151
152 // 表按地址排列;index 是跨段的扇区序号,bank_entries 记录每个 bank 中已经走过的扇区
153 // 数,即下一个扇区在该 bank 内的序号。bank 2 的起点由表给出,小容量型号上它与 bank 1
154 // 之间可能有空洞(如 H743xG 在 0x08100000,G474xC 在 0x08040000)。
155 // The table is ordered by address; index is the sector number across runs, and
156 // bank_entries counts the sectors already passed in each bank, which is the next
157 // sector's number within that bank. The table gives where bank 2 starts, after a gap on
158 // smaller parts (H743xG at 0x08100000, G474xC at 0x08040000).
159 uint32_t bank_entries[2] = {0U, 0U};
160 [[maybe_unused]] uint32_t index = 0U;
161 for (size_t r = 0; r < region_count_; ++r)
162 {
163 const auto& region = regions_[r];
164 for (uint32_t k = 0; k < region.sector_count; ++k, ++index)
165 {
166 const uint32_t address = region.address + region.sector_size * k;
167#if defined(FLASH_BANK_2)
168 const size_t bank_slot = (STM32FlashBankOf(address) == FLASH_BANK_2) ? 1U : 0U;
169#else
170 const size_t bank_slot = 0U;
171#endif
172 [[maybe_unused]] const uint32_t number_in_bank = bank_entries[bank_slot]++;
173 if (address + region.sector_size <= start_addr)
174 {
175 continue;
176 }
177 if (address >= end_addr)
178 {
179 return ErrorCode::OK;
180 }
181 FLASH_EraseInitTypeDef erase_init = {};
182
183#if defined(FLASH_TYPEERASE_PAGES) && defined(FLASH_PAGE_SIZE) // STM32F1/G4... series
184 // 有 Page 字段的系列(G0、G4、L4、L5、U5 等)按 bank 内页号编号;其余系列用页地址。
185 // Families with a Page field (G0, G4, L4, L5, U5, ...) number pages within each
186 // bank; the others take the page address.
187 erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
188 SetNbPages(erase_init, address, number_in_bank);
189 erase_init.NbPages = 1;
190 SetBanks(erase_init, address);
191#elif defined(FLASH_TYPEERASE_SECTORS) // STM32F4/F7/H7... series
192 erase_init.TypeErase = FLASH_TYPEERASE_SECTORS;
193#if defined(FLASH_SECTOR_SIZE)
194 // H5、H7 的扇区大小一致,按 bank 内扇区号编号。
195 // H5 and H7 have uniform sectors numbered within each bank.
196 erase_init.Sector = number_in_bank;
197#elif defined(FLASH_SECTOR_TOTAL)
198 // F2、F4、F7 的扇区号跨两个 bank 连续编号,等于跨段的扇区序号。
199 // F2, F4 and F7 number sectors across both banks, as the index across runs does.
200 erase_init.Sector = index;
201#else
202#error "No supported Flash sector numbering defined"
203#endif
204 erase_init.NbSectors = 1;
205#if defined(FLASH_BANK_1)
206 erase_init.Banks = STM32FlashBankOf(address);
207#endif
208#if defined(FLASH_CR_PSIZE)
209 erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_1;
210#endif
211#else
213#endif
214
215 uint32_t error = 0;
216 HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase_init, &error);
217 if (status != HAL_OK || error != 0xFFFFFFFFU)
218 {
219 return ErrorCode::FAILED;
220 }
221 }
222 }
223
224 return ErrorCode::OK;
225}
@ NOT_SUPPORT
不支持 / Not supported
@ FAILED
操作失败 / Operation failed
@ OK
操作成功 / Operation successful
@ ARG_ERR
参数错误 / Argument error

◆ Write()

ErrorCode STM32Flash::Write ( size_t offset,
ConstRawData data )
overridevirtual

向闪存写入数据 / Writes data to the flash memory.

Parameters
offset数据写入的起始偏移地址 / The starting offset to write data.
data需要写入的数据 / The data to be written.
Returns
返回操作结果的错误码 / ErrorCode indicating success or failure.

Implements LibXR::Flash.

Definition at line 227 of file stm32_flash.cpp.

228{
229 if (!data.addr_ || data.size_ == 0)
230 {
231 return ErrorCode::ARG_ERR;
232 }
233
234 uint32_t addr = base_address_ + offset;
235 if (!IsInRange(addr, data.size_))
236 {
238 }
239
240 FlashOperationGuard operation;
241
242 const uint8_t* src = reinterpret_cast<const uint8_t*>(data.addr_);
243 size_t written = 0;
244
245#if defined(FLASH_TYPEPROGRAM_FLASHWORD) || defined(FLASH_TYPEPROGRAM_QUADWORD)
247 uint32_t flash_word_buffer[MIN_WRITE_SIZE / sizeof(uint32_t)];
248 while (written < data.size_)
249 {
250 size_t chunk_size = LibXR::min<size_t>(MinWriteSize(), data.size_ - written);
251
252 Memory::FastSet(flash_word_buffer, 0xFF, sizeof(flash_word_buffer));
253 Memory::FastCopy(flash_word_buffer, src + written, chunk_size);
254
255 if (Memory::FastCmp(reinterpret_cast<const uint8_t*>(addr + written), src + written,
256 chunk_size) == 0)
257 {
258 written += chunk_size;
259 continue;
260 }
261
262 if (HAL_FLASH_Program(program_type_, addr + written,
263 reinterpret_cast<uint32_t>(flash_word_buffer)) != HAL_OK)
264 {
265 return ErrorCode::FAILED;
266 }
267
268 written += chunk_size;
269 }
270
271#else
272 while (written < data.size_)
273 {
274 size_t chunk_size = LibXR::min<size_t>(MinWriteSize(), data.size_ - written);
275
276 if (Memory::FastCmp(reinterpret_cast<const uint8_t*>(addr + written), src + written,
277 chunk_size) == 0)
278 {
279 written += chunk_size;
280 continue;
281 }
282
283 uint64_t word = 0xFFFFFFFFFFFFFFFF;
284 Memory::FastCopy(&word, src + written, chunk_size);
285
286 if (HAL_FLASH_Program(program_type_, addr + written, word) != HAL_OK)
287 {
288 return ErrorCode::FAILED;
289 }
290
291 written += chunk_size;
292 }
293#endif
294
295 return ErrorCode::OK;
296}
size_t size_
数据字节数 / Data size in bytes
const void * addr_
数据起始地址 / Data start address
size_t MinWriteSize() const
获取最小可写块大小(字节) / Returns the minimum writable block size in bytes.
Definition flash.hpp:83
static void FastSet(void *dst, uint8_t value, size_t size)
快速内存填充 / Fast memory fill
static int FastCmp(const void *a, const void *b, size_t size)
快速内存比较 / Fast memory comparison
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
@ OUT_OF_RANGE
超出范围 / Out of range
constexpr auto min(LeftType a, RightType b) -> std::common_type_t< LeftType, RightType >
计算两个数的最小值 / Computes the minimum of two numbers
constexpr size_t HW_CACHE_LINE_SIZE
真实硬件缓存行大小(用于 DMA / cache coherency) / Hardware cache-line size used for DMA/cache-coherency boundarie...
Definition libxr_def.hpp:54

Member Data Documentation

◆ MIN_WRITE_SIZE

size_t LibXR::STM32Flash::MIN_WRITE_SIZE = STM32FlashMinWriteSize()
staticconstexpr

最小写入单位(字节),由 HAL 的 FLASH_TYPEPROGRAM_* 宏确定;可直接作为 DatabaseRaw 的模板参数 / Minimum write unit in bytes, determined from the HAL FLASH_TYPEPROGRAM_* macros; usable directly as the DatabaseRaw template argument

Definition at line 146 of file stm32_flash.hpp.


The documentation for this class was generated from the following files: