Просмотр исходного кода

some text fomarting, update unit test to test get buffer info for fifo

hathach 4 лет назад
Родитель
Сommit
18c35bb89e
3 измененных файлов с 193 добавлено и 70 удалено
  1. 22 20
      src/common/tusb_fifo.c
  2. 21 24
      src/common/tusb_fifo.h
  3. 150 26
      test/test/test_fifo.c

+ 22 - 20
src/common/tusb_fifo.c

@@ -57,7 +57,8 @@ static inline void _ff_unlock(tu_fifo_mutex_t mutex)
 #endif
 
 /** \enum tu_fifo_copy_mode_t
- * \brief Write modes intended to allow special read and write functions to be able to copy data to and from USB hardware FIFOs as needed for e.g. STM32s and others
+ * \brief Write modes intended to allow special read and write functions to be able to
+ *        copy data to and from USB hardware FIFOs as needed for e.g. STM32s and others
  */
 typedef enum
 {
@@ -77,7 +78,10 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si
   f->item_size = item_size;
   f->overwritable = overwritable;
 
-  f->max_pointer_idx = 2*depth - 1;               // Limit index space to 2*depth - this allows for a fast "modulo" calculation but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable only if overflow happens once (important for unsupervised DMA applications)
+  // Limit index space to 2*depth - this allows for a fast "modulo" calculation
+  // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable
+  // only if overflow happens once (important for unsupervised DMA applications)
+  f->max_pointer_idx = 2*depth - 1;
   f->non_used_index_space = UINT16_MAX - f->max_pointer_idx;
 
   f->rd_idx = f->wr_idx = 0;
@@ -319,7 +323,8 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu
 static uint16_t advance_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset)
 {
   // We limit the index space of p such that a correct wrap around happens
-  // Check for a wrap around or if we are in unused index space - This has to be checked first!! We are exploiting the wrap around to the correct index
+  // Check for a wrap around or if we are in unused index space - This has to be checked first!!
+  // We are exploiting the wrap around to the correct index
   if ((p > p + offset) || (p + offset > f->max_pointer_idx))
   {
     p = (p + offset) + f->non_used_index_space;
@@ -335,7 +340,8 @@ static uint16_t advance_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset)
 static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset)
 {
   // We limit the index space of p such that a correct wrap around happens
-  // Check for a wrap around or if we are in unused index space - This has to be checked first!! We are exploiting the wrap around to the correct index
+  // Check for a wrap around or if we are in unused index space - This has to be checked first!!
+  // We are exploiting the wrap around to the correct index
   if ((p < p - offset) || (p - offset > f->max_pointer_idx))
   {
     p = (p - offset) - f->non_used_index_space;
@@ -496,7 +502,8 @@ static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo
   _ff_lock(f->mutex_rd);
 
   // Peek the data
-  n = _tu_fifo_peek_n(f, buffer, n, f->wr_idx, f->rd_idx, copy_mode);        // f->rd_idx might get modified in case of an overflow so we can not use a local variable
+  // f->rd_idx might get modified in case of an overflow so we can not use a local variable
+  n = _tu_fifo_peek_n(f, buffer, n, f->wr_idx, f->rd_idx, copy_mode);
 
   // Advance read pointer
   f->rd_idx = advance_pointer(f, f->rd_idx, n);
@@ -634,7 +641,8 @@ bool tu_fifo_read(tu_fifo_t* f, void * buffer)
   _ff_lock(f->mutex_rd);
 
   // Peek the data
-  bool ret = _tu_fifo_peek(f, buffer, f->wr_idx, f->rd_idx);    // f->rd_idx might get modified in case of an overflow so we can not use a local variable
+  // f->rd_idx might get modified in case of an overflow so we can not use a local variable
+  bool ret = _tu_fifo_peek(f, buffer, f->wr_idx, f->rd_idx);
 
   // Advance pointer
   f->rd_idx = advance_pointer(f, f->rd_idx, ret);
@@ -910,12 +918,12 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
     cnt = f->depth;
   }
 
-  // Skip beginning of buffer
+  // Check if fifo is empty
   if (cnt == 0)
   {
-    info->len_lin = 0;
+    info->len_lin  = 0;
     info->len_wrap = 0;
-    info->ptr_lin = NULL;
+    info->ptr_lin  = NULL;
     info->ptr_wrap = NULL;
     return;
   }
@@ -930,18 +938,16 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
   // Check if there is a wrap around necessary
   if (w > r) {
     // Non wrapping case
-    info->len_lin = cnt;
+    info->len_lin  = cnt;
     info->len_wrap = 0;
     info->ptr_wrap = NULL;
   }
   else
   {
-    info->len_lin = f->depth - r;                 // Also the case if FIFO was full
+    info->len_lin  = f->depth - r;         // Also the case if FIFO was full
     info->len_wrap = cnt - info->len_lin;
     info->ptr_wrap = f->buffer;
   }
-
-  return;
 }
 
 /******************************************************************************/
@@ -957,8 +963,6 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
                     Pointer to FIFO
    @param[out]      *info
                     Pointer to struct which holds the desired infos
-   @param[in]       n
-                    Number of ITEMS to write into buffer
  */
 /******************************************************************************/
 void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
@@ -985,16 +989,14 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
   if (w < r)
   {
     // Non wrapping case
-    info->len_lin = r-w;                                    // Limit to required length
+    info->len_lin = r-w;
     info->len_wrap = 0;
     info->ptr_wrap = NULL;
   }
   else
   {
     info->len_lin = f->depth - w;
-    info->len_wrap = free - info->len_lin;                  // Remaining length - n already was limited to free or FIFO depth
-    info->ptr_wrap = f->buffer;                             // Always start of buffer
+    info->len_wrap = free - info->len_lin; // Remaining length - n already was limited to free or FIFO depth
+    info->ptr_wrap = f->buffer;            // Always start of buffer
   }
-
-  return;
 }

+ 21 - 24
src/common/tusb_fifo.h

@@ -25,10 +25,6 @@
  * This file is part of the TinyUSB stack.
  */
 
-/** \ingroup Group_Common
- * \defgroup group_fifo fifo
- *  @{ */
-
 #ifndef _TUSB_FIFO_H_
 #define _TUSB_FIFO_H_
 
@@ -62,16 +58,16 @@ extern "C" {
  */
 typedef struct
 {
-  uint8_t* buffer                        ; ///< buffer pointer
-  uint16_t depth                         ; ///< max items
-  uint16_t item_size                     ; ///< size of each item
-  bool overwritable                      ;
+  uint8_t* buffer               ; ///< buffer pointer
+  uint16_t depth                ; ///< max items
+  uint16_t item_size            ; ///< size of each item
+  bool overwritable             ;
 
-  uint16_t non_used_index_space          ; ///< required for non-power-of-two buffer length
-  uint16_t max_pointer_idx               ; ///< maximum absolute pointer index
+  uint16_t non_used_index_space ; ///< required for non-power-of-two buffer length
+  uint16_t max_pointer_idx      ; ///< maximum absolute pointer index
 
-  volatile uint16_t wr_idx               ; ///< write pointer
-  volatile uint16_t rd_idx               ; ///< read pointer
+  volatile uint16_t wr_idx      ; ///< write pointer
+  volatile uint16_t rd_idx      ; ///< read pointer
 
 #if CFG_FIFO_MUTEX
   tu_fifo_mutex_t mutex_wr;
@@ -82,10 +78,10 @@ typedef struct
 
 typedef struct
 {
-  uint16_t len_lin                      ; ///< linear length in item size
-  uint16_t len_wrap                     ; ///< wrapped length in item size
-  void * ptr_lin                        ; ///< linear part start pointer
-  void * ptr_wrap                       ; ///< wrapped part start pointer
+  uint16_t len_lin  ; ///< linear length in item size
+  uint16_t len_wrap ; ///< wrapped length in item size
+  void * ptr_lin    ; ///< linear part start pointer
+  void * ptr_wrap   ; ///< wrapped part start pointer
 } tu_fifo_buffer_info_t;
 
 #define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \
@@ -133,21 +129,22 @@ uint16_t tu_fifo_remaining              (tu_fifo_t* f);
 bool     tu_fifo_overflowed             (tu_fifo_t* f);
 void     tu_fifo_correct_read_pointer   (tu_fifo_t* f);
 
+static inline uint16_t tu_fifo_depth(tu_fifo_t* f)
+{
+  return f->depth;
+}
+
 // Pointer modifications intended to be used in combinations with DMAs.
 // USE WITH CARE - NO SAFTY CHECKS CONDUCTED HERE! NOT MUTEX PROTECTED!
 void     tu_fifo_advance_write_pointer  (tu_fifo_t *f, uint16_t n);
 void     tu_fifo_advance_read_pointer   (tu_fifo_t *f, uint16_t n);
 
-// If you want to read/write from/to the FIFO by use of a DMA, you may need to conduct two copies to handle a possible wrapping part
-// This functions deliver a pointer to start reading/writing from/to and a valid linear length along which no wrap occurs.
-
-void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
+// If you want to read/write from/to the FIFO by use of a DMA, you may need to conduct two copies
+// to handle a possible wrapping part. These functions deliver a pointer to start
+// reading/writing from/to and a valid linear length along which no wrap occurs.
+void tu_fifo_get_read_info (tu_fifo_t *f, tu_fifo_buffer_info_t *info);
 void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
 
-static inline uint16_t tu_fifo_depth(tu_fifo_t* f)
-{
-  return f->depth;
-}
 
 #ifdef __cplusplus
 }

+ 150 - 26
test/test/test_fifo.c

@@ -24,15 +24,19 @@
  * This file is part of the TinyUSB stack.
  */
 
+#include <string.h>
 #include "unity.h"
 #include "tusb_fifo.h"
 
 #define FIFO_SIZE 10
-TU_FIFO_DEF(ff, FIFO_SIZE, uint8_t, false);
+TU_FIFO_DEF(tu_ff, FIFO_SIZE, uint8_t, false);
+tu_fifo_t* ff = &tu_ff;
+tu_fifo_buffer_info_t info;
 
 void setUp(void)
 {
-  tu_fifo_clear(&ff);
+  tu_fifo_clear(ff);
+  memset(&info, 0, sizeof(tu_fifo_buffer_info_t));
 }
 
 void tearDown(void)
@@ -44,12 +48,12 @@ void tearDown(void)
 //--------------------------------------------------------------------+
 void test_normal(void)
 {
-  for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(&ff, &i);
+  for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, &i);
 
   for(uint8_t i=0; i < FIFO_SIZE; i++)
   {
     uint8_t c;
-    tu_fifo_read(&ff, &c);
+    tu_fifo_read(ff, &c);
     TEST_ASSERT_EQUAL(i, c);
   }
 }
@@ -86,30 +90,30 @@ void test_read_n(void)
   uint8_t data[20];
   for(int i=0; i<sizeof(data); i++) data[i] = i;
 
-  for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(&ff, data+i);
+  for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, data+i);
 
   uint8_t rd[10];
   uint16_t rd_count;
 
   // case 1: Read index + count < depth
   // read 0 -> 4
-  rd_count = tu_fifo_read_n(&ff, rd, 5);
+  rd_count = tu_fifo_read_n(ff, rd, 5);
   TEST_ASSERT_EQUAL( 5, rd_count );
   TEST_ASSERT_EQUAL_MEMORY( data, rd, rd_count ); // 0 -> 4
 
   // case 2: Read index + count > depth
   // write 10, 11, 12
-  tu_fifo_write(&ff, data+10);
-  tu_fifo_write(&ff, data+11);
-  tu_fifo_write(&ff, data+12);
+  tu_fifo_write(ff, data+10);
+  tu_fifo_write(ff, data+11);
+  tu_fifo_write(ff, data+12);
 
