RPi Pico CRC check error (memcpy)
farzadsw opened this issue · comments
I tried to run the sample code on an RPi Pico, but I always got a 0 as output (Arduino IDE 2.0.3).
The problem is the memcpy function for shifting the arrays with overlapping memory. I changed it to memmove and it works now (Also I increased the buffer size for Serial1, to 128 bytes).
Line 137 in 90f1fcd
Just ran into the same issue, also note that memcpy is used in multiple other places in the library and could produce unpredictable results. This should be noted in the Arduino reference if the library is no longer being updated?
This is an Arduino library. I believe that the RPi Pico is a multi-processor, multi-threading, multi-tasking type of micro-controller. In that kind of environment, I can understand why memcpy
might deliver unpredictable results, and probably why the RPi C++ SDK doesn't like it. memmove
is more reliable because it uses an intermediate register, but it takes slightly longer and uses more memory. If using memmove
works for you, then go ahead. I'll be happy to make a note in the reference. May I ask why you don't use the Python version of this library?
Thanks for the clarification.
In my case, I had existing code written in C++ with a relatively fast control loop, so I decided to stick with C++.
The beauty of the C++ is its ability to get "close to the metal," which can be important for IoT projects with limited resources (or when just having fun).
memcpy
is meant to be the fastest library routine for memory-to-memory copy. It is usually more efficient than strcpy
, which must scan the data it copies or memmove
, which must take precautions to handle overlapping inputs.
A C++ reference for memcpy
states:
"To avoid overflows, the size of the arrays pointed to by both the destination and source parameters, shall be at least num bytes, and should not overlap (for overlapping memory blocks, memmove
is a safer approach)."
https://cplusplus.com/reference/cstring/memcpy/
In practice, if memory areas do not overlap, one can use memcpy
in any direction. If they do overlap, one needs to determine which end of the destination overlaps with the source and choose the direction of copy accordingly.
• If the beginning of the destination overlaps with the source, copy from the end of the source to the end of the destination.
src | A | B | C | |
\ \ \
3 2 1
\ \ \
dest | A | A | B | C|
• If the end of destination overlaps, copy from beginning of the source to the beginning of the destination.
src | | A | B | C |
/ / /
1 2 3
/ / /
dest | A | B | C | C |
I do not see anything inherently wrong or "undefined" about the way memcpy
is used in this library. And you have not included your code, so I can't really tell where the real problem may be. But I'm happy to know that you were able to find a solution. Please include your code next time.
All the best,
Bud Ryerson
San Francisco