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.

Sharing variables between DSP & ARM in shared mem?

Guru 15580 points

Other Parts Discussed in Thread: OMAP-L138, SYSBIOS

Can someone recommend a way to share variables between DSP & ARM on an OMAP-L138 using shared memory? I would like to use the ARM to process data that was placed in a structure or buffer in shared memory by the DSP. I have several different types of variables including uint8's and arrays of uint8's. I assume I need to tell the linker to place these variable in a custom-named section, but how to I ensure that the linker keeps them at a specific address location that both the DSP and ARM know about? I will use the CHIPSIG interrupt to signal one core that the data is ready for processing, and/or processing has been completed by the other core.

Thx,

MikeH

 

  • I'm going to attempt to carry on this thread based on an answer received in my other thread.

    You can declare your own section to contain shared structure as well as the location in memory. For ARM look up SPNU151 section 4.3.5 (rev F for this post) and SPNU118 (revI) section 7.5. For DSP the same kind of info is at  SPRU186S section 7.5 (also).

    For an example of how DSP/BIOS Link declares structures that are common to both processors, look up the file dsplink.h which is common to both DSP and ARM programming sides. The file <dsp link path>/config/all/CFG_OMAPL138GEM_SHMEM.c contains information on how address and size can be controlled for shared memory.

    Note that for using shared structures without OSes, you need to set up your own mutex mechanism.

    I assume you are referring to the following memory defines:

     

    /** ============================================================================

     *  @name   RESETCTRLADDR

     *

     *  @desc   Indicates the start address of Reset Ctrl memory region.

     *          last two nibbles must be zero i.e. align to 256 boundary.

     *  ============================================================================

     */

    #define  RSTENTRYID         0

    #define  RESETCTRLADDR      0xC3E00000

    #define  RESETCTRLSIZE      0x80

    /** ============================================================================

     *  @name   CODEMEMORYADDR/CODEMEMORYSIZE

     *

     *  @desc   Indicates startaddress/size for dsplink code region.

     *  ============================================================================

     */

    #define  CODEENTRYID        1

    #define  CODEMEMORYADDR     (RESETCTRLADDR + RESETCTRLSIZE)

    #define  CODEMEMORYSIZE     0xFFF80u

    /** ============================================================================

     *  @name   SHAREDENTRYID/SHAREDMEMORYADDR/SHAREDMEMORYSIZE

     *

     *  @desc   Indicates startaddress/size for dsplink shared memory region.

     *  ============================================================================

     */

    #define  SHAREDENTRYID0     2

    #define  SHAREDMEMORYADDR0  (CODEMEMORYADDR + CODEMEMORYSIZE)

    #define  SHAREDMEMORYSIZE0  0x5000

    /** ============================================================================

     *  @name   SHAREDENTRYID/SHAREDMEMORYADDR/SHAREDMEMORYSIZE

     *

     *  @desc   Indicates startaddress/size for dsplink shared memory region.

     *  ============================================================================

     */

    #define  SHAREDENTRYID1     3

    #define  SHAREDMEMORYADDR1  (SHAREDMEMORYADDR0 + SHAREDMEMORYSIZE0)

    #define  SHAREDMEMORYSIZE1  0x2B000

    /** ============================================================================

     *  @name   POOLMEMORYADDR/POOLMEMORYSIZE

     *

     *  @desc   Indicates startaddress/size for dsplink POOL memory region.

     *  ============================================================================

     */

    #define  POOLENTRYID        4

    #define  POOLMEMORYADDR     (SHAREDMEMORYADDR1 + SHAREDMEMORYSIZE1)

    #define  POOLMEMORYSIZE     0x000D0000u

    ...which provides a good example of how to declare the memory sections. But what I am struggling with is, how do I place my structures in those locations and be assured that the linker puts them exactly where the DSP and ARM expects them to be?

    For example:

    If I declare the following structure type and instance of the structure, myStruct:

    typedef struct

    { Uint8 variable1

    Uint8 variable2

    }MY_STRUCT_T;

    MY_STRUCT_T myStruct;

    How do I place myStruct at (for example) memory location 0x80004000 in shared memory, such that I can use a reference to myStruct in both ARM and DSP code as follows:

    myStruct.variable1 = 1u;

    myStruct.variable2 = 2u;

    Or....

    Uint8 my_dsp_variable;

    my_dsp_variable = myStruct.variable1;

    Or....

    Uint8 my_arm_variable;

    my_arm_variable = myStruct.variable2;

    Any guidance would be much appreciated.

    Thx,

    MikeH

     

     

     

     

     

  • The brute force way would be use a pointer that has a literal address. Assumes that the ARM side is not using Linux. Also assumes that the packing, alignment and endian are identical between ARM and DSP.

    MY_STRUCT_T *myStruct = (MY_STRUCT *)(0x80004000);

    myStruct->variable1 = 1u;
    myStruct->variable2 = 2u;

    Uint8 my_dsp_variable;
    my_dsp_variable = myStruct->variable1;

    my_arm_variable = myStruct->variable2;

    In theory a more elegant would be to use section pragmas and linker scripts to place your variable in the right spot. Never had to do in CCS. A bit awkward in GCC.

    I'm looking at connecting the ARM and DSP myself. Just curious what made you decide Linux, DSP/BIOS and DSPLINK wasn't a viable solution?

  • Norman,

    Thanks for the pointers. I will give this a try.

    Norman Wong said:
    st curious what made you decide Linux, DSP/BIOS and DSPLINK wasn't a viable solution?

    1. I don't speak Linux. Therefore DSPLINK not an option for me.

    2. DSP/BIOS (aka bios 5) is not available for the ARM. 

    3. I have been trying to migrate from DSP/BIOS to SYSBIOS for the past couple of weeks and have run into numerous bugs and out of date documentation.

    4. Based on #3 above, I must rely *heavily* on support from this forum. For SYSBIOS, and especially EDMA3, the support has been somewhat slow (time zone issues), which has cost me days of waiting, which I cannot afford.

    Good luck!

    MikeH

     

  • For SYSBIOS on ARM you may want to take a look at SYSBIOS for CCSv5.

  • Loc,

    Loc said:
    For SYSBIOS on ARM you may want to take a look at SYSBIOS for CCSv5.

    Thanks for the suggestion.

    1. Does it have a tutorial?

    2. Does it have well-documented examples?

    3. Does it have a training module?

    4. Is fully release-compatible between DSP & ARM?

    Thx,

    MikeH

  • Norman is right that you can use a pointer and dereference the same to get a structure there.  To get data there without using pointers, you would need to use the DATA_SECTION pragma (if using the TI compiler) with a linker command file that places the object file section referenced in the pragma into a particular memory location. Same can be done with GCC using attributes and linker command file, though the LD linker command file syntax seems more difficult to use (though both the TI linker and the GCC/binutils linker have many similarities in terms of syntax).

    One other thing I wanted to bring up is cache coherency, which is something you will have to manage if your caches are enabled on one or both cores and the region you are sharing is cacheable memory.  You probably have already thought of this, but I thought I'd bring it up for you and anyone else who may later read this thread.

    Regards, Daniel

  • Daniel,

    Thanks for the tips on allocating variables shared memory.

    Daniel Allred said:
    One other thing I wanted to bring up is cache coherency, which is something you will have to manage if your caches are enabled on one or both cores and the region you are sharing is cacheable memory.

    I want to question the "and" above. I *do* have cache memory enable in the DSP, but only in non-shared memory (ie L1 and L2). But I *do not* have cache enabled for any shared memory space. Is there still a potential chaching issue?

    Daniel Allred said:
    You probably have already thought of this, but I thought I'd bring it up for you and anyone else who may later read this thread.

    No I hadn't thought of it, but glad you did.

    Thanks.

    MikeH

     

  • MikeH said:

    I *do* have cache memory enable in the DSP, but only in non-shared memory (ie L1 and L2). But I *do not* have cache enabled for any shared memory space. Is there still a potential chaching issue?

    Mike,

    I'm talking about the regions of the 32-bit memory space that are cacheable into the L1 and L2 caches that you have enabled.  This is done using the MAR bits in the C674x megamodule.  Each MAR bit corresponds to 16 MB the 4GB 32-bit memory space. Therefore there are 256 MAR bits, each one in a separate register (see section 4.4.4 and section 4.4.5 of the SPRUFK5 megamodule document). For example, if you were storing data in the L3 shared memory at address 0x80000000 and you wanted it be cacheable, you would need to set the PC bit (bit 0) of the MAR128 register to 1.  This would mean that data and code in that region could be present in the caches and would not have to be fetched every time it was needed by the DSP core.  But this is where you could run into cache coherency issues if another system master (such as the ARM core) modifies the memory without the DSP knowing about it. So, if you don't want to have to worry about that, you would need to mark the region as non-cacheable by setting the PC bit to 0.

    The same situation could exist on the ARM core, but I don't know enough about the ARM to say how particular regions of the memory map can be configured as cacheable or non-cacheable.

    Regards, Daniel

     

  • Daniel,

    Daniel Allred said:
    I'm talking about the regions of the 32-bit memory space that are cacheable into the L1 and L2 caches that you have enabled

    Doh! :)

    I have only enabled DDR for caching at this point. But I will keep your warnings in mind as things progress and memory allocations change.

    Thanks!

    MikeH