What's new in NIL4

In ChibiOS release 20.3.0 NIL has been upgraded to major version 4 and it is packed with new features and enhancements. Note that all new features are optional, the core NIL is not larger than previous versions, it just gained a growth path.

New Features

  • Full threading.
  • Event Sources.
  • Synchronous Messages.
  • RT API compatibility.
  • OS Library compatibility.

Full Threading

NIL3 was only able to spawn all its threads at startup. NIL4 cal still start threads at statup but, in addition, it can also start threads at runtime. Now thread are also able to terminate and be restarted using functions chThdExit() and chThdCreate(). It is also possible to synchronize with the termination of a thread using chThdWait().

Event Sources

The event flags in NIL3 have been enhanced with event_source_t and event_listener_t objects. Now threads can “register” on multiple event sources and handle events.

Synchronous Messages

A very fast inter-threads synchronous messaging system has been added. A thread can send a message to another thread then wait for an answer (synchronously, no queues).

RT API compatibility

The old API and the new features are fully compatible with RT. NIL4 can be seen as a subset of RT6. The two OSes are so compatible that now they share a single OSAL in order to interface with HAL.

OS Library compatibility

The new OS Library includes a lot of new extended functionalities, NIL4 is able to use this extension without problems.


NIL4 is not fully compatible with NIL3, there are some differences that need to be considered.

Source organization

NIL3 was composed by just two files: ch.h and ch.c. The new code base is larger so some mechanisms have been moved in separate source files for clarity: chevt.c, chevt.h, chsem.c, chsem.h, chmsg.c, chmsg.h.

Threads Table

The previous format was:

  THD_TABLE_ENTRY(waThread1, "blinker1", Thread1, NULL)
  THD_TABLE_ENTRY(waThread2, "blinker2", Thread2, NULL)
  THD_TABLE_ENTRY(waThread3, "tester",   Thread3, NULL)

The priority of threads was the position in the table, all threads were defined in the table,

The new table is organized as follow:

  THD_TABLE_THREAD(0, "blinker1", waThread1, Thread1, NULL)
  THD_TABLE_THREAD(1, "blinker2", waThread2, Thread2, NULL)
  THD_TABLE_THREAD(4, "tester",   waThread3, Thread3, NULL)

The difference are:

  • THD_TABLE_ENTRY has been renamed THD_TABLE_THREAD.
  • There is one extra parameter, the priority (it was implicit previously).
  • The order of parameter changed for readability but the parameters are the same.
  • Not all threads need to be defined in the table, more can be started at runtime using chThdCreate(). Note that the restriction on priorities still apply, only one thread can be created/defined at any given priority level. Starting/defining more threads at the same priority is an error.

Other Enhancements


New functions chSemResetWithMessage() and chSemResetWithMessageI() are available. Now it is possible to send any message when resetting a semaphore not just MSG_RESET. There are no compatibility issues with NIL3.


The Event-Source and Event-Listener paradigms have been implemented in addition to the “direct event flags” previously supported. There are no compatibility issues with NIL3.


When upgrading a ChibiOS component, like NIL, please remember to do the following:

  1. Use makefiles from the new version.
  2. Use startup files from the new version.
  3. Use linker scripts from the new version.
  4. Use configuration files from the new version (chconf.h in this case).