This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to code a Bootloader

Other Parts Discussed in Thread: TMS320C6746, OMAP-L138

Hi everyone,

I am currently working with the 5505 EZDSP and I am looking into the bootloader section. I know what a boot loader is and its purpose, but now I need to program one something I have never done.

I've read the document about the bootloader for the DSP which I understand but now I am wondering how do I code one? I mean, is it like a C code where you define adresses and such or do I need to do it with ASM? ( I can program both language so it's alright). I just don't know where to look anymore. I've searched many threads on differents message board to no avail. If you could point me out on a document, website or anything else to get me started on the structure and programmation of the bootloader, I'd appreciate it.

Jean-Francois

  • Boot loader code is no different from other code and can be written in c.  The boot loader is a convenience by  providing a little bit of code that enables a suitable method to load the primary code into the device from external memory,  disk drive, USB port, or other common interface that would not be available to the processor at power up.

     As an example you may want a user to be able to load or update the firmware of a product via its USB port to avoid the issue of the user having to understand or own a XDS560 JTAG emulator and associated IDE as required to flash a device directly.

    Where to start?  Decide the location of the boot loader, is it in external non-volatile ROM, pre-flashed into the flash memory of the device or some other place?  It must be at a location where the processor can start execution at power up.  Next decide the location of the program files to be loaded, are they on a hard disk, ROM, or available from the host via USB?

    Let say your device can start execution from external ROM so you put the boot code here. Your design uses flash for code space and you plan to load this from a host PC via USB. So, using c, you write a program that is stored in the ROM that loads the program into flash, from the host PC, over USB.

    Often several boot loaders can be "chained". An example would be to use  short simple loader code* in the ROM. That code would access a more complex loader from on board external SPI flash using the C5501  McBSP0 configured to operate in SPI mode which is not directly available to the device at power up. This second more complex loader would then access the program files from the host PC via the USB.

     

    Yet another option is "no boot loader" where the primary code is preloaded into memory that is available from power up or reset.

     

    * Note there is a boot ROM already associated with some devices such as the TLV320C5501  See SPRA911C − October 2004 at  http://focus.ti.com/lit/an/spra911c/spra911c.pdf for more details.

     

  • looking at the TMSCV5505 bootloader here is what I have to do (each number is a word, like 1 is the first word and so on).

    1 Boot Signature (16-bits) 0x09AA
    2 Entry Point (32-bits) Byte address to begin execution (MSW)
    3 Byte address to begin execution (LSW)
    4 Register Configuration Count (16-bits, N = count) 1 to 216 - 1
    5 Register Config #1 Address in I/O space
    6 Register Config #1 Value or delay count
    7 Register Config #2 Address in I/O space
    8 Register Config #2 Value or delay count
    . . .
    Register Config #N Address in I/O space
    4+2N Register Config #N Value or delay count 0 to 216 - 1
    5+2N Section 1 word count (16-bits) Size is the number of valid (non-pad) 1 to 216-1
    data words in block M = (size + 2) rounded up to nearest multiple of
    64-bit boundary
    6+2N Destination MSW address to load Section 1 (32-bits) 16-bit word address MSW
    7+2N Destination LSW address to load Section 1 (32-bits) 16-bit word address LSW
    8+2N First word of Section 1 (16-bits)
    . . .
    5+2N+M Last word of Section 1, often pad data (padded to 64-bit boundary)
    . . .
    X Section X word count (16-bits) Size is the number of valid (non-pad) 1 to 216-1
    data words in block N' = (size + 2) rounded up to nearest multiple of
    64-bit boundary
    X+1 Destination MSW address to load Section X (32-bits) 16-bit word address MSW
    X+2 Destination LSW address to load Section X (32-bits) 16-bit word address LSW
    X+3 First word of Section X (16-bits)
    . . .
    X+N' Last word of Section X, often pad data (padded to 64-bit boundary)
    X+N'+1 Zero word. Note that if more than one source block was read, word 0x0000
    X+N' shown above would be the last word of the last source block.
    Each block would have the format shown in the shaded entries.

    In theory , I understand all this. But to apply it, it's different. I mean, in my code, I need to put at the first address (0x0000) the data 0x09AA.

    so basicly, the memory would be organized somewhat like

    ADDR                    VALUE

    0x0000                  0x09AA  --- boot signature
    0x0001                  0x0000 (fictionnal value) --- MSW entry point
    0x0002                  0x0400(fictionnal Value) --- LSW entry point

    and so on with the rest of the parameter. How am i supposed to do that? I mean, I dont see how in C programmation I can do that. Maybe in ASM but naturally I would go directly into HEX file as I can set directly a value at a specific address.Or even just create a program to directly put the value I need into the SPI EEPROM.

    I'm kind of confused on how to express my problem as it is confusing for me to grasp the coding of the bootloader. I understand that the bootloader is nothing more than a code, but I need to be able to specify value at specific address which I dont think I can do in C. Anyways, thanks for the help I think I understand a little bit more about my problem but I'm still confused. So any more inputs are welcome.

    Thanks

    Jean-Francois

  • c permits constants to be loaded into specific addresses.   What I IDE are you using, CCS?

  • Yes i am using CCS 4.2.3 if I'm not mistaken. How would one do to load a constant in a specific address? I remember vaguely doing that in school 2 1/2 years ago but I've never really used it after that

    Thanks

    Jean-Francois.

     

  • Pointers

    int *your_pointer

    You can set the first address to 0x0000  put the values in a array() and then loop through adding 1 to the pointer address and incrementing array(i = 1) this way the values will be in a nice table in the code with comments and the pointer function will be just a few  lines.

  • By doing that, will I really get the first address ( 0x0000) to be at the value I want? I don't understand  everything going behind a compiler/linker and I don't know much, but from what I know, using a pointer will generate a code and the first value will not be what I want it to be. But correct me if i'm wrong.

    Basically, my code will be something like from what I understand from your post.

     

    short *BootPtr = 0x0000; //set the first address to be written
    short BootTable[NUM_ARG] ; // I NUM_ARG is the space I need

    For ( Number of iteration)
    {
      *BootPtr = BootTable[Iteration] ;
      BootPtr++
    }

     

    And then I use Hex55 and get my bootloader?

  • J.F Gagnon said:
    short *BootPtr = 0x0000; //set the first address to be written



    *BootPtr will return the value at this address. You want ptr = 0x0000;

    This is a snippet of something I have used. It is similar to your code:

    #define BUFFER_SIZE 0xYY  // number of lines


    short  RegValue[] = //boot loader hex values
    {
    0x09AA,   // Boot Signature (16-bits)
    0xVVVV,  // next  value
    0xYYYY,
    -
    -
    -
    0xZZZZ  // Last value
    };

        for (i = 0; i < BUFFER_SIZE; i++)
        {
            // Write byte to memory location
            *ptr = RegValue[i];
             ptr = ptr + 1;

        }

     

  • When you initialize a pointer, if you give a value like I did ( int* ptr = value) , the value is the address. But this only applies for the first call. After that, it follows the pointer behavior where *ptr = value means changing the value inside the pointer and ptr = value sets the address of the pointer.

    But anyways, thanks for the answers, I will try that shortly and I will give feedback

    Thanks

    Jean-Francois

  • Why do you want to write your own bootloader?  What feature(s) are not present in the bootloader that is embedded in the VC5505 DSP.

    Regards.

  • I am working on a school project. At my next trimester, I will need to design an audio amplifier  and another device ( it can be anything we want) that reacts with the music coming from the amplifier.That other device is a big dance floor that can change the color of tiles and it's what we are working on right now.

    The chain will be like this Audio Amp --->Computer--->Dancefloor. And to make the connection between the computer and the dancefloor, we chose the ethernet protocol because basically every computer has an ethernet port making our device useable by any computers(and other reasons too). With the bootloader, I hope to be able to make the connection between the device and the computer transparent to the user by making the initial connection to the computer automatic when the device is plugged in and powered.

    That's for my part right now because we've just begun the project, but I need to communicate to another uC too and we might need some initial setup too.

  • And correct me if I'm wrong, but I will need the bootloader to go fetch my code in my SPI EEPROM when the device will be stand-alone (later) and not on the EVM kit.

  • JF,

    I don't think you need to write a bootloader to accomplish what you want to do.  This might just be difference in definitions of words.  What you need to do can be accomplished in your application intialization code.  The bootloader on the DSP is used primarily for copying your application from flash to runtime memory and setting up the C environment.  Any custom configuration like you mention can take place as the application is starting up.

    One thing to note.  The C5505 DSP does not have an ethernet peripheral.  If you want to use ethernet to communicate to the dance floor, you will need to come up with some type of bridge.  I haven't heard of that being done before myself.  Maybe someone else has information on this type of interface.

    If you want a device with embedded EMAC you might want to look at TMS320C6746/48, or if you also want an ARM MPU integrated.  Look at the OMAP-L138.

    Regards.

  • Correct on the use of the bootloader.  That is the main intent.

    Regards.

  • I too need a bootloader, one that will spi boot from a specified eeprom sector.  to solve the age old problem... if the customer powers down during a firmware upgrade. sector0 has my bootloader that gets automatically loaded by ti's bootloader. then it checks for a valid application to load from another sector.  if none it waits for a new load image over a uart we have on the emif. i wrote all my code to decipher the boot table and have one remaining problem....

    *(Uint16*)sectAddr

    progData;  copies to data memory and not program memory. how do i copy to program memory?

    also i cannot use memcpy() because that is not located in a spot that will not be overwritten.

    Thanks,

    Paul

  • For the Ethernet part, I will use the ENC28j60 from microchips. I've already used that one. The reason why we use the 5505 EVM module is that me and my friend already had one so we could start right up our project. Also , as we are students and not a company, we don't have much money to put on that project and buying another Development Kit/EVM is another cost to the project and we are already left with a good tab right now. And we don't plan on going commercial neither, it's only for a fun project that you can still somewhat use. So we figured that this DSP will do the trick.

    Anyways, thanks for the answers, it clarifies a lot of things for me.