-  rd_count = tu_fifo_read_n(&ff, rd, 7);
+  rd_count = tu_fifo_read_n(ff, rd, 7);
   TEST_ASSERT_EQUAL( 7, rd_count );
 
   TEST_ASSERT_EQUAL_MEMORY( data+5, rd, rd_count ); // 5 -> 11
 
   // Should only read until empty
-  TEST_ASSERT_EQUAL( 1, tu_fifo_read_n(&ff, rd, 100) );
+  TEST_ASSERT_EQUAL( 1, tu_fifo_read_n(ff, rd, 100) );
 }
 
 void test_write_n(void)
@@ -119,52 +123,172 @@ void test_write_n(void)
   for(int i=0; i<sizeof(data); i++) data[i] = i;
 
   // case 1: wr + count < depth
-  tu_fifo_write_n(&ff, data, 8); // wr = 8, count = 8
+  tu_fifo_write_n(ff, data, 8); // wr = 8, count = 8
 
   uint8_t rd[10];
   uint16_t rd_count;
 
-  rd_count = tu_fifo_read_n(&ff, rd, 5); // wr = 8, count = 3
+  rd_count = tu_fifo_read_n(ff, rd, 5); // wr = 8, count = 3
   TEST_ASSERT_EQUAL( 5, rd_count );
   TEST_ASSERT_EQUAL_MEMORY( data, rd, rd_count ); // 0 -> 4
 
   // case 2: wr + count > depth
-  tu_fifo_write_n(&ff, data+8, 6); // wr = 3, count = 9
+  tu_fifo_write_n(ff, data+8, 6); // wr = 3, count = 9
 
-  for(rd_count=0; rd_count<7; rd_count++) tu_fifo_read(&ff, rd+rd_count); // wr = 3, count = 2
+  for(rd_count=0; rd_count<7; rd_count++) tu_fifo_read(ff, rd+rd_count); // wr = 3, count = 2
 
   TEST_ASSERT_EQUAL_MEMORY( data+5, rd, rd_count); // 5 -> 11
 
