Assuming you are using the default sbSEND_COMPLETE, etc. macros in your configuration, am I wrong in my assumption that if a task is actively using the task notification feature directly, and using stream/message buffers either directly or indirectly as part of some API then the task will block waiting for a task notification that was “consumed” by the polling loop inside the stream buffer call?
Now the sbSEND_COMPLETE macros seem to acknowledge this flaw without actually describing in detail why they exist. These macros are a bit messy compared to the rest of the tightly nit kernel if this is indeed why they exist.
If this is indeed the case, would it not make sense to remember any external task notifications within the stream buffer implementation, and restore them before exiting so that the user(or someone constructing a peripheral driver using stream buffers) does not have to warn its users about these side effects?
To elaborate, the sbSEND_COMPLETE and related macros should be made permanent, additionally the stream buffer should have an additional state that is only set when a task notification is received from outside of the stream buffer API, and the sbXXXX_COMPLETE macros can have the calling task send a task notification to itself, without changing the value(current code looks like it preserves this value intentionally which is odd given it does not preserve the notification status).
I am currently using the above method in most of the peripheral drivers I have designed to implement a low memory(stack may negate this, not sure) semaphore that does not care whether or not the calling task utilizes the notification feature.
I may be wrong in my assumptions, but the existence of the above mentioned macros makes me think otherwise.
I am sure my explanation is a bit confusing so feel free to ask questions so I can elaborate.
In summary, if task notifications are being used by a task that is also using stream buffers, any task notifications received other than send or receive complete notifications will be lost. This is somewhat addressed by the sbXXXX_COMPLETE macros but this critical flaw(unless I am misunderstanding) is not clear at all.
If someone is relying on an event sent by a task notification, and it is infrequent, or happens to always occur while that same task is communicating using a stream buffer, that event will only ever be handled the next time the notification state is set, if it ever is.
EDIT: Another thing my peripheral drivers do to avoid losing “external task notifications” is they will also set the “restore notification state” variable if they attempt to send a task notification but see that an external event has already set it. This external event will of course serve the purpose of waking up the task to handle the peripheral driver event, but right before exiting the driver will send itself a task notification so the caller will immediately handle its own event.