This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

lwip socket mqtt freertos

Hello,

I am possibly in over my head on this, but I am hoping someone can help fill in some blanks for me.

The end goal is to have the tm4c1294 launchpad device running FreeeRTOS connect to a mqtt broker as a client and publish some data. I have freertos running, grabbing data, blinking lights etc. I am working on the internet connectivity part. 

Using lwip and some of the examples I have the board successfully pulling an ip from dhcp. I am now stuck on creating a tcp socket to pass mqtt messages to a broker. I am planning on using the paho mqtt library. It does require some of the low level socket connection commands to be handled. 

I am possibly naive, but I was assuming changing "LWIP_SOCKET" to "1" would allow me to access the api calls to setup a socket. This introduced 100+ errors. What am I missing? I have been searching the web for examples, but to my understanding, as long as I follow the api calls in tivaware/third_party/lwip-1.4.1-src-api, I should be good right? In order to use the socket apis I need to change my lwipopts.h header correct? 

Thanks!

  • TM4C port of lwIP does not support BSD sockets style APIs.

    Unlike the sockets APIs (which are sequential), the lwIP raw APIs are interrupt based. I am not sure how much effort would be required to make the low level paho mqtt library to work with these raw APIs.

    As far as TCP code goes, this link has some sample lwIP applications. The "tcpecho_raw" implements a TCP server that echos back packets to the TCP client.

    The "freertos_demo" in the folder "/examples/boards/dk-tm4c129x/freertos_demo" implements a HTTP server (based on lwIP). This code can be used as the base application and the HTTP server part can be replaced with "tcpecho_raw" to implement a tcp example with FreeRTOS.

    Thanks,

    Sai

  • Hi Sai. Thank you for your answer. It explains a lot. Is it just me or is it misleading to have api documents included with lwip, and have features in there that aren't supported? Was there documentation that states this isn't supported or is it just common knowledge? Is there any work being done on getting this supported, or is there a different way to get socket support?

    I'll be playing with the raw api calls and see what I can come up with. More questions to come!
  • Re-writing a sockets app in the lwIP stack requires a different approach. The TI S3E sample code from the previous generation contains a telnet-uart example thats a good start. Socket support on lwIP requires a pile of infrastructure software that isn't there and is more of an RTOS thing.

    The lwIP wikia pages contain plenty of info on using the raw/tcp interface. You can probably build a shim layer that will do what you want so that the existing code isn't any wiser, ie, a fake open() and write() interface that will splice it all together.

    The single biggest change with the Raw/TCP interface that you'll have to accomodate is that in lwIP, you must be prepared to re-try, rather than letting the networking stack do it for you.
  • What do you mean by it is a "RTOS thing"? Are you inferring that sockets should be handled by an rtos task? I also don't understand how how socket support requires a pile of infrastructure. The wiki site you point me to has api support for sockets. Is it that it hasn't been ported for tiva products?

    I will start looking into a shim layer. This will work for this quick and dirty prototype but it doesn't sit well with me moving forward.

    How are people doing sockets on a tiva product? I find it hard to believe I am the only one that wants to do this.
  • In order to have a real socket interface, you need to have threads or tasks. A socket interface requires that the program block when you perform a blocking operation such as read(). In an OS situation, you get a context switch when you call read(). The OS then decides that there is no data for you, and saves your thread/task context and lets another one run. When some data appears on the socket that has the pending read(), the OS then wakes the task/thread and the scheduler starts it up. uIP (micro-ip) uses proto-threads for this. Thats a form of fakery - its sort of like threads, but not really.

    The key point is that this all transparent to the programmer with an actual socket interface.

    So yes, sockets are a RTOS/OS thing. If you want to use a true socket interface you'll also need to use some sort of an OS that is capable of task-switching. This isn't a high bar. They're out there.

    lwIP is a much lighter/minimalist stack and as a result it puts more burden on the programmer. For instance, write() can fail - you have to re-try. The stack calls your function when you have data on your port. Its a significantly different approach than Berkely sockets.

    There is an added complication with lwIP in that you can't re-try with a function thats called by lwIP in the first place - you'll starve the ethernet interrupt handler. Solving that is pretty involved, too much for here.
  • Hi Sai,

    What do you mean by saying "TM4C port of lwIP does not support BSD sockets style APIs."

    And what kind of work should be done if I want to use lwip+freertos on TM4C129X EVB?

    Thanks a lot !