<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>LPC MicrocontrollersのトピックRingBuffer library, suggestion for V2.13</title>
    <link>https://community.nxp.com/t5/LPC-Microcontrollers/RingBuffer-library-suggestion-for-V2-13/m-p/575090#M19168</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;STRONG&gt;Content originally posted in LPCWare by mch0 on Tue Sep 09 06:43:52 MST 2014&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN&gt;Hello,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I would like to propose an addition to the current ringbuffer library.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;A ringbuffer naturally must wrap around at some address and there is no problem with the library.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;However, there are at least two other libraries (USB and LWIP) which can use linear memory space only or very efficiently (zero copy model).&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;If you want to combine the two libraries it is necessary to know the number of bytes in the ringbuffer that can be accessed in a linear fashion, i.e. before the wrap.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;For example, in my application, I "printf()" into a ringbuffer and likewise "scanf()" from another ringbuffer.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;On the other side of each ringbuffer I can attach different channels for input/output. Currently these include USB, the UARTs and Ethernet via LWIP. All channels tested and working so far.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Now LWIP wants to copy from/to a linear buffer, no matter if you use zero-copy or not.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;To achieve this I have added the following code to the ringbuffer library (note that I have not modified any existing code):&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD bgcolor="#cacaca"&gt; &lt;PRE&gt;**
 * @briefReturn number of bytes in the ring buffer that can be retrieved in ascending linear order from tail
 * @paramRingBuff: Pointer to ring buffer
 * @returnNumber of bytes in linear order
 */

int RingBuffer_GetCountLinear(RINGBUFF_T *RingBuff)
{
return MIN(RingBuffer_GetCount(RingBuff),RingBuff-&amp;gt;count - RB_INDT(RingBuff));
}

/**
 * @briefReturn pointer to tail
 * @paramRingBuff: Pointer to ring buffer
 * @returnPointer to tail
 */

STATIC INLINE void* RingBuffer_GetTail(RINGBUFF_T *RingBuff)
{
return RingBuff-&amp;gt;data+RB_INDT(RingBuff);
}

/**
 * @briefMove tail pointer by n bytes (deletes n oldest bytes)
 * @paramRingBuff: Pointer to ring buffer
 * @paramn: number of bytes to be deleted
 * @returnNumber of bytes deleted
 */

int RingBuffer_MoveTail(RINGBUFF_T *RingBuff, int n)
{
if (RingBuffer_GetCount(RingBuff) &amp;lt; n) n=RingBuffer_GetCount(RingBuff);
RingBuff-&amp;gt;tail+=n;
return n;
}&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;These functions now allow me to determine the number of bytes I can read in ascending order. When read, I can discard them from the buffer.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I have tested these fucnctions in my telnet-application.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;A use case, here for LWIP, could look like this:&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD bgcolor="#cacaca"&gt; &lt;PRE&gt;
// if the buffer is not empty, then stuff as much as possible into the LWIP buffers again
if (!RingBuffer_IsEmpty(&amp;amp;out.rb))
{
// get number of bytes that can be copied/accessed in ascending order
n=MIN(tcp_sndbuf(lwip_dbg.accepted), RingBuffer_GetCountLinear(&amp;amp;out.rb));

// copy data directly from ringbuffer memory to LWIP memory
tcp_write(lwip_dbg.accepted, RingBuffer_GetTail(&amp;amp;out.rb), n, TCP_WRITE_FLAG_COPY);

// free ringbuffer memory
RingBuffer_MoveTail(&amp;amp;out.rb, n);
}
&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;In this example I do not use the zero-copy strategy, but this is just a matter of deferring the last line to the next callback of data_sent().&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Right now I have placed these additional three functions outside the V2.12 ringbuffer libray to keep it in the original state. However, if deemed useful by the LPCOpen developers, I would suggest to include these functions after additional test in the next version.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;I think they could be useful for others and they cannot break any existing code.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Best regards,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Mike&lt;/SPAN&gt;&lt;BR /&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Wed, 15 Jun 2016 20:16:10 GMT</pubDate>
    <dc:creator>lpcware</dc:creator>
    <dc:date>2016-06-15T20:16:10Z</dc:date>
    <item>
      <title>RingBuffer library, suggestion for V2.13</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/RingBuffer-library-suggestion-for-V2-13/m-p/575090#M19168</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;STRONG&gt;Content originally posted in LPCWare by mch0 on Tue Sep 09 06:43:52 MST 2014&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN&gt;Hello,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I would like to propose an addition to the current ringbuffer library.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;A ringbuffer naturally must wrap around at some address and there is no problem with the library.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;However, there are at least two other libraries (USB and LWIP) which can use linear memory space only or very efficiently (zero copy model).&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;If you want to combine the two libraries it is necessary to know the number of bytes in the ringbuffer that can be accessed in a linear fashion, i.e. before the wrap.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;For example, in my application, I "printf()" into a ringbuffer and likewise "scanf()" from another ringbuffer.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;On the other side of each ringbuffer I can attach different channels for input/output. Currently these include USB, the UARTs and Ethernet via LWIP. All channels tested and working so far.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Now LWIP wants to copy from/to a linear buffer, no matter if you use zero-copy or not.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;To achieve this I have added the following code to the ringbuffer library (note that I have not modified any existing code):&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD bgcolor="#cacaca"&gt; &lt;PRE&gt;**
 * @briefReturn number of bytes in the ring buffer that can be retrieved in ascending linear order from tail
 * @paramRingBuff: Pointer to ring buffer
 * @returnNumber of bytes in linear order
 */

