FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [September 2008 Threads] FreeRTOS hangs in vListInsertPosted by szymansk on September 23, 2008 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.
pxList0x2000646c uxNumberOfItems2 pxIndex0x20006474 xItemValue4294967295 pxNext0x200064f4 pxPrevious0x200064f4 pvOwner0x0000000a pvContainer0x0000000a xListEnd{...}
pxNewListItem0x200064f4 xItemValue6 pxNext0x200064f4 pxPrevious0x200064f4 pvOwner0x200064dc pvContainer0x2000646c
pxIterator0x200064f4 xItemValue6 pxNext0x200064f4 pxPrevious0x200064f4 pvOwner0x200064dc pvContainer0x2000646c
"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] = '\0';
/* 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
RE: FreeRTOS hangs in vListInsertPosted by Dave on September 23, 2008 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.
RE: FreeRTOS hangs in vListInsertPosted by szymansk on September 23, 2008 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?
RE: FreeRTOS hangs in vListInsertPosted by Dave on September 23, 2008 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.
RE: FreeRTOS hangs in vListInsertPosted by szymansk on September 23, 2008 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!!!
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|