rust嵌入式开发之总结
我们用rust开发的新版产品刚刚交付,已经在海上安装测试完毕并顺利投产。终于松了口气,同时也有时间和精力来做个全面的总结了。
这个产品,目前差不多有三版:
- 第一个版本是用c+rt-thread写的,投产后出了一个内存泄露的bug,由于我们的产品是安装到海上,bug修复了也很难更新到产品上,最后穷尽洪荒之力才找出对策进行了处置【不是排除】,但现在依然象个定时炸弹一样悬在那。导致我对c失去信心,最终下定决心换用rust
- 第二个是用rust写的demo版本,是基于RTIC框架写的。后因认为RTIC框架的限制比较大,在写完主体功能后就废弃了
- 第三个版本就是基于Embassy框架写的这一刚交付的版本
ps:海上的情况太过复杂,很多情况是我们现在的测试环境无法完全模拟的
本文即是基于笔者开发这三个版本的经验,对rust嵌入式的开发所做的一个阶段性的总结。
开发门槛高 vs 现场智能化
就嵌入式来说,rust+Embassy vs c+rt-thread的门槛是两个级别。
我是java和python的系统工程师,开发第一个版本时,就没用过c,也没开发过嵌入式!但花了一个月的时间,第一个版本就写完了。
开发第三个版本时,有了第一个版本的所有设备功能的开发经验,有第二个版本的rust尝试,但总的开发时间是从年后到5月下旬,合到三个月了。
当然,这里面主要的原因有两个:
1、rust在嵌入式方面的生态没有c这么成熟:有rt-thread这样的RTOS。虽然Embassy也比较成熟了,但它不是一个完整的RTOS,需要花大量的精力来开发一些较为底层的功能部件,如之前介绍过的数据锁:rust嵌入式开发之基于await构造应用级临界区。
当然,如果只是如多数嵌入式的应用场景那样的话,用RTIC框架完全可以:rust嵌入式开发之RTICvsEmbassy,那就简单很多了。但如我上面那篇文章所述,RTIC框架能力有限,起码对我司来说的是不够的:
- 我们需要连接大量各厂家的设备,串口之多以至于只能用10串口的STM32F403VG,每种设备的协作机制完全不同,所以就需要强大的异步协作能力,RTIC就没有提供异步支持
- 海上工程的特殊性,决定了我们必须提供多种的错误恢复手段,RTIC太弱
2、除了第一版中通常的现场操控能力之外,在新版中我还开发了额外的应用能力,如命令行,这相当于在做RTOS中的shell了,所以本质上还是rust嵌入式的生态还不够成熟的问题。
第一个版本是以在服务器上抄收到现场数据为完工标志,但海上施工非常困难,出海时一切正常,突然瓢泼大雨的再正常不过了,所以有必要提供现场的检查手段,因此需要提供命令行功能。
其它还有debug、对象锁之类。
这也是我坚持认为,随着MCU的资源越来越丰富,嵌入式编程必然会走向复杂化、应用化的原因:为了在竞争中获胜,现场器件越来越智能化是必要的、必须的趋势!
如我们现在就在考虑海上碰撞的预警、检测与证据固定,已经在进行功能方面的论证。
也正是基于这个判断,我才会坚定的抛弃c而拥抱rust。
概要之,如果只是瞄准目前通常的嵌入式应用场景:固定功能的现场操控。其实没必要用rust嵌入式编程【rust+RTIC功能有限又自带rust的高门槛,完全属于自找麻烦】,门槛太高、成本也高出很多;开发周期【尤其是产品成型的第一个版本的开发周期】太长,可能会导致产品验证出现问题。
但是,如果希望提高竞争水准、抬升行业准入门槛,并将其中一个发力点落在现场感知、反应的智能化能力上,我认为除非有极深的积累,否则rust嵌入式自然拥有相当强的竞争力,毕竟c太古老了,不太适合快速低成本开发高可靠、高价值的应用。
对冲rust的高门槛
rust门槛高、心智负担重,这是公认的rust的缺点。但就嵌入式而言,这个缺点其实是不存在的。
原因非常简单,嵌入式再如何复杂,现在也远比后台应用简单的多,所以完全可以采取措施来对冲rust的高门槛:
1、用静态变量互斥访问来对冲rust的生命周期、借用难
对rust的生命周期、借用,作为初学者的我也很头疼,而我的解决办法非常粗暴:
嵌入式的应用场景简单,所以我直接把主要功能所需要的数据静态化、然后进行包裹、再用互斥锁进行保护,这样一来,所有的操作接口都是:&'static self。
这就完全不再需要考虑生命周期和借用的问题了,编程难度直线下降,编译器一声都不敢吱:)
这个方法在上线后,轻松抗住了一天40万条数据的采集压力!而且经过计算,还远没到设备极限,大家可以放心大胆的用:)
2、用资源的高耗费来对冲编程的复杂度
既然现在MCU的资源极大的丰富了,堆资源就好,绕开死磕技术难度的坑就是了。
就如我们的串口读取,底层申请了内存,上层应用什么时候用完、需要进行释放是不清楚的,而且串口读取到的数据,还可能流经多种功能模块,比如用蓝牙模块以modbus协议读取设备数据,就需要流经串口模块、蓝牙模块、modbus模块、应用模块。这对内存管理就带了很大的压力。
所以我同样是用简单粗暴的方法来应对:每层自己申请自己释放,要提交给上层的,就做一次内存copy。
这样过一层就做一次内存copy的资源耗费显然太过巨大,但这样简单啊,硬怼资源就很容易实现,反正内存copy那点开销相比现在的MCU和嵌入式场景实在不值一提。
这个以资源开销来换简化编程、消弭bug的方法在我们多个串口、多种设备管控,一天40多万条数据的采集、海上无线传输的压力下工作良好!
一句话:在目前的情况下,rust嵌入式编程不需要考虑优化、不需要担心浪费,堆资源是最应优先考虑的方案。
在我来看,对一个产品来说,有两个指标是决定性的:
- 关键需求的满足度
- 产品的稳定性
前者是客户花钱的理由,rust的现代性和良好生态是支撑我们依托智能化产品来提升核心竞争力的利器,自然就是选择rust的最大理由;后者是客户付钱的理由,rust写出的程序天然自带的健壮性和可靠性,就是选择rust的第二大理由。
当然,rust在嵌入式方面的生态还有所不足,但这只是时间问题,总要给新生儿成长的时间。
谁都有缺点,弥补缺点就需要成本。借用工程技术手段和高资源开销来弥补rust的缺点,就是我们目前必要的成本。
现在看下来,这些成本完全可以接受。
rust嵌入式的不足
生态、生态、生态。这必须是rust嵌入式的最大不足。尤其是在芯片国产替代的当下,国产芯片在rust嵌入式方面的投入基本可以忽略。
如我们第一版用的就是国产的GD32,但在看好rust嵌入式的前景之后,由于芯片厂商等在基础设施方面的投入不足,最后只好又选了STM32。
当然,我相信国内的芯片厂家既然提供了这么强大的MCU,最终一定是需要软件来消耗掉这些资源的,我们的新版本已经消耗掉了384K的Flash,还有很大空间值得挖掘:)
而这要靠c肯定不现实,最终还是要在rust上发力的。只是需要提提速啊:(
rust嵌入式在生态方面的最大不足,对我们来说,自然就是缺乏一个如国产的rt-thread这样的国产RTOS。由于缺了不少必要的基础部件,就需要自己来开发,这相当于提升了开发门槛和成本。
rust嵌入式的第二个不足,就是no_std和std的隔离。这就导致rust的良好生态在嵌入式方面被大幅度的削弱了。
比如:我在命令行中原本要实现参数的核验,但rust工业标准的正则表达式crate在no_std下就用不了,只好用了可以支持no_std的regex-automata,但用下来总感觉有些问题,由于时间太紧张了,实在无法全面测试,最后干脆就先取消了命令行的参数核验能力。
就目前来说,no_std的问题还影响不大,但随着现场智能化诉求的提升,这个问题势必会带来越来越大的限制。
第三个不足应该是rust的不足,就是IDE在编辑界面无法自动扩展宏。
我选择rust的一个重要理由,就是相比c中的宏,rust的过程宏异常的强大:完全可以媲美java中的反射和python中的@修饰符,关键还是零开销:rust嵌入式之用类函数宏简写状态机定义。
在java和python中我都自己实现了ORM、状态机等,所以我深知反射技术是各种框架的基础,对现代软件工程和编程技术具有无与伦比的巨大意义,当然,还有所要花费的巨大开销。
在rust中,我同样用过程宏实现了状态机、命令行、debug、控制台、串口/pwm等接口操作的自动扩写、扩展对象锁、命令-期望等等。
对rust的过程宏,我实在是太满意了。
但是,宏用得太多,某些利用宏扩写出来的技术细节我自己也就记不清楚了,当需要探究某个技术细节的时候,IDE竟然不给自动展开所扩写的代码,还需要手动执行命令来展开宏,然后去另外的文件中来查看,非常低效。
这个不足,在排错的时候尤其讨厌!
结语
虽然rust嵌入式有着种种的不足,但我依然相信rust在嵌入式领域前程远大。
相关文章:
rust嵌入式开发之总结
我们用rust开发的新版产品刚刚交付,已经在海上安装测试完毕并顺利投产。终于松了口气,同时也有时间和精力来做个全面的总结了。 这个产品,目前差不多有三版: 第一个版本是用crt-thread写的,投产后出了一个内存泄露的…...

【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版6(附带项目源码)
最终效果 系列导航 文章目录 最终效果系列导航前言方法一、使用excel配置表excel转txt文本读取txt数据按配置信息生成僵尸 方法二、使用ScriptableObject 配置关卡信息源码结束语 前言 本节主要是推荐两种实现配置关卡信息,并按表生成僵尸和关卡波次 方法一、使用…...
回溯算法指组合总和
题目: 找出所有相加之和为 n 的 k 个数的组合,且满足下列条件: 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。 思路: 这种问题…...
java-stream转换map key重复报错解决小记
解决key重复问题 在用stream转成map过程中会有key重复的隐患,如果数据没重复还好,如果重复了会提示 java.lang.IllegalStateException: Duplicate key 8753444332651at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)at ja…...

