Page 1 of 1

STM32F2 lwIP client

Posted: Tue Nov 20, 2018 8:46 pm
by nojwa
Exists somewhere example for TCP client over lwip (ST's family)?

Connection to the server server failed err_t == -4. Wireshark didn't detect any request for connection to server (to pc ip: *, *, 6, 110).

Have you some experiences? Some lwipopt for tcp client ... anything?

Error output:
[018.434] [./src/ethcomm.c:ethCommThread] start client thread
[018.442] [./src/ethcomm.c:ethCommThread] binded: 0, state: 0
[018.447] [./src/ethcomm.c:ethCommThread] connected: -4, state: 0

Code: Select all

static void ethMacAddress(struct lwipthread_opts *ipSettings)
{
    uint8_t mac[6];

    mac[0] = 0x06;
    mac[1] = 0x*;
    mac[2] = 0x*;
    mac[3] = 0x02;
    mac[4] = 0x03;
    mac[5] = 0x04;

    dhexprint(mac, 6);

ipSettings->macaddress = mac;
}

static void ethIpSettings(struct lwipthread_opts *ipSettings)
{
    ip_addr_t ip, netmask;

    IP4_ADDR(&ip, *, *, 6, 102);

    ipSettings->address = ip.addr;
    IP4_ADDR(&netmask, 255, 255, 255, 0);
    ipSettings->netmask = netmask.addr;
    ipSettings->addrMode = NET_ADDRESS_STATIC;
}

static THD_WORKING_AREA(ethThread_wa, 2048);
static thread_t *ethThread = NULL;

static THD_FUNCTION(ethCommThread, arg)
{
    (void) arg;

    dprint("start client thread\n");
    chRegSetThreadName("tcp_client");

    struct netconn *conn;
    err_t err;

    /* Create a new TCP connection handle */
    conn = netconn_new(NETCONN_TCP);
    LWIP_ERROR("tcp client: invalid conn", (conn != NULL), chThdExit(MSG_RESET););

    /* Bind to port 2000 with default IP address */
    err = netconn_bind(conn, IP_ADDR_ANY, 2000);
    dprint("binded: %d, state: %d\n", err, conn->state);

    ip_addr_t serverIp;
    IP4_ADDR(&serverIp, *, *, 6, 110);

    err = netconn_connect(conn, &serverIp, 6000);
    dprint("connected: %d, state: %d\n", err, conn->state);
}

uint8_t ethernetInit()
{
    struct lwipthread_opts ipSettings;
    ethIpSettings(&ipSettings);

    ethMacAddress(&ipSettings);
    lwipInit(&ipSettings);

    ethThread = chThdCreateStatic(ethThread_wa, sizeof(ethThread_wa), NORMALPRIO, ethCommThread, NULL);
    return 0;
}

Re: STM32F2 lwIP client

Posted: Tue Nov 20, 2018 8:52 pm
by Giovanni
Hi,

There are lwIP demos in ChibiOS for F4 and F7.

Giovanni

Re: STM32F2 lwIP client

Posted: Tue Nov 20, 2018 9:53 pm
by nojwa
Hi Giovanni,

i know. I tried demo for F4, but this demo is for server side. Demo is fully operational.

Now i write client side, but can't make a operational connection.

Re: STM32F2 lwIP client

Posted: Tue Nov 20, 2018 10:06 pm
by Giovanni
Hi,

I don't have any demo for client side, try looking into the "user projects" forum, there could be more examples.

Giovanni

Re: STM32F2 lwIP client

Posted: Wed Nov 21, 2018 8:34 pm
by nojwa
Hi,

No matter. I am not found satisfactory answer in thread "user projects". One post about client side, but any answer.

I will try to find some problem on my side and at the same time i will wait for some next advice, experiences or some fully operational client-example.

thx Nojwa

Re: STM32F2 lwIP client

Posted: Wed Nov 21, 2018 11:24 pm
by steved
Unfortunately for you, I think most uses of lwip with Chibios are server applications.

One suggestion is to start by coding your application to use sockets. Even if you are not familiar with them, you will find plenty of examples elsewhere since it is a standard interface. This will allow you to prove your hardware interface and some of your client code. (I've used lwip with sockets in a server application, and it pretty much just worked). The default lwip options file should be good enough to get you going.
Sockets add a bit more overhead, so you may want to convert to the lwip native interface later on.

Re: STM32F2 lwIP client

Posted: Thu Nov 22, 2018 9:55 am
by Polux
Hi,

ESP32 also uses LWIP. You will find plenty of examples.

Angelo

Re: STM32F2 lwIP client  Topic is solved

Posted: Tue Feb 05, 2019 10:33 pm
by nojwa
This is fully function TCP client - chibios 18.2.1 lwip 2.0.3

Code: Select all


static void ethMacAddress(struct lwipthread_opts *ipSettings)
{
    uint8_t mac[6];

    mac[0] = 0x06;
    mac[1] = *;
    mac[2] = *;
    mac[3] = *;
    mac[4] = *;
    mac[5] = *;

    ipSettings->macaddress = mac;
}

static void ethIpSettings(struct lwipthread_opts *ipSettings)
{
    ip_addr_t ip, netmask;

    IP4_ADDR(&ip, 192, 168, 0, 2);
    ipSettings->address = ip.addr;

    dprint("ip: %d.%d.%d.%d", ip4_addr1(&ip), ip4_addr2(&ip), ip4_addr3(&ip), ip4_addr4(&ip));

    IP4_ADDR(&netmask, 255, 255, 255, 0);
    ipSettings->netmask = netmask.addr;

    dprint("mask: %d.%d.%d.%d", ip4_addr1(&netmask), ip4_addr2(&netmask), ip4_addr3(&netmask), ip4_addr4(&netmask));

    ipSettings->addrMode = NET_ADDRESS_STATIC;
}

uint8_t ipInit()
{
    struct lwipthread_opts ipSettings;
    ethIpSettings(&ipSettings);

    ethMacAddress(&ipSettings);
    lwipInit(&ipSettings);

    return 0;
}

===================================================================================
static void precessData(struct netconn *conn)
{
    struct netbuf *inbuf = NULL;
    char *buf;
    u16_t buflen;

    err_t err = netconn_recv(conn, &inbuf);
    if (err == ERR_OK) {
        do {
            netbuf_data(inbuf, (void **)&buf, &buflen);

            int i = 0;
            for (; i < buflen; ++i)
                dprint("%x", buf[i]);

        } while (netbuf_next(inbuf) >= 0);
    }
    else {
        dprint("receiving data failed: %d", err);
    }

    netbuf_delete(inbuf);
}

static volatile int state = 0;
static void netconnCallback(struct netconn *conn, enum netconn_evt evt, u16_t len)
{
    dprint("evt: %d, state: %d, len: %d, err: %d", evt, conn->state, len, conn->last_err);

    if (evt == NETCONN_EVT_RCVPLUS && len == 0 && state == 2) {
        dprint("connection closed");
        state = 3;
    }

    if (evt == NETCONN_EVT_RCVPLUS && len > 0) {
        dprint("data recived");
    }

    if (evt == NETCONN_EVT_ERROR) {
        dprint("connection is forced closed");
    }
}

static struct netconn *createClient(err_t *err)
{
    struct netconn *tcpConnection;

    /* Create a new TCP connection handle */
    tcpConnection = netconn_new_with_callback(NETCONN_TCP, netconnCallback);
    LWIP_ERROR("tcp client: invalid conn", (tcpConnection != NULL), chThdExit(MSG_RESET););

    ip_addr_t localIp;
    IP4_ADDR(&localIp, 192, 168, 0, 2);

    /* Bind to port 2000 with default IP address */
    err_t bindOk = netconn_bind(tcpConnection, &localIp, 22222);

    if (bindOk != ERR_OK) {
        dprint("binded failed: %d\n", bindOk);
        *err = bindOk;
        netconn_delete(tcpConnection);
        return tcpConnection;
    }

    ip_addr_t serverIp;
    IP4_ADDR(&serverIp, 192, 168, 0, 1);

    err_t connectOk = netconn_connect(tcpConnection, &serverIp, 22222);

    if (bindOk == ERR_OK && connectOk == ERR_OK) {
       *err = ERR_OK;
       dprint("connection established\n");
    }
    else {
        dprint("connection failed: %\n", connectOk);
        *err = connectOk;
        netconn_delete(tcpConnection);
    }

    return tcpConnection;
}

static THD_WORKING_AREA(ethThread_wa, 512);
static thread_t *ethThread = NULL;

static THD_FUNCTION(ethCommThread, arg)
{
    (void) arg;

    dprint("start client thread\n");
    chRegSetThreadName("tcp_client");

    err_t err;
    struct netconn *tcpConnection = NULL;

    while(1) {
       if (state == 0) {
            tcpConnection = createClient(&err);

            if (err == ERR_OK)
                 state = 2;           
        }

        if (state == 3) {
            netconn_shutdown(tcpConnection, 1, 1);
            netconn_close(tcpConnection);
            state = 0;
        }

        if (state == 2)
            precessData(tcpConnection);
             
        chThdSleepMilliseconds(200);
    };
}

uint8_t tcpInit()
{
    ethThread = chThdCreateStatic(ethThread_wa, sizeof(ethThread_wa), NORMALPRIO, ethCommThread, NULL);
    return 0;
}