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:
Fri May 24 15:25:25 2013 +0000
Revision:
3:b4047e8a0123
Updated from main repo + fixed Mutexes;

Who changed what in which revision?

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