budryerson / TFMini-Plus

Arduino library for the Benewake TFMini-Plus and TFMini-S LiDAR distance sensors.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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).

memcpy( frame, frame + 1, TFMP_FRAME_SIZE);

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