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

Philipp Burch phip at hb9etc.ch
Tue Nov 4 21:48:49 CET 2014


Any other comments/suggestions/thoughts on this?

Regards,
Philipp

On 02.11.2014 22:39, Philipp Burch wrote:
> Hi Uwe!
> 
> On 02.11.2014 21:37, Uwe Bonnes wrote:
>>>>>>> "Philipp" == Philipp Burch <phip at hb9etc.ch> writes:
>>
>>     Philipp> Hi everyone, I'm using an I2C EEPROM as non-volatile storage on
>>     Philipp> my board. Since Nut/OS and/or Nut/Net already contain
>> ...
>>     Philipp> But I also needed a workaround/hack in my I2C driver to make
>>     Philipp> that stuff work. The problem is that NutLoadConfig() is called
>>     Philipp> during system initialization from the idle loop. The driver
>>     Philipp> normally is interrupt-driven and waits for an event using
>>     Philipp> NutEventWait(), but this crashes when called from the idle
>>     Philipp> thread (NutThreadSwitch() causes a BusFault on the
>>     Philipp> Cortex-M4). 
>>
>> Unexpected crashed often result from a stack to small. Did you try with more
>> stack space?
> 
> Stack size for both idle and main is set to 4096 bytes, which should be
> far more than is required.
> Single-stepping with the debugger revealed that when NutThreadSwitch()
> is called, the global runQueue is 0 (NULL). What then follows is
> 
> //...
>     /* Select thread on top of the run queue. */
>     runningThread = runQueue;
>     runningThread->td_state = TDS_RUNNING;
> //...
> 
> and this surprisingly doesn't fault. I don't really understand that, as
> the second line is a write directly into flash space (address 0x15
> according to the debugger). But in the next inline-ASM block, the last
> instruction to restore the registers crashes:
> 
> //...
>     /* Restore context. */
> #if       (__CORTEX_M >= 0x03)
>      __asm__ __volatile__(              /* */
>         "@ Load context\n\t"            /* */
>         "ldr     sp, %0\n\t"            /* Restore stack pointer. */
> 
> #if defined (MCU_USE_CORTEX_FPU)
>         "ldmfd   sp!, {r4}\n\t"         /* Get saved FPU status... */
> 
>         "vmsr    fpscr, r4\n\t"         /* ...and save back. */
>         "vpop    {s16-s31}\n\t"         /* Restore FPU registers. */
> #endif
> 
>         "ldmfd   sp!, {r4}\n\t"         /* Get saved status... */
>         "msr     xpsr_nzcvq, r4\n\t"   /* ...and save execution and
> application status in psr. */
>         "cpsie   i\n\t"                 /* ...enable interrupts */
>         "ldmfd   sp!, {r4-r11, pc}\n\t" /* Restore registers. */
>         ::"m"(runningThread->td_sp)     /* */
>     );
> //...
> 
> Seeking for the cause of runQueue being 0, I found the NutEventWait()
> function. Unless the queue has been signaled, program flow continues
> along the lines
> 
> //...
>     /*
>      * Remove the current thread from the list of running threads
>      * and add it to the specified queue.
>      */
>     NutThreadRemoveQueue(runningThread, &runQueue);
>     NutThreadAddPriQueue(runningThread, (NUTTHREADINFO **) qhp);
> //...
> 
> The first line makes runQueue 0x0 and the second one doesn't change
> that. I think this is basically correct operation, but then
> NutThreadResume() should not try to switch to the next thread in the
> runQueue when it is empty.
> 
> Cheers,
> Philipp
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
> 


More information about the En-Nut-Discussion mailing list