[En-Nut-Discussion] Move NutLoadConfig() into main thread?

Philipp Burch phip at hb9etc.ch
Sun Nov 2 20:40:41 CET 2014


Hi everyone,

I'm using an I2C EEPROM as non-volatile storage on my board. Since
Nut/OS and/or Nut/Net already contain functionality for
platform-independent storage of system configuration data, I'd like to
use that of course. I've now written a device driver for the EEPROM
(type 24AA02E48, this also contains a unique identifier for use as
Ethernet MAC) and integrated it into nvmem.c, so the memory can be
transparently accessed from the OS and from application code. A patch
for it will follow soon, this could probably be integrated into trunk.

But I also needed a workaround/hack in my I2C driver to make that stuff
work. The problem is that NutLoadConfig() is called during system
initialization from the idle loop. The driver normally is
interrupt-driven and waits for an event using NutEventWait(), but this
crashes when called from the idle thread (NutThreadSwitch() causes a
BusFault on the Cortex-M4). The workaround now is for the I2C driver to
check if it is called from the idle thread and if so, fall back to
busy-waiting instead of using event queues. This makes it work, but is
ugly, inefficient and platform-dependent.

So my question is if it would be possible to move the initial call to
NutLoadConfig() from the idle thread into the main thread. Another
solution would be to make NutEventWait() or NutThreadSwitch() aware of
calls from the idle thread, so that it either busy-waits for the event
or immediately returns. I have to admit, however, that I don't know
enough about the Nut/OS and scheduler internals to justify if any of
those would be a sensible solution.

Oh, and I found the passage with the call to NutLoadConfig() in
<arch/cm3/os/nutinit.c> quite interesting:

//...
#define HEARTBEAT_ACTIVE()
#define HEARTBEAT_IDLE()
#endif
    /* Read OS configuration from non-volatile memory. We can't do this
    ** earlier, because the low level driver may be interrupt driven. */
    NutLoadConfig();

#ifdef NUT_INIT_MAIN
    NutMainInit();
#error main
#endif
//...

1. The comment seems to state that exactly that should work what I'm
doing here, but it doesn't.
2. Enabling NUT_INIT_MAIN obviously always causes a compiler error, why
is that?

Please feel free to comment on any of my statements/suggestions/thoughts
here, I'm probably just doing something stupid, which should be done
entirely differently.

Thanks and best regards,
Philipp


More information about the En-Nut-Discussion mailing list