Project

General

Profile

Change data between ARM & DSP cores, undefined behaviour

Added by Yan Yandoff about 2 years ago

Hello!

I have MityDSP OMAPL-138F, version linux kernel - 3.2, version dsplink 1.65 (from MDK-2012-03-2012), pc Ubuntu-14.04.05 LTS. ARM & DSP clock freq - 300MHz.

I want to establish a continuous exchange of data between two cores ARM and DSP. ARM core sends data to the DSP core and sends it back to the ARM core. Below are some small examples.
ARM core

#include <cstdio>
#include <cstdlib>

#include "dspapp.h" 
#include "ipc_inbound.h" 
#include "ipc_outbound.h" 

#include <string.h>
#include <signal.h>

using namespace MityDSP;

int handleInboundMessage(void *Buffer, uint16_t Length, void *UserArg);
void dsp_sender();
void signalHandler(int signum);

volatile bool gbDone = false;
volatile int sigStart = 1;
const int BUFF_SIZE_PC = 128;

// tcDspApp class for booting and loading the DSP
    tcDspApp*         lpDspApp = NULL;
    // Used to setup handling of inbound messages from DSP
    tcIPCInbound*     lpMessageInbound  = NULL;
    // Used to send messages to the DSP
    tcIPCOutbound*     lpMessageOutbound  = NULL;
    // Message to send to the DSP
    char            lpMessage[] = "Hello DSP";
    // Pointer to buffer obtained from dsplink
    char*            lpMessageBuffer = NULL;

int main(int argc, char* argv[])
{

    // Check application usage
    if (argc < 2)
    {
        printf("usage: arm_image dsp_image.out\n");
        return -1;
    }

    // Create the DspApp object
    lpDspApp = new tcDspApp();

    // Load the DSP.out file
    printf("Loading file %s\n", argv[1]);
    lpDspApp->LoadApp(argv[1]);

    printf("Starting application.\n");

    // Create the object to handle incoming messages from the DSP
    lpMessageInbound =  new tcIPCInbound((char*)"GPPMSGQ1");

    if (NULL != lpMessageInbound)
    {
        // Register the callback for handling messages from the DSP
        lpMessageInbound->Register(handleInboundMessage, (void*)NULL);

        // Intiailize the inbound controller to create the thread that handles the callbacks
        lpMessageInbound->Initialize();
    }

    // Create the object used to send messages to the DSP
    lpMessageOutbound = new tcIPCOutbound((char*)"DSPMSGQ0");

    // Wait for the DSP to finish initialization
    while(false == gbDone);

    // Reset bool in prep for next receive message from DSP
    gbDone = false;

    //test
    dsp_sender();

    printf("Exiting application.\n");

    // Stop the DSP application from running
    lpDspApp->StopApp();

    return 0;
}

int handleInboundMessage(void *apBuffer, uint16_t anLength, void *apUserArg)
{
    // printf("ARM received a message from the DSP:\n");

    printf("DSP Message = (%s).\n", ((char *)apBuffer));

    // Notify the main function that we have received a message from the DSP and are done
    gbDone = true;

    return 0;
}

void dsp_sender()
{
    const int N = 41;
    char tmp_buffer[N] = {0};

    int counter = 0;
    lpMessageBuffer = (char *)lpMessageOutbound->GetBuffer(BUFF_SIZE_PC);

    (void)signal(SIGINT, signalHandler);

    while (sigStart)
    {
        counter++;
        sprintf(tmp_buffer, "Test message #%d.\n", counter);        
        memcpy(lpMessageBuffer, tmp_buffer, BUFF_SIZE_PC);
        lpMessageOutbound->SendMessage(lpMessageBuffer);        
        // lpMessageOutbound->ReturnBuffer(lpMessageBuffer);

        usleep(5000);
    }

}

void signalHandler(int signum)
{
    sigStart = 0;
}

DSP core

#include <std.h>
#include <tsk.h>
#include <stdio.h>
#include <string.h>

#include "core/cl_ipc_inbound.h" 
#include "core/cl_ipc_outbound.h" 

using namespace MityDSP;

// Forward declarations
void init();
int handleInboundMessage(void *apBuffer, uint32_t anLength, void *apUserArg) ;

// Object for sending GPPMSGQ1 messages that the ARM will receive
tcCL_IPCOutbound*     gpOutbound;
// Object for receiving DSPMSGQ0 messages that the DSP will receive
tcCL_IPCInbound*     gpInbound;

const int BUFF_SIZE_PC = 128;
char* glpMessageBuffer = NULL;

int main(int argc, char* argv[])
{
    // initialize the DSPLink system
    tcCL_IPCInit::GetInstance();

    // Launch an initialization task
       TSK_Attrs* lpAttrs = new TSK_Attrs;
    *lpAttrs           = TSK_ATTRS;
    lpAttrs->name      = "Initialize";
    lpAttrs->stacksize = 8192*2;
    lpAttrs->priority  = 5;
       TSK_create((Fxn)init,lpAttrs);

    return 0;
}

void init()
{
    // Message to ARM core.
    char lpReturnMessage[] = "DSP Initialization finished.";

    // Create the inbound link for messages to the DSP
       gpInbound = new tcCL_IPCInbound();

       gpInbound->Open("DSPMSGQ0", 8);

    // Create the outbound controller for sending messages to the ARM
       gpOutbound = new tcCL_IPCOutbound("GPPMSGQ1");

    if (NULL != gpInbound)
    {
        // Register a callback function to handle messages from the ARM
           gpInbound->RegisterCallback(handleInboundMessage, (void*)NULL);
    }

    // Obtain a dsplink buffer for the return message
    glpMessageBuffer = (char*)gpOutbound->GetBuffer(BUFF_SIZE_PC);

    // Make sure we received a valid buffer
    if (NULL != glpMessageBuffer)
    {
        memcpy(glpMessageBuffer, lpReturnMessage, strlen(lpReturnMessage)+1);

        // Send the message back to the ARM
        gpOutbound->SendMessage(glpMessageBuffer);
    }
}

