JakobJ
JakobJ

Reputation: 1273

FreeRTOS stuck in vListInsert

I'm using FreeRTOS 10.0.1 and have a really hard problem, trying to solve it for days, getting my code to run on a CC1310 (Arm Cortex M3). I use the TI SDK and read data from a I2C device, first time is successful, second gets stuck in the vListInsert, with the pxIterator->pxNext points to itself, so the for loop is infinite.

The driver is waiting for a SemaphoreP_pend(), if I set a breakpoint, I can see that the post gets called, but the kernel is just stuck.

I have set the SysTick and PendSV isr prio to 7 (lowest).

The i2c interrupt is prio 6.

configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 1.

There is no stack overflow as far as I can tell.

Please help, how do I debug this problem ?

Best regards Jakob

Upvotes: 0

Views: 815

Answers (4)

Gabriel Staples
Gabriel Staples

Reputation: 52797

There are at least 5 reasons why your code might get stuck inside the infinite for loop in the vListInsert() function in the list.c FreeRTOS kernel source code file.

Here, I've augmented reason 4:

/* *** NOTE ***********************************************************
*  If you find your application is crashing here then likely causes are
*  listed below.  In addition see https://www.FreeRTOS.org/FAQHelp.html for
*  more tips, and ensure configASSERT() is defined!
*  https://www.FreeRTOS.org/a00110.html#configASSERT
*
*   1) Stack overflow -
*      see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html
*   2) Incorrect interrupt priority assignment, especially on Cortex-M
*      parts where numerically high priority values denote low actual
*      interrupt priorities, which can seem counter intuitive.  See
*      https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition
*      of configMAX_SYSCALL_INTERRUPT_PRIORITY on
*      https://www.FreeRTOS.org/a00110.html
*   3) Calling an API function from within a critical section or when
*      the scheduler is suspended, or calling an API function that does
*      not end in "FromISR" from an interrupt.
*   4) Using a queue or semaphore before it has been initialised or
*      before the scheduler has been started (are interrupts firing
*      before vTaskStartScheduler() has been called?).
*     - This includes initializing binary semaphores before taking them. If
*       you create one with `xSemaphoreCreateBinary()` or
*       `xSemaphoreCreateBinaryStatic()`, you must call `xSemaphoreGive()`
*       before calling `xSemaphoreTake(). See:
*       https://freertos.org/xSemaphoreCreateBinaryStatic.html:
*       > The semaphore is created in the 'empty' state, meaning the
*       > semaphore must first be given using the xSemaphoreGive() API
*       > function before it can subsequently be taken (obtained) using the
*       > xSemaphoreTake() function.
*   5) If the FreeRTOS port supports interrupt nesting then ensure that
*      the priority of the tick interrupt is at or below
*      configMAX_SYSCALL_INTERRUPT_PRIORITY.

Source (my pull request): https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/1051/files

Upvotes: 0

Michael Ansolis
Michael Ansolis

Reputation: 171

I ran into an issue with FreeRTOS getting stuck in vListInsert() when I accidentally disabled interrupts and tried to disable interrupts again. Make sure you don't have a call to taskENTER_CRITICAL() followed by portDISABLE_INTERRUPTS().

Upvotes: 0

JakobJ
JakobJ

Reputation: 1273

I solved the Issue, after getting help from @realtime-rik, I decided to check all my interrupt priorities again. They where all ok, but in the process I discovered two things.

  1. The TI-SDK had structs with buffers in some of the drivers, which where rtos dependent, so their size should be set manually for each driver depending on the rtos usage.
  2. I called the board init function in main before the scheduler was started, and inside board init, one of the drivers was using FreeRTOS queues. I have moved board init to my thread now.

Upvotes: 1

Realtime Rik
Realtime Rik

Reputation: 1714

This is almost certainly a problem with interrupt priorities and the list getting corrupted. The interrupt priority is stored in the top 3 bits in your case (as there are 3 priority bits). So 7 is stored as 7 << 5 (11100000b) (you can pad the lower bits with 1 if you like so priority 7 == 255). This is handled by FreeRTOS.

What I suspect is happening is your I2C interrupt of priority 6, is not being << 5 so you have 00000110b which gives a priority of 0 (highest, as its the top 3 bits)

Upvotes: 1

Related Questions