dhylands wrote: ↑Fri Apr 13, 2018 9:53 pm
mp_store_name stores a reference into the locals dict.
How was device_module allocated? and why are you casting it to mp_obj_t?
modules are normally declared const and come from flash, and flash objects aren't garbage collected.
So I'm confused by your example.
It was allocated globally just like the other definitions of "mp_obj_module"
Code: Select all
mp_obj_dict_t atiupy_device_dict;
mp_obj_module_t device_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&atiupy_device_dict,
};
I'm casting it because
Code: Select all
void mp_store_name(qstr qst, mp_obj_t obj);
void mp_store_global(qstr qst, mp_obj_t obj);
I changed it to const and I still have the same issue
Code: Select all
const mp_obj_module_t device_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&atiupy_device_dict,
};
...
// Add the device module to the main dictionary
mp_store_name(MP_QSTR_device, (mp_obj_t)&device_module);
The very first thing I execute is "gc.collect()" and then if I do "dir(device)", my C-debugger hits a trap that indicates invalid memory access.
Here's my
gc_collect().
Code: Select all
void gc_collect(void)
{
// get current time, in case we want to time the GC
#if 0
uint32_t start = mp_hal_ticks_us();
#endif
// start the GC
gc_collect_start();
// get the registers and the sp
mp_uint_t regs[10];
mp_uint_t sp = gc_helper_get_regs_and_sp(regs);
// trace the stack, including the registers (since they live on the stack in this function)
//#if MICROPY_PY_THREAD
gc_collect_root((void**)sp, ((uint32_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t));
//#else
// gc_collect_root((void**)sp, ((uint32_t)&g_uPyStackEnd - sp) / sizeof(uint32_t));
//#endif
// trace root pointers from any threads
#if MICROPY_PY_THREAD
mp_thread_gc_others();
#endif
// end the GC
gc_collect_end();
#if 0
// print GC info
uint32_t ticks = mp_hal_ticks_us() - start;
gc_info_t info;
gc_info(&info);
printf("GC@%lu %lums\n", start, ticks);
printf(" " UINT_FMT " total\n", info.total);
printf(" " UINT_FMT " : " UINT_FMT "\n", info.used, info.free);
printf(" 1=" UINT_FMT " 2=" UINT_FMT " m=" UINT_FMT "\n", info.num_1block, info.num_2block, info.max_block);
#endif
}
My processor is an M4 so the assembly function
gc_helper_get_regs_and_sp() is the same one as the one in the folder
stmhal
It's not "device_module" that's the problem but the things that are in "device_module"'s dictionary.
Normally, the hierarchy looks like this:
everything below "device" is created dynamically and placed into the dictionary of its parent using
mp_obj_dict_store
Code: Select all
mp_obj_dict_store(MP_OBJ_FROM_PTR(mp_obj_periph_type_module->globals), MP_OBJ_NEW_QSTR(periph_ch_qstr), mp_obj_periph_ch);
What must be happening is that I'm doing this wrong i.e. the "chain" is not being created from "device" down to the "device.CAN.xyz" and everything downstream of "device" is being garbage collected.