先看看目录,做到步骤明确
系统基于K210的MicroPython
记住这个流程:
除了模块是要激活的,凡是定义了的,都必须要注册一下
具体调用的函数名实在字典前面的****:MP_OBJ_NEW_QSTR(MP_QSTR_*****)
micropython中都是指针,所以采用字典的形式,可以理解为字典存放着当前模块的所有对象的指针
基本步骤(按顺序):
简单示例
源码编写
#include "stdint.h"
#include "stdio.h"
#include "py/obj.h"
#include "py/runtime.h"
//-------------------------------必须包含上面的库文件,否则出现问题,具体原因还不清楚----------------
//------------------------------------------------------------------------------
STATIC mp_obj_t modtest_test0()
{
printf("This is motest function :test0\n");
return mp_const_none;//不需要返回数据就返回它
}
//每一个我们和python接口的函数都需要使用这个宏定义
STATIC const MP_DEFINE_CONST_FUN_OBJ_0(modtest_obj_test0,modtest_test0);
//------------------------------------------------------------------------------
//参数类型要用mp_obj_t
STATIC mp_obj_t modtest_test1(mp_obj_t data)
{
printf("This function have one parameters: %d\n",mp_obj_get_int(data)); //请注意这里从参数中提取整数使用的方法
return mp_const_none; //同样没有返回值
}
//这里使用的宏定义和面的名称不一样,OBJ_1区别
STATIC const MP_DEFINE_CONST_FUN_OBJ_1(modtest_obj_test1,modtest_test1);
//------------------------------------------------------------------------------
STATIC const mp_rom_map_elem_t modtest_globals_table[] = {
{MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_modtest)},
{MP_OBJ_NEW_QSTR(MP_QSTR_test0), MP_ROM_PTR(&modtest_obj_test0)},
{MP_OBJ_NEW_QSTR(MP_QSTR_test1), MP_ROM_PTR(&modtest_obj_test1)}, //把新定义的函数注册进modtest_globals_table
};
//前面的是具体调用时所显示的函数名,后面是指向编写的代码
//实际调用时候调用:
//.__name__
//.test0()
//.test1()
//这个可以认为是把modtest_globals_table注册到 mp_module_modtest.globals里面去
STATIC MP_DEFINE_CONST_DICT(mp_module_modtest_globals, modtest_globals_table);
//------------------------------------------------------------------------------
//这个是定义一个module类型
const mp_obj_module_t my_lib_module = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mp_module_modtest_globals,
};
MP_REGISTER_MODULE(MP_QSTR_my_lib, my_lib_module, MODULE_MY_LIB_ENABLED);
//------------------------------------------------------------------------------
最后一行的
MP_REGISTER_MODULE(MP_QSTR_my_lib, my_lib_module, MODULE_MY_LIB_ENABLED);
特别重要,决定该模块是否注册。
相关的设置
设置编译位置
位置的设置,决定着是否编译。
打开
MaixPy\components\micropython\CMakeLists.txt
然后在############## Add source files ###############下面添加编译地址
append_srcs_dir(MPY_PORT_SRCS "port/src/my_lib")
是否**编译进固件**
上面的步骤决定着是否编译,编译进固件则取决于这个,千万不要弄错了位置
文件目录:
MaixPy\components\micropython\port\include\mpconfigport.h
中添加
#define MODULE_MY_LIB_ENABLED (1)
#这里有必要说一些,这是是否激活你的模块的语句,并且要和模块名一致
编译测试
带参数的c模块
传入参数处理
类别 | 函数接口 | 参数数据转换 |
---|---|---|
int32 | mp_obj_t input_data_obj | mp_int_t input_data = mp_obj_get_int(input_data_obj); |
float | mp_obj_t input_data_obj | mp_float_t input_data = mp_obj_get_float(input_data_obj); |
NULL结尾的str | mp_obj_t input_data_obj | const char* input_data = mp_obj_str_get_str(input_data_obj); |
一般str:
函数接口:
mp_obj_t input_data_obj
获取数据和长度:
size_t input_data_len;//数据长度
const char* input_data = mp_obj_str_get_data(input_data_obj, &input_data_len);
list:
函数接口:
mp_obj_t input_data_obj
获取数据和长度:
//定义一个空指针、获取列表长度长度的变量
mp_obj_t *input_data = NULL;
size_t input_data_len = 0;
//将参数(input_data_obj 视为 input_data_arg),得到对应的长度、起始地址
mp_obj_get_array(input_data_arg, &input_data_len, &input_data);
//获取对应序列的值:int、float、str
mp_int_t input_data_item_1 = mp_obj_get_int(input_data[0]);
mp_float_t input_data_item_2 = mp_obj_get_float(input_data[1]);
//注意这个,他是一个字符串
const char* input_data_item_3 = mp_obj_str_get_str(input_data[2]);
函数内部定义变量
c | MicroPython |
---|---|
int | mp_int_t |
float | mp_float_t |
str | const char* |
传出参数以及内部变量处
类别 | 预先变量定义 | 返回时语句 |
---|---|---|
无返回值 | 无需定义 | mp_const_none ; |
布尔值 | bool ret_val; | mp_obj_new_bool( ret_val ); |
整型数据 | mp_int_t ret_val; | return mp_obj_new_int(ret_val); |
浮点数 | mp_float_t ret_val; | mp_obj_new_float(ret_val); |
字符串 | const char* str; | mp_obj_new_str(首地址, 长度); |
字节串 | const char* str; | mp_obj_new_bytes(首地址, 长度); |
列表:
列表定义:
mp_obj_t ret_val[] = {
mp_obj_new_int(123),
mp_obj_new_float(456.789),
mp_obj_new_str("hello", 5),
};
返回:
mp_obj_new_list(3, ret_val);
mp_obj_new_list函数的定义:
mp_obj_t mp_obj_new_list(size_t n, const mp_obj_t *items);
字典定义:
ret_val = mp_obj_dict(0);
mp_obj_dict_store(ret_val, mp_obj_new_str("element1", 8), mp_obj_new_int(123));
mp_obj_dict_store(ret_val, mp_obj_new_str("element2", 8), mp_obj_new_float(456.789));
mp_obj_dict_store(ret_val, mp_obj_new_str("element3", 8), mp_obj_new_str("hello", 5));
返回:
return ret_val;
对list参数传入的测试
list测试:
目的:传入一个数组,获取每一个单元的数据并打印,最后统计并打印数据长度
第一步:请将下列函数拷贝到文件中
//--------------------------------------------------------------------
STATIC mp_obj_t list_test_func( mp_obj_t input_data_obj ) {
//定义一个空指针、获取列表长度长度的变量
mp_obj_t *input_data = NULL;
size_t input_data_len = 0;
//将参数(input_data_obj 视为 input_data_arg),得到对应的长度、起始地址
mp_obj_get_array(input_data_obj, &input_data_len, &input_data);
//定义的一个返回变量,这里用不到
mp_float_t ret_val;
mp_int_t i;
/* Your code start! */
ret_val = 0.1;
for(i=0 ; i < input_data_len;i++)
{
//打印列表中每一个浮点数
printf("arg %ld is %f\n",i , mp_obj_get_float( input_data[i] ) );
}
//打印列表长度
printf("length of list is %d\n", i);
/* Your code end! */
// Example exception
//if (some_val == 0) {
// mp_raise_ValueError("some_val can't be zero!");
//}
return mp_obj_new_float(ret_val);
}
MP_DEFINE_CONST_FUN_OBJ_1(list_test_func_obj, list_test_func);
第二步:请将下面 <未注释> 的代码行拷贝到模块注册列表中
// STATIC const mp_rom_map_elem_t my_module_globals_table[] = { <----- 在模块中找到这个列表
// { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_builtins) },
//----------------------------------------------------------------------------------------------------
{ MP_ROM_QSTR(MP_QSTR_list_test_func), MP_ROM_PTR(&list_test_func_obj) },
//----------------------------------------------------------------------------------------------------
// Example constant
{ MP_ROM_QSTR(MP_QSTR_EXAMPLE_CONST), MP_ROM_INT(123) },
// };
常见编译错误以及注意事项
注意事项
1.变量的定义要先定义,定义完必须赋值
2.要先定义函数,然后定义字典,最后定义模块
编译错误
1.未初始化==========》定义了,但是没有赋值;
源码
#include "stdint.h"
#include "stdio.h"
#include "py/obj.h"
#include "py/runtime.h"
//--------------------------------------------------------------------
STATIC mp_obj_t list_test_func( mp_obj_t input_data_obj ) {
//定义一个空指针、获取列表长度长度的变量
mp_obj_t *input_data = NULL;
size_t input_data_len = 0;
//将参数(input_data_obj 视为 input_data_arg),得到对应的长度、起始地址
mp_obj_get_array(input_data_obj, &input_data_len, &input_data);
//获取对应序列的值:int、float、str
//mp_int_t input_data_item_1 = mp_obj_get_int(input_data[0]);
//mp_float_t input_data_item_2 = mp_obj_get_float(input_data[1]);
//注意这个,他是一个字符串
//const char* input_data_item_3 = mp_obj_str_get_str(input_data[2]);
//定义的一个返回变量,这里用不到
mp_float_t ret_val;
mp_int_t i;
/* Your code start! */
ret_val = 0.1;
for(i=0 ; i < input_data_len;i++)
{
//打印列表中每一个浮点数
printf("arg %ld is %f\n",i , mp_obj_get_float( input_data[i] ) );
}
//打印列表长度
printf("length of list is %d\n", i);
/* Your code end! */
// Example exception
//if (some_val == 0) {
// mp_raise_ValueError("some_val can't be zero!");
//}
return mp_obj_new_float(ret_val);
}
MP_DEFINE_CONST_FUN_OBJ_1(list_test_func_obj, list_test_func);
//--------------------------------------------------------------------
STATIC mp_obj_t mode_test()
{
printf("This is motest function :test0\n");
return mp_const_none;//不需要返回数据就返回它
}
//每一个我们和python接口的函数都需要使用这个宏定义
STATIC const MP_DEFINE_CONST_FUN_OBJ_0(mp_mode_test,mode_test);
//--------------------------------------------------------------------
//参数类型要用mp_obj_t
STATIC mp_obj_t func_fir(mp_obj_t data)
{
mp_obj_t x[] = {0,1,2};
printf("This function have one parameters: %s\n",mp_obj_str_get_str(data)); //请注意这里从参数中提取整数使用的方法
return (mp_obj_new_int(x[0])); //同样没有返回值
}
//这里使用的宏定义和面的名称不一样,OBJ_1区别
STATIC const MP_DEFINE_CONST_FUN_OBJ_1(mp_func_fir,func_fir);
//--------------------------------------------------------------------
STATIC const mp_rom_map_elem_t modtest_globals_table[] = {
{MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_modtest)},
{MP_OBJ_NEW_QSTR(MP_QSTR_test0), MP_ROM_PTR(&mp_mode_test)},
{ MP_ROM_QSTR(MP_QSTR_list_test_func), MP_ROM_PTR(&list_test_func_obj) },
{ MP_ROM_QSTR(MP_QSTR_EXAMPLE_CONST), MP_ROM_INT(123) },
{MP_OBJ_NEW_QSTR(MP_QSTR_FIR), MP_ROM_PTR(&mp_func_fir)}, //把新定义的函数注册进modtest_globals_table
};
//这个可以认为是把modtest_globals_table注册到 mp_module_modtest.globals里面去
STATIC MP_DEFINE_CONST_DICT(mp_module_modtest_globals, modtest_globals_table);
//--------------------------------------------------------------------
//这个是定义一个module类型
const mp_obj_module_t my_lib_module = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mp_module_modtest_globals,
};
MP_REGISTER_MODULE(MP_QSTR_my_lib, my_lib_module, MODULE_MY_LIB_ENABLED);
持续更新中,,,记得收藏