【问题标题】:To write a bootloader in C or C++?用 C 或 C++ 编写引导加载程序?
【发布时间】:2010-12-10 09:22:15
【问题描述】:

我正在为嵌入式系统编写程序,更具体地说是引导加载程序。我将使用 C 库与一些硬件组件进行交互,我可以选择用 C 或 C++ 编写它。有什么理由我应该选择其中一个吗?我不需要 C++ 的面向对象特性,但它确实具有更强大的类型系统。它是否有其他语言特性可以使程序更加健壮?我知道有些人避免使用 C++,因为它可以(但并非总是)生成大型固件映像。

【问题讨论】:

    标签: c++ c bootloader embedded


    【解决方案1】:

    CµClibc 一起使用。它将使您的代码更简单并减少其占用空间。可以在以下位置找到:www.uclibc.org

    【讨论】:

    • 有链接到哪里可以找到这个库?
    【解决方案2】:

    使用 C++ 并选择您需要的语言功能。只要您了解所使用的 C++ 抽象,您仍然可以完全控制输出对象代码。

    如果避免使用虚函数,OO 的使用仍然可以很好地运行。避免需要大量复制才能传递值的不可变对象类型,例如 std::string。但是,您仍然可以使用模板等功能,而不会对运行时性能产生任何实际影响。

    【讨论】:

      【解决方案3】:

      之前的大多数答案都假设您的引导加载程序小而简单,这通常是这种情况;但是,如果它变得更复杂(即您需要能够从以太网端口、USB 端口或串行端口加载……您需要在清除现有代码之前验证正在加载的代码,等)您可能需要考虑 C++。

      我还发现引导加载程序和应用程序通常共享一些公共代码,因此您可能还需要考虑使用与应用程序相同的语言来促进代码共享。

      【讨论】:

        【解决方案4】:

        除非有使用 C++ 的特定原因,否则我会使用 C。对于引导加载程序,您实际上并不需要 OO。

        使用最简单的工具来完成这项工作。

        【讨论】:

        • 阿门使用最简单的工具来完成这项工作。我认为我必须对此表示赞同! :D
        • 不,您不应该使用最简单的工具来完成工作,而应该使用使您的工作变得最简单的工具。最简单的工具显然是二进制编辑器,它允许您将指令操作码作为二进制输入。不建议。高级语言可能会使您的工作更加困难,因为您必须通过一层又一层的运行时支持代码进行调试。 C 和 C++(如果以适合嵌入式的风格使用)都达成了一个非常好的折衷方案,即让您看到正在发生的一切,但以人性化的方式呈现。
        【解决方案5】:

        如果您不需要使用面向对象,请使用 C。那里有简单的选择。它更简单,更容易,同时完成相同的任务。

        有些顽固分子会不同意,但 OO 是 C++ > C 的原因,在很多情况下反之亦然。

        【讨论】:

        • 您也可以用 C 编写 OO,实际上几乎可以用任何语言编写,也就是说,您可以在一个结构中收集数据并编写对其进行操作的方法;虽然它结束了。
        • 是的,但我认为凯尔知道这一点。一个经过深思熟虑的回复,我是 c 和 c++ 的粉丝
        • 另外,在很多情况下,OO 是 C++
        • “你可以用任何语言编写 OO” - OOP 不是关于“在结构上使用方法”,它是关于拥有 动态绑定 方法。如果您已经在 C++ 中拥有 vtable 机制,那么您自己在纯 C 中实现 vtable 机制是不合理的。
        • 我不同意这个。 OOP 支持可能是最不相关更喜欢 C++ 的原因,尤其是在嵌入式环境中。正如 Al 的回答所示,C++ 包含大量改进,这些改进只是产生比 C 更好、更健壮的代码,但绝不是特定于 OOP。
        【解决方案6】:

        这不是一个特别容易回答的问题。这取决于许多因素,包括:

        • 您喜欢如何布局代码。
        • 是否有可用于您的目标(以及您可能希望在其上使用引导加载程序的任何其他目标)的 C++ 编译器。
        • 代码大小对您的应用程序有多重要(我们说的可能是额外的 10%,而不是另一个答案所建议的 MB)。

        就我个人而言,我真的很喜欢将类作为我的代码布局的一种方式。即使在编写 C 代码时,我也倾向于将所有内容保存在模块化文件中,文件范围的静态函数“模拟”成员函数和(一些)文件范围的静态变量来“模拟”成员变量。话虽如此,我现有的大多数嵌入式项目(所有这些都是相对较小的规模,最大 128kB 闪存,包括引导加载程序,但通常更少)倾向于用 C 编写。现在我有一个 C++ 编译器,我当然在考虑转向 C++。

        简单地使用引用、重载和模板对 C++ 有相当大的好处,即使您不使用类。当然,我不会使用很多更高级的功能,包括使用动态内存分配(新)。再说一次,如果可能的话,我也会避免在嵌入式 C 中进行动态内存分配(malloc 等)。

        如果您有一个 C++ 编译器(即使它只是 g++),那么值得通过它运行您的代码只是为了进行额外的类型检查,这样您就可以减少代码中的问题数量。 C++ 编译器可以处理一些即使是静态分析工具也无法发现的东西。

        有关人们拒绝 C++ 的许多无效原因的详细讨论,请参阅 Dan Saks' article on Embedded.com

        【讨论】:

        • 好答案。我可能会根据目标做出选择。如果它比 8 位 µC 更大,我会尝试坚持使用 C++。我已经学会讨厌 C++,但如果你知道自己在做什么,我认为它可以给你带来与使用 C 相同的好处。一如既往,一个非常好的建议:知道你在做什么以及为什么。
        • “即使只有 g++”是什么意思?这是一个非常好的 C++ 编译器。在这种情况下是否有一些具体的理由来避免它?无论如何,很好的答案,我同意。 C++ 的许多特性(如引用和模板)可以简单地用于编写更安全、更健壮的代码,而不会在内存或速度方面产生运行时成本。当然,C++ 还具有许多在嵌入式环境中应该非常小心的特性。但它们可以避免,就像你说的那样。
        • 我同意将 C++ 用作“更好的 C”对于这样的事情是一个好主意。但是当我过去尝试这样做时,我也发现自己有点进退两难: 尝试以这种方式使用 C++,同时避免动态内存。C++ 中很多有用的东西都依赖于动态内存,我发现自己一直在努力从 C++ 库和技术中重新发明我想要使用的东西,而这通常只是说得更简单——这个项目使用的是 C,句号。
        • @jalf:对不起,我应该措辞更好。当我说“即使它只有 g++”时,我的意思是:“即使你不费心为你的嵌入式平台寻找一个(或找不到一个),而只是选择一个免费的 PC 像 g++”。跨度>
        • @David:一个小的修正——多态性不依赖于动态内存。在许多需要动态内存的 C++ 代码中使用的其他不错的技术:shared_pointer、pimpl。 Pimpl 不是很难做到,尽管.shared_pointer 可以写成使用一个固定的块分配区域来包含指针和引用计数,但是当我说你结束时,这就是我所说的那种事情不得不重新实现。
        【解决方案7】:

        C 语言比 C++ 更容易解析。这意味着同时是有效 C 和有效 C++ 的程序将作为 C 程序编译得更快。可能不是一个主要问题,但这只是 C++ 可能过度杀伤的另一个原因。

        【讨论】:

          【解决方案8】:

          对于引导加载程序,显而易见的选择是 C,尤其是在嵌入式系统上。生成的代码需要接近金属,并且很容易调试,可能通过放入汇编中,这在 C++ 中如果不小心很快就会变得很困难。此外,C 工具链比 C++ 工具链更普遍,允许您的引导加载程序在更多平台上使用。最后,生成的二进制文件通常更小,并且在编写 C 风格时使用更少的内存。

          【讨论】:

            【解决方案9】:

            用 C 编写程序与用 C++ 编写程序不同。如果您只知道如何在 C++ 中执行此操作,那么您的选择是 C++。为了编写引导加载程序,最好尽量减少代码,因此您可能必须禁用标准 C++ 库。如果您知道如何用 C 编写代码,那么您应该使用 C — 对于此类任务,它是更常见的选择。

            【讨论】:

              猜你喜欢
              • 2012-03-02
              • 2011-10-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-01-19
              • 1970-01-01
              相关资源
              最近更新 更多