本文介绍了在C语言中实现附加功能的选项,但这些功能是通过在MicroPython主资源库之外编写的代码实现的。第一种方法适用于构建定制固件,其中包含一些可从Python访问的特定项目附加模块或函数。第二种方法用于构建可在运行时加载的模块。
有关构建MicroPython主资源库中核心模块的更多信息,请参阅库部分。
MicroPython外部C语言模块
在开发用于MicroPython的模块时,可能会遇到Python环境的限制,这通常是由于无法访问某些硬件资源或Python速度限制造成的。
如果限制无法通过MicroPython性能调优中的建议来解决,那么用C语言编写部分或全部模块是一个可行的选择。
如果模块旨在访问或使用常见的硬件或库,建议在MicroPython源代码树中与类似模块一起实现,并将其作为拉取请求提交。但是,如果目标是晦涩难懂或专有的系统,将其保留在MicroPython主资源库之外可能更有意义。
本文将介绍如何将这些外部模块编译到MicroPython可执行文件或固件映像中。Make和CMake两种编译工具都支持,在编写外部模块时,最好为这两种工具添加编译文件,这样模块就可以在所有移植上使用。但在编译某个特定的移植时,您只需使用一种编译方法,即 Make或CMake。
另一种方法是在.mpy
文件中使用本地机器代码,这样就可以编写放置在.mpy
文件中的自定义C代码,并将其动态导入运行中的MicroPython系统而无需重新编译主固件。
外部C语言模块结构
MicroPython用户C模块是一个包含以下文件的目录:
-
模块的
*.c / *.cpp / *.h
源代码文件。
这些文件通常包括正在实现的底层功能以及用于公开函数和模块的MicroPython绑定函数。
目前,编写这些函数/模块的最佳参考方法是在MicroPython目录中查找类似模块并将其作为示例。 -
micropython.mk
包含该模块的Makefile 片段。
在microropython.mk
中,$(USERMOD_DIR)
是模块目录的路径。由于每个c模块都要重新定义它,因此应在microropython.mk
中将其扩展为一个本地make
变量,例如EXAMPLE_MOD_DIR := $(USERMOD_DIR)
microropython.mk
必须将模块源文件添加到SRC_USERMOD_C
或SRC_USERMOD_LIB_C
变量中。前者将用于处理MP_QSTR_
和MP_REGISTER_MODULE
定义,后者则不会(例如非MicroPython专用的帮助程序和库代码)。这些路径应包括$(USERMOD_DIR)
的扩展副本,例如:SRC_USERMOD_C += $(EXAMPLE_MOD_DIR)/modexample.c SRC_USERMOD_LIB_C += $(EXAMPLE_MOD_DIR)/utils/algorithm.c
同样,对C++源文件使用
SRC_USERMOD_CXX
和SRC_USERMOD_LIB_CXX
。
如果有自定义编译器选项(如-I
用于添加搜索头文件的目录),则应将这些选项添加到用于C代码的CFLAGS_USERMOD
和用于C++代码的CXXFLAGS_USERMOD
中。 -
micropython.cmake
包含该模块的CMake
配置。
在micropython.cmake
中,可以使用${CMAKE_CURRENT_LIST_DIR}
作为当前模块的路径。
microropython.cmake
应定义一个INTERFACE
库,并将源文件、编译定义和包含目录与之关联。然后将该库链接到usermod
目标。add_library(usermod_cexample INTERFACE) target_sources(usermod_cexample INTERFACE ${ CMAKE_CURRENT_LIST_DIR}/examplemodule.c ) target_include_directories(usermod_cexample INTERFACE ${ CMAKE_CURRENT_LIST_DIR} ) target_link_libraries(usermod INTERFACE usermod_cexample)
完整使用示例见下文。
基本示例
cexample
模块提供了一个函数和一个类的示例。cexample.add_ints(a, b)
函数将两个整数参数相加并返回结果。cexample.Timer()
可创建计时器,用于测量对象实例化后的经过时间。
在MicroPython源代码树的examples
目录中可以找到该模块,它有一个源文件和一个 Makefile 片段,内容如下:
micropython/
└──examples/
└──usercmodule/
└──cexample/
├── examplemodule.c
├── micropython.mk
└── micropython.cmake
<