MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.
microPython Python最小内核源码解析
NI-motion运动控制c语言示例代码解析
python编程示例系列 python编程示例系列二
python的Web神器Streamlit
这段代码是MicroPython的一部分,用于管理和查找qstr(快速字符串)。qstr是MicroPython中的一个概念,表示一个已经被存储在只读内存中的字符串,这样可以快速地通过索引来访问它们。代码中使用了哈希表来快速查找字符串,并且支持多线程环境下的线程安全。此外,还支持字符串的压缩和解压缩,以节省内存空间。代码中还包含了一些用于调试和内存管理的辅助函数。
#include <assert.h>
#include <string.h>
#include <stdio.h>
// 引入MicroPython特定的头文件
#include "py/mpstate.h"
#include "py/qstr.h"
#include "py/gc.h"
#include "py/runtime.h"
// 根据编译时定义的宏开关,决定是否打印调试信息
#if MICROPY_DEBUG_VERBOSE // 打印调试信息
#define DEBUG_printf DEBUG_printf
#else // 不打印调试信息
#define DEBUG_printf(...) (void)0
#endif
// qstr是qstr池中字符串的索引。
// qstr的数据是\0结尾的(因此可以使用printf打印)
// 根据宏定义决定哈希掩码的大小
#if MICROPY_QSTR_BYTES_IN_HASH
#define Q_HASH_MASK ((1 << (8 * MICROPY_QSTR_BYTES_IN_HASH)) - 1)
#else
#define Q_HASH_MASK (0xffff)
#endif
// 如果启用了线程支持,定义线程安全的操作
#if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
#define QSTR_ENTER() mp_thread_mutex_lock(&MP_STATE_VM(qstr_mutex), 1)
#define QSTR_EXIT() mp_thread_mutex_unlock(&MP_STATE_VM(qstr_mutex))
#else
#define QSTR_ENTER()
#define QSTR_EXIT()
#endif
// qstr池的初始大小,设置为使第一次动态分配的池大小是这个值的两倍
#define MICROPY_ALLOC_QSTR_ENTRIES_INIT (10)
// 计算字符串的哈希值,使用djb2算法
size_t qstr_compute_hash(const byte *data, size_t len) {
size_t hash = 5381; // 初始化哈希值为5381
for (const byte *top = data + len; data < top; data++) {
hash = ((hash << 5) + hash) ^ (*data); // 对每个字节进行哈希计算
}
hash &= Q_HASH_MASK; // 应用哈希掩码
// 确保有效的哈希值永远不会是0,0表示“哈希未计算”
if (hash == 0) {
hash++;
}
return hash;
}
// 静态qstr表,内容必须保持稳定,因为它是.mpy ABI的一部分
#if MICROPY_QSTR_BYTES_IN_HASH
const qstr_hash_t mp_qstr_const_hashes_static[] = {
// 根据genhdr/qstrdefs.generated.h文件生成的qstr哈希值
#ifndef NO_QSTR
#define QDEF0(id, hash, len, str) hash,
#define QDEF1(id, hash, len, str)
#include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
#endif
};
#endif
const qstr_len_t mp_qstr_const_lengths_static[] = {
// 根据genhdr/qstrdefs.generated.h文件生成的qstr长度
#ifndef NO_QSTR
#define QDEF0(id, hash, len, str) len,
#define QDEF1(id, hash, len, str)
#include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
#endif
};
const qstr_pool_t mp_qstr_const_pool_static = {
NULL, // 没有前一个池
0, // 没有前一个池
false, // 未排序
MICROPY_ALLOC_QSTR_ENTRIES_INIT,
MP_QSTRnumber_of_static, // 对应于数组中字符串的数量
#if MICROPY_QSTR_BYTES_IN_HASH
(qstr_hash_t *)mp_qstr_const_hashes_static,
#endif
(qstr_len_t *)mp_qstr_const_lengths_static,
{
// 根据genhdr/qstrdefs.generated.h文件生成的字符串
#ifndef NO_QSTR
#define QDEF0(id, hash, len, str) str,
#define QDEF1(id, hash, len, str)
#include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
#endif
},
};
// 固件中定义的其余qstrs的池,已排序
#if MICROPY_QSTR_BYTES_IN_HASH
const qstr_hash_t mp_qstr_const_hashes[] = {
// 根据genhdr/qstrdefs.generated.h文件生成的qstr哈希值
#ifndef NO_QSTR
#define QDEF0(id, hash, len, str)
#define QDEF1(id, hash, len, str) hash,
#include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
#endif
};
#endif
const qstr_len_t mp_qstr_const_lengths[] = {
// 根据genhdr/qstrdefs.generated.h文件生成的qstr长度
#ifndef NO_QSTR
#define QDEF0(id, hash, len, str)
#define QDEF1(id, hash, len, str) len,
#include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
#endif
};
const qstr_pool_t mp_qstr_const_pool = {
&mp_qstr_const_pool_static,
MP_QSTRnumber_of_static,
true, // 已排序
MICROPY_ALLOC_QSTR_ENTRIES_INIT,
MP_QSTRnumber_of - MP_QSTRnumber_of_static, // 对应于数组中字符串的数量
#if MICROPY_QSTR_BYTES_IN_HASH
(qstr_hash_t *)mp_qstr_const_hashes,
#endif
(qstr_len_t *)mp_qstr_const_lengths,
{
// 根据genhdr/qstrdefs.generated.h文件生成的字符串
#ifndef NO_QSTR
#define QDEF0(id, hash, len, str)
#define QDEF1(id, hash, len, str) str,
#include "genhdr/qstrdefs.generated.h"
#undef