# Static deque for CANFD ISR buffer

**URL:** <https://forum.opencyphal.org/t/static-deque-for-canfd-isr-buffer/649>\
**Category:** LibCyphal\
**Created:** [October 15, 2019, 5:13pm UTC](https://forum.opencyphal.org/t/static-deque-for-canfd-isr-buffer/649 "2019-10-15T17:13:49Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![noxuz](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/noxuz/32/397_2.png) [@noxuz](https://forum.opencyphal.org/u/noxuz)\
**Post date:** [October 15, 2019, 5:13pm UTC](https://forum.opencyphal.org/t/static-deque-for-canfd-isr-buffer/649/1 "2019-10-15T17:13:49Z")

</div>

Regarding the S32K driver layer for libuavcan, the current implementation uses an almost naive use of the deque STL for limiting the size of the RX queue as shown briefly next:

```
if (RX_ISRframeCount &lt;= Frame_Capactiy )
{
RX_ISRframeCount++;

/* Insert the frame into the queue */ 
S32K_InterfaceManager::frame_ISRbuffer.push_back(FrameISR);
}

```

And in the read function it will be inverted as shown:

```
/* Check if the ISR buffer isn't empty */
if(!S32K_InterfaceManager::frame_ISRbuffer.empty())
{
/* Get the front element of the queue buffer */
out_frames[1] = FS32K_InterfaceManager::frame_ISRbuffer.front();

/* Pop the front element of the queue buffer */
S32K_InterfaceManager::frame_ISRbuffer.pop_front();

/* Decrease frame count */
RX_ISRframeCount--;
}

```

¿How can the deque STL be used while keeping a static deterministic ISR buffer?

Thank you in advance.

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [October 16, 2019, 8:43am UTC](https://forum.opencyphal.org/t/static-deque-for-canfd-isr-buffer/649/2 "2019-10-16T08:43:54Z")

</div>

Hi Abraham. I am no @scottdixon, but if I were impersonating him I would have probably said:

```auto
std::deque<CAN::Frame, libuavcan::platform::memory::PoolAllocator<...>>

```

Replace the ellipsis with the appropriate parameters as needed. The second template parameter `libuavcan::platform::memory::PoolAllocator` comes from:

> <https://github.com/UAVCAN/libuavcan/blob/1e0d947132b565601612f7cae528ce31f492f9f9/libuavcan/include/libuavcan/platform/memory.hpp#L180-L305>

I assume here that the pool allocator is interrupt-safe. If you are uncomfortable with such assumptions, write your own queue instead, or just re-use this one:

> <https://github.com/UAVCAN/libuavcan_stm32/blob/4e0a24756090d218b469f561d7e0d35e5f2f5427/driver/include/uavcan_stm32/can.hpp#L49-L78>

(implementation: [https://github.com/UAVCAN/libuavcan\_stm32/blob/4e0a24756090d218b469f561d7e0d35e5f2f5427/driver/src/uc\_stm32\_can.cpp#L126-L183;](https://github.com/UAVCAN/libuavcan_stm32/blob/4e0a24756090d218b469f561d7e0d35e5f2f5427/driver/src/uc_stm32_can.cpp#L126-L183;) you will need to ensure synchronized access).

I don’t think you need `RX_ISRframeCount`; use `std::deque<>::size()` instead or whatever queue class you’re using. Redundant state is bad.

I strongly recommend following a consistent naming style as described in the [Zubax C++ Conventions](https://kb.zubax.com/x/84Ah).

---

<div class="post-metadata">

**Author:** ![scottdixon](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/scottdixon/32/39_2.png) [@scottdixon](https://forum.opencyphal.org/u/scottdixon)\
**Post date:** [October 16, 2019, 5:22pm UTC](https://forum.opencyphal.org/t/static-deque-for-canfd-isr-buffer/649/3 "2019-10-16T17:22:34Z")

</div>

The block allocator is ISR-safe (it uses an optimistic/lockless implementation to find free blocks) as long as you are _not_ compiling with `-fno-threadsafe-statics` (which we are in our current example so we should change that).

In short, Pavel’s channeling of myself is correct.

---

<div class="post-metadata">

**Author:** ![noxuz](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/noxuz/32/397_2.png) [@noxuz](https://forum.opencyphal.org/u/noxuz)\
**Post date:** [October 18, 2019, 5:34pm UTC](https://forum.opencyphal.org/t/static-deque-for-canfd-isr-buffer/649/4 "2019-10-18T17:34:32Z")

</div>

Thank you, the PoolAllocator fits as a plug & play custom allocator for the STL deque, the line would be as follows

```
/* Intermediate RX buffer for ISR reception with static memory pool */
static std::deque<FrameType, platform::PoolAllocator<S32K_FRAME_CAPACITY, sizeof(FrameType)> > frame_ISRbuffer;

```

This constant it’s a private member of S32K\_InterfaceManager

```
/* Frame capacity for the intermediate ISR buffer */
constexpr static std::size_t S32K_FRAME_CAPACITY = 500;

```

And substituted the CAN::Frame with the “using” directive from the class template parameter at interfaces.hpp which solves to CAN::Frame\< CAN::TypeFD::MaxFrameSizeBytes\>

```
    /**
    * The media-specific frame type exchanged across this interface.
    */
    using FrameType = FrameT;

```

The changes can be seen in [https://github.com/noxuz/libuavcan\_s32k/blob/master/S32K\_libuavcan.hpp](https://github.com/noxuz/libuavcan_s32k/blob/master/S32K_libuavcan.hpp)
