RngLib

From ProjectWiki
(Difference between revisions)
Jump to: navigation, search
m (Reverted edits by Iqoquhir (Talk); changed back to last version by 74.132.200.196)
Line 1: Line 1:
=[http://ekipebu.co.cc This Page Is Currently Under Construction And Will Be Available Shortly, Please Visit Reserve Copy Page]=
+
<big>rngLib - an implementation of vxWorks style ring buffers</big>
&lt;big&gt;rngLib - an implementation of vxWorks style ring buffers&lt;/big&gt;
+
  
 
__TOC__
 
__TOC__
Line 13: Line 12:
  
 
==Where to get it==
 
==Where to get it==
Currently the sources for this are part of [http://blea.ch/wiki/index.php/Category:LIBTHDS LibThds]. The source can be downloaded via SVN (see libthds page) or directly from the svn httpd:&lt;br&gt;
+
Currently the sources for this are part of [http://blea.ch/wiki/index.php/Category:LIBTHDS LibThds]. The source can be downloaded via SVN (see libthds page) or directly from the svn httpd:<br>
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/source/shared/source/rngLib.c rngLib.c]
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/source/shared/source/rngLib.c rngLib.c]
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/source/shared/include/rngLib.h rngLib.h]
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/source/shared/include/rngLib.h rngLib.h]
32bit buffer versions:&lt;br&gt;
+
32bit buffer versions:<br>
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/source/shared/source/rng32Lib.c rng32Lib.c]
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/source/shared/source/rng32Lib.c rng32Lib.c]
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/source/shared/include/rng32Lib.h rng32Lib.h]
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/source/shared/include/rng32Lib.h rng32Lib.h]
  
An example of rng32Lib usage that caches keypresses during vblank handler may be found here:&lt;br&gt;
+
An example of rng32Lib usage that caches keypresses during vblank handler may be found here:<br>
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/examples/rng32Lib/ rng32Lib example]
 
* [http://svn.blea.ch/thdslib/trunk/thdslib/examples/rng32Lib/ rng32Lib example]
  
Line 26: Line 25:
 
The function descriptions here are given using the character/8bit versions of the functions. For the 32 bit version, please note that function names and data type names are the same, except where indicated, and prefixed with either 'rng32' for functions, 'RNG32' for macros, and 'RING32_ID' for data types. They function in an identical manner except for using unsigned long int (u32) instead of char (u8) for data.
 
The function descriptions here are given using the character/8bit versions of the functions. For the 32 bit version, please note that function names and data type names are the same, except where indicated, and prefixed with either 'rng32' for functions, 'RNG32' for macros, and 'RING32_ID' for data types. They function in an identical manner except for using unsigned long int (u32) instead of char (u8) for data.
  
'''rngCreate'''&lt;br&gt;
+
'''rngCreate'''<br>
 
Creates a new ring buffer instance
 
Creates a new ring buffer instance
 
* nbytes - number to bytes (or 32 bit words for thFifo32) to be allocated for this buffer. Directly represents how much data the buffer can hold.
 
* nbytes - number to bytes (or 32 bit words for thFifo32) to be allocated for this buffer. Directly represents how much data the buffer can hold.
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
RING_ID rngCreate(int nbytes);
 
RING_ID rngCreate(int nbytes);
&lt;/source&gt;
+
</source>
  
'''rngDelete'''&lt;br&gt;
+
'''rngDelete'''<br>
 
Deletes a ring buffer instance
 
Deletes a ring buffer instance
 
* ringId - object of type RING_ID to be destroyed
 
* ringId - object of type RING_ID to be destroyed
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
void rngDelete(RING_ID ringId);
 
void rngDelete(RING_ID ringId);
&lt;/source&gt;
+
</source>
  
'''rngFlush'''&lt;br&gt;
+
'''rngFlush'''<br>
 
Removes all content from ring buffer.
 
Removes all content from ring buffer.
 
* ringId - object of type RING_ID
 
* ringId - object of type RING_ID
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
void rngFlush(RING_ID ringId);  //empty all buffer content,
 
void rngFlush(RING_ID ringId);  //empty all buffer content,
&lt;/source&gt;
+
</source>
  
'''rngBufGet'''&lt;br&gt;
+
'''rngBufGet'''<br>
 
Retrieves data, if available, from ring buffer.
 
Retrieves data, if available, from ring buffer.
 
* ringId - object of type RING_ID
 
* ringId - object of type RING_ID
 
* buffer - point to buffer to contain data
 
* buffer - point to buffer to contain data
 
* maxbytes - maximum number of bytes to be read
 
* maxbytes - maximum number of bytes to be read
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
int rngBufGet(RING_ID rngId, char *buffer, int maxbytes);  //get number of chars, retuns nbytes gotten
 
int rngBufGet(RING_ID rngId, char *buffer, int maxbytes);  //get number of chars, retuns nbytes gotten
&lt;/source&gt;
+
</source>
  
'''rngBufPut'''&lt;br&gt;
+
'''rngBufPut'''<br>
 
* ringId - object of type RING_ID
 
* ringId - object of type RING_ID
 
* buffer - pointer to buffer containing data to be placed into buffer
 
* buffer - pointer to buffer containing data to be placed into buffer
 
* nbytes - number of bytes to place into buffer, usually the length of buffer.
 
* nbytes - number of bytes to place into buffer, usually the length of buffer.
 
Returns the number of bytes actually written to the buffer. If buffer is full will return 0.  
 
Returns the number of bytes actually written to the buffer. If buffer is full will return 0.  
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
int rngBufPut(RING_ID rngId, char *buffer, int nbytes); //write a number of chars, returns nbytes put
 
int rngBufPut(RING_ID rngId, char *buffer, int nbytes); //write a number of chars, returns nbytes put
&lt;/source&gt;
+
</source>
  
'''rngIsEmpty'''&lt;br&gt;
+
'''rngIsEmpty'''<br>
 
Test if ring buffer contains data
 
Test if ring buffer contains data
 
* ringId - object of type RING_ID
 
* ringId - object of type RING_ID
 
Returns true if ring buffer is empty, otherwise false.
 
Returns true if ring buffer is empty, otherwise false.
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
bool rngIsEmpty(RING_ID ringId); //tst if buffer is empty
 
bool rngIsEmpty(RING_ID ringId); //tst if buffer is empty
&lt;/source&gt;
+
</source>
  
'''rngCreate'''&lt;br&gt;
+
'''rngCreate'''<br>
 
Test if ring buffer is at maximum capacity
 
Test if ring buffer is at maximum capacity
 
* ringId - object of type RING_ID
 
* ringId - object of type RING_ID
 
Returns true if buffer is full, otherwise false
 
Returns true if buffer is full, otherwise false
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
bool rngIsFull(RING_ID ringId);  //tst if full
 
bool rngIsFull(RING_ID ringId);  //tst if full
&lt;/source&gt;
+
</source>
  
'''rngFreeBytes/rng32FreeWords'''&lt;br&gt;
+
'''rngFreeBytes/rng32FreeWords'''<br>
 
* ringId - object of type RING_ID
 
* ringId - object of type RING_ID
 
Returns an integer indicating the maximum number of bytes (or 32 bit words for thFifo32) that may be placed in buffer before it is full.
 
Returns an integer indicating the maximum number of bytes (or 32 bit words for thFifo32) that may be placed in buffer before it is full.
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
int rngFreeBytes(RING_ID ringId); //how many free bytes remain?
 
int rngFreeBytes(RING_ID ringId); //how many free bytes remain?
&lt;/source&gt;
+
</source>
 
32bit version
 
32bit version
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
int rng32FreeWords(RING_ID ringId); //how many free bytes remain?
 
int rng32FreeWords(RING_ID ringId); //how many free bytes remain?
&lt;/source&gt;
+
</source>
  
'''rngNBytes/rng32NWords'''&lt;br&gt;
+
'''rngNBytes/rng32NWords'''<br>
 
Number of bytes bytes (or 32 bit words for thFifo32) that may be gotten from the ring buffer
 
Number of bytes bytes (or 32 bit words for thFifo32) that may be gotten from the ring buffer
 
* ringId - object of type RING_ID
 
* ringId - object of type RING_ID
 
Returns number of bytes (or 32 bit words for thFifo32) that may be retrieved from buffer
 
Returns number of bytes (or 32 bit words for thFifo32) that may be retrieved from buffer
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
int rngNBytes(RING_ID ringId);   
 
int rngNBytes(RING_ID ringId);   
&lt;/source&gt;
+
</source>
 
32bit version
 
32bit version
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
int rngNWords(RING_ID ringId);   
 
int rngNWords(RING_ID ringId);   
&lt;/source&gt;
+
</source>
  
'''rngPutAhead'''&lt;br&gt;
+
'''rngPutAhead'''<br>
 
Put a single byte into ring buffer without incrementing count. rngFreeBytes, rngIsFull, or rngIsEmpty should probably be used for most cases to first determine that placing a character into the buffer will not result in overflow.
 
Put a single byte into ring buffer without incrementing count. rngFreeBytes, rngIsFull, or rngIsEmpty should probably be used for most cases to first determine that placing a character into the buffer will not result in overflow.
 
* ringId - object of type RING_ID
 
* ringId - object of type RING_ID
 
* byte - single character (or 32bit word for thFifo32) to be placed into buffer
 
* byte - single character (or 32bit word for thFifo32) to be placed into buffer
 
* offset - where to store the data, 0 would be at first, 1 would be the character after 0, 2 would be two characters ahead, etc etc
 
* offset - where to store the data, 0 would be at first, 1 would be the character after 0, 2 would be two characters ahead, etc etc
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
void rngPutAhead(RING_ID ringId, char byte, int offset); //put byte in the read buffer without incrementing counter
 
void rngPutAhead(RING_ID ringId, char byte, int offset); //put byte in the read buffer without incrementing counter
&lt;/source&gt;
+
</source>
  
'''rngMoveAhead'''&lt;br&gt;
+
'''rngMoveAhead'''<br>
 
Used in conjunction with (usually after) rngPutAhead, will increment the number of characters (or 32bit words for thFifo32) specified.
 
Used in conjunction with (usually after) rngPutAhead, will increment the number of characters (or 32bit words for thFifo32) specified.
 
* ringId - object of type RING_ID
 
* ringId - object of type RING_ID
 
* n - number of bytes (or 32bit words for thFifo32) to increment fifo counter. Usually the number of bytes placed into the buffer using rngMoveAhead.
 
* n - number of bytes (or 32bit words for thFifo32) to increment fifo counter. Usually the number of bytes placed into the buffer using rngMoveAhead.
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
void rngMoveAhead(RING_ID ringId, int n); //move inbuffer ahead n # of bytes (used after a PutAhead)
 
void rngMoveAhead(RING_ID ringId, int n); //move inbuffer ahead n # of bytes (used after a PutAhead)
&lt;/source&gt;
+
</source>
  
 
==Macros==
 
==Macros==
'''RNG_ELEM_PUT'''&lt;br&gt;
+
'''RNG_ELEM_PUT'''<br>
 
Puts a single character (or 32bit word for thFifo32) into the ring buffer and increments the element count, faster than rngPutBytes and should be used when single character or word is to be placed into buffer.
 
Puts a single character (or 32bit word for thFifo32) into the ring buffer and increments the element count, faster than rngPutBytes and should be used when single character or word is to be placed into buffer.
 
* r - object of type RING_ID  
 
* r - object of type RING_ID  
Line 128: Line 127:
 
* t - an integer to be used internally by the macro for calculations
 
* t - an integer to be used internally by the macro for calculations
 
returns 1 if successfull, otherwise 0
 
returns 1 if successfull, otherwise 0
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
// returns 1 if success 0 if not
 
// returns 1 if success 0 if not
 
#define RNG_ELEM_PUT(r, c, t)
 
#define RNG_ELEM_PUT(r, c, t)
&lt;/source&gt;
+
</source>
 
For example:
 
For example:
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
register int myregint;
 
register int myregint;
 
RNG_ELEM_PUT(myringid, 'c', myregint);
 
RNG_ELEM_PUT(myringid, 'c', myregint);
 
//Is equivalent to:
 
//Is equivalent to:
ringPutBytes(myringid, &quot;c&quot;, 1);
+
ringPutBytes(myringid, "c", 1);
&lt;/source&gt;
+
</source>
  
'''RNG_ELEM_GET'''&lt;br&gt;
+
'''RNG_ELEM_GET'''<br>
 
Gets a single character (or 32bit word for thFifo32) from the ring buffer and decrements the element count, faster than rngGetBytes and should be used when single character or word is to be retrieved into buffer.
 
Gets a single character (or 32bit word for thFifo32) from the ring buffer and decrements the element count, faster than rngGetBytes and should be used when single character or word is to be retrieved into buffer.
 
* r - object of type RING_ID  
 
* r - object of type RING_ID  
Line 146: Line 145:
 
* t - an integer to be used internally by the macro for calculations
 
* t - an integer to be used internally by the macro for calculations
 
returns 1 if successfull, otherwise 0
 
returns 1 if successfull, otherwise 0
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
#define RNG_ELEM_GET(r,p,f)
 
#define RNG_ELEM_GET(r,p,f)
&lt;/source&gt;
+
</source>
 
For example:
 
For example:
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
 
register int myregint;
 
register int myregint;
char blah[]=&quot;c&quot;;
+
char blah[]="c";
 
RNG_ELEM_GET(myringid, blah, myregint);
 
RNG_ELEM_GET(myringid, blah, myregint);
 
//Is equivalent to:
 
//Is equivalent to:
char blah[]=&quot;c&quot;;
+
char blah[]="c";
 
ringPutBytes(myringid, blah, 1);
 
ringPutBytes(myringid, blah, 1);
&lt;/source&gt;
+
</source>
  
 
==Examples==
 
==Examples==
Write the string into buffer and read it back out again.&lt;br&gt;
+
Write the string into buffer and read it back out again.<br>
&lt;source lang=&quot;c&quot;&gt;
+
<source lang="c">
char blahsrc[]=&quot;this is blah&quot;;
+
char blahsrc[]="this is blah";
 
char blahdst[0x20];
 
char blahdst[0x20];
 
int putcnt, getcnt;
 
int putcnt, getcnt;
Line 172: Line 171:
 
//read bytes back out of ring buffer
 
//read bytes back out of ring buffer
 
getcnt=rngBufGet(rid, blahdst, sizeof(blahdst));
 
getcnt=rngBufGet(rid, blahdst, sizeof(blahdst));
printf(&quot;put %d bytes into buffer, read %d bytes out: %s\n&quot;,putcnt,getcnt,blahdst);
+
printf("put %d bytes into buffer, read %d bytes out: %s\n",putcnt,getcnt,blahdst);
&lt;/source&gt;
+
</source>
 
ring buffers are very useful. ^^
 
ring buffers are very useful. ^^
  

Revision as of 11:45, 26 November 2010

rngLib - an implementation of vxWorks style ring buffers

Contents

What is this?

Ring buffers work like any first in first out buffers (FIFOs), except are implemented in software. They may be used to store data such as catching keypresses, serial or other data while the system is busy which may then be read out later in the exact order it was received into the buffer. They are interrupt, thread, and interprocessor safe meaning they are perfect for transfer of data between arm7 and arm9. So long as data is read out before the buffer 'fills' no data loss should result. In this way ring buffers are perfect for storing data of various lengths that is received faster than may be immediately processed.

The functions here are pretty self explanatory. thdslib provides for byte and/or 32bit word sized ring buffers. These may be used in conjunction with the FIFO or anyplace you need more code.

rngLib is based on the VxWorks implementation of the same name and are intended to be compatible. For further information beyond what is provided here see the vxWorks reference page linked above.

The functions may just as easily be used on any system as well as the NDS, with only slight modifications (mostly change the bool data type to what the system expects).

Where to get it

Currently the sources for this are part of LibThds. The source can be downloaded via SVN (see libthds page) or directly from the svn httpd:

32bit buffer versions:

An example of rng32Lib usage that caches keypresses during vblank handler may be found here:

Functions

The function descriptions here are given using the character/8bit versions of the functions. For the 32 bit version, please note that function names and data type names are the same, except where indicated, and prefixed with either 'rng32' for functions, 'RNG32' for macros, and 'RING32_ID' for data types. They function in an identical manner except for using unsigned long int (u32) instead of char (u8) for data.

rngCreate
Creates a new ring buffer instance

  • nbytes - number to bytes (or 32 bit words for thFifo32) to be allocated for this buffer. Directly represents how much data the buffer can hold.
RING_ID rngCreate(int nbytes);

rngDelete
Deletes a ring buffer instance

  • ringId - object of type RING_ID to be destroyed
void rngDelete(RING_ID ringId);

rngFlush
Removes all content from ring buffer.

  • ringId - object of type RING_ID
void rngFlush(RING_ID ringId);  //empty all buffer content,

rngBufGet
Retrieves data, if available, from ring buffer.

  • ringId - object of type RING_ID
  • buffer - point to buffer to contain data
  • maxbytes - maximum number of bytes to be read
int rngBufGet(RING_ID rngId, char *buffer, int maxbytes);  //get number of chars, retuns nbytes gotten

rngBufPut

  • ringId - object of type RING_ID
  • buffer - pointer to buffer containing data to be placed into buffer
  • nbytes - number of bytes to place into buffer, usually the length of buffer.

Returns the number of bytes actually written to the buffer. If buffer is full will return 0.

int rngBufPut(RING_ID rngId, char *buffer, int nbytes); //write a number of chars, returns nbytes put

rngIsEmpty
Test if ring buffer contains data

  • ringId - object of type RING_ID

Returns true if ring buffer is empty, otherwise false.

bool rngIsEmpty(RING_ID ringId); //tst if buffer is empty

rngCreate
Test if ring buffer is at maximum capacity

  • ringId - object of type RING_ID

Returns true if buffer is full, otherwise false

bool rngIsFull(RING_ID ringId);  //tst if full

rngFreeBytes/rng32FreeWords

  • ringId - object of type RING_ID

Returns an integer indicating the maximum number of bytes (or 32 bit words for thFifo32) that may be placed in buffer before it is full.

int rngFreeBytes(RING_ID ringId); //how many free bytes remain?

32bit version

int rng32FreeWords(RING_ID ringId); //how many free bytes remain?

rngNBytes/rng32NWords
Number of bytes bytes (or 32 bit words for thFifo32) that may be gotten from the ring buffer

  • ringId - object of type RING_ID

Returns number of bytes (or 32 bit words for thFifo32) that may be retrieved from buffer

int rngNBytes(RING_ID ringId);

32bit version

int rngNWords(RING_ID ringId);

rngPutAhead
Put a single byte into ring buffer without incrementing count. rngFreeBytes, rngIsFull, or rngIsEmpty should probably be used for most cases to first determine that placing a character into the buffer will not result in overflow.

  • ringId - object of type RING_ID
  • byte - single character (or 32bit word for thFifo32) to be placed into buffer
  • offset - where to store the data, 0 would be at first, 1 would be the character after 0, 2 would be two characters ahead, etc etc
void rngPutAhead(RING_ID ringId, char byte, int offset); //put byte in the read buffer without incrementing counter

rngMoveAhead
Used in conjunction with (usually after) rngPutAhead, will increment the number of characters (or 32bit words for thFifo32) specified.

  • ringId - object of type RING_ID
  • n - number of bytes (or 32bit words for thFifo32) to increment fifo counter. Usually the number of bytes placed into the buffer using rngMoveAhead.
void rngMoveAhead(RING_ID ringId, int n); //move inbuffer ahead n # of bytes (used after a PutAhead)

Macros

RNG_ELEM_PUT
Puts a single character (or 32bit word for thFifo32) into the ring buffer and increments the element count, faster than rngPutBytes and should be used when single character or word is to be placed into buffer.

  • r - object of type RING_ID
  • c - character to be placed into the ring buffer
  • t - an integer to be used internally by the macro for calculations

returns 1 if successfull, otherwise 0

// returns 1 if success 0 if not
#define RNG_ELEM_PUT(r, c, t)

For example:

register int myregint;
RNG_ELEM_PUT(myringid, 'c', myregint);
//Is equivalent to:
ringPutBytes(myringid, "c", 1);

RNG_ELEM_GET
Gets a single character (or 32bit word for thFifo32) from the ring buffer and decrements the element count, faster than rngGetBytes and should be used when single character or word is to be retrieved into buffer.

  • r - object of type RING_ID
  • c - character to be placed into the ring buffer
  • t - an integer to be used internally by the macro for calculations

returns 1 if successfull, otherwise 0

#define RNG_ELEM_GET(r,p,f)

For example:

register int myregint;
char blah[]="c";
RNG_ELEM_GET(myringid, blah, myregint);
//Is equivalent to:
char blah[]="c";
ringPutBytes(myringid, blah, 1);

Examples

Write the string into buffer and read it back out again.

char blahsrc[]="this is blah";
char blahdst[0x20];
int putcnt, getcnt;
 
//create 32 byte long rng buffer
RING_ID rid=rngCreate(0x20);
//write bytes into ring buffer
putcnt=rngBufPut(rid, blahsrc, strlen(blahsrc)+1);
//read bytes back out of ring buffer
getcnt=rngBufGet(rid, blahdst, sizeof(blahdst));
printf("put %d bytes into buffer, read %d bytes out: %s\n",putcnt,getcnt,blahdst);

ring buffers are very useful. ^^

Personal tools
irssi scripts
eggdrop scripts