首页/新闻资讯/正文详情

STM32DUINO V3.0 Core API 升级可能造成的问题及对策

发布时间:2026/11/5 23:43:12 来源:云帆数科 栏目:资讯中心
STM32DUINO V3.0 Core API 升级可能造成的问题及对策
Arduino 官方发布了一套通用API 框架希望减少差异一统各硬件平台比如AVRSTM32。官方repo 链接arduino/ArduinoCore-API。stm32duino 在V2.12 版本后发布了V3.0全面迁移到了这套Core API但是目前我的建议是先不要跟着升级尤其是用V2 版本的老项目至少也需要仔细测试评估过再说。原因存在一批可能导致不兼容的API 变更有用户报告说编译后程序体积变大了4.8kB(15.3%)导致Flash 里塞不下串口和SPI 类全面虚函数化对运行时性能可能有少量影响V3.0.0 版本迁移没处理干净留下了一些BUG而V3.0.1 版本尚未发布这次升级并没有带来明显的功能性收益升级收益新增STM32C5xx 系列硬件支持并引入C5xx 系列的HALv2 库变更和问题1、引入Arduino Core APIstm32duino 自己fork 了一份core api而不是直接引入arduino 官方的东西链接在stm32duino/ArduinoCore-API。理论上迁移到core api 以后能提高用户程序的可移植性和库的通用性但是我觉得收益很小因为不通用的部分主要是真实的硬件架构和外设差异这些东西不太可能完美的靠api 层覆盖。比方说怎么在没有DMA 的硬件上使用DMA现有各arduino 平台在通用性上已经做的差不多了。2、外设抽象类这是最显著的变化core api 里定义了几个外设抽象类HardwareSerialHardwareSPIHardwareI2C2.1、HardwareSerial其中HardwareSerial顶掉了旧的串口实现类的名字于是以后Serial对象的类型要变更为Uart。旧的v2 版程序里的对象定义都要改// v2HardwareSerialSerial1(PA9,PA10);HardwareSerialSerial3(PB11,PB10,NC,NC);// v3UartSerial1(PA9,PA10);UartSerial3(PB11,PB10,NC,NC);因为Uart继承了HardwareSerial所以旧代码里接收HardwareSerial对象指针或引用的部分不用改比如voidwait_for_serial(HardwareSerials){while(s.available()0){yield();}}理论上旧代码要改的应该也不多Uart类的接口和旧的HardwareSerial完全兼容但是我觉得更好的做法应该是用HardwareUART作为抽象基类留着HardwareSerial保持兼容。实际上我对这整套抽象基类的设计都很不喜欢太土味OOP 了徒增虚函数开销只实现了约束接口的作用不如用concept。2.2 HardwareSPI传统的Arduino SPI 是个仅作为SPI 主机侧使用的接口内部实现非常简单用软件轮询驱动通讯。现在SPIClass成为了HardwareSPI的实现类接口变成虚函数还增加了SPI 从机侧和硬件中断接口。下面是抽象类定义classHardwareSPI{public:virtual~HardwareSPI(){}virtualuint8_ttransfer(uint8_tdata)0;virtualuint16_ttransfer16(uint16_tdata)0;virtualvoidtransfer(void*buf,size_t count)0;// Transaction FunctionsvirtualvoidusingInterrupt(intinterruptNumber)0;virtualvoidnotUsingInterrupt(intinterruptNumber)0;virtualvoidbeginTransaction(SPISettings settings)0;virtualvoidendTransaction(void)0;// SPI Configuration methodsvirtualvoidattachInterrupt()0;virtualvoiddetachInterrupt()0;virtualvoidbegin()0;virtualvoidend()0;};旧的setter 彻底删掉了现在只能经过beginTransaction传入SPI 硬件配置。SPISettings类也被标准化成单纯的配置参数容器而AVR 平台上SPISettings的旧实现是内置了配置参数到寄存器值的转换不存储原始配置参数不提供getter只缓存了寄存器值用于快速复用配置。不知道新的core api 要怎么处理这个行为冲突。毕竟AVR 平台是arduino 生态的老家不太可能放着不管。classSPISettings{public:constexprSPISettings(uint32_tclock,BitOrder bitOrder,SPIMode dataMode,SPIBusMode busModeSPI_CONTROLLER):clockFreq(clock),dataMode(dataMode),bitOrder(bitOrder),busMode(busMode){}constexprSPISettings(uint32_tclock,BitOrder bitOrder,intdataMode,SPIBusMode busModeSPI_CONTROLLER):clockFreq(clock),dataMode((SPIMode)dataMode),bitOrder(bitOrder),busMode(busMode){}// Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.constexprSPISettings():clockFreq(4000000),dataMode(SPI_MODE0),bitOrder(MSBFIRST),busMode(SPI_CONTROLLER){}booloperator(constSPISettingsrhs)const;booloperator!(constSPISettingsrhs)const;uint32_tgetClockFreq()const;SPIModegetDataMode()const;BitOrdergetBitOrder()const;SPIBusModegetBusMode()const;private:uint32_tclockFreq;SPIMode dataMode;BitOrder bitOrder;SPIBusMode busMode;friendclassHardwareSPI;};另外一个问题是枚举命名变更SPI 设备模式枚举的名字把MASTER改成了CONTROLLERSLAVE改成了PERIPHERAL// V2// Device modetypedefenum{SPI_MASTER,/* Device is master */SPI_SLAVE/* Device is slave */}SPIDeviceMode;// V3// Platforms should define SPI_HAS_PERIPHERAL_MODE if SPI peripheral// mode is supported, to allow applications to check whether peripheral// mode is available or not.typedefenum{SPI_CONTROLLER0,SPI_PERIPHERAL1,}SPIBusMode;这个问题不大SPI 库一直都是默认以主模式运行根本不支持从模式上面V3 的注释也说了硬件平台可以自己决定要不要支持从模式如果支持就定义宏SPI_HAS_PERIPHERAL_MODE应用代码应该检查这个标志。政治正确的问题没什么好说的。与这个改名同步Arduino 现在也在倡议把信号线名称MISO改成CIPO, 也就是从MasterInSlaveOut 改为*C**ontrollerInPeripheralOut。MOSISS 也一样。另一种说法是把MOSI 改成SDO (SerialDataOut)MISO 改成SDI (SerialDataIn)省略主从关系默认以主设备为中心看数据流向。怎么感觉这样改反而是完全剥夺了从设备的权益[doge]。2.3、HardwareI2C和SPI 库一样core api 提供了硬件I2C 抽象类Wire 或TwoWire 现在要继承它并实现那些虚函数。不过Wire 库本身就比较庞大多一层虚函数影响比SPI 库更小。下面是抽象类定义classHardwareI2C:publicStream{public:virtualvoidbegin()0;virtualvoidbegin(uint8_taddress)0;virtualvoidend()0;virtualvoidsetClock(uint32_tfreq)0;virtualvoidbeginTransmission(uint8_taddress)0;virtualuint8_tendTransmission(boolstopBit)0;virtualuint8_tendTransmission(void)0;virtualsize_trequestFrom(uint8_taddress,size_t len,boolstopBit)0;virtualsize_trequestFrom(uint8_taddress,size_t len)0;virtualvoidonReceive(void(*)(int))0;virtualvoidonRequest(void(*)(void))0;};I2C 还保留了setClock接口而不是要求在beginTrasmission时传入配置参数emmm有点恶心。另外注意Wire 库里begin函数有多个重载voidbegin(uint8_t,boolgeneralCallfalse,boolNoStretchModefalse);voidbegin(int,boolgeneralCallfalse,boolNoStretchModefalse);voidbegin()override{begin(false);}voidbegin(uint8_taddress)override{begin(address,false,false);}其中从core api 继承的begin(uint8_t)可能和begin(uint8_t, bool, bool)冲突因为后者的两个bool 参数都有默认值。而如果传入的地址是字面量整数就ok因为整数字面量默认类型是int会优先匹配到begin(int, bool, bool)这个重载。uint8_taddr0x3c;begin(addr);// 出错同时匹配到两个重载begin(0x3c);// 没问题至于有这个int重载的原因是为了兼容I2C 标准里的11bit 扩展地址用uint8_t只能传入一般的7bit 地址。显然arduino 官方的core api 设计没考虑到这个问题。3、变更的枚举和常量值引脚模式枚举里面OUTPUT_OPEN_DRAIN和INPUT_ANALOG的值互换了代码里没直接使用整数值的话不影响。// V2#defineINPUT0x0#defineOUTPUT0x1#defineINPUT_PULLUP0x2#defineINPUT_PULLDOWN0x3#defineINPUT_ANALOG0x4#defineOUTPUT_OPEN_DRAIN0x5// V3typedefenum{INPUT0x0,OUTPUT0x1,INPUT_PULLUP0x2,INPUT_FLOATINGINPUT,/* 0x0 */INPUT_PULLDOWN0x3,OUTPUT_OPENDRAIN0x4,/* ← 2.12 是 0x5 */OUTPUT_OPEN_DRAINOUTPUT_OPENDRAIN,INPUT_ANALOG0x5,/* ← 2.12 是 0x4 */}PinMode;串口模式从uint8_t类型变成了uint16_t数值也发生变化。旧代码里没直接写数值就没太大影响不过如果旧代码里把配置常量用uint8_t存储过不改代码的话就装不下新的uint16_t常量了。// V2// Define config for Serial.begin(baud, config);// below configs are not supported by STM32//#define SERIAL_5N1 0x00//#define SERIAL_5N2 0x08// ...//#define SERIAL_6N2 0x0A#defineSERIAL_8N10x06#defineSERIAL_8N20x0E// ...#defineSERIAL_8O20x3E// V3#defineSERIAL_5N1(SERIAL_STOP_BIT_1|SERIAL_PARITY_NONE|SERIAL_DATA_5)#defineSERIAL_6N1(SERIAL_STOP_BIT_1|SERIAL_PARITY_NONE|SERIAL_DATA_6)// ...#defineSERIAL_8S2(SERIAL_STOP_BIT_2|SERIAL_PARITY_SPACE|SERIAL_DATA_8)4、浮点转字符串打印性能退化V2 版本Print.h里提供的printFloat是个函数模板templateclassTsize_tprintFloat(T,uint8_t){/* .. */}如果程序里只需要打印单精度浮点float模板就只会实例化成一份printfFloat(float, uint8_t)但是如果一份固件里同时用了打印float和double就只能再多实例化一份双精度版本printFloat(double, uint8_t)两个版本并存显然这样会导致代码体积膨胀。可能是出于这种考虑V3 版本没有这个模板只提供一份双精度版实现哪怕只用单精度浮点float也要转换成double再打印。这样最大的问题是在STM32F4 之类有单精度硬件浮点单元FPU 的芯片上旧的代码生成的单精度版本可以用硬件浮点处理速度更快代码体积更小如果强行用双精度那就只能像没有FPU 一样用软件处理浮点导致性能退化。至于M0 系列的芯片本来就没有硬件FPU旧代码可能会分别实例化出一份单精度和双精度的实现导致体积膨胀所以换成用V3 以后可能会省一点空间。最佳方案可能是编译时检测目标芯片是否配置了FPU然后再决定要不要提供一份有硬件加速的单精度实现。5、String 类从双精度浮点double 构造时要吃掉大量栈空间String(float/double)构造函数里的临时缓冲从固定char buf[33]改成了按FLT/DBL_MAX_10_EXP算出来的大小(api/String.h:61-62定义FLT_MAX_DECIMAL_PLACES 10、DBL_MAX_DECIMAL_PLACES 10):// String.cppString::String(doublevalue,unsignedchardecimalPlaces){staticsize_tconstDOUBLE_BUF_SIZEDBL_MAX_10_EXPDBL_MAX_DECIMAL_PLACES111;// 308 10 3 321charbuf[DOUBLE_BUF_SIZE];// 2.12 这里是 char buf[33];...}所以输入double时缓冲区尺寸从33 字节膨胀到了321 字节这还是挺可观的尤其是对那些内存只有2K、4K 的M0 芯片而言。不过String里与浮点转换有关的函数用了两种实现第一种就是这个构造函数另外还有String::concat(double)这个函数把double转换成字符串并拼接到已有的String对象后面它的缓冲区没膨胀。所以doubled3.14;String s{d};// 一下吃掉321 字节缓冲区空间String ss;ssd;// 调用concat 拼接正常对策PlatformIO 锁定库版本可以在platformio.ini锁定库版本到V2.12如下[env:app] platform platformio/ststm3219.7.1 ; platform 版本也要锁 platform_packages platformio/framework-arduinoststm324.21200.0 ; 锁定stm32duino 框架版本 ; 还有这两个库最新版会检测stm32duino 框架版本V3 以下不能编译所以也要锁定到V3 之前的版本 lib_deps stm32duino/STM32duino Low Power 1.5.0 stm32duino/STM32duino RTC 1.9.0总结可以看出来官方这套core api 还相当不成熟官方源码里还留着一堆TODO 和问号比如在HardwareSerial.h里 名为XXX 的某人问道// XXX: Those constants should be defined as const int / enums?// XXX: shall we use namespaces too?#defineSERIAL_PARITY_EVEN(0x1ul)#defineSERIAL_PARITY_ODD(0x2ul)#defineSERIAL_PARITY_NONE(0x3ul)#defineSERIAL_PARITY_MARK(0x4ul)你问我我问谁。总之这套core api 并没有增加什么功能收益我只看到了一堆兼容性隐患和草率的设计决策。而且官方repo 里攒了99 个issue但是上一次提交更新已经是去年的事了。前途堪忧怕不是已经死了。所以还是那句话目前不推荐使用V3 版stm32duino除非st 接手core api 然后积极更新但那也要看他们什么时候能发V3.0.1没准直接反悔回退了。

