EngineeringSpirit / FreeLwIP-Nios-II

FreeRTOS with LwIP integration in the Nios II EDS
19 stars 28 forks source link

alt_printf() issue when trace facility enabled - system crash #11

Open modemo opened 10 years ago

modemo commented 10 years ago

Hi to everyone!

First of all, sorry for reporting as issue, but I wasn't sure, if you would be aware of issue, if I put in into my fork.

I sync my fork with yours dev branch, to keep me synchronization somehow :) I use latest commit (9ed192e28f72a8cb721235b8c0b8fb03d00e1ded) from dev branch and merge it with my fork. Seems ok in basic, but have issues, when using alt_printf() with trace facility enabled in FreeRTOS. Monitor task periodicly (20s) sends using UART JTAG (STDOUT) report about tasks and stacks (generated by vTaskList). After sending whole string with this alt_printf transfer, system crash and I found it in StackOverflow hook (task info is corrupted). But I think this is not problem related to stack. It has something to do with interupts during UART transmission. When I use option small driver (UART pollen, not interrupt driven) everythnig works ok. Any ideas how to find, what is the problem?

PS: I used port with mluthi's ignored interrupt context solution before.

Best regards, Modemo

modemo commented 9 years ago

With support from Percepio side, I probably found issue that cause problems with trace facility. In the Nios II port of FreeRTOS, portENTER_CRITICAL and portEXIT_CRITICAL are mapped to vTaskEnterCritical and vTaskExitCritical. Since events are traced in kernel interrupts, they are call from interrupt context, but vTaskEnterCritical and vTaskExitCritical are not safe to call from ISR.

There are 2 options:

I think, that changing nios2 port would be cleaner solution and resolution of possible bug. And also to avoid possible nesting interactions with FreeRTOS rutines.

MicroBlaze and NIOS2 are very simillar processor, I study port for MicroBlaze and it use something like this:

define portENTER_CRITICAL(){ \

extern UBaseType_t uxCriticalNesting;   \
microblaze_disable_interrupts();                    \
uxCriticalNesting++;                                \
}

define portEXIT_CRITICAL(){ \

extern UBaseType_t uxCriticalNesting;   \
/\* Interrupts are disabled, so we can _/            \
/_ access the variable directly. _/                 \
uxCriticalNesting--;                                \
if( uxCriticalNesting == 0 )            \
       {                                                    \
    /_ The nesting has unwound and we               \
    can enable interrupts again. */                 \
    portENABLE_INTERRUPTS();                        \
       }                                                    \
}

Wouldn't be better to use something like this also for nios2 port? Thank you for suggestions.