当前位置:网站首页>Read the source code of micropyton - add the C extension class module (2)
Read the source code of micropyton - add the C extension class module (2)
2022-06-10 21:05:00 【suyong_ yq】
read micropyton Source code - add to C Extension class module (2)
Su Yong ,2021 year 8 month
List of articles
have a look machine_pin_type Definition of instance
go back to ports/mimxrt/machine_pin.c file , Same as machine_pin_type There are also “machine_pin_af_type”, stay “pin.h” and “ports/mimxrt/boards/mimxrt_prefix.c” It is mentioned in the document , About the reuse of specified pin functions , It also seems to be defined as an instance object , But it is not registered in any module , For the time being , After reading machine_pin_type Then come back and see .
as for “machine_pin_irq_methods”, Still defining machine_pin_type Is called in the method to which the , I'll see it later .
Told the side story , Finally, I can calm down and pay attention to machine_pin_type 了 .
const mp_obj_type_t machine_pin_type = {
{
&mp_type_type},
.name = MP_QSTR_Pin,
.print = machine_pin_obj_print,
.call = machine_pin_obj_call,
.make_new = mp_pin_make_new,
.locals_dict = (mp_obj_dict_t *)&machine_pin_locals_dict,
};
Whole machine_pin.c Just to fill this one mp_obj_type_t Examples of structures of type , What's used here is “ Hard callback ” The encoding mode of . About “mp_obj_type_t” The definition of , For details, see “py/obj.h” file , Only the necessary fields are explained here .
“&mp_type_type” Specify that the base class of this module is a type object , Directly inherits some types (type) Object method .“mp_type_type” stay dynruntime.h The document defines , Same as mp_type_type There are also mp_type_str、mp_type_tuple、mp_type_list etc. .
“.name” The name of this module is registered in , stay python In the implementation of , Are indexed by name strings , Keyword strings are all in qstr type ,qstr The string of type is used directly “MP_QSTR_” Prefix , And don't use double quotation marks . This is during compilation , Will compile the host python Scripts automatically extract these qstr Actual string for , This operation is similar to c Preprocessing in the compiler tool chain .
“.print” Specified function , It is when the user is python Call in print(Pin) Function time , take Pin The instantiated object of is printed as a string .
machine_pin Yes print The implementation of the function is as follows , Print “machine_pin_obj_t” Structure type “name” Field string .
STATIC void machine_pin_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) {
(void)kind;
const machine_pin_obj_t *self = MP_OBJ_TO_PTR(o);
mp_printf(print, "Pin(%s)", qstr_str(self->name));
}
“machine_pin_obj_t” The structure type is in “pin.h” Defined in the file , But I think it can also be placed directly in “machine_pin.h” In file . stay mimxrt In the implementation of ,machine_pin_type and machine_pin_af_type All belong to “pin.h” in . As for this “name” When was the field filled in , I guess it is. new Filled in when , Let's wait and see .“mp_print_t” Is the printed object , It can be an interactive terminal , It can also be log file .
- “.call” Specified function , The corresponding is Python An instance method of a very special class in , namely __call__(). The function of this method is similar to overloading in a class () Operator , So that the class instance object can call ordinary functions , With “ Object name ()” In the form of . To be frank , The name of the instance object itself is also regarded as a function name .machine_pin Yes call The implementation of the function is as follows :
STATIC mp_obj_t machine_pin_obj_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
machine_pin_obj_t *self = self_in;
if (n_args == 0) {
return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self));
} else {
mp_hal_pin_write(self, mp_obj_is_true(args[0]));
return mp_const_none;
}
}
Combined with the implementation example here call() Usage of attribute function :
pin1 = Pin() # Instantiate a Pin The object of pin1
print(pin1()) # If the number of parameters is 0 individual , Then return to mp_hal_pin_read() Function to read the pin value
pin1(0) # If the parameter is 1 individual , Then the first parameter passed in args[0] As mp_hal_pin_write() The parameters of the function , The write pin specifies the level value
See :Python call() Method ( Detailed Edition )
- “.make_new” Specified function , Is the operation process of instantiating a class object . This new The function will “ Out of thin air ”, stay gc Dynamically apply for a piece of memory in the managed memory area , Fill in the necessary attribute information , Then the handle of this memory ( The pointer ) Back to the caller . The corresponding... Will be described in detail below “mp_pin_make_new()” Implementation of function , The parameter transfer process implemented by this function is quite interesting , You can specify objects in different numbering ways , There will be a special space for a detailed introduction below .
Add a sentence , If you follow a seemingly uniform naming convention , there “mp_pin_make_new()” Function names should be used like other attribute functions “machine_pin_obj” Prefix , be called “machine_pin_obj_make_new”
- “.locals_dict” Is a list of local keywords contained in this class and their corresponding functions ( Constant ? function ?). stay python There is a built-in function in locals(),locals() The function returns all local variables in the current position as dictionary type . Guess what's going on here “locals_dict” Is to provide a returnable Dictionary , Also used as a module internal “.” The property and method resources that the operator continues to access .
machine_pin Yes locals_dict The implementation is as follows :
STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = {
// instance methods
{
MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_off_obj) },
{
MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_on_obj) },
{
MP_ROM_QSTR(MP_QSTR_low), MP_ROM_PTR(&machine_pin_off_obj) },
{
MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&machine_pin_on_obj) },
{
MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_pin_value_obj) },
{
MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pin_init_obj) },
{
MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_pin_irq_obj) },
// class attributes
{
MP_ROM_QSTR(MP_QSTR_board), MP_ROM_PTR(&machine_pin_board_pins_obj_type) },
{
MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&machine_pin_cpu_pins_obj_type) },
// class constants
{
MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(PIN_MODE_IN) },
{
MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(PIN_MODE_OUT) },
{
MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(PIN_MODE_OPEN_DRAIN) },
{
MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(PIN_PULL_UP_100K) },
{
MP_ROM_QSTR(MP_QSTR_PULL_UP_47K), MP_ROM_INT(PIN_PULL_UP_47K) },
{
MP_ROM_QSTR(MP_QSTR_PULL_UP_22K), MP_ROM_INT(PIN_PULL_UP_22K) },
{
MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(PIN_PULL_DOWN_100K) },
{
MP_ROM_QSTR(MP_QSTR_PULL_HOLD), MP_ROM_INT(PIN_PULL_HOLD) },
{
MP_ROM_QSTR(MP_QSTR_DRIVER_OFF), MP_ROM_INT(PIN_DRIVE_OFF) },
{
MP_ROM_QSTR(MP_QSTR_POWER_0), MP_ROM_INT(PIN_DRIVE_POWER_0) }, // R0 (150 Ohm @3.3V / 260 Ohm @ 1.8V)
{
MP_ROM_QSTR(MP_QSTR_POWER_1), MP_ROM_INT(PIN_DRIVE_POWER_1) }, // R0/2
{
MP_ROM_QSTR(MP_QSTR_POWER_2), MP_ROM_INT(PIN_DRIVE_POWER_2) }, // R0/3
{
MP_ROM_QSTR(MP_QSTR_POWER_3), MP_ROM_INT(PIN_DRIVE_POWER_3) }, // R0/4
{
MP_ROM_QSTR(MP_QSTR_POWER_4), MP_ROM_INT(PIN_DRIVE_POWER_4) }, // R0/5
{
MP_ROM_QSTR(MP_QSTR_POWER_5), MP_ROM_INT(PIN_DRIVE_POWER_5) }, // R0/6
{
MP_ROM_QSTR(MP_QSTR_POWER_6), MP_ROM_INT(PIN_DRIVE_POWER_6) }, // R0/7
{
MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(1) },
{
MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(2) },
“mp_rom_map_elem_t” As the name suggests, it is stored in rom Medium map Element type , Contains a number of “ Key value pair ”, On the left for qstr Keyword string of type , The right corresponds to the resource . for example :“MP_QSTR_off” The corresponding is “off” Keywords and functions “machine_pin_off_obj”,“MP_ROM_PTR()” The macro specifically specifies that this is a “PTR” The pointer ;“MP_QSTR_IN” The corresponding is “IN” Key words and “PIN_MODE_IN” Constant ,“MP_ROM_INT()” The macro specifically specifies that this is a “INT” Integers ,“PIN_MODE_INT” The value of is also in “pin.h” Defined in the file .
In particular
stay machine_pin.c Some macro operations are used in the file , Encapsulate a function or an array into an object . Bear in mind , stay python in , Everything is the object , function 、 Array 、 Variables and even constants .
As small as a pointer 、 Constant :
MP_ROM_PTR(&machine_pin_off_obj)
MP_ROM_INT(1)
As big as a function 、 Array :
MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_off_obj, machine_pin_off);
MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_init_obj, 1, machine_pin_init);
MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table);
Their implementation code is in “py/obj.h” In file , It actually defines a new variable that references the current resource :
#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) \ const mp_obj_fun_builtin_fixed_t obj_name = \ {
{
&mp_type_fun_builtin_0}, .fun._0 = fun_name}
#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) \ const mp_obj_fun_builtin_fixed_t obj_name = \ {
{
&mp_type_fun_builtin_1}, .fun._1 = fun_name}
#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) \ const mp_obj_fun_builtin_fixed_t obj_name = \ {
{
&mp_type_fun_builtin_2}, .fun._2 = fun_name}
#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) \ const mp_obj_fun_builtin_fixed_t obj_name = \ {
{
&mp_type_fun_builtin_3}, .fun._3 = fun_name}
...
#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}
...
#define MP_DEFINE_CONST_DICT(dict_name, table_name) \ const mp_obj_dict_t dict_name = {
\ .base = {
&mp_type_dict}, \ .map = {
\ .all_keys_are_qstrs = 1, \ .is_fixed = 1, \ .is_ordered = 1, \ .used = MP_ARRAY_SIZE(table_name), \ .alloc = MP_ARRAY_SIZE(table_name), \ .table = (mp_map_elem_t *)(mp_rom_map_elem_t *)table_name, \ }, \ }
As for “mp_type_fun_builtin_1” The definition of , be located “py/objfun.c” In file , Is a constant structure , Not a type :
STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_1));
mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in);
mp_arg_check_num(n_args, n_kw, 1, 1, false);
return self->fun._1(args[0]);
}
const mp_obj_type_t mp_type_fun_builtin_1 = {
{
&mp_type_type },
.flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_BUILTIN_FUN,
.name = MP_QSTR_function,
.call = fun_builtin_1_call,
.unary_op = mp_generic_unary_op,
};
“mp_type_fun_builtin_1” Of “.call” Point to “fun_builtin_1_call()” function , From the implementation code of this function, we can see , Among them through “mp_arg_check_num()” The function checks the arguments , Valid incoming parameters are only 1 individual . After through “self->fun._1()” Function execution MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) Carry out the fun_name, and obj_name It's here “self”.
Similarly , stay “fun_builtin_2_call()” Function , The valid parameters are also filtered as 2 individual ,“self->fun._2()” The passed in arguments to the function are two ,args[0] and args[1].
as for func._1 and func._2, And the function pointers of variable parameters or keyword parameters that you may often see later var and kw, In fact, they are all function pointers , Defined in the structure as sharing a block of memory union. stay “py/obj.h” There is :
typedef struct _mp_obj_fun_builtin_fixed_t {
mp_obj_base_t base;
union {
mp_fun_0_t _0;
mp_fun_1_t _1;
mp_fun_2_t _2;
mp_fun_3_t _3;
} fun;
} mp_obj_fun_builtin_fixed_t;
typedef struct _mp_obj_fun_builtin_var_t {
mp_obj_base_t base;
uint32_t sig; // see MP_OBJ_FUN_MAKE_SIG
union {
mp_fun_var_t var;
mp_fun_kw_t kw;
} fun;
} mp_obj_fun_builtin_var_t;
This section references a lot of code , It's longer , That's it . The next section explains in detail Pin Definition methods of internal variables and member functions in the module .
END
边栏推荐
- Solve the problem that the idea automatically becomes * when there are more than 5 identical packages
- 牛客网:数组中出现次数超过一半的数字
- Li Kou 10821084 solution_ Question of SQL query type
- Arduino中Serial.print()与Serial.write()函数的区别,以及串口通信中十六进制与字符串的收发格式问题和转换过程详解
- 京东发布基于张量网络加速的大规模、分布式量子机器学习平台TeD-Q
- Meetup预告:Linkis新版本介绍以及DSS的应用实践
- "Bug" problem analysisruntimeerror:which is output 0 of resubackward0
- Jiangbolong forestee xp2000 PCIe 4.0 SSD multi encryption function, locking data security
- AttributeError: module ‘collections‘ has no attribute ‘MutableMapping‘
- Deploying static websites using OSS and CDN on Alibaba cloud international
猜你喜欢

