From: David Brown on
Bill Leary wrote:
> "Walter Banks" <walter(a)bytecraft.com> wrote in message
> news:480FAC36.E382E22B(a)bytecraft.com...
>>> Why would you bother optimising a traditional call to main into a jump?
>>
>> When C runs on embedded systems processors that are not hosted main
>> should never return.
>
> Usually, no. But it's a good idea to make sure the system does
> something reasonable if it does.
>

Why should the system do something reasonable if the programmer does
something unreasonable? In my gcc programs, main is tagged with a
"noreturn" attribute - attempting to return from main will produce at
least a warning message, possibly an error (I can't remember off-hand).
I'm sure Walter's compilers are able to enforce no return from main
equally well.
From: Chris H on
In message
<f9b88f12-3621-441c-ad80-1db7328f7621(a)b64g2000hsa.googlegroups.com>,
compton75(a)hotmail.com writes
>On Apr 22, 3:50�am, Lax <Lax.Cla...(a)gmail.com> wrote:
>> 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.)?
>
>Can't interface with with external hardware without assembly.
>
Not true... most embedded C compilers have extensions which permit this.
--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/



From: David Brown on
Paul Keinanen wrote:
> On Wed, 23 Apr 2008 08:26:59 -0400, Walter Banks
> <walter(a)bytecraft.com> wrote:
>
>
>> Chris H wrote:
>>
>>> 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.
>> 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
>
> While you might be able to write the startup code completely in C, but
> does this works with different optimization switches, with different
> compiler versions or even with different compilers ?
>

If it is written correctly, then for the most part the answer is yes.
But when you are dealing with such low-level coding, you should be
prepared at least to re-check the code when changing tools.

Although technically written in C, start-up code often contains C
statements that are just thin wrappers around assembly code, using
macros, inlined functions, intrinsics, and the like. The definitions of
these will often need modified for different compilers, but the usage of
these macros and inlines is mostly independent of the compiler.

> The ability to understand the generated assembly code will
> significantly help, if you have to move into a different environment.
>

The ability to understand the generated assembly code is *always* a good
thing in embedded development. It is particularly relevant during such
critical startup code (as well as in any time-critical parts of the code).

By writing startup routines in C rather than assembly, however, you
reduce your requirements to an understanding of assembly, rather than
the knowledge to write good assembly for the target. IIRC, I first
started using C for startup code when targeting a PPC processor. Until
you get used to it, it is hard to write good PPC assembly. Rather than
trying to figure out which addressing modes made sense, which registers
are used for which functions in the ABI, and so on, it was much easier
to write it in C and let the compiler figure out the details. My task
was then reduced to checking the generated assembly (and the not
insignificant task of figuring out how to get the chip's hardware
configured!).

From: Walter Banks on


CBFalconer wrote:

> Walter Banks wrote:
> >
> ... snip ...
> >
> > In our case the first C compiler was written for the C6805
> > and that was based on a 6805 mistral compiler we had written
> > a few years earlier. Our initial startup code was written
> > in C on a compiler that would support it.
> >
> > register_sp SP;
> >
> > SP = int_value;
>
> In other words you seized a user available identifier, register_sp,
> and then recognized that in the code to accept an int_value and
> initialize the stack pointer. This is not C, but an extension.
> The only thing wrong with that is that it is not marked as an
> extension. If the mechanism is also used to read the SP the above
> declaration should mark it as volatile. I think it would be better
> to use a name reserved for the implementation, such as
> __register_sp.
>
> I am not objecting to extensions. However I believe they should
> minimize any effects on standard C.

Force of habit. Both are actually supported in our compilers.
register_sp existed before the ISO naming rules __register_sp
was alludes after and register_sp was kept so old code
wouldn't break with updated compilers.

Your point is well taken, I should have used the proper current syntax.

w..


From: Walter Banks on


Mark Borgerson wrote:

> > register_sp SP;
> >
> > SP = int_value;
> >
> I must be using the wrong compilers! ;-)
>
> Imagecraft for the MSP430, IAR for the ARM, IAR for
> the MSP430 and Codewarrior for M68K systems all seem
> to use an assembly-language routine for initial setup.

Mark,

Actually Byte Craft compilers are a little more complex. The compiler
/ linker keeps track of the things that architecturally need to be
initialized and generates code for this after reset. This usually initializes
the stack from either default, declared values in the application or
linker information. There are other architectural dependent things
in some processor families like clock options default ISA's, memory
map tables. These choices are selected with application pragma's.

The function called __STARTUP if it exists in the application gets
executed as soon as the processor is stable but before the variables
are initialized. __STARTUP is used to support user initialization and
is the way many embedded products trap a maintenance startup
mode. (Maintenance modes are user defined often ground a output
pin when processor is reset, jump or call maintenance software
in the application)

__STARTUP is written like any C function. When it is called no
variables have been initialized so if it goes into a maintenance mode
the variables have their values pre-reset.

After __STARTUP returns the remaining compiler generated
initialization is executed and then there is a jump to main(..).

The compiler/linker in the simplest case just ties the reset vector
to main (default stack) in the most complex goes through the
steps outlined above.

Regards,

--
Walter Banks
Byte Craft Limited
Tel. (519) 888-6911
http://www.bytecraft.com
walter(a)bytecraft.com