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.

F2837xD + TI-RTOS + External Memory

Other Parts Discussed in Thread: SYSBIOS

I'm using the TI-RTOS and the F28377D Chip with an external memory device attached. I've already configured and can use the external memory to store data or execute code but I have a couple of questions.

After I setup the pins and registers to support the EMIF1 interface to the External Asynchronous RAM I create an HeapMem_Handle to the starting at the linker location for the external memory data section. This returns a valid handle. 

Currently I'm doing the following for creating the handle:

HeapMem_Params_init(&params);

params.buf = &extHeapStart;
params.size = 0xF0000; //TODO Determine how to get this programmatically

ext_mem_part_id = HeapMem_create(&params, NULL);

When I used the extHeapSize variable that I created in the linker file I got the size equal to the global variables that I manually allocated to this heap not the size of the memory region which is what I want as I need to be able to allocate data off of this heap. 

1. Is there a way to get my heap's full size programmatically rather than the hard coded value which is much less maintainable?

I have multiple tasks running in the system and each task has it's own stack. I want to allocate some or all of these off of the external heap I've set up due to their sizes. I tried the following in the task creation:

Task_Params_init(&params);

params.stackSize = stack_size;

params.priority = priority;
params.arg0 = arg1;

#ifdef USE_EXT_RAM
//Use the External Memory
if(opts == 1) {
    params.stackHeap = HeapMem_Handle_to_xdc_runtime_IHeap(ext_mem_part_id);
}
#endif

task_id = Task_create((Task_FuncPtr)func, &params, NULL);

When I try to run the program I get the following exception:

[C28xx_CPU1] ti.sysbios.family.c28.TaskSupport: line 114: Stack (0x110000) not located on PAGE 0 (stack must be located entirely below 0x10000)
xdc.runtime.Error.raise: terminating execution

I've tried moving the heap to PAGE 0 but I got the same error. Is it possible to use the external memory which starts after 0x10000? 

Finally I'm trying to get the statistics on how much memory is actually being used.

I've run: HeapMem_getStats(ext_mem_part_id, &stats); 

res = HeapMem_isBlocking(ext_mem_part_id);
HeapMem_getExtendedStats(ext_mem_part_id, &ext_stats);

The values I get don't make sense:

stats.totalSize = 983040 (0xF0000)

stats.totalFreeSize = 1134516288 (0x439F5840)

stats.largestFreeSize = 1134516288 (0x439F5840)

is Blocking = True

ext_stats.buf = 0x110000

ext_stats.size = 983040 (This one prints out incorrectly in my sprintf function)

Is there something I need to do in order to get valid statistics from external memory?

Thanks,