int handleInboundMessage(void* apBuffer, uint32_t anLength, void* apUserArg)
{
    int retval = 0;

    char *data = new char[BUFF_SIZE_PC]();
    memcpy(data, apBuffer, BUFF_SIZE_PC);
//    gpInbound->ReturnBuffer(apBuffer);

    memcpy(glpMessageBuffer, data, BUFF_SIZE_PC);

        // Send the message back to the ARM
    retval = gpOutbound->SendMessage(glpMessageBuffer) ? 0 : -1;

    delete []data;

    return retval;
}

They often fail. How to fix it?

Thanks!


Replies (4)

RE: Change data between ARM & DSP cores, undefined behaviour - Added by Jonathan Cormier about 2 years ago

They often fail. How to fix it?

Could you clarify what you mean about it failing often? Error messages? What does failure mean?

RE: Change data between ARM & DSP cores, undefined behaviour - Added by Yan Yandoff about 2 years ago

After N-iterations I get an errors:

DSP Message = (TUnable to handle kernel NULL pointer dereference at virtual address 00000004
est message #58152.
).
pgd = c53bc000
[00000004] *pgd=c53f0831, *pte=00000000, *ppte=00000000
Internal error: Oops: 817 [#1] PREEMPT
Modules linked in: minix fpga_gpio(O) fpga_spi(O) fpga_uart(O) fpga_ctrl(O) dsplinkk(O) ipv6
CPU: 0    Tainted: G           O  (3.2.0 #1)
PC is at LIST_GetHead+0x34/0x4c [dsplinkk]
LR is at LDRV_MSGQ_get+0x4c/0xc0 [dsplinkk]
pc : [<bf0a2c4c>]    lr : [<bf09d630>]    psr: 20000013
sp : c4481e98  ip : 00000008  fp : 00000000
r10: 80008051  r9 : 80040800  r8 : bf0ad600
r7 : c6c65000  r6 : c4481f04  r5 : 00008000  r4 : ffffffff
r3 : 00000000  r2 : 00000000  r1 : c4481f04  r0 : c6c67000
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: c53bc000  DAC: 00000015
Process serial_port_arm (pid: 2398, stack limit = 0xc4480270)
Stack: (0xc4481e98 to 0xc4482000)
1e80:                                                       00000029 426d2d64
1ea0: c018e03a 426d2d64 c5353d58 c0009524 c4480000 00000000 426d2d4c bf0a9d38
1ec0: a0000013 c018954c c503b0cc c00366e0 c503b000 00000000 00000000 60000013
1ee0: c4480000 c05caed0 00000000 00008000 c8004000 00010001 ffffffff 00000000
1f00: 00000000 c8004000 a0000093 c44ec7c0 426d2d64 426d2d64 c5353d58 c0009524
1f20: 00000000 c0091300 c5255700 00000000 00000000 00000000 00000001 00000003
1f40: c52728c8 00000002 c5a86cb8 00000000 c4480000 00000000 00000001 c44ec7c0
1f60: 00000000 c52362e0 c4481f8c c44ec7c0 426d2d64 c018e03a 00000003 c0009524
1f80: c4480000 c00913b8 00000003 00000001 426d2d64 0002b2ac 40d3a014 0002b2a8
1fa0: 00000036 c00093a0 0002b2ac 40d3a014 00000003 c018e03a 426d2d64 00000003
1fc0: 0002b2ac 40d3a014 0002b2a8 00000036 0002b2b4 ffffffff 426d2d94 426d2d4c
1fe0: 0002b2ac 426d2c30 0000c6b4 4036719c 80000010 00000003 00000000 00000000
[<bf0a2c4c>] (LIST_GetHead+0x34/0x4c [dsplinkk]) from [<bf09d630>] (LDRV_MSGQ_get+0x4c/0xc0 [dsplinkk])
[<bf09d630>] (LDRV_MSGQ_get+0x4c/0xc0 [dsplinkk]) from [<bf0a9d38>] (DRV_Ioctl+0x1d0/0x778 [dsplinkk])
[<bf0a9d38>] (DRV_Ioctl+0x1d0/0x778 [dsplinkk]) from [<c0091300>] (do_vfs_ioctl+0x500/0x584)
[<c0091300>] (do_vfs_ioctl+0x500/0x584) from [<c00913b8>] (sys_ioctl+0x34/0x54)
[<c00913b8>] (sys_ioctl+0x34/0x54) from [<c00093a0>] (ret_fast_syscall+0x0/0x2c)
Code: 05812000 15803000 15913000 15933000 (15830004) 
---[ end trace 7b54f38c0d506897 ]---

The number of iterations can be any. How to fix it?

RE: Change data between ARM & DSP cores, undefined behaviour - Added by Gregory Gluszek about 2 years ago

My guess is that the system is running out of DSPLink buffers. I would recommend checking return codes for functions such as GetBuffer(). GetBuffer() will return a NULL pointer if it cannot obtain a new buffer.

Thanks,
\Greg

RE: Change data between ARM & DSP cores, undefined behaviour - Added by Yan Yandoff about 2 years ago

Gregory Gluszek wrote:

My guess is that the system is running out of DSPLink buffers. I would recommend checking return codes for functions such as GetBuffer(). GetBuffer() will return a NULL pointer if it cannot obtain a new buffer.

Thanks,
\Greg

Added checking of pointers. It seems to work stably. We will see.

Thanks!

    (1-4/4)
    Add picture from clipboard (Maximum size: 600 MB)