MicroPython中pyboard模块与C实现的映射关系及定义位置咨询
Great question! This is one of the key differences between MicroPython and standard CPython—many core hardware-focused modules like pyb don’t have a corresponding .py file you can dig into. Instead, they’re directly implemented in C and registered with the MicroPython virtual machine (VM) at firmware compile time. Let’s break this down using your examples.
1. Where is the pyb module’s Python file?
Short answer: There isn’t one. When you run import pyb, the MicroPython VM doesn’t scan the filesystem for a pyb.py file. Instead, it checks a pre-registered list of built-in modules that are defined entirely in C.
For the pyboard (STM32 port), the pyb module lives in a file like ports/stm32/modules/pybmodule.c. This file contains a C structure (mp_module_t) that describes the module: its name, and a dictionary of all the classes, functions, and constants it exposes (like LED, Pin, UART, etc.). The module gets registered with the VM during firmware compilation, so it’s available immediately when the board boots up.
2. The LED class and its intensity() method
Same logic applies here—there’s no Python class definition for LED in a .py file. The LED class is a C-defined type (mp_type_t structure) that’s added to the pyb module’s dictionary.
When you run from pyb import LED, the VM looks up the LED entry in the pyb module’s C dictionary, which points to the mp_type_t structure for the LED class. This structure includes:
- The class name (
LED) - A constructor (for creating instances like
LED(1)) - A dictionary of methods, including
intensity()
The intensity() method is a C function wrapped into a MicroPython object. For example, in pybmodule.c, you’ll find a function like pyb_led_intensity() that handles the low-level hardware logic to adjust the LED’s brightness. This function is registered as a method of the LED type via a method table, so when you call LED(1).intensity(50), the VM directly invokes this C function.
Under the Hood: A Simplified C Code Example
To make this concrete, here’s a stripped-down snippet of what the C code looks like for the LED class and intensity method:
// C implementation of the intensity() method STATIC mp_obj_t pyb_led_intensity(mp_obj_t self_in, mp_obj_t intensity_in) { // Convert MicroPython objects to C types pyb_led_obj_t *self = MP_OBJ_TO_PTR(self_in); uint8_t intensity = mp_obj_get_int(intensity_in); // Low-level hardware call to set LED brightness led_set_intensity(self->led_id, intensity); return mp_const_none; } // Wrap the C function into a MicroPython function object STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_led_intensity_obj, pyb_led_intensity); // Method table for the LED class STATIC const mp_rom_map_elem_t pyb_led_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_intensity), MP_ROM_PTR(&pyb_led_intensity_obj) }, // Other methods like on(), off(), toggle() go here }; STATIC MP_DEFINE_CONST_DICT(pyb_led_locals_dict, pyb_led_locals_dict_table); // Define the LED class type const mp_obj_type_t pyb_led_type = { { &mp_type_type }, .name = MP_QSTR_LED, .locals_dict = (mp_obj_dict_t*)&pyb_led_locals_dict, // Constructor and other class properties go here }; // Add the LED class to the pyb module's dictionary STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pyb) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pyb_led_type) }, // Other pyb module members go here }; STATIC MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table); // Define the pyb module itself const mp_obj_module_t pyb_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&pyb_module_globals, }; // Register the module with the MicroPython VM MP_REGISTER_MODULE(MP_QSTR_pyb, pyb_module);
Key Takeaways
- No .py files for built-in hardware modules: MicroPython’s core modules like
pybare implemented in C and registered directly with the VM to save memory and boost performance. - Classes are C structures: Types like
LEDare defined asmp_type_tstructs, with methods mapped directly to C functions. - VM handles translation: When you call a method like
intensity(), the MicroPython VM looks up the corresponding C function and executes it directly, skipping Python-level interpretation entirely.
内容的提问来源于stack exchange,提问作者hustzhuch

