Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing firmware: assembly or high level?

Tags:

Related to:

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

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?

Thanks

like image 556
cbrulak Avatar asked Jan 16 '09 21:01

cbrulak


People also ask

Is firmware written in assembly?

That is to say, firmware is typically written in a low level language (be it C or assembly), compiled and assembled into machine code, and placed in a known position on this storage, where the hardware, during its startup process can read from a known location, and begin executing that machine code.

Which programming language is used to write firmware?

Embedded Firmware Design LanguagesC/C++: C is something of a legacy language for embedded systems and tends to be preferred over C++. Hardware Description Languages (HDLs): The most popular are probably VHDL or Verilog. If you're programming an FPGA or designing an ASIC, use an HDL to define digital logic.

Can firmware be written in Python?

Yes, e.g.: Android is largely written in Java. Lots of robots are coded in Python based on ROS and OpenCV.

Is C used for firmware?

A simple embedded program in the C language, one of the most popular languages for writing embedded applications, is also included. In embedded firmware programming, the C language, and to a lesser extent C++, is widely used.

What language should be used to write firmware?

This approach allows pretty much ANY language to be used for writing firmware. But the framework itself still falls into the category 1. Use an interpreted language with interpreter or Virtual Machine (VM) which is written in the language of category 1 or 2.

What is assembly level language?

Assembly level language : It is a low-level language that allows users to write a program using alphanumeric mnemonic codes, instead of numeric code for a set of instructions examples of large assembly language programs from this time are IBM PC DOS. 2. High-level language : It is a machine-independent language.

What is a firmware?

Firmware is set of instruction or program written on non-volatile memory of hardware system. We can say Firmware is a term used for software in embedded systems. In firmware, the data will be read from memory written to memory. Mainly Assembly, C or C++ are used to write the firmware.

What is the most difficult part of firmware testing?

With firmware, often the most difficult bugs are timing related, and only show up once you are on the actual hardware. In the worst cases, the actual act of probing can alter timings such that the bugs won't appear - only in the "production" version. Then you have real fun.


2 Answers

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.

like image 107
Jason S Avatar answered Oct 06 '22 02:10

Jason S


Most microcontroller manufacturers provide some sort of cross-compiler where you can compile the code on your PC and then transfer it over to the microcontroller.

Why C?
An advantage of C is that your code will be easier to port to other microcontrollers in the future. The history of computing has shown that code typically outlasts hardware implementations.
A second advantage is control structures (if, for, while) that make code more readable and maintainable.

Why Assembly Language?
You can hand craft optimizations.

Verdict
As is often the case with this sort of question, the trade-offs are very dependent on the specific use.
Be aware that it is often possible to mix the two by making assembly calls within C code, so you can find a balance that is right for your project.

Specific to the PIC hardware
It seems that you don't have the option of GCC with most PIC hardware. On the other hand, as a commenter noted, the Microchip C30 compiler for the 16-bit PIC24 and dsPIC33 is gcc.
PIC is also not yet supported by SDCC.
New Info: according to a comment, SDCC has workable support for PIC.
There are some other open source options, but I don't have experience with them.

like image 32
John Mulder Avatar answered Oct 06 '22 01:10

John Mulder