MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.
microPython Python最小内核源码解析
NI-motion运动控制c语言示例代码解析
python编程示例系列 python编程示例系列二
python的Web神器Streamlit
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
// 定义 MicroPython 配置和运行时环境的头文件
#include "py/mpconfig.h"
#include "py/runtime.h"
#include "py/mpprint.h"
// 定义一个宏,用于分配内存时向上取整到8的倍数,同时至少比原值大1
#define ROUND_ALLOC(a) (((a) & ((~0U) - 7)) + 8)
// 初始化 vstr 结构体,分配指定大小的内存,初始长度设置为0
void vstr_init(vstr_t *vstr, size_t alloc) {
if (alloc < 1) {
alloc = 1; // 如果分配的内存小于1,重置为1
}
vstr->alloc = alloc; // 设置分配的内存大小
vstr->len = 0; // 初始化字符串长度为0
vstr->buf = m_new(char, vstr->alloc); // 分配内存
vstr->fixed_buf = false; // 标记是否为固定缓冲区
}
// 初始化 vstr 结构体,分配刚好足够容纳给定长度字符串的内存,并设置长度
void vstr_init_len(vstr_t *vstr, size_t len) {
vstr_init(vstr, len + 1); // 分配内存,长度加1为了容纳字符串结束符'\0'
vstr->len = len; // 设置字符串的实际长度
}
// 使用给定的固定大小的缓冲区初始化 vstr 结构体
void vstr_init_fixed_buf(vstr_t *vstr, size_t alloc, char *buf) {
vstr->alloc = alloc; // 设置分配的内存大小
vstr->len = 0; // 初始化字符串长度为0
vstr->buf = buf; // 设置字符串缓冲区
vstr->fixed_buf = true; // 标记为固定缓冲区
}
// 初始化 vstr 结构体,并设置打印函数,用于后续的字符串添加操作
void vstr_init_print(vstr_t *vstr, size_t alloc, mp_print_t *print) {
vstr_init(vstr, alloc); // 初始化 vstr
print->data = vstr; // 设置打印数据为 vstr 结构体
print->print_strn = (mp_print_strn_t)vstr_add_strn; // 设置打印字符串的函数指针
}
// 清空 vstr 结构体,释放内存
void vstr_clear(vstr_t *vstr) {
if (!vstr->fixed_buf) {
// 如果不是固定缓冲区,则释放内存
m_del(char, vstr->buf, vstr->alloc);
}
vstr->buf = NULL; // 清空缓冲区指针
}
// 创建并初始化一个新的 vstr 结构体,分配指定大小的内存
vstr_t *vstr_new(size_t alloc) {
vstr_t *vstr = m_new_obj(vstr_t); // 创建新的 vstr 结构体对象
vstr_init(vstr, alloc); // 初始化 vstr
return vstr; // 返回新创建的 vstr 对象
}
// 释放 vstr 结构体占用的内存
void vstr_free(vstr_t *vstr) {
if (vstr != NULL) {
// 检查 vstr 是否为空
if (!vstr->fixed_buf) {
// 如果不是固定缓冲区,则释放内存
m_del(char, vstr->buf, vstr->alloc);
}
m_del_obj(vstr_t, vstr); // 释放 vstr 结构体对象
}
}
// 扩展 vstr 结构体的内存,增加指定大小的内存空间,并返回新扩展的内存地址
char *vstr_extend(vstr_t *vstr, size_t size) {
if (vstr->fixed_buf) {
// 如果是固定缓冲区,则不能重新分配内存
// 抛出运行时错误
mp_raise_msg(&mp_type_RuntimeError, NULL);
}
char *new_buf = m_renew(char, vstr->buf, vstr->alloc, vstr->alloc + size); // 重新分配内存
char *p = new_buf + vstr->alloc; // 获取新扩展的内存地址
vstr->alloc += size; // 更新分配的内存大小
vstr->buf = new_buf; // 更新缓冲区地址
return p; // 返回新扩展的内存地址
}
// 确保 vstr 结构体有足够的额外空间来存储指定大小的数据
static void vstr_ensure_extra(vstr_t *vstr, size_t size) {
if (vstr->len + size > vstr->alloc) {
// 如果当前分配的内存不足以存储额外的数据
if (vstr->fixed_buf) {
// 如果是固定缓冲区,则不能重新分配内存
// 抛出运行时错误
mp_raise_msg(&mp_type_RuntimeError, NULL);
}
size_t new_alloc = ROUND_ALLOC((vstr->len + size) + 16); // 计算新的内存分配大小
char *new_buf = m_renew(char, vstr->buf, vstr->alloc, new_alloc); // 重新分配内存
vstr->alloc = new_alloc;