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.

OMAPL138 DSPlink Loop Example

Other Parts Discussed in Thread: OMAPL138

Hello,

I am on a custom board using the OMAPL138 part, Linux v2.6.38 running on the ARM and DSP BIOS _5_41_11_38 on the C674x DSP.

Using dsplink_1_65_01_06 i have the a version of the message sample working good sending messages back and forth to/from ARM and DSP using MSGQ.

Now I am trying to get the loop sample application to work, however on the ARM side we end up wating forever on the first CHNL_reclaim, and on the DSP side we wait forever on the first SIO_reclaim. (the first message is from the ARM going to the DSP).

Can someone explain the process of the CHNL better. When should the DSP send an interrupt to the ARM allow the ARM to reclaim the chnl? Should this be done when the DSP does SIO_issue? or Should it be done when when it does SIO_reclaim? Is there any way i can debug this or check for the interrupts? Also if anyone has more documentation on the CHNL module, or the SIO claim/reclaim module that would also be helpful.

Thanks,

Dan

  • Daniel,

    I'm sorry, but DSPLink is no longer a supported product.

    The only suggestion I have is to connect CCS to the DSP (after loading and running from the ARM) and inspect the program state. You might need to add a spin loop in your code to keep the DSP busy waiting until you have connected with CCS.

    { volatile int spin=1; while (spin); }

    After you connect, use CCS to set the variable 'spin' to zero.

    If you custom board does not have JTAG support, then you might need to use a development kit to do your debugging.

    http://www.ti.com/tool/tmdxlcdk138

    ~Ramsey

  • Hi Ramsey,

    Thank you for the reply. I have traced the problem down to something more specific and it has little to do w/ dsplink.

    The problem is that in the ZCPYDATA_Ctrl structure, the DSP never sets the field dspFreeMask, described below. Without a bit set in that field the ARM can never trigger the ZPCY to happen so we will never be able to reclaim channels on either the DSP or ARM side. 

    I understand DSPlink is no longer reported, but maybe you have some ideas about where in the code this is supposed to be written by the DSP?

    Also is there any way to step-in to the SIO_issue and SIO_reclaim functions? It seems only the API and header files for the SIO module are available and we have no access to the source in DSP BIOS. Do you have any idea how I can debug the SIO_issue function ( i suspect it is this function that should write to the ZCPY control structure).

    from dsplink/src/data/DspBios/_zcpy_data.h

    /** ============================================================================
    * @name ZCPYDATA_Ctrl
    *
    * @desc Defines the control structure used by GPP and DSP for ZCPY data
    * driver
    *
    * @field gppFreeMask
    * Indicating that a command is pending for the DSP on the channel
    * corresponding to the index.
    * This field is modified by the GPP only.
    * @field dspFreeMask
    * Indicating that a command is pending for the GPP on the channel
    * corresponding to the index.
    * This field is modified by the DSP only.
    * @field gppOutputFull
    * Output full flag mask for gpp channel.
    * @field dspOutputFull
    * Output full flag mask for dsp channel.
    * @field toDspList
    * Holds the list of buffers to be sent to the DSP.
    * @field toDspPadding
    * Padding for alignment.
    * @field fmDspList
    * Holds the list of buffers to be received from the DSP.
    * @field fmDspPadding
    * Padding for alignment.
    * @field csToDspList
    * Shared critical section object for protection of operations by
    * the two processors on the toDspList.
    * @field csFmDspList
    * Shared critical section object for protection of operations by
    * the two processors on the fmDspList.
    * ============================================================================
    */
    typedef struct ZCPYDATA_Ctrl_tag {
    volatile ZCPYDATA_ChnlMask gppFreeMask [MAX_SUPPORTED_CHHANNELS] ;
    volatile ZCPYDATA_ChnlMask dspFreeMask [MAX_SUPPORTED_CHHANNELS] ;
    volatile ZCPYDATA_ChnlMask gppOutputFull [MAX_SUPPORTED_CHHANNELS] ;
    volatile ZCPYDATA_ChnlMask dspOutputFull [MAX_SUPPORTED_CHHANNELS] ;

    volatile QUE_Elem toDspList ;
    ADD_PADDING (toDspPadding, ZCPYDATA_QUE_PADDING)
    volatile QUE_Elem fmDspList ;
    ADD_PADDING (fmDspPadding, ZCPYDATA_QUE_PADDING)
    volatile MPCS_ShObj csToDspList ;
    volatile MPCS_ShObj csFmDspList ;

    volatile QUE_Elem freeChirps ;
    ADD_PADDING (freeChirpsPadding, ZCPYDATA_QUE_PADDING)
    volatile MPCS_ShObj csFreeChirps ;
    } ZCPYDATA_Ctrl ;


    Thanks,

    Dan

  • Dan,

    You should have access to all the source files for DSPLink. If you don't have the source files, try getting a new download from the following link.

    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/legacy.html

    I see dspFreeMask getting set in ZCPYDATA_mdSubmitChan followed by a HAL_cacheWbInv operation.

    ctrlPtr->dspFreeMask [chnlObj->chnlId].bitValue = 1 ;
    HAL_cacheWbInv ((Ptr) &(ctrlPtr->dspFreeMask [chnlObj->chnlId]),
    sizeof (ZCPYDATA_ChnlMask)) ;

    I'm wondering if the issue has to do with cache configuration. You should also be able to instrument the code above and rebuild DSPLink (on the DSP side). This would help verify that the code is being executed.

    Unfortunately, DSP/BIOS does not ship source files.

    ~Ramsey

  • Thank you, yes i found the lines you are describing.

    Just one more question - is it possible to step through DSPlink source using jtag/debugger and ccs? When i try to set a breakpoint in DSPlink source it acts as if symbols aren't loaded, however at the same time i can still break in the loop application/sample code (i.e. loop_execute).

    EDIT: for now i just edit the make files as necessary and recompile the dsplink dsp side libraries in the windows environment. This way the compiled paths in the symbols will match.

  • Dan,

    Yes, you should be able to use CCS to step through the DSP side code of DSPLink. Make sure you are linking with the debug libraries. By default, when you build DSPLink it will build both debug and release libraries. Maybe the following link will help.

    http://processors.wiki.ti.com/index.php/Building_DSPLink

    From your post above, it looks like you might be building on a Linux server and then running CCS on Windows. This should also work. From Windows, you probably have some network path to access the DSPLink source code, or maybe you copied the DSPLink source code to your Windows machine. In CCS, use the Source Lookup Path dialog to map your Windows path prefix to your actual build path prefix. For example, if you build path is /usr/home/dsplink/... and your Windows path is C:\Products\dsplink\... then you would create a mapping as follows:

    CCS > Menu > Window > Preferences
    C/C++ > Debug > Source Lookup Path
    Add... > Path Mapping > OK

    Name: Dan
    Add
    Compilation path: /usr/home/dsplink
    Local file system path: C:\Products\DSPLink

    You might need to restart your debug session after creating the source path mapping. Copy the DSP executable file to your Windows machine.

    Then, in CCS,  select the DSP in the Debug window (you don't need to be connected). Then select Load Symbols and use the DSP executable file.

    Run > Load > Load Symbols...

    This option is also available from the toolbar icon menu. After you have the DSP loaded and running, you can connect to the DSP. At this point, you should have full source level debugging. When you are done, you can let the DSP free run and then disconnect.

    Run > Free Run
    Run > Disconnect Target

    Now you can restart your test or reboot your board. On the next test, you can simply re-load your symbols and connect again.

    ~Ramsey

  • Thanks Ramsey - I can now debug and step through all of the DSPlink source.

    Stepping through the code i can see that I get an interrupt from the ARM, but the zcpydata semaphore just doesnt seem to work. As i step through the interrupt i can see IPS_ISR() calls the ZCPYDATA_callback() which posts to the zcpyDataSem and therefore is supposed to wake up the ZCPYDATA_tskFxn() and call ZCPYDATA_dataCtrl().

    The problem is despite posting to the semaphore, the task never wakes up. I've also noticed that there is no SEM_Create to create the semaphore, only a SEM_new, which when stepped over does not add a new semaphore to the display in the ROV. Lastly the ZCPYDATA_tskFxn in the ROV does not show as blocked or pending on the zcpyDataSem semaphore.

    Is there a problem with this semaphore? Where is SEM_create called for it? I dont see it in any tconf files or in the source. Is it okay to call SEM_new w/out calling sem create first?

    Thanks,

    Dan

  • Dan,

    Re: loop example.

    Have you found Chapter 16 in the User Guide which explains the loop example? It's not much, but might help. In particular, the DSP executable can be built in two modes: 1) Using TSK with SIO, and 2) using SWI with GIO. I'm wondering if you are building with the expected mode. There is also some discussion on CHNL in chapters 7, 13, 14, 15.

    dsplink/docs/UserGuide.pdf

    There is also a design document on TSK and SWI configuration.

    dsplink/docs/design/LNK_207_DES.pdf

    Re: Semaphore

    There are two ways to "create" a semaphore: 1) SEM_create which allocates memory for a new object, and 2) SEM_new which initializes a new semaphore using existing memory. We call the second type of semaphore a "constructed" semaphore. In the loop example, they are using SEM_new because the actual semaphore is an embedded object in the ZCPYDATA_DevObject. So, its memory has already been allocated. Unfortunately, ROV does not know about semaphores created by using SEM_new. So, it is expected that these semaphores will not show up in the ROV view.

    The ZCPYDATA_tskFxn might not show up as blocked on the semaphore because it is a constructed semaphore. If you are ambitious, you might try changing zcpyDataSem from type SEM_Obj to type SEM_Handle and replace SEM_new with SEM_create. Then your semaphore should show up in ROV. After you get the program working, change it back. Otherwise, you might incur a memory leak.

    I would double check your build configuration to make sure you are building the loop example for TSK mode.

    ~Ramsey

  • Thanks I now have the example running. I had to explicitly on my own add the zcpydatasem semaphore to our base TCONF, so that when we call SEM_new it would register.

    Then immediately after the SEM_new call in the ZCPYDATA_mdBindDev() function i dynamically created the ZCPYDATA_tskFxn(). First i tried also adding this to TCONF but because of its high priority it would run before the semaphore that it pends on was initialized.

    I can try removing the sem create calls in TCONF now and try only to use sem_new as explained above, but mainly its working.

    One question I have now is about DPC_Create and ZCPYDATA_dpc() function. Does DPC_Create cause ZCPYDATA_dpc() to act as a thread? How is ZCPYDATA_dpc called? IT seems this function is running about 2 to 3 times for every one loop in the loop example. After one successful loop, it seems this function is called too soon and the DSP is not ready with another channel yet (ZCPYDATA_getNextOutputChannel returns CHNLID_INVALID because the dsp has not written any bits to the dspFreeMask). This will happen 2 or 3 times before the DSP writes the corresponding bit saying its ready.


    Thanks for you help.