MSP430, CC430 Custom Bootloder Part 2

In this part we will write a function that runs in the RAM. To do this we must know the memory sections, size and how to copy our function to ram and calling it.

So lets look at the memory organization of the CC430F6137:

CC430F6137 memory organization

 

As you see we have 4K of ram which we need to use smartly, but it is enough for our job. Remember we use RAM for heap, stack and now we will also copy our function there,  we will also need an unused area for the buffer in later sections of this tutorial.

To copy the function there we must know the address of the function which is very easy to get with a function pointer. So lets see some code, we will have a function named bootloader_start() which will make the necessary jobs to copy and call the bootloader function on RAM. The bootloader function will not do much work only blink a led for now. It is a very basic code piece enter many parameters like RAM_FUNCTION_SIZE manually, for now. Call below function from your main program. My main clock is 1MHZ so adjust the timeout value to see the led blink if you use higher clock speed.

#define RAM_ROUTINE_TABLE 0x001C00
#define RAM_FOR_RAM_ROUTINES 0x001C10
#define RAM_FUNCTION_SIZE 0X200
#define TABLE_BOOTLOADER 0

void functionCopy(unsigned int * source, unsigned int* destination, unsigned int size)
{
 char *tempsrc, *tempdst;

 if (size > 0)
 {
 tempsrc = (char*) source;
 tempdst = (char*) destination;
 while (size > 0)
 {
 *(tempdst++)=*(tempsrc++);
 size--;
 }
 }
}


//ram function that will blink a led on PORT4 PIN1
void bootloader(void)
{
   unsigned int timeoutValue=0;

while(1)
{
 while(timeoutValue++<0x4fff);
 timeoutValue = 0;
  P4OUT^= BIT1;
}

}

void bootloader_start(void)
{
 void *source, *dest;
 unsigned int *functablePtr;

 void (*strtBootloader)(void);

 P4DIR=0xff;
 asm(" dint");
 asm(" nop");

 dest = (void*) RAM_FOR_RAM_ROUTINES;
 source = &bootloader;

 functionCopy((unsigned int*) source, (unsigned int*) dest, RAM_FUNCTION_SIZE); //copy bootloader functions to RAM

 functablePtr = (unsigned int*) (RAM_ROUTINE_TABLE);  
 *(functablePtr + TABLE_BOOTLOADER ) = (unsigned int) RAM_FOR_RAM_ROUTINES; /*save the function start address useful when you copy multiple functions to ram
so when we go to ram we will now functions calling addresses*/

 strtBootloader = (void(*)()) *(functablePtr + TABLE_BOOTLOADER); /*this is one of many ways to call a function from memory*/
 strtBootloader();

}

Look at the defines, and see how we arrange the memory for our job.

#define RAM_ROUTINE_TABLE 0x001C00
#define RAM_FOR_RAM_ROUTINES 0x001C10
#define RAM_FUNCTION_SIZE 0X200
#define TABLE_BOOTLOADER 0

We will use RAM_ROUTINE_TABLE to save our function addresses. Every function address is two bytes, but we reserved a 10 byte space to use in the future tutorials. We point it to start of RAM section.
RAM_FOR_RAM_ROUTINES is the start of memory space we copy our functions, we point it to 0x1c010 , RAM_FUNCTION_SIZE is the size of function to be copied, but now we only give a value of 512 bytes. Later I will show how to determine/calculate the exact function size.

TABLE_BOOTLOADER is an index for our bootloader function.

Leave a Reply

Your email address will not be published. Required fields are marked *