message buffers and queue set

radozub wrote on Wednesday, June 12, 2019:

Hello,
There exists Queue set to unblock task from multiple queues.

Is there any similar instrument for message buffer,

Thanks

heinbali01 wrote on Thursday, June 13, 2019:

A set of Message Buffers does not exist, and I do not think that is necessary, because Message Buffers use the task-notification as a way to unblock tasks.

Suppose your task must read from several messages buffers, you can call xStreamBufferReceive() in a non-blocking way:

	BaseType_t xIndex;
	char cBuffer[ BUFFER_SIZE ];
	for( ;; )
	{
	TickType_t xTicksToWait = portMAX_DELAY;
	TickType_t xNonBlocking = 0u;

		xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
		for( xIndex = 0; xIndex < queue_count; xIndex++ )
		{
			xCount = xStreamBufferReceive( xStreamBuffer[ xIndex ], ( void * ) cBuffer, sizeof( cBuffer ), xNonBlocking );
			if( xCount > 0 )
			{
			}
		}
	}

So first the task blocks until one of the message buffers unblock it. When woken up, it will check all message buffers.

Would that work for you?

radozub wrote on Thursday, June 13, 2019:

OK, I underestand, make sense.
I’ll try to implement this way.
Thank you for your help.

Radomir

radozub wrote on Friday, June 14, 2019:

Hello again,
please let me underestand in the example you posted above, who is responsible for notification sending.
Just to clarify, I am using message buffer, not stream buffer mentioned above.

I have sw timer callback function sending data by message buffer

void mySwTimerCallbackFnc(void)
{
/* myBuf filled with some data */
xMessageBufferSend( xMessageBuffer, myBuf, sizeof(myBuf), 0);
}

a) am I responsible to send notification to task . Or “xMessageBufferSend” API does it.
b) if I am responsible to send task notification, may I use EventGroup for the same task synchronisation purpose.
c) how the “xMessageBufferSend” knows what task to notify?
Thank you

Radomir

richarddamon wrote on Friday, June 14, 2019:

Radomir, it depends a bit on which notify you mean. If you mean for normal application of Message buffers, then Message Buffers are designed to have a single sender and a single receiver. If the receiver is blocked on the Message Buffer, waiting on a messgae, the API will wake it up and it will take the message. If it isn’t waiting on the buffer, the API doesn’t remember who is the receiver, but doesn’t need to do anything, as the task will check the buffer and find the message, and continue,

If you are refering to the example multiple Message Buffer mode described by Hein, the the sending code needs to know about it, and after posting the message, post the wake up notification to move the task along, and it will need to know what task to notify.

I personally might do it differently, since message buffers can handle multiple different types of messages, I would try to have the receiver waiting on just a single message buffer, and each sender, if needed, sends different messages with the information in them indicating which type of message it is. Then, to get around the single sender requirement, the Message Buffer would be protected by a Mutex, so the senders aquire the mutex, send the message, and give back the mutex to send a message. (This would all be encased in a Multisender Message Buffer API (user written, but easily a local user library).

If that is not feasable, then I would likely encapsulate it in a private API to send the message, and the API would have a way to know which task it needs to wake up (in part as that allows me to easly change how that is determined, rather than needing to find all the places I did this).

radozub wrote on Friday, June 14, 2019:

Richard, thank you for clarification,
that the xMessageBufferSend API looks for blocked task and then sends notification.
Also important thing is that xMessageBufferSend API DOES NOT send notify,
if no task is waiting for. (means that I can use notification for other purposes).

Single message buffer is not applicable as I need prioritize messages (commnds vs data)

So I am going with encapsulation API with use of Event Groups

Many thank

Radomir

richarddamon wrote on Friday, June 14, 2019:

My undertanding of how MessageBuffers use TaskNotification is they don;'t use any bits within the notification word, and don’t clear the bits, so they share well with other uses of TaskNotification (at least in the latest version of FreeRTOS). If your notifications set a bit or increment the count, then that will be remembered even through a MessageBuffer wait. If such a notification comes while waiting for a MessageBuffer, it will wake up the task, it will see the Buffer is still empty, and continue waiting for the rest of the block time, and that notification will still be pending when you check for it. You only will run into issues if you also use a zero value notification, those really require that you know the task is currently waiting for THAT particular zero value notification (which the Message Buffers do, as the task sets a flag in the buffer just before starting the wait)

radozub wrote on Friday, June 14, 2019:

That is interesting, it means that message buffer doesn’t “consume” notification
if buffer is empty! Thanks for clarification.

Radomir