RingBuffer Component with Put/Get/Clear Events

Sometimes I have a good idea how to extend one of my Processor Expert components with an extra feature, but then I step back because why implementing more than I need at the moment? Until another user of the component simply asks for the same thing, and here we go: if one or more can take advantage of a feature, that’s definitely a strong argument to add it :-). This happened with the RingBuffer Processor Expert component I’m using in many projects. And a reader of this blog asked to add some extra event methods: when an item is added or removed to the buffer.

RingBuffer used in USB Component with Extra Events

RingBuffer used in USB Component with Extra Events

Beside of the OnItemPut() and OnItemGet() events, I added an extra OnClear() event which gets called when the ring buffer Clear() method gets called. The events are disabled  by default not to add any overhead, and they can be enabled individually.

Using the CDE (Component Development Environment) of Processor Expert makes it very easy to such additional events: define the interface for the event, and then add the event code to the driver. Below shows it for the Put() method:

byte %'ModuleName'%.%Put(%'ModuleName'_ElementType elem)
{
  byte res = ERR_OK;
  %'ModuleName'%.DEFINE_CRITICAL();

  %'ModuleName'%.ENTER_CRITICAL();
  if (%'ModuleName'%.inSize==%'ModuleName'%.BUF_SIZE) {
    res = ERR_TXFULL;
  } else {
    %'ModuleName'%.buffer[%'ModuleName'%.inIdx] = elem;
    %'ModuleName'%.inSize++;
    %'ModuleName'%.inIdx++;
    if (%'ModuleName'%.inIdx==%'ModuleName'%.BUF_SIZE) {
      %'ModuleName'%.inIdx = 0;
    }
  }
  %'ModuleName'%.EXIT_CRITICAL();
%if defined(OnBufferFull)
  if (res==ERR_TXFULL) {
    %OnBufferFull(); /* call user event */
  }
%endif
%if defined(OnItemPut)
  %OnItemPut(elem); /* call optional user event */
%endif
  return res;
}

To check the details of the change, see the commit on GitHub.

So with using the new RingBuffer events in my USB stack, I can get application notifications for every byte received or sent, which is very useful.

The updated component will be available with the next *.PEupd release.

Happy Eventing 🙂

10 thoughts on “RingBuffer Component with Put/Get/Clear Events

  1. Is it possible to increase the size of Ring buffer ? I am using CodeWarrior version 10.3 and there the limit on ring buffer size is 256bytes.

    Like

  2. Hi Erick,
    Thanks for keeping us informed with new features.
    I was using an old version version of this ring buffer component, just updated and seems the new one doesn’t have the “Clear:” Method. is it correct?
    Thanks
    Marco

    Like

    • Hi Marco,
      No, that would not be correct. The ‘RingBuffer’ component has a Clear() method. Are you sure that you use the ‘RingBuffer’ component? I ask because in the past I had a RingBufferUInt8 which is obsolete new.
      Can you check again?
      Thanks,
      Erich

      Like

      • Hi Erick,
        This happened in a Home copy of the project where I need to do some code walk through, Compilation failed due the lack of the “Clear” method. After updating the components from Sourceforge, compilation failed again, but If I add a new Ringbuffer then I get the Clear method along with the events mentioned in this post, what I need is erase and replace with the new.
        One thing I notice is that this new ring buffer component generates a Critical Section. I have worked with the component that lacks this referenced component for months. is there any advice on this? so far I haven’t notice any critical section problem as just move the ring buffer to another buffer where I I do any data handling. My application requires 8 UARTs and I am multiplexing the serial port 2:1 with each one having its own working buffer, where I do the data processing.
        Thanks again for valuable work, it is very useful and practical. It has saved me tons of hours of work!
        Marco

        Like

  3. Hi Erich,

    Thank you for all your work over the years. Your posts have been a great resource.

    I have only recently introduced this component into a Processor Expert project (one whose MCU is only supported by Processor Expert of old). The ring buffer is from the 2019-12-31 Components archive. I was surprised to find that the implementation handled overflow situations a bit strangely; I would expect a ring buffer to replace the oldest data and continue nicely. It could perhaps set the overflow flag and invoke a user defined function per occurrence. But I would not expect it to reject the character put and return ERR_TXFULL. It seems the up front work I now do to work around the situation should be handled by the component. Curious about your thoughts.

    James

    Like

    • Hi James,
      thanks!
      About the overflow handling: this is of course up to debate. It all depends where you want to loose the data (if at all): on the producer side or the consumer side.
      To my understanding it makes more sense the way it is implemented, so the producer could wait and give the consumer time to pick the data.
      This is consistent for example how FreeRTOS is handling queues too.
      If you need to call a user defined function: you could to this with the current implementation too: the producer could do this when he receives ERR_TXFULL.
      Of course it all depends for what you need the ring buffer: with the current implementation say the beginning of a message is retained. If it would overwrite things as in your approach the start of the message would get overwritten and potentially invalidate the message.
      In any case: you could change the component how it works if you like to change it?
      I hope that makes sense.

      Liked by 1 person

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.