@@ -70,6 +70,22 @@ bi_decl(bi_block_device(
70
70
BINARY_INFO_BLOCK_DEV_FLAG_WRITE |
71
71
BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN ));
72
72
73
+ // Flash erase and write must run with interrupts disabled and the other core suspended,
74
+ // because the XIP bit gets disabled.
75
+ static uint32_t begin_critical_flash_section (void ) {
76
+ if (multicore_lockout_victim_is_initialized (1 - get_core_num ())) {
77
+ multicore_lockout_start_blocking ();
78
+ }
79
+ return save_and_disable_interrupts ();
80
+ }
81
+
82
+ static void end_critical_flash_section (uint32_t state ) {
83
+ restore_interrupts (state );
84
+ if (multicore_lockout_victim_is_initialized (1 - get_core_num ())) {
85
+ multicore_lockout_end_blocking ();
86
+ }
87
+ }
88
+
73
89
STATIC mp_obj_t rp2_flash_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * all_args ) {
74
90
// Parse arguments
75
91
enum { ARG_start , ARG_len };
@@ -135,19 +151,17 @@ STATIC mp_obj_t rp2_flash_writeblocks(size_t n_args, const mp_obj_t *args) {
135
151
mp_buffer_info_t bufinfo ;
136
152
mp_get_buffer_raise (args [2 ], & bufinfo , MP_BUFFER_READ );
137
153
if (n_args == 3 ) {
138
- // Flash erase/program must run in an atomic section because the XIP bit gets disabled.
139
- mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
154
+ mp_uint_t atomic_state = begin_critical_flash_section ();
140
155
flash_range_erase (self -> flash_base + offset , bufinfo .len );
141
- MICROPY_END_ATOMIC_SECTION (atomic_state );
156
+ end_critical_flash_section (atomic_state );
142
157
mp_event_handle_nowait ();
143
158
// TODO check return value
144
159
} else {
145
160
offset += mp_obj_get_int (args [3 ]);
146
161
}
147
- // Flash erase/program must run in an atomic section because the XIP bit gets disabled.
148
- mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
162
+ mp_uint_t atomic_state = begin_critical_flash_section ();
149
163
flash_range_program (self -> flash_base + offset , bufinfo .buf , bufinfo .len );
150
- MICROPY_END_ATOMIC_SECTION (atomic_state );
164
+ end_critical_flash_section (atomic_state );
151
165
mp_event_handle_nowait ();
152
166
// TODO check return value
153
167
return mp_const_none ;
@@ -170,10 +184,9 @@ STATIC mp_obj_t rp2_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_
170
184
return MP_OBJ_NEW_SMALL_INT (BLOCK_SIZE_BYTES );
171
185
case MP_BLOCKDEV_IOCTL_BLOCK_ERASE : {
172
186
uint32_t offset = mp_obj_get_int (arg_in ) * BLOCK_SIZE_BYTES ;
173
- // Flash erase/program must run in an atomic section because the XIP bit gets disabled.
174
- mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
187
+ mp_uint_t atomic_state = begin_critical_flash_section ();
175
188
flash_range_erase (self -> flash_base + offset , BLOCK_SIZE_BYTES );
176
- MICROPY_END_ATOMIC_SECTION (atomic_state );
189
+ end_critical_flash_section (atomic_state );
177
190
// TODO check return value
178
191
return MP_OBJ_NEW_SMALL_INT (0 );
179
192
}
0 commit comments