首先,我特别单独把 F042F4 拎出来的目的是这颗芯片放不下 HAL,而如果你想用 ST 的 USB 库又非得用 HAL 不可(Cube 没有 LL USB 库)这个困局不应该存在的。
然后您觉得 HAL 已经可以跨平台了。我想说的是请您放眼一下别的厂家,您就知道 ST 的 HAL 有多么平台局限了。RTE 可以跨厂家,但是如果我想在 ST 的芯片上用 RTE 就得用 HAL(又是一个不能用 LL 的)然后代码臃肿的问题就又回来了。这也是为什么我会提到别家的芯片内置的 ROM:别家芯片的 RTE 只依赖这个 ROM。换句话说,如果我用 NXP LPC 或 TI LM3S/MSP432 的芯片我至少不用为了硬件库预留代码空间;但是 ST 的芯片上我需要为底层硬件库预留空间,这里就是为什么我需要考虑这个库的文件体积,进而抱怨 HAL 臃肿了
您试试看从 STM32 跨到别的厂家的单片机,您就知道 HAL 的抽象度为什么不够了。横向比较一下 ST HAL、TI StellarisWare、ASF、MPLAB Harmony、LPC Xpresso 你会发现这些东西全都是渣渣,反而是 Keil RTE 还像点样子。
STD 和 HAL 不是 ARM 的,这两个是 ST 的。ST 的商业先传团队值得好好奖励一下,因为他们成功的把很多人都套到 Keil+HAL 的圈子里面不能自拔了,想办法套个商业模式你就成功了。
ARM 的是 CMSIS-RTE,好像反而没多少人用哦?
如果你把 MCU 分割成功能模块,每一个模块还是那点复杂度,上世纪 70 年代如此,现在还是如此。如果每一个功能模块都对应一个独立的驱动程序,复杂 MCU 不过是多几个驱动程序,每个驱动程序有三四个实例罢了。这东西要各个击破啊。
楼主,如果说到横向比较,那么你是否知道基于HAL库上有个叫mbedTLS的东东?你想写个代码所有MCU都支持,干嘛还使用寄存器啊?直接使用mbed啊。恕我多嘴,恰好HAL+mbedTLS就可以实现。
mbedTLS 不是拿来干这个的,RTFM!你说的是 RTE,但就算是 RTE 是我也不用:太庞大了。你试试看 STM32F042F4P6 上 RTE,能塞得进去算你牛。
楼主你这么说就有点极端了,MCU的性能与库的抽象度是两个相对的因子,那那个M0的MCU来弄个RTM算什么事,这个除ST外的其他MCU也不能把,对于M0核的MCU,HAL有点勉强,SPL相对OK,最适合的当属LL库。M0使用HAL不是不行,而是合不合适的问题。RTM也类似,所以楼主的这个假设算是极端了。之所以和楼主讨论这么多,原本就是看到楼主各种说HAL的不便效率方面低下而推荐寄存器操作方式方式,殊不知LL库的推出正式解决这种问题,后来楼主又说HAL抽象度不够,殊不知基于HAL之上的各种中间件实现APP与底层的完全分离,甚至跨平台,到最后又回到CPU本身处理性能与之匹配的库所产生的效率问题上。这种拿低性能处理器搭配重量级的软件的假设本身就没有可取之处。话题已经偏移最初的含义了,没有继续讨论的意义了。
我的库至少把硬件抽象到了某种标准接口上。我选用的接口定义是 POSIX 优先,Arduino 其次。你可以看看这几个文件,目标芯片是 STM32F103CBT6,芯片容量比较大,我就没有用简化驱动:
POSIX 设备驱动:http://github.com/SushiBits/LCDC ... system/src/device.c
串口驱动,继承 POSIX 设备:http://github.com/SushiBits/LCDC ... /system/src/usart.c
HD44780 驱动,继承 POSIX 设备:http://github.com/SushiBits/LCDC ... ob/master/src/lcd.c
POSIX 时钟驱动:http://github.com/SushiBits/LCDC ... r/system/src/time.c
应用程序:http://github.com/SushiBits/LCDC ... b/master/src/main.c
你真的认为库固定放在ROM内好?你认为所有人都认可吗?你有没有考虑过一旦出现问题的可追索性?库方式至少还是开源的。至于空间,放ROM真的就好吗?ST真的就只是仅仅不远多提供一个可以存放库的ROM吗?这种方式与提供库的方式有什么本质区别吗?仅仅只是不占空间?
首先,我特别单独把 F042F4 拎出来的目的是这颗芯片放不下 HAL,而如果你想用 ST 的 USB 库又非得用 HAL 不可(Cube 没有 LL USB 库)这个困局不应该存在的。
然后您觉得 HAL 已经可以跨平台了。我想说的是请您放眼一下别的厂家,您就知道 ST 的 HAL 有多么平台局限了。RTE 可以跨厂家,但是如果我想在 ST 的芯片上用 RTE 就得用 HAL(又是一个不能用 LL 的)然后代码臃肿的问题就又回来了。这也是为什么我会提到别家的芯片内置的 ROM:别家芯片的 RTE 只依赖这个 ROM。换句话说,如果我用 NXP LPC 或 TI LM3S/MSP432 的芯片我至少不用为了硬件库预留代码空间;但是 ST 的芯片上我需要为底层硬件库预留空间,这里就是为什么我需要考虑这个库的文件体积,进而抱怨 HAL 臃肿了
ROM 固化的库不占代码空间,至少 NXP、TI 和 Infinieon 都在用。如果库有问题,芯片 ID 中会反映出芯片库版本,软件里面带上一个替换的函数和指针补丁就可以了。(这个时候我也只是带了一个替换函数,而不是整个库。)
总算看出楼主写这个贴子的出发点了,F042F4/6,16K/32K FLASH,内置USB专用晶振,这么点空间的FLASH放整个HAL当然不可能了,如果对HAL进行配置,比如只保留HAL的USB部分,其他一概不要,或者其只需要使用到外设的LL部分,或者干脆自己使用寄存器方式。这样应该是可以的。看楼主的应用的复杂度,如果只是需要USB做些简单功能比如鼠标之类的,F042是可以实现的,大不了使用SPL或者自己使用寄存器了。如果单从技术角度出发的话,更复杂的应用,楼主是应该考虑换成F072了,毕竟042的价格定位如此,楼主说这么多,最希望的是继续F042的价格,但需要F072的FLASH大小吧
LightSwitchUSB 项目,同样的 GCC 工具链,只用 HAL USB 空白固件 -Os 优化等级都要 13kB。我现在完全不用 HAL,第三方无依赖 USB 库 + 手写其他所有驱动,整个东西加上业务逻辑不开优化都只有 9kB。这个数字是死的,你要辩驳就没有意义了。
在 042 上可以不用 HAL 解决问题,这些在 042 上写的驱动我也可以移植到 072/103/303/407 上照用不误。(其实定时、GPIO 复用这两个驱动我是从 303 上移植过来的。)这么看来,HAL 是不是就没有普适性了?我是花时间学会 HAL 然后看见 042 再回头去学习直接操作寄存器,还是一上来就直接用寄存器然后走遍四方都不怕?
再说一句,如果你的产品销量很大的话,用一颗便宜的单片机在产品的整个生命周期里面所节省的成本可远远多于几个工程师三天的工资。同样情况下,能用 042 我就不考虑 072 了。当年雅达利开发街机游戏《Breakout》的时候开给沃兹的奖金其实是很有道理的:现在少许多花一点研发成本,将来批量出货的时候省大钱。