Skip to content

Commit 6cb0258

Browse files
Merge pull request #5026 from LMESTM/flash_init_issue_4967
STM32: Lock / Unlock flash for each operation
2 parents 5bf224f + f5aa7c7 commit 6cb0258

File tree

5 files changed

+208
-60
lines changed

5 files changed

+208
-60
lines changed

targets/TARGET_STM/TARGET_STM32F4/flash_api.c

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ static uint32_t GetSector(uint32_t Address);
4040
static uint32_t GetSectorSize(uint32_t Sector);
4141

4242
int32_t flash_init(flash_t *obj)
43+
{
44+
return 0;
45+
}
46+
47+
int32_t flash_free(flash_t *obj)
48+
{
49+
return 0;
50+
}
51+
52+
static int32_t flash_unlock(void)
4353
{
4454
/* Allow Access to Flash control registers and user Falsh */
4555
if (HAL_FLASH_Unlock()) {
@@ -48,28 +58,34 @@ int32_t flash_init(flash_t *obj)
4858
return 0;
4959
}
5060
}
51-
int32_t flash_free(flash_t *obj)
61+
62+
static int32_t flash_lock(void)
5263
{
53-
/* Disable the Flash option control register access (recommended to protect
64+
/* Disable the Flash option control register access (recommended to protect
5465
the option Bytes against possible unwanted operations) */
5566
if (HAL_FLASH_Lock()) {
5667
return -1;
5768
} else {
5869
return 0;
5970
}
6071
}
72+
6173
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
6274
{
6375
/*Variable used for Erase procedure*/
6476
static FLASH_EraseInitTypeDef EraseInitStruct;
6577
uint32_t FirstSector;
6678
uint32_t SectorError = 0;
67-
79+
int32_t status = 0;
80+
6881
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
82+
return -1;
83+
}
6984

85+
if (flash_unlock() != HAL_OK) {
7086
return -1;
7187
}
72-
88+
7389
/* Get the 1st sector to erase */
7490
FirstSector = GetSector(address);
7591

@@ -79,19 +95,26 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
7995
EraseInitStruct.Sector = FirstSector;
8096
EraseInitStruct.NbSectors = 1;
8197
if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
82-
return -1;
83-
} else {
84-
return 0;
98+
status = -1;
8599
}
100+
101+
flash_lock();
102+
103+
return status;
86104
}
87105

88106
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
89107
{
108+
int32_t status = 0;
90109

91110
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
92111
return -1;
93112
}
94113

114+
if (flash_unlock() != HAL_OK) {
115+
return -1;
116+
}
117+
95118
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
96119
you have to make sure that these data are rewritten before they are accessed during code
97120
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
@@ -105,16 +128,19 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
105128
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
106129
__HAL_FLASH_DATA_CACHE_ENABLE();
107130

108-
while (size > 0) {
131+
while ((size > 0) && (status == 0)) {
109132
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, (uint64_t)*data) != HAL_OK) {
110-
return -1;
133+
status = -1;
111134
} else {
112135
size--;
113136
address++;
114137
data++;
115138
}
116139
}
117-
return 0;
140+
141+
flash_lock();
142+
143+
return status;
118144
}
119145

120146
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)

targets/TARGET_STM/TARGET_STM32F7/flash_api.c

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,24 @@ static uint32_t GetSectorSize(uint32_t Sector);
3838

3939
int32_t flash_init(flash_t *obj)
4040
{
41-
/* Allow Access to Flash control registers and user Flash */
41+
return 0;
42+
}
43+
int32_t flash_free(flash_t *obj)
44+
{
45+
return 0;
46+
}
47+
48+
static int32_t flash_unlock(void)
49+
{
50+
/* Allow Access to Flash control registers and user Falsh */
4251
if (HAL_FLASH_Unlock()) {
4352
return -1;
4453
} else {
4554
return 0;
4655
}
4756
}
48-
int32_t flash_free(flash_t *obj)
57+
58+
static int32_t flash_lock(void)
4959
{
5060
/* Disable the Flash option control register access (recommended to protect
5161
the option Bytes against possible unwanted operations) */
@@ -55,18 +65,24 @@ int32_t flash_free(flash_t *obj)
5565
return 0;
5666
}
5767
}
68+
5869
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
5970
{
6071
/* Variable used for Erase procedure */
6172
FLASH_EraseInitTypeDef EraseInitStruct;
6273
FLASH_OBProgramInitTypeDef OBInit;
6374
uint32_t SectorId;
6475
uint32_t SectorError = 0;
76+
int32_t status = 0;
6577

6678
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
6779
return -1;
6880
}
6981

82+
if (flash_unlock() != HAL_OK) {
83+
return -1;
84+
}
85+
7086
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
7187
you have to make sure that these data are rewritten before they are accessed during code
7288
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
@@ -102,19 +118,27 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
102118
EraseInitStruct.NbSectors = 1;
103119

