So I dived into lwIP to understand how to do this. Aside from noticing lwIP is a mess of half-defined functions, unclear preconditions and a lot of #ifdef settings. I managed to come up with this:
Code: Select all
#include "ch.h"
#include "hal.h"
#include "threads.h" // shared resources and semaphores
#include "chprintf.h"
#include "lwip/api.h"
#include <stdio.h>
#define cout ((BaseSequentialStream *) &SD2)
msg_t Thread2(void *arg);
WORKING_AREA(waThread2, 512);
msg_t Thread2(void *arg)
{
// nested block to ensure cleanup of local variables since chThdExit() doesn't return!
{
// const for placement in ROM, static for pre-allocation in compiler instead of heap
const systime_t t = 100;
static uint32_t i=0;
// Connection
static struct netconn *conn;
static ip_addr_t ip;
IP4_ADDR(&ip, 192,168,5,10);
// Payload
const char buf[] = "This is a test, system time is now ";
static char send_cache[64];
// Error checking
static err_t err;
// Name thread
chRegSetThreadName("tcp_conn");
// Forever, unless requested to terminate
while (!chThdShouldTerminate()) {
// Create new connection
conn = netconn_new( NETCONN_TCP );
// Suggest this local port (doesn't always work)
netconn_bind(conn, IP_ADDR_ANY, 1234 );
// Set timeout, otherwise netconn_write() won't fail
netconn_set_sendtimeout(conn, 1000);
// Connect to ip
err = netconn_connect(conn, &ip, 1235 );
// Verify connection
if(err != ERR_OK){
// Report failed
chSemWait(&coutLock);
chprintf(cout, "tcp could not connect\r\n");
chSemSignal(&coutLock);
}else{
// Continously send a datastring with systime
do{
// Assemble datastring in cache
uint32_t size = sprintf(send_cache,"%s%d\r\n", buf, chTimeNow());
// Write cache to tcp, blocking without copy to lwip data
err = netconn_write(conn, send_cache, size, NETCONN_NOCOPY);
// Blink a led
palTogglePad(GPIOD, GPIOD_LED4);
// Report success
chSemWait(&coutLock);
chprintf(cout, "tcp %010d, %d\r\n", chTimeNow(), i++);
chSemSignal(&coutLock);
// Wait a while
chThdSleepMilliseconds(t);
// Check for success
}while(err == ERR_OK && !chThdShouldTerminate());
// report disconnect
chSemWait(&coutLock);
chprintf(cout, "tcp disconnected %d\r\n", netconn_err(conn));
chSemSignal(&coutLock);
}
// Failed, close connection (probably caused by a disconnect or ignore by the server)
netconn_close(conn);
// Delete connection and start over
netconn_delete(conn);
// Delay, otherwise the cout will flood (the pc cannot keep up)
chThdSleepMilliseconds(1000);
} // end of while
} // end of block
chThdExit(0);
return 0;
}
I'm convinced this can serve as an example with at least some quality, please improve if you disagree.