CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2
Fork of USB_Ethernet by
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
Generated on Wed Jul 13 2022 02:20:45 by 1.7.2