Is it possible to overwrite in MessageBuffer?

I have a case where simply using xQueueOverwrite() would probably work. But since it’s a “single writer - single reader” case, I thought it would be a better idea to use Message Buffers, as I know that they are more lightweight than Message Queues. Unfortunately, there is no function like xMessageBufferOverwrite(). :slightly_frowning_face:

The first thing comes to mind is resetting the message buffer before sending new data:

xMessageBufferReset(buffer);
xMessageBufferSend(buffer, /* other arguments */);

But this method may fail, as xMessageBufferReset() fails if there is a task blocked on the message buffer which is quite likely.

Is there a suggested workaround for this problem? Is it possible that a function like xMessageBufferOverwrite() can be added to FreeRTOS API in the future? Or should I just use xQueueOverwrite() without worrying about the possible performance gains that could be achieved if I could use a message buffer instead of a message queue?

I think the issue with MessageBufferOverwrite is that it is hard to know where in a given Message Buffer the last message is stored to overwrite it, and because messages are variable length, you can’t just overwrite the first one without a lot of work either, and in either case it still might not fit.

Also, since the real purpose, as stated in the documentation is for queues of length one, the message buffer doesn’t add a whole lot to the system, as other options would work.

A quick thought of how to do this with a message buffer would be to try to reset, and if that fails there is a task blocking, so you know the buffer is empty so you can send. Nothing wrong with the system telling you the reset failed.

Unfortunately it’s not always the case, or maybe I’m designing/imagining it wrong.

I’m trying to implement a client-server mechanism, where clients send requests to servers and wait for or ignore the responses. The reception of a response is an indication of the completion of the request, even when the response contains no meaningful data. Clients can also make non-blocking requests.

Now consider this case: A client makes 3 requests to the server. It doesn’t care the data in responses, but the 3rd one is a blocking call so that the client knows when all 3 request are completed. Then the server tasks runs. For each request, it needs to send a response to the client task using the message buffer. Of course, after the first response, the client is no longer blocked. But the server task may still be in running state and in this case, it tries to queue 2 more responses to the message buffer, which is already full and at the same time, has a task blocking on it.

Honestly, I think that this is an inherently bad protocol design, for many reasons. At the very least, the client should wait for a response, even when ignoring it.

I think the key here is that the message buffer can be defined to hold more than one message, and in fact it normally is.

Perhaps you should also have an indication in the message if the sender wants a completion event. If you aren’t going to wait for the event, or even clear it, it shouldn’t be sent. After all, if the sender wants to queue up 3 requests and then wait for the 2nd and third to complete, you don’t want the 3rd completion to overwrite the 2nd completion just because the receiver hasn’t picked up the message.

I’m trying to implement 2 types of calls: Blocking & non-blocking.

Blocking one is easier. The client just waits for the response in the message buffer (with an optional timeout). However, the response may belong to a previous call which had timed-out. So the server assigns a job ID during the call and it also includes the same ID in the response message so that the client can check if the last response is the one it expects and not a response to a previous call.

In the non-blocking version, the client doesn’t block on message buffer, but it may still want to query it later to determine if the server has processed the request (and send a response).

I’m sorry to bother you with the implementation details. xQueueOverwrite() probably solves my problem. I just wanted to know if it’s possible to mimic the same behavior using message buffers. As the response return path (buffer or queue) is “single writer - single reader”, I thought it might be a good opportunity to use more lightweight message buffers instead of message queues.

As I said, the structure of message buffers, with the variable sized buffers, makes a true overwrite operation hard to implement. If the message buffer is really only expected to hold a single message, then the rest/send sequence should work (if reset gives an ‘error’ it isn’t really a problem). This does have the expected issue that some replies can be lost by being overwritten.

As has been mentioned, this protocol seems not well designed.

Thanks for your attention and suggestions. For now, I will go with xQueueOverwrite() as it’s the fastest route. But I will also consider a redesign of the protocol in long term.