libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
stm32_flash.cpp
1#include "stm32_flash.hpp"
2
3using namespace LibXR;
4
5STM32Flash::STM32Flash(const FlashSector* sectors, size_t sector_count,
6 size_t start_sector)
7 : Flash(sectors[start_sector - 1].size, DetermineMinWriteSize(),
8 {reinterpret_cast<void*>(sectors[start_sector - 1].address),
9 sectors[sector_count - 1].address - sectors[start_sector - 1].address +
10 sectors[sector_count - 1].size}),
11 sectors_(sectors),
12 base_address_(sectors[start_sector - 1].address),
13 program_type_(DetermineProgramType()),
14 sector_count_(sector_count)
15{
16}
17
18ErrorCode STM32Flash::Erase(size_t offset, size_t size)
19{
20 if (size == 0)
21 {
22 return ErrorCode::ARG_ERR;
23 }
24
25 uint32_t start_addr = base_address_ + offset;
26 uint32_t end_addr = start_addr + size;
27
28 HAL_FLASH_Unlock();
29
30 for (size_t i = 0; i < sector_count_; ++i)
31 {
32 const auto& sector = sectors_[i];
33 if (sector.address + sector.size <= start_addr)
34 {
35 continue;
36 }
37 if (sector.address >= end_addr)
38 {
39 break;
40 }
41 FLASH_EraseInitTypeDef erase_init = {};
42
43#if defined(FLASH_TYPEERASE_PAGES) && defined(FLASH_PAGE_SIZE) // STM32F1/G4... series
44 erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
45 SetNbPages(erase_init, sector.address, i);
46 erase_init.NbPages = 1;
47 SetBanks(erase_init);
48#elif defined(FLASH_TYPEERASE_SECTORS) // STM32F4/F7/H7... series
49 erase_init.TypeErase = FLASH_TYPEERASE_SECTORS;
50 erase_init.Sector = static_cast<uint32_t>(i);
51 erase_init.NbSectors = 1;
52 erase_init.Banks = FLASH_BANK_1;
53#else
54 return ErrorCode::NOT_SUPPORT;
55#endif
56
57 uint32_t error = 0;
58 HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase_init, &error);
59 if (status != HAL_OK || error != 0xFFFFFFFFU)
60 {
61 HAL_FLASH_Lock();
62 return ErrorCode::FAILED;
63 }
64 }
65
66 HAL_FLASH_Lock();
67 return ErrorCode::OK;
68}
69
70ErrorCode STM32Flash::Write(size_t offset, ConstRawData data)
71{
72 if (!data.addr_ || data.size_ == 0)
73 {
74 return ErrorCode::ARG_ERR;
75 }
76
77 uint32_t addr = base_address_ + offset;
78 if (!IsInRange(addr, data.size_))
79 {
80 return ErrorCode::OUT_OF_RANGE;
81 }
82
83 HAL_FLASH_Unlock();
84
85 const uint8_t* src = reinterpret_cast<const uint8_t*>(data.addr_);
86 size_t written = 0;
87
88#if defined(STM32H7) || defined(STM32H5)
89 alignas(32) uint32_t flash_word_buffer[8] = {0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu,
90 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu,
91 0xFFFFFFFFu, 0xFFFFFFFFu};
92 while (written < data.size_)
93 {
94 size_t chunk_size = LibXR::min<size_t>(MinWriteSize(), data.size_ - written);
95
96 std::memcpy(flash_word_buffer, src + written, chunk_size);
97
98 if (memcmp(reinterpret_cast<const uint8_t*>(addr + written), src + written,
99 chunk_size) == 0)
100 {
101 written += chunk_size;
102 continue;
103 }
104
105 if (HAL_FLASH_Program(program_type_, addr + written,
106 reinterpret_cast<uint32_t>(flash_word_buffer)) != HAL_OK)
107 {
108 HAL_FLASH_Lock();
109 return ErrorCode::FAILED;
110 }
111
112 written += chunk_size;
113 }
114
115#else
116 while (written < data.size_)
117 {
118 size_t chunk_size = LibXR::min<size_t>(MinWriteSize(), data.size_ - written);
119
120 if (memcmp(reinterpret_cast<const uint8_t*>(addr + written), src + written,
121 chunk_size) == 0)
122 {
123 written += chunk_size;
124 continue;
125 }
126
127 uint64_t word = 0xFFFFFFFFFFFFFFFF;
128 std::memcpy(&word, src + written, chunk_size);
129
130 if (HAL_FLASH_Program(program_type_, addr + written, word) != HAL_OK)
131 {
132 HAL_FLASH_Lock();
133 return ErrorCode::FAILED;
134 }
135
136 written += chunk_size;
137 }
138#endif
139
140 HAL_FLASH_Lock();
141 return ErrorCode::OK;
142}
143
144bool STM32Flash::IsInRange(uint32_t addr, size_t size) const
145{
146 uint32_t end = addr + size;
147 for (size_t i = 0; i < sector_count_; ++i)
148 {
149 const auto& s = sectors_[i];
150 if (addr >= s.address && end <= s.address + s.size)
151 {
152 return true;
153 }
154 }
155 return false;
156}
常量原始数据封装类。 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. 抽象基类,表示闪存接口。
Definition flash.hpp:19
size_t MinWriteSize() const
Returns the minimum writable block size in bytes. 获取最小可写块大小(字节)。
Definition flash.hpp:73
ErrorCode Write(size_t offset, ConstRawData data) override
Writes data to the flash memory. 向闪存写入数据。
STM32Flash(const FlashSector *sectors, size_t sector_count, size_t start_sector)
STM32Flash 类,构造时传入扇区列表,自动判断编程粒度。
ErrorCode Erase(size_t offset, size_t size) override
Erases a section of the flash memory. 擦除闪存的指定区域。
LibXR 命名空间
Definition ch32_gpio.hpp:9
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值
STM32Flash 通用类,构造时传入扇区列表,自动判断编程粒度。