104120
if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
105-
return -1;
106-
} else {
107-
return 0;
121+
status = -1;
108122
}
123+
124+
flash_lock();
125+
126+
return status;
109127
}
110128

111129
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
112130
uint32_t size)
113131
{
132+
int32_t status = 0;
133+
114134
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
115135
return -1;
116136
}
117137

138+
if (flash_unlock() != HAL_OK) {
139+
return -1;
140+
}
141+
118142
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
119143
you have to make sure that these data are rewritten before they are accessed during code
120144
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
@@ -123,17 +147,20 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
123147
__HAL_FLASH_ART_RESET();
124148
__HAL_FLASH_ART_ENABLE();
125149

126-
while (size > 0) {
150+
while ((size > 0) && (status == 0)) {
127151
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE,
128152
address, (uint64_t)*data) != HAL_OK) {
129-
return -1;
153+
status = -1;
130154
} else {
131155
size--;
132156
address++;
133157
data++;
134158
}
135159
}
136-
return 0;
160+
161+
flash_lock();
162+
163+
return status;
137164
}
138165

139166
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)

targets/TARGET_STM/TARGET_STM32L0/flash_api.c

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,30 +26,51 @@
2626

2727
int32_t flash_init(flash_t *obj)
2828
{
29-
/* Unlock the Flash to enable the flash control register access *************/
30-
HAL_FLASH_Unlock();
3129
return 0;
3230
}
3331

3432
int32_t flash_free(flash_t *obj)
3533
{
36-
/* Lock the Flash to disable the flash control register access (recommended
37-
* to protect the FLASH memory against possible unwanted operation) *********/
38-
HAL_FLASH_Lock();
3934
return 0;
4035
}
4136

37+
static int32_t flash_unlock(void)
38+
{
39+
/* Allow Access to Flash control registers and user Falsh */
40+
if (HAL_FLASH_Unlock()) {
41+
return -1;
42+
} else {
43+
return 0;
44+
}
45+
}
46+
47+
static int32_t flash_lock(void)
48+
{
49+
/* Disable the Flash option control register access (recommended to protect
50+
the option Bytes against possible unwanted operations) */
51+
if (HAL_FLASH_Lock()) {
52+
return -1;
53+
} else {
54+
return 0;
55+
}
56+
}
57+
4258
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
4359
{
4460
uint32_t FirstPage = 0;
4561
uint32_t PAGEError = 0;
4662
FLASH_EraseInitTypeDef EraseInitStruct;
63+
int32_t status = 0;
4764

4865
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
4966

5067
return -1;
5168
}
5269

70+
if (flash_unlock() != HAL_OK) {
71+
return -1;
72+
}
73+
5374
/* Clear OPTVERR bit set on virgin samples */
5475
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
5576

@@ -65,16 +86,20 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
6586
DCRST and ICRST bits in the FLASH_CR register. */
6687

6788
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
68-
return -1;
69-
} else {
70-
return 0;
89+
status = -1;
7190
}
91+
92+
flash_lock();
93+
94+
return status;
95+
7296
}
7397

7498
int32_t flash_program_page(flash_t *obj, uint32_t address,
7599
const uint8_t *data, uint32_t size)
76100
{
77101
uint32_t StartAddress = 0;
102+
int32_t status = 0;
78103

79104
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
80105
return -1;
@@ -85,14 +110,18 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
85110
return -1;
86111
}
87112

113+
if (flash_unlock() != HAL_OK) {
114+
return -1;
115+
}
116+
88117
/* Program the user Flash area word by word */
89118
StartAddress = address;
90119

91120
/* HW needs an aligned address to program flash, which data
92121
* parameters doesn't ensure */
93122
if ((uint32_t) data % 4 != 0) {
94123
volatile uint32_t data32;
95-
while (address < (StartAddress + size)) {
124+
while ((address < (StartAddress + size)) && (status == 0)) {
96125
for (uint8_t i =0; i < 4; i++) {
97126
*(((uint8_t *) &data32) + i) = *(data + i);
98127
}
@@ -101,21 +130,23 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
101130
address = address + 4;
102131
data = data + 4;
103132
} else {
104-
return -1;
133+
status = -1;
105134
}
106135
}
107136
} else { /* case where data is aligned, so let's avoid any copy */
108-
while (address < (StartAddress + size)) {
137+
while ((address < (StartAddress + size)) && (status == 0)) {
109138
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
110139
address = address + 4;
111140
data = data + 4;
112141
} else {
113-
return -1;
142+
status = -1;
114143
}
115144
}
116145
}
117146

118-
return 0;
147+
flash_lock();
148+
149+
return status;
119150
}
120151

121152
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) {

0 commit comments

Comments
 (0)