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
Date:
Thu Sep 26 07:05:22 2013 +0000
Revision:
70:cd218dd180e5
Parent:
68:0847e35d08a6
Child:
73:dfb737147f6e
Update from masterbranch

Who changed what in which revision?

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