1

I am struggling (like many others it seems) to get started with LwIP over PPPos (ppp over serial) for STM32. I could have ended that sentence earlier, because even without PPPos I am having a hard time understanding where to start.

I have read, and read, and read. Their official home page, wiki, tons of forums, and trying to digest github examples for other platforms. But still I am having a hard time to have a clue where to start.

There seem to be little (none?) examples on this online taking me through the whole process. And I really don't get it. The IoT world is exploding. So I really thought it would be "easy" to have some hello world example.

What I have at the moment:

  • An LTE modem which I can use via AT commands
  • A small application which runs on my nucleo (F446ze) board which can blink LEDs, communicate over UART3 with my PC, and UART2 with the LTE modem
  • Played around with free RTOS, that part was surprisingly easy to familiarize

But instead of clumsy internet communication using AT commands (and AT+CMQTT commands) I want to rely on a proper TCP/IP stack. Set the LTE modem in data mode (PPP), and have LwIP take over the TCP/IP stack.

Is this still very complicated anno 2021? Or am I completely looking in the wrong direction? Is there anybody who can point me in the right direction?

I already have freertos working too. I don't mind to use it. I also don't mind to go without. I am just looking for a way to get started with LwIP without having to reverse engineer the LwIP stack completely.

bas
  • 13,550
  • 20
  • 69
  • 146

1 Answers1

4

Going top-to-bottom, you have your application code which in the end will likely want to talk to some server: resolve DNS name, open a tcp connection etc. This is what LwIP provides - a set of API functions: socket functions, DNS functions and other. For example, when you do a TCP socket connect to a given IP address and port, it decides which out of available network interfaces to use, constructs a frame in form of array of bytes and sends those bytes over that interface. This is where LwIP part ends - it requesting given network interface to output X bytes it provides, as well as consuming any bytes that may arrive on that interface. It doesn't know how exactly to make the bytes "come out", but it knows how to construct the data to send and understands the data you give it.

Going bottom-to-top, you have your modem - LTE, 3G, 2G, doesn't really matter. Modems provide a set of AT commands to talk to them to perform a set of functions: set SIM card PIN, get signal quality, list available operators, select an operator etc., as well as a way to switch it to PPP mode, which also done ATD command. Assuming the modem has been configured properly before, once you switch it to PPP mode it'll be able to send data using PPP protocol and will also "spit out" any data it receives. This is where the modem part ends - when switched to PPP mode, the modem is able to send and receive raw network traffic using PPP protocol. It knows how to output the raw bytes you give it, but it doesn't understand them on a very high level.

Your role is to connect (interface) both parts. Your modem uses PPP to produce and consume network traffic. LwIP has the capability to understand and produce PPP frames.

In case of sending data out, after preparing a PPP frame LwIP is going to call the sio_write function that is expected to send provided bytes to modem that's already in PPP mode. This is the part that you need to fill in. In case of reads sio_read is used and it's your job to fill it in so that it returns bytes that were received from the modem. How you're going to do that - using RTOS and queues for bytes, no RTOS or any other way - doesn't matter. It's what you find more convenient or what fits your overall project structure better. As long as those functions do what they're supposed to, LwIP will be happy to use them.

This interfacing is discussed in more detail here: https://lwip.fandom.com/wiki/PPP#PPP_over_serial. Again, the general concept is that LwIP is just a software library and in the end it'll want to send and receive bytes. Your job is enabling it to do so, by filling in the functions it expects.

J_S
  • 2,985
  • 3
  • 15
  • 38
  • Hi Jacek, thx for the very detailed answer. I hope it is clear to you that I have a hard time figuring out how to integrate LwIP and configure it for my needs. I can simply clone their archive and integrate it in my project. I'm sure it will build. But then then what? Should I just implement the sio_read and sio_write method and supply every byte I receive from my uart port and things will magically work? I read that I need to modify quite a bit of configuration. Or am I making up obstacles? I think I'm just really hesitant to get started, lacking confidence. – bas Apr 12 '21 at 09:48
  • Well, you need to configure both "sides" first. For modem this means that you need to send correct AT commands in order to make it switch to PPP mode that actually works (SIM pin given correctly, correct APN is used etc.). For LwIP on the other hand it means that the stack itself is initialized, has network interface added, the interface is configured and so on. This is much beyond the scope of this answer, as it's basically asking "how to get started with modem" and "how to get started with LwIP". I only touched on the part where you integrate both parts that are already in a correct state. – J_S Apr 12 '21 at 10:03
  • Then I am not making myself clear enough in the question. I am capable of setting the modem in PPP mode. I just have little understanding of what to do afterwards in configuring LwIP to pick up the bytes and allow me to open sockets and send/receive TCP/IP messages. Can you help me there? Which steps should I do? Preferably with some small examples code would really make a difference – bas Apr 12 '21 at 11:17
  • Everything described in the URL I've linked above. Sample LwIP configuration is in section [Example Task Application code](https://lwip.fandom.com/wiki/PPP#Example_Task_Application_code). Implementation details of `sio_write` and `sio_read` are given at the start of the [PPP over serial](https://lwip.fandom.com/wiki/PPP#PPP_over_serial) section. – J_S Apr 12 '21 at 11:24
  • Ah, now I am starting to see where my mind took the wrong turn... E.g. `u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len);` I thought **I** was supposed to call that function. But LwIP will call it, I only have to implement what it should do. So assuming I have my PPP connection activated, all I have to do in the implementation is to send over the data? – bas Apr 12 '21 at 11:40
  • Exactly. That's the functions LwIP calls. – J_S Apr 12 '21 at 11:54
  • OK, thx for the time and efforts here! I will start my journey and see how far I get – bas Apr 12 '21 at 12:16