EmbeddedRelated.com
Forums

Need startup file for LPC176x with GNUARM,FreeRTOS

Started by prab...@yahoo.co.in March 12, 2010
--- In l..., "rtstofer" wrote:
> Besides the vectors, there is still the requirement to initialize the C enviorment: initialize .data, clear .bss, run the constructors (if any) and so on. About the only difference I see is that there are a lot more vectors. Other than that, it's the same as the ARM7.
>
> It would take some pretty clever C code to initialize the .data segment. I suppose it could be done but I'm glad it isn't! A wee bit of assembly language just isn't that big of a deal.
>
> Richard
>

Hi Richard

I am not against assembler (it is of course always useful - whether in its own file(s) or in in-line code - in a pre-emptive OS some parts for the Kernel will probably have no choice; although I do have a book which shows how to write a pre-emptive OS with pure C++ code...). I certainly wouldn't know how to do these in C:
asm("cpsid i")
asm("cpsie i")
asm("wfi")

I suppose constructors are needed when working with C++. When not, the standard GCC initialisation looks something like:
extern unsigned char __data_start__, __data_end__;
extern const unsigned char __data_load_start__;
extern unsigned char __text_start__, __text_end__;
extern const unsigned char __text_load_start__;
extern unsigned char __bss_start__, __bss_end__;

extern void __init_gnu_data(void)
{
unsigned char *ptrData;
unsigned long ulInitDataLength;
#ifndef _RAM_DEBUG
const unsigned char *ptrFlash = &__data_load_start__;
ulInitDataLength = (&__data_end__ - &__data_start__);
ptrData = &__data_start__;
while (ulInitDataLength--) { // initialise data
*ptrData++ = *ptrFlash++;
}

ptrData = &__text_start__;
ptrFlash = &__text_load_start__;
if (ptrFlash != ptrData) { // if a move is required
ulInitDataLength = (&__text_end__ - &__text_start__);
while (ulInitDataLength--) { // initialise text
*ptrData++ = *ptrFlash++;
}
}
#endif
ptrData = &__bss_start__;
ulInitDataLength = (&__bss_end__ - &__bss_start__);
while (ulInitDataLength--) { // initialise bss
*ptrData++ = 0;
}
}
IAR tends to have "intrinsics" which do things that would other require a bit of in-line assembler (eg. __disable_interrupt(), __enable_interrupt and __sleep_mode() for the above). In addition, it has its own secretive method of initialising variables which is best left to it by calling __segment_init(). How Keil does it, based on region tables, is also a good reason to just use their start-up code rather than poking in a hornet's nest...

Note also that uVision3 didn't support in-line assembly for the Cortex M3 the last time I tried so here I had no choice but to add an assembler file to the project;-/
Regards

Mark

An Engineer's Guide to the LPC2100 Series

--- In l..., FreeRTOS Info wrote:
> As far as I know - ARM themselves don't use this feature and instead
> provide assembly startup code.

Hi Richard

You have hit the nail on the head... the point is not really that it is that important to avoid assembler code. It is that you will often see the statement "doesn't need any assembler code" on presentations from Cortex M3 chip manufacturers (as a marketing argument as to how much improved it is) but the same chip manufacturers will give you their start-up code in assembler, as will ARM.

When I started with the Cortex M3 in about 1997 I visited a Luminary Micro workshop which was accompanied by ARM people. First there was a presentation of ARM as a company and a comparison between ARM7 and Cortex M3 - one advantage being "no assembler code needed" appearing high up on the slides. Then Luminary did their presentation - again the slides showed the benefit - "doesn't need any assembler code". The next part looked at some examples - written in assembler code of course....

Just do a search at Luminary or NXP web sites (these are the only two Cortex M3 families I use at the moment so I don't know about the others) - or look at the original Cortex M3 white paper from Shyam Sadasivan (http://www.arm.com/files/pdf/IntroToCortex-M3.pdf) Quotes: "Cortex M3 processor removes the need to write assembler wrappers..." ".. with developers not required to write any assembler code..." ", and that start-up code is now significantly simplified as no assembler code register manipulation is required." ", removing the need for the assembler and enabling the developer to program just in C ...". They are full of praises for this 'significant' advantage.

Myself, I never actually ever saw the difference to an 68000 and don't think I ever saw any code which bothered much about it either.

Strange business the marketing side of software programming,...;-)
Regards

Mark

Hi all,
Thanks for all your detail information.

As per my understanding,i am using following code(Refered from freeRTOS Demo

project,\FreeRTOS5.4.0\Demo\CORTEX_LPC1768_GCC_RedSuite)

__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) {
// Core Level - CM3
(void *)&_vStackTop,/* The initial stack pointer._vStackTop initialized

from ld script.*/
Reset_Handler,
.
.
.
}

