memcpy

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
kster59
XCore Addict
Posts: 162
Joined: Thu Dec 31, 2009 8:51 am

memcpy

Post by kster59 »

Does Xc support memcpy?

I want to copy data byte by byte from a struct into a char array.

Normally I just use memcpy but Xc doesn't support pointers.

The function prototype for memcpy in C is:
void *memcpy(void *s1, const void *s2, size_t n);

is there another version that basically is:
void memcpy(void &s1, const void &s2, size_t n);

so that the variables s1 and s2 are just passed by reference instead of pointers so that it works for Xc?


User avatar
paul
XCore Addict
Posts: 169
Joined: Fri Jan 08, 2010 12:13 am
Contact:

Post by paul »

Two options I guess... roll your own OR use a C function. You should be able to wrap a C function around memcpy that will allow you to use it from XC in the format you suggest- thats probably going to be the simplest method!
Paul

On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

The safestring.h header provides equivalents to the C library functions defined in <string.h> that can be called from XC. The functions are prefixed with "safe" because:
  • We had to change the name so they didn't clash with the C library functions
  • They perform array bound checking
For example the equivalent of memcpy() is safememcpy(). safememcpy() is prototyped as:

Code: Select all

void safememcpy(unsigned char dst[], const unsigned char src[], unsigned length);
You will need to use a reinterpret cast if the arguments aren't char arrays.
DaveBest
Member++
Posts: 25
Joined: Mon Jan 18, 2010 3:36 pm

Post by DaveBest »

Greetings,

Is there any way to implement something akin to memmove?
I got to handle incoming data which is buffered in an array.
My buffered data consists of several packets of data, where each packet is 188 Bytes long.
Packets can be meaningful or just stuffing packets with no longer usefull data.
The Buffer is sent per UDP to a receiver and should ideally only contain the usefull packets with the stuffing ones removed to save bandwidth. Sending each packet itself creates a lot of overhead and its quite possible that oftentimes the whole data contains only stuffing packets.

Right now i sort out the stuffing packets and move the remaining packets ahead in the buffer.
But this seems kind of sluggish and i hope to find a better way.

Code: Select all

// packet_size denotes the size of the UDP packet payload to be sent
// and is usually 1128 Bytes (6*188)
for (int i = 0; i<packet_size;i++) 
{
    if (((buf[i]==0x47)&&(buf[i+1]==0x1f))&&(buf[i+2]==0xff)) // ID the stuffing Header
    {
        // Move the whole buffer 188 Bytes ahead, replacing the stuffing packet
    	for (int j = 0; j < ((packet_size-188)-i);j++)
    	{
    		buf[i+j] = buf[i+j+188];
    	}
        // reduce size, rest is duplicate
    	packet_size -= 188;
    	i--;
    }
}
Right now it works but i hope to make it a bit faster. safememcpy seems not completly applicable without using another buffer array. A memmove could possibly do the trick, i hope.

I am open for suggestions, i guess it is quite easy but i can't seem to think of a better way right now.
User avatar
Andy
Respected Member
Posts: 279
Joined: Fri Dec 11, 2009 1:34 pm

Post by Andy »

Is using C out of the question? If you put your function with memmove() in a C file and put a prototype in a header and include that in the XC file, you should be able to achieve the same functionality with little or no overhead.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

I'd suggest using a wrapper function written in C to allow the use of memmove from XC. I think the following should do the job:

Code: Select all

/**
 * Copies size bytes from dst_offset to src_offset. If the source and
 * destination areas overlap then copying takes place as if the bytes are
 * first copied from the source into a temporary array and then copied to the
 * destination.
 */
void mymemmove(unsigned char data[], unsigned dst_offset, unsigned src_offset, unsigned size) {
  memmove(&data[dst_offset], &data[src_offset], size);
}
User avatar
mike34
Member
Posts: 10
Joined: Thu Apr 08, 2010 2:33 pm
Contact:

Post by mike34 »

Hello

Not trying to avoiding your problemsolving here but Im sure there is something Im missing, still have to ask. Are you in control of what ends up in the buffer the in first place? Moving around data and identifying dummyblocks seems to me a bit expensive. Is it possible to stop those non wanted blocks from entering the buffer and end up with 100 % ready to transfer data? (more efficient)

/Mikael
DaveBest
Member++
Posts: 25
Joined: Mon Jan 18, 2010 3:36 pm

Post by DaveBest »

Unfortunately no.
It's a stream of data @1-2MHz, read over a 8 bit port with external clocking. So we just gather chunks of data and process them while letting another thread filling in when we are busy and likewise.

For the datasource all the data that it is streaming is valid.
It is just stuffing some of it. And we handle some of the data in code and mark that as obsolete/stuffing, so there is no use in transfering except for eating up bandwidth.
Post Reply