[En-Nut-Discussion] Scheduling out of Interrupt sometimes take a timertick NAP
harald.kipp at egnite.de
Mon Mar 9 13:57:13 CET 2015
On 09.03.2015 12:35, Uwe Bonnes wrote:
> e.g.the STM32 Spi driver may be used DMA/interrupt driven. When transfer is
> finished, the interrupt routine signals the waiting thread via
> NutEventPostFromIrq(). The waiting thread then deasserts chipselect. This
> can be controlled good with a logic analyser. However I often see a gap of
> nearly exact 1 ms between the last sck toggle and the cs deassert.
I'd say that this is the a problem of the driver code. There is no
guaranteed time between NutEventPost... and the return from its
> I never
> saw such a gap with NutEventPost().
As long as other threads with same or higher priority are ready to run,
the scheduler will _immediately_ switch the thread on any call to
NutEventPost(). With NutEventPostFromIrq() this context switch is
delayed until the currently running thread releases the CPU. Btw. in
earlier releases this function was named NutEventPostAsync(), which IMHO
better reflects its behavior. This function is not limited to interrupt
Anyway, depending on your thread layout, NutEventPost() may show a
significant gap as well.
> These gaps substantial slows down
> effective SPI transfer rate, as, b.t.w. also does DMA/interrupt driven SPI
> transfers on small chunks with fast rate with regard to polling transfer
> due to additional scheduling round trips.
Definitely. I think, the AT91 SPI bus driver is the most advanced in
that sense. Wasn't it Ole, who implemented dynamic switching between
polling and DMA mode in the AT91 SPI driver?
The Nut/OS SPI bus drivers are a compromise. The intention is to have a
simple way to attach several devices to one single SPI bus without
hassle. Here it really shines. I've several sources which compile
flawlessly for several targets by just adding a different low level bus
Even the AT91 driver does not provide the optimal performance for
specific requirements. In such cases I typically create my own local
implementation, which doesn't need to be portable or configurable at all.
> Can anybody help debugging?
I'd suggest to check, which thread is running when the delay occurs.
Possibly one or two calls to NutThreadYield() may help.
If you really need maximum performance, it is probably easier to create
an STM32-specific SPI API, which makes use of double buffering and
hardware-controlled chips selects.
A global solution is of course most welcome, but may become bloated,
difficult to configure and hard to port to new platforms. Not mentioning
the time required to get it working as reliable as the current
More information about the En-Nut-Discussion