PICO зависает при создании объекта micropython

Недавно я начал работать над небольшим драйвером для Raspberry Pico и датчика bme280. Я хотел использовать официальный bosh API, написанный на C, и поэтому решил написать весь код на C, используя API micropython C для написания пользовательских модулей. Мне удалось скомпилировать мой код в файл UF2, и мой модуль появляется, когда я пытаюсь перечислить модули с помощью help('modules'). Когда я импортирую свой модуль, класс с кодом драйвера появляется в dir(mymodule), но когда я пытаюсь создать объект, терминал, подключенный к PICO, зависает и больше не отвечает.

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);

Я думаю, что проблема кроется где-то в процедуре инициализации, так как она не идет дальше... Может быть, есть что-то, что микропитон делает за кулисами, что я игнорирую. Существует не так много документации по написанию пользовательских модулей на C... любая помощь/подсказки/идеи очень ценятся :)

EDIT+ANSWER:
Да, я получил пример для сборки, поэтому я начал урезать свой код до минимума, необходимого, чтобы он был почти идентичен примеру, и поэтому я нашел ошибку. .. Проблема была в том, что я использовал другое имя для типа класса в объявлении: BME280_class_type и в определении: BME280_type


person Leonardo    schedule 05.04.2021    source источник


Ответы (1)


Вы определили .print, но его нет в вашем коде.

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,
};

Пример написания правильной функции класса print есть здесь

Однако этого должно быть достаточно, по крайней мере, для удовлетворения требований печати. Вставьте это в свой код и посмотрите, перестанет ли он зависать.

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");
}

Кроме того, я уверен, что вы просто исключили это из своего примера, иначе вы вообще не смогли бы его построить, но ради тщательности ~ вы должны включить соответствующие файлы заголовков.

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

Редактировать: мне было любопытно. Вы сказали, что у вас есть все для сборки, но оно зависает. Я закомментировал функцию print для одного из моих классов C MODULE, и она не собиралась. Это говорит мне о том, что вы (как и заголовок) решили просто исключить эту часть из своего примера. Это пустая трата времени. Как вам помочь, если ваш пример создает ошибки, которых для вас не существует? Однако, несмотря на то, что этот ответ теперь неверен, я собираюсь оставить его в качестве примера того, почему искатели ответов не должны выбирать, что публиковать. Просто опубликуйте ВСЕ соответствующие скрипты для вашей проблемы, а остальное позвольте нам выяснить. У меня, вероятно, был бы ответ для вас, если бы я не решал не ту проблему. На самом деле, я вижу вашу проблему, вы создаете свой модуль со смешанными пространствами имен.

person Michael Guidry    schedule 06.04.2021
comment
Привет большое спасибо за ваше время и ответ! Я думаю, что иногда лучше не копировать и не вставлять целые файлы, полные кода, который не имеет ничего общего с проблемой. В этом случае я слишком много вырезал, извините за это. В любом случае, проблема была внутри кода, который я разместил на этот раз: я использовал разные имена для типа класса в объявлении: BME280_class_type и BME280_type. Еще раз спасибо! - person Leonardo; 06.04.2021