Anthony

  • Hi Anthony,

    Anthony Gendreau said:

    After I setup the pins and registers to support the EMIF1 interface to the External Asynchronous RAM I create an HeapMem_Handle to the starting at the linker location for the external memory data section. This returns a valid handle. 

    Currently I'm doing the following for creating the handle:

    HeapMem_Params_init(&params);

    params.buf = &extHeapStart;
    params.size = 0xF0000; //TODO Determine how to get this programmatically

    ext_mem_part_id = HeapMem_create(&params, NULL);

    When I used the extHeapSize variable that I created in the linker file I got the size equal to the global variables that I manually allocated to this heap not the size of the memory region which is what I want as I need to be able to allocate data off of this heap. 

    1. Is there a way to get my heap's full size programmatically rather than the hard coded value which is much less maintainable?

    Are "extHeapStart" and "extHeapSize" both symbols you created in the linker script ? Can you share your linker script ? Also, from your post it looks like you want to make the entire external memory heap. Is that correct ?

    Anthony Gendreau said:

    I have multiple tasks running in the system and each task has it's own stack. I want to allocate some or all of these off of the external heap I've set up due to their sizes. I tried the following in the task creation:

    Task_Params_init(&params);

    params.stackSize = stack_size;

    params.priority = priority;
    params.arg0 = arg1;

    #ifdef USE_EXT_RAM
    //Use the External Memory
    if(opts == 1) {
        params.stackHeap = HeapMem_Handle_to_xdc_runtime_IHeap(ext_mem_part_id);
    }
    #endif

    task_id = Task_create((Task_FuncPtr)func, &params, NULL);

    When I try to run the program I get the following exception:

    [C28xx_CPU1] ti.sysbios.family.c28.TaskSupport: line 114: Stack (0x110000) not located on PAGE 0 (stack must be located entirely below 0x10000)
    xdc.runtime.Error.raise: terminating execution

    I've tried moving the heap to PAGE 0 but I got the same error. Is it possible to use the external memory which starts after 0x10000? 

    The stack pointer on the C28x is only 16-bits wide. Therefore, the stack needs to placed such that it lies entirely withing a 0-0xFFFF address range.

    Anthony Gendreau said:

    Finally I'm trying to get the statistics on how much memory is actually being used.

    I've run: HeapMem_getStats(ext_mem_part_id, &stats); 

    res = HeapMem_isBlocking(ext_mem_part_id);
    HeapMem_getExtendedStats(ext_mem_part_id, &ext_stats);

    The values I get don't make sense:

    stats.totalSize = 983040 (0xF0000)

    stats.totalFreeSize = 1134516288 (0x439F5840)

    stats.largestFreeSize = 1134516288 (0x439F5840)

    is Blocking = True

    ext_stats.buf = 0x110000

    ext_stats.size = 983040 (This one prints out incorrectly in my sprintf function)

    Is there something I need to do in order to get valid statistics from external memory?

    Maybe the heap data structures have somehow got corrupted or were not properly init'ed. At what point in your application do you call HeapMem_getStats() ? Is it in main() or from within another task thread.

    Best,

    Ashish

  • Are "extHeapStart" and "extHeapSize" both symbols you created in the linker script ? Can you share your linker script ? Also, from your post it looks like you want to make the entire external memory heap. Is that correct ?

     

    Yes I create extHeapStart and extHeapSize in the linker file. Shown in part below:

    MEMORY

    {

    PAGE 0 :  /* Program Memory */

    ...

    PAGE 1 : /* Data Memory */

    ...

        /* External RAMs */

        RAMEXT_FUNCS  : origin = 0x100000, length = 0x10000

        RAMEXT_DATA   : origin = 0x110000, length = 0xF0000

    }

    SECTIONS
    {

    ....

        /* External Heap */

        extHeap           : > RAMEXT_DATA PAGE = 1

                              START(_extHeapStart),

                              SIZE(_extHeapSize),

                              END(_extHeapEnd)

    }

    There is code executing out of the RAMEXT_FUNCS section of the memory but that is symbolically different region then the heap. I do have a large set of globals that I've moved to the extHeap using is this causing an issue?

    #ifdef USE_EXT_RAM

    #pragma SET_DATA_SECTION("extHeap")

    #endif

    The stack pointer on the C28x is only 16-bits wide. Therefore, the stack needs to placed such that it lies entirely withing a 0-0xFFFF address range.

    Ok I'll work around the limitation on the stack pointer size. 

    Maybe the heap data structures have somehow got corrupted or were not properly init'ed. At what point in your application do you call HeapMem_getStats() ? Is it in main() or from within another task thread.

     

    Currently I'm running the HeapMem_getStats() at the end of my main function after I've done all of my initialization code but before I actually call BIOS_start(). As for initialization it includes creating all of my tasks which is done programmatically. I also run the same call on the default heap instance and that works successfully. 

    Are "extHeapStart" and "extHeapSize" both symbols you created in the linker script ? Can you share your linker script ? Also, from your post it looks like you want to make the entire external memory heap. Is that correct ?

  • Hi Anthony,

    Anthony Gendreau said:

    #ifdef USE_EXT_RAM

    #pragma SET_DATA_SECTION("extHeap")

    #endif

    This is not going to put the heap in external memory. Its just going to put data into external RAM. Since when you create a HeapMem instance, the buffer points to this memory, I believe data corruption can potentially occur as global data as well as the heap are pointing to same memory.

    In order to create and put the heap into external RAM and use it as the heap for all allocations (i.e. make it the default heap), you can do the following (untested code):

    In the *.cfg script:
    
    var Memory = xdc.useModule('xdc.runtime.Memory');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var params = new HeapMem.Params;
    params.size = 0xF0000;
    params.sectionName = ".extHeap";
    Program.global.heap0 = HeapMem.create(params);
    Memory.defaultHeapInstance = Program.global.heap0; // Make this the default heap
    
    In the *.c file:
    #include <xdc/runtime/Memory.h>
    #include <xdc/cfg/global.h>
    
    func() {
        Memory_Stats stat;
        // Get stats for heap0 that was created at build time
        Memory_getStats(HeapMem_Handle_to_xdc_runtime_IHeap(heap0), &stat);
        ...
    }
    
    Linker script:
    
    SECTIONS
    {
    
    ....
    
        /* External Heap */
    
        .extHeap          :   START(_extHeapStart),
                              SIZE(_extHeapSize),
                              END(_extHeapEnd)
                              { *(.extHeap) } > RAMEXT_DATA PAGE = 1
    }

    Also, you will need to remove the SET_DATA_SECTION("extHeap") call from the code. If you need to place global data in external RAM, you can create a different section for that purpose and place it in external RAM.

    Best,

    Ashish

  • I understand that the #pragma line didn't make the global memory part of the heap. I'll separate the sections to avoid any potential issues.

    The EMIF interface isn't setup until some of my initialize code runs in my main() function before I call BIOS_start(). \

    If I create the heap in the *.cfg file will there be an issue since the interface is set up yet?

    Also if I set the default heap to my external memory will the stack for the tasks attempt to create off of that heap and then fail because the heap is outside of the valid memory range?

  • Anthony Gendreau said:

    The EMIF interface isn't setup until some of my initialize code runs in my main() function before I call BIOS_start(). \

    If I create the heap in the *.cfg file will there be an issue since the interface is set up yet?

    If the heap instance is created in the cfg file then the heap initialization/startup functions that are run during boot up (before main() is called), will attempt to initialize the heap buffer. These functions will generate a fault if the external RAM is not accessible.

    In order to avoid this problem, you can initialize the EMIF interface very early (before the heap init function is called) by registering the EMIF init function as a reset function (see http://rtsc.eclipse.org/cdoc-tip/xdc/runtime/Reset.html#fxns for more info on registering reset functions).

    Anthony Gendreau said:

    Also if I set the default heap to my external memory will the stack for the tasks attempt to create off of that heap and then fail because the heap is outside of the valid memory range?

    Yes, if the HeapMem instance is also the default heap instance then task stack will be created on this heap (unless the task config params specify stack base address).

    Best,

    Ashish

  • Everything works except setting the default heap. If I do that I get the same stack issue when I create the task. So currently I'm moving forward with 2 heaps (1 internal and 1 external).