王春城 | 如何解决精益转型过程中的信任问题?
实践证明,精益转型不仅仅是技术和管理方法的更新,更是一场深刻的文化变革。在这个过程中,涉及到多个部门、多个层级的协同合作,需要团队成员之间的深度沟通和高度信任。如果缺乏信任,团队成员之间就会产生隔阂和抵触情…...
Ubuntu Nvidia Docker单机多卡环境配置
ubuntu版本是22.04,现在最新版本是24.xx,截止当前,Nvidia的驱动最高还是22.04版本,不建议更新至最新版本。本部分是从0开始安装Nvidia docker的记录,若已安装Nvdia驱动,请直接跳至3。 1、更新软件软件列表…...

小公司的软件开发IT工具箱
目录 工具链困境 难题的解决 达到的效果 资源要求低 工具箱一览 1、代码管理工具 2、自动化发版(测试)工具 3、依赖库(制品包)管理 4、镜像管理 5、授权管理(可选) 待讨论:为什么不是…...
代码随想录算法训练营第四十四天| 背包问题、背包问题之滚动数组、416. 分割等和子集
背包问题 题目链接:背包问题 文档讲解:代码随想录/背包问题 视频讲解:视频讲解-背包问题 状态:已完成(1遍) 解题过程 这几天属实是有点分身乏术了,先直接看题解AC了,二刷的时候再…...

