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.

c55 local variables in wrong memory



Hello,

I have some code where I use a local variable to do a few operations on memory before writing it out to memory in the CE0 space, but for some reason the local variables are being stored at memory location 0x00 which is a reserved area for registers. Because of this, the values arent stored/read correctly and it's causing issues. Some example code is

volatile unsigned long *addr;

void display_write(volatile unsigned long offset, char pixel) {

addr = display_base_address+offset;
addr = (volatile unsigned long*)(((volatile unsigned long)addr)>>1);
*addr = pixel;
}

It stores addr at 0x00 in this case. Here is my memory map

MEMORY CONFIGURATION

name origin length used unused attr fill
(bytes) (bytes) (bytes) (bytes)
---------------------- -------- --------- -------- -------- ---- --------
PAGE 0:
DARAM01 00000100 00003f00 000004eb 00003a15 RWIX

PAGE 1:
DARAM23 00004000 00004000 00000000 00004000 RWIX


SECTION ALLOCATION MAP
(Addresses surrounded by []'s are displayed for convenience only!)

output attributes/
section page orgn(bytes) orgn(words) len(bytes) len(words) input sections
-------- ---- ----------- ----------- ---------- ---------- --------------
.cinit 0 [ 00000100 ] 00000080 * 00000000 UNINITIALIZED

.text 0 00000100 [ 00000080 ] 000004b7 *
00000100 [ 00000080 ] 0000020a * McBSP.obj (.text)
0000030a [ 00000185 ] 000000e8 * EMIF.obj (.text)
000003f2 [ 000001f9 ] 000000a3 * main.obj (.text)
00000495 [ 0000024a+] 0000009d * GPIO.obj (.text)
00000532 [ 00000299 ] 00000067 * display.obj (.text)
00000599 [ 000002cc+] 0000001d * CLOCK.obj (.text)
000005b6 [ 000002db ] 00000001 * --HOLE-- [fill = 20]

.bss 0 [ 000005b8 ] 000002dc * 0000001a UNINITIALIZED
[ 000005b8 ] 000002dc * 00000010 EMIF.obj (.bss)
[ 000005d8 ] 000002ec * 00000006 display.obj (.bss)
[ 000005e4 ] 000002f2 * 00000004 main.obj (.bss)

.data 1 [ 00004000 ] 00002000 * 00000000 UNINITIALIZED

and my linker cmd file is

/****************************************************************************/
/* C5501.cmd */
/* Copyright (c) 2010 Texas Instruments Incorporated */
/* */
/* Description: This file is a sample linker command file that can be */
/* used for linking programs built with the C compiler and */
/* running the resulting .out file on a C5502. */
/* Use it as a guideline. You will want to */
/* change the memory layout to match your specific */
/* target system. You may want to change the allocation */
/* scheme according to the size of your program. */
/* */
/****************************************************************************/
-heap 0x1000
-stack 0x1000


MEMORY
{
PAGE 0 :

DARAM01 : origin = 0x000100, length = 0x003F00

PAGE 1 :

DARAM23 : origin = 0x004000, length = 0x004000

}

SECTIONS
{
.cinit > DARAM01 PAGE 0
.text > DARAM01 PAGE 0
.stack > DARAM23 PAGE 1
.sysstack > DARAM23 PAGE 1
.sysmem > DARAM23 PAGE 1
.data > DARAM23 PAGE 1
.cio > DARAM01 PAGE 0
.bss > DARAM01 PAGE 0
.const > DARAM01 PAGE 0
}

  • You've shown us part of the linker map file, which helps, but we need to see the part of the linker command file where it shows the address of "addr".  I see nothing in the linker command file which would allow the linker to place anything at address 0x0, so there is probably something strange going on.

    In this example, "addr" is not a local variable in the usual C terminology.  A local variable is one defined inside of a function.  It matters because for C55x, local variables are SP-relative, and global variables are .bss-relative.

  • Sorry. Here is the full map file for my current build

    ******************************************************************************
    TMS320C55x Linker PC v4.4.1
    ******************************************************************************
    >> Linked Sat Mar 09 18:28:56 2013

    OUTPUT FILE NAME: <StereoDSP.out>
    ENTRY POINT SYMBOL: "_main" address: 000003f2


    MEMORY CONFIGURATION

    name origin length used unused attr fill
    (bytes) (bytes) (bytes) (bytes)
    ---------------------- -------- --------- -------- -------- ---- --------
    PAGE 0:
    DARAM01 00000100 00003f00 000004eb 00003a15 RWIX

    PAGE 1:
    DARAM23 00004000 00004000 00000000 00004000 RWIX


    SECTION ALLOCATION MAP
    (Addresses surrounded by []'s are displayed for convenience only!)

    output attributes/
    section page orgn(bytes) orgn(words) len(bytes) len(words) input sections
    -------- ---- ----------- ----------- ---------- ---------- --------------
    .cinit 0 [ 00000100 ] 00000080 * 00000000 UNINITIALIZED

    .text 0 00000100 [ 00000080 ] 000004b7 *
    00000100 [ 00000080 ] 0000020a * McBSP.obj (.text)
    0000030a [ 00000185 ] 000000e8 * EMIF.obj (.text)
    000003f2 [ 000001f9 ] 000000a3 * main.obj (.text)
    00000495 [ 0000024a+] 0000009d * GPIO.obj (.text)
    00000532 [ 00000299 ] 00000067 * display.obj (.text)
    00000599 [ 000002cc+] 0000001d * CLOCK.obj (.text)
    000005b6 [ 000002db ] 00000001 * --HOLE-- [fill = 20]

    .bss 0 [ 000005b8 ] 000002dc * 0000001a UNINITIALIZED
    [ 000005b8 ] 000002dc * 00000010 EMIF.obj (.bss)
    [ 000005d8 ] 000002ec * 00000006 display.obj (.bss)
    [ 000005e4 ] 000002f2 * 00000004 main.obj (.bss)

    .data 1 [ 00004000 ] 00002000 * 00000000 UNINITIALIZED


    GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name

    abs. value/
    byte addr word addr name
    --------- --------- ----
    00000002 $TI_capability$C5500$CallingConvention
    00000002 $TI_capability$C5500$MemoryModel
    00000001 $TI_capability_requires_rev2
    000002dc .bss
    00002000 .data
    00000100 .text
    ffffffff ___binit__
    000002dc ___bss__
    ffffffff ___c_args__
    ffffffff ___cinit__
    00002000 ___data__
    00002000 ___edata__
    000002f6 ___end__
    000005b7 ___etext__
    ffffffff ___pinit__
    00000100 ___text__
    000002f0 _addr
    00000599 _clock_init
    000002ec _display_base_address
    00000532 _display_init
    00000591 _display_size
    000002ee _display_total_size
    00000554 _display_write
    0000036e _emif_base_ce
    000002dc _emif_base_ce0
    000002de _emif_base_ce1
    000002e0 _emif_base_ce2
    000002e2 _emif_base_ce3
    000002e4 _emif_ce0_size
    000002e6 _emif_ce1_size
    000002e8 _emif_ce2_size
    000002ea _emif_ce3_size
    000003b2 _emif_ce_size
    0000030a _emif_init
    00000510 _gpio_read
    00000505 _gpio_read_all
    000004ba _gpio_set
    00000495 _gpio_set_all
    000002f4 _i
    000003f2 _main
    000001a5 _mcbsp_init_0
    0000015c _mcbsp_loopback
    00000100 _mcbsp_off
    00000126 _mcbsp_on
    000002d8 _mcbsp_read_byte
    00000208 _mcbsp_recv_full
    00000270 _mcbsp_recv_ready
    0000014c _mcbsp_reset
    0000023c _mcbsp_trans_empty
    000002a4 _mcbsp_trans_ready
    000002ee _mcbsp_write_byte
    000002f2 _total_size
    ffffffff binit
    ffffffff cinit
    00002000 edata
    000002f6 end
    000005b7 etext
    ffffffff pinit


    GLOBAL SYMBOLS: SORTED BY Symbol Address

    abs. value/
    byte addr word addr name
    --------- --------- ----
    00000001 $TI_capability_requires_rev2
    00000002 $TI_capability$C5500$CallingConvention
    00000002 $TI_capability$C5500$MemoryModel
    00000100 .text
    00000100 ___text__
    00000100 _mcbsp_off
    00000126 _mcbsp_on
    0000014c _mcbsp_reset
    0000015c _mcbsp_loopback
    000001a5 _mcbsp_init_0
    00000208 _mcbsp_recv_full
    0000023c _mcbsp_trans_empty
    00000270 _mcbsp_recv_ready
    000002a4 _mcbsp_trans_ready
    000002d8 _mcbsp_read_byte
    000002ee _mcbsp_write_byte
    0000030a _emif_init
    0000036e _emif_base_ce
    000003b2 _emif_ce_size
    000003f2 _main
    00000495 _gpio_set_all
    000004ba _gpio_set
    00000505 _gpio_read_all
    00000510 _gpio_read
    00000532 _display_init
    00000554 _display_write
    00000591 _display_size
    00000599 _clock_init
    000005b7 ___etext__
    000005b7 etext
    000002dc .bss
    000002dc ___bss__
    000002dc _emif_base_ce0
    000002de _emif_base_ce1
    000002e0 _emif_base_ce2
    000002e2 _emif_base_ce3
    000002e4 _emif_ce0_size
    000002e6 _emif_ce1_size
    000002e8 _emif_ce2_size
    000002ea _emif_ce3_size
    000002ec _display_base_address
    000002ee _display_total_size
    000002f0 _addr
    000002f2 _total_size
    000002f4 _i
    000002f6 ___end__
    000002f6 end
    00002000 .data
    00002000 ___data__
    00002000 ___edata__
    00002000 edata
    ffffffff ___binit__
    ffffffff ___c_args__
    ffffffff ___cinit__
    ffffffff ___pinit__
    ffffffff binit
    ffffffff cinit
    ffffffff pinit

    [58 symbols]

    As a side note, this was my attempt at making it work. Originally, addr was a local variable, but I tried moving it out of the function so that the system would write to 0x00 and 0x02. addr in this case is in a good location, but the asm code still writes to 0x00 and 0x02 within the routine. As soon as the function is entered, it moves AC0 into 0x00 so that it can use AC0 for other things. A few lines after, it reads back the value from 0x00 (incorrectly, because these are registers in 0x00-0x80) and does this a few more times. I have no idea why it would want to use these memory addresses as temporary storage when there are so many more registers free...

  • Jama Mohamed said:
    I have no idea why it would want to use these memory addresses as temporary storage when there are so many more registers free...

    Primarily because you've defined "offset" to be volatile.  Even if you use the optimizer, the compiler will generally be forced to keep volatile objects in memory.  In your test case, it's pointless to define offset as volatile, because it is a plain integer-typed object local to the function.  Remove volatile from the declaration of offset, remove volatile from the cast of addr to unsigned long, and turn on the optimizer to at least level 0.

    I'm guessing the address of the variable "addr" is not the issue, but its contents are.  What is the value of the contents of addr after the first statement in the function?

  • The value of addr is 0x00010200 in the first loop which is wrong. It should be 0x00010000. The reason that 0x200 is there is because the value at 0x00 is being grabbed as 0x100 and then shifted. That value should be 0x00 because AC0 was stored into it (and AC0 was zero). As a reference, this is what the disassembly looks like

    display_write:
    000443: 4efd                             AADD #-3,SP
    000445: eb0008                       MOV AC0,dbl(@#00h)
    000448: 20                                 NOP
    000449: 20                                 NOP
    27 addr = display_base_address+offset;
    00044a: ed31bf00025e          MOV dbl(*(#0025eh)),XAR3
    000450: ed0018                       MOV dbl(@#00h),AC1
    000453: 90b0                            MOV XAR3,AC0
    000455: 5010                            SFTL AC1,#1
    000457: 2410                            ADD AC1,AC0
    000459: eb3108000262         MOV AC0,dbl(*(#00262h))
    28 addr = (volatile unsigned long*)(((volatile unsigned long)addr)>>1);
    00045f: 4440                             SFTS AC0,#-1
    000461: eb3108000262         MOV AC0,dbl(*(#00262h))
    29 *addr = pixel;
    000467: ed31bf000262           MOV dbl(*(#00262h)),XAR3
    00046d: 2240                            MOV T0,AC0
    00046f: eb6108                        MOV AC0,dbl(*AR3)
    30 }
    000472: 4e03                           AADD #3,SP
    000474: 4804                            RET

    Commands like "MOV AC0,dbl(@#00h)" are the issue, where it is using memory address 0x00 when it absolutely shouldnt be.

    Also, here is the updated memory  map

    ******************************************************************************
    TMS320C55x Linker PC v4.4.1
    ******************************************************************************
    >> Linked Sun Mar 10 14:46:09 2013

    OUTPUT FILE NAME: <StereoDSP.out>
    ENTRY POINT SYMBOL: "_main" address: 000002ff


    MEMORY CONFIGURATION

    name origin length used unused attr fill
    (bytes) (bytes) (bytes) (bytes)
    ---------------------- -------- --------- -------- -------- ---- --------
    PAGE 0:
    DARAM01 00000100 00003f00 000003d0 00003b30 RWIX

    PAGE 1:
    DARAM23 00004000 00004000 00000000 00004000 RWIX


    SECTION ALLOCATION MAP
    (Addresses surrounded by []'s are displayed for convenience only!)

    output attributes/
    section page orgn(bytes) orgn(words) len(bytes) len(words) input sections
    -------- ---- ----------- ----------- ---------- ---------- --------------
    .cinit 0 [ 00000100 ] 00000080 * 00000000 UNINITIALIZED

    .text 0 00000100 [ 00000080 ] 0000039c *
    00000100 [ 00000080 ] 00000121 * McBSP.obj (.text)
    00000221 [ 00000110+] 000000de * EMIF.obj (.text)
    000002ff [ 0000017f+] 000000a3 * main.obj (.text)
    000003a2 [ 000001d1 ] 0000007f * GPIO.obj (.text)
    00000421 [ 00000210+] 0000005d * display.obj (.text)
    0000047e [ 0000023f ] 0000001d * CLOCK.obj (.text)
    0000049b [ 0000024d ] 00000001 * --HOLE-- [fill = 20]

    .bss 0 [ 0000049c ] 0000024e * 0000001a UNINITIALIZED
    [ 0000049c ] 0000024e * 00000010 EMIF.obj (.bss)
    [ 000004bc ] 0000025e * 00000006 display.obj (.bss)
    [ 000004c8 ] 00000264 * 00000004 main.obj (.bss)

    .data 1 [ 00004000 ] 00002000 * 00000000 UNINITIALIZED


    GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name

    abs. value/
    byte addr word addr name
    --------- --------- ----
    00000002 $TI_capability$C5500$CallingConvention
    00000002 $TI_capability$C5500$MemoryModel
    00000001 $TI_capability_requires_rev2
    0000024e .bss
    00002000 .data
    00000100 .text
    ffffffff ___binit__
    0000024e ___bss__
    ffffffff ___c_args__
    ffffffff ___cinit__
    00002000 ___data__
    00002000 ___edata__
    00000268 ___end__
    0000049c ___etext__
    ffffffff ___pinit__
    00000100 ___text__
    00000262 _addr
    0000047e _clock_init
    0000025e _display_base_address
    00000421 _display_init
    00000476 _display_size
    00000260 _display_total_size
    00000443 _display_write
    00000285 _emif_base_ce
    0000024e _emif_base_ce0
    00000250 _emif_base_ce1
    00000252 _emif_base_ce2
    00000254 _emif_base_ce3
    00000256 _emif_ce0_size
    00000258 _emif_ce1_size
    0000025a _emif_ce2_size
    0000025c _emif_ce3_size
    000002c4 _emif_ce_size
    00000221 _emif_init
    00000407 _gpio_read
    000003fc _gpio_read_all
    000003bf _gpio_set
    000003a2 _gpio_set_all
    00000266 _i
    000002ff _main
    0000015a _mcbsp_init_0
    00000148 _mcbsp_loopback
    00000100 _mcbsp_off
    0000011e _mcbsp_on
    00000205 _mcbsp_read_byte
    000001bd _mcbsp_recv_full
    000001e1 _mcbsp_recv_ready
    0000013c _mcbsp_reset
    000001cf _mcbsp_trans_empty
    000001f3 _mcbsp_trans_ready
    00000213 _mcbsp_write_byte
    00000264 _total_size
    ffffffff binit
    ffffffff cinit
    00002000 edata
    00000268 end
    0000049c etext
    ffffffff pinit


    GLOBAL SYMBOLS: SORTED BY Symbol Address

    abs. value/
    byte addr word addr name
    --------- --------- ----
    00000001 $TI_capability_requires_rev2
    00000002 $TI_capability$C5500$CallingConvention
    00000002 $TI_capability$C5500$MemoryModel
    00000100 .text
    00000100 ___text__
    00000100 _mcbsp_off
    0000011e _mcbsp_on
    0000013c _mcbsp_reset
    00000148 _mcbsp_loopback
    0000015a _mcbsp_init_0
    000001bd _mcbsp_recv_full
    000001cf _mcbsp_trans_empty
    000001e1 _mcbsp_recv_ready
    000001f3 _mcbsp_trans_ready
    00000205 _mcbsp_read_byte
    00000213 _mcbsp_write_byte
    00000221 _emif_init
    00000285 _emif_base_ce
    000002c4 _emif_ce_size
    000002ff _main
    000003a2 _gpio_set_all
    000003bf _gpio_set
    000003fc _gpio_read_all
    00000407 _gpio_read
    00000421 _display_init
    00000443 _display_write
    00000476 _display_size
    0000047e _clock_init
    0000024e .bss
    0000024e ___bss__
    0000049c ___etext__
    0000024e _emif_base_ce0
    0000049c etext
    00000250 _emif_base_ce1
    00000252 _emif_base_ce2
    00000254 _emif_base_ce3
    00000256 _emif_ce0_size
    00000258 _emif_ce1_size
    0000025a _emif_ce2_size
    0000025c _emif_ce3_size
    0000025e _display_base_address
    00000260 _display_total_size
    00000262 _addr
    00000264 _total_size
    00000266 _i
    00000268 ___end__
    00000268 end
    00002000 .data
    00002000 ___data__
    00002000 ___edata__
    00002000 edata
    ffffffff ___binit__
    ffffffff ___c_args__
    ffffffff ___cinit__
    ffffffff ___pinit__
    ffffffff binit
    ffffffff cinit
    ffffffff pinit

    [58 symbols]

     

  • The value of addr is 0x00010200 in the first loop which is wrong. It should be 0x00010000. The reason that 0x200 is there is because the value at 0x00 is being grabbed as 0x100 and then shifted. That value should be 0x00 because AC0 was stored into it (and AC0 was zero). As a reference, this is what the disassembly looks like

    display_write:
    000443: 4efd                             AADD #-3,SP
    000445: eb0008                       MOV AC0,dbl(@#00h)
    000448: 20                                 NOP
    000449: 20                                 NOP
    27 addr = display_base_address+offset;
    00044a: ed31bf00025e          MOV dbl(*(#0025eh)),XAR3
    000450: ed0018                       MOV dbl(@#00h),AC1
    000453: 90b0                            MOV XAR3,AC0
    000455: 5010                            SFTL AC1,#1
    000457: 2410                            ADD AC1,AC0
    000459: eb3108000262         MOV AC0,dbl(*(#00262h))
    28 addr = (volatile unsigned long*)(((volatile unsigned long)addr)>>1);
    00045f: 4440                             SFTS AC0,#-1
    000461: eb3108000262         MOV AC0,dbl(*(#00262h))
    29 *addr = pixel;
    000467: ed31bf000262           MOV dbl(*(#00262h)),XAR3
    00046d: 2240                            MOV T0,AC0
    00046f: eb6108                        MOV AC0,dbl(*AR3)
    30 }
    000472: 4e03                           AADD #3,SP
    000474: 4804                            RET

    Commands like "MOV AC0,dbl(@#00h)" are the issue, where it is using memory address 0x00 when it absolutely shouldnt be.

    Here is the updated memory map

    ******************************************************************************
    TMS320C55x Linker PC v4.4.1 
    ******************************************************************************
    >> Linked Sun Mar 10 14:46:09 2013

    OUTPUT FILE NAME: <StereoDSP.out>
    ENTRY POINT SYMBOL: "_main" address: 000002ff


    MEMORY CONFIGURATION

    name origin length used unused attr fill
    (bytes) (bytes) (bytes) (bytes)
    ---------------------- -------- --------- -------- -------- ---- --------
    PAGE 0:
    DARAM01 00000100 00003f00 000003d0 00003b30 RWIX

    PAGE 1:
    DARAM23 00004000 00004000 00000000 00004000 RWIX


    SECTION ALLOCATION MAP
    (Addresses surrounded by []'s are displayed for convenience only!)

    output attributes/
    section page orgn(bytes) orgn(words) len(bytes) len(words) input sections
    -------- ---- ----------- ----------- ---------- ---------- --------------
    .cinit 0 [ 00000100 ] 00000080 * 00000000 UNINITIALIZED

    .text 0 00000100 [ 00000080 ] 0000039c * 
    00000100 [ 00000080 ] 00000121 * McBSP.obj (.text)
    00000221 [ 00000110+] 000000de * EMIF.obj (.text)
    000002ff [ 0000017f+] 000000a3 * main.obj (.text)
    000003a2 [ 000001d1 ] 0000007f * GPIO.obj (.text)
    00000421 [ 00000210+] 0000005d * display.obj (.text)
    0000047e [ 0000023f ] 0000001d * CLOCK.obj (.text)
    0000049b [ 0000024d ] 00000001 * --HOLE-- [fill = 20]

    .bss 0 [ 0000049c ] 0000024e * 0000001a UNINITIALIZED
    [ 0000049c ] 0000024e * 00000010 EMIF.obj (.bss)
    [ 000004bc ] 0000025e * 00000006 display.obj (.bss)
    [ 000004c8 ] 00000264 * 00000004 main.obj (.bss)

    .data 1 [ 00004000 ] 00002000 * 00000000 UNINITIALIZED


    GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name

    abs. value/
    byte addr word addr name
    --------- --------- ----
    00000002 $TI_capability$C5500$CallingConvention
    00000002 $TI_capability$C5500$MemoryModel
    00000001 $TI_capability_requires_rev2
    0000024e .bss
    00002000 .data
    00000100 .text
    ffffffff ___binit__
    0000024e ___bss__
    ffffffff ___c_args__
    ffffffff ___cinit__
    00002000 ___data__
    00002000 ___edata__
    00000268 ___end__
    0000049c ___etext__
    ffffffff ___pinit__
    00000100 ___text__
    00000262 _addr
    0000047e _clock_init
    0000025e _display_base_address
    00000421 _display_init
    00000476 _display_size
    00000260 _display_total_size
    00000443 _display_write
    00000285 _emif_base_ce
    0000024e _emif_base_ce0
    00000250 _emif_base_ce1
    00000252 _emif_base_ce2
    00000254 _emif_base_ce3
    00000256 _emif_ce0_size
    00000258 _emif_ce1_size
    0000025a _emif_ce2_size
    0000025c _emif_ce3_size
    000002c4 _emif_ce_size
    00000221 _emif_init
    00000407 _gpio_read
    000003fc _gpio_read_all
    000003bf _gpio_set
    000003a2 _gpio_set_all
    00000266 _i
    000002ff _main
    0000015a _mcbsp_init_0
    00000148 _mcbsp_loopback
    00000100 _mcbsp_off
    0000011e _mcbsp_on
    00000205 _mcbsp_read_byte
    000001bd _mcbsp_recv_full
    000001e1 _mcbsp_recv_ready
    0000013c _mcbsp_reset
    000001cf _mcbsp_trans_empty
    000001f3 _mcbsp_trans_ready
    00000213 _mcbsp_write_byte
    00000264 _total_size
    ffffffff binit
    ffffffff cinit
    00002000 edata
    00000268 end
    0000049c etext
    ffffffff pinit


    GLOBAL SYMBOLS: SORTED BY Symbol Address

    abs. value/
    byte addr word addr name
    --------- --------- ----
    00000001 $TI_capability_requires_rev2
    00000002 $TI_capability$C5500$CallingConvention
    00000002 $TI_capability$C5500$MemoryModel
    00000100 .text
    00000100 ___text__
    00000100 _mcbsp_off
    0000011e _mcbsp_on
    0000013c _mcbsp_reset
    00000148 _mcbsp_loopback
    0000015a _mcbsp_init_0
    000001bd _mcbsp_recv_full
    000001cf _mcbsp_trans_empty
    000001e1 _mcbsp_recv_ready
    000001f3 _mcbsp_trans_ready
    00000205 _mcbsp_read_byte
    00000213 _mcbsp_write_byte
    00000221 _emif_init
    00000285 _emif_base_ce
    000002c4 _emif_ce_size
    000002ff _main
    000003a2 _gpio_set_all
    000003bf _gpio_set
    000003fc _gpio_read_all
    00000407 _gpio_read
    00000421 _display_init
    00000443 _display_write
    00000476 _display_size
    0000047e _clock_init
    0000024e .bss
    0000024e ___bss__
    0000049c ___etext__
    0000024e _emif_base_ce0
    0000049c etext
    00000250 _emif_base_ce1
    00000252 _emif_base_ce2
    00000254 _emif_base_ce3
    00000256 _emif_ce0_size
    00000258 _emif_ce1_size
    0000025a _emif_ce2_size
    0000025c _emif_ce3_size
    0000025e _display_base_address
    00000260 _display_total_size
    00000262 _addr
    00000264 _total_size
    00000266 _i
    00000268 ___end__
    00000268 end
    00002000 .data
    00002000 ___data__
    00002000 ___edata__
    00002000 edata
    ffffffff ___binit__
    ffffffff ___c_args__
    ffffffff ___cinit__
    ffffffff ___pinit__
    ffffffff binit
    ffffffff cinit
    ffffffff pinit

    [58 symbols]

     

  • The value of addr is 0x00010200 in the first loop which is wrong. It should be 0x00010000. The reason that 0x200 is there is because the value at 0x00 is being grabbed as 0x100 and then shifted. That value should be 0x00 because AC0 was stored into it (and AC0 was zero). As a reference, this is what the disassembly looks like

    display_write:
    000443: 4efd                             AADD #-3,SP
    000445: eb0008                       MOV AC0,dbl(@#00h)
    000448: 20                                 NOP
    000449: 20                                 NOP
    27 addr = display_base_address+offset;
    00044a: ed31bf00025e          MOV dbl(*(#0025eh)),XAR3
    000450: ed0018                       MOV dbl(@#00h),AC1
    000453: 90b0                            MOV XAR3,AC0
    000455: 5010                            SFTL AC1,#1
    000457: 2410                            ADD AC1,AC0
    000459: eb3108000262         MOV AC0,dbl(*(#00262h))
    28 addr = (volatile unsigned long*)(((volatile unsigned long)addr)>>1);
    00045f: 4440                             SFTS AC0,#-1
    000461: eb3108000262         MOV AC0,dbl(*(#00262h))
    29 *addr = pixel;
    000467: ed31bf000262           MOV dbl(*(#00262h)),XAR3
    00046d: 2240                            MOV T0,AC0
    00046f: eb6108                        MOV AC0,dbl(*AR3)
    30 }
    000472: 4e03                           AADD #3,SP
    000474: 4804                            RET

    Commands like "MOV AC0,dbl(@#00h)" are the issue, where it is using memory address 0x00 when it absolutely shouldnt be.

  • Here is the updated memory map

    ******************************************************************************
    TMS320C55x Linker PC v4.4.1 
    ******************************************************************************
    >> Linked Sun Mar 10 14:46:09 2013

    OUTPUT FILE NAME: <StereoDSP.out>
    ENTRY POINT SYMBOL: "_main" address: 000002ff


    MEMORY CONFIGURATION

    name origin length used unused attr fill
    (bytes) (bytes) (bytes) (bytes)
    ---------------------- -------- --------- -------- -------- ---- --------
    PAGE 0:
    DARAM01 00000100 00003f00 000003d0 00003b30 RWIX

    PAGE 1:
    DARAM23 00004000 00004000 00000000 00004000 RWIX


    SECTION ALLOCATION MAP
    (Addresses surrounded by []'s are displayed for convenience only!)

    output attributes/
    section page orgn(bytes) orgn(words) len(bytes) len(words) input sections
    -------- ---- ----------- ----------- ---------- ---------- --------------
    .cinit 0 [ 00000100 ] 00000080 * 00000000 UNINITIALIZED

    .text 0 00000100 [ 00000080 ] 0000039c * 
    00000100 [ 00000080 ] 00000121 * McBSP.obj (.text)
    00000221 [ 00000110+] 000000de * EMIF.obj (.text)
    000002ff [ 0000017f+] 000000a3 * main.obj (.text)
    000003a2 [ 000001d1 ] 0000007f * GPIO.obj (.text)
    00000421 [ 00000210+] 0000005d * display.obj (.text)
    0000047e [ 0000023f ] 0000001d * CLOCK.obj (.text)
    0000049b [ 0000024d ] 00000001 * --HOLE-- [fill = 20]

    .bss 0 [ 0000049c ] 0000024e * 0000001a UNINITIALIZED
    [ 0000049c ] 0000024e * 00000010 EMIF.obj (.bss)
    [ 000004bc ] 0000025e * 00000006 display.obj (.bss)
    [ 000004c8 ] 00000264 * 00000004 main.obj (.bss)

    .data 1 [ 00004000 ] 00002000 * 00000000 UNINITIALIZED


    GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name

    abs. value/
    byte addr word addr name
    --------- --------- ----
    00000002 $TI_capability$C5500$CallingConvention
    00000002 $TI_capability$C5500$MemoryModel
    00000001 $TI_capability_requires_rev2
    0000024e .bss
    00002000 .data
    00000100 .text
    ffffffff ___binit__
    0000024e ___bss__
    ffffffff ___c_args__
    ffffffff ___cinit__
    00002000 ___data__
    00002000 ___edata__
    00000268 ___end__
    0000049c ___etext__
    ffffffff ___pinit__
    00000100 ___text__
    00000262 _addr
    0000047e _clock_init
    0000025e _display_base_address
    00000421 _display_init
    00000476 _display_size
    00000260 _display_total_size
    00000443 _display_write
    00000285 _emif_base_ce
    0000024e _emif_base_ce0
    00000250 _emif_base_ce1
    00000252 _emif_base_ce2
    00000254 _emif_base_ce3
    00000256 _emif_ce0_size
    00000258 _emif_ce1_size
    0000025a _emif_ce2_size
    0000025c _emif_ce3_size
    000002c4 _emif_ce_size
    00000221 _emif_init
    00000407 _gpio_read
    000003fc _gpio_read_all
    000003bf _gpio_set
    000003a2 _gpio_set_all
    00000266 _i
    000002ff _main
    0000015a _mcbsp_init_0
    00000148 _mcbsp_loopback
    00000100 _mcbsp_off
    0000011e _mcbsp_on
    00000205 _mcbsp_read_byte
    000001bd _mcbsp_recv_full
    000001e1 _mcbsp_recv_ready
    0000013c _mcbsp_reset
    000001cf _mcbsp_trans_empty
    000001f3 _mcbsp_trans_ready
    00000213 _mcbsp_write_byte
    00000264 _total_size
    ffffffff binit
    ffffffff cinit
    00002000 edata
    00000268 end
    0000049c etext
    ffffffff pinit


    GLOBAL SYMBOLS: SORTED BY Symbol Address

    abs. value/
    byte addr word addr name
    --------- --------- ----
    00000001 $TI_capability_requires_rev2
    00000002 $TI_capability$C5500$CallingConvention
    00000002 $TI_capability$C5500$MemoryModel
    00000100 .text
    00000100 ___text__
    00000100 _mcbsp_off
    0000011e _mcbsp_on
    0000013c _mcbsp_reset
    00000148 _mcbsp_loopback
    0000015a _mcbsp_init_0
    000001bd _mcbsp_recv_full
    000001cf _mcbsp_trans_empty
    000001e1 _mcbsp_recv_ready
    000001f3 _mcbsp_trans_ready
    00000205 _mcbsp_read_byte
    00000213 _mcbsp_write_byte
    00000221 _emif_init
    00000285 _emif_base_ce
    000002c4 _emif_ce_size
    000002ff _main
    000003a2 _gpio_set_all
    000003bf _gpio_set
    000003fc _gpio_read_all
    00000407 _gpio_read
    00000421 _display_init
    00000443 _display_write
    00000476 _display_size
    0000047e _clock_init
    0000024e .bss
    0000024e ___bss__
    0000049c ___etext__
    0000024e _emif_base_ce0
    0000049c etext
    00000250 _emif_base_ce1
    00000252 _emif_base_ce2
    00000254 _emif_base_ce3
    00000256 _emif_ce0_size
    00000258 _emif_ce1_size
    0000025a _emif_ce2_size
    0000025c _emif_ce3_size
    0000025e _display_base_address
    00000260 _display_total_size
    00000262 _addr
    00000264 _total_size
    00000266 _i
    00000268 ___end__
    00000268 end
    00002000 .data
    00002000 ___data__
    00002000 ___edata__
    00002000 edata
    ffffffff ___binit__
    ffffffff ___c_args__
    ffffffff ___cinit__
    ffffffff ___pinit__
    ffffffff binit
    ffffffff cinit
    ffffffff pinit

    [58 symbols]

     

  • Here are the updated variable locations

    GLOBAL SYMBOLS: SORTED BY Symbol Address

    abs. value/
    byte addr word addr name
    --------- --------- ----
    00000001 $TI_capability_requires_rev2
    00000002 $TI_capability$C5500$CallingConvention
    00000002 $TI_capability$C5500$MemoryModel
    00000100 .text
    00000100 ___text__
    00000100 _mcbsp_off
    0000011e _mcbsp_on
    0000013c _mcbsp_reset
    00000148 _mcbsp_loopback
    0000015a _mcbsp_init_0
    000001bd _mcbsp_recv_full
    000001cf _mcbsp_trans_empty
    000001e1 _mcbsp_recv_ready
    000001f3 _mcbsp_trans_ready
    00000205 _mcbsp_read_byte
    00000213 _mcbsp_write_byte
    00000221 _emif_init
    00000285 _emif_base_ce
    000002c4 _emif_ce_size
    000002ff _main
    000003a2 _gpio_set_all
    000003bf _gpio_set
    000003fc _gpio_read_all
    00000407 _gpio_read
    00000421 _display_init
    00000443 _display_write
    00000476 _display_size
    0000047e _clock_init
    0000024e .bss
    0000024e ___bss__
    0000049c ___etext__
    0000024e _emif_base_ce0
    0000049c etext
    00000250 _emif_base_ce1
    00000252 _emif_base_ce2
    00000254 _emif_base_ce3
    00000256 _emif_ce0_size
    00000258 _emif_ce1_size
    0000025a _emif_ce2_size
    0000025c _emif_ce3_size
    0000025e _display_base_address
    00000260 _display_total_size
    00000262 _addr
    00000264 _total_size
    00000266 _i
    00000268 ___end__
    00000268 end
    00002000 .data
    00002000 ___data__
    00002000 ___edata__
    00002000 edata
    ffffffff ___binit__
    ffffffff ___c_args__
    ffffffff ___cinit__
    ffffffff ___pinit__
    ffffffff binit
    ffffffff cinit
    ffffffff pinit

    [58 symbols]

     

  • No expert on this. I think the disassembly might be wrong. From what I have seen of assembly listings, opcode eb0008 means "MOV AC0,dbl(*SP(#00h))". That means AC0 is beibg saved to a temporary stack variable. The parameters are passed in registers, AC0 = offset and AC1 = pixel. What is the value of the variable display_base_address? Is offset in units of int or long? Note that an offset of 1 will result in 2 being added to display_base_address. What memory model are you using?

  • display_base_address is 0x010000 which is the beginning of my CE0 space. offset is in units of unsigned long in this case.

    According to the c55 asm reference, eb0008 means MOV from AC0 to Smem address 0x00000000 using @dma. There is no mention of the stack at all.

    My memory model has program and data space accessing the same memory, but with data addresses on a 31 bit bus instead of a 32 bit bus.

  • What Mr. Wong was asking, was are you using the small or large memory model?  The small model assumes ALL data is in the first 2^16 words, and will silently drop the higher bits.  Since display_base_address is located at 0x010000, it would seem that your data is not in the first 2^16 words, and you should switch to the large memory model.

  • Also make sure SP is set to a reasonable value and that the CPL bit is set to 1.

  • So I set my CPL bit from 0 to 1 when I started at main, and now the data is being stored at SP (which is what I want). But I am still having issues where whenever I call a function, it overwrites the local variables in the stack. It stores the return address over the first local variable in the stack. Could this be caused due to the way my compiler is compiling my code? Does it assume that I am not using a data stack?

    Note, my stack mode is set to 32-bit slow which should be the default

    Edit: Upon further inspection, the CALL and RET functions work as expected. CALL first does SP = SP - 1 and then store the return address in the stack. RET does the opposite as expected. The problem is that my MOV reg, *SP(00h) command stores values to SP-1 as opposed to SP. This means that whenever I do a CALL, it overwrites SP-1 and the value is trashed once I exit the subroutine. Am I missing something?

    Edit2: Changing my stack pointer to an odd data value fixed the problem, but writing to the EMIF (CE0) still causes errors.

    Note: CALL is overwriting the tail end of the LONG datatype at *SP(00h). It is as if CALL is only doing SP-1 instead of SP-2 (to accommodate for the long data type). 

    Also, as a side question. Is my way of writing to the EMIF correct? I want to write to the first value in the CE0 space (0x010000 in the memory map shown in the datasheet). Because data memory uses one less byte, I've been shifting it down. Is this correct? Whenever I try writing to 0x010002 or 0x008001, the debugger crashes. Also, why does the offset get shifted by 1 upon entering the function?

  • I'm sorry, I don't know anything about EMIF.

    Do you have any hand-coded assembly functions in your program?  Do you have any interrupt handler functions?

    SP must be aligned to an even boundary for C programs.  The CALL instruction pushes one word of the return address to the stack, and the C function will adjust SP by an odd number to return SP to an even boundary.  If you don't keep the SP aligned, double-word accesses will behave strangely. 

    What is the value of the SP register when executing "MOV reg *SP(00h)" ?

    Is CPL still 1 when executing "MOV reg *SP(00h)" ?

  • So when the system reset, CPL is initialized to 0, so I have to manually change it before I step though the program. Is there a way to do this automatically (for when I run this stand alone without a debugger)? Also, I have to manually set the stack pointers. Is there a way to do this in code as well?

    With CPL set to 1, all of my stack operations are working as expected. The reason my CALL/RET were having issues was because my SP was set to an even value instead of an ODD. Setting it to an odd valued fixed it.

  • You are expected to provide a RESET interrupt handler (also called the boot routine), which is responsible for setting up the processor state at the start of the program.  Processor state includes the value of the SP and processor mode bits.  TI provides a sample boot routine called _c_int00 in the RTS library.

    Jama Mohamed said:
    Setting it to an odd valued fixed it.

    Be careful - you are supposed to set SP to an even value before the first CALL.  When that CALL occurs, the SP will be changed to an odd value.  The first thing a function should do is push another word so that SP is even again.  For the rest of the execution of the function, SP should remain even until it is time to return.  The function should restore SP to its previous (odd) value, and then the RET instruction will pop one word and SP will be even again.

  • Is there some sort of documentation that will tell me exactly what _c_int00 does?

  • See the "TMS320C55x Optimizing C/C++ Compiler v 4.4 User ' s Guide" http://www.ti.com/lit/ug/spru281g/spru281g.pdf chapter 6 "Run-Time Environment" for information about the processor state requirements of compiled code, especially section 6.3.2 "Status Registers".  See also the source code for _c_int00 in file boot.asm in rtssrc.zip