编写固件:汇编还是高级?

c assembly embedded firmware

24074 观看

17回复

相关:

如果您正在为微控制器编写代码,那么如果您使用汇编语言或C语言或其他高级语言编写,会有真正的区别吗?如果你编写C代码,你会如何编译它?

谢谢

作者: cbrulak 的来源 发布者: 2019 年 6 月 7 日

回应 (17)


31

决定

几条评论:

1)绝对不是装配,除非性能或优化限制保证。以下指标通过汇编进入屋顶:

  • 是时候编码了
  • 时间来调试它
  • 是时候测试了
  • 记录它的时间
  • 是时候弄清楚(1年后)你编码时你在做什么
  • 犯错的可能性

2)我的首选项是C ++而不是C,因为它的命名空间封装和它促进了编译时面向对象的实践。C有太多的全局变量和命名空间冲突的机会。(实时Java会很好,但据我所知,它的要求仍然很高)

或者更确切地说是C ++的一个子集:排除异常,虚函数,运行时类型识别,以及大多数情况下的动态内存分配 - 基本上是在编译时未指定的任何内容,因为在运行时通常需要大量额外资源。这是C ++的“膨胀”。

我已经使用TI和IAR的C ++编译器,分别用于TMS320和MSP430微控制器,并且通过适当的优化设置,它们可以很好地减少您对C ++的开销。(特别是如果你通过明智地使用inline关键字来帮助它)

我甚至使用模板来获得一些编译时的好处,这些好处促进了良好的代码重用:例如,编写单个源代码文件来处理8位,16位和32位CRC; 和编译时多态,允许您指定类的通常行为,然后重用它,但覆盖它的一些功能。同样,TI编译器具有极低的开销,并具有适当的优化设置。

我一直在寻找Microchip PIC的C ++编译器; 我找到的唯一一家生产IAR的公司就是IAR。($$$一直是个障碍,但我希望有时会买一份)Microchip C18 / C30编译器非常好,但它们是C,而不是C ++。

