From 7084b9f03676c8bf0bc1369aac5661bf34986032 Mon Sep 17 00:00:00 2001 From: skarg Date: Fri, 22 Feb 2013 16:19:42 +0000 Subject: [PATCH] Added Javadoc to fifo module and header file. --- bacnet-stack/include/fifo.h | 90 ++++---- bacnet-stack/src/fifo.c | 394 ++++++++++++++++++++++-------------- 2 files changed, 274 insertions(+), 210 deletions(-) diff --git a/bacnet-stack/include/fifo.h b/bacnet-stack/include/fifo.h index 4cbdc916..0df5f7ac 100755 --- a/bacnet-stack/include/fifo.h +++ b/bacnet-stack/include/fifo.h @@ -1,92 +1,72 @@ -/************************************************************************** -* -* Copyright (C) 2012 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*********************************************************************/ +/** +* @file +* @author Steve Karg +* @date 2004 +*/ #ifndef FIFO_H #define FIFO_H -/* Functional Description: Generic FIFO library for deeply - embedded system. See the unit tests for usage examples. - This library only uses a byte sized chunk. - This library is designed for use in Interrupt Service Routines - and so is declared as "static inline" */ - #include #include +/** +* FIFO data structure +* +* @{ +*/ struct fifo_buffer_t { - volatile unsigned head; /* first byte of data */ - volatile unsigned tail; /* last byte of data */ - volatile uint8_t *buffer; /* block of memory or array of data */ - unsigned buffer_len; /* length of the data */ + /** first byte of data */ + volatile unsigned head; + /** last byte of data */ + volatile unsigned tail; + /** block of memory or array of data */ + volatile uint8_t *buffer; + /** length of the data */ + unsigned buffer_len; }; typedef struct fifo_buffer_t FIFO_BUFFER; +/** @} */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - unsigned FIFO_Count( - FIFO_BUFFER const *b); + unsigned FIFO_Count(FIFO_BUFFER const *b); - bool FIFO_Full( - FIFO_BUFFER const *b); + bool FIFO_Full(FIFO_BUFFER const *b); - bool FIFO_Available( - FIFO_BUFFER const *b, + bool FIFO_Available(FIFO_BUFFER const *b, unsigned count); - bool FIFO_Empty( - FIFO_BUFFER const *b); + bool FIFO_Empty(FIFO_BUFFER const *b); - uint8_t FIFO_Peek( - FIFO_BUFFER const *b); + uint8_t FIFO_Peek(FIFO_BUFFER const *b); - uint8_t FIFO_Get( - FIFO_BUFFER * b); + uint8_t FIFO_Get(FIFO_BUFFER * b); - unsigned FIFO_Pull( - FIFO_BUFFER * b, + unsigned FIFO_Pull(FIFO_BUFFER * b, uint8_t * data_bytes, unsigned length); - bool FIFO_Put( - FIFO_BUFFER * b, + bool FIFO_Put(FIFO_BUFFER * b, uint8_t data_byte); - bool FIFO_Add( - FIFO_BUFFER * b, + bool FIFO_Add(FIFO_BUFFER * b, uint8_t * data_bytes, unsigned count); - void FIFO_Flush( - FIFO_BUFFER * b); + void FIFO_Flush(FIFO_BUFFER * b); /* note: buffer_len must be a power of two */ - void FIFO_Init( - FIFO_BUFFER * b, + void FIFO_Init(FIFO_BUFFER * b, volatile uint8_t * buffer, unsigned buffer_len); +#ifdef TEST +#include "ctest.h" + void testFIFOBuffer(Test * pTest); +#endif + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bacnet-stack/src/fifo.c b/bacnet-stack/src/fifo.c index 877a7c21..6c9d2707 100755 --- a/bacnet-stack/src/fifo.c +++ b/bacnet-stack/src/fifo.c @@ -1,56 +1,107 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 by Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -/** @file fifo.c Generic FIFO library for deeply embedded system */ - -/* Functional Description: Generic FIFO library for deeply - embedded system. See the unit tests for usage examples. */ - +/** +* @file +* @author Steve Karg +* @date 2004 +* @brief Generic interrupt safe FIFO library for deeply embedded system. +* +* @section LICENSE +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to: +* The Free Software Foundation, Inc. +* 59 Temple Place - Suite 330 +* Boston, MA 02111-1307 +* USA. +* +* As a special exception, if other files instantiate templates or +* use macros or inline functions from this file, or you compile +* this file and link it with other works to produce a work based +* on this file, this file does not by itself cause the resulting +* work to be covered by the GNU General Public License. However +* the source code for this file must still be made available in +* accordance with section (3) of the GNU General Public License. +* +* This exception does not invalidate any other reasons why a work +* based on this file might be covered by the GNU General Public +* License. +* +* @section DESCRIPTION +* +* Generic interrupt safe FIFO library for deeply embedded system +* This library only uses a byte sized chunk for a data element. +* It uses a data store whose size is a power of 2 (8, 16, 32, 64, ...) +* and doesn't waste any data bytes. It has very low overhead, and +* utilizes modulo for indexing the data in the data store. +* +* To use this library, first declare a data store, sized for a power of 2: +* {@code +* static volatile uint8_t data_store[64]; +* } +* +* Then declare the FIFO tracking structure: +* {@code +* static FIFO_BUFFER queue; +* } +* +* Initialize the queue with the data store: +* {@code +* FIFO_Init(&queue, data_store, sizeof(data_store)); +* } +* +* Then begin to use the FIFO queue by giving it data, retreiving data, +* and checking the FIFO queue to see if it is empty or full: +* {@code +* uint8_t in_data = 0; +* uint8_t out_data = 0; +* uint8_t add_data[5] = {0}; +* uint8_t pull_data[5] = {0}; +* unsigned count = 0; +* bool status = false; +* +* status = FIFO_Put(&queue, in_data); +* if (!FIFO_Empty(&queue)) { +* out_data = FIFO_Get(&queue); +* } +* if (FIFO_Available(&queue, sizeof(add_data))) { +* status = FIFO_Add(&queue, add_data, sizeof(add_data)); +* } +* count = FIFO_Count(&queue); +* if (count == sizeof(add_data)) { +* count = FIFO_Pull(&queue, &pull_data[0], sizeof(pull_data)); +* } +* +* } +* +* Normally the FIFO is used by a producer, such as in interrupt service +* routine, which places data into the queue using FIFO_Put(), and a consumer, +* such as a main loop handler, which pulls data from the queue by first +* checking the queue for data using FIFO_Empty(), and then pulling data from +* the queue using FIFO_Get(). +* +*/ #include #include #include #include "fifo.h" -/**************************************************************************** -* DESCRIPTION: Returns the number of elements in the ring buffer -* RETURN: Number of elements in the ring buffer -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -unsigned FIFO_Count( - FIFO_BUFFER const *b) +/** +* Returns the number of bytes in the FIFO +* +* @param b - pointer to FIFO_BUFFER structure +* +* @return Number of bytes in the FIFO +*/ +unsigned FIFO_Count(FIFO_BUFFER const *b) { unsigned head, tail; /* used to avoid volatile decision */ @@ -63,91 +114,106 @@ unsigned FIFO_Count( } } -/**************************************************************************** -* DESCRIPTION: Returns the empty/full status of the ring buffer -* RETURN: true if the ring buffer is full, false if it is not. -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool FIFO_Full( - FIFO_BUFFER const *b) +/** +* Returns the full status of the FIFO +* +* @param b - pointer to FIFO_BUFFER structure +* +* @return true if the FIFO is full, false if it is not. +*/ +bool FIFO_Full(FIFO_BUFFER const *b) { return (b ? (FIFO_Count(b) == b->buffer_len) : true); } -/**************************************************************************** -* DESCRIPTION: Tests to see if space is available -* RETURN: true if the number of bytes is available -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool FIFO_Available( - FIFO_BUFFER const *b, +/** +* Tests to see if space is available in the FIFO +* +* @param b - pointer to FIFO_BUFFER structure +* @param count [in] - number of bytes tested for availability +* +* @return true if the number of bytes sought is available +*/ +bool FIFO_Available(FIFO_BUFFER const *b, unsigned count) { return (b ? (count <= (b->buffer_len - FIFO_Count(b))) : false); } -/**************************************************************************** -* DESCRIPTION: Returns the empty/full status of the ring buffer -* RETURN: true if the ring buffer is empty, false if it is not. -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool FIFO_Empty( - FIFO_BUFFER const *b) +/** +* Returns the empty status of the FIFO +* +* @param b - pointer to FIFO_BUFFER structure +* @return true if the FIFO is empty, false if it is not. +*/ +bool FIFO_Empty(FIFO_BUFFER const *b) { return (b ? (FIFO_Count(b) == 0) : true); } -/**************************************************************************** -* DESCRIPTION: Looks at the data from the head of the list without removing it -* RETURN: byte of data, or zero if nothing in the list -* ALGORITHM: none -* NOTES: Use Empty function to see if there is data to retrieve -*****************************************************************************/ -uint8_t FIFO_Peek( - FIFO_BUFFER const *b) +/** +* Peeks at the data from the front of the FIFO without removing it. +* Use FIFO_Empty() or FIFO_Available() function to see if there is +* data to retrieve since this function doesn't return a flag indicating +* success or failure. +* +* @param b - pointer to FIFO_BUFFER structure +* +* @return byte of data, or zero if nothing in the list +*/ +uint8_t FIFO_Peek(FIFO_BUFFER const *b) { + unsigned index; + if (b) { - return (b->buffer[b->tail % b->buffer_len]); + index = b->tail % b->buffer_len; + return (b->buffer[index]); } return 0; } -/**************************************************************************** -* DESCRIPTION: Gets the data from the front of the list, and removes it -* RETURN: the data, or zero if nothing in the list -* ALGORITHM: none -* NOTES: Use Empty function to see if there is data to retrieve -*****************************************************************************/ -uint8_t FIFO_Get( - FIFO_BUFFER * b) +/** +* Gets a byte from the front of the FIFO, and removes it. +* Use FIFO_Empty() or FIFO_Available() function to see if there is +* data to retrieve since this function doesn't return a flag indicating +* success or failure. +* +* @param b - pointer to FIFO_BUFFER structure +* +* @return the data +*/ +uint8_t FIFO_Get(FIFO_BUFFER * b) { uint8_t data_byte = 0; + unsigned index; if (!FIFO_Empty(b)) { - data_byte = b->buffer[b->tail % b->buffer_len]; + index = b->tail % b->buffer_len; + data_byte = b->buffer[index]; b->tail++; } return data_byte; } -/**************************************************************************** -* DESCRIPTION: Pulls the data from the front of the list, and removes it -* RETURN: the data (in parameter) and the number of bytes pulled -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -unsigned FIFO_Pull( - FIFO_BUFFER * b, - uint8_t * data_bytes, +/** +* Pulls one or more bytes from the front of the FIFO, and removes them +* from the FIFO. If less bytes are available, only the available bytes +* are retrieved. +* +* @param b - pointer to FIFO_BUFFER structure +* @param buffer [out] - buffer to hold the pulled bytes +* @param length [in] - number of bytes to pull from the FIFO +* +* @return the number of bytes actually pulled from the FIFO +*/ +unsigned FIFO_Pull(FIFO_BUFFER * b, + uint8_t * buffer, unsigned length) { unsigned count; uint8_t data_byte; - + unsigned index; count = FIFO_Count(b); if (count > length) { @@ -159,32 +225,38 @@ unsigned FIFO_Pull( length = count; } while (count) { - data_byte = b->buffer[b->tail % b->buffer_len]; + index = b->tail % b->buffer_len; + data_byte = b->buffer[index]; b->tail++; - *data_bytes = data_byte; - data_bytes++; + if (buffer) { + *buffer = data_byte; + buffer++; + } count--; } return length; } -/**************************************************************************** -* DESCRIPTION: Adds an element of data to the FIFO -* RETURN: true on successful add, false if not added -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool FIFO_Put( - FIFO_BUFFER * b, +/** +* Adds a byte of data to the FIFO +* +* @param b - pointer to FIFO_BUFFER structure +* @param data_byte [in] - data to put into the FIFO +* +* @return true on successful add, false if not added +*/ +bool FIFO_Put(FIFO_BUFFER * b, uint8_t data_byte) { bool status = false; /* return value */ + unsigned index; if (b) { - /* limit the ring to prevent overwriting */ + /* limit the buffer to prevent overwriting */ if (!FIFO_Full(b)) { - b->buffer[b->head % b->buffer_len] = data_byte; + index = b->head % b->buffer_len; + b->buffer[index] = data_byte; b->head++; status = true; } @@ -193,25 +265,29 @@ bool FIFO_Put( return status; } -/**************************************************************************** -* DESCRIPTION: Adds one or more elements of data to the FIFO -* RETURN: true if space available and added, false if not added -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool FIFO_Add( - FIFO_BUFFER * b, - uint8_t * data_bytes, +/** +* Adds one or more bytes of data to the FIFO +* +* @param b - pointer to FIFO_BUFFER structure +* @param buffer [out] - data bytes to add to the FIFO +* @param count [in] - number of bytes to add to the FIFO +* +* @return true if space available and added, false if not added +*/ +bool FIFO_Add(FIFO_BUFFER * b, + uint8_t * buffer, unsigned count) { bool status = false; /* return value */ + unsigned index; - /* limit the ring to prevent overwriting */ - if (FIFO_Available(b, count)) { + /* limit the buffer to prevent overwriting */ + if (FIFO_Available(b, count) && buffer) { while (count) { - b->buffer[b->head % b->buffer_len] = *data_bytes; + index = b->head % b->buffer_len; + b->buffer[index] = *buffer; b->head++; - data_bytes++; + buffer++; count--; } status = true; @@ -220,14 +296,14 @@ bool FIFO_Add( return status; } -/**************************************************************************** -* DESCRIPTION: Flushes any data in the buffer -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void FIFO_Flush( - FIFO_BUFFER * b) +/** +* Flushes any data in the FIFO buffer +* +* @param b - pointer to FIFO_BUFFER structure +* +* @return none +*/ +void FIFO_Flush(FIFO_BUFFER * b) { unsigned head; /* used to avoid volatile decision */ @@ -237,18 +313,20 @@ void FIFO_Flush( } } -/**************************************************************************** -* DESCRIPTION: Configures the ring buffer -* RETURN: none -* ALGORITHM: none -* NOTES: buffer_len must be a power of two -*****************************************************************************/ -void FIFO_Init( - FIFO_BUFFER * b, +/** +* Initializes the FIFO buffer with a data store +* +* @param b - pointer to FIFO_BUFFER structure +* @param buffer [in] - data bytes used to store bytes used by the FIFO +* @param buffer_len [in] - size of the buffer in bytes - must be power of 2. +* +* @return none +*/ +void FIFO_Init(FIFO_BUFFER * b, volatile uint8_t * buffer, unsigned buffer_len) { - if (b) { + if (b && buffer && buffer_len) { b->head = 0; b->tail = 0; b->buffer = buffer; @@ -262,17 +340,19 @@ void FIFO_Init( #include #include #include - #include "ctest.h" -/* test the FIFO */ -/* note: must be a power of two! */ -#define FIFO_BUFFER_SIZE 64 -void testFIFOBuffer( - Test * pTest) +/** +* Unit Test for the FIFO buffer +* +* @param pTest - test tracking pointer +*/ +void testFIFOBuffer(Test * pTest) { + /* FIFO data structure */ FIFO_BUFFER test_buffer = { 0 }; - volatile uint8_t data_store[FIFO_BUFFER_SIZE] = { 0 }; + /* FIFO data store. Note: size must be a power of two! */ + volatile uint8_t data_store[64] = { 0 }; uint8_t add_data[40] = { "RoseSteveLouPatRachelJessicaDaniAmyHerb" }; uint8_t test_add_data[40] = { 0 }; uint8_t test_data = 0; @@ -284,7 +364,7 @@ void testFIFOBuffer( ct_test(pTest, FIFO_Empty(&test_buffer)); /* load the buffer */ - for (test_data = 0; test_data < FIFO_BUFFER_SIZE; test_data++) { + for (test_data = 0; test_data < sizeof(data_store); test_data++) { ct_test(pTest, !FIFO_Full(&test_buffer)); ct_test(pTest, FIFO_Available(&test_buffer, 1)); status = FIFO_Put(&test_buffer, test_data); @@ -297,7 +377,7 @@ void testFIFOBuffer( status = FIFO_Put(&test_buffer, 42); ct_test(pTest, status == false); /* unload the buffer */ - for (index = 0; index < FIFO_BUFFER_SIZE; index++) { + for (index = 0; index < sizeof(data_store); index++) { ct_test(pTest, !FIFO_Empty(&test_buffer)); test_data = FIFO_Peek(&test_buffer); ct_test(pTest, test_data == index); @@ -313,7 +393,7 @@ void testFIFOBuffer( ct_test(pTest, test_data == 0); ct_test(pTest, FIFO_Empty(&test_buffer)); /* test the ring around the buffer */ - for (index = 0; index < FIFO_BUFFER_SIZE; index++) { + for (index = 0; index < sizeof(data_store); index++) { ct_test(pTest, FIFO_Empty(&test_buffer)); ct_test(pTest, FIFO_Available(&test_buffer, 4)); for (count = 1; count < 4; count++) { @@ -381,8 +461,12 @@ void testFIFOBuffer( } #ifdef TEST_FIFO_BUFFER -int main( - void) +/** +* Main program entry for Unit Test +* +* @return returns 0 on success, and non-zero on fail. +*/ +int main(void) { Test *pTest; bool rc;