最新一站式AI创作中文系统网站源码+系统部署+支持GPT对话、Midjourney绘画、Suno音乐、GPT-4o文档分析等大模型
一、系统简介 本文将介绍最新的一站式AI创作中文系统(集成ChatGPTMidjourneySunoStable Diffusion)——星河易创AI系统,该系统基于ChatGPT的核心技术,融合了自然语言问答、绘画、音乐、文档分享、图片识别等创作功能,…...
C# 语言类型(二)—预定义类型之字符串及字符类型简述
总目录 C# 语法总目录 参考链接: C#语法系列:C# 语言类型(一)—预定义类型值之数值类型 C#语法系列:C# 语言类型(二)—预定义类型之字符串及字符类型简述 C#语法系列:C# 语言类型(三)—数组/枚举类型/结构体 C#语法系列:C# 语言类型(四)—传递参数及其修饰符 C#语法…...
微信小程序canvas画图使用百分比适配不同机型屏幕达到任何屏幕比例皆可!完美适配任何机型!指定canvas尺寸适配亦可!保证全网唯一完美
错误代码示例: // 在onLoad中调用 const that this wx.getSystemInfo({success: function (res) {console.log(res)that.setData({model: res.model,screen_width: res.windowWidth/375,screen_height: res.windowHeight})} }) 我看到网上很多使用上面这种代码去…...

Redis-02
redis安装包位置 /opt/redis-7.2.5 redis默认安装路径: 配置文件路径:/usr/local/bin/redisconfig gcc安装位置 /opt/rhredis启动: 在/usr/local/bin目录下输入redis-server redisconfig/redis.confredis-cli -p 6379redis性能测试命令 red…...

如何编辑pdf文件内容?编辑技巧大揭秘,秒变办公达人!
如何编辑pdf文件内容?在数字化办公日益普及的今天,PDF文件因其跨平台、格式稳定的特点,成为我们日常工作和学习中不可或缺的一部分。然而,PDF文件的编辑却常常令人头疼,许多人面对需要修改内容的PDF文件时感到无从下手…...
Linux Shell Script 编写入门
Linux Shell 脚本是一种强大的工具,能够帮助用户自动化任务、简化系统管理以及提高工作效率。本文将带您全面了解如何编写 Linux Shell 脚本,并介绍一些常见的脚本编写技巧和注意事项。 目录 什么是 Linux ShellShell 脚本的基本结构常用 Shell 命令变…...

不是从APP store下载的APP在mac上一直提示有损坏,打不开怎么办?
1.点击设置 2.安全与隐私 3.通用看看允许从以下位置下载的APP是否有任何来源 4.如果没有,mac桌面点击🔍输入终端或Terminal 命令行输入下述代码: sudo spctl --master-disable 5.回车,输入mac开机密码。注意:此时密…...
ubuntu22.04部署docker版zlmediakit和源码运行wvp-GB28181-pro
1 运行zlmediakit 1. 修改zlmediakit配置文件 先用run命令运行zlmediakit,将zlmediakit的配置文件拷贝出来 docker run -d -p 1935:1935 -p 8080:80 -p 8554:554 \ -p 10000:10000 -p 10000:10000/udp -p 8000:8000/udp \ --name zlmediakit \ zlmediakit/zlmedi…...

MySQL表的增删改查初阶(上篇)
本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. 🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人…...

Spring Boot 集成 zxing 生成条形码与二维码
前面我们知道了怎么通过 使用 zxing 生成二维码以及条形码, 由于我们现在都是 web 端的项目了,那么我们看下怎么使用 Spring Boot 集成然后返回给前端展示: 工程源码 对应的工程源码我放到了这里:github源码路径,点击…...
C# 编程基础:注释、变量、常量、数据类型和自定义类型
C# 是一种功能强大的面向对象编程语言,它提供了丰富的特性来帮助开发者编写清晰、高效的代码。本文将介绍C#中的注释、变量、常量、基本数据类型以及如何创建和使用自定义类型。 注释 注释用于解释代码的目的,它们不会被程序执行。 单行注释使用 //。…...

网络原理-三
一、连接管理 建立连接,断开连接 建立连接,TCP有连接的. 客户端执行 socket new Socket(SeverIP,severPort); -> 这个操作就是在建立连接. 上述只是调用socket api,真正建立连接的过程,实在操作系统内核完成的. 内核是怎样完成上述的 " 建立连接 "过程的…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...