3)关于编译器优化的一个具体警告:它可以/将使调试变得非常困难; 通常不可能单步执行优化的C / C ++代码,并且您的监视窗口可能会显示与您认为应该包含未优化代码的内容无关的变量。(一个好的调试器会警告你一个特定的变量已经优化不存在或者进入寄存器而不是内存位置。很多调试器都没有。> :(

另外一个好的编译器可以让你通过#pragmas在功能级别选择/选择优化。我使用过的只允许您在文件级别指定优化。

4)将C代码连接到汇编:这通常很困难。最简单的方法是创建一个具有所需签名的存根函数,例如uint16_t foo(uint16_t a, uint32_t b) {return 0; },where uint16_t= unsigned short,我们通常将#位显式化。然后编译它并编辑它产生的程序集(只需确保保留代码的开始/退出部分)并注意不要在完成后修复任何寄存器而不恢复它们。

内联汇编通常会遇到问题,除非您正在执行一些非常简单的操作,例如启用/禁用中断。

我最喜欢的方法是编译器内在函数/“扩展ASM”语法。Microchip的C编译器基于GNU C编译器,它具有“ 扩展ASM ”,允许您对内联汇编的位进行编码,但是您可以给它很多提示,告诉它您正在引用哪些寄存器/变量,它将处理所有的保存/恢复寄存器以确保您的汇编代码与C一起“很好”.TI用于TMS320 DSP的编译器不支持这些; 它确实有一组有限的内在函数,它们有一些用处。

我已经使用汇编来优化一些经常执行的控制循环代码,或者计算sin(),cos()和arctan()。但是否则我会远离集会并坚持使用高级语言。

作者: Jason S 发布者: 16.01.2009 11:25

21

大多数微控制器制造商提供某种交叉编译器,您可以在PC上编译代码然后将其传输到微控制器。

为何选择C?
C的一个优点是您的代码将来更容易移植到其他微控制器。计算历史表明,代码通常比硬件实现更耐用。
第二个优点是控制结构(if,for,while)使代码更易读和可维护。

为什么汇编语言?
您可以手工优化。

判决
与这类问题的情况一样,权衡取决于具体用途。
请注意,通常可以通过在C代码中进行汇编调用来混合这两者,这样您就可以找到适合您项目的余额。

具体到PIC硬件
似乎是你没有GCC的大部分PIC硬件的选项。另一方面,正如评论者所指出的,16位PIC24和dsPIC33的Microchip C30编译器是gcc。SDCC
尚未支持PIC 。新信息:根据评论,SDCC对PIC有可行的支持。 还有其他一些开源选项,但我没有使用它们的经验。

作者: John Mulder 发布者: 16.01.2009 09:45

7

最好的选择可能是用C编写代码,然后对于需要手动优化并且可以比编译器做得更好的极少数实例,您应该将程序集编码到c文件中。

作者: Kibbee 发布者: 16.01.2009 09:53

6

对于PC来说,汇编编码已成为过去,但在嵌入式编码中非常重要。

在嵌入式中编写程序集与在PC上编写程序集不同。PC编译器在生成优化指令时“比人类更好”。嵌入式系统通常具有奇怪的架构,其优化编译器并不像PC优化编译器那样成熟。

作者: Dustin Getz 发布者: 13.02.2009 09:06

5

我在为微控制器编写程序集时遇到的一个问题是需要非常小心地编写代码。有一个跨越内存边界的跳转表,并导致你的代码跳转到非常奇怪的地方是相当令人不安的。在C语言编码中,编译器为您提供了基础。

作者: Harper Shelby 发布者: 16.01.2009 09:55

5

我肯定会选择C.它更快,它创造了更可靠的软件。大会几乎没有提供,在稀缺的场合。请记住在C:

  • 您可以轻松地从现有平台移植代码,甚至可以从PC移植代码。
  • 您可以使用高级语言进行开发,而不会影响执行速度或代码大小。如果可以使用高质量的编译器(PIC18有很多选择),那么使用C语言最好比手工制作的组件更好。
  • 调试,测试和维护代码要容易得多。C生成更可靠的代码。

另一件事与PIC18有关。您不必处理非直观的PIC架构和内存BANK等问题。

作者: kgiannakakis 发布者: 16.01.2009 09:59

4

我以前在8051的IAR C编译器方面有很好的经验。

我最近的方法一直是: -

使用良好的优化编译器将其写入C,并且只有在大小或速度有问题时,才考虑在汇编程序中重写某些部分。

但是,由于采用这种方法,我从来不需要编写一行汇编程序......

作者: Roddy 发布者: 16.01.2009 10:04

4

去找c!

我曾在一家大型CE制造商工作过。我最后一次看到装配是在1996年左右的一些小型中断服务程序中用于RC5和RC6解码和电视调谐算法。之后总是使用c和C ++(只使用类,没有stl,异常或rtti)。我对8051的旧KEIL编译器以及greenhills编译器(MIPS)和VxWorks工具集(基于PowerPC)有很好的经验。

正如Roddy所说,首先用C语言编写,然后稍后优化组装(如果需要)。

作者: RoccoD 发布者: 21.01.2009 03:48

3

在许多情况下,装配可以更快; 当你在桌面上时,编译器往往被优化到手工装配很少是必需的程度,但在uC世界中,它往往是。此外,如果您需要编写中断处理例程和类似的东西,您通常无法在C中执行此操作。

至于编译,谷歌周围为你的目标的C编译器。

作者: Cody Brocious 发布者: 16.01.2009 09:45

2

绝对是C,除了

  • 程序存储器非常有限。在经过精心设计的汇编程序代码之后,您可以设法在这个1024字节的Flash中使用您的程序,剩下0个字节。在这种情况下,没有C编译器会有任何好处。

  • 你想要有绝对时间控制。如果任何数量的中断延迟太长,您将不得不依赖汇编程序。

作者: stevenvh 发布者: 13.02.2009 08:58

2

这些天的问题是,嵌入式可以是任何东西,从具有6个引脚和几个字节RAM的ATTiny到运行嵌入式操作系统的多核SBC,这会让一些人的桌面计算机感到羞耻。

因此,语言/开发环境的选择需要考虑您需要的效率与系统的复杂程度。

首先 - C无处不在,并且可以很好地扩展,越高越好,你最终会调用外部库等来处理复杂性。

对于非常小的微型(测量flash / ram,以字节为单位),最好使用ASM,当你达到kb范围时,可以使用C或任何其他传统语言,因为你不需要计算每个字节。一旦你有兆字节玩,你就有能力,并且越来越有可能要求使用RTOS来处理所有事情并缩短开发时间。当你拥有硬件时,你可以运行一个完整的操作系统,你可以从硬件中抽象自己,只需在像Java这样的填充单元格中编写所有东西,而不必过多担心这一切是多么浪费,以及你是如何不再是一个真正的程序员...;)

