Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

problem with memcpy

Altera_Forum
Honored Contributor II
3,066 Views

Hi, 

 

I want to copy many times a region of memory located in one of my slaves into a local buffer. This ram region is filled by a master, and i use a function which advice me when the ram have been updated. If i use the macro IORD it works fine, but is too slow for the system specs. http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif  

 

int read_buffer( alt_u32 *dest_ptr, 

alt_u32 *source_ptr, 

int length) 

int i; 

for (i=0;i<length;i++) 

*dest_ptr++ = IORD(source_ptr,i); 

... 

 

int main() 

int i; 

alt_u32 buffer[122][188]; 

... 

for (i=0;i<122;i++) 

WaitUntilSlaveRamisUpdated(); 

read_buffer((alt_u32*) &buffer[i],(alt_u32*)MySlave_BASE,188); 

... 

 

So, if we print the buffer, we will see something similar to .. 

 

buf[0][0] = 0; 

buf[0][1] = 1; 

.. 

buf[0][187] = 187; 

buf[1][0] = 188; 

buf[1][1] = 189; 

.. 

buf[122][188] = 22935; 

 

 

So i wanna try using memcpy. The problem is that memcpy only works for the first time i call it, and then never refresh the correct values. http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/mad.gif  

 

int read_buffer( alt_u32 *dest_ptr, 

alt_u32 *source_ptr, 

int length) 

memcpy(dest_ptr,source_ptr,188*4); 

 

so, the result is 

 

buf[0][0] = 0; 

buf[0][1] = 1; 

.. 

buf[0][187] = 187; 

buf[1][0] = 0; 

buf[1][1] = 1; 

.. 

buf[122][188] = 187; 

 

I don&#39;t understand why is happening this. I have monitored the avalon signals in the signaltap, and it seems that memcpy only goes to my slave the first iteration. 

 

Does anybody understand this? 

 

Thanks in advance ! http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/laugh.gif
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
1,398 Views

Hi Ochando, 

 

I don&#39;t understand what is happening either but I can think of two things that might be affecting the result. 

Firstly, IORD() reads as 32-bits whereas memcpy() reads as 8-bits. How does your slave respond to these different requests? Also, I think, the IORD() version will do 188 reads but the memcpy() version will do 752. 

Secondly, it looks like there is some kind of data cache going on, the first set of 188 integers are read ok then all followong sets are the same. Bear in mind that IORD() ALWAYS reads i.e. the data at the address is considered to be volatile. memcpy() doesn&#39;t know about volatility. 

 

Sorry I don&#39;t have an answer. 

 

Banx.
0 Kudos
Altera_Forum
Honored Contributor II
1,397 Views

Hi ochando, 

 

> and it seems that memcpy only goes to my slave the first iteration. 

 

Sounds like you need to flush/invalidate your data cache -- do you have a data cache? 

 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

Thanks all of you for your soon answer. 

 

I thought it was a cache problem too, so i tried to use the HAL function alt_dcache_flush(), but i couldn&#39;t resolve ( i must be doing something wrong http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif ). Anyway, i will loose too much time if i have to flush the dcache each iteration. I have to think on it, but by the moment, i&#39;m gonna try using al alternative method, doing a dma from my own master.
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

Hi ochando, 

 

> tried to use the HAL function alt_dcache_flush(), but i couldn&#39;t resolve ( i must be doing 

> something wrong 

 

You must invalidate the source (your peripheral) prior to performing read access. 

 

> nyway, i will loose too much time if i have to flush the dcache each iteration. I have to think 

> on it, but by the moment, i&#39;m gonna try using al alternative method, doing a dma from my 

> own master. 

 

No doubt, a good DMA implemenation is much faster. But this won&#39;t solve your cache 

coherency problems: you will still need to invalidate main memory regions prior to accessing 

data that was transferred via DMA from the peripheral, and you will still need to flush main 

memory regions prior to DMA transfers to the peripheral. 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,398 Views

Hi Scott, 

 

Finally i have solved the problem. It was effectively the cache, so i have remaped a region of memory to bypass the data cache using alt_remap_uncached(). 

 

Many thanks !! 

 

 

 

 

--- Quote Start ---  

originally posted by smcnutt@Jan 29 2007, 09:30 PM 

hi ochando, 

 

>  tried to use the hal function alt_dcache_flush(), but i couldn&#39;t resolve ( i must be doing 

> something wrong 

 

you must invalidate the source[/b] (your peripheral) prior to performing read access. 

 

> nyway, i will loose too much time if i have to flush the dcache each iteration. I have to think 

> on it, but by the moment, i&#39;m gonna try using al alternative method, doing a dma from my 

> own master. 

 

No doubt, a good DMA implemenation is much faster. But this won&#39;t solve your cache 

coherency problems: you will still need to invalidate main memory regions prior to accessing 

data that was transferred via DMA from the peripheral, and you will still need to flush main 

memory regions prior to DMA transfers to the peripheral. 

 

Regards, 

--Scott 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=21003) 

--- Quote End ---  

[/b] 

--- Quote End ---  

0 Kudos
Reply