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:
TASS Belgium NV
Date:
Mon Dec 16 11:25:54 2013 +0100
Revision:
131:4758606c9316
Parent:
73:dfb737147f6e
Child:
137:a1c8bfa9d691
Syncronized with master branch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 68:0847e35d08a6 1 /*********************************************************************
TASS Belgium NV 131:4758606c9316 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
TASS Belgium NV 131:4758606c9316 3 See LICENSE and COPYING for usage.
tass 68:0847e35d08a6 4
TASS Belgium NV 131:4758606c9316 5 .
tass 68:0847e35d08a6 6
TASS Belgium NV 131:4758606c9316 7 Authors: Daniele Lacamera
TASS Belgium NV 131:4758606c9316 8 *********************************************************************/
tass 68:0847e35d08a6 9
tass 68:0847e35d08a6 10
tass 68:0847e35d08a6 11 #include "pico_config.h"
tass 68:0847e35d08a6 12 #include "pico_frame.h"
tass 68:0847e35d08a6 13
tass 68:0847e35d08a6 14 #ifdef PICO_SUPPORT_DEBUG_MEMORY
tass 68:0847e35d08a6 15 static int n_frames_allocated;
tass 68:0847e35d08a6 16 #endif
tass 68:0847e35d08a6 17
tass 68:0847e35d08a6 18 /** frame alloc/dealloc/copy **/
tass 68:0847e35d08a6 19 void pico_frame_discard(struct pico_frame *f)
tass 68:0847e35d08a6 20 {
TASS Belgium NV 131:4758606c9316 21 (*f->usage_count)--;
TASS Belgium NV 131:4758606c9316 22 if (*f->usage_count <= 0) {
TASS Belgium NV 131:4758606c9316 23 pico_free(f->usage_count);
tass 68:0847e35d08a6 24 #ifdef PICO_SUPPORT_DEBUG_MEMORY
TASS Belgium NV 131:4758606c9316 25 dbg("Discarded buffer @%p, caller: %p\n", f->buffer, __builtin_return_address(3));
TASS Belgium NV 131:4758606c9316 26 dbg("DEBUG MEMORY: %d frames in use.\n", --n_frames_allocated);
tass 68:0847e35d08a6 27 #endif
TASS Belgium NV 131:4758606c9316 28 pico_free(f->buffer);
TASS Belgium NV 131:4758606c9316 29 if (f->info)
TASS Belgium NV 131:4758606c9316 30 pico_free(f->info);
TASS Belgium NV 131:4758606c9316 31 }
TASS Belgium NV 131:4758606c9316 32
tass 68:0847e35d08a6 33 #ifdef PICO_SUPPORT_DEBUG_MEMORY
TASS Belgium NV 131:4758606c9316 34 else {
TASS Belgium NV 131:4758606c9316 35 dbg("Removed frame @%p(copy), usage count now: %d\n", f, *f->usage_count);
TASS Belgium NV 131:4758606c9316 36 }
tass 68:0847e35d08a6 37 #endif
TASS Belgium NV 131:4758606c9316 38 pico_free(f);
tass 68:0847e35d08a6 39 }
tass 68:0847e35d08a6 40
tass 68:0847e35d08a6 41 struct pico_frame *pico_frame_copy(struct pico_frame *f)
tass 68:0847e35d08a6 42 {
TASS Belgium NV 131:4758606c9316 43 struct pico_frame *new = pico_zalloc(sizeof(struct pico_frame));
TASS Belgium NV 131:4758606c9316 44 if (!new)
TASS Belgium NV 131:4758606c9316 45 return NULL;
TASS Belgium NV 131:4758606c9316 46
TASS Belgium NV 131:4758606c9316 47 memcpy(new, f, sizeof(struct pico_frame));
TASS Belgium NV 131:4758606c9316 48 *(new->usage_count) += 1;
tass 68:0847e35d08a6 49 #ifdef PICO_SUPPORT_DEBUG_MEMORY
TASS Belgium NV 131:4758606c9316 50 dbg("Copied frame @%p, into %p, usage count now: %d\n", f, new, *new->usage_count);
tass 68:0847e35d08a6 51 #endif
TASS Belgium NV 131:4758606c9316 52 new->next = NULL;
TASS Belgium NV 131:4758606c9316 53 return new;
tass 68:0847e35d08a6 54 }
tass 68:0847e35d08a6 55
tass 68:0847e35d08a6 56
tass 70:cd218dd180e5 57 struct pico_frame *pico_frame_alloc(uint32_t size)
tass 68:0847e35d08a6 58 {
TASS Belgium NV 131:4758606c9316 59 struct pico_frame *p = pico_zalloc(sizeof(struct pico_frame));
TASS Belgium NV 131:4758606c9316 60 if (!p)
TASS Belgium NV 131:4758606c9316 61 return NULL;
TASS Belgium NV 131:4758606c9316 62
TASS Belgium NV 131:4758606c9316 63 p->buffer = pico_zalloc(size);
TASS Belgium NV 131:4758606c9316 64 if (!p->buffer) {
TASS Belgium NV 131:4758606c9316 65 pico_free(p);
TASS Belgium NV 131:4758606c9316 66 return NULL;
TASS Belgium NV 131:4758606c9316 67 }
TASS Belgium NV 131:4758606c9316 68
TASS Belgium NV 131:4758606c9316 69 p->usage_count = pico_zalloc(sizeof(uint32_t));
TASS Belgium NV 131:4758606c9316 70 if (!p->usage_count) {
TASS Belgium NV 131:4758606c9316 71 pico_free(p->buffer);
TASS Belgium NV 131:4758606c9316 72 pico_free(p);
TASS Belgium NV 131:4758606c9316 73 return NULL;
TASS Belgium NV 131:4758606c9316 74 }
TASS Belgium NV 131:4758606c9316 75
TASS Belgium NV 131:4758606c9316 76 p->buffer_len = size;
tass 68:0847e35d08a6 77
tass 68:0847e35d08a6 78
TASS Belgium NV 131:4758606c9316 79 /* By default, frame content is the full buffer. */
TASS Belgium NV 131:4758606c9316 80 p->start = p->buffer;
TASS Belgium NV 131:4758606c9316 81 p->len = p->buffer_len;
TASS Belgium NV 131:4758606c9316 82 *p->usage_count = 1;
tass 68:0847e35d08a6 83 #ifdef PICO_SUPPORT_DEBUG_MEMORY
tass 68:0847e35d08a6 84 dbg("Allocated buffer @%p, len= %d caller: %p\n", p->buffer, p->buffer_len, __builtin_return_address(2));
tass 68:0847e35d08a6 85 dbg("DEBUG MEMORY: %d frames in use.\n", ++n_frames_allocated);
tass 68:0847e35d08a6 86 #endif
TASS Belgium NV 131:4758606c9316 87 return p;
tass 68:0847e35d08a6 88 }
tass 68:0847e35d08a6 89
tass 68:0847e35d08a6 90 struct pico_frame *pico_frame_deepcopy(struct pico_frame *f)
tass 68:0847e35d08a6 91 {
TASS Belgium NV 131:4758606c9316 92 struct pico_frame *new = pico_frame_alloc(f->buffer_len);
TASS Belgium NV 131:4758606c9316 93 int addr_diff;
TASS Belgium NV 131:4758606c9316 94 unsigned char *buf;
TASS Belgium NV 131:4758606c9316 95 uint32_t *uc;
TASS Belgium NV 131:4758606c9316 96 if (!new)
TASS Belgium NV 131:4758606c9316 97 return NULL;
tass 68:0847e35d08a6 98
TASS Belgium NV 131:4758606c9316 99 /* Save the two key pointers... */
TASS Belgium NV 131:4758606c9316 100 buf = new->buffer;
TASS Belgium NV 131:4758606c9316 101 uc = new->usage_count;
tass 68:0847e35d08a6 102
TASS Belgium NV 131:4758606c9316 103 /* Overwrite all fields with originals */
TASS Belgium NV 131:4758606c9316 104 memcpy(new, f, sizeof(struct pico_frame));
tass 68:0847e35d08a6 105
TASS Belgium NV 131:4758606c9316 106 /* ...restore the two key pointers */
TASS Belgium NV 131:4758606c9316 107 new->buffer = buf;
TASS Belgium NV 131:4758606c9316 108 new->usage_count = uc;
tass 68:0847e35d08a6 109
TASS Belgium NV 131:4758606c9316 110 /* Update in-buffer pointers with offset */
TASS Belgium NV 131:4758606c9316 111 addr_diff = (int)(new->buffer - f->buffer);
TASS Belgium NV 131:4758606c9316 112 new->net_hdr += addr_diff;
TASS Belgium NV 131:4758606c9316 113 new->transport_hdr += addr_diff;
TASS Belgium NV 131:4758606c9316 114 new->app_hdr += addr_diff;
TASS Belgium NV 131:4758606c9316 115 new->start += addr_diff;
TASS Belgium NV 131:4758606c9316 116 new->payload += addr_diff;
tass 68:0847e35d08a6 117
tass 68:0847e35d08a6 118 #ifdef PICO_SUPPORT_DEBUG_MEMORY
TASS Belgium NV 131:4758606c9316 119 dbg("Deep-Copied frame @%p, into %p, usage count now: %d\n", f, new, *new->usage_count);
tass 68:0847e35d08a6 120 #endif
TASS Belgium NV 131:4758606c9316 121 new->next = NULL;
TASS Belgium NV 131:4758606c9316 122 return new;
tass 68:0847e35d08a6 123 }
tass 68:0847e35d08a6 124
tass 68:0847e35d08a6 125 /**
tass 68:0847e35d08a6 126 * Calculate checksum of a given string
tass 68:0847e35d08a6 127 */
tass 70:cd218dd180e5 128 uint16_t pico_checksum(void *inbuf, uint32_t len)
tass 68:0847e35d08a6 129 {
TASS Belgium NV 131:4758606c9316 130 uint8_t *buf = (uint8_t *) inbuf;
TASS Belgium NV 131:4758606c9316 131 uint32_t tmp = 0;
TASS Belgium NV 131:4758606c9316 132 uint32_t sum = 0;
TASS Belgium NV 131:4758606c9316 133 uint32_t i = 0;
tass 68:0847e35d08a6 134
TASS Belgium NV 131:4758606c9316 135 for(i = 0; i < len; i++) {
TASS Belgium NV 131:4758606c9316 136 if (i % 2) {
TASS Belgium NV 131:4758606c9316 137 sum += buf[i];
TASS Belgium NV 131:4758606c9316 138 } else {
TASS Belgium NV 131:4758606c9316 139 tmp = buf[i];
TASS Belgium NV 131:4758606c9316 140 sum += (tmp << 8);
TASS Belgium NV 131:4758606c9316 141 }
tass 68:0847e35d08a6 142 }
TASS Belgium NV 131:4758606c9316 143 while (sum >> 16) { /* a second carry is possible! */
TASS Belgium NV 131:4758606c9316 144 sum = (sum & 0x0000FFFF) + (sum >> 16);
TASS Belgium NV 131:4758606c9316 145 }
TASS Belgium NV 131:4758606c9316 146 return (uint16_t) (~sum);
tass 68:0847e35d08a6 147 }
tass 68:0847e35d08a6 148
tass 70:cd218dd180e5 149 uint16_t pico_dualbuffer_checksum(void *inbuf1, uint32_t len1, void *inbuf2, uint32_t len2)
tass 68:0847e35d08a6 150 {
TASS Belgium NV 131:4758606c9316 151 uint8_t *b1 = (uint8_t *) inbuf1;
TASS Belgium NV 131:4758606c9316 152 uint8_t *b2 = (uint8_t *) inbuf2;
TASS Belgium NV 131:4758606c9316 153 uint16_t tmp = 0;
TASS Belgium NV 131:4758606c9316 154 uint32_t sum = 0;
TASS Belgium NV 131:4758606c9316 155 uint32_t i = 0, j = 0;
tass 68:0847e35d08a6 156
TASS Belgium NV 131:4758606c9316 157 for(i = 0; i < len1; i++) {
TASS Belgium NV 131:4758606c9316 158 if (j % 2) {
TASS Belgium NV 131:4758606c9316 159 sum += b1[i];
TASS Belgium NV 131:4758606c9316 160 } else {
TASS Belgium NV 131:4758606c9316 161 tmp = b1[i];
TASS Belgium NV 131:4758606c9316 162 sum = sum + (uint32_t)(tmp << 8);
TASS Belgium NV 131:4758606c9316 163 }
TASS Belgium NV 131:4758606c9316 164
TASS Belgium NV 131:4758606c9316 165 j++;
tass 68:0847e35d08a6 166 }
TASS Belgium NV 131:4758606c9316 167 j = 0; /* j has to be reset if len1 is odd */
TASS Belgium NV 131:4758606c9316 168 for(i = 0; i < len2; i++) {
TASS Belgium NV 131:4758606c9316 169 if (j % 2) {
TASS Belgium NV 131:4758606c9316 170 sum += b2[i];
TASS Belgium NV 131:4758606c9316 171 } else {
TASS Belgium NV 131:4758606c9316 172 tmp = b2[i];
TASS Belgium NV 131:4758606c9316 173 sum = sum + (uint32_t)(tmp << 8);
TASS Belgium NV 131:4758606c9316 174 }
tass 68:0847e35d08a6 175
TASS Belgium NV 131:4758606c9316 176 j++;
tass 68:0847e35d08a6 177 }
TASS Belgium NV 131:4758606c9316 178 while (sum >> 16) { /* a second carry is possible! */
TASS Belgium NV 131:4758606c9316 179 sum = (sum & 0x0000FFFF) + (sum >> 16);
TASS Belgium NV 131:4758606c9316 180 }
TASS Belgium NV 131:4758606c9316 181 return (uint16_t) (~sum);
tass 68:0847e35d08a6 182 }
tass 68:0847e35d08a6 183
tass 70:cd218dd180e5 184 uint16_t pico_dualbuffer_checksum_broken(void *inbuf1, uint16_t len1, void *inbuf2, uint16_t len2)
tass 68:0847e35d08a6 185 {
TASS Belgium NV 131:4758606c9316 186 uint16_t *b1 = (uint16_t *) inbuf1;
TASS Belgium NV 131:4758606c9316 187 uint16_t *b2 = (uint16_t *) inbuf2;
TASS Belgium NV 131:4758606c9316 188 uint32_t sum = 0;
TASS Belgium NV 131:4758606c9316 189 int i = 0, j = 0;
TASS Belgium NV 131:4758606c9316 190 for(i = 0; i < (len1 >> 1); i++) {
TASS Belgium NV 131:4758606c9316 191 sum += short_be(b1[i]);
TASS Belgium NV 131:4758606c9316 192 j++;
TASS Belgium NV 131:4758606c9316 193 }
TASS Belgium NV 131:4758606c9316 194 for(i = 0; i < (len2 >> 1); i++) {
TASS Belgium NV 131:4758606c9316 195 sum += short_be(b2[i]);
TASS Belgium NV 131:4758606c9316 196 j++;
TASS Belgium NV 131:4758606c9316 197 }
TASS Belgium NV 131:4758606c9316 198 sum = (sum & 0xFFFF) + (sum >> 16);
TASS Belgium NV 131:4758606c9316 199 sum += (sum >> 16);
TASS Belgium NV 131:4758606c9316 200
TASS Belgium NV 131:4758606c9316 201 /* Take the bitwise complement of sum */
TASS Belgium NV 131:4758606c9316 202 sum = ~sum;
TASS Belgium NV 131:4758606c9316 203 return (uint16_t) (sum);
tass 68:0847e35d08a6 204 }
tass 68:0847e35d08a6 205
tass 68:0847e35d08a6 206