I've run PPP on LwIP (STM32 based, using a Telit LTE module).
It was pretty challenging to get set up and running due to the lack of documentation, both in-code and "official."
In a nutshell though, you implement an sio_write() routine which takes data from LwIP's PPP driver and puts it to hardware. Anything coming from the serial link gets delivered to pppos_input(). That takes care of the link between the hardware and the PPP implementation. That's the easy part. :-)
From there you're in a state machine of your own design. I had the following states:
* INIT: call pppInit(), jumps to DISCONNECTED state
* DISCONNECTING: call pppLinkTerminated() and pppClose() to reset things, jumps to DISCONNECTED
* DISCONNECTED: does nothing until the higher-level code wants to start a connection (jumps to START)
* START: calls pppSetAuth() and pppOverSerialOpen(), jumps to CONNECTING
* CONNECTING: runs lwip_loop() until you either get a connection (from the link status callback which sets the state to CONNECTED) or drops back to DISCONNECTING to close up and try again
* CONNECTED: runs lwip_loop() until your higher level code decides it wants to tear the link down.
What's lwip_loop() I hear you ask? it's the dumb routine that shuttles data received from the serial link to pppos_input(). The routine also handled the periodic call to sys_check_timeout() which is an LwIP function that handles all the IP (including PPP) timeouts. You might design your architecture differently.
This code was able to establish and maintain PPP links for *days* over the cell network, and correctly re-established the connection if the link dropped (either through a remote disconnection or my disconnecting the antenna to test). My code did a fair bit more too (GPS, autobaud, dialing, selecting a carrier, maintaining link info, SMS, battery level, etc.) but none of those are important to PPP and LwIP.
Good luck!