美文网首页
MicroPython添加Module(二)

MicroPython添加Module(二)

作者: tianxiaoMCU | 来源:发表于2019-03-29 09:19 被阅读0次

    上一篇已经创建了一个machine的模块并实现了函数,按照这个方式可以将引脚、串口、定时器等所有外设的功能都添加到这个模块里面。但是,这么多的外设,每个外设还有不少的操作函数,全部一起加到模块里,使用起来非常的不方便。MicroPython支持将一个class添加到模块里,因此我们可以将每个外设设计成一个单独的class,外设的操作作为class的method,这样添加到模块里,调用时就比较便捷了。本文以LED为例进行说明。

    classes

    跟模块类似,类也是一个c结构体,只是跟模块的字段不完全一样而已。

    STATIC const mp_rom_map_elem_t led_locals_dict_table[] = {
    };
    
    STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table);
    
    const mp_obj_type_t pyb_led_type = {
        {&mp_type_type},
        .name = MP_QSTR_LED,
        .print = led_obj_print,
        .make_new = led_obj_make_new,
        .locals_dict = (mp_obj_dict_t *)&led_locals_dict,
    };
    

    可以看到,一个类需要两个函数:make_new用于构造类并分配类需要的所有内存空间,print用于打印该类的对象。

    // this is the actual C-structure for our new object
    typedef struct _pyb_led_obj_t
    {
        // base represents some basic information, like type
        mp_obj_base_t base;
        // a member created by us
        mp_uint_t led_id;
    } pyb_led_obj_t;
    
    STATIC const pyb_led_obj_t pyb_led_obj[] = {
        {{&pyb_led_type}, PYB_LED_TOP_LEFT_1},
        {{&pyb_led_type}, PYB_LED_TOP_RIGHT_1},
        {{&pyb_led_type}, PYB_LED_TOP_RIGHT_2},
        {{&pyb_led_type}, PYB_LED_TOP_LEFT_2},
    };
    

    首先定义一个LED的对象结构,里面包含了类的数据和一个额外的字段。然后定义了4个静态的LED对象。接下来创建print函数用于打印这些对象:

    void led_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind)
    {
        pyb_led_obj_t *self = MP_OBJ_TO_PTR(self_in);
        mp_printf(print, "LED(%u)", self->led_id);
    }
    

    还有构造函数

    STATIC mp_obj_t led_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args)
    {
        // check arguments
        mp_arg_check_num(n_args, n_kw, 1, 1, false);
    
        // get led number
        mp_int_t led_id = mp_obj_get_int(args[0]);
    
        // check led number
        if (!(1 <= led_id && led_id <= NUM_LEDS))
        {
            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "LED(%d) doesn't exist", led_id));
        }
    
        // return static led object
        return MP_OBJ_FROM_PTR(&pyb_led_obj[led_id - 1]);
    }
    

    到这里一个类所需的基本元素就都具备了,紧接着实现类的方法。

    methods

    这里实现了LED的3个方法,on、off和toggle。

    /// Turn the LED on.
    mp_obj_t led_obj_on(mp_obj_t self_in)
    {
        pyb_led_obj_t *self = MP_OBJ_TO_PTR(self_in);
        Board_LED_Set(self->led_id, true);
        return mp_const_none;
    }
    STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
    
    /// \method off()
    /// Turn the LED off.
    mp_obj_t led_obj_off(mp_obj_t self_in)
    {
        pyb_led_obj_t *self = MP_OBJ_TO_PTR(self_in);
        Board_LED_Set(self->led_id, false);
        return mp_const_none;
    }
    STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
    
    /// \method toggle()
    /// Toggle the LED between on and off.
    mp_obj_t led_obj_toggle(mp_obj_t self_in)
    {
        pyb_led_obj_t *self = MP_OBJ_TO_PTR(self_in);
        Board_LED_Toggle(self->led_id);
        return mp_const_none;
    }
    STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
    

    将实现好的方法添加到类字典里,同时添加的还有一些类常量。

    STATIC const mp_rom_map_elem_t led_locals_dict_table[] = {
        // instance methods
        {MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&led_obj_on_obj)},
        {MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&led_obj_off_obj)},
        {MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&led_obj_toggle_obj)},
    
        // class constants
        {MP_ROM_QSTR(MP_QSTR_TOP_LEFT_1), MP_ROM_INT(PYB_LED_TOP_LEFT_1)},
        {MP_ROM_QSTR(MP_QSTR_TOP_RIGHT_1), MP_ROM_INT(PYB_LED_TOP_RIGHT_1)},
        {MP_ROM_QSTR(MP_QSTR_TOP_RIGHT_2), MP_ROM_INT(PYB_LED_TOP_RIGHT_2)},
        {MP_ROM_QSTR(MP_QSTR_TOP_LEFT_2), MP_ROM_INT(PYB_LED_TOP_LEFT_2)},
    };
    
    将类添加到模块

    上面已经完成了一个完整的类,想要能够访问,还需要将这个类添加到模块中。注意:不要忘了在qstrdefsport.h中定义所有的QSTR名字,不然编译报错!!!

    STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
        {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_machine)},
    
        {MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj)},
        {MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj)},
    
        {MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pyb_led_type)},
    };
    
    使用已添加的method
    import machine
    
    led = machine.LED(machine.LED.TOP_LEFT_1)
    led.on()
    

    相关文章

      网友评论

          本文标题:MicroPython添加Module(二)

          本文链接:https://www.haomeiwen.com/subject/qrcpvqtx.html