Hi,
I am using a Giga R1 with mbed_giga/4.0.10. I have a simple application split across the M4 and M7 codes. On the M4 my loop() function sleeps for 750ms then calls RPC.send() three times, passing in a std::array<uint32_t, 3> it also calls RPC.println() three times. The send and println calls are interleaved.
On the M7 side the handler for the function invoked indirectly by RPC.send() displays the contents of the array with Serial.println. The array contains, amongst other things, a sequence number. I noticed yesterday that I was dropping messages. In the loop() call, the recommended pattern of while (RPC.available()) { RPC.read() ... etc } is used to handle the debug messages.
I started to investigate and tried two things on a hunch:
- I stopped calling
Serial.printlnin the function on the M7 that handled debug messages. This made no difference. - I removed the
RPC.printlncalls on the M4. This fixed the issue but I don't understand why.
The M4 is sending (std::array and debug messages) 210 bytes for each loop() call. It looks to me like the RX ring buffer polled by RPC.available() is 256 bytes so 210 is a fair chunk of that. This rx_buffer looks like it is filled from the OPENAMP endpoint. Is this right? The M7 is doing nothing in the loop(), and in the message handler for std::array it prints its contents on Serial.
Looking into this a little, as far as I can tell RPC.send() and RPC.println() write to the same raw endpoint (ENDPOINT_RAW). This makes me wonder if the debug printer (which does the 'traditional' call RPC.read() while RPC.available() contends with the event dispatched thread which presumably is doing the same thing. Is this possible? Could the RPC.read() in the main loop() consume data the event dispatch thread might want?
I also noticed that all failures in the underlying message send are lost. See RPC.cpp:
void rpc::client::send_msgpack(RPCLIB_MSGPACK::sbuffer *buffer) {
OPENAMP_send(&rp_endpoints[ENDPOINT_RAW], (const uint8_t*)buffer->data(), buffer->size());
}
OPENAMP_send returns error statuses. Why are these not propagated?
Looking at the ring buffer impl the store looks like this:
template <int N>
void RingBufferN<N>::store_char( uint8_t c )
{
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (!isFull())
{
_aucBuffer[_iHead] = c ;
_iHead = nextIndex(_iHead);
_numElems = _numElems + 1;
}
}
This looks odd to me, i.e. any character pushed when the buffer is full is dropped and the callee is not informed of the drop.
Any clues or thoughts appreciated. I'm new to this stack.
Thanks a lot,
Andy