当前位置:网站首页>Read the source code of micropyton - add the C extension class module (4)

Read the source code of micropyton - add the C extension class module (4)

2022-06-10 21:05:00 suyong_ yq

read micropyton Source code - add to C Extension class module (4)

Su Yong ,2021 year 8 month


make_new() Function is equivalent to initializing an instance of a class . After initialization , Users can use class instances to call functions to perform functions . Here again, let's see how to write the function .

Without input parameters pin.on() & pin.off()

stay “ports/mimxrt/machine_pin.c” find machine_pin_off() and machine_pin_on() function :


// pin.off()
STATIC mp_obj_t machine_pin_off(mp_obj_t self_in) {
    
    machine_pin_obj_t *self = self_in;
    mp_hal_pin_low(self);
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_off_obj, machine_pin_off);

// pin.on()
STATIC mp_obj_t machine_pin_on(mp_obj_t self_in) {
    
    machine_pin_obj_t *self = self_in;
    mp_hal_pin_high(self);
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_on_obj, machine_pin_on);

These function functions are registered to python Medium , It is not directly called by the user in a certain place , therefore , You should also pay attention to the parameter transfer .

With machine_pin_off() For example :

  • The return value type is mp_obj_t, If there is nothing to return , Just use “return mp_const_none”
  • The first parameter passed in self_in, It's actually make_new() The first parameter in the parameter list , Hardware related information can be extracted from it , And then call SDK Of API Operate the underlying hardware . Here you can call API, There is no need to call again mp_hal_pin_low() perhaps mp_hal_pin_high().

actually , stay “ports/mimxrt/mphalport.h” in ,mp_hal_pin_low() perhaps mp_hal_pin_high() The code for is as follows :

#define mp_hal_pin_high(p) (GPIO_PinWrite(p->gpio, p->pin, 1U))
#define mp_hal_pin_low(p) (GPIO_PinWrite(p->gpio, p->pin, 0U))

With input parameters pin.init()

stay “ports/mimxrt/machine_pin.c” find machine_pin_init() function :

// pin.init(mode, pull, [kwargs])
STATIC mp_obj_t machine_pin_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
    
    return machine_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
}
MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_init_obj, 1, machine_pin_init);

I can't understand this , I expected the first parameter to be the same self_in, But here, the parameter list is used to transfer parameters :n_args Is the number of parameters transferred by the user ,args Is a list of positional parameters ,kw_args It is the keyword parameter list of wearing vest .

I wonder if this is especially for reuse machine_pin_obj_init_helper() Function is written like this . I saw rp2 The implementation of the , It's a mess , At least mimxrt It's still a little standardized , Or reference mimxrt How about .

As long as there are parameters , The parameters are transferred uniformly in the form of parameter list , You can do it all cover live .

Macro functions “MP_DEFINE_CONST_FUN_OBJ_KW()” This parameter in “1”, Refer to “py/obj.h” Defined in the , Means at least 1 Parameters .

#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) \ const mp_obj_fun_builtin_var_t obj_name = \ {
      {
      &mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, true), .fun.kw = fun_name}

Having a return value pin.value()

stay “ports/mimxrt/machine_pin.c” find machine_pin_init() function :

// pin.value([value])
STATIC mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args) {
    
    return machine_pin_obj_call(args[0], (n_args - 1), 0, args + 1);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_pin_value);

Yes, it is pin.init() A lesson from the past , This pin.value() Use the positional parameter list to save the incoming parameters , It's no wonder .

Here is also the reuse machine_pin_obj_call() function .

Finally used “MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN()” Macro functions , Means at least 1 Parameters , At most 2 Parameters ?2 What the hell is this parameter ?

#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) \ const mp_obj_fun_builtin_var_t obj_name = \ {
      {
      &mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, false), .fun.var = fun_name}

Processing of return value , Just return the object , If it's an integer , Just use macro functions “MP_OBJ_NEW_SMALL_INT()” Convert an integer to OBJ Just return directly in the form of , This return value will be directly returned to the user script .

Summary

How to write function functions : No parameter 、 There are keyword parameters ( The number of parameters is greater than or equal to 1)、 Only position parameters ( The number of parameters is greater than 1)、 There is a return value , Several elements have been revealed .

next step , Apply the pattern here to realize the migration on the new platform , In case of specific problems, refer to the existing implementations .


From morning to night , I'm sick of writing .
END

原网站

版权声明
本文为[suyong_ yq]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/161/202206101740014040.html

随机推荐