Free (GPLv2) TCP/IP stack developed by TASS Belgium

Dependents:   lpc1768-picotcp-demo ZeroMQ_PicoTCP_Publisher_demo TCPSocket_HelloWorld_PicoTCP Pico_TCP_UDP_Test ... more

PicoTCP. Copyright (c) 2013 TASS Belgium NV.

Released under the GNU General Public License, version 2.

Different licensing models may exist, at the sole discretion of the Copyright holders.

Official homepage: http://www.picotcp.com

Bug tracker: https://github.com/tass-belgium/picotcp/issues

Development steps:

  • initial integration with mbed RTOS
  • generic mbed Ethernet driver
  • high performance NXP LPC1768 specific Ethernet driver
  • Multi-threading support for mbed RTOS
  • Berkeley sockets and integration with the New Socket API
  • Fork of the apps running on top of the New Socket API
  • Scheduling optimizations
  • Debugging/benchmarking/testing

Demo application (measuring TCP sender performance):

Import programlpc1768-picotcp-demo

A PicoTCP demo app testing the ethernet throughput on the lpc1768 mbed board.

Committer:
daniele
Date:
Tue Jun 11 23:28:50 2013 +0000
Revision:
25:d63125298eb3
Parent:
24:8bff2b51ea3b
Child:
26:dc3e7f96338f
Fixed close

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daniele 12:0c6fa180a6ec 1 /*********************************************************************
daniele 12:0c6fa180a6ec 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
daniele 12:0c6fa180a6ec 3 See LICENSE and COPYING for usage.
daniele 12:0c6fa180a6ec 4
daniele 12:0c6fa180a6ec 5 *********************************************************************/
daniele 12:0c6fa180a6ec 6 #ifndef _INCLUDE_PICO_QUEUE
daniele 12:0c6fa180a6ec 7 #define _INCLUDE_PICO_QUEUE
daniele 12:0c6fa180a6ec 8 #include <stdint.h>
daniele 12:0c6fa180a6ec 9 #include "pico_config.h"
daniele 12:0c6fa180a6ec 10 #include "pico_frame.h"
daniele 12:0c6fa180a6ec 11
daniele 25:d63125298eb3 12 #define Q_LIMIT 0
daniele 24:8bff2b51ea3b 13
daniele 12:0c6fa180a6ec 14 #ifndef NULL
daniele 12:0c6fa180a6ec 15 #define NULL ((void *)0)
daniele 12:0c6fa180a6ec 16 #endif
daniele 12:0c6fa180a6ec 17
daniele 12:0c6fa180a6ec 18 struct pico_queue {
daniele 12:0c6fa180a6ec 19 uint32_t frames;
daniele 12:0c6fa180a6ec 20 uint32_t size;
daniele 12:0c6fa180a6ec 21 uint32_t max_frames;
daniele 12:0c6fa180a6ec 22 uint32_t max_size;
daniele 12:0c6fa180a6ec 23 struct pico_frame *head;
daniele 12:0c6fa180a6ec 24 struct pico_frame *tail;
daniele 12:0c6fa180a6ec 25 #ifdef PICO_SUPPORT_MUTEX
daniele 12:0c6fa180a6ec 26 void * mutex;
daniele 12:0c6fa180a6ec 27 #endif
daniele 12:0c6fa180a6ec 28 uint8_t shared;
daniele 12:0c6fa180a6ec 29 };
daniele 12:0c6fa180a6ec 30
daniele 12:0c6fa180a6ec 31 #ifdef PICO_SUPPORT_MUTEX
daniele 12:0c6fa180a6ec 32 #define LOCK(x) {\
daniele 12:0c6fa180a6ec 33 if (x == NULL) \
daniele 12:0c6fa180a6ec 34 x = pico_mutex_init(); \
daniele 12:0c6fa180a6ec 35 pico_mutex_lock(x); \
daniele 12:0c6fa180a6ec 36 }
daniele 12:0c6fa180a6ec 37 #define UNLOCK(x) pico_mutex_unlock(x);
daniele 12:0c6fa180a6ec 38
daniele 12:0c6fa180a6ec 39 #else
daniele 12:0c6fa180a6ec 40 #define LOCK(x) do{}while(0)
daniele 12:0c6fa180a6ec 41 #define UNLOCK(x) do{}while(0)
daniele 12:0c6fa180a6ec 42 #endif
daniele 12:0c6fa180a6ec 43
daniele 12:0c6fa180a6ec 44 #ifdef PICO_SUPPORT_DEBUG_TOOLS
daniele 12:0c6fa180a6ec 45 static void debug_q(struct pico_queue *q)
daniele 12:0c6fa180a6ec 46 {
daniele 12:0c6fa180a6ec 47 struct pico_frame *p = q->head;
daniele 12:0c6fa180a6ec 48 dbg("%d: ", q->frames);
daniele 12:0c6fa180a6ec 49 while(p) {
daniele 12:0c6fa180a6ec 50 dbg("(%p)-->", p);
daniele 12:0c6fa180a6ec 51 p = p->next;
daniele 12:0c6fa180a6ec 52 }
daniele 12:0c6fa180a6ec 53 dbg("X\n");
daniele 12:0c6fa180a6ec 54 }
daniele 12:0c6fa180a6ec 55
daniele 12:0c6fa180a6ec 56 #else
daniele 12:0c6fa180a6ec 57
daniele 12:0c6fa180a6ec 58 #define debug_q(x) do{}while(0)
daniele 12:0c6fa180a6ec 59 #endif
daniele 12:0c6fa180a6ec 60
daniele 12:0c6fa180a6ec 61 static inline int pico_enqueue(struct pico_queue *q, struct pico_frame *p)
daniele 12:0c6fa180a6ec 62 {
daniele 12:0c6fa180a6ec 63 if ((q->max_frames) && (q->max_frames <= q->frames))
daniele 12:0c6fa180a6ec 64 return -1;
daniele 24:8bff2b51ea3b 65
daniele 24:8bff2b51ea3b 66 if ((Q_LIMIT) && (Q_LIMIT < p->buffer_len + q->size))
daniele 24:8bff2b51ea3b 67 return -1;
daniele 24:8bff2b51ea3b 68
daniele 12:0c6fa180a6ec 69 if ((q->max_size) && (q->max_size < (p->buffer_len + q->size)))
daniele 12:0c6fa180a6ec 70 return -1;
daniele 12:0c6fa180a6ec 71
daniele 12:0c6fa180a6ec 72 if (q->shared)
daniele 12:0c6fa180a6ec 73 LOCK(q->mutex);
daniele 12:0c6fa180a6ec 74
daniele 12:0c6fa180a6ec 75 p->next = NULL;
daniele 12:0c6fa180a6ec 76 if (!q->head) {
daniele 12:0c6fa180a6ec 77 q->head = p;
daniele 12:0c6fa180a6ec 78 q->tail = p;
daniele 12:0c6fa180a6ec 79 q->size = 0;
daniele 12:0c6fa180a6ec 80 q->frames = 0;
daniele 12:0c6fa180a6ec 81 } else {
daniele 12:0c6fa180a6ec 82 q->tail->next = p;
daniele 12:0c6fa180a6ec 83 q->tail = p;
daniele 12:0c6fa180a6ec 84 }
daniele 12:0c6fa180a6ec 85 q->size += p->buffer_len;
daniele 12:0c6fa180a6ec 86 q->frames++;
daniele 12:0c6fa180a6ec 87 debug_q(q);
daniele 12:0c6fa180a6ec 88
daniele 12:0c6fa180a6ec 89 if (q->shared)
daniele 12:0c6fa180a6ec 90 UNLOCK(q->mutex);
daniele 12:0c6fa180a6ec 91 return q->size;
daniele 12:0c6fa180a6ec 92 }
daniele 12:0c6fa180a6ec 93
daniele 12:0c6fa180a6ec 94 static inline struct pico_frame *pico_dequeue(struct pico_queue *q)
daniele 12:0c6fa180a6ec 95 {
daniele 12:0c6fa180a6ec 96 struct pico_frame *p = q->head;
daniele 12:0c6fa180a6ec 97 if (q->frames < 1)
daniele 12:0c6fa180a6ec 98 return NULL;
daniele 12:0c6fa180a6ec 99 if (q->shared)
daniele 12:0c6fa180a6ec 100 LOCK(q->mutex);
daniele 12:0c6fa180a6ec 101
daniele 12:0c6fa180a6ec 102 q->head = p->next;
daniele 12:0c6fa180a6ec 103 q->frames--;
daniele 12:0c6fa180a6ec 104 q->size -= p->buffer_len;
daniele 12:0c6fa180a6ec 105 if (q->head == NULL)
daniele 12:0c6fa180a6ec 106 q->tail = NULL;
daniele 12:0c6fa180a6ec 107 debug_q(q);
daniele 12:0c6fa180a6ec 108 p->next = NULL;
daniele 12:0c6fa180a6ec 109 if (q->shared)
daniele 12:0c6fa180a6ec 110 UNLOCK(q->mutex);
daniele 12:0c6fa180a6ec 111 return p;
daniele 12:0c6fa180a6ec 112 }
daniele 12:0c6fa180a6ec 113
daniele 12:0c6fa180a6ec 114 static inline struct pico_frame *pico_queue_peek(struct pico_queue *q)
daniele 12:0c6fa180a6ec 115 {
daniele 12:0c6fa180a6ec 116 struct pico_frame *p = q->head;
daniele 12:0c6fa180a6ec 117 if (q->frames < 1)
daniele 12:0c6fa180a6ec 118 return NULL;
daniele 12:0c6fa180a6ec 119 debug_q(q);
daniele 12:0c6fa180a6ec 120 return p;
daniele 12:0c6fa180a6ec 121 }
daniele 12:0c6fa180a6ec 122
daniele 12:0c6fa180a6ec 123 static inline void pico_queue_empty(struct pico_queue *q)
daniele 12:0c6fa180a6ec 124 {
daniele 12:0c6fa180a6ec 125 struct pico_frame *p = pico_dequeue(q);
daniele 12:0c6fa180a6ec 126 while(p) {
daniele 12:0c6fa180a6ec 127 pico_free(p);
daniele 12:0c6fa180a6ec 128 p = pico_dequeue(q);
daniele 12:0c6fa180a6ec 129 }
daniele 12:0c6fa180a6ec 130 }
daniele 12:0c6fa180a6ec 131
daniele 12:0c6fa180a6ec 132 static inline void pico_queue_protect(struct pico_queue *q)
daniele 12:0c6fa180a6ec 133 {
daniele 12:0c6fa180a6ec 134 q->shared = 1;
daniele 12:0c6fa180a6ec 135 }
daniele 12:0c6fa180a6ec 136
daniele 12:0c6fa180a6ec 137 #endif