FreeRTOS hangs in vListInsert

Hi, since some days I am stuck in a very indeterministic problem. I am working on an LM3S8962 evaluation board. Using the arm-none-eabi-gcc (Sourcery G++ Lite 2008q1-126) 4.2.3 and arm-none-eabi-g++. I wrote a c++ wrapper for FreeRTOS which is working fine (I did a test running several tasks using semaphore and queues to communicate and the UART1 for output, which is running stable since a week). However, I have a serious problem with receiving from the UART. I implemented an interrupt handle for my UART that is sending a message to a queue when a string has been send to the uart ending with a newline or escape char. The message is received in a task that I stripped so much down, that it is basically doing nothing but receiving this message. This works for some seconds sometimes several minutes up to over half an hour (I am continously sending a message of 8 bytes to the UART and the frequency of the message or the baud rate does not matter, I tested several setups). But than it stops in an endless loop trying to add the task to the eventlist. Here the debug trace:         Thread [0] (Suspended: Signal ‘SIGINT’ received. Description: Interrupt.)                6 vListInsert() /home/szymansk/workspace/SymbricatorRTOS/FreeRTOS503/list.c:130 0x00012334                5 vTaskPlaceOnEventList() /home/szymansk/workspace/SymbricatorRTOS/FreeRTOS503/tasks.c:1494 0x0001392a                4 xQueueGenericReceive() /home/szymansk/workspace/SymbricatorRTOS/FreeRTOS503/queue.c:930 0x000126c0                3 UART0IOStreamTask::task() /home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/src/tasks/UART0IOStreamTask.cpp:271 0x000035ac                2 __thread_main_dispatcher() /home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/src/core/Task.cpp:114 0x000092b4                1 <symbol is not available> 0x00000000    The endless loop is caused by the problem that the pxIterator in vListInsert() is the same as pxNewListItem pointing with pxIterator->next to itself. Therefor is pxIterator->pxNext->xItemValue <= xValueOfInsertion always true and causes the endless loop. pxList    0x2000646c        uxNumberOfItems    2        pxIndex    0x20006474            xItemValue    4294967295            pxNext    0x200064f4            pxPrevious    0x200064f4            pvOwner    0x0000000a            pvContainer    0x0000000a        xListEnd    {…}    pxNewListItem    0x200064f4        xItemValue    6        pxNext    0x200064f4        pxPrevious    0x200064f4        pvOwner    0x200064dc        pvContainer    0x2000646c    pxIterator    0x200064f4        xItemValue    6        pxNext    0x200064f4        pxPrevious    0x200064f4        pvOwner    0x200064dc        pvContainer    0x2000646c    "pxCurrentTCB" = 0x200064dc        pxTopOfStack = 0x20006780        xGenericListItem = {…}        xEventListItem = {…}            xItemValue = 6            pxNext = 0x200064f4            pxPrevious = 0x200064f4            pvOwner = 0x200064dc            pvContainer = 0x2000646c        uxPriority = 5        pxStack = 0x20006520            *pxStack = 2779096485        pcTaskName = 0x20006510    I also implemented the vApplicationStackOverflowHook as an infinite loop and put a breakpoint in it (using configCHECK_FOR_STACK_OVERFLOW 2) . But it has never been called. As far as I can say seems the stack of the task to be ok after I had a look at the memory. Does anyone have a clue why this doesn’t work? What am I doing wrong? Many thanks in advance and best regards, Marc. void UART0IOStreamTask::task( ) {     static portCHAR buf[UARTIOStream::LINELENGTH];         for( ;; )     {         // Wait for a uart message to arrive.         if (xQueueReceive( uart0Queue, buf, 50 ) == pdTRUE)             UARTCharPut(UART1_BASE, ‘.’);     } } //***************************************************************************** // // The UART interrupt handler. // //***************************************************************************** extern "C" void UART0IntHandler(void) {     unsigned long ulStatus;     char cChar;     static char bLastWasCR = 0;     static unsigned long ulCount = 0;     portBASE_TYPE xHigherPriorityTaskWoken;     unsigned long ulLen = UARTIOStream::TXBUFFERSIZE;     char pcBuf[]={’1’};     //     // Adjust the length back by 1 to leave space for the trailing     // null terminator.     //     ulLen–;        //     // Get the interrrupt status.     //     ulStatus = UARTIntStatus(UART0_BASE, true);     //     // Clear the asserted interrupts.     //     UARTIntClear(UART0_BASE, ulStatus);     //     // Loop while there are characters in the receive FIFO.     //     /* We have not woken a task at the start of the ISR. */     xHigherPriorityTaskWoken = pdFALSE;     //     // Read the next character from the UART and write it back to the queue     //     /* Was an Rx interrpt pending? */     if( ulStatus & UART_INT_RX || ulStatus & UART_INT_RT)     {     /* Loop until the buffer is empty. */     do     {         /* Obtain a byte from the buffer. */          cChar = UARTCharGetNonBlocking(UART0_BASE);         //          // See if the backspace key was pressed.          //          if(cChar == ‘b’)          {              //              // If there are any characters already in the buffer, then delete              // the last.              //              if(ulCount)              {                  //                  // Rub out the previous character.                  //                  if (UART0IOStreamTask::verbose == 1) {                       UARTCharPutNonBlocking(UART0_BASE, ‘b’);                      UARTCharPutNonBlocking(UART0_BASE, ‘ ‘);                      UARTCharPutNonBlocking(UART0_BASE, ‘b’);                  }                  //                  // Decrement the number of characters in the buffer.                  //                  ulCount–;              }              //              // Skip ahead to read the next character.              //              continue;          }          //           // If this character is LF and last was CR, then just gobble up the           // character because the EOL processing was taken care of with the CR.           //           if((cChar == ‘n’) && bLastWasCR)           {               bLastWasCR = 0;               continue;           }           //            // See if a newline or escape character was received.            //            if((cChar == ‘r’) || (cChar == ‘n’) || (cChar == 0x1b))            {                //                // If the character is a CR, then it may be followed by a LF which                // should be paired with the CR.  So remember that a CR was                // received.                //                if(cChar == ‘r’)                {                    bLastWasCR = 1;                       if (UART0IOStreamTask::verbose == 1) {                         UARTCharPutNonBlocking(UART0_BASE, ‘n’);                        UARTCharPutNonBlocking(UART0_BASE, ‘r’);                    }                }                //                // Stop processing the input and end the line.                //                break;            }            //             // Process the received character as long as we are not at the end of             // the buffer.  If the end of the buffer has been reached then all             // addiT0IOnal characters are ignored until a newline is received.             //             if(ulCount < ulLen)             {                 //                 // Store the character in the caller supplied buffer.                 //                    UART0IOStreamTask::uart0RXBuffer[ulCount] = cChar;                 //                 // Increment the count of characters received.                 //                 ulCount++;                 //                 // Reflect the character back to the user.                 //                 if (UART0IOStreamTask::verbose == 1)                      UARTCharPutNonBlocking(UART0_BASE, cChar);             }     } while(UARTCharsAvail(UART0_BASE));         //     // Add a null terminaT0IOn to the string.     //        UART0IOStreamTask::uart0RXBuffer[ulCount] = ‘’;       /* Post the byte. */     if (bLastWasCR) {         bLastWasCR = 0;         UART0IOStreamTask::uart0RXBufferSize = ulCount;                    ulCount = 0;         if (xQueueSendFromISR( UART0IOStreamTask::uart0Queue, pcBuf, &xHigherPriorityTaskWoken ) == pdTRUE)             ulMessageCounter++;     }     }         /* Now the buffer is empty we can switch context if necessary. */     if( xHigherPriorityTaskWoken )     {         /* Actual macro used here is port specific. */         taskYIELD();     } } C++ wrapper part: portBASE_TYPE Task::taskCreate() {     TaskManager::instance()->addTask(this);     status = RUNNING;     return xTaskCreate( __thread_main_dispatcher, (SC) pcName, usStackDepth, this, uxPriority, &pvCreatedTask);    } void __thread_main_dispatcher(void *threadobjptr) {     Task * thread = static_cast< Task * >(threadobjptr);     thread->task_is_running = true;     // call the thread’s main() methode;     thread->task(); } arm-none-eabi-g++ -DGCC_ARMCM3 -DPART_LM3S8962 -I"/home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/include" -I"/home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/src/Maze" -I"/home/szymansk/workspace/SymbricatorRTOS/StellarisDriverLib" -I"/home/szymansk/workspace/SymbricatorRTOS/LM3S8962 Project" -I"/home/szymansk/workspace/SymbricatorRTOS/FreeRTOS503/include" -I"/home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/include/core" -I"/home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/src/MDL2e" -O0 -g3 -pedantic -Wall -mthumb -mcpu=cortex-m3 -MD -c  -fno-rtti -fno-exceptions -fcheck-new -fno-enforce-eh-specs -Wabi -Woverloaded-virtual -fomit-frame-pointer arm-none-eabi-gcc -DGCC_ARMCM3 -Dgcc -DPART_LM3S8962 -I"/home/szymansk/workspace/SymbricatorRTOS/FreeRTOS503" -I"/home/szymansk/workspace/SymbricatorRTOS/StellarisDriverLib" -I"/home/szymansk/workspace/SymbricatorRTOS/webserver/uip" -I"/home/szymansk/workspace/SymbricatorRTOS/webserver" -I"/home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/src/MDL2e" -I"/home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/include" -I"/home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/include/MDL2e" -I"/home/szymansk/workspace/SymbricatorRTOS/LM3S8962 Project" -I"/home/szymansk/workspace/SymbricatorRTOS/FreeRTOS503/include" -I"/home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/src/MDL2e/decoder" -I"/home/szymansk/workspace/SymbricatorRTOS/SymbricatorOS/src/MDL2e/core" -O0 -g3 -pedantic -Wall -mthumb -mcpu=cortex-m3 -MD -c -fno-exceptions -std=gnu99 -fomit-frame-pointer Linker: arm-none-eabi-g++ -L/home/apps/arm-codesourcery/arm-none-eabi/lib/thumb -L/home/apps/arm-codesourcery/arm-none-eabi/lib -T ../LM3S8962 Project/standalone.ld -mthumb -mcpu=cortex-m3 -fno-rtti -fno-exceptions -fcheck-new

FreeRTOS hangs in vListInsert

The stack overflow will only detect errors during the context switch. If you corrupt a list structure and hang because of the corruption then it is possible you never get to the next context switch (although the tick should till be running? critical section?). Is you UART interrupt priority below configMAX_SYSCALL_INTERRUPT_PRIORITY?  Remember on the Cotex that 255 is the LOWEST priority not the highest as is a common mistake.

FreeRTOS hangs in vListInsert

The configMAX_SYSCALL_INTERRUPT_PRIORITY was set to 191 = 0b10111111 which is equal to 5 as only the first three msb are valid for the priority. The priority of the UART interrupt was set to 0x60 = 01100000 which is 3. If I understood it right it seems to be correct. The priority of the task handling the message coming from the UART interrupt was 5 could this be a problem? How can I figure out what happens with the list. And when should I use use the critical section stuff?

FreeRTOS hangs in vListInsert

I think you have it the wrong way around. As there are only three bits available think of it as 0 being the highest priority and 7 being the lowest priority. The UART interrupt priority must be equal to or lower than configMAX_SYSCALL_INTERRUPT_PRIORITY, so it must have an equal to or higher priority number assigned (higher numbers are lower priorities). You have assigned configMAX_SYSCALL_INTERRUPT_PRIORITY a priority of 5, so interrupts that use system calls can be assigned priority values of 5, 6 or 7 only.  Priortities 5, 6 and 7 are equal to or LOWER than the max syscall priority of 5.

FreeRTOS hangs in vListInsert

This is definitely true. Shame on me. And it seems to work. I also found a typical copy and paste error in an other interrupt which was meant to set the priority of this interrupt but just set the priority of the problematic interrupt back… I’ll make a long term test. Thanks a lot!!!