使用正确的工具:嵌入式编程

Emb*_*rog 16 c c++ java embedded

我对编程非常适合嵌入式编程的语言很感兴趣.特别是:

是否可以用C++编写嵌入式系统?或者使用纯C更好?或者,只有当语言的某些功能(例如RTTI,例外和模板)被排除在外时,C++才行吗?

那个域里的Java怎么样?

谢谢.

Cli*_*ord 27

是否可以用C++编写嵌入式系统?

是的,当然,即使是8位系统.C++只有比C稍微不同的运行时初始化要求,即在调用main()之前必须调用任何静态对象的构造函数.开销(不包括你控制范围内的构造函数本身)很小,但你必须要小心,因为没有定义构造的顺序.

使用C++,您只需为您使用的内容付费(而且有用的内容可能是免费的).也就是说,例如,一块也是C++可编译的C代码通常不需要更多内存,并且在编译为C++时执行速度不比编译为C时慢.有些C++元素可能需要小心有,但许多最有用的功能来自很少或没有成本,并有很大的好处.

或者使用纯C更好?

可能在某些情况下.一些较小的8位甚至16位目标没有C++编译器(或者至少没有任何一种代表),使用C代码可以提供更大的可移植性.此外,对于应用程序较少的资源严重受限的目标,C++可以带来的优势很小.C++中的额外功能(主要是那些支持OOP的功能)使其适用于相对较大和复杂的软件构造.

或者,只有当语言的某些功能(例如RTTI,例外和模板)被排除在外时,C++才行吗?

可接受的语言功能完全取决于目标和应用程序.如果您受内存限制,您可能会避免使用昂贵的功能或库,即使这样,也可能取决于它是您缺少的代码还是数据空间(在这些是独立的目标上).如果应用程序是硬实时的,那么您将避免使用那些不确定的特性和库类.

一般来说,我建议如果你的目标是32位,总是使用C++优先于C,然后削减你的C++以适应内存和性能限制.对于较小的部分,在选择C++时要稍微谨慎一些,尽管不要完全打折; 它可以让生活更轻松.

如果您确实选择使用C++,请确保您拥有适合C++的调试器硬件/软件.使用C++构建复杂软件相对容易,使得一个体面的调试器更有价值.并非嵌入式领域中的所有工具都具有C++知识或能力.

我总是建议在任何嵌入式主题上挖掘Embedded.com的档案,它有很多文章,包括一些这样的问题,包括:

关于Java,我不是专家,但它有很大的运行时要求,使其不适合资源受限的系统.您可能会使用Java将自己限制在相对昂贵的硬件上.它的主要好处是平台独立性,但是这种可移植性并没有扩展到不支持Java的平台(其中有很多),因此它可以说比具有抽象硬件接口的精心设计的C或C++实现更不便携.

[edit]我刚刚在TechOnline时事通讯中收到了这篇文章:在嵌入式应用程序中高效地使用C++


sho*_*osh 9

在嵌入式系统中,您编程的语言通常取决于实际可用的编译器.
如果您的硬件只有C编译器,那就是您要使用的.如果它有一个像样的C++编译器,那么实际上没有理由偏爱C而不是C++.
我敢说Java在嵌入式系统中不是一个非常受欢迎的选择.

  • @Judge Maygarden:C++并没有神奇地"吃掉"内存,你只需支付你使用的内容,即使是C编译为C++也可能会受益于强大的类型检查,而无需运行时成本.至于Java,在你编写一行代码之前,它会在运行时支持中占用大量资源,但你不会对此提出相同的反对意见. (5认同)
  • 我有一个C++编译器可用,仍然使用C."没有理由更喜欢C over C++"是一个非常强大的声明.如果你不是很小心,C++可以隐含地通过约束系统上的内存来吃东西.此外,Java是许多嵌入式系统(例如移动电话)的极受欢迎的选择. (3认同)
  • @Judge Maygarden:我不同意你使用Java的地方和方式 - 这些平台不是特别受资源限制或硬实时.关于"模板代码膨胀",正如我所说,你只需支付你使用的东西,如果你不使用模板就没有膨胀,而且由于C没有它们,你什么也没有丢失.此问题在很大程度上是编译器/链接器的错误,而不是语言本身(如果您没有有效的模板支持,则不会有帮助).我确信我从未说过C不应该被使用;-) (2认同)

