# MessageBuffers for core-to-core communication

**URL:** <https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318>\
**Category:** Kernel\
**Created:** [April 14, 2021, 8:33pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318 "2021-04-14T20:33:08Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmh](https://avatars.discourse-cdn.com/v4/letter/c/3da27b/32.png) [@cmh](https://forums.freertos.org/u/cmh)\
**Post date:** [April 14, 2021, 8:33pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/1 "2021-04-14T20:33:09Z")

</div>

I am interested in using MessageBuffers as an inter-core message transport in an AMP setup, as described in Richard Barry’s blog post [https://www.freertos.org/2020/02/simple-multicore-core-to-core-communication-using-freertos-message-buffers.html](https://www.freertos.org/2020/02/simple-multicore-core-to-core-communication-using-freertos-message-buffers.html).

I can follow how this works, but I think there’s a problem if you want to use some MessageBuffers for inter-core communication (ICC), and some for communication within the same core (eg between an ISR and a Task on the same core). In this case you need to overload sbSEND\_COMPLETED such that the ICC version gets used when it’s needed for the ICC-related buffers, but the standard implementation (in stream\_buffer.c) gets used otherwise.

This doesn’t seem to be possible with the current mechanism for providing the custom implementation; as soon as we redefine sbSEND\_COMPLETED we lose all access to the standard implementation, because its all opaquely hidden in stream\_buffer.c.

Is this correct or have I misunderstood something?

# Chris

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [April 14, 2021, 8:54pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/2 "2021-04-14T20:54:50Z")

</div>

Hmm - you raise a very good point, there is no easy way to do this. How would you like to see this made more flexible?

---

<div class="post-metadata">

**Author:** ![RAc](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rac/32/1389_2.png) [@RAc](https://forums.freertos.org/u/RAc)\
**Post date:** [April 14, 2021, 9:19pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/3 "2021-04-14T21:19:50Z")

</div>

well, I’m not too familiar (yet) with the concept, but wouldn’t x[xxx]CreateBuffer **Static** () provide a straightforward solution? Since you know where the affected memory area is, you can keep a second reference to it and use that reference for the non-opaque processing (assuming of course that all concurrent accesses between the two domains of usage are appropriately serialized)?

---

<div class="post-metadata">

**Author:** ![cmh](https://avatars.discourse-cdn.com/v4/letter/c/3da27b/32.png) [@cmh](https://forums.freertos.org/u/cmh)\
**Post date:** [April 14, 2021, 10:24pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/4 "2021-04-14T22:24:39Z")

</div>

I guess I’m a C++ programmer at heart. When we overload a virtual function to extend or modify the behaviour of a class, we always have access to the base class function, which we can call from within our overload function if that’s appropriate.

The current mechanism for overloading sbSEND\_COMPLETED unfortunately implicitly removes access to the base class behaviour. It’s late at night now, so I’ll have a think tomorrow about how that access could be preserved without breaking the FreeRTOS coding style.

---

<div class="post-metadata">

**Author:** ![cmh](https://avatars.discourse-cdn.com/v4/letter/c/3da27b/32.png) [@cmh](https://forums.freertos.org/u/cmh)\
**Post date:** [April 15, 2021, 7:02am UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/5 "2021-04-15T07:02:50Z")

</div>

So, I’ve had a think about this. FreeRTOS doesn’t use virtual functions anywhere, so that doesn’t seem a wise direction to go, so how about a user-supplied ‘hook’ function that gets called at an appropriate point in xMessageBufferSend(), and whose return value can signal back whether to do the standard implementation of sbSEND\_COMPLETED or not. Something like this:

> ```
> xMessageBufferSend()
> {
> /* If a time out is specified and there isn't enough
> space in the message buffer to send the data, then
> enter the blocked state to wait for more space. */
> if( time out != 0 )
> {
> while( there is insufficient space in the buffer &&
> not timed out waiting )
> {
> Enter the blocked state to wait for space in the buffer
> }
> }
> 
> if( there is enough space in the buffer )
> {
> write data to buffer
> #if configUSE_SB_COMPLETED_HOOK
> BaseType_t f = xSbCompletedHook(pxUpdatedBuffer) 
> if (f==pdTRUE)
> {
> sbSEND_COMPLETED(pxUpdatedBuffer)
> }
> #else
> sbSEND_COMPLETED(pxUpdatedBuffer)
> #endif
> }
> }
> 
> ```

I think this, possibly with equivalent changes in related functions, would satisfy what I need, but I recognise I’m not so familiar with the ‘big picture’ where FreeRTOS is concerned so it may be sub-optimal from some other angle.

EDIT: If done this way, maybe sbSEND\_COMPLETED would no longer need to be a user-definable macro, but instead could be a regular private function or just inlined. Alternatively the macro could be retained, at the expense of complexity and potentially causing confusion, for backward compatibility (and maybe deprecated at some point).

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [April 15, 2021, 12:20pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/6 "2021-04-15T12:20:43Z")

</div>

The current method makes a ‘global’ change for all stream/message buffers. The alternative would be to add a callback parameter to the create buffer call that would allow a per-instance override of this operation (this would need to be a new function with the existing one just defaulting to the current behavior). This would add a ‘pointer’ to the size of the buffer control block, which isn’t that bad (and perhaps the addition of the pointer could be controlled by a macro like configUSE\_SB\_COMPLETED\_CALLBACK so old code doesn’t even pay that cost.

---

<div class="post-metadata">

**Author:** ![cmh](https://avatars.discourse-cdn.com/v4/letter/c/3da27b/32.png) [@cmh](https://forums.freertos.org/u/cmh)\
**Post date:** [April 15, 2021, 12:34pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/7 "2021-04-15T12:34:43Z")

</div>

Yes, that would work for me too. You call it a callback, I called it a virtual function, but it’s much the same thing - ie a function called through a pointer held in the per-instance StreamBuffer object.

One point to consider is whether there are valid use cases where you want to do something _in addition to_, as opposed to _instead of_, the default behaviour. I’m not knowledgeable enough about FreeRTOS’s ‘big picture’ to comment on that.

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [April 15, 2021, 12:59pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/8 "2021-04-15T12:59:17Z")

</div>

The difference between a callback and a virtual function is that virtual functions require that you have ‘classes’ with ‘inheretance’ which is beyond the capabilities of C. Call backs allow altering the behavior on a per-instance case, instead of having to create a ‘sub-class’ (which C doesn’t allow). Note that the current Queue/Semaphore/Mutex sharing of common ‘base’ code isn’t done with inheritance, but by carefully defining the Queue (the ‘base’) case as being generic enough that the others are just special cases of it, and the Queue code actually does handle at least most of the special case (I think recursive mutexes add special code, which is why you need to use a different call to use them).

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [April 15, 2021, 7:07pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/9 "2021-04-15T19:07:11Z")

</div>

See [[Feature Request] Enable each stream buffer to use a different sbSEND\_COMPLETED implementation · Issue #312 · FreeRTOS/FreeRTOS-Kernel · GitHub](https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/312)

---

<div class="post-metadata">

**Author:** ![cmh](https://avatars.discourse-cdn.com/v4/letter/c/3da27b/32.png) [@cmh](https://forums.freertos.org/u/cmh)\
**Post date:** [April 15, 2021, 7:33pm UTC](https://forums.freertos.org/t/messagebuffers-for-core-to-core-communication/12318/10 "2021-04-15T19:33:17Z")

</div>

Great. Thanks for your interest in this. In the mean time I have built a simple mechanism using cross-core interrupts and direct task notifications to synchronise a pair of threads, one on each core. I’ll use this to manage access to my own structure in shared memory from those two threads, rather than try to reuse the MessageBuffer from FreeRTOS.

I guess I’ll mark this thread ‘solved’, even though it’s more closed than solved!
