编写固件:装配或高级? [英] Writing firmware: assembly or high level?

查看:172
本文介绍了编写固件:装配或高级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关:

  • Testing firmware
  • starting a microcontroller simulator/emulator
  • Interpreting assembly code

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

If you are writing code for a microcontroller is there a real difference if you write in assembly or C or some other high level language? If you wrote C code, how would you compile it?

谢谢

推荐答案

几条评论:

1)除非性能或优化限制值得保证,否则绝对不会装配。以下指标通过装配完成:

1) Absolutely not assembly unless performance or optimization constraints warrant it. The following metrics go through the roof with assembly:


  • 编码时间

  • 调试时间

  • 测试时间

  • 记录时间

  • 时间找出(1年后) )你编码时你正在做什么

  • 犯错误的机会

  • time to code it
  • time to debug it
  • time to test it
  • time to document it
  • time to figure out (1 year later) what it was you were doing when you coded it
  • chances of making a mistake

2)我的首选项是C ++而不是C,它的命名空间封装和它促进了编译时面向对象的实践。 C对全局变量和命名空间冲突有很多机会。 (实时Java将会很好,但是从我所理解的它的要求还是相当高的)

2) My preference would be C++ rather than C for its namespace encapsulation & its facilitation of compile-time object-oriented practices. C has too many opportunities for global variables and namespace collisions. (Real-time Java would be nice but from what I understand its requirements are still pretty high)

或者是C ++的一个子集:排除异常,虚拟函数,时间类型识别,大多数情况下也是动态内存分配 - 基本上在编译时没有指定任何内容,因为它在运行时通常需要大量的额外资源。这是C ++的膨胀。

Or rather a subset of C++: Exclude exceptions, virtual functions, run-time type identification, also dynamic memory allocation in most cases -- basically anything that's left unspecified at compile time, as it will usually require a lot of extra resources during runtime. That's the "bloat" of C++.

我已经分别使用TI和IAR的C ++编译器,分别用于TMS320和MSP430微控制器,并使用适当的优化设置做一个梦幻般的工作,减少您可能期望从C ++的开销。 (特别是如果您通过明智地使用 inline 关键字来帮助)

I have used both TI's and IAR's compilers for C++, for the TMS320 and MSP430 microcontrollers (respectively) and with proper optimization settings, they do a fantastic job of reducing the overhead you might expect from C++. (Especially if you help it out by judicious use of the inline keyword)

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

I have even used templates for some of their compile-time benefits which promote good code reuse: e.g. writing a single source code file to handle 8-bit, 16-bit, and 32-bit CRCs; and compile-time polymorphism to allow you to specify the usual behavior of a class, and then reuse that but override some of its functions. Again, the TI compiler had an extremely low overhead with appropriate optimization settings.

我一直在寻找Microchip PICs的C ++编译器;我发现生产一个的唯一公司是IAR。 ($$$一直是一个障碍,但我希望有时候可以购买)Microchip C18 / C30编译器相当不错,但是C,而不是C ++。

I have been looking for a C++ compiler for the Microchip PICs; the only company I've found that produces one is IAR. ($$$ has been an obstacle but I hope to buy a copy sometime) The Microchip C18/C30 compilers are pretty good but they're C, not C++.

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

3) A specific caveat about compiler optimization: it can/will make debugging very difficult; often it's impossible to single-step through optimized C/C++ code and your watch windows may show variables that have no correlation with what you think they should contain with unoptimized code. (A good debugger would warn you that a particular variable has been optimized out of existence or into a register rather than a memory location. Many debuggers do not. >:(

还有一个很好的编译器可以通过#pragmas在函数级别选择/选择优化,我使用的只是让你在文件级别指定优化。

Also a good compiler would let you pick/choose optimization at the function level through #pragmas. The ones I've used only let you specify optimization at the file level.

4)将C代码连接到程序集:这通常很困难,最简单的方法是创建一个具有你想要的签名的存根功能,例如 uint16_t foo(uint16_t a,uint32_t b){return 0;} ,其中 uint16_t = unsigned short,我们通常使位数明确,然后编译并编辑它生成的程序集(只需确保离开代码的开始/退出部分)和小心不要在完成任何寄存器之后修复它们。

4) Interfacing C code to assembly: This is usually difficult. The easiest way is to make a stub function that has the signature you want e.g. uint16_t foo(uint16_t a, uint32_t b) {return 0; }, where uint16_t = unsigned short, we usually make the # of bits explicit. Then compile it and edit the assembly it produces (just make sure to leave the begin/exit parts of the code) and be careful not to clobber any registers without restoring them after you are done.

内联汇编通常可以有问题,除非你正在做一些简单的 像启用/禁用中断。

Inline assembly usually can have problems unless you are doing something very simple like enabling/disabling interrupts.

我最喜欢的方法是编译器内在函数/扩展ASM语法。 Microchip的C编译器基于GNU C编译器,它具有扩展ASM ,它可以让你编写内联汇编的位,但是你可以给出很多提示,告诉你你正在引用哪些寄存器/变量,它将处理所有的寄存器的保存/恢复,以确保你的汇编代码播放好 TI的TMS320 DSP编译器不支持这些;它有一些有限的内在函数,有一些用处。

The approach I like best is compiler intrinsics / "extended ASM" syntax. Microchip's C compiler is based on the GNU C compiler and it has "extended ASM" which lets you code bits of inline assembly but you can give it lots of hints to tell it which registers/variables you are referencing and it will handle all the saving/restoring of registers to make sure your assembly code "plays nice" with C. TI's compiler for the TMS320 DSP doesn't support these; it does have a limited set of intrinsics which have some use.

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

I've used assembly to optimize some control loop code that got executed frequently, or to calculate sin(), cos(), and arctan(). But otherwise I'd stay away from assembly and stick with a high-level language.

这篇关于编写固件:装配或高级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