EmbeddedRelated.com
Forums

Defining code location in memory

Started by "faro.salvatore" January 18, 2010
First of all thanks to anyone that can shed some light to my questions...

I'm writing a bootloader and have a few doubts on how to proceed in some simple things:

1) What is the best way to put a jump from the bootloader to the main application using c code? Or should I embed asm code with a jmp instruction to do this??

2) How do I instruct my compiler (Rowley Crossworks) to compile my code at an address that I define, for example I could compile my bootloader at address 0xe000 and my main application code at 0x1100... This leads me to another curiosity, is it possible to instruct the compiler as to the memory location to use for a particular function?

Thanks.

Beginning Microcontrollers with the MSP430

Paul
Isn't SLAA341 on the TI web site?

-Bill Knight
R O SoftWare
Paul Curtis wrote:
>
>
> > make a search on the motorola site
> > with the key word
> >
> > "slaa341_Flash_monitor"
>
> Curveball! :-)
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
>
> CrossWorks V2 is out for LPC1700, LPC3100, LPC3200, SAM9, and more!

> Paul
> Isn't SLAA341 on the TI web site?

Might be, but hey, those Motorolanites may have snatched it whilst we were
distracted...

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks V2 is out for LPC1700, LPC3100, LPC3200, SAM9, and more!

I'm not sure that this is the BEST way, but we have this function for jumping to code from our bootloader.

/*****************************************************************************/
/** @brief Call a function at a passed in address
*
* @param[in] uint16 func_addr. Address of function to call.
*
* @par
* Create a function pointer which points to the address passed
* in as a parameter. Call the function.
*
* @warning This function will \b not return! It is meant to pass control of the
* processor to another application!
******************************************************************************/
void call_func_addr(uint16_t func_addr)
{
void(*funcPtr)(void);
funcPtr = (void(*)(void))func_addr;
(*funcPtr)();
}

Then something like this:
#define AUTO_APP_ADDR ((uint16_t *) 0x10FE) // Application start address is stored here

call_func_addr(*AUTO_APP_ADDR); // Jump to the app

We did this so we can arbitrarily move the application address without changing the bootloader. We just had to pre-define the storage location of the address (0x10FE).

It looks a little convoluted, but it works great. No compiler warnings. I would ask someone what this code means in a job interview. The answer is:
Defines a pointer (funcPtr) to a function which returns void and has no arguments.
Assigns the function pointer to the address passed in (func_addr), which got cast to be a pointer to a function which returns void and has no arguments.
Call the function pointed to by funcPtr.

Whew!

Stuart
--- In m..., "faro.salvatore" wrote:
>
> First of all thanks to anyone that can shed some light to my questions...
>
> I'm writing a bootloader and have a few doubts on how to proceed in some simple things:
>
> 1) What is the best way to put a jump from the bootloader to the main application using c code? Or should I embed asm code with a jmp instruction to do this??
>
> 2) How do I instruct my compiler (Rowley Crossworks) to compile my code at an address that I define, for example I could compile my bootloader at address 0xe000 and my main application code at 0x1100... This leads me to another curiosity, is it possible to instruct the compiler as to the memory location to use for a particular function?
>
> Thanks.
>

Thanks to everyone for their ideas, I think that the code given by Stuart_Rubin is pretty cool and can probably be an option. I like it because it allows for address changes by code and can be used in a lookup table scheme.

In the SLAA341 examples they simply update the PC... It's very easy and effective, it's one of the things I was considering from the start... Only problem is that you must know the address at compile time as I believe it must be a constant but in my case where application code will always be in the same place it is a valid option.

I noticed that in the CrossWorks version of the code for SLA341 the asm instrction was replaced with opcodes, any particular reason? I thought that CrossWorks also had the asm instruction (Unless I remember wrong).

//asm(" mov &0xFC40, PC;");
__insert_opcode(0x1042);
__insert_opcode(0x40fc);

On another note for the code start address placement so far I have found that CrossWorks seems to use an XML memory map file "$(PackagesDir)/targets/msp430/MSP430F169.xml", so probably I'm going to try copying this file and making the necessary changes.

address that I define

--- In m..., "Paul Curtis" wrote:
>
> > Paul
> > Isn't SLAA341 on the TI web site?
>
> Might be, but hey, those Motorolanites may have snatched it whilst we were
> distracted...
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> CrossWorks V2 is out for LPC1700, LPC3100, LPC3200, SAM9, and more!
>

Hi,

> I noticed that in the CrossWorks version of the code for SLA341 the asm
> instrction was replaced with opcodes, any particular reason? I thought
> that CrossWorks also had the asm instruction (Unless I remember wrong).
>
> //asm(" mov &0xFC40, PC;");
> __insert_opcode(0x1042);
> __insert_opcode(0x40fc);

CrossWorks will never, ever, (at least until I am dead and buried) support
inline assembly language using asm(). Clear? Never. Just in case,
that's no, it doesn't and won't have it.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks V2 is out for LPC1700, LPC3100, LPC3200, SAM9, and more!
That's very clear now :)

--- In m..., "Paul Curtis" wrote:
>
> Hi,
>
> > I noticed that in the CrossWorks version of the code for SLA341 the asm
> > instrction was replaced with opcodes, any particular reason? I thought
> > that CrossWorks also had the asm instruction (Unless I remember wrong).
> >
> > //asm(" mov &0xFC40, PC;");
> > __insert_opcode(0x1042);
> > __insert_opcode(0x40fc);
>
> CrossWorks will never, ever, (at least until I am dead and buried) support
> inline assembly language using asm(). Clear? Never. Just in case,
> that's no, it doesn't and won't have it.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> CrossWorks V2 is out for LPC1700, LPC3100, LPC3200, SAM9, and more!
>

C has a perfectly good "goto" instruction for situations like this. People may turn up their noses at it, but it is certainly preferable to patching in an assembly "jmp" instruction.

SherpaDoug

--- In m..., "faro.salvatore" wrote:
>
> First of all thanks to anyone that can shed some light to my questions...
>
> I'm writing a bootloader and have a few doubts on how to proceed in some simple things:
>
> 1) What is the best way to put a jump from the bootloader to the main application using c code? Or should I embed asm code with a jmp instruction to do this??
>
> 2) How do I instruct my compiler (Rowley Crossworks) to compile my code at an address that I define, for example I could compile my bootloader at address 0xe000 and my main application code at 0x1100... This leads me to another curiosity, is it possible to instruct the compiler as to the memory location to use for a particular function?
>
> Thanks.
>

First of all thanks to anyone that can shed some light to my questions...
>
>I'm writing a bootloader and have a few doubts on how to proceed in some simple things:
>
>1) What is the best way to put a jump from the bootloader to the main application using c code? Or should I embed asm code with a jmp instruction to do this??
>
>2) How do I instruct my compiler (Rowley Crossworks) to compile my code at an address that I define, for example I could compile my bootloader at address 0xe000 and my main application code at 0x1100... This leads me to another curiosity, is it possible to instruct the compiler as to the memory location to use for a particular function?
>
>Thanks.
>
>

Hi,
2)
The correct way of doing what you want is to modify the Linker File (.cmd), I don't know if you are familiar with this file in CCS but if you take a look at this post you will have your answer: http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/19730/76879.aspx#76879
Basically you need to separate your flash memory into 2 segments in the Linker File and then on your code, instruct the linker which files you want on the "special" segment and just leave the other functions unchanged and they will be put on the other part of the flash(default .text) (assuming you changed correctly your .cmd file).
Ask faro.salvatore !

--- In m..., juliociapara@... wrote:
>
> First of all thanks to anyone that can shed some light to my questions...
> >
> >I'm writing a bootloader and have a few doubts on how to proceed in some simple things:
> >
> >1) What is the best way to put a jump from the bootloader to the main application using c code? Or should I embed asm code with a jmp instruction to do this??
> >
> >2) How do I instruct my compiler (Rowley Crossworks) to compile my code at an address that I define, for example I could compile my bootloader at address 0xe000 and my main application code at 0x1100... This leads me to another curiosity, is it possible to instruct the compiler as to the memory location to use for a particular function?
> >
> >Thanks.
> >
> >
> >
> > Hi,
> 2)
> The correct way of doing what you want is to modify the Linker File (.cmd), I don't know if you are familiar with this file in CCS but if you take a look at this post you will have your answer: http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/19730/76879.aspx#76879
> Basically you need to separate your flash memory into 2 segments in the Linker File and then on your code, instruct the linker which files you want on the "special" segment and just leave the other functions unchanged and they will be put on the other part of the flash(default .text) (assuming you changed correctly your .cmd file).
>