At power up,(start execute at flash address 0)
This above code will initialize the stack of my application.Then
Reset handler will initialize data section,bss using assembly code.
From Reset handler,main function will be call.Then application create task etc.

If i set optimization off also,my code will not crash.Because i initialized
stack pointer in above code(&_vStackTop) using __attribute__

((section(".isr_vector"))).This will start code from address 0(flash).which means
first instruction will initialize the stack.

Please let me know if i am wrong???Please guide me.

Thanks,

________________________________
From: mjbcswitzerland
To: l...
Sent: Sat, 13 March, 2010 2:46:09 AM
Subject: [lpc2000] Re: Need startup file for LPC176x with GNUARM,FreeRTOS

--- In lpc2000@yahoogroups .com, FreeRTOS Info wrote:
> As far as I know - ARM themselves don't use this feature and instead
> provide assembly startup code.

Hi Richard

You have hit the nail on the head... the point is not really that it is that important to avoid assembler code. It is that you will often see the statement "doesn't need any assembler code" on presentations from Cortex M3 chip manufacturers (as a marketing argument as to how much improved it is) but the same chip manufacturers will give you their start-up code in assembler, as will ARM.

When I started with the Cortex M3 in about 1997 I visited a Luminary Micro workshop which was accompanied by ARM people. First there was a presentation of ARM as a company and a comparison between ARM7 and Cortex M3 - one advantage being "no assembler code needed" appearing high up on the slides. Then Luminary did their presentation - again the slides showed the benefit - "doesn't need any assembler code". The next part looked at some examples - written in assembler code of course....

Just do a search at Luminary or NXP web sites (these are the only two Cortex M3 families I use at the moment so I don't know about the others) - or look at the original Cortex M3 white paper from Shyam Sadasivan (http://www.arm. com/files/ pdf/IntroToCorte x-M3.pdf) Quotes: "Cortex M3 processor removes the need to write assembler wrappers..." ".. with developers not required to write any assembler code..." ", and that start-up code is now significantly simplified as no assembler code register manipulation is required." ", removing the need for the assembler and enabling the developer to program just in C ...". They are full of praises for this 'significant' advantage.

Myself, I never actually ever saw the difference to an 68000 and don't think I ever saw any code which bothered much about it either.

Strange business the marketing side of software programming, ...;-)

Regards

Mark

Your Mail works best with the New Yahoo Optimized IE8. Get it NOW! http://downloads.yahoo.com/in/internetexplorer/
On Sat, Mar 13, 2010 at 5:16 AM, mjbcswitzerland wrote:
>
> When I started with the Cortex M3 in about 1997 I visited a Luminary
> Micro workshop which was accompanied by ARM people.

Wow 1997 and Cortex M3. So you are traveling faster than Light. ;-)

--
Xiaofan http://mcuee.blogspot.com
> > When I started with the Cortex M3 in about 1997 I visited a Luminary
> > Micro workshop which was accompanied by ARM people.
>
> Wow 1997 and Cortex M3. So you are traveling faster than Light. ;-)

Yes, it was all very advanced information at the time and the Luminary people were still working at ARM. I did often wonder why it took them another 9 years to actually get the first chip out...

Regards

Mark

..of course it may also have been a type....;-)

--- In l..., Xiaofan Chen wrote:
> >
> > When I started with the Cortex M3 in about 1997 I visited a Luminary
> > Micro workshop which was accompanied by ARM people.
>
> Wow 1997 and Cortex M3. So you are traveling faster than Light. ;-)
>
> --
> Xiaofan http://mcuee.blogspot.com
>

Yes, everything was very advanced information at the time and the Luminary people were still all working for ARM. I always wondered why it took them another 9 years to get the first chips out...

Regards

Mark

...or maybe typo ;-)

On 12/03/2010 20:48, FreeRTOS Info wrote:
> //
> // Zero fill the bss segment. This is done with inline assembly
> since this
> // will clear the value of pulDest if it is not kept in a register.
> //
>
> followed by a small amount of inline assembly to do the zeroing. 9
> lines total. In-lining assembly in that way is really easy with GCC,
> but less easy with other tool chains.

Late to the party, but I have to add that this is not necessary. Those
variables are stored either on the stack or in registers. The only
reason a C loop would wipe the stack is if the stack is being located in
the .bss segment.

