lwIP – 경량 IP 스택
(nongnu.org)- 임베디드 장치에서도 TCP/IP를 올릴 수 있도록, lwIP 2.1.0은 TCP/IP 프로토콜 제품군을 작은 독립 구현체로 제공함
- 수십 KB RAM과 약 40KB 코드 ROM 수준의 환경을 겨냥하면서도 완전한 규모의 TCP를 제공하는 데 초점을 둠
- 지원 범위는 IPv4/IPv6, ICMP, IGMP, MLD, IPv6 Neighbor Discovery, DHCP, UDP, TCP, raw/native API, Berkeley식 socket API, altcp, PPP, DNS, 6LoWPAN까지 넓음
- 기본 제공 애플리케이션으로 HTTP 서버, SNMPv2c 에이전트, SNTP, NetBIOS 이름 서비스 응답기, mDNS 응답기, iPerf 서버, MQTT 클라이언트가 포함됨
- BSD 라이선스로 제공되며, Savannah의 Git 저장소와 메일링 리스트를 통해 전 세계 개발자 네트워크가 개발·유지보수함
임베디드용 TCP/IP 스택 설계
- lwIP는 TCP/IP 프로토콜 제품군의 작은 독립 구현체임
- 설계 목표는 RAM 사용량 절감과 완전한 규모의 TCP 제공을 함께 달성하는 것임
- 수십 KB의 여유 RAM이 있는 임베디드 시스템에 적합함
- 코드 ROM은 약 40KB 공간을 전제로 함
- 원래 Adam Dunkels가 Swedish Institute of Computer Science의 Computer and Networks Architectures lab에서 개발했으며, 현재는 전 세계 개발자 네트워크가 유지보수함
-
네트워크 프로토콜과 API
- IP 계층은 IPv4와 IPv6를 지원하고, 여러 네트워크 인터페이스 간 패킷 포워딩도 가능함
- 네트워크 유지보수와 디버깅에는 ICMP를, 멀티캐스트 트래픽 관리에는 IGMP를 제공함
- IPv6 관련 기능으로 MLD와 ND를 포함함
- MLD는 RFC 2710 준수를 목표로 하지만 MLDv2는 지원하지 않음
- ND는 RFC 4861 Neighbor Discovery와 RFC 4862 주소 자동 설정 준수를 목표로 함
- 주소 설정과 이름 해석 기능으로 DHCP, AutoIP/APIPA, stateless DHCPv6, DNS, mDNS를 제공함
- 전송 계층은 UDP와 TCP를 포함함
- UDP는 실험적 UDP-lite 확장을 포함함
- TCP는 혼잡 제어, RTT 추정, fast recovery, fast retransmit, SACK 전송을 지원함
- API와 확장 기능으로 raw/native API, 선택적 Berkeley식 socket API, 선택적 계층형 TCP altcp, PPPoS, PPPoE, 6LoWPAN을 지원함
- altcp는 TCP 기반 프로토콜에 거의 투명한 TLS를 제공함
-
포함 애플리케이션
- HTTP 서버는 SSI와 CGI를 지원하며, HTTPS는 altcp를 통해 제공됨
- SNMPv2c 에이전트는 MIB 컴파일러를 포함하고, v3는 altcp를 통해 제공됨
- SNTP, NetBIOS 이름 서비스 응답기, mDNS 응답기를 포함함
- iPerf 서버 구현과 MQTT 클라이언트를 포함하며, MQTT의 TLS 지원은 altcp를 통해 제공됨
개발 참여와 문서
- lwIP는 BSD 라이선스로 자유롭게 제공됨
- 개발은 Savannah에서 호스팅되며, Savannah 인터페이스, Git, 메일링 리스트를 통해 개선에 참여할 수 있음
- 핵심 개발팀이 Git 소스 트리에 변경 사항을 커밋함
- TCP/IP 스택은
lwipGit 모듈에서 유지됨 - 플랫폼 포트 같은 기여는
contribGit 모듈에 있음
- TCP/IP 스택은
- 현재 Git 트리는 웹에서 열람 가능함
- 패치와 버그는 lwIP project page를 통해 제출함
- 지속적 통합 빌드는 GCC와 clang을 대상으로 Travis CI에서 제공됨
- 소스 코드의 자체 문서는 현재 Git 소스에서 정기적으로 추출되어 lwIP 웹 페이지에서 제공됨
- 문서와 학습 자료는 wiki, 메일링 리스트, 검색 가능한 아카이브,
docs/파일, 소스 코드 문서에서 확인할 수 있음
댓글과 토론
Hacker News 의견들
-
IP 스택이라고만 하기엔 꽤 절제된 표현임. HTTP 클라이언트, HTTP 서버, MQTT 클라이언트로 쓸 만큼 들어 있고, 실제로도 그렇게 쓰는 걸 봤음
임베디드 네트워킹의 busybox에 더 가깝지만, 라이선스는 훨씬 쓰기 편함 -
몇 년 전 프로젝트에서 LwIP를 썼고, 시스템 테스트를 꽤 좋은 방식으로 구성했음
여러 마이크로컨트롤러가 내부 LAN으로 통신하는 프로젝트였고, 작은 임베디드 커널인 MicroCOS 위에 LwIP를 IP 스택으로 올렸음
크로스 플랫폼 빌드 도구를 갖춰서 독립 실행형 마이크로프로세서 애플리케이션을 네이티브 실행용으로도, gcc로 x64 실행 파일로도 빌드할 수 있었음. 후자의 경우 LwIP의 최하위 링크 계층을 표준 TCP/IP를 쓰는 목(mock)으로 구현했고, 작은 TCP 서버를 띄운 뒤 마이크로컨트롤러 애플리케이션들이 개발자 머신에서 실제 시스템 안에서 도는 것처럼 서로 통신하게 했음
이 구성이 아주 잘 동작해서 프로젝트 개발 기간 동안 몇 년간 사용했음 -
LwIP 같은 선택지를 찾는다면 NetXDuo와 그 짝인 ThreadX, FileX, LevelX, UsbX도 고려할 만함. 나는 UsbX 대신 TinyUSB를 씀
아마 20년쯤 상용 RTOS 네트워크 스택의 상위권에 있던 것 같고, 몇 번 주인이 바뀐 뒤 지금은 Eclipse Foundation이 지원하며 MIT 라이선스임. 나라면 LwIP보다 이걸 쓰겠음
https://github.com/eclipse-threadx/netxduo- ThreadX와 관련 프로젝트들이 이제 MIT 라이선스라는 점이 아주 좋음. 인수와 오픈소스화 전에도 ThreadX와 NetX를 꽤 썼고, 전반적으로 사용감이 좋았음
TX는 API와 시스템 설계, 구현이 단단해서 쓰기 좋음. 예전에 NetX BSD 소켓 계층에서 애매한 버그를 몇 개 만나 내부에서 고쳤던 기억이 나는데, 너무 오래돼 세부사항은 찾기 어렵지만 이제는 수정 사항을 업스트림하기 쉬워져서 좋음
- ThreadX와 관련 프로젝트들이 이제 MIT 라이선스라는 점이 아주 좋음. 인수와 오픈소스화 전에도 ThreadX와 NetX를 꽤 썼고, 전반적으로 사용감이 좋았음
-
Adam Dunkels는 Protothreads도 대부분 작성했음. https://dunkels.com/adam/pt/
- 그는 LwIP보다도 더 작은 Contiki OS용 TCP/IP 스택 uIP도 작성했음
https://en.wikipedia.org/wiki/UIP_(software)
- 그는 LwIP보다도 더 작은 Contiki OS용 TCP/IP 스택 uIP도 작성했음
-
nongnu.org가 무엇이고 gnu.org와 어떤 관계인지 궁금했는데, 답을 찾았음
http://savannah.gnu.org 는 Free Software Foundation이 후원하는 “공식” GNU 소프트웨어 호스팅 사이트이고, http://savannah.nongnu.org 는 FSF가 후원하지 않는 “커뮤니티” 프로젝트용 호스팅 사이트라고 함
https://news.ycombinator.com/item?id=11747093 -
LwIP가 자원 제약 장치에서 가장 많이 쓰이는 TCP/IP 스택일 것 같음. 다만 오랫동안 제대로 된 대안이 없어 보였고, https://github.com/FreeRTOS/FreeRTOS-Plus-TCP는 유망해 보임
- 품질 좋은 대안도 있음. ThreadX의 NetXDuo는 한동안 오픈소스였고, Zephyr도 자체 스택을 제공함
- LWIP는 FreeRTOS 스케줄러와 꽤 잘 통합됨. 예전에 그 조합을 써봤는데, “plus-TCP” 스택은 비교하면 어떤지 궁금함
-
LWIP가 좋은 이유는 패킷의 생애 동안 Ethernet MAC DMA가 할당한 같은 메모리 블록을 계속 쓸 수 있게 해주기 때문임
사용 사례에 맞게 메모리 풀을 꽤 최적화해서 memcpy 횟수를 줄일 수 있음 -
직접 경량 TCP/IP 스택을 구현해보고 싶다면 Jeremy Bentham의 책 TCP/IP Lean이 훌륭한 자료임
-
글에 따르면 LwIP는 “수십 KB의 여유 RAM과 약 40KB의 코드 ROM 공간이 있는 임베디드 시스템에 적합하다”고 함
- 내장 Ethernet MAC 주변장치가 있는 Cortex M4에서 돌려봤는데, 통합이 놀랄 만큼 단순했음
기본적으로 패킷을 LwIP 스택에 넘기는 수신 ISR과, LwIP 스택이 패킷 전송에 호출할 수 있는 송신 함수만 설정하면 됐음 - LwIP는 인기 있는 ESP32 장치용 Espressif ESP-IDF 프레임워크의 일부임
이 플랫폼에서 몇 년간 LwIP를 써왔고 동작은 하지만, 여전히 원하는 것보다 메모리를 더 많이 먹음. 다행히 이제는 RAM 2MB짜리 ESP32 장치가 있음
- 내장 Ethernet MAC 주변장치가 있는 Cortex M4에서 돌려봤는데, 통합이 놀랄 만큼 단순했음
-
Pico W가 이걸 쓰는 게 맞나? https://github.com/raspberrypi/pico-examples/blob/master/pic...