int RingBuffer_GetCountLinear(RINGBUFF_T *RingBuff)
{
return MIN(RingBuffer_GetCount(RingBuff),RingBuff-&amp;gt;count - RB_INDT(RingBuff));
}

/**
 * @briefReturn pointer to tail
 * @paramRingBuff: Pointer to ring buffer
 * @returnPointer to tail
 */

STATIC INLINE void* RingBuffer_GetTail(RINGBUFF_T *RingBuff)
{
return RingBuff-&amp;gt;data+RB_INDT(RingBuff);
}

/**
 * @briefMove tail pointer by n bytes (deletes n oldest bytes)
 * @paramRingBuff: Pointer to ring buffer
 * @paramn: number of bytes to be deleted
 * @returnNumber of bytes deleted
 */

int RingBuffer_MoveTail(RINGBUFF_T *RingBuff, int n)
{
if (RingBuffer_GetCount(RingBuff) &amp;lt; n) n=RingBuffer_GetCount(RingBuff);
RingBuff-&amp;gt;tail+=n;
return n;
}&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;These functions now allow me to determine the number of bytes I can read in ascending order. When read, I can discard them from the buffer.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I have tested these fucnctions in my telnet-application.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;A use case, here for LWIP, could look like this:&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD bgcolor="#cacaca"&gt; &lt;PRE&gt;
// if the buffer is not empty, then stuff as much as possible into the LWIP buffers again
if (!RingBuffer_IsEmpty(&amp;amp;out.rb))
{
// get number of bytes that can be copied/accessed in ascending order
n=MIN(tcp_sndbuf(lwip_dbg.accepted), RingBuffer_GetCountLinear(&amp;amp;out.rb));

// copy data directly from ringbuffer memory to LWIP memory
tcp_write(lwip_dbg.accepted, RingBuffer_GetTail(&amp;amp;out.rb), n, TCP_WRITE_FLAG_COPY);

// free ringbuffer memory
RingBuffer_MoveTail(&amp;amp;out.rb, n);
}
&lt;/PRE&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;In this example I do not use the zero-copy strategy, but this is just a matter of deferring the last line to the next callback of data_sent().&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Right now I have placed these additional three functions outside the V2.12 ringbuffer libray to keep it in the original state. However, if deemed useful by the LPCOpen developers, I would suggest to include these functions after additional test in the next version.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;I think they could be useful for others and they cannot break any existing code.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Best regards,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Mike&lt;/SPAN&gt;&lt;BR /&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 15 Jun 2016 20:16:10 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/RingBuffer-library-suggestion-for-V2-13/m-p/575090#M19168</guid>
      <dc:creator>lpcware</dc:creator>
      <dc:date>2016-06-15T20:16:10Z</dc:date>
    </item>
  </channel>
</rss>

