Tasmota Berry 固件固化(Solidification)的预处理器宏转储机制:tasmota_defines_for_berry.h 的设计与消费链路
Tasmota Berry 固件固化Solidification的预处理器宏转储机制tasmota_defines_for_berry.h 的设计与消费链路【免费下载链接】TasmotaAlternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at项目地址: https://gitcode.com/GitHub_Trending/ta/Tasmota导读Tasmota 的 Berry 脚本固件化solidification会在编译期把.be脚本编译为预构建的 C 结构体并直接嵌入固件而固化产物正确性的前提是Berry 侧看到的USE_*功能开关、D_*语言字符串常量必须与 C 编译器构建固件时看到的取值完全一致。tasmota/tasmota_defines_for_berry.h正是为此而生的构建期产物——它把配置头文件中的全部#define宏转储为扁平文本供 Berry 固化工具有条件地固化类/模块、折叠字符串常量。读完本文你将掌握这套宏转储机制的产生过程、输出内容结构以及它在 Berry 固化工具链中的完整消费方式。一、为什么需要这份宏转储文件1.1 Berry solidification 是什么Berry solidification 将.be脚本编译为预构建的 C 结构体直接嵌入固件。固化工序在构建期于宿主机上运行通过berry_portBerry VM 的 Python 重新实现执行。仓库中lib/libesp32/berry_tasmota/solidify_all_python.be、lib/libesp32/berry_matter/solidify_all_python.be等固化脚本即是这一环节的入口。1.2 一致性问题两个编译器的视角必须对齐固化代码要保证正确就必须知道哪些 Tasmota 功能被编译进了固件。例如一个被固化的类若引用了USE_MATTER_DEVICE或某个D_JSON_*字符串常量就必须看到与 C 编译器相同的取值。否则固化字节码可能嵌入错误的常量或包含死代码路径。简单说固化器运行在宿主机 Python 环境而固件由交叉编译器构建两者之间需要一个共享的事实源——这就是tasmota_defines_for_berry.h的角色。二、转储文件是如何产生的2.1 构建管线中的位置pio-tools/dump-defines.py在 PlatformIO 构建中作为post-script运行注册于 platformio_tasmota32.ini位于gen-berry-defines.py与gen-berry-structures.py之前。整个 ESP32 构建管线中与 Berry 固化相关的脚本顺序为post:pio-tools/dump-defines.py # 第 1 步转储宏到 .h post:pio-tools/gen-berry-defines.py # 第 2 步.h 转成 Berry 可导入的 .be post:pio-tools/gen-berry-structures.py # 第 3 步运行固化 coc 生成预编译结构 post:pio-tools/post_esp32.py2.2 核心命令脚本在宿主机上以宏转储模式调用 C 预处理器xtensa-esp32-elf-g -E -dM -x c -DESP32 build_flags -D entries -I include/ -I tasmota/include/ -I tasmota/ -include tasmota/include/tasmota.h -include tasmota/my_user_config.h -include include/tasmota_options.h -include tasmota/include/i18n.h - /dev/null tasmota/tasmota_defines_for_berry.h在 dump-defines.py 中该命令被组装为cmd [cxx, -E, -dM, -x, c] cmd define_flags # 从 BUILD_FLAGS 提取的 -D 条目 cmd include_flags # -I include/ -I tasmota/include/ -I tasmota/ stub for header in forced_includes: cmd [-include, str(header)] cmd.append(-) # 读取空 stdin2.3 关键设计决策决策原因使用 post-scriptpost:$CXX在平台构建器运行后才会指向真正的交叉编译器无需-m32hack使用交叉编译器$CXX保证 int/指针宽度、字节序以及 ESP32 目标专属的内建宏都正确-E -dM仅预处理模式输出展开所有头文件后可见的每一个#define只包含配置/i18n 头文件不包含tasmota.inotasmota.ino会引入 Arduino/框架库头文件EEPROM.h、WiFiHelper.h等在 PlatformIO 的 LDF 运行之前无法解析这些库也不贡献固化器需要的宏空sdkconfig.h桩tasmota_configurations_ESP32.h会#include每个 MCU 构建期才生成的sdkconfig.h其CONFIG_*值对 Berry 固化无用故提供空桩文件屏蔽见 dump-defines.py透传BUILD_FLAGS中的-D标志保证USE_CONFIG_OVERRIDE、MY_LANGUAGE、固件变体标志等与实际构建完全一致2.4 产出物与 gitignore输出写入tasmota/tasmota_defines_for_berry.h该文件在 .gitignore 中被忽略连同后续生成的tasmota_defines_for_berry.be一起——它是构建产物每次构建都会重新生成。三、输出内容长什么样该文件是gcc -dM格式的扁平#define行列表。一个典型的tasmota32构建大约生成3 200 行大致分布如下类别数量示例USE_*功能开关约 220#define USE_BERRYD_*字符串JSON 键、命令、传感器名约 2 000#define D_JSON_TEMPERATURE Temperature固件元数据少量#define CODE_IMAGE_STR tasmota32语言/区域少量#define LANGUAGE_LCID 2057编译器内建宏等其余#define __INT_MAX__ 2147483647代表性样例/* Feature flags */ #define USE_BERRY #define USE_MATTER_DEVICE #define USE_RULES #define USE_TLS #define USE_WEBSERVER #define USE_IPV6 1 #define USE_ZIGBEE_ZNP /* Language / locale */ #define LANGUAGE_LCID 2057 /* en_GB */ #define CODE_IMAGE_STR tasmota32 /* JSON key strings */ #define D_JSON_TEMPERATURE Temperature #define D_JSON_TEMPERATURE_UNIT TempUnit /* Command strings */ #define D_CMND_STATUS Status /* Sensor name strings */ #define D_SENSOR_SWITCH Switch未定义的标志不会出现在文件中。例如如果my_user_config.h中注释掉了USE_ZIGBEE总开关文件中就不会有#define USE_ZIGBEE行——只剩那些无条件声明的子配置默认常量USE_ZIGBEE_ZNP、USE_ZIGBEE_CHANNEL等。四、固化器如何消费这份文件4.1 两步转换.h → .be → 固化脚本导入宏转储文件不能直接被 Berry 固化器读取先由pio-tools/gen-berry-defines.py解析并转换为 Berry 脚本tasmota/tasmota_defines_for_berry.be。该脚本支持的转换规则其余一律降级为注释#define NAME → preproc.define(NAME) #define NAME true/false → preproc.define(NAME, true/false) #define NAME string → preproc.define(NAME, string) #define NAME 123 → preproc.define(NAME, 123) #define NAME 0x1A → preproc.define(NAME, 0x1A) #define NAME -42 → preproc.define(NAME, -42)被忽略的类型包括以__开头的编译器内建宏以及值为表达式、标识符、浮点数等的宏。生成的.be文件以import preproc开头随后逐行调用preproc.define(...)。随后各固化脚本导入该.be文件。以 berry_tasmota 固化脚本 为例import ../../../tasmota/tasmota_defines_for_berry.be as tasmota_defines固化器gen-berry-structures.py以python3 -m berry_port -s -g solidify_all_python.be方式驱动据此获得与固件完全一致的宏视图。4.2 固化的两大核心用途条件固化Conditional solidification——只有当对应的USE_*标志存在时某个.be类或模块才会被固化。例如berry_matter的类只在USE_MATTER_DEVICE存在时固化避免把未被编译进固件的功能代码写入产物。常量折叠Constant folding——D_JSON_*与D_CMND_*字符串常量可以直接嵌入固化字节码而不必在运行时查询语言文件既减小固件体积又省去运行时开销。4.3 coc 阶段的直接引用值得注意的是gen-berry-structures.py最后一步调用coc编译器生成预编译 Berry 结构体时将.h文件直接作为编译输入传入见 gen-berry-structures.py 中的-c ... tasmota/tasmota_defines_for_berry.h参数与default/berry_conf.h一起参与 C 结构体的生成进一步印证了该文件在整个固化链中的事实源地位。4.4 固化缓存与失效由于固化过程较慢gen-berry-structures.py为每个模块维护两级缓存存放于.pio/build/env/berry_solidify_cache/快速路径比较每个输入文件的st_mtime_ns全部一致且输出.h存在则跳过固化慢速路径mtime 不一致时如git checkout后回退到 MD5 内容哈希比较内容未变则更新缓存 mtime下次构建恢复快速路径。tasmota/tasmota_defines_for_berry.be是各模块固化脚本共享的依赖文件会被一并纳入缓存输入集合与哈希校验——这意味着改动my_user_config.h或user_config_override.h导致宏变化时tasmota_defines_for_berry.h重新生成、mtime 变化从而自动触发各模块的重新固化。4.5 跳过固化当迭代 C/C 代码而无需触碰 Berry 源码、或构建环境没有python3时可在build_flags中加入-DDISABLE_BERRY_SOLIDIFY来跳过整个固化工序见 gen-berry-structures.py。五、构建期完整数据流小结my_user_config.h / user_config_override.h / tasmota_options.h / i18n.h BUILD_FLAGS │ 每次 ESP32 构建开始时 ▼ dump-defines.pypost-script$CXX 交叉编译器 │ -E -dM -x c 强制 include sdkconfig.h 空桩 ▼ tasmota/tasmota_defines_for_berry.h gitignored约 3 200 行 │ ▼ gen-berry-defines.py ▼ tasmota/tasmota_defines_for_berry.be preproc.define(...) 序列 │ ├──► 各 solidify_all_python.be 导入条件固化 / 常量折叠 └──► gen-berry-structures.py → coc.h 直接作为 -c 输入→ src/solidify/*.h 嵌入固件因为该文件在每个 esp32 构建开始时重新生成它始终反映当前的user_config_override.h与platformio_override.ini设置——这正是其作为固化事实源可靠性的根本保证。六、相关仓库资源导航宏转储实现pio-tools/dump-defines.py宏转换脚本pio-tools/gen-berry-defines.py固化与缓存管理pio-tools/gen-berry-structures.py构建注册platformio_tasmota32.ini固化脚本示例lib/libesp32/berry_tasmota/solidify_all_python.be、lib/libesp32/berry_matter/solidify_all_python.be、lib/libesp32_lvgl/lv_binding_berry/solidify_all_python.be配置源头tasmota/my_user_config.h、include/tasmota_options.h、tasmota/include/i18n.h、tasmota/user_config_override_sample.hgitignore 规则.gitignore实践提示若你在自定义固件中新增USE_*开关或修改MY_LANGUAGE无需手动同步任何 Berry 固化输入——下次构建时dump-defines.py会自动重新生成宏转储固化链随即自适应但请记得该.h/.be均为构建产物不要手工编辑或提交到版本库。【免费下载链接】TasmotaAlternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at项目地址: https://gitcode.com/GitHub_Trending/ta/Tasmota创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

基于鲁棒优化的应急电源配置与调度系统实现

基于鲁棒优化的应急电源配置与调度系统实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/24 14:46:48 阅读更多 →
硬分叉运维实战:Web3节点升级的共识同步与全流程指南

硬分叉运维实战:Web3节点升级的共识同步与全流程指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 16:01:38 阅读更多 →
9款高效降AI率工具评测与学术写作优化指南

9款高效降AI率工具评测与学术写作优化指南

1. 项目背景与核心需求作为专科院校的学生,在学术写作和日常作业中经常面临一个严峻挑战——如何有效降低AI生成内容的检测率。随着各类AI检测工具(如Turnitin、Grammarly、Copyleaks等)的普及,直接使用AI辅助生成的内容容易被识别…

2026/10/23 18:45:54 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/25 11:19:54 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/24 17:47:00 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/24 18:34:36 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/25 10:02:42 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/25 3:12:30 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/24 21:09:59 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 10:02:43 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 13:21:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 7:47:32 阅读更多 →