8#include "libxr_def.hpp"
9#include "libxr_type.hpp"
27template <
typename,
typename =
void>
28struct HasFlashPage : std::false_type
32template <
typename,
typename =
void>
33struct HasFlashBank : std::false_type
38struct HasFlashPage<T, std::void_t<decltype(std::declval<T>().Page)>> : std::true_type
43struct HasFlashBank<T, std::void_t<decltype(std::declval<T>().Banks)>> : std::true_type
49typename std::enable_if<!HasFlashPage<T>::value>::type SetNbPages(T& init, uint32_t addr,
53 init.PageAddress = addr;
58typename std::enable_if<HasFlashPage<T>::value>::type SetNbPages(T& init, uint32_t addr,
67typename std::enable_if<!HasFlashBank<T>::value>::type SetBanks(T& init)
74typename std::enable_if<HasFlashBank<T>::value>::type SetBanks(T& init)
86template <
size_t SECTOR_COUNT,
size_t START_SECTOR>
96 :
Flash(sectors[START_SECTOR - 1].size, DetermineMinWriteSize(),
97 {
reinterpret_cast<void*
>(sectors[START_SECTOR - 1].address),
98 sectors[SECTOR_COUNT - 1].address - sectors[START_SECTOR - 1].address +
99 sectors[SECTOR_COUNT - 1].size}),
101 base_address_(sectors[START_SECTOR - 1].address),
102 program_type_(DetermineProgramType())
106 ErrorCode
Erase(
size_t offset,
size_t size)
override
110 return ErrorCode::ARG_ERR;
113 uint32_t start_addr = base_address_ + offset;
114 uint32_t end_addr = start_addr + size;
118 for (
size_t i = 0; i < SECTOR_COUNT; ++i)
120 const auto& sector = sectors_[i];
121 if (sector.address + sector.size <= start_addr)
125 if (sector.address >= end_addr)
129 FLASH_EraseInitTypeDef erase_init = {};
131#if defined(FLASH_TYPEERASE_PAGES) && defined(FLASH_PAGE_SIZE)
132 erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
133 SetNbPages(erase_init, sector.address, i);
134 erase_init.NbPages = 1;
135 SetBanks(erase_init);
136#elif defined(FLASH_TYPEERASE_SECTORS)
137 erase_init.TypeErase = FLASH_TYPEERASE_SECTORS;
138 erase_init.Sector =
static_cast<uint32_t
>(i);
139 erase_init.NbSectors = 1;
140 erase_init.Banks = FLASH_BANK_1;
142 return ErrorCode::NOT_SUPPORT;
146 HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase_init, &error);
147 if (status != HAL_OK || error != 0xFFFFFFFFU)
150 return ErrorCode::FAILED;
155 return ErrorCode::OK;
162 return ErrorCode::ARG_ERR;
165 uint32_t addr = base_address_ + offset;
166 if (!IsInRange(addr, data.
size_))
168 return ErrorCode::OUT_OF_RANGE;
173 const uint8_t* src =
reinterpret_cast<const uint8_t*
>(data.
addr_);
176#if defined(STM32H7) || defined(STM32H5)
177 alignas(32) uint32_t flash_word_buffer[8] = {0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu,
178 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu,
179 0xFFFFFFFFu, 0xFFFFFFFFu};
180 while (written < data.
size_)
184 std::memcpy(flash_word_buffer, src + written, chunk_size);
186 if (memcmp(
reinterpret_cast<const uint8_t*
>(addr + written), src + written,
189 written += chunk_size;
193 if (HAL_FLASH_Program(program_type_, addr + written,
194 reinterpret_cast<uint32_t
>(flash_word_buffer)) != HAL_OK)
197 return ErrorCode::FAILED;
200 written += chunk_size;
204 while (written < data.
size_)
208 if (memcmp(
reinterpret_cast<const uint8_t*
>(addr + written), src + written,
211 written += chunk_size;
215 uint64_t word = 0xFFFFFFFFFFFFFFFF;
216 std::memcpy(&word, src + written, chunk_size);
218 if (HAL_FLASH_Program(program_type_, addr + written, word) != HAL_OK)
221 return ErrorCode::FAILED;
224 written += chunk_size;
229 return ErrorCode::OK;
234 uint32_t base_address_;
235 uint32_t program_type_;
237 static constexpr uint32_t DetermineProgramType()
239#ifdef FLASH_TYPEPROGRAM_BYTE
240 return FLASH_TYPEPROGRAM_BYTE;
241#elif defined(FLASH_TYPEPROGRAM_HALFWORD)
242 return FLASH_TYPEPROGRAM_HALFWORD;
243#elif defined(FLASH_TYPEPROGRAM_WORD)
244 return FLASH_TYPEPROGRAM_WORD;
245#elif defined(FLASH_TYPEPROGRAM_DOUBLEWORD)
246 return FLASH_TYPEPROGRAM_DOUBLEWORD;
247#elif defined(FLASH_TYPEPROGRAM_FLASHWORD)
248 return FLASH_TYPEPROGRAM_FLASHWORD;
250#error "No supported FLASH_TYPEPROGRAM_xxx defined"
254 static constexpr size_t DetermineMinWriteSize()
256#ifdef FLASH_TYPEPROGRAM_BYTE
258#elif defined(FLASH_TYPEPROGRAM_HALFWORD)
260#elif defined(FLASH_TYPEPROGRAM_WORD)
262#elif defined(FLASH_TYPEPROGRAM_DOUBLEWORD)
264#elif defined(FLASH_TYPEPROGRAM_FLASHWORD)
265 return FLASH_NB_32BITWORD_IN_FLASHWORD * 4;
267#error "No supported FLASH_TYPEPROGRAM_xxx defined"
271 bool IsInRange(uint32_t addr,
size_t size)
const
273 uint32_t end = addr + size;
274 for (
size_t i = 0; i < SECTOR_COUNT; ++i)
276 const auto& s = sectors_[i];
277 if (addr >= s.address && end <= s.address + s.size)
常量原始数据封装类。 A class for encapsulating constant raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
Abstract base class representing a flash memory interface. 抽象基类,表示闪存接口。
size_t min_write_size_
Minimum writable block size in bytes. 最小可写块大小(字节)。
STM32Flash 通用类,构造时传入扇区列表,自动判断编程粒度。
ErrorCode Erase(size_t offset, size_t size) override
Erases a section of the flash memory. 擦除闪存的指定区域。
STM32Flash(const FlashSector(§ors)[SECTOR_COUNT])
STM32Flash 类,构造时传入扇区列表,自动判断编程粒度。
ErrorCode Write(size_t offset, ConstRawData data) override
Writes data to the flash memory. 向闪存写入数据。
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值
STM32Flash 通用类,构造时传入扇区列表,自动判断编程粒度。