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.

Can I jump to sci_boot directly from an application using TMS320F28034?

Other Parts Discussed in Thread: TMS320F28034, TMS320F28027, CONTROLSUITE

I have an application running on the TMS320F28034.   Is it possible to jump to sci_boot() from the application using software?

  •  Right now I jump to sci_boot loader by grounding the appropriate GPIO pin.  I would like to do it in software if there is a way?  If there isn't away then I will have to add a switch to my design to allow a user to update firmware.  I really need this answered.  I'm surprised no one has an answer to this question.  It seems as though it would be a simple "No you can't"  Yes you can here's a way. 

  • Hi James,

    Yes you can, here's a way :):
    https://e2e.ti.com/support/microcontrollers/c2000/f/171/p/244450/864118#pi316717=1

    That thread should give you a decent idea on what you'd want to do.


    Thank you,
    Brett

  • Hi Brett

    I plan to use the TMS320F28034 but for now I am using the TMS320F28027 for debugging.

    I was able to make some progress. It seems I can jump to the sci_boot using this code

    //////////////////////////////////////////
    unsigned long boot_addr = 0x003FF6C7;

    void (*entry)();

    void main(void) {
    unsigned long thisTimeStamp;

    HAL_disablewatchdog(&hal, sizeof(hal));
    entry = (void(*)())(boot_addr);

    entry();
    ////////////////////////////////////////////

    I have a downloader that works when I jump to sci_boot using the GPIO pin. When I use this same downloader that was coded by a third party with the code I have posted above for some reason the autobaud portion of the code passes in sci_boot and my function above that jumped to the sci_boot suddenly returns and doesn't wait for data. Is there something else I would need to do to have sci_boot wait for data?
  • Hi James,

    I might recommend changing the clock/pll settings to how they would be if this code was being run from a cold boot.


    Thank you,
    Brett

  • I am not sure how to do that.  What bits/registers would I set?  The code I showed is the first thing to get executed in my app? Wouldn't the mean that all registers are default like they would be during a cold bootl?

  • Hi James,

    Sorry, it was not abundantly clear that the code you specified was being called immediately after boot.  In your case, therefore, nothing would need to be reinitialized.

    After looking at this further, I do think you will need to call the SelectBootMode function prior to calling SCI_Boot().    Or better yet, I'd recommend adding some of the non-boot-mode-determination code in that function into your code.  Some software in the SelectBootMode function does touch the clock settings and may affect the behavior of SCI_Boot.

    Let me know if you stay stuck.  If this happens, I'll need to loop in others.


    Thank you,
    Brett

  • Hi Brett,

    I am still stuck on this.  What I really want to do is skip having to change the state of pins to get to the bootloader.  I just want to call the bootloader directly from software.   By doing this I would avoid having to put any switches on my design.  One thing to note is if I execute the code below using address 0x003ff7bf which is the address of InitBoot which calls SelectBootMode I am able to download using C2prog as long as I ground gpio 37.  When I run the code below C2prog will actually block until I ground gpio 37 and then the download will proceed successfully.  Is there a way in software to set gpio 37 low?   If I could that it would solve everything.   I did try to call SelectBootMode at address 0x003ff559 and the function didn't even wait.  It just returned immediately.  The first thing I tried was to call sci_boot at address 0x003ff6c7.  C2prog gets past autobaud but then sci_boot returns before the download can begin.   How can I call the boot loader from software without having to physically change the state of any pins?

    unsigned long init_boot_addr = 0x003ff7bf; // init_boot
    //unsigned long init_boot_addr = 0x003ff559; // SelectBootMode
    //unsigned long init_boot_addr = 0x003ff6c7; // sci_boot
    void (*entry)();


    void main(void) {
    unsigned long thisTimeStamp;

    entry = (void(*)())(init_boot_addr);
    entry();

  • James,
    you should be able to call SCI_BOOT from application . You mentioned that when you do this C2Prog gets past the autobaud detection but then SCIBOOT returns.

    This is easier to debug, please try below steps.

    1.> load your application that calls SCIBOOT in ROM
    2.> Now put a break point at SCIBOOT call into ROM and step into the routine
    3.> Now add boot ROM symbols from the Boot ROM COFF file i ncontrolSuite.(C:\ti\controlSUITE\libs\utilities\boot_rom\2803x\2803x_boot_rom_v1\Release)
    4.> you should be able to do source level debug now - if the CCS asks for sources (or cannot find source) then point it to the sources folder - C:\ti\controlSUITE\libs\utilities\boot_rom\2803x\2803x_boot_rom_v1\source.
    5.> now you should be able to put a HW break point past the auto Baud and see what is going on.

    there could be couple of things that might be going wrong and above steps will help you catch the error.

    #1> SCIBOOT function in ROM does below assignment. The variable GetWordData is a function pointer in RAM. Make sure it is getting initializes properly

    GetWordData = SCIA_GetWordData;

    #2.> if SCIBOOT doesn't get a proper key word then it returns immediately
    #3.> GetLongData() and CopyData() are other function and as long as the incoming hex data is in proper format these two functions should be able to parse the data properly and program it in RAM.

    Hope this helps.

    Best Regards
    Santosh Athuru
  • Hi Santosh,

    I am able to load symbols from this path
    C:\ti\controlSUITE\libs\utilities\boot_rom\2802x\2802x_boot_rom_v2_0\Release\TMS320x2802x_boot_rom_Gold_v200.out
    and debug as I am currently debugging with the 28027. I plan to move to the TMS320F28034 later.
    This allows me to single step into the SCI_Boot() function shown below. I am not able to set a break point for some reason. I tried to set a break point at the function ReadReservedFn(); The break point shows up disabled in code composer. When I click the checkbox to try and enable it, I get the following error

    "No code is associated with "C\ti\controlSUITE\libs\utilities\boot_rom\2802x\2802x_boot_rom_v2_0\source\SCI_Boot.c", line 62 in any loaded symbols"

    How do I set a break point in the code below?

    Uint32 SCI_Boot()
    {
    Uint32 EntryAddr;

    // Asign GetWordData to the SCI-A version of the
    // function. GetWordData is a pointer to a function.
    GetWordData = SCIA_GetWordData;

    SCIA_Init();
    SCIA_AutobaudLock();

    // If the KeyValue was invalid, abort the load
    // and return the flash entry point.
    if (SCIA_GetWordData() != 0x08AA) return FLASH_ENTRY_POINT;

    ReadReservedFn();

    EntryAddr = GetLongData();

    CopyData();

    return EntryAddr;
    }
  • James,

    same is possible with 2803x, you should be able to put a HW break point, can you try to enable it from the dis-assembly window?

    Best regards

    Santosh Athuru

  • Hi Santosh,

    Enabling break points in the dis-assembly window was the key to understanding the boot loading process. I managed to get the whole downloading process to work regardless of pin states using the code below. The code below first calls sci_boot directly. After debugging I noticed that sci_boot is only responsible for writing the blocks of data to there respective addresses. Erasing the flash sectors and programming is done by what ever code is at the entry point address returned by sci_boot. You can see below I take the return value from sci_boot, make a function pointer and call it. The return value from sci_boot is 0. So I call the code at address 0. This allows C2prog to erase sectors and program successfully. Is it possible to load symbols for the code at address 0 so I can single step that code too?




    unsigned long init_boot_addr = 0x003ff6c7; // sci_boot

    typedef unsigned long Uint32;


    Uint32 (*entry)();


    void main(void) {


    entry = (Uint32(*)())(init_boot_addr);
    init_boot_addr = entry();
    entry = (Uint32(*)())(init_boot_addr);
    init_boot_addr = entry();
  • yes, after loading the code the SCI BOOT returns the entry point and you will have to branch to the entry point to execute the loaded code. so before you branch to the entry point at 0x0 , you can use the load menu from CCS and "add symbols" and point to the COFF file that was downloaded.

    If you are trying to come up with a SCI based flash programmer, then you can refer to the flash programming kernel examples in controlSuite (C:\ti\controlSUITE\device_support\f2802x\v230\f2802x_examples_structs\f28027_flash_kernel), this example runs from flash and can upgrade flash. It is just an example and you can tweak it as you need.

    Hope this helps.

    Best Regards
    Santosh Athuru
  • Hi Santosh,

    I added symbols as you suggested.   The symbols I load are the ones for the file I am trying to download.

    this is the path and file name. 

    C:\Jason\CodeForJason\Firmware\GOI_ACIM\GOI_ACIM\GOI_ACIM.out

    When I try to step into the call at address 0.   The disassembly window shows "no debug contest",    How can I step into the call at address 0 and debug?

    The second thing I tried is to build the project at this path and debug

    C:\ti\controlSUITE\device_support\f2802x\v230\f2802x_examples_structs\f28027_flash_kernel)

    The first problem I encountered is that C2prog gave this error when I try and download

    *** PLEASE RESET TARGET IN SCI BOOT-LOADER MODE ***
    Connecting with target (autobaud)... OK.
    Bootloading... failed (no response)!

    So I did further debugging and found that this function doesn't echo anything back.  Note that the echos are commented out.  

    Uint16 SCIA_GetOnlyWordData()
    {
    Uint16 wordData;
    Uint16 byteData;

    wordData = 0x0000;
    byteData = 0x0000;

    // Fetch the LSB and verify back to the host
    while(SciaRegs.SCIRXST.bit.RXRDY != 1) { }
    wordData = (Uint16)SciaRegs.SCIRXBUF.bit.RXDT;
    //SciaRegs.SCITXBUF = wordData;

    // Fetch the MSB and verify back to the host
    while(SciaRegs.SCIRXST.bit.RXRDY != 1) { }
    byteData = (Uint16)SciaRegs.SCIRXBUF.bit.RXDT;
    //SciaRegs.SCITXBUF = byteData;

    checksum += wordData + byteData;

    // form the wordData from the MSB:LSB
    wordData |= (byteData << 8);

    return wordData;
    }

    Then I tried to put the echos in like so. 

    Uint16 SCIA_GetOnlyWordData()
    {
    Uint16 wordData;
    Uint16 byteData;

    wordData = 0x0000;
    byteData = 0x0000;

    // Fetch the LSB and verify back to the host
    while(SciaRegs.SCIRXST.bit.RXRDY != 1) { }
    wordData = (Uint16)SciaRegs.SCIRXBUF.bit.RXDT;
    SciaRegs.SCITXBUF = wordData;

    // Fetch the MSB and verify back to the host
    while(SciaRegs.SCIRXST.bit.RXRDY != 1) { }
    byteData = (Uint16)SciaRegs.SCIRXBUF.bit.RXDT;
    SciaRegs.SCITXBUF = byteData;

    checksum += wordData + byteData;

    // form the wordData from the MSB:LSB
    wordData |= (byteData << 8);

    return wordData;
    }

    When I try and download using the above code C2Prog give me this error

    *** PLEASE RESET TARGET IN SCI BOOT-LOADER MODE ***
    Connecting with target (autobaud)... OK.
    Bootloading... failed (invalid echo)!

    C2prog sends a 170 and expects to get the 170 echo'ed back.  Then it sends and 8 and expects to get that echo'ed back.  The values are getting received correctly but C2prog doesn't seem to understand them when they get sent back.   Do you know why this would be?

  • James,

    from the source code comments, that example is supposed to work with serial loader utility, to get it working with C2Prog the SCIBOOT functions should be similar to what they were in boot ROM SCIBOOT.C file. Try to use SCIBOOT.C and SharedBoot.c from the boot ROM and see if that works.

    Also refer to this app note.

    http://www.ti.com/lit/an/sprabv4a/sprabv4a.pdf

    on the first problem, I don;t understand the no debug context issue. If you have code loaded at 0x0, then you should be able to step through that code right?

    Best Regards

    Santosh Athuru

  • Hi Santosh,

    When I use SCIBOOT.c and SharedBoot.c from the boot ROM. The problem with echoing goes away only to show a problem further on with receiving the blocks. The program now hangs up waiting for data at wordData = (*GetWordData)() and the address read at BlockHeader.DestAddr = GetLongData() seems to be an impossible value based on my hex file. So for some reason the blocks are not being read properly in this code.

    void CopyData()
    {

    struct HEADER {
    Uint16 BlockSize;
    Uint32 DestAddr;
    } BlockHeader;

    Uint16 wordData;
    Uint16 i;

    // Get the size in words of the first block
    BlockHeader.BlockSize = (*GetWordData)();

    // While the block size is > 0 copy the data
    // to the DestAddr. There is no error checking
    // as it is assumed the DestAddr is a valid
    // memory location

    while(BlockHeader.BlockSize != (Uint16)0x0000)
    {
    BlockHeader.DestAddr = GetLongData();
    for(i = 1; i <= BlockHeader.BlockSize; i++)
    {
    wordData = (*GetWordData)();
    *(Uint16 *)BlockHeader.DestAddr++ = wordData;
    }

    // Get the size of the next block
    BlockHeader.BlockSize = (*GetWordData)();
    }
    return;
    }

    Since I could not get the the above to work I went back to my code that does work. Based on the document you sent in your last post. Isn't it true that when I call address 0 that it is calling the flash kernel? If so is there a way to load symbols for it?
  • James,
    ok lets concentrate on your application code, since you got it working mostly. I'm not sure with C2PROG what gets loaded - right?

    1.> You are calling the SCI BOOT in ROM from your application in flash and use C2PROG to program a new application in flash - right?

    During this step, you have set up break point in SCIBOOT in ROM and it is loading a program (I believe it is the firmware upgrade kernel from C2PROG guys) and returns the entry point 0x0 to your application in flash that called the SCIBOOT in ROM in first place. Now this applicaiton has to branch to 0x0 to start the kernel.

    Now you want to load symbols for this kernel, I don;t think we have the COFF file or symbols for the kernel because it is coming from C2PROG. But at the same time I don;t think you have to go worry about debugging the kernel because C2PROG made sure that it works and will be able to download your final application to flash.

    You just have to make sure that as soon as SCIBOOT in ROM returns the Entry point (0x0) to your code, do a branch to this entry point and you should be done.

    Does this make sense?

    Best Regards
    Santosh Athuru
  • Hi Santosh,

    I would actually like to focus on my application code posted below.  The code below when I run it gives me the output from C2prog that I have posted below.  It has acheived my first goal which is to call the boot loader stuff without having to change the state of pins.   I would now like to write my own boot loader to do exactly what C2prog is doing.  When I call sci_boot directly at address 0x003ff6c7 below  C2prog give me the following output.  The sci_boot code I'm able to debug and can see it loads the code into RAM.

    Connecting with target (autobaud)... OK.
    Bootloading... OK.

    When I make the call to address 0.  This allows C2prog to do the following 

    Connecting with target... 
    -Chip ID: 0xCF
    -Chip Rev: 0x02
    OK.
    Unlocking target... OK.
    Loading... OK.
    Connecting with target... 
    -Flash API version: 200
    OK.
    Erasing flash... [ABC] OK.
    Programming... OK.

    I am going to get a serial port sniffer and figure out what the packets are that C2prog is sending to do the flash burn.   Do you have a document that specifies these packets that 

    1.  Read the chip id shown above.

    2.  Unlock the target shown above

    3.  Read the flash api version

    4 Erase sectors [ABC}

    6  Do the programming 

    unsigned long init_boot_addr = 0x003ff6c7; // sci_boot

    typedef unsigned long Uint32;
    typedef unsigned int Uint16;

    Uint32 (*entry)();


    void main(void) {
    unsigned long thisTimeStamp;

    entry = (Uint32(*)())(init_boot_addr);
    init_boot_addr = entry();
    entry = (Uint32(*)())(init_boot_addr);
    init_boot_addr = entry();

    *** PLEASE RESET TARGET IN SCI BOOT-LOADER MODE ***
    Connecting with target (autobaud)... OK.
    Bootloading... OK.
    Please wait...
    Connecting with target...
    -Chip ID: 0xCF
    -Chip Rev: 0x02
    OK.
    Unlocking target... OK.
    Loading... OK.
    Connecting with target...
    -Flash API version: 200
    OK.
    Erasing flash... [ABC] OK.
    Programming... OK.

  • James,

    I'm not sure how C2 PROG is reading the Chip ID and REV, if must be loading a small program that reads this and sends it back and then waits for the HEX file to come in.

    The App note, below and the ControlSuite examples should be enough to develop your own Firmware upgrade kernel on target and associated Host serial programmer. The app note refers to a serial utility and I believe you can download it and modify as needed.

    www.ti.com/.../sprabv4a.pdf



    Best Regards
    Santosh Athuru
  • Hi Santosh,

    After sniffing the packets with a packet sniffer I can see that all SCI_Boot does is load a program and then jump to it.  

    It is this program that allows C2prog to output the following to do the burn  (I guess it could be two programs.  One to get the chip ID and rev and another to do the flash burn) 

    Connecting with target... 

    -Chip ID: 0xCF
    -Chip Rev: 0x02
    OK.
    Unlocking target... OK.
    Loading... OK.
    Connecting with target...
    -Flash API version: 200
    OK.
    Erasing flash... [ABC] OK.
    Programming... OK.

    Now the question becomes.  What program?  Since the output above reads a flash api version of 200.  I wonder if the program C2 prog is loading the program at 

    C:\ti\controlSUITE\device_support\f2802x\v200\f2802x_examples\flash_f28027

    in order to send the erase sector commands and program the flash.  What program do you think C2prog is loading if it claims to be running -Flash API version: 200?

    When I sniff the output during the programming phase of C2prog I can see the bytes from  the intel hex record get programmed.  For example 

    Output packet from C2prog captured with packet sniffer

    00 3F 5F 57 A9 F1 0E E6 1E AC 56 63 00 A7 56 05 
    00 A7 56 8B A9 91 D0 0A 0E EE 1E AC 56 63 00 A7

    56 05 00 A7 D5 A3 FC FF FE

    I am able to match this data from the following line of the intel hex record for example.  

      <L1015>:205F5700A9F10EE61EAC566300A7560500A7568BA991D00A0EEE1EAC566300A7560500A753</L1015>

    So what ever program C2prog is loading is excepting packets that take the following from

    <32bit address><data><D5 A3 FC FF FE>

    It seems that every packet that programs an intel hex record line has an FF FE on the end.   It also has some other data between the <data> and <FF FE>

    In the above would you be able to say what the D5 A3 FC is?  Is it some type of check sum?

  • James,

     I apologize, I cannot help with reverse engineering of C2Prog. Please take a look at the flash programming examples from ControlSuite for your device and flash programming kernels and with the guidance provided in this thread you should be able to come up with your own flash programming solution as you want to.

    Also please check with C2Prog guys on the questions you have about their product.

    Best Regards

    Santosh Athuru

  • No Worries Santosh,

    I think I get what I need to do now.   I didn't realize that C2prog would be loading something non standard.  I thought C2prog would be loading something from ti which is not proprietary. 

    I don't want to infringe on any copy right stuff for sure.   I now plan to write my own flash loader based on the example you gave.  I'll let you know if I have any question about that. 

  • Hi Santosh,

    I wrote my own host PC application to send an intel hex file to the code at 

    C:\ti\controlSUITE\device_support\f2802x\v230

    I am running the code above without any changes in the ccs debugger.

    It seems as though the file is being written to flash properly.   Unfortunately it will not boot.  Can you confirm that all I need to do is write the hex file and entry point and the code should run?  Is there any else I need to write to get the code to boot?  I've tried two different entry points.

    this one from my map file 

    OUTPUT FILE NAME: <GOI_ACIM.out>
    ENTRY POINT SYMBOL: "_c_int00" address: 003f5813

    I also tried the address of main.

    0     003f413b  _main   

    Which one should I be using?

    Can you think of any reason why the code will not run after it has been programmed.?

  • James,

    for boot to flash to work, the entry point should be at BOOT TO FLASH entry point as mentioned in the boot ROM chapter of TRM.

    You can program the same COFF file from CCS and compare the Flash contents between CCS programming and your boot loader programming.

    Hope this helps.

    best Regards

    Santosh Athuru

  • Hi Santosh,
    Do you mean in this manual?
    www.ti.com/.../sprufn6a.pdf

    If you do Section 2.11 is as follows: Is says the entry point of the program? What is the address number of the BOOT TO FLASH you speak of in your last comment?

    2.11 Bootloader Data Stream Structure
    The following two tables and associated examples show the structure of the data stream incoming to the
    bootloader. The basic structure is the same for all the bootloaders and is based on the C54x source data
    stream generated by the C54x hex utility. The C28x hex utility (hex2000.exe) has been updated to support
    this structure. The hex2000.exe utility is included with the C2000 code generation tools. All values in the
    data stream structure are in hex.
    The first 16-bit word in the data stream is known as the key value. The key value is used to tell the
    bootloader the width of the incoming stream: 8 or 16 bits. Note that not all bootloaders will accept both 8
    and 16-bit streams. Please refer to the detailed information on each loader for the valid data stream width.
    For an 8-bit data stream, the key value is 0x08AA and for a 16-bit stream it is 0x10AA. If a bootloader
    receives an invalid key value, then the load is aborted.
    The next 8 words are used to initialize register values or otherwise enhance the bootloader by passing
    values to it. If a bootloader does not use these values then they are reserved for future use and the
    bootloader simply reads the value and then discards it. Currently only the SPI and I2C and parallel XINTF
    bootloaders use these words to initialize registers.
    The tenth and eleventh words comprise the 22-bit entry point address. This address is used to initialize
    the PC after the boot load is complete. This address is most likely the entry point of the program
    downloaded by the bootloader.
  • Flash entry point is 0x3F7 FF6. On Boot to flash mode, the boot ROM branches to this location, the codestart section of your application should link to this address.

    the Entrypoint you see in the bootloader data stream structure is for peripheral loading, for ex: SCIBOOT gets the hex data, it parses the data as per the bootlaoder data stream structure and programs RAM and at the end of loading, the entry point specified in the hex file will be used to start the downloaded application.


    Best Regards
    Santosh Athuru