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.

TMS320F280049: How to run the whole code from RAM after loading from Flash

Part Number: TMS320F280049
Other Parts Discussed in Thread: C2000WARE

We have a power electronics control appllication and we want the whole code to load from Flash and run from RAM for 2 reasons:

  1. ISR performane without any Flash wait states
  2. Main() code writes to the same flash bank that stores the code, so ISR should run uninterrupted while main() is doing flash operations (no read stalls)

But I am aware that boot code (like boot28.asm) needs to be run from Flash only as it does the work of loading to RAM. So, at least some part of the RTS library needs to be run directly from Flash. 

I am using the cmd as below text and also I have converted the whole project code to ramfunc using --ramfunc in Runtime model options. In linker , we use COFF, so #if defined(__TI_EABI__) parts can be ignored. The flash to RAM load is done using BINIT. In f28004x_codestartbranch.asm, only watchdog is being disabled before long branching to _c_int00

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
MEMORY
{
PAGE 0 :
/* BEGIN is used for the "boot to Flash" bootloader mode */
BEGIN : origin = 0x086000, length = 0x000002
RAMGS0_3 : origin = 0x00C000, length = 0x007FF8
// RAMGS3_RSVD : origin = 0x013FF8, length = 0x000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
RESET : origin = 0x3FFFC0, length = 0x000002
/* Flash sectors */
/* BANK 0 */
FLASH_BANK0_SEC6_15 : origin = 0x086002, length = 0x009FFE /* on-chip Flash */
// FLASH_BANK1_SEC15 : origin = 0x09F000, length = 0x000FF0 /* on-chip Flash */
// FLASH_BANK1_SEC15_RSVD : origin = 0x09FFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
PAGE 1 :
BOOT_RSVD : origin = 0x000002, length = 0x0000F1 /* Part of M0, BOOT rom will use this for stack */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

We are facing 2 issues:

  1. How do we ensure that only boot code is running directly from Flash while all other code can be run from RAM? I tried to run memcpy.c.obj from RAM, but then microcontroller fails to boot. The currect working memory allocation is shown in photo below. For our purpose memcpy should be running from RAM as we might need to use it  in ISR. This is just one example. Ideally only boot.asm should be running directly from Flash.
  2. With current settings, we cannot debug the code. Debug runs normally when we use a different linker where we load and run code from RAM only.
  • Hi,

    Pls refer this link -https://software-dl.ti.com/ccs/esd/documents/sdto_cgt_Linker-Command-File-Primer.html

    Do you need to have memcpy.obj in Flash which has to be copied to RAM or can it be placed in RAM itself?

    Best Regards

     Siddharth

  • Hi Siddharth,
    The linker file has been written after referring to the primer. Did I miss anything?
    memcpy is needed because if I remove it from Flash, the microcontroller refuses to boot. I guess memcpy is used to copy from Flash to RAM before main() is called.

    May I know when Goerge Mock willl be back from his vacation?

  • Hi Arpan,

    Will reassign this thread to the compiler team for their inputs.  I think George Mock will be back on Dec 5th.

    Best Regards

    Siddharth

  • Hello Arpan,

    I will be trying to help debug this issue further before handing it off to the compiler team.

    I guess memcpy is used to copy from Flash to RAM before main() is called.

    Based on this it sounds like you were trying to use memcpy in RAM to try and program Flash, is my understanding correct? If so, this cannot be done; Flash is programmed/erased via the Flash API, which cannot be executed in the same bank which is being programmed/erased.

    How do we ensure that only boot code is running directly from Flash while all other code can be run from RAM?

    In your linker command file if you have the .text section allocated on Flash and then have #pragma predefines for each function that should be in RAM, this will ensure that those functions are executing in RAM (i.e. #pragma CODE_SECTION(myFunction, ".TI.ramfunc");).

    With current settings, we cannot debug the code. Debug runs normally when we use a different linker where we load and run code from RAM only.

    Since you're using BINIT, you can also refer to the flash_ex3_flash_to_ram example in C2000Ware_5_01_00_00\driverlib\f2838x\examples\c28x\flash. While it is on a different device, the specific steps for doing Flash to RAM are still relevant (although the number of functions which are moved from Flash to RAM will be expanded in your case).

  • Hi Omer,

    Based on this it sounds like you were trying to use memcpy in RAM to try and program Flash, is my understanding correct?

    No. We are not using memcpy at the moment, but we might use in future. I should be able to run any code from RAM without any ifs and buts. So, even memcpy function should be available to be run from RAM

    In your linker command file if you have the .text section allocated on Flash and then have #pragma predefines for each function that should be in RAM, this will ensure that those functions are executing in RAM (i.e. #pragma CODE_SECTION(myFunction, ".TI.ramfunc");).

    This is not what I have done. Whole code I have written is in .ti.ramfunc. Only the library object files are in .text. I have handled those in linker to load from flash and run from RAM. It is not possible to assign RTS lib and driverlib code objects to .ti.ramfunc. They will go to .text section only as the lib files are pre-compiled

    Since you're using BINIT, you can also refer to the flash_ex3_flash_to_ram example in C2000Ware_5_01_00_00\driverlib\f2838x\examples\c28x\flash.

    I'll check this. Please refer this query to compiler team as it needs more advanced treatment. 

  • Please refer this query to compiler team as it needs more advanced treatment. 

    We had previously tried to have someone on the compiler team respond to this, but they have reassigned it to our group because they require more debugging first before they are willing to respond. I will try to at least narrow down the issue to something they can address before forwarding them this post a second time.

    I tried to run memcpy.c.obj from RAM, but then microcontroller fails to boot.

    Can you provide some detail on this? Is there an error message of some sort that shows that the device failed to boot?

    With current settings, we cannot debug the code. Debug runs normally when we use a different linker where we load and run code from RAM only.

    On this point again, have you already tried swapping differences one-at-a-time where possible to see if there's a specific change that makes it so debugging is not possible?

  • Hi Omer,

    I will try to at least narrow down the issue to something they can address before forwarding them this post a second time.

    Okay. Let's try.

    Can you provide some detail on this? Is there an error message of some sort that shows that the device failed to boot?

    So, as we cannot debug, we can't see what's happening. But from our LEDs, we are sure that the after the code jumps from our bootloader to this application, code gets stuck somewhere and doesn't run as it should.

    On this point again, have you already tried swapping differences one-at-a-time where possible to see if there's a specific change that makes it so debugging is not possible?

    No. I have not had the time to look into it in detail. We load and run from RAM in debug mode whenever we want to debug something.

    But I suspect it could be something related to (BINIT) method. I had previously tried to use assembly code example to copy code from Flash to RAM before _c_int00 is called. But the code did not work. We cannot use the typical memcpy inside main() to copy from Flash to RAM as main() itself is part of .ti.Ramfunc and needs to be copied to RAM from Flash to be run.

    Right now, resolving the unavailability of debug is low priority issue. The more important issue is to get the whole code running from RAM

  • Hi Omer,

    Since you're using BINIT, you can also refer to the flash_ex3_flash_to_ram example in C2000Ware_5_01_00_00\driverlib\f2838x\examples\c28x\flash. While it is on a different device, the specific steps for doing Flash to RAM are still relevant (although the number of functions which are moved from Flash to RAM will be expanded in your case).

    Please note that we are using COEFF, while this example uses EABI.

    The example has .const in flash, while we are loading .econst from Flash to RAM for fetch during application Run. Same for .switch

  • So, as we cannot debug, we can't see what's happening. But from our LEDs, we are sure that the after the code jumps from our bootloader to this application, code gets stuck somewhere and doesn't run as it should.

    Sorry, my assumption was that you were using a debugger to run this program, is that not the case? If so, would it be possible to try and run a debug session that way you can step or at least view the Disassembly for what's happening? I will guide you further from there.

    But I suspect it could be something related to (BINIT) method. I had previously tried to use assembly code example to copy code from Flash to RAM before _c_int00 is called. But the code did not work. We cannot use the typical memcpy inside main() to copy from Flash to RAM as main() itself is part of .ti.Ramfunc and needs to be copied to RAM from Flash to be run.

    Right now, resolving the unavailability of debug is low priority issue. The more important issue is to get the whole code running from RAM

    The BINIT method should work for loading code from Flash to RAM and allowing it to execute from there before main has been called. As you correctly stated memcpy cannot do this. Unfortunately without having debug available, that makes it difficult to debug this issue. Can you check your project's map file to verify that the code or relevant functions are at least loaded to the correct Flash bank? You can find this under CPU1_FLASH or the relevant directory for your Build Configuration. Without debug we can't look to see where it gets loaded to at runtime, but we can at least see where the code is first set to.

  • Hi Omer,

    One of the issues we are looking to resolve is that debug is not working.

    We are facing 2 issues:

    1. How do we ensure that only boot code is running directly from Flash while all other code can be run from RAM? I tried to run memcpy.c.obj from RAM, but then microcontroller fails to boot. The currect working memory allocation is shown in photo below. For our purpose memcpy should be running from RAM as we might need to use it  in ISR. This is just one example. Ideally only boot.asm should be running directly from Flash.
    2. With current settings, we cannot debug the code. Debug runs normally when we use a different linker where we load and run code from RAM only.

    So, we cannot use debugger to run our code. Please note that our main application is jumped from our own bootloader, which is at Bank0, sector 0 of Flash and starts by default. I can try to Run the code directly without the bootloader, by moving it to 0x80000.

    Let me attach the current map file. 

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ******************************************************************************
    TMS320C2000 Linker PC v20.2.5
    ******************************************************************************
    >> Linked Thu Nov 30 13:01:12 2023
    OUTPUT FILE NAME: <UV_MotorControl.out>
    ENTRY POINT SYMBOL: "code_start" address: 00086000
    MEMORY CONFIGURATION
    name origin length used unused attr fill
    ---------------------- -------- --------- -------- -------- ---- --------
    PAGE 0:
    RAMGS0_3 0000c000 00007ff8 000072bb 00000d3d RWIX
    BEGIN 00086000 00000002 00000002 00000000 RWIX
    FLASH_BANK0_SEC6_15 00086002 00009ffe 000076a5 00002959 RWIX
    RESET 003fffc0 00000002 00000000 00000002 RWIX
    PAGE 1:
    BOOT_RSVD 00000002 000000f1 00000000 000000f1 RWIX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • I'm not sure why the debugging would not work because of a change in the linker command file (I assume that's what you mean by different linker, but correct me if I'm wrong). Is there an error message or console output that states that the debugger failed to connect? Or is this intentional that you're loading a non-debug version of the code to the device?

    For the sake of being able to look into the first issue, we need to be able to debug the code to see what's happening otherwise I can only take guesses that are more than likely not helpful. I've not heard of memcpy specifically not being able to be run from RAM, does it work fine if run from Flash? Have you verified that it's included with the other functions your copying from Flash to RAM (if so, can you show how this is done)?

  • Hi Omer,

    Can I give you a project file with proprietary code removed for you to experiment with? I have also not tried to debug after eliminating the debugger yet. Please give me some time.

  • Sure you can send me the code so I can try to test it on my side while you try to get your debugger working (you can either privately message me or post the code here).

  • Hi Omer,
    Please give me some time so that I can:

    1. Test the main application without bootloader to check if debugging works
    2. Create a minimal project and send it to you to reproduce the issue. Right now I have some higher priority tasks to attend to.