Forums » Software Development »
Change data between ARM & DSP cores, undefined behaviour
Added by Yan Yandoff over 6 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 (5)
RE: Change data between ARM & DSP cores, undefined behaviour - Added by Jonathan Cormier over 6 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 over 6 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 over 6 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 over 6 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!
RE: Change data between ARM & DSP cores, undefined behaviour - Added by Demon Demonof over 3 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
Maybe you need to create a memory pool cmem in the command line terminal?