tass-belgium / picotcp-modules

Application level modules to run on top of the popular Embedded picoTCP TCP/IP stack
GNU General Public License v2.0
8 stars 11 forks source link

[HTTP server] add feature to send large blocks (>150K in chunks) #12

Open phalox opened 8 years ago

phalox commented 8 years ago

Etienne Cochard suggests these changes, to assosiate data with a connection

  1. Add field to struct struct http_client { uint16_t connectionID; struct pico_socket _sck; void buffer; uint16_t buffer_size; uint16_t buffer_sent; char resource; uint16_t state; uint16t method; char *body; void user_data; <<<<<<<<<<<<<<<<< };
  2. Create two new functions void pico_http_set_user_data(uint16_t conn, void* data) { struct http_client *client = find_client(conn); if (!client) { dbg("Wrong connection ID\n"); return; }

    client->user_data = data; }

void* pico_http_get_user_data(uint16_t conn) { struct http_client *client = find_client(conn); if (!client) { dbg("Wrong connection ID\n"); return NULL; }

return  client->user_data;

}

  1. This will also require support from the device driver, therefore the last step refers to the specific device driver.

in pico_f4x7_eth.c (https://github.com/tass-belgium/cyassl-picotcp/blob/master/src/pico_f4x7_eth.c)

int16_t f4x7_frame_push(ETH_HandleTypeDef heth, uint8_t buf, uint16_t len) { // if in use, avoid crashing the buffer if ((heth->TxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) <<< you should have added something like that before (this code is for discovery stm32F7 / i can give you the full source for this board) return 0;

uint8_t *buffer = (uint8_t *)(heth->TxDesc->Buffer1Addr);
/* copy frame from local buf to DMA buffers */
memcpy(buffer, buf, len);                                          <<< because the memory should be used by the DMA & you may scratch it

/* Prepare transmit descriptors to give to DMA*/
if (HAL_ETH_TransmitFrame(heth, len) != HAL_OK)
    return 0;
return len;

}

maximevince commented 8 years ago

About the device driver modification: One cannot simply remove the memcpy(buffer, buf, len); This buffer was allocated by the stack (using PICO_ZALLOC), and will be freed after pico_eth_send() has been called. If that buffer is just attached to the DMA, chances are that the contents get corrupted, since the stacked released this memory back into the malloc-pool.

A zero-copy implementation is needed to eliminate the memcpy(), but it exists only for the RX-side at this moment... (See pico_stack_recv_zerocopy() at https://github.com/tass-belgium/picotcp/blob/72848bdc0c8bd84fe66ecf329d39957c5598fd0c/include/pico_stack.h)

eco747 commented 8 years ago

the goal was not to remove memcpy (saddly) but to avoid modification of a used (by DMA) buffer please read these line before the highlighted code:

// if in use, avoid crashing the buffer
if ((heth->TxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) <<< you should have added something like that before (this code is for discovery stm32F7 / i can give you the full source for this board)
return 0;