Mbed3 diving into network

November 1, 2015

mbed-example-network

After a couple of days struggling and fixing things (I sent another pull request fixing a #warning in mbed-hal-ksdk-mcu), today I can look at the actual mbed3 examples without build errors (Mbed / me not setting target) or missing libraries (Fedora).

So the first thing was leave mbed-client-examples, which is aimed at their cloud protocol / servers, and checkout the git version of mbed-example-network, which is aimed at generic network activity.

He builds four examples, the most interesting for me of which is "helloworld-tcpclient.bin". This does one fixed thing using "by hand" http directly on the socket. The one fixed thing is reach out to (the old...) server and fetch some text... surprisingly enough "Hello world!".


TCP client IP Address is 192.168.2.205
Starting DNS lookup for developer.mbed.org
DNS Response Received:
developer.mbed.org: 217.140.101.30
Connecting to 217.140.101.30:80
Connected to 217.140.101.30:80
Sending HTTP Get Request...
HTTP Response received.
HTTP: Received 473 chars from server
HTTP: Received 200 OK status ... [OK]
HTTP: Received 'Hello world!' status ... [OK]
HTTP: Received message:

HTTP/1.1 200 OK
Server: nginx/1.7.10
Date: Sun, 01 Nov 2015 00:42:37 GMT
Content-Type: text/plain
Content-Length: 14
Connection: keep-alive
Last-Modified: Fri, 27 Jul 2012 13:30:34 GMT
Accept-Ranges: bytes
Cache-Control: max-age=36000
Expires: Sun, 01 Nov 2015 10:42:37 GMT
X-Upstream-L3: 172.17.42.1:8080
X-Upstream-L2: developer-sjc-indigo-1-nginx
X-Upstream-L1-next-hop: 217.140.101.34:8001
X-Upstream-L1: developer-sjc-indigo-border-nginx

Hello world!


That worked great. But not until you read the source and saw that unlike mbed-client-examples, this code, I guess ported from earlier mbed, sets the serial port for 115200.

void app_start(int argc, char *argv[]) {
    (void) argc;
    (void) argv;
    static Serial pc(USBTX, USBRX);
    pc.baud(115200);
...

The other app defaults to 9600, at least on the one recommended supported board, K64F. So you will see nothing switching between these apps even though they are both official example apps.

I made a bug about it on the github project and offered to send a fix

https://github.com/ARMmbed/mbed-client-examples/issues/32

Three notable things

1) It's C++

Although you can write mainly in C, you have no choice but to frame it inside C++, because mbed3 apis themselves are in C++

2) The callbacks are sophisticated

In app_start(), which is the mbed3 equivalent of main(), he instantiates some things and then immediately goes back to the scheduler (minar) after scheduling a callback to start the test. It's what you would do in a generic event loop, set the state for the next thing you want and then return to the event loop.

The callback also has a specific object instantiation associated with it. They also have some ghetto varargs where you can fix how many args the callback wants and have that delivered at callback time.

    mbed::util::FunctionPointer1<void, const char*> fp(hello, &HelloHTTP::startTest);
    minar::Scheduler::postCallback(fp.bind(HTTP_PATH));

So it's basically doing schedule_the_callback(callback_t cb, void *context, ...); in two steps. Since it's mandatory to be defining callbacks a lot, I guess this will be very handy once you get used to it. But it's a C++ believer's way (C would have a state enum, and a switch() to do the callback work).

3) The class hierarchy for Socket is cool, send is unposixy

There is a TCPStream class which understands TCP connection state, and fires events as they change (bear in mind though, all events are serialized and never preempt other event handlers). TCPStream has a few carefully-chosen apis

He also inherits from the Socket class (this is nicely done)

So particularly the send flow has a critical deviation from posix... it's not a ding, these SoCs have way less resources and a different OS architecture than assumed in posix. But for example even though libwebsockets is otherwise quite compatible with mbed3, being singlethreaded and nonblocking, he assumes in many places he can do things like make a buffer on the stack, "send" it, and exit the function, as you can do in posix. So that requires some thought.

What we learned this time

Next post about mbed