相关推荐

AI新手必看:Prompt、Skills、MCP、Workflow、Agent核心概念解析
AI新手必看:Prompt、Skills、MCP、Workflow、Agent核心概念解析

学习AI如同掌握一门新语言,Prompt、Agent、MCP、Skills、Workflow等概念繁多且易混淆。本文通过建立关系表,清晰解析了每个概念的核心作用与重点,帮助读者理解任务表达、能力封装、系统连接和执行组织等关键方面,为深入AI学习打下… · 2026/11/4 18:42:11

helm项目管理
helm项目管理

一、部署与helm基本操作1.源码二进制方式安装 Helm 配置 bash 命令补全[rootmaster ~]# wget https://get.helm.sh/helm-v4.1.3-linux-amd64.tar.gz #下载 Helm 二进制压缩包(Helm 是 K8s 包管理器) [rootmaster … · 2026/11/3 12:01:00

智慧地铁大屏 · 19 个组件完整操作手册
智慧地铁大屏 · 19 个组件完整操作手册

所以下面每个组件都要新建一个 SQL 数据集,不是一个数据集做所有图。1. 通用套路(19 个组件都照这个做)1.1 第 1 步:建 SQL 数据集公共数据 → 智能地铁数据 → 【新建数据集】 → 选「SQL 数据集」↓ 数据连接:… · 2026/11/3 13:54:14

