TI C6000 DSP — Moving Code Sections to External Memory (CCS / JTAG)

1. The Core Problem — Summary

Your .far section is 0x2082C bytes (~130 KB) but only ~0x18A0C (~99 KB) is free in IRAM. You need to move sections to EMIFBSDRAM (at 0xC0000000). The challenges are:

  1. Debugger can't find main → EMIF SDRAM not initialized before code load
  2. Verification error → JTAG trying to verify code in un-initialized SDRAM
  3. Concern about which sections must stay together

2. Root Cause — Why the Debugger Can't Find main in SDRAM

EMIFBSDRAM at 0xC0000000 is NOT self-initializing memory.
Unlike IRAM (on-chip SRAM, always ready), external SDRAM must be configured by the EMIF controller before it is accessible. Until that happens, any attempt to load or run code there results in bus errors, verification failures, or “can’t find main.”

When CCS connects via JTAG:

  1. It resets the DSP
  2. It tries to load your program (.out file sections) into their mapped addresses
  3. If .text is mapped to 0xC0000000 and EMIF/SDRAM is not yet initialized → bus error / can’t find main

3. The Standard Solution — GEL File EMIF Initialization

Your GEL file must initialize the EMIF controller and SDRAM before CCS loads the program.

In CCS, the GEL file is executed at connect time, before program load. You need to add or verify that your GEL file does the following:

GEL File Must Do (in StartUp() or a connected function)

StartUp()
{
    // Step 1: Tell CCS this memory exists and is R/W
    GEL_MapAdd(0xC0000000, 0, 0x10000000, 1, 1);

    // Step 2: Initialize EMIFB registers
    // (specific values depend on your board's SDRAM type/speed)
    *(int*)0x01800000 = 0x...;  // EMIFB SDRAM Control register
    *(int*)0x01800004 = 0x...;  // EMIFB SDRAM Timing register
    *(int*)0x01800008 = 0x...;  // EMIFB Refresh Control register

    // Step 3: (Optional) PLL/clock setup if not already done
}

Critical GEL Line

GEL_MapAdd(0xC0000000, 0, 0x10000000, 1, 1);

This tells the CCS memory map that 0xC0000000–0xCFFFFFFF (256 MB) is valid, readable, and writable. Without this, JTAG will not attempt to load or verify there.

4. CMD File — How to Safely Move Sections

Recommended Section Migration Strategy

Section Can Move to EMIFBSDRAM? Notes
.text Yes (with caveats) Code runs slower from SDRAM; cache helps
.far Yes — most common move Large data arrays, far-call data
.fardata Yes
.const Yes Read-only constants
.data Yes Initialized data
.bss / .neardata Prefer keep near Near-data pointer assumptions
.stack Keep in IRAM Stack must be accessible at boot before EMIF init
.cinit Careful Used at C startup to init .bss/.data — must be accessible early
.sysinit / .gblinit Keep in IRAM Boot-time init code runs before EMIF ready
.vecs / .hwi_vec Keep in IRAM Interrupt vectors must be in fast, always-ready memory
.rtdx_text Keep in IRAM JTAG RTDX communication

Suggested CMD File Changes

SECTIONS
{
    /* ---- KEEP IN IRAM (boot-critical, interrupt, JTAG) ---- */
    .text:             load > IRAM
    .stack:            load > IRAM
    .sysinit:          load > IRAM
    .gblinit:          load > IRAM
    .vecs:             load > IRAM
    .hwi_vec:          load > IRAM
    .hwi:              load > IRAM
    .rtdx_text:        load > IRAM
    .rtdx_data:        load > IRAM
    .ti.handler_table: load > IRAM
    .c6xabi.exidx:     load > IRAM
    .c6xabi.extab:     load > IRAM
    .binit:            load > IRAM
    .init_array:       load > IRAM
    .cinit:            load > IRAM   /* used at C startup */
    .ti.decompress:    load > IRAM

    /* ---- MOVE TO EMIFBSDRAM (large sections) ---- */
    .far:              load > EMIFBSDRAM   /* <-- fixes your overflow */
    .fardata:          load > EMIFBSDRAM
    .const:            load > EMIFBSDRAM

    /* ---- Keep grouped in L3_CBA_RAM ---- */
    GROUP: load > L3_CBA_RAM
    {
        .bss:
        .neardata:
        .rodata:
    }
}

5. Moving .text — Special Considerations

Option A — Move ALL .text to EMIFBSDRAM

.text: load > EMIFBSDRAM

Option B — Split .text (Recommended for Performance)

Keep critical/ISR code in IRAM; move bulk application code to SDRAM:

/* Critical code stays in IRAM */
.text:cinit      load > IRAM
.text:_vectors   load > IRAM

/* Bulk application code in SDRAM */
.text            load > EMIFBSDRAM

Or use #pragma CODE_SECTION in C to place specific functions:

#pragma CODE_SECTION(myLargeFunction, ".text_sdram")

Then in CMD:

.text_sdram: load > EMIFBSDRAM

6. CCS Debug Configuration — What Needs to Change

In CCS Target Configuration (.ccxml)

  1. Confirm your GEL file is assigned to the DSP core
  2. Ensure GEL_MapAdd() covers the EMIFBSDRAM range
  3. Ensure EMIF init happens in OnTargetConnect() or StartUp()

Memory Verification Errors

If you get verification errors, CCS is trying to read back what it wrote to SDRAM but finds mismatches because SDRAM is not properly initialized:

7. Enabling Cache — Essential for SDRAM Code Performance

If you move .text to SDRAM, enable L1P/L2 cache so the DSP caches instructions:

// Set Memory Attribute Register for EMIFBSDRAM range (0xC0000000)
// MAR192 — cacheable, prefetchable
*(unsigned int*)0x01848380 = 0x0F;

Or in CCS: Target → Memory Browser → Configure Cache

8. Complete Checklist for Success

9. Key Takeaway Table

Question Answer
Do sections have to be together? No — sections can be in any memory region independently
Why can't debugger find main in SDRAM? SDRAM not initialized before JTAG loads code
Fix is in which file? GEL file (EMIF init + GEL_MapAdd)
What sections MUST stay in IRAM? .stack, .vecs, .hwi_vec, .sysinit, RTDX sections
Can .far safely move to EMIFBSDRAM? Yes — this is the standard solution
Can .text move to EMIFBSDRAM? Yes — after GEL fix; use cache for performance
Verification error cause? JTAG reading back from uninitialized SDRAM
The single most important fix: Make sure your GEL file initializes the EMIF-B controller and calls GEL_MapAdd(0xC0000000, ...) before CCS loads the program. Once that is working, moving .far (and optionally .text) to EMIFBSDRAM in the CMD file will work perfectly and the debugger will find main without issues.