lwIP basic configuration in Keil MDK

RTOS integration

Beyond stack space, there are no special considerations for the CMSIS-RTOS v2 API

  • When using FreeRTOS native interface:
    • in RTOS/FreeRTOSConfig.h
      • add #define configUSE_POSIX_ERRNO 1 and #define configPRINTF printf
      • configure a minimum stack size (configMINIMAL_STACK_SIZE) of 256 words. The default of 128 may work in many situations but in others lwIP may not start.
    • in the project configuration (Project -> Options for Target 'Target 1'), in the C/C++ (AC6) tab we've added Misc Controls: -Wno-format-security to silence a warning due to the way lwIP handles its logging macro, that we've just set to use printf

lwIP integration

  • Add the proper libraries to the Run-Time Environment configuration; in the Run-Time Environment management window:

    • for CMSIS Driver, used as Ethernet driver: select CMSIS Driver -> Ethernet MAC (API) -> Ethernet MAC and CMSIS Driver -> Ethernet PHY (API) -> LAN8742A (check the correct PHY for your hardware, this one is the one used on the Nucleo boards)Keil MDK Manage Run-Time Environment
    • for lwIP itself:
      • set Network Variant as lwIP
      • set Network -> API
      • select Network -> Core and its Variant as IPv4 (or another variant with IPv6 support if you wish)
      • select Network -> RTOS and its Variant as your OS choice: CMSIS-RTOS2 for any RTOS with the CMSIS-RTOS v2 API (including FreeRTOS), or FreeRTOS for FreeRTOS native API
      • select Network -> Driver-> Ethernet and its Variant as CMSIS Driver
      • select Network -> Interface -> EthernetKeil MDK Manage Run-Time Environment
  • Then there are two config files we need to change according to our application:

    • In Network/ethif_config.h, using the Configuration Wizard, we can configure our MAC Address
    • In Network/lwipopts.h look for these macros and change them, or add those that do not exist, if any_
      • #define MEMP_NUM_NETCONN 10 - we'll be using several connections simultaneously; even though we are using the socket interface, internally lwIP uses a decoupling API called netconn, so we need to set the number of allowed connections high enough
      • #define LWIP_SOCKET 1
      • #define TCPIP_THREAD_STACKSIZE 1024
      • #define TCPIP_THREAD_PRIO - set to osPriorityNormal for CMSIS-RTOS API and to (configMAX_PRIORITIES - 1) for FreeRTOS native API
      • #define TCPIP_MBOX_SIZE 6
      • #define DEFAULT_THREAD_STACKSIZE 1024
      • #define DEFAULT_THREAD_PRIO - set to osPriorityNormal for CMSIS-RTOS API and to (configMAX_PRIORITIES - 1) for FreeRTOS native API
      • #define LWIP_SOCKET 1
  • Finally, in the project configuration (Project -> Options for Target 'Target 1'):

    • in the C/C++ (AC6) tab we've added Misc Controls: -Wno-implicit-int-conversion to silence a warning due to ethernetif.c having an uncasted conversion (this belongs to CMSIS-Driver)
    • for F7-based boards, in the Linker tab we've added Misc Controls: --diag_suppress 6918 to silence a warning due to padding on a RAM region (this also belongs to CMSIS-Driver)

We didn't change any other default parameters, this is just an approach; for serious work and performance, a tuning operation might be needed.


  • Create an app_main task
    • Initialize the network
    • Create a task to poll for link changes and to serve the ethernetif (or two tasks if you prefer)
    • Poll the IP address until it has a valid value
    • Create the server task to run Mongoose, and terminate.


If using FreeRTOS, do not loop but exit on task termination:

FreeRTOS native API: