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.

TMS320F28379D: How to auto-start CPU2 application

Part Number: TMS320F28379D

Tool/software:

On my TMS320F28379D board, I have a custom CAN bootloader which resides in flash sectors A and B and runs on CPU1.  The bootloader’s “BEGIN” address = 0x80000 (defined in its .cmd file) so that it autostarts.

When the bootloader starts up, it waits to receive messages on the CAN, if it does, it uses those incoming message contents to store my main application in flash sectors C-E.  If it doesn’t receive any CAN messages, it tries to automatically start the main application that’s already stored in sectors C-E by calling runMainApplication() where the bootloader’s .cmd file contains:

Fullscreen
1
_runMainApplication = 0x0BFFC0;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

And the main application’s “BEGIN” address = 0xBFFC0 (defined in its .cmd file).

I’d like to separate some of the functionality out of the main application (in particular an ADC and its ISR) and run it on CPU2.  But I’m not sure how to make the CPU2 application auto-start.

I’m guessing the CPU2 application should reside in different flash sectors, say F-H.  But what should its “BEGIN” address be?  And how will it start if the bootloader is running on CPU1?  Do I need a second bootloader running on CPU2?

Thank you

  • After playing with the "led_ex1_blinky_cpu1" and "led_ext2_blinky_cpu2" examples, I think I've answered my own questions.

    I think I can have a single bootloader running on CPU1, which loads both the CPU1 and CPU2 applications into different flash sectors.

    After the bootloader initializes the board, and it detects no incoming CAN msgs, it can start CPU2 via:

    Fullscreen
    1
    IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    And it can still start the CPU1 application via "runMainApplication()" which references the CPU1 "BEGIN" address.

    And it looks like both the bootloader and the CPU2 applications' "BEGIN" addresses must = 0x80000.

  • This isn't working.  When I try to boot from flash, neither my main CPU1 application nor my CPU2 application auto-starts.

    I'm guessing my bootloader running on CPU1 can't have the same "BEGIN" address as my CPU2 application?

  • Diane,

    The flash banks assigned to CPU1 and CPU2 are physically independent; while the addresses local to the CPUs might be the same they do not refer to the same physical memory.  For instance address 0x80000 in CPU1 does not necessarily contain the same data as 0x80000 in CPU2.  Just to confirm that the entry point for flash boot for both CPU1 and CPU2 is 0x80000, but there can be different contents for each core.

    Now, as you mention, CPU1 is responsible for releasing CPU2 from reset during its boot up process, the IPC command you see in the led_blinky_cpu is doing just that.  However, the passed variable in this command isn't controlling the boot mode, that is handled by the BMODE value in the CPU2 OTP.  I believe that this should be boot to flash when OTP is in its native/erased state, so you don't need to do anything, but I wanted to give that distinction.  The passed value is to set up GPIOs for CPU2 in case it boots to its own serial loader, etc.

    Would you be able to share the .map files from both CPU1 and CPU2 projects?  I can take a look to better understand where things are getting allocated to see if I can spot any issues.

    Best,

    Matthew

  • Matthew,

    I'm sorry I can't share the .map files.

    But what you said about the flash banks being physically independent, makes me think that I can't have a single bootloader running on CPU1 that loads both the CPU1 application into flash sectors C-E, and loads the CPU2 application into flash sectors F-H.

    Do I need 2 bootloaders?  I'm wondering how I can make 2 bootloaders (on CPU1 and CPU2) both use the same CANA and CANB interfaces.

    Thank you,

    Diane

  • I have this working now when booting from flash.

    I have a single bootloader running on CPU1, checking for incoming CAN msgs.  When it receives them, it loads either the CPU1 application in sectors D-J, or the CPU2 application in sectors K-N.

    Both my bootloader and CPU2 applications' "BEGIN" = 0x80000.  I moved my CPU1 application's "BEGIN" to 0xB7FF0 (inside of sector J).

    If my bootloader doesn't detect any incoming CAN msgs, it first auto-starts the CPU2 application via:

    Fullscreen
    1
    IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    And then it auto-starts the CPU1 application via (which doesn't return to the bootloader):

    Fullscreen
    1
    runMainApplication();
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Where my .cmd file defines runMainApplication to be my CPU1 application's "BEGIN":

    Fullscreen
    1
    _runMainApplication = 0x0B7FF0;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    However, I'm not sure how to debug CPU2 inside Code Composer (when not booting from flash):

    1. I created a debug configuration for both CPUs:
    2. And had it load both CPU1 application:
    3. And CPU2 application:
    4. And not erase any flash sectors on either CPU1 or CPU2 (since my bootloader already loaded both apps):
    5. When I start debugging, and both CPU1 and CPU2 are paused on their first lines, I continue CPU2
    6. For CPU1, I load a JS file in the Scripting Console to jump to my bootloader's BEGIN (0x80000), to allow the bootloader to do the board initialization:
    7. Fullscreen
      1
      2
      3
      4
      5
      6
      script = ScriptingEnvironment.instance()
      debug_server = script.getServer("DebugServer.1")
      debug_server.setConfig("D:/code/EPPS_controller_c2000/CCode/EPPSTargetConfiguration.ccxml")
      debug_session = debug_server.openSession("Texas Instruments XDS100v2 USB Debug Probe_0/C28xx_CPU1")
      debug_session.target.connect()
      debug_session.memory.writeRegister("PC", 0x80000)
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    8. When I continue the debug session from there, CPU1's symbols are visible, but CPU2's symbols aren't:
    9. I'm guessing it's because my bootloader reset CPU2 with the IPCBootCPU2() call.  Is there a way I can connect the debug session to the already running CPU2 application?

    Thank you,

    Diane

  • Diane,

    Sorry for the delay, I was out a few days at the end of last week.

    Is there a way I can connect the debug session to the already running CPU2 application?

    Yes, if you right click on CPU2 to can the select the "connect device" option that pops up.  Once you are connected you can then go to Run-Load Symbols and pick your .out file again.  You should now be able to debug.

    I'm not sure why the settings you had didn't work, it may have something to do with CPU2 being held in reset by CPU1.

    To your earlier point on using CPU1 to load CPU2 flash, we can't do this directly, i.e. CPU1 cannot program CPU2 flash addresses.  However, we could use shared RAM(accessible by both CPUs) to give this data across so you don't have to have independent CAN bootloaders; i.e. CPU 1 could take in all the data, boot, and then part of its flow would be to take this data and push it to CPU2 either with shared RAM or IPC commands, etc.

    Best,
    Matthew

  • Matthew,

    Thank you for your suggestions.  I think I'll create a second bootloader just for CPU2.  But since both CPU1 bootloader and CPU2 bootloader won't be able to share a CAN (I know I could switch ownership of the CAN, but that may be cumbersome), I think I'll use shared RAM to communicate between the 2 bootloaders.  And that shared RAM can act as a "virtual" CAN for bootloader 1 to pipe the proper incoming CAN msgs to bootloader 2.  Then bootloader 2 can load the incoming .out into the CPU2 flash sectors.

    Diane