CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2

Dependents:   USBEthernet_TEST

Fork of USB_Ethernet by Daniele Lacamera

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pico_queue.h Source File

pico_queue.h

00001 /*********************************************************************
00002 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
00003 See LICENSE and COPYING for usage.
00004 
00005 *********************************************************************/
00006 #ifndef _INCLUDE_PICO_QUEUE
00007 #define _INCLUDE_PICO_QUEUE
00008 #include <stdint.h>
00009 #include "pico_config.h"
00010 #include "pico_frame.h"
00011 
00012 #define Q_LIMIT 0
00013 
00014 #ifndef NULL
00015 #define NULL ((void *)0)
00016 #endif
00017 
00018 struct pico_queue {
00019   uint32_t frames;
00020   uint32_t size;
00021   uint32_t max_frames;
00022   uint32_t max_size;
00023   struct pico_frame *head;
00024   struct pico_frame *tail;
00025 #ifdef PICO_SUPPORT_MUTEX
00026   void * mutex;
00027 #endif
00028   uint8_t shared;
00029 };
00030 
00031 #ifdef PICO_SUPPORT_MUTEX
00032 #define LOCK(x) {\
00033   if (x == NULL) \
00034     x = pico_mutex_init(); \
00035   pico_mutex_lock(x); \
00036 }
00037 #define UNLOCK(x) pico_mutex_unlock(x);
00038 
00039 #else 
00040 #define LOCK(x) do{}while(0)
00041 #define UNLOCK(x) do{}while(0)
00042 #endif
00043 
00044 #ifdef PICO_SUPPORT_DEBUG_TOOLS
00045 static void debug_q(struct pico_queue *q)
00046 {
00047   struct pico_frame *p = q->head;
00048   dbg("%d: ", q->frames);
00049   while(p) {
00050     dbg("(%p)-->", p);
00051     p = p->next;
00052   }
00053   dbg("X\n");
00054 }
00055 
00056 #else
00057 
00058 #define debug_q(x) do{}while(0)
00059 #endif
00060 
00061 static inline int pico_enqueue(struct pico_queue *q, struct pico_frame *p)
00062 {
00063   if ((q->max_frames) && (q->max_frames <= q->frames))
00064     return -1;
00065     
00066   if ((Q_LIMIT) && (Q_LIMIT < p->buffer_len + q->size))
00067     return -1;
00068     
00069   if ((q->max_size) && (q->max_size < (p->buffer_len + q->size)))
00070     return -1;
00071 
00072   if (q->shared)
00073     LOCK(q->mutex);
00074 
00075   p->next = NULL;
00076   if (!q->head) {
00077     q->head = p;
00078     q->tail = p;
00079     q->size = 0;
00080     q->frames = 0;
00081   } else {
00082     q->tail->next = p;
00083     q->tail = p;
00084   }
00085   q->size += p->buffer_len;
00086   q->frames++;
00087   debug_q(q);
00088 
00089   if (q->shared)
00090     UNLOCK(q->mutex);
00091   return q->size;
00092 }
00093 
00094 static inline struct pico_frame *pico_dequeue(struct pico_queue *q)
00095 {
00096   struct pico_frame *p = q->head;
00097   if (q->frames < 1)
00098     return NULL;
00099   if (q->shared)
00100     LOCK(q->mutex);
00101 
00102   q->head = p->next;
00103   q->frames--;
00104   q->size -= p->buffer_len;
00105   if (q->head == NULL)
00106     q->tail = NULL;
00107   debug_q(q);
00108   p->next = NULL;
00109   if (q->shared)
00110     UNLOCK(q->mutex);
00111   return p;
00112 }
00113 
00114 static inline struct pico_frame *pico_queue_peek(struct pico_queue *q)
00115 {
00116   struct pico_frame *p = q->head;
00117   if (q->frames < 1)
00118     return NULL;
00119   debug_q(q);
00120   return p;
00121 }
00122 
00123 static inline void pico_queue_empty(struct pico_queue *q)
00124 {
00125   struct pico_frame *p = pico_dequeue(q);
00126   while(p) {
00127     pico_free(p);
00128     p = pico_dequeue(q);
00129   }
00130 }
00131 
00132 static inline void pico_queue_protect(struct pico_queue *q)
00133 {
00134   q->shared = 1;
00135 }
00136 
00137 #endif