1

I recently started working on a small driver for the raspberry pico and the bme280 sensor. I wanted to use the official bosh API written in C and therefore decided to write all the code in C using the micropython C api to write usermodules. I managed to get my code compiled into a UF2 file and my module shows up when I try to list the modules with help('modules'). When I import my module the class with the driver code shows up in dir(mymodule) but when I try to create an object the terminal connected to the PICO hangs and doesn't respond anymore.

typedef struct {
    mp_obj_base_t base;
    uint8_t sda;
    uint8_t scl;
    uint8_t i2c_address;
} BME280_obj_t;

const mp_obj_type_t BME280_class_type;  

STATIC mp_obj_t BME280_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 2, 2, true);
    BME280_obj_t* self = m_new_obj(BME280_obj_t);
    self->base.type = &BME280_class_type;
    self->sda = mp_obj_get_int(args[0]);
    self->scl = mp_obj_get_int(args[1]);
    self->i2c_address = n_args <= 2? BME280_I2C_ADDR_SEC : mp_obj_get_int(args[2]);
    return MP_OBJ_FROM_PTR(self);
}

STATIC const mp_rom_map_elem_t BME280_locals_dict_table[] = {
    // for testing purpose i removed all methods from the class
};


STATIC MP_DEFINE_CONST_DICT(BME280_locals_dict, BME280_locals_dict_table);

const mp_obj_type_t BME280_type = {
    { &mp_type_type },
    .name = MP_QSTR_BME280,
    .print = BME280_print,
    .make_new = BME280_make_new,
    .locals_dict = (mp_obj_dict_t*) &BME280_locals_dict,
};

STATIC const mp_rom_map_elem_t bme280_module_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bme280) },
    { MP_OBJ_NEW_QSTR(MP_QSTR_BME280), (mp_obj_t)&BME280_class_type }
};

STATIC MP_DEFINE_CONST_DICT(bme280_module_globals, bme280_module_globals_table);

// module registration

const mp_obj_module_t bme280_user_cmodule = {
    .base = { &mp_type_module },
    .globals = (mp_obj_dict_t*)&bme280_module_globals,
};

MP_REGISTER_MODULE(MP_QSTR_melopero_bme280, melopero_bme280_user_cmodule, 1);

I think the problem relies somewhere in the initialization procedure since it does not go further... Maybe there is something that micropython is doing behind the scenes that I'm ignoring. There is not so many documentation on writing usermodules in C... any help/hints/ideas are greatly apreciated :)

EDIT+ANSWER:
Yes I got the example to build and so I started to strip down my code to the minimum necessary to get it almost identical to the example and so I found the error... The problem was that I used a different name for the class type in the declaration: BME280_class_type and in the definition: BME280_type

Leonardo
  • 56
  • 7

1 Answers1

1

You have .print defined but it doesn't exist in your code.

const mp_obj_type_t BME280_type = {
    { &mp_type_type },
    .name = MP_QSTR_BME280,
    .print = BME280_print,
    .make_new = BME280_make_new,
    .locals_dict = (mp_obj_dict_t*) &BME280_locals_dict,
};

There is an example of writing a proper class print function here

However, this should be enough to at least satisfy the print requirement. Paste this into your code and see if it stops hanging.

STATIC void BME280_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
    (void)kind;
    BME280_obj_t *self = MP_OBJ_TO_PTR(self_in);
    mp_print_str(print, "BME280");
}

Also, I'm sure you just left this out of your example, otherwise you wouldn't have been able to build it, at all, but for the sake of being thorough ~ you have to include the proper header files.

#include <stdio.h>
#include "py/runtime.h"
#include "py/obj.h"

Edit: I was curious. You said you got everything to build, but it hangs. I commented out the print function for one of my C MODULE classes, and it would not build. This tells me that you (like the header) decided to just leave this part out of your example. This wastes time. How can you be helped if your example is creating errors that do not exist for you? However, even though this answer is now wrong, I am going to leave it up as an example of why answer-seekers shouldn't pick and choose what to post. Just post ALL of the relevant script to your problem and let us figure out the rest. I'd probably have an answer for you if I wasn't solving the wrong problem. Actually, I do see your problem, you're creating your module with mixed namespaces.

OneMadGypsy
  • 4,640
  • 3
  • 10
  • 26
  • Hi thank you very much for your time and answer! I think that sometimes it is better to not copy and paste whole files full of code that has nothing to do with the problem. In this case I stripped too much out sorry for this. Anyway the problem was inside the code that I posted this time: I used different names for the class type in the declaration: ```BME280_class_type``` and ```BME280_type```. Thank you again! – Leonardo Apr 06 '21 at 15:21