k210编写c模块,参数的传入和传出

本文详细介绍了基于K210芯片的MicroPython模块开发流程,包括源码编写、编译位置设置、是否编译进固件的判断、参数处理和错误处理。通过示例代码展示了如何定义和注册函数、处理不同类型的参数,以及创建和注册模块。同时,文章还列举了常见的编译错误和注意事项,帮助开发者避免常见问题。
摘要由CSDN通过智能技术生成

系统基于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模块

传入参数处理

类别函数接口参数数据转换
int32mp_obj_t input_data_objmp_int_t input_data = mp_obj_get_int(input_data_obj);
floatmp_obj_t input_data_objmp_float_t input_data = mp_obj_get_float(input_data_obj);
NULL结尾的strmp_obj_t input_data_objconst 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]);

函数内部定义变量

cMicroPython
intmp_int_t
floatmp_float_t
strconst 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);


持续更新中,,,记得收藏

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酸奶可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值