[ACCEPTED]-Writing firmware: assembly or high level?-firmware
Several comments:
1) Absolutely not assembly 80 unless performance or optimization constraints 79 warrant it. The following metrics go through 78 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 77 would be C++ rather than C for its namespace 76 encapsulation & its facilitation of 75 compile-time object-oriented practices. C has too many 74 opportunities for global variables and namespace 73 collisions. (Real-time Java would be nice 72 but from what I understand its requirements 71 are still pretty high)
Or rather a subset 70 of C++: Exclude exceptions, virtual functions, run-time 69 type identification, also dynamic memory 68 allocation in most cases -- basically anything 67 that's left unspecified at compile time, as 66 it will usually require a lot of extra resources 65 during runtime. That's the "bloat" of 64 C++.
I have used both TI's and IAR's compilers 63 for C++, for the TMS320 and MSP430 microcontrollers 62 (respectively) and with proper optimization 61 settings, they do a fantastic job of reducing 60 the overhead you might expect from C++. (Especially 59 if you help it out by judicious use of the 58 inline
keyword)
I have even used templates for 57 some of their compile-time benefits which 56 promote good code reuse: e.g. writing a 55 single source code file to handle 8-bit, 16-bit, and 54 32-bit CRCs; and compile-time polymorphism to allow you to specify 53 the usual behavior of a class, and then 52 reuse that but override some of its functions. Again, the 51 TI compiler had an extremely low overhead 50 with appropriate optimization settings.
I 49 have been looking for a C++ compiler for 48 the Microchip PICs; the only company I've 47 found that produces one is IAR. ($$$ has 46 been an obstacle but I hope to buy a copy 45 sometime) The Microchip C18/C30 compilers 44 are pretty good but they're C, not C++.
3) A 43 specific caveat about compiler optimization: it 42 can/will make debugging very difficult; often 41 it's impossible to single-step through optimized 40 C/C++ code and your watch windows may show 39 variables that have no correlation with 38 what you think they should contain with 37 unoptimized code. (A good debugger would 36 warn you that a particular variable has 35 been optimized out of existence or into 34 a register rather than a memory location. Many 33 debuggers do not. >:(
Also a good compiler 32 would let you pick/choose optimization at 31 the function level through #pragmas. The 30 ones I've used only let you specify optimization 29 at the file level.
4) Interfacing C code 28 to assembly: This is usually difficult. The 27 easiest way is to make a stub function that 26 has the signature you want e.g. uint16_t foo(uint16_t a, uint32_t b) {return 0; }
, where 25 uint16_t
= unsigned short, we usually make the # of 24 bits explicit. Then compile it and edit 23 the assembly it produces (just make sure 22 to leave the begin/exit parts of the code) and 21 be careful not to clobber any registers without restoring 20 them after you are done.
Inline assembly 19 usually can have problems unless you are 18 doing something very simple like enabling/disabling 17 interrupts.
The approach I like best is compiler 16 intrinsics / "extended ASM" syntax. Microchip's 15 C compiler is based on the GNU C compiler 14 and it has "extended ASM" which lets you code 13 bits of inline assembly but you can give 12 it lots of hints to tell it which registers/variables 11 you are referencing and it will handle all 10 the saving/restoring of registers to make 9 sure your assembly code "plays nice" with 8 C. TI's compiler for the TMS320 DSP doesn't 7 support these; it does have a limited set 6 of intrinsics which have some use.
I've used 5 assembly to optimize some control loop code 4 that got executed frequently, or to calculate 3 sin(), cos(), and arctan(). But otherwise 2 I'd stay away from assembly and stick with 1 a high-level language.
Most microcontroller manufacturers provide 23 some sort of cross-compiler where you can 22 compile the code on your PC and then transfer 21 it over to the microcontroller.
Why C?
An advantage 20 of C is that your code will be easier to 19 port to other microcontrollers in the future. The 18 history of computing has shown that code 17 typically outlasts hardware implementations.
A 16 second advantage is control structures (if, for, while) that 15 make code more readable and maintainable.
Why Assembly Language?
You 14 can hand craft optimizations.
Verdict
As is often 13 the case with this sort of question, the 12 trade-offs are very dependent on the specific 11 use.
Be aware that it is often possible 10 to mix the two by making assembly calls 9 within C code, so you can find a balance 8 that is right for your project.
Specific to the PIC hardware
It seems that 7 you don't have the option of GCC with most 6 PIC hardware. On the other hand, as a commenter 5 noted, the Microchip C30 compiler for the 4 16-bit PIC24 and dsPIC33 is gcc.
PIC is 3 also not yet supported by SDCC.
New Info: according to a comment, SDCC has workable support for PIC.
There are some 2 other open source options, but I don't have experience 1 with them.
Best option is probably to code in C, and 4 then for the very few instances where you 3 need to hand optimize and can do a better 2 job than the compiler, you should code the 1 assembly into your c files.
Assembly coding is a thing of the past for 7 PCs, but is very relevant in embedded.
Writing 6 assembly in embedded is different than writing 5 assembly on PCs. PC compilers are "better 4 than humans" at generating optimized instructions. Embedded 3 systems often have weird architectures, and 2 their optimizing compilers are not nearly 1 as mature as a PC optimizing compiler.
One issue I ran into with writing assembly 6 for a microcontroller is the need to be 5 very careful how your code was laid out. Having 4 a jump table cross memory boundaries, and 3 causing your code to jump to really weird 2 places is rather disturbing. Coding in C, the 1 compiler covers that base for you.
I would definitely go with C. It is faster 6 and it creates more reliable software. Assembly 5 has very little to offer and in scarce occasions. Have 4 in mind that in C:
- You would be able to easily port code from existing platforms, even from PCs.
- You can develop in a high level language without compromising execution speed or code size. Provided that a quality compiler is available (there are many choices for PIC18), these would be most probably be better with C than hand crafted assembly.
- It is much easier to debug, test and maintain the code. C produces more reliable code.
Another thing that specifically 3 has to do with PIC18. You won't have to 2 deal with the non-intuitive PIC architecture 1 and things like memory BANKs.
I've had good experience with IAR C compilers 7 for 8051's in the past.
My recent approach 6 has always been this:-
Write it in C with 5 a good optimizing compiler, and ONLY THEN 4 if there's a problem with size or speed, consider 3 rewriting certain parts in assembler.
However, since 2 taking this approach I've never needed to write 1 a single line of assembler...
Go for c !
I've worked for a large CE manufacturer. The 10 last time I saw assembly was there was around 9 1996 in some small interrupt services routines 8 for RC5 and RC6 decoding and TV tuning algorithms. After 7 that always used c, and C++ (only used classes, no 6 stl, exceptions or rtti). I have good experiences 5 with the old KEIL compiler for 8051 and 4 with greenhills compiler (MIPS) and the 3 VxWorks toolset (PowerPC based).
As Roddy 2 says, first write in C , and optimize in 1 assembly later (if needed).
Assembly can in many cases be faster; when 7 you're on a desktop, the compilers tend 6 to be optimized to the point that hand assembly 5 is rarely a necessity, but in the uC world, it 4 often is. Also, if you need to write interrupt 3 handling routines and things like that, you 2 often can't do it in C.
As for compilation, google 1 around for a C compiler for your target.
Definitely C, except when
program memory 8 is extremely limited. Say after painstaking 7 hand-optimizing your assembler code you 6 manage to fit your program in this 1024 5 bytes of Flash, with 0 bytes left. In this 4 case no C compiler will be any good.
you 3 want to have absolute timing control. If 2 any amount of interrupt latency is too long 1 you'll have to rely on assembler.
The problem these days is that embedded 31 can be anything from an ATTiny with 6 pins 30 and a few bytes of RAM to a multi-core SBC 29 running an embedded OS that would put some 28 people's desktop computers to shame.
As such, the 27 choice of langauge / development environment 26 needs to take into account how efficient 25 you need to be vs how complex the system 24 is.
First off - C works everywhere and scales 23 pretty well, the higher you go the more 22 you'll end up calling external libraries 21 etc. to handle the complexity.
For very small 20 micros (measuring flash/ram in bytes) you 19 are best off using ASM, when you get up 18 to the kb range, C or any of the other traditional 17 languages can be used as you don't need 16 to count every byte. Once you have megabytes 15 to play with you have both the ability and 14 increasingly likely the requirement to use 13 an RTOS to take care of everything and cut 12 down development time. By the time you have 11 hardware you could run a full blown OS on 10 you can probably abstract yourself from 9 the hardware and just write everything in 8 a padded cell like Java or somesuch without 7 worrying too much about how terribly wasteful 6 it all is and how you're not a real programmer 5 anymore... ;)
The exception to the above 4 is when you need all the performance you 3 can wring out of the hardware, at which 2 point you may need to drop down a level 1 or two to keep things efficient.
That is the bottom line if you use C you 34 can hand optimize later, I wouldnt use anything 33 other than C or assembler (no C++, etc).
The 32 key is the microcontroller instruction set 31 if you are using a PIC or even an 8051 I 30 would use assembler only. If it is a compiler 29 friendly isa like arm or avr or msp430 then 28 use C to save some typing but you will probably 27 have some routines in assembler for various 26 reasons. Likewise you probably want to 25 avoid a C library, even newlib can be just 24 too bulky, borrow code or ideas from them 23 but dont just link one in. Oh, back to 22 the question, look at what C compilers are 21 available for the target, again arm and 20 avr you wont have any problems. Likely 19 msp is okay as well. Just because Keil 18 or Iar will SELL you a compiler doesnt mean 17 you should buy it or use it, the output 16 of pay for as well as free compilers can 15 be dreadful. You need to be well versed 14 in the asm anyway and examine the output 13 (you probably have to write a disassembler 12 to do this).
Bottom line (another bottom 11 line), there is no global answer (well avoid 10 anyhthing higher than C is a global answer) it 9 always depends on what the platform is what 8 your resources are what your task is what 7 the performance requirements are what the 6 portability requirements are (if it is truly 5 embedded on a microcontroller much of it 4 is by definition not portable) what compilers, debuggers, jtag, etc 3 are availble, even so far as what host operating 2 system are you developing on can be a big 1 factor.
There is one other time when writing in 18 assembly may be necessary: if you need to 17 do some low-level RAM test or similar, which 16 requires absolute control over where data 15 is being stored.
For example, software which 14 confirms to SIL-2 (Safety Integrity Level) and 13 above may require continual checks on RAM, in 12 order to detect any possible data corruption. The 11 area of RAM you're checking can't be changing 10 while it's being checked, and so writing 9 the test in assembler allows you to ensure 8 that this is true, for example by storing 7 any local variables in specific registers 6 or in another area of RAM. This would be 5 difficult, if not impossible, in C.
Startup 4 code which zeroes the RAM and initialises 3 non-zero static variables may also be written 2 in assembler for the same written, though 1 this sort of code is normally provided.
If you're writing code that is highly dependent 10 on device-specific peripherals, and the 9 tool chain you're using doesn't provide 8 the necessary intrinsics to utilize them 7 efficiently (like the crappy Freescale DSP563CC 6 compiler), then use assembly.
Besides that, I 5 think the unwritten rules of using assembly 4 vs. a high-level language are more or less 3 the same as those for desktop software development: keep 2 the code clean, maintainable, and optimize 1 hot code with machine language.
Code in assembler language are really fast 10 with small footprint, but code written in 9 assembler language are not reusable code. This 8 reusibility feature for code are most important 7 feature for software design. For example, if 6 you have assembler project code for x86 5 processor, it can be use only for x86 processor, not 4 for ARM processor. But if you have project 3 C/C++ code for x86 processor, you can use 2 this code for ARM processor. So, it is 1 better to avoid assembler for software development.
It is too bad no one has mentioned Forth 3 or Scheme so far. Both can be appropriate 2 for small environments, and can give impressive 1 productivity gains.
Plain C or Pascal, Modula2. But due to compiler 12 availability that means C.
The extra's of 11 C++ and similars are only interesting out 10 of style grounds, since dynamic allocation 9 and program size is usually very limited.
Also 8 a more complicated runtime can be a pain 7 if your apps get tight.
Assembler can be 6 useful too, but only if you sell really 5 gigantic quantities, and a smaller firmware 4 means a smaller, cheaper chip (less flash) and 3 the program's size is overseeable (read: there 2 is some chance that you will get it bugfree 1 in time)
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.