Answer deleted by a moderator — question mentions my project by name, and I disclosed authorship

LwIP vs Mongoose vs CycloneTCP on STM32: technical trade-offs for a resource-constrained project

I'm the author of Mongoose. The question asks for a comparison including Mongoose. I disclosed my affiliation in the first sentence, explicitly declined to argue the subjective parts, and limited myself to footprint figures, which are objectively measurable. The answer was deleted with no comment and I can't tell which guideline it fell foul of. What's needed for it to be acceptable?

Here is my deleted answer, unmodified:

I represent Mongoose, https://github.com/cesanta/mongoose. My opinion is biased, so I leave others to comment about the comparison, but let me cover the part that is objective: footprint. The throughput / latency heavily depends on the use case and environment, so the real test would be to implement the same functionality on all stacks and compare them head to head. So footprint. First of, any networking app consists of those parts:Driver (Ethernet frames) -> TCP/IP stack (IP/TCP/UDP/ICMP) -> TLS -> Application If we're talking about STM32s with a built-in MAC, then let's assume we're talking about Ethernet driver specifically. lwIP does not provide drivers. If you're using lwIP, then you rely on STM32 Cube Ethernet HAL driver. It is not part of lwIP. It has a history of issues, instability. Had recent rewrites, which may or may not got rid of them. You can take a look at this article https://mongoose.ws/articles/lwip-vs-mongoose-tcpip-stack-integration/ which has references to various drivers including Zephyr and Netx (not in your list) to build your own opinion. Both Mongoose and Cyclone do provide drivers. I won't comment about Mongoose's quality of code (cause I am one of the authors and of course Mongoose it is awesome), but I could tell that Cyclone's driver and overall, stack code is pretty descent, so if I were to choose between lwIP and Cyclone, I'd choose Cyclone - they are our competitors but it's fair to acknowledge. Cyclone is a quality software. The Ethernet driver on STM32 uses an array of DMA-accessible buffers for TX and RX, organised in a ring. The size and number of these buffers is configurable. By default, Mongoose uses 4 buffers for both TX and RX, 1500 bytes each, which gives 12Kb RAM footprint on a driver level. The buffer size of 1500 is chosen so that it can hold the whole Ethernet frame. The RX path is interrupt-based. When an interrupt arrives, the IRQ handler copies the received frame into the receive queue, which protects the stack from the sudden traffic bursts. The default size of the queue is 8 Kb (also confugurable). Small Ethernet frames are 60 bytes in size, so we can buffer > 100 frames before TCP/IP starts consuming them. TCP/IP stack's loop run by user code fetches frames from the queue: IRQ handler produces, TCP/IP stack consumes. So, another 8Kb on a driver level. Of course you can reduce the number of DMA buffers to 2 and reduce the size of the queue to 1.5 Kb to hold only one frame, seemingly reducing RAM footprint, but you'd pay the price of severe packet loss. The more RAM you put in DMA buffers and the queue, the more stable your stack against the packet loss during bursts will be. Mongoose's defaults are good for most conditions, so you don't need to worry about that stuff. Then, on the TCP level, Mongoose does not use socket with its own buffers - so it avoids double-buffering. In this sense it is quite similar on the lwip's Netconn API. You have asked about API comparison
  • so lwIP has 3 APIs:
raw: callback based, can be used in RTOS and no RTOS env netconn, built on raw, connection-oriented, can be used in RTOS and no RTOS env BSD sockets, RTOS only. See "BSD API explained" https://www.youtube.com/watch?v=pp9AM5A1mDs So Mongoose's API is similar to lwIP's netconn API, and it can be used in both RTOS and no-RTOS environments. Examples are at https://github.com/cesanta/mongoose/tree/master/tutorials/stm32, the "minimal" examples do not use any framework, just CMSIS headers, so are really minimal and you can use them for a quick benchmarks. On that level, the RAM footprint is what each connection takes. It is driven by the compile time constant MG_IO_SIZE, which is set to 512 bytes by default and sets allocation granularity for incoming and outgoing data. Usually a connection takes about few Kb RAM - also depends on the application layer. To summarise:RAM: Driver level: 12Kb + 8Kb = 20Kb, plus few Kb per connection.Flash: about 50Kb If you use TLS, Mongoose provides its own stack too (but can use mbed or wolf), and that also adds:RAM: several Kb, but spikes at TLS handshake for cert loads.Flash: about 60Kb There is a 2 hour video, full Mongoose TCP/IP stack walk through https://www.youtube.com/watch?v=x5Uy-CIz33k which explains almost every bit, and is useful even if you won't use Mongoose, cause many things apply to any stack. Also I'd recommend to watch "STM32 Ethernet explained" https://www.youtube.com/watch?v=6kHYvFjeuaQ, with an associated article at https://mongoose.ws/articles/stm32-ethernet-explained/ If you use Cube, I recommend this ST Knowledge Base article on how to spin Mongoose on a CubeMX project: https://community.st.com/stm32-mcus-60/stm32h7-ethernet-with-mongoose-getting-started-guide-165096 Maintenance - you can always reach to us, developers, directly, by filing an issue or discussion at github.com/cesanta/mongoose or by scheduling a tech no-strings-attached VC call at https://mongoose.ws, so you have an authoritative help at any time. Commercial customers have SLA and security alerts with fixes 1 month before CVEs get public. That said, the TCP/IP stack API does not matter much. It is either BSD or proprietary (like NetX, or lwIP netconn, or Mongoose). Integrating any stack is not a big deal. What matters is the API to build your application. How simple / complex your application ends up, that what matters most. How many external pieces, like Websocket / JSON / MQTT / OTA / rollbacks / crashdump reports / digital signatures you need to stitch to you app. For example, to wire a more or less professional Web UI, you need tons on top of TCP/IP stack, and that is where things get hairy. Even if you're using AI, the more movings parts you have, the more fragile your app becomes. Mongoose is good in this regard: it has only two files, and mongoose.h has docstrings that describe all API functions, so it's easy for AI to produce error-free code. These days AI just spits lwIP based code (cause lwIP dominates AI training data) and people go ahead with it, to pay the maintenance and forensics costs later. If your app is anything more complex than TCP echo, your simple quick TCP echo or HTTP hello world benchmark won't reflect the reality, cause frameworks you're considering is more than just TCP/IP stacks, some of them are far beyond. Hope that helps!
添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论