FreeRTOS NULL pointer in xTaskIncrementTick()

I have created a project with FreeRTOS and FreeRTOS-IP stack but I have a big problem.

When I run the project I get inside tasks.c I get on xTaskIncrementTick(), line 2779 pxDelayedTaskList with a NULL value:

/* The delayed list is not empty, get the value of the
 * item at the head of the delayed list.  This is the time
 * at which the task at the head of the delayed list must
 * be removed from the Blocked state. */
pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );

This happens at the very first run.
Any ideas how I can find the reason for this?

Do you mean the value of pxDelayedTaskList itself is NULL or the listGET_OWNER_OF_HEAD_ENTRY(pxDelayedTaskList) yields NULL?

Can we see some code? You most likely have a misconfigured system (ie wrong order of priorities of interrupt handlers, in particular priorities of the sys tick and service handlers).

pxDelayedTaskList is NULL when xTaskIncrementTick() is called for the first time.

Which code should I place here? It’s a lot of code.
“misconfigured system … priorities of the sys tick and service handlers”
I have used FreeRTOS several times and now from your sentence I remember this in the past… :slight_smile:

As far as I can tell, it’s not possible for pxDelayedTaskList to be NULL because it is initialized with the first task creation, which is done at latest in xTaskStartScheduler().

Unless of course you have interrupts enabled before your OS starts up. If the sys tick handler gets to execute before xTaskScheduler() is called, that might explain the behavior you see…

A very good point.
Once you said the word interrupts there was a light in the tunnel.
For reasons that defy sanity the STM32F767ZI (also also the STM32F4xx…) start with interrupts enabled!!!
I knew this but of course I forgot…
Once one disables interrupts at the beginning of the main:

int main(void)

the gods become pleased and the system works, well at least it doesn’t crash.
Now to put the FreeRTOS-IP stack to work…


The STM32 doesn’t enable interrupts on startup (after RESET) by itself. There is some code somewhere which does it. Since often the (NVIC) interrupt priority is also set near/before enabling interrupts you should find that piece of code because also interrupt priorities must be adjusted well wrt. to FreeRTOS and its configuration.

Actually, Hartmut has a good point here, though I don’t know offhand whether the STM Cortex POD starts with ints enabled or disabled. All Startup routines I’ve ever seen for M3s and M4s have a

__asm volatile ("cpsid i");

as the first instruction in the reset vector entry, and I think I remember having had problems with no explicit disabling myself a long time ago.

Anyways, main() may or may not be a good point to disable interrupts for sanity. You need to trace through the entire control flow from the reset vector to main() to make sure some intermeidate startup code doesn’t enable interrupts for you at the wrong time. Depending on the startup sequence, that may be quite cumbersome. For example, the ST HAL (bad software. Don’t use it) registers a timer interrupt for itself to implement timeout conditions, so during processor initialization it must have interrupts enabled. One can of course relocate that timer interrupt > configMAX_SYSCALL_INTERRUPT_PRIORITY and disable interrupts below that, but it means messing with a lot of code.

I have placed a breakpoint at Reset_Handler and PRIMASK is 0!
After __disable_irq();
PRIMASK becomes 1.

According to

The Arm Cortex-M offers two methods of disabling and re-enabling interrupts. The simplest method is to set and clear the interrupt bit in the PRIMASK register. This method is simple and fast, but it disables all interrupt levels indiscriminately.

I had the same problem before in a STM32F401 and the ST forum responded that this was the new (ab)normality. :slight_smile:

I think this is the right place to disable interrupts.

    PUBWEAK Reset_Handler


    nop             ; a breakpoint in this line doesn't work!
    **cpsid i         ; disable interrupts**

    LDR     R0, =SystemInit
    BLX     R0
    LDR     R0, =__iar_program_start
    BX       R0