This is happening here because someone tried to be clever and used an
uninitialised global array as the stack pointer. Nice idea in theory,
but I much prefer to have the stack at the top of memory. Specifying
this address manually at the start of the table removes any need for
inline assembly in the reset function (but doesn't zero the stack, if
you're into that sort of thing).

Of course, you still need to locate that table at the start of flash so
you will require some non-portable 'attributes' in there, I suppose.
Although I guess you could put it in a separate file and take care of
positioning it entirely in the linker script...

Pete
--- In l..., Pete Vidler wrote:
> you will require some non-portable 'attributes' in there, I suppose.
> Pete
>

Yes such things are a bit of a nuisance. The follow attempts to make the non-portable code behave:
#if defined COMPILE_IAR5
__root const VECTOR_TABLE __vector_table @ ".intvec" // __root forces the function to be linked in IAR5 project
#elif defined COMPILE_IAR
__root const VECTOR_TABLE reset_vect @ "RESETVECT" // __root forces the function to be linked in IAR4 project
#elif defined _GNU
const VECTOR_TABLE __attribute__((section(".vectors"))) reset_vect
#elif defined _COMPILE_KEIL
__attribute__((section("RESET"))) const VECTOR_TABLE reset_vect
#else
const VECTOR_TABLE reset_vect
#endif
= {...};

This does it for IAR4/5, Keil and GCC whereby the an IDE define is used to distinguish. The final, default case, is used when working with a simulator which need to fixed location.

Regards

Mark

http://www.uTasker.com

Anyone please confirm my understanding is correct.If not,please guide me?

Thanks for all supports.

________________________________
From: pra bu
To: l...
Sent: Mon, 15 March, 2010 6:06:44 PM
Subject: Re: [lpc2000] Re: Need startup file for LPC176x with GNUARM,FreeRTOS

Hi all,
Thanks for all your detail information.

As per my understanding, i am using following code(Refered from freeRTOS Demo

project,\FreeRTOS5. 4.0\Demo\ CORTEX_LPC1768_ GCC_RedSuite)

__attribute_ _ ((section(". isr_vector" )))
void (* const g_pfnVectors[ ])(void) {
// Core Level - CM3
(void *)&_vStackTop,/ * The initial stack pointer._vStackTop initialized

from ld script.*/
Reset_Handler,
.
.
.
}

At power up,(start execute at flash address 0)
This above code will initialize the stack of my application. Then
Reset handler will initialize data section,bss using assembly code.
From Reset handler,main function will be call.Then application create task etc.

If i set optimization off also,my code will not crash.Because i initialized
stack pointer in above code(&_vStackTop) using __attribute_ _

((section(". isr_vector" ))).This will start code from address 0(flash).which means
first instruction will initialize the stack.

Please let me know if i am wrong???Please guide me.

Thanks,

________________________________
From: mjbcswitzerland
To: lpc2000@yahoogroups .com
Sent: Sat, 13 March, 2010 2:46:09 AM
Subject: [lpc2000] Re: Need startup file for LPC176x with GNUARM,FreeRTOS

--- In lpc2000@yahoogroups .com, FreeRTOS Info wrote:
> As far as I know - ARM themselves don't use this feature and instead
> provide assembly startup code.

Hi Richard

You have hit the nail on the head... the point is not really that it is that important to avoid assembler code. It is that you will often see the statement "doesn't need any assembler code" on presentations from Cortex M3 chip manufacturers (as a marketing argument as to how much improved it is) but the same chip manufacturers will give you their start-up code in assembler, as will ARM.

When I started with the Cortex M3 in about 1997 I visited a Luminary Micro workshop which was accompanied by ARM people. First there was a presentation of ARM as a company and a comparison between ARM7 and Cortex M3 - one advantage being "no assembler code needed" appearing high up on the slides. Then Luminary did their presentation - again the slides showed the benefit - "doesn't need any assembler code". The next part looked at some examples - written in assembler code of course....

Just do a search at Luminary or NXP web sites (these are the only two Cortex M3 families I use at the moment so I don't know about the others) - or look at the original Cortex M3 white paper from Shyam Sadasivan (http://www.arm. com/files/ pdf/IntroToCorte x-M3.pdf) Quotes: "Cortex M3 processor removes the need to write assembler wrappers..." ".. with developers not required to write any assembler code..." ", and that start-up code is now significantly simplified as no assembler code register manipulation is required." ", removing the need for the assembler and enabling the developer to program just in C ...". They are full of praises for this 'significant' advantage.

Myself, I never actually ever saw the difference to an 68000 and don't think I ever saw any code which bothered much about it either.

Strange business the marketing side of software programming, ...;-)

Regards

Mark
________________________________
Your Mail works best with the New Yahoo Optimized IE8. Get it NOW!.

The INTERNET now has a personality. YOURS! See your Yahoo! Homepage. http://in.yahoo.com/
On 15/03/2010 19:36, Mark wrote:
> This does it for IAR4/5, Keil and GCC whereby the an IDE define is used
> to distinguish. The final, default case, is used when working with a
> simulator which need to fixed location.

Binutils and (I suspect) most linkers can specify a segment based on the
object filename. If you put the vector table in a completely separate
source file from anything else, you might just be able to do it all in
the linker scripts without any attributes...

Of course, it would take a seriously pressing need for portability
before I bothered doing that (too brittle -- someone might change the
file and make a hard-to-debug mess of it). I'm almost always using GCC
these days, so I would just go with a #define for my attribute needs and
add your approach if needed later.

Pete