面试必备——synchronized底层原理的基础知识

LeetCode:497. Random points in non overlapping rectangles -- medium
![JS basic and frequently asked interview questions [] = =! [] result is true, [] = = [] result is false detailed explanation](/img/42/bcda46a9297a544b44fea31be3f686.png)
JS basic and frequently asked interview questions [] = =! [] result is true, [] = = [] result is false detailed explanation

Software definition boundary (SDP)

Diablo immortal wiki address Diablo immortal database address sharing

User defined date component. The left and right buttons control forward or backward year, month, week and day turning

牛客网:数组中出现次数超过一半的数字

Pytorch deep learning -- neural network convolution layer conv2d

vulnhub-The Planets: Earth

RuntimeError: Attempting to deserialize object on CUDA device 1 but torch. cuda. device_ count() is 1.
随机推荐
详解三级缓存解决循环依赖
Canvas advanced functions (medium)
【电脑使用】如何设置没有自启项的软件开机启动
农产品期货开户的条件是什么?现在开户的手续费是多少?
LeetCode:497. 非重叠矩形中的随机点————中等
终于有人说清楚了Cookie、Session、Token的区别。详解,面试题。
An old programmer of about 10 years said: simple crud function enters the era of codeless development 1. Adding, deleting, modifying and checking interface information
RuntimeError: Attempting to deserialize object on CUDA device 1 but torch.cuda.device_count() is 1.
Enhance the target method with surround notifications - extract notes
KCon 2022 议题大众评选火热进行中!不要错过“心仪”的议题哦~
Portable FDW framework for Pb
深度学习调参经验和工具
玩艺术也得学数学?
六级考试-商务英语-考前最后一背
In MySQL basics, MySQL adds an automatically added primary key (or any field) to an existing table
Redis cluster form - sentry mode cluster and high availability mode cluster - redis learning notes 003
为什么网页样式属性,有的需要加冒号“:”,有的不用?
72. editing distance ●●
LeetCode:1037. 有效的回旋镖————简单
pdf.js-----js解析pdf文件实现预览,并获取pdf文件中的内容(数组形式)