EasyU优启通PE维护盘实战指南:制作、启动与核心操作全解析
EasyU优启通PE维护盘实战指南:制作、启动与核心操作全解析

1. 为什么一个PE维护盘值得单独拿出来聊装系统、修引导、救数据、清病毒,这些活儿但凡干过几次的人都知道,真正决定效率的往往不是你手速多快,而是手边那套PE环境靠不靠谱。EasyU(圈内习惯叫优启通)就是在这个场景下被… · 2026/11/5 16:49:35

Rust原来很简单二:所有权系统
Rust原来很简单二:所有权系统

Part 2 核心篇 —— 所有权系统 本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理 6… · 2026/11/5 16:26:08

基于Hadoop+Spark的民宿智能推荐系统设计与实现
基于Hadoop+Spark的民宿智能推荐系统设计与实现

1. 项目概述:大数据时代的民宿智能推荐这个毕业设计项目融合了当前大数据领域最主流的技术栈,构建了一个完整的民宿推荐系统解决方案。作为一名长期从事大数据系统开发的工程师,我认为这个选题非常贴合实际应用场景——随着旅游业的复苏和共享… · 2026/11/5 14:59:25

ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计
ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计

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

UART接口24位ADC搭配RS485,解决远距离温度监控难题
UART接口24位ADC搭配RS485,解决远距离温度监控难题

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

UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践
UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践

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

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

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

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

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

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

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

多智能体协作系统架构设计与实践优化
多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39

大模型系统性入门实战指南:从原理到部署微调的全链路路线
大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39

鸿蒙文件系统沙箱机制解析与开发实践
鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

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

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

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

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码