I took a quick look at these routines. I noticed that they lack
any type of "critical section" around where the queue data and
pointers are modified. Calling these routines as-is from an ISR
context and from a non-ISR context might result in race conditions
and odd, intermittent behavior.
Here's my critical section routines. The enter just pushes the
global interrupt state and then disables interrupts, the exit
pops the interrupt state. Observant list readers might note an
uncanny resemblance to NutOS's critical section code...
extern inline void utos_enter_cs(void)
{
asm volatile(
"in __tmp_reg__, __SREG__" "\n\t"
"push __tmp_reg__" "\n\t"
"cli" "\n\t"
);
}
extern inline void utos_exit_cs(void)
{
asm volatile(
"pop __tmp_reg__" "\n\t"
"out __SREG__, __tmp_reg__" "\n\t"
);
}
Since these routines push and pop from the stack, you have to be
careful to balance them within a function. I'll leave where to
insert them into the code as an exercise to the reader ;)