上述情况的例外情况是,当您需要从硬件中获取的所有性能时,您可能需要降低一到两级才能保持高效。

作者: John U 发布者: 22.06.2012 06:12

1

还有一次可能需要在汇编中进行写入:如果需要进行低级RAM测试或类似操作,则需要绝对控制数据的存储位置。

例如,确认SIL -2(安全完整性等级)及以上的软件可能需要对RAM进行连续检查,以便检测任何可能的数据损坏。您正在检查的RAM区域在检查时无法更改,因此在汇编程序中编写测试可以确保这是真的,例如将任何局部变量存储在特定寄存器或RAM的另一个区域中。如果不是不可能的话,在C中这将是困难的。

尽管提供了这种类型的代码,但是将RAM归零并初始化非零静态变量的启动代码也可以用汇编程序写入相同的代码。

作者: Steve Melnikoff 发布者: 30.01.2009 07:14

1

如果您编写的代码高度依赖于特定于设备的外设,并且您使用的工具链无法提供必要的内在函数来有效地利用它们(如蹩脚的Freescale DSP563CC编译器),那么请使用汇编。

除此之外,我认为使用汇编语言与高级语言的不成文规则与桌面软件开发的规则大致相同:保持代码清洁,可维护,并使用机器语言优化热代码。

作者: switchmode 发布者: 07.02.2009 04:57

0

这是底线,如果你使用C你可以稍后进行优化,我不会使用除C或汇编程序之外的任何东西(没有C ++等)。

关键是微控制器指令集,如果你使用的是PIC,甚至是8051我只使用汇编程序。如果它是一个编译器友好的像arm或avr或msp430那么使用C来保存一些输入,但你可能会因为各种原因在汇编程序中有一些例程。同样地,你可能想要避免使用C库,即使是newlib也可能过于笨重,从它们那里借用代码或想法,但不要只链接一个。哦,回到问题,看看C编译器可用于目标,再次胳膊和avr你不会有任何问题。可能msp也没问题。仅仅因为Keil或Iar会卖给你一个编译器并不意味着你应该购买它或使用它,付费和免费编译器的输出可能是可怕的。

底线(另一个底线),没有全局答案(完全避免任何高于C的全局答案)它总是取决于平台是什么,你的资源是什么,你的任务是什么,性能要求是什么,便携性要求是(如果它真的嵌入在微控制器上的大部分是定义不可移植的)可以使用什么编译器,调试器,jtag等,即使你正在开发的主机操作系统可能是一个重要因素。

作者: old_timer 发布者: 22.01.2009 08:54

0

到目前为止,没有人提到Forth或Scheme太糟糕了。两者都适用于小型环境,可以提高效率。

作者: Jeff Allen 发布者: 09.02.2009 09:58

0

普通C或Pascal,Modula2。但由于编译器可用性意味着C.

由于动态分配和程序大小通常非常有限,因此C ++和类似物的额外功能仅仅是出于风格的考虑。

如果您的应用程序变得紧张,更复杂的运行时也会很麻烦。

汇编程序也很有用,但只有当你卖出巨大的数量时,较小的固件意味着更小,更便宜的芯片(闪存更少)并且程序的大小是可监督的(读:你有可能在时间上免费获得它)

作者: Marco van de Voort 发布者: 01.05.2009 09:43

0

汇编语言中的代码非常快,占用空间小,但用汇编语言编写的代码不是可重用的代码。代码的这种可重用性特征是软件设计的最重要特征。例如,如果您有x86处理器的汇编程序代码,则它只能用于x86处理器,而不能用于ARM处理器。但是如果您有x86处理器的项目C / C ++代码,则可以将此代码用于ARM处理器。因此,最好避免使用汇编程序进行软件开发。

作者: Josko Marsic 发布者: 06.06.2019 11:30
32x32