ste*_*anv 9

如今,嵌入式编程涵盖了大量应用程序.
粗略地说,它从传感器/交换机到完整的安全系统.
您的语言应该基于复杂性和硬件资源.
它是HW(CPU,...),操作系统,协议......旁边的选择之一......
可能的选择:

  • 开关:汇编程序
  • 类似路由器的设备:C和/或C++
  • 手持设备:Java或QT/C++
  • 完整系统:使用python组合C和/或C++


Jas*_*n S 6

或者,只有当语言的某些功能(例如RTTI,例外和模板)被排除在外时,C++才行吗?

按照这些思路思考是件好事.编译时复杂性并不是一件大事,但运行时复杂性会产生资源成本.

C++有助于类/名称空间模块化(例如foo(),多个上下文中的方法)和实例模块化(成员字段bar属于多个对象),这两者都是软件设计的一大优势.还有一些功能,如const引用,静态强制转换和模板,可以帮助实施约束,并且运行成本很低或没有.

不会排除模板.它们考虑起来很复杂,你需要一个能够很好地处理它们的编译器,但是资源成本几乎都是编译时间 - 每次使用具有不同类参数的模板时,"花费"的事实是,您生成一组新的代码来实例化成员函数.但是,如果没有模板,你几乎肯定要做同样的事情.此外,模板允许您在一般情况下设计和测试库,这些文件在编译时而不是链接时实例化.只是为了澄清:模板允许你有一个你测试的文件啊.然后将它与文件Bh或Bc一起使用以在编译时实例化它.(图书馆将被链接而不是编译,这使它变得不那么灵活 - 模板方法可以被优化掉,所以它们不会产生函数调用.)我在嵌入式系统中使用了模板来实现CRC代码和定点数学:我可以测试一般代码,把它在版本控制中,然后通过编写一个派生自模板或具有模板成员字段的简单类多次重复使用它.当然,典型的例子是STL.

RTTI和例外:这些增加了运行时复杂性.我不太了解资源成本,但我希望RTTI相当简单(只需添加一个类型标记,花费额外的空间),而异常可能是野蛮的,涉及堆栈展开.

虚函数:由于内存+执行时间成本(最小但仍然存在)以及调试的复杂性,我过去常常将它们排除在外,但它们允许您将对象相互分离.如果你不使用虚函数,当一个类的实例(例如Foo)需要执行与另一个类的实例(例如Bar)相关联的代码时,那么第一个类需要知道关于第二个类的所有内容(编译Foo)你需要与Bar中的所有方法建立静态链接 - 这会增加很多紧耦合.

动态内存分配:这是另一件大事(也就是在C中),我们避免像我公司的瘟疫一样 - 不仅会出现各种各样的错误,而且大的运行时成本是分配器/ deallocator,你必须愿意并且能够知道成本是多少并接受它.


编辑:喜欢在嵌入式领域使用Java而不是C++.不幸的是我的选择是有限的,并且我工作的空间中的运行时资源成本(代码大小,内存大小,垃圾收集时间限制)太高.我使用Java的原因是因为它的运行时好处而且更多用于事实上,它的软件设计更清晰,工具更好(OMG!重构!哇喔!)......对我而言,关键似乎在于两件事,这使得C/C++相比之下感觉非常笨重:

  1. 一切都是对象,所有方法都是虚拟的,所以你可以在很大程度上依赖于接口的抽象.

  2. Java中的接口/实现分离并不是这种笨拙丑陋的.c/.h文件分裂,使编译器变得如此之慢.相比之下,我在Eclipse中使用Java,它在编辑时自动编译代码.这太棒了!我立即发现了大部分错误.在C/C++中,我必须等待整个编译周期.

有一天,我希望C/C++和Java之间会有一种语言能够为软件开发提供Java的优势,而不需要让Java对桌面/服务器应用程序如此具有吸引力但在大多数嵌入式世界中没有吸引力的花俏.