Though Ive been programming for years now, I am new to embedded programming. The problem that I have right is the following:
I have some code running from Flash, that at some point I would like to copy over to RAM and start executing from there. The idea is that I would at that point download another image from the serial port and flash it.
The chip Im using is going to be one of the HCS12S derivatives. I know that conceptually you can copy over code then jump to the right location, but is there any nicer way to do this? Perhaps by exploiting the compiler?
Any ingeniuos help would be greatly appreciated. Thanks,
I have done this very same thing in the past with PPC. This is very typical for "loaders" in the embedded world. I am not familiar with your processor but a few things to look for are:
1.) The RAM location being copied to is linker "executable". This could require "saving" or allocating some space in the linker command file or similiar.
2.) It might be easy to copy over a dummy existing function so that you can call the "copied" function in your code. If you do this make sure the parameters are the same etc.
3.) Alternative to #2 is create function pointer and assign it to the "copied" address. Then call the function pointer. This is how I have done it. We reserved space in the linker command file in the "executable" section with a symbol name. We then copied the code into an address represented by the symbol name. We also marked the end of the space with a symbol name for checking overflow etc. Liked to use linker symbol names to avoid hardcoding etc.
The linker supports this explicitly, for example Cosmic: you can define where a segment is placed in ROM and where it shall be located in RAM. That's the preferable method since you have full debug information for the RAM part.
The compiler supports position independent code. The overhead is low in the HC(S)12 since there are long relative branches and addressing modes. Copy from ROM to RAM and it still works.
Assembler programming with relative addressing. A loader is so small, it should be no problem. I'm finishing these days a HCS12 bootloader receiving BASE64 coded data instead of S19 (or binary) with encryption in less than 2K of code, approx. 1000 LOC.
Have the same address for RAM and ROM: copy the ROM contents to RAM and relocate RAM to the top of the memory to overlay ROM. This way, you can even use interrupts. There is an application note from Freescale about a serial bootloader describing this.
Think also about about format and handshake.
I use BASE64 encoding because it adds less overhead than S19 but is still 7bit ASCII. You can send it by mail, look at it with a text editor, and transfer it with any terminal software.
Avoid handshake. Flash programming is faster than 115kbits/s, so you only need some buffering to be able to receive at full speed.
Since here in c.a.e are not many threads about Motorola/Freescale HC(S)12, HC08 microcontrollers, I suggest that you join also the "official" mailing lists. There are people from Freescale, compiler manufacturers (Cosmic, Imagecraft, Metrowerks), debugger manufacturers (Nohau) and many more.
On 13 Mar 2005 12:39:24 -0800, " email@example.com" wrote in comp.arch.embedded:
This is a pretty common feature, supported by quite a few compilers for embedded processors. I don't use the same compiler Oliver does, but there is something similar in one I am using late, TI's Code Composer studio for the 28xx DSP family.
The exact syntax differs from one tool set to another, but the basic concept is pretty simple, and here are some excerpts from a TI build:
First you need some way of specifying that certain code belongs to a specific section. The TI tool set provides two ways to do this from C. On a function by function basis, there is a pragma:
#pragma CODE_SECTION(a_function, "special");
That tells the linker that all functions defined for "special" belong together and separate from all other code and data.
Then in the linker command file, you specify what to do with that section, and create symbols that can be used to locate it at run time:
This tells the linker that all code specified for "special" section is built into the flash image (memory section "P_FLASH_APP") but will be executed from a different location in RAM ("P_HORAM"). It also tells the linker to create three global symbols that the code can use to copy the image from flash to RAM.
Before you call the relocated code, you need to copy it. With the TI tools, that means you must have some code something like this: