Writing firmware: assembly or high level?

前端 未结 17 1693
时光说笑
时光说笑 2020-12-13 02:29

Related to:

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

If you are writing co

相关标签:
17条回答
  • 2020-12-13 03:09

    If you're writing code that is highly dependent on device-specific peripherals, and the tool chain you're using doesn't provide the necessary intrinsics to utilize them efficiently (like the crappy Freescale DSP563CC compiler), then use assembly.

    Besides that, I think the unwritten rules of using assembly vs. a high-level language are more or less the same as those for desktop software development: keep the code clean, maintainable, and optimize hot code with machine language.

    0 讨论(0)
  • 2020-12-13 03:11

    Several comments:

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

    • 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) 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)

    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++.

    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)

    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.

    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) 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. >:(

    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) 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.

    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.

    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.

    0 讨论(0)
  • 2020-12-13 03:11

    Best option is probably to code in C, and then for the very few instances where you need to hand optimize and can do a better job than the compiler, you should code the assembly into your c files.

    0 讨论(0)
  • 2020-12-13 03:11

    Code in assembler language are really fast with small footprint, but code written in assembler language are not reusable code. This reusibility feature for code are most important feature for software design. For example, if you have assembler project code for x86 processor, it can be use only for x86 processor, not for ARM processor. But if you have project C/C++ code for x86 processor, you can use this code for ARM processor. So, it is better to avoid assembler for software development.

    0 讨论(0)
  • 2020-12-13 03:15

    Assembly coding is a thing of the past for PCs, but is very relevant in embedded.

    Writing assembly in embedded is different than writing assembly on PCs. PC compilers are "better than humans" at generating optimized instructions. Embedded systems often have weird architectures, and their optimizing compilers are not nearly as mature as a PC optimizing compiler.

    0 讨论(0)
  • 2020-12-13 03:15

    There is one other time when writing in assembly may be necessary: if you need to do some low-level RAM test or similar, which requires absolute control over where data is being stored.

    For example, software which confirms to SIL-2 (Safety Integrity Level) and above may require continual checks on RAM, in order to detect any possible data corruption. The area of RAM you're checking can't be changing while it's being checked, and so writing the test in assembler allows you to ensure that this is true, for example by storing any local variables in specific registers or in another area of RAM. This would be difficult, if not impossible, in C.

    Startup code which zeroes the RAM and initialises non-zero static variables may also be written in assembler for the same written, though this sort of code is normally provided.

    0 讨论(0)
提交回复
热议问题