Arduino 库开发者如何用 ESP_ARDUINO_VERSION 宏兼容 arduino-esp32 2.x 与 3.x?

📅 发布时间:2026/9/14 7:36:54
Arduino 库开发者如何用 ESP_ARDUINO_VERSION 宏兼容 arduino-esp32 2.x 与 3.x?
Arduino 库开发者如何用 ESP_ARDUINO_VERSION 宏兼容 arduino-esp32 2.x 与 3.x【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32如果你的 Arduino 库需要同时跑在 arduino-esp32 2.x 和 3.x 两个大版本上直接调用某一版 API 就会在另一版编译失败——两个大版本基于不同的 ESP-IDF2.x 基于 ESP-IDF 4.43.0 基于 ESP-IDF 5.1LEDC、I2S、RMT、BLE 等模块都有破坏性改动。官方给出的做法是在库源码里用ESP_ARDUINO_VERSION宏做条件编译把两个版本的代码分支隔离开。本文基于仓库中的兼容指南、版本头文件和迁移指南给出从写条件编译、到运行时验证版本、再到可选把库挂进 CI 编译测试的完整路径。版本宏从哪里来这些宏定义在 esp_arduino_version.h 中随 core 源码一起编译进工程库代码无需额外包含宏含义ESP_ARDUINO_VERSION_MAJOR/MINOR/PATCH大版本、次版本、补丁号当前仓库中的值为 3、3、11ESP_ARDUINO_VERSION_VAL(major, minor, patch)把三位版本号打包成整数规则为((major 16) \| (minor 8) \| (patch))专门用于、这类比较ESP_ARDUINO_VERSION当前 core 版本对应的整数等价于ESP_ARDUINO_VERSION_VAL(ESP_ARDUINO_VERSION_MAJOR, ESP_ARDUINO_VERSION_MINOR, ESP_ARDUINO_VERSION_PATCH)ESP_ARDUINO_VERSION_STR当前 core 版本的字符串形式供打印用1.x 的 core 没有这组宏所以条件编译的第一层判断是“宏是否存在”而不是直接比较版本号。写 2.x / 3.x 双兼容的条件编译官方兼容指南给出的标准写法如下外层#ifdef把 1.x 挡在外面内层比较区分 3.x 与 2.x#ifdef ESP_ARDUINO_VERSION_MAJOR #if ESP_ARDUINO_VERSION ESP_ARDUINO_VERSION_VAL(3, 0, 0) // Code for version 3.x #else // Code for version 2.x #endif #else // Code for version 1.x #endif判断逻辑是ESP_ARDUINO_VERSION_MAJOR未定义说明是 1.x两个大版本都覆盖不到时走最后一个分支已定义则把ESP_ARDUINO_VERSION与打包后的整数3.0.0比较命中哪个分支就编入哪一版的实现。库内部所有在两个大版本间有差异的调用点都套在这层结构里。哪些 API 必须分支处理具体要分支的调用点以 2.x 到 3.0 迁移指南中列出的破坏性变更为准常用的有模块3.x 的变化库代码需要分支的点LEDCledcSetup、ledcAttachPin移除新增ledcAttach合并了前两者的功能ledcDetachPin改名为ledcDetach所有函数的channel参数改为pin3.x 分支用ledcAttach2.x 分支用ledcSetupledcAttachPinRMT所有函数的rmt_obj_t* rmt参数改为int pinrmtEnd、rmtReadData等移除新增rmtSetEOT、rmtWriteAsync等传参类型和函数集合都要分版本写BLE返回值和参数类型从std::string改为StringUUID 数据类型从uint16_t改为BLEUUID类BLEScan::start与BLEScan::getResults返回类型改为BLEScanResults*涉及字符串、UUID、扫描结果取用的代码ADCanalogSetClockDiv、adcAttachPin、analogSetVRefPin移除调用了被移除函数的代码Hall 传感器3.x 不再支持hallRead移除相关功能整体降级或屏蔽构建系统3.x 中额外编译标志会覆盖默认标志C 和 C 的 extra flags 必须包含-MMD -c自定义编译标志的工程以 LEDC 为例把两个文档的结论组合起来一个库里的分支骨架是这样函数名来自迁移指南具体签名以仓库对应 API 文档为准#ifdef ESP_ARDUINO_VERSION_MAJOR #if ESP_ARDUINO_VERSION ESP_ARDUINO_VERSION_VAL(3, 0, 0) // 3.x使用 ledcAttach合并了 ledcSetup 与 ledcAttachPin // 原 channel 参数位置改为传 pin #else // 2.x使用 ledcSetup ledcAttachPin #endif #else // 1.x #endif迁移指南同时提醒3.0.0 已把全部官方示例更新为新 API3.0.0 之前的旧示例与 3.0.0 及之后的版本不兼容不要直接把旧示例当参考实现。更完整的 API 差异清单见 migration_guides。运行时验证实际生效的 core 版本编译分支是否正确最直接的验证是打印当前 core 版本。兼容指南给出的写法Serial.printf( ESP32 Arduino core version: %s\n, ESP_ARDUINO_VERSION_STR);输出的字符串应与当前安装的 core 版本号一致例如在 3.x 上打印出 3.x 的三段式版本号说明ESP_ARDUINO_VERSION比较走的是预期分支。仓库内也有现成用法可对照Esp.cpp 中EspClass::getCoreVersion()直接返回ESP_ARDUINO_VERSION_STR所以通过ESP.getCoreVersion()拿到的就是同一字符串ConsoleSysInfo 示例 的version命令也是用ESP_ARDUINO_VERSION_STR打印 core 版本。可选把库挂进 External Library Test CI 编译测试如果要持续验证“库在最新 core 上能否编译通过”可以把自己的库加入 arduino-esp32 的 External Library Test CI流程见 external_libraries_test.rst在仓库的 .github/workflows/lib.json 中按字母顺序添加一条记录。库来源二选一nameArduino Library Manager 中的库名或source-url未收录库的仓库地址exclude_targets不支持的 SoC 列表无则填空数组和sketch_path待编译的示例路径为必填version、required-libs、destination-name可选。文档中的示例文档示例按自己的库替换{ name: ArduinoBLE, exclude_targets: [ esp32s2 ], sketch_path: [ ~/Arduino/libraries/ArduinoBLE/examples/Central/Scan/Scan.ino ] }提交 PREspressif 团队会给 PR 加lib_test标签触发 CIPR 上的测试会先/后各编译一次全部库和示例结果按BEFORE - AFTER排列用于判断 PR 是否破坏或修复了某些库。PR 合并后每周一次的定时任务会对 master 分支再测一次结果写入LIBRARIES_TEST.md图标含义成功、有警告的成功、失败N/A表示该目标在exclude_targets中未测。定时结果文件的文档示例注意这条路径的边界该 CI 是对“最新 coremaster 分支”的编译测试验证的是库在 3.x 侧能否编译通过官方也明确说明“测试只是编译示例不代表库烧录到设备后能正常运行”2.x 侧的兼容仍需靠上面的条件编译和自行编译验证。限制与核对清单1.x 分支只由#ifdef ESP_ARDUINO_VERSION_MAJOR的存在性判断决定1.x 下不要直接使用ESP_ARDUINO_VERSION比较。条件编译只隔离编译问题两个大版本的 API 语义差异如 BLE 返回类型、RMT 传参仍要在各分支里各写各的实现。运行时打印ESP_ARDUINO_VERSION_STR只能确认“当前烧的是哪一版 core”不能替代在 2.x 和 3.x 两套 core 上各编译验证一次。需要查更多 API 差异时从 2.x_to_3.0 迁移指南入手总入口是 core_compatibility 指南。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考