Project

General

Profile

Write to SharedMem from DSP and read it from ARM

Added by stefan nielsen almost 10 years ago

Hi im trying to write to some shared memory from the DSP and read it back from the ARM. Ive expanded the HelloWorldDSP project, so memory is mapped as in that project. I tried on 4 different memory areas.

DSP code:

#define SHARED_MEM_BASE 0x80000000 
#define IRAM_MEM_BASE     0x11800000 
#define POOL_MEM_BASE   0xC6830000
#define DSP_MEM_BASE    0xC6000080

unsigned int volatile * const port_shared = (unsigned int *) SHARED_MEM_BASE;
unsigned int volatile * const port_iram   = (unsigned int *) IRAM_MEM_BASE;
unsigned int volatile * const port_pool   = (unsigned int *) POOL_MEM_BASE;
unsigned int volatile * const port_dsp    = (unsigned int *) DSP_MEM_BASE;

unsigned int value = 1;
char tmp[80];

sprintf(tmp,"********** Log Test trying to write Shared Mem to adr: %#010x, value %d     ******* \n",SHARED_MEM_BASE,value);
debugPrint(tmp);
*port_shared = value; // write to port /
value = *port_shared; // read from port /
sprintf(tmp,"********** Log Test read from Shared Mem adr: %#010x, value read: %d     ******* \n",SHARED_MEM_BASE,value);
debugPrint(tmp);

This seems to work for the DSP and all read back values are okay, using similar printouts.

ARM code:

#define SHARED_MEM_BASE 0x80000000
#define POOL_MEM_BASE   0xC6830000
#define IRAM_MEM_BASE     0x11800000
#define DSP_MEM_BASE    0xC6000080

unsigned int volatile * const port_pool   = (unsigned int *) POOL_MEM_BASE;
unsigned int volatile * const port_shared = (unsigned int *) SHARED_MEM_BASE;
unsigned int volatile * const port_iram   = (unsigned int *) IRAM_MEM_BASE;
unsigned int volatile * const port_dsp   = (unsigned int *) DSP_MEM_BASE;

char tmp[80];
int value_pool   = *port_pool; // read from port /
int value_iram   = *port_iram; // read from port /
int value_shared = *port_shared; // read from port /
int value_dsp = *port_dsp; // read from port /
sprintf(tmp,"*** Log Test read from adr: %#010x, value:%d,   adr: %#010x, value:%d,    adr: %#010x, value:%d,  adr: %#010x, value:%d ******* \n" 
    ,POOL_MEM_BASE
    ,value_pool
    ,IRAM_MEM_BASE
    ,value_iram
    ,SHARED_MEM_BASE
    ,value_shared
    ,DSP_MEM_BASE
    ,value_dsp);
    printf(tmp);

This makes the ARM give up. Below is the response seen in the consol.

Unable to handle kernel paging request at virtual address c6b7300c
pgd = c52d0000
[c6b7300c] *pgd=c4493811, *pte=00000000, *ppte=00000000
Internal error: Oops: 807 [#1] PREEMPT
Modules linked in: dsplinkk(O) ipv6
CPU: 0    Tainted: G           O  (3.2.0 #1)
PC is at remove_wait_queue+0x24/0x70
LR is at remove_wait_queue+0x1c/0x70
pc : [<c00366bc>]    lr : [<c00366b4>]    psr: 80000093
sp : c5173e50  ip : c5a84044  fp : 00000000
r10: 00000001  r9 : 80040800  r8 : c6b73008
r7 : 000003e8  r6 : c5172000  r5 : 00000013  r4 : c5173e64
r3 : c6b73008  r2 : c6b73008  r1 : 00000000  r0 : 00000001
Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: c52d0000  DAC: 00000015
Process KK_Converter (pid: 2390, stack limit = 0xc5172270)
Stack: (0xc5173e50 to 0xc5174000)
3e40:                                     c6b73000 fffffe00 c5172000 bf0a6ffc
3e60: 80000013 00000001 c52b0c20 c0016fa0 c6b73008 c6b73008 00000001 000003e8
3e80: 00008000 c5173f04 c6b6f000 bf0ad600 80008051 bf09d668 00000029 41da6d64
3ea0: c018e03a 41da6d64 c44a6648 c0009524 c5172000 00000000 41da6d4c bf0a9d38
3ec0: a0000013 c018954c c51188cc c00366e0 c5118800 00000000 00000000 60000013
3ee0: c5172000 c05caed0 00000000 00008000 c8000200 00010000 000003e8 00000000
3f00: 41da6da4 00000000 a0000093 c505a3e0 41da6d64 41da6d64 c44a6648 c0009524
3f20: 00000000 c0091300 c0161818 00000030 00000000 febfd000 c5173f9c 80000010
3f40: c056a484 00000030 41da6d4c c0022958 41da6d4c c0009c88 00000001 c505a3e0
3f60: 00000000 c5318180 c5173f8c c505a3e0 41da6d64 c018e03a 00000003 c0009524
3f80: c5172000 c00913b8 00000003 00000001 41da6d64 00021158 00000080 00000000
3fa0: 00000036 c00093a0 00021158 00000080 00000003 c018e03a 41da6d64 00000003
3fc0: 00021158 00000080 00000000 00000036 00000000 41da6fa0 401448ac 41da6d4c
3fe0: 00000152 41da6c40 0000ab48 4038519c 80000010 00000003 018c0265 e0800000
[<c00366bc>] (remove_wait_queue+0x24/0x70) from [<bf0a6ffc>] (SYNC_WaitSEM+0x254/0x290 [dsplinkk])
[<bf0a6ffc>] (SYNC_WaitSEM+0x254/0x290 [dsplinkk]) from [<bf09d668>] (LDRV_MSGQ_get+0x84/0xc0 [dsplinkk])
[<bf09d668>] (LDRV_MSGQ_get+0x84/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: e3a00001 ebff7d25 e5943010 e594200c (e5823004)
---[ end trace 0b3ac9a59b6033d9 ]---
note: KK_Converter[2390] exited with preempt_count 1
Unable to handle kernel paging request at virtual address c6c2800c
pgd = c52d0000
[c6c2800c] *pgd=c52ee811, *pte=00000000, *ppte=00000000
Internal error: Oops: 807 [#2] PREEMPT
Modules linked in: dsplinkk(O) ipv6
CPU: 0    Tainted: G      D    O  (3.2.0 #1)
PC is at remove_wait_queue+0x24/0x70
LR is at remove_wait_queue+0x1c/0x70
pc : [<c00366bc>]    lr : [<c00366b4>]    psr: 20000093
sp : c51ede50  ip : c50f6044  fp : 00000000
r10: 00000001  r9 : 80040800  r8 : c6c28008
r7 : 000003e8  r6 : c51ec000  r5 : 20000013  r4 : c51ede64
r3 : c6c28008  r2 : c6c28008  r1 : 00000000  r0 : 00000001
Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: c52d0000  DAC: 00000015
Process KK_Converter (pid: 2391, stack limit = 0xc51ec270)
Stack: (0xc51ede50 to 0xc51ee000)
de40:                                     c6c28000 fffffe00 c51ec000 bf0a6ffc
de60: 000003e8 00000001 c52b19e0 c0016fa0 c6c28008 c6c28008 80008051 000003e8
de80: 00008000 c51edf04 c6c24000 bf0ad600 80008051 bf09d668 00000029 425abd64
dea0: c018e03a 425abd64 c44a6648 c0009524 c51ec000 00000000 425abd4c bf0a9d38
dec0: 00000001 c00543b4 c05644b4 c52942a0 00000000 c00562c4 00002000 c0053c40
dee0: febfd000 c0161898 c0161818 00008000 c8000000 00010001 000003e8 00000000
df00: 425abda4 00000000 425abd4c c505a3e0 425abd64 425abd64 c44a6648 c0009524
df20: 00000000 c0091300 00000003 c51edf8c 00000020 c53181b0 c505a3e0 00000000
df40: c5318180 c51edf8c c0009524 c51ec000 00000000 425abd4c 00000001 c505a3e0
df60: 00000000 c5318180 c51edf8c c505a3e0 425abd64 c018e03a 00000003 c0009524
df80: c51ec000 c00913b8 00000003 00000001 425abd64 00009630 00000080 00000000
dfa0: 00000036 c00093a0 00009630 00000080 00000003 c018e03a 425abd64 00000003
dfc0: 00009630 00000080 00000000 00000036 00000000 425abfa0 401448ac 425abd4c
dfe0: 00000152 425abc40 0000ab48 4038519c 80000010 00000003 018ca264 00006000
[<c00366bc>] (remove_wait_queue+0x24/0x70) from [<bf0a6ffc>] (SYNC_WaitSEM+0x254/0x290 [dsplinkk])
[<bf0a6ffc>] (SYNC_WaitSEM+0x254/0x290 [dsplinkk]) from [<bf09d668>] (LDRV_MSGQ_get+0x84/0xc0 [dsplinkk])
[<bf09d668>] (LDRV_MSGQ_get+0x84/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: e3a00001 ebff7d25 e5943010 e594200c (e5823004)
---[ end trace 0b3ac9a59b6033da ]---
note: KK_Converter[2391] exited with preempt_count 1

I also tried

unsigned int NumOfBytes = 4;
static unsigned int res[4] = {0,0,0,0};
lpDspApp->ReadMemory((void*)IRAM_MEM_BASE, 4, &res[0]);
sprintf(tmp,"*** Log Test read from adr: %#010x, value read[0]:%d,read[1]:%d,read[2]:%d,read[3]:%d     ******* \n",IRAM_MEM_BASE,res[0],res[1],res[2],res[3]);
printf(tmp);

but no luck and similar response as above.

Anybody has any idea as to what im duing wrong ?

thanks in advance
/stefan


Replies (11)

RE: Write to SharedMem from DSP and read it from ARM - Added by Michael Williamson almost 10 years ago

The linux OS uses virtual memory addresses. You can't access RAM by physical address in the normal case.

You need to use /dev/mem and mmap in the memory you want to access (though it will not be cacheable with this technique). See the examples folder in the MDK or trying searching / googling for linux memory map and /dev/mem for example code. Or you need to use the DSPLINK API for memory access.

Otherwise, you'll need to write a linux kernel module in order to get direct access to memory.

Sorry.

-Mike

RE: Write to SharedMem from DSP and read it from ARM - Added by stefan nielsen almost 10 years ago

Hi thanks for the quick reply. I found some stuff of how to do it on the ARM side, following the example you pointed out. On the DSP is it okay to write to memory as showed above ?

RE: Write to SharedMem from DSP and read it from ARM - Added by Michael Williamson almost 10 years ago

DSP code is OK, though if you have the caches enabled for the regions of SRAM or RAM you may need to add a cache write back call to ensure the data is moved to external memory for the ARM to pick up.

-Mike

RE: Write to SharedMem from DSP and read it from ARM - Added by Jonathan Cormier almost 10 years ago

You may find this post helpful for transmitting non-string data using dsplink. https://support.criticallink.com/redmine/boards/10/topics/4178?r=4179#message-4179

Note that the tsData::data_ptr requires tcDspApp::ReadMemory() on the ARM side to copy the memory into ARM space.

RE: Write to SharedMem from DSP and read it from ARM - Added by stefan nielsen almost 10 years ago

Hi thanks for the help, I still got some problems with reading on the ARM.

ARM code:

const char memDevice[] = "/dev/mem";
int *map = NULL;
int _fdmem;
/* open /dev/mem and error checking */
_fdmem = open( memDevice, O_RDWR | O_SYNC );

if (_fdmem < 0){
printf("Failed to open the /dev/mem !\n");
return 0;
}
else{
    printf("open /dev/mem successfully !\n");
    }
/* mmap() the opened /dev/mem */
map= (int *)(mmap(0,MAPPED_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,_fdmem,DDR_RAM_PHYS));

And then i read like this:

// use 'map' pointer to access the mapped area!
for (int i=0;i<10;i++)
printf("content: 0x%x\n",*(map+i));

This gets me the values i wrote from the DSP, but the ARM side just doesnt continuing running my app.

Then tried this as suggested.

int res[10];
char tmp[80];
lpDspApp->ReadMemory((void*)map, 4, &res[0]);
sprintf(tmp,"*** Log Test value read[0]:%d,read[1]:%d,read[2]:%d,read[3]:%d     ******* \n",res[0],res[1],res[2],res[3]);
printf(tmp);

but his does not give me the correct values written from the DSP. Any ideas what im missing ?

Thanks Stefan

RE: Write to SharedMem from DSP and read it from ARM - Added by stefan nielsen almost 10 years ago

Hi

do i need to use

int tcDspApp::SetSharedMemCfg(tsSharedMemCfg* pConfig)

or

int tcDspApp::SetPoolCfg(uint32_t anNumBufPools, uint32_t *apBufSizes,
uint32_t *apNumBuf, bool abExactMatch)

to use the Iram at 0x11802000 on the DSP ?

RE: Write to SharedMem from DSP and read it from ARM - Added by Michael Williamson almost 10 years ago

No you don't need ot use SetSharedMemCfg() or SetPoolCfg() if you are not using the tcDspInbound and tcDspOutbound message passing frameworks.

If you look at the dspapp.cpp file in the MDK, you will see the following parameters:

/**
 *  Read a section of DSP memory.  This is a light wrapper for the PROC_read()
 *  call.
 *
 *  \param DspAddr Physical Memory pointer of source data
 *
 *  \param NumBytes number of bytes to transfer
 *
 *  \param DestAddr Virtual Address of destination
 *
 *  \return non-zero on error.
 */
int tcDspApp::ReadMemory(void* DspAddr, unsigned int NumBytes, void* DestAddr)

The ReadMemory call, I believe, takes a DSP physical address as the source not a memory mapped address. I don't think you want to call it with the map variable.

-Mike

RE: Write to SharedMem from DSP and read it from ARM - Added by stefan nielsen almost 10 years ago

Hi mike

your are rigth. I tried it before the

map= (int *)(mmap(0,MAPPED_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,_fdmem,DDR_RAM_PHYS));

and forgot to correct it back.. Its working now, thanks alot..

RE: Write to SharedMem from DSP and read it from ARM - Added by Frank C almost 10 years ago

Hi,

I am trying to get the shared memory working as well (by writing from DSP side and reading back from ARM side) using the HelloWorld as a basis. But ARM side doesn't read back correct values. I am using the same stuff from here. It seems I don't need to use /dev/mmap if I use ReadMemory call
Could you take a look at it and see what I am missing? Thanks

DSP side write value 1

#define SHARED_MEM_BASE 0xC6800000
unsigned int volatile * const port_shared = (unsigned int *) SHARED_MEM_BASE;
...
value = 1;
sprintf(tmp,"DSP... Writing to addr %#010x: %d\n",port_shared, value);
debugPrint(tmp);
*(port_shared) = value;

ARM side read

#define SHARED_MEM_BASE 0xC6800000
...
tcDspApp* lpDspApp = NULL;
lpDspApp = new tcDspApp();
...
lpDspApp->ReadMemory((void*)SHARED_MEM_BASE, 4, &res[0]);
sprintf(tmp,"ARM... Reading from address %#010x:%d\t%d\t%d\t%d\n",SHARED_MEM_BASE, res[0],res[1],res[2],res[3]);
printf(tmp);
}

dspapp.h has the memory addresses as:

SharedMemCfg() 
: RESETCTRLADDR    (0xC6000000)
, RESETCTRLSIZE    (0x80)
, CODEMEMORYADDR   (0xC6000080)
, CODEMEMORYSIZE   (0x007FFF80)
, SHAREDMEMORYADDR0(0xC6800000)
, SHAREDMEMORYSIZE0(0x00005000)
, SHAREDMEMORYADDR1(0xC6805000)
, SHAREDMEMORYSIZE1(0x0002B000)
, POOLMEMORYADDR   (0xC6830000)
, POOLMEMORYSIZE   (0x00800000)

Thanks,
-Frank

RE: Write to SharedMem from DSP and read it from ARM - Added by Jonathan Cormier almost 10 years ago

Pretty sure you have to flush the DSP cache after changing values.

RE: Write to SharedMem from DSP and read it from ARM - Added by Frank C almost 10 years ago

Thanks for the cache info. Completely missed that part.

I reverted to the original code, and I've added BCACHE_wb() call after I write to memory on the DSP side, but I still have a problem somewhere.

I changed the SHARED_MEM_BASE to 0x80000000

and when I read from the ARM side, it just spits out some random data, and StopApp() call gives

ERROR: DSP_EWRONGSTATE
StopApp - Error in PROC_stop [0x8000801b]

and it just hangs there.

Is there anything else I am missing here?

Thanks!

    (1-11/11)
    Go to top
    Add picture from clipboard (Maximum size: 1 GB)