-  TEST_ASSERT_EQUAL(2, tu_fifo_count(&ff));
+  TEST_ASSERT_EQUAL(2, tu_fifo_count(ff));
 }
 
 void test_peek(void)
 {
   uint8_t temp;
 
-  temp = 10; tu_fifo_write(&ff, &temp);
-  temp = 20; tu_fifo_write(&ff, &temp);
-  temp = 30; tu_fifo_write(&ff, &temp);
+  temp = 10; tu_fifo_write(ff, &temp);
+  temp = 20; tu_fifo_write(ff, &temp);
+  temp = 30; tu_fifo_write(ff, &temp);
 
   temp = 0;
 
-  tu_fifo_peek(&ff, &temp);
+  tu_fifo_peek(ff, &temp);
   TEST_ASSERT_EQUAL(10, temp);
+
+  tu_fifo_read(ff, &temp);
+  tu_fifo_read(ff, &temp);
+
+  tu_fifo_peek(ff, &temp);
+  TEST_ASSERT_EQUAL(30, temp);
+}
+
+void test_get_read_info_when_no_wrap()
+{
+  uint8_t ch = 1;
+
+  // write 6 items
+  for(uint8_t i=0; i < 6; i++) tu_fifo_write(ff, &ch);
+
+  // read 2 items
+  tu_fifo_read(ff, &ch);
+  tu_fifo_read(ff, &ch);
+
+  tu_fifo_get_read_info(ff, &info);
+
+  TEST_ASSERT_EQUAL(4, info.len_lin);
+  TEST_ASSERT_EQUAL(0, info.len_wrap);
+
+  TEST_ASSERT_EQUAL_PTR(ff->buffer+2, info.ptr_lin);
+  TEST_ASSERT_NULL(info.ptr_wrap);
+}
+
+void test_get_read_info_when_wrapped()
+{
+  uint8_t ch = 1;
+
+  // make fifo full
+  for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, &ch);
+
+  // read 6 items
+  for(uint8_t i=0; i < 6; i++) tu_fifo_read(ff, &ch);
+
+  // write 2 items
+  tu_fifo_write(ff, &ch);
+  tu_fifo_write(ff, &ch);
+
+  tu_fifo_get_read_info(ff, &info);
+
+  TEST_ASSERT_EQUAL(FIFO_SIZE-6, info.len_lin);
+  TEST_ASSERT_EQUAL(2, info.len_wrap);
+
+  TEST_ASSERT_EQUAL_PTR(ff->buffer+6, info.ptr_lin);
+  TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap);
+}
+
+void test_get_write_info_when_no_wrap()
+{
+  uint8_t ch = 1;
+
+  // write 2 items
+  tu_fifo_write(ff, &ch);
+  tu_fifo_write(ff, &ch);
+
+  tu_fifo_get_write_info(ff, &info);
+
+  TEST_ASSERT_EQUAL(FIFO_SIZE-2, info.len_lin);
+  TEST_ASSERT_EQUAL(0, info.len_wrap);
+
+  TEST_ASSERT_EQUAL_PTR(ff->buffer+2, info .ptr_lin);
+  // application should check len instead of ptr.
+  // TEST_ASSERT_NULL(info.ptr_wrap);
+}
+
+void test_get_write_info_when_wrapped()
+{
+  uint8_t ch = 1;
+
+  // write 6 items
+  for(uint8_t i=0; i < 6; i++) tu_fifo_write(ff, &ch);
+
+  // read 2 items
+  tu_fifo_read(ff, &ch);
+  tu_fifo_read(ff, &ch);
+
+  tu_fifo_get_write_info(ff, &info);
+
+  TEST_ASSERT_EQUAL(FIFO_SIZE-6, info.len_lin);
+  TEST_ASSERT_EQUAL(2, info.len_wrap);
+
+  TEST_ASSERT_EQUAL_PTR(ff->buffer+6, info .ptr_lin);
+  TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap);
 }
 
 void test_empty(void)
 {
   uint8_t temp;
-  TEST_ASSERT_TRUE(tu_fifo_empty(&ff));
-  tu_fifo_write(&ff, &temp);
-  TEST_ASSERT_FALSE(tu_fifo_empty(&ff));
+  TEST_ASSERT_TRUE(tu_fifo_empty(ff));
+
+  // read info
+  tu_fifo_get_read_info(ff, &info);
+
+  TEST_ASSERT_EQUAL(0, info.len_lin);
+  TEST_ASSERT_EQUAL(0, info.len_wrap);
+
+  TEST_ASSERT_NULL(info.ptr_lin);
+  TEST_ASSERT_NULL(info.ptr_wrap);
+
+  // write info
+  tu_fifo_get_write_info(ff, &info);
+
+  TEST_ASSERT_EQUAL(FIFO_SIZE, info.len_lin);
+  TEST_ASSERT_EQUAL(0, info.len_wrap);
+
+  TEST_ASSERT_EQUAL_PTR(ff->buffer, info .ptr_lin);
+  // application should check len instead of ptr.
+  // TEST_ASSERT_NULL(info.ptr_wrap);
+
+  // write 1 then re-check empty
+  tu_fifo_write(ff, &temp);
+  TEST_ASSERT_FALSE(tu_fifo_empty(ff));
 }
 
 void test_full(void)
 {
-  TEST_ASSERT_FALSE(tu_fifo_full(&ff));
+  TEST_ASSERT_FALSE(tu_fifo_full(ff));
+
+  for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, &i);
+
+  TEST_ASSERT_TRUE(tu_fifo_full(ff));
+
+  // read info
+  tu_fifo_get_read_info(ff, &info);
+
+  TEST_ASSERT_EQUAL(FIFO_SIZE, info.len_lin);
+  TEST_ASSERT_EQUAL(0, info.len_wrap);
 
-  for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(&ff, &i);
+  TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_lin);
+  // skip this, application must check len instead of buffer
+  // TEST_ASSERT_NULL(info.ptr_wrap);
 
-  TEST_ASSERT_TRUE(tu_fifo_full(&ff));
+  // write info
 }