Skip to content

Commit 27775ab

Browse files
committed
bricks/_common/micropython: fix unaligned access
STM32F0 processors crash when trying to perform unaligned access. This fixes a crash when running multi-file mpy programs where the mpy_size field is not 32-bit aligned. Fixes: pybricks/support#746
1 parent 1815b8e commit 27775ab

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

bricks/_common/micropython.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <pbio/button.h>
1111
#include <pbio/main.h>
12+
#include <pbio/util.h>
1213
#include <pbsys/main.h>
1314
#include <pbsys/program_stop.h>
1415

@@ -147,8 +148,8 @@ static void do_execute_raw_code(mp_module_context_t *context, const mp_raw_code_
147148

148149
/** mpy info and data for one script or module. */
149150
typedef struct {
150-
/** Size of the mpy program. */
151-
uint32_t mpy_size;
151+
/** Size of the mpy program. Not aligned, use pbio_get_uint32_le() to read. */
152+
uint8_t mpy_size[4];
152153
/** Null-terminated name of the script, without file extension. */
153154
char mpy_name[];
154155
/** mpy data follows thereafter. */
@@ -183,7 +184,7 @@ static mpy_info_t *mpy_data_find(qstr name) {
183184
const char *name_str = qstr_str(name);
184185

185186
for (mpy_info_t *info = mpy_first; info < mpy_end;
186-
info = (mpy_info_t *)(mpy_data_get_buf(info) + info->mpy_size)) {
187+
info = (mpy_info_t *)(mpy_data_get_buf(info) + pbio_get_uint32_le(info->mpy_size))) {
187188
if (strcmp(info->mpy_name, name_str) == 0) {
188189
return info;
189190
}
@@ -208,7 +209,7 @@ static void run_user_program(void) {
208209
// This is similar to __import__ except we don't push/pop globals
209210
mp_reader_t reader;
210211
mp_vfs_map_minimal_t data;
211-
mp_vfs_map_minimal_new_reader(&reader, &data, mpy_data_get_buf(info), info->mpy_size);
212+
mp_vfs_map_minimal_new_reader(&reader, &data, mpy_data_get_buf(info), pbio_get_uint32_le(info->mpy_size));
212213
mp_module_context_t *context = m_new_obj(mp_module_context_t);
213214
context->module.globals = mp_globals_get();
214215
mp_compiled_module_t compiled_module = mp_raw_code_load(&reader, context);
@@ -327,7 +328,7 @@ mp_obj_t pb_builtin_import(size_t n_args, const mp_obj_t *args) {
327328
// Parse the static script data.
328329
mp_reader_t reader;
329330
mp_vfs_map_minimal_t data;
330-
mp_vfs_map_minimal_new_reader(&reader, &data, mpy_data_get_buf(info), info->mpy_size);
331+
mp_vfs_map_minimal_new_reader(&reader, &data, mpy_data_get_buf(info), pbio_get_uint32_le(info->mpy_size));
331332

332333
// Create new module and execute in its own context.
333334
mp_obj_t module_obj = mp_obj_new_module(module_name_qstr);

0 commit comments

Comments
 (0)