- mixing C and assembly
- Posted by Lax on April 22nd, 2008
Are there any situations where programming an embedded processor
"requires" at least some assembly code?
How about for AVR, MSP430, 68HC11, 8051(Atmel)?
Can these 4 microcontrollers be programmed fully in C without touching
assembly (even interrupts and etc.)?
- Posted by Pertti Kellomäki on April 22nd, 2008
Lax wrote:
At least for AVR one can write pretty much everything using
gcc and avr-libc. However, while writing "cli();" in your C program
is not technically "touching assembly", it is not much different
from including the cli instruction as inline assembly. It is more
convenient, but still very much target dependent.
--
Pertti
- Posted by Piotr on April 22nd, 2008
Lax pisze:
IMO, generally it is possible, but sometimes C compiler doesn't
optimalize code such good as you want. In this case you can write it in
assembly language or change your approach to the problem.
--
Piotr Piwko
http://www.embedded-engineering.pl/
- Posted by Vladimir Vassilevsky on April 22nd, 2008
Lax wrote:
You have to resort to assembly in the two special cases:
1. The system level work like switching the contexts of the tasks, C
startup code, etc.
2. The parts of code where the performance is very critical.
Other then that, everything can be done in C.
Vladimir Vassilevsky
DSP and Mixed Signal Design Consultant
http://www.abvolt.com
- Posted by hectorhg on April 22nd, 2008
I think that it should be possible, although as it has been said,
compiler may not optimize your code properly, and you may have some lost o
performance. You may try the asm directive of C as a solution to avoi
writing a whole file in assembly code.
Good Luck!
- Posted by Grant Edwards on April 22nd, 2008
On 2008-04-22, Lax <Lax.Clarke@gmail.com> wrote:
Usually.
Yes.
Sometimes. It depends on the toolchain and on the job to be
done. Most toolchains provide C extensions to do things like
interrupts and access special hardware features. If those
extensions are sufficient for what you need to do, then you
don't need to write assembly code. If they aren't, then you do.
--
Grant Edwards grante Yow! ... or were you
at driving the PONTIAC that
visi.com HONKED at me in MIAMI last
Tuesday?
- Posted by Bill Leary on April 22nd, 2008
"Lax" <Lax.Clarke@gmail.com> wrote in message
news:2defcf6d-7dab-4699-9ce1-d433240398e4@m36g2000hse.googlegroups.com...
In every case where I've worked an embedded processor directly, I've had to
at least initialize the environment so it could run C. Basically, setup the
stack, clear RAM and jump to _main.
In cases where there's an OS on it already, and that has an applications
hook, then it could have been done with only C. In some cases, however,
it's been expedient to use some assembler.
I have no experience with the first two. For the last two, without an OS,
yes. With an OS, for the 68HC11 I did for expediency, but could have
avoided it, but for the 8051 I had to do some assembly. Perhaps selection
of a different OS or development package would have made it possible to
avoid assembler.
- Bill
- Posted by linnix on April 22nd, 2008
On Apr 22, 9:51 am, "Bill Leary" <Bill_Le...@msn.com> wrote:
There are always assembly involved somewhere, but you don't have to
write them. Why are you re-inventing run-time libraries?
Yes for AVR, you can interrupt, sleep, powerdown and change clock
speeds in C. The only assembly I have used is to load flash codes
into data space, for which there is no C equivalent.
- Posted by Walter Banks on April 22nd, 2008
Vladimir Vassilevsky wrote:
Vladimir,
In your second point I would qualify it to parts of code
requiring exact timing on anything that we have released
recently that seems to be the only limitation.
Regards,
--
Walter Banks
Byte Craft Limited
Tel. (519) 888-6911
http://www.bytecraft.com
walter@bytecraft.com
- Posted by Grant Edwards on April 22nd, 2008
On 2008-04-22, Bill Leary <Bill_Leary@msn.com> wrote:
For processors without an external bus (IOW they have a fixed
memory map), many toolchains will provide startup code that
does all that. That's certainly true for GCC on the Atmel AVR
and TI MSP430: tell the compiler which part you're using, and
you don't have to write a lick of startup code.
--
Grant Edwards grante Yow! Did something bad
at happen or am I in a
visi.com drive-in movie??
- Posted by Hans-Bernhard Bröker on April 22nd, 2008
Lax wrote:
Yes. Somebody, somewhere, some time, will have to write some assembly
code. Startup code, low-level support routines for the C compiler, task
switching support, ... that kind of thing.
It depends on just about every partner in the process (from chip
designer to application customer) whether "somebody" includes you, the
embedded software engineer.
That depends entirely on what one still considers to be "in" C, and how
the tool makers chose to handle those features of an embedded controller
that strictly pure standard C can't handle. E.g., ISRs could be mapped
to the signal() mechanism of standard C. But hardly anyone ever
actually does that. Instead, there are compiler extensions or assembly
wrappers that link C functions to interrupts.
- Posted by Neil on April 23rd, 2008
Walter Banks wrote:
- Posted by Neil on April 23rd, 2008
Lax wrote:
MAYBE
For many applications using small CPUs you do not need any ASM. There
are situations where you do need it. Your code may vary.
Of the above I have used Keil 8051 C compiler. Many general apps did
not need ASM.
- Posted by Chris H on April 23rd, 2008
In message <fulm9l$r16$02$1@news.t-online.com>, Hans-Bernhard Bröker
<HBBroeker@t-online.de> writes
I agree... if you go to comp.lang.c you will find that Gcc is NOT C...
it is a "C like language" as it is not a full C implementation and has
Gcc extensions quite apart from extensions for the target
Also most compilers for embedded targets have many "assembler like"
extensions eg where you can put hex directly into registers and
peripherals. The "C" function to set up the UART on an 8051 with a Keil
compiler looks almost the same as assembler!
As has already been mentioned the start up code has to be in assembler
as it sets up the memory for the stack etc however if you use the
standard one that comes with the compiler you will never need to see it.
It is usually automatically pulled in as an object file.
That said you can program most of these micros in pure C with no
extensions (compiler or targets) BUT it is usually very inefficient code
and no one is likely to employ you if you do that.
--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
- Posted by David Brown on April 23rd, 2008
Chris H wrote:
gcc supports at least as high a proportion of C99 as the great majority
of commercial compilers, and I don't know off-hand of any pre-C99
language issues. Just like all commercial compilers I am familiar with
(I've used a few over the years), gcc has extensions which can be
enabled or disabled. Some of these extensions are target-specific (such
as for interrupt handling), others are target-independent (such as
allowing certain C++ constructs in C, and vice-versa).
Since gcc has barely been mentioned in this thread, you must have good
reason for bringing it up - surely it was not merely for gratuitous and
unsubstantiated bashing (and surely it was not trolling for my reply, to
re-establish our relationship after too many recent agreements :-)
Since you hang out gcc for not being "a full C implementation", and for
having "extensions quite apart from extensions for the target", can you
give me some examples of other available compilers that *are* "full C
implementations" (along with an explanation of exactly what you mean by
that phrase), which have *no* compiler extensions, and which are
targeted at embedded systems?
Beyond the obsessive gcc-bashing, I pretty much agree with your post.
Embedded toolchains are pretty much useless unless you can get low-level
access beyond what can be written in standard C with standard libraries,
so there are normally either extensions to the compiler, or extra
library functions (often just wrappers around embedded assembly).
Although the compiler and its libraries will often handle this sort of
thing, it is sometimes useful to write it yourself. Sometimes you want
to use different memory layouts from the standard ones, and sometimes
you need board-specific low-level code at the start. For example, I
have a card with external sdram - I needed to initialise the sdram
before copying the program over from flash to sdram and running it
there. I also have two separate sets of .bss and .data - one in the
sdram, and one in fast internal ram. So I had a specific startup
routine to handle that copying.
Depending on your tools, however, this sort of thing can often be
written in C - even though your real C environment is not yet ready (for
example, initialised data are not yet initialised, and for C++ your
global objects are not yet constructed). I find that my assembly can
often be reduced to two or three op-codes at the very start (if the
toolchains standard startup code is not suitable), along with some
embedded assembly macros or function wrappers for things like interrupt
control, or accessing cpu-space registers on some targets.
You usually need to use your compiler's target extensions (for
interrupts, if nothing else), unless you have a ready-made OS layer that
handles that sort of thing for you.
For "general" C programming, it is rare that you can write significantly
smaller or faster code using assembly than a good compiler will
generate. This is especially true for big processors where manually
tracking things like register allocations, pipelining, and instruction
overlap will drive you up the wall - the compiler does this quickly and
easily, and thus will generate better code than all but the most
dedicated assembly programmers. Similarly, for very small and limited
cpus, modern compilers can optimise things like bank switching and data
placement better than a human can while still writing legible and
maintainable code.
Compilers often have other extensions which *can* make a big difference,
however. Extensions giving hints to the compiler ("inline" is often
available as an extension when compiling for older C standards) can make
the generated code smaller and/or faster. Extensions for source code,
such as unnamed structs and unions, or flexible array types, can lead to
clearer and neater source code. Obviously you must be aware of when
such extensions make your code non-portable between targets and/or
compilers - it's a tradeoff you have to evaluate.
The one place where compiler assembly-like extensions and/or real
assembly can make a big difference is for dsp programming. Compilers
are getting better at turning C loops into optimal dsp code, but in many
cases you have to write something horrendous involving all sorts of
compiler/target-specific pseudo-functions to end up with optimal
assembly - writing in pure assembly is often clearer and neater.
- Posted by Walter Banks on April 23rd, 2008
Neil wrote:
Our startup code is in C.
w..
- Posted by Walter Banks on April 23rd, 2008
Chris H wrote:
There is no requirement for the start up code to be in asm. A lot of
compilers come with asm sample startup but the code could have
been written in C in the same compiler. The same extensions that
support embedded systems make this possible
Regards,
--
Walter Banks
Byte Craft Limited
Tel. (519) 888-6911
http://www.bytecraft.com
walter@bytecraft.com
- Posted by Walter Banks on April 23rd, 2008
David Brown wrote:
In the area of DSP the single biggest change has been IEC/ISO 18037
which made it a lot easier to express DSP algorithms in C without
using obscure syntax. The C source quickly became a lot easier to
port between architectures. The biggest difference was clear way to
simply express the data structure of the target processor. At the
instruction level the compiler was responsible for mapping the C
on the processors mac instructions.
Porting went from needing to rewrite the asm code for each target to
changing declarations describing the data struct with a minor
amount of tweaking.
There are other things in this C extension as well that normalized the
definitions of fract and accum data types which cleaned up a way to
represent data for DSP applications.
Regards,
--
Walter Banks
Byte Craft Limited
Tel. (519) 888-6911
http://www.bytecraft.com
walter@bytecraft.com
- Posted by David Brown on April 23rd, 2008
Walter Banks wrote:
Once support fract/accum/sat becomes common in C compilers, then it will
certainly make it easier to write legible, portable code working with
scaled fractional integers. I seriously doubt that it will entirely
remove the need for extensions and intrinsics to get optimal code from
powerful DSPs, but it will certainly be a solid step in the right
direction and will let you write close to optimal code for everything
but the tightest of inner loops.
mvh.,
David
- Posted by Mark Borgerson on April 23rd, 2008
In article <480F2B12.69B62031@bytecraft.com>, walter@bytecraft.com
says...
stack pointer in C?
Mark Borgerson