Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FreeRTOS tasks are not context switching

I'm using FreeRTOS port for PIC32 microcontroller on the PIC32MX starter kit. Was just playing with tasks but the tasks aren't context switching. Here are my main config settings:

#define configMAX_PRIORITIES    ( ( unsigned portBASE_TYPE ) 5 )
#define configKERNEL_INTERRUPT_PRIORITY         0x01
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    0x03
#define configTICK_RATE_HZ              ( ( portTickType ) 100 )

Now I have two tasks defined which blink two LEDs. Both have priority of 4(highest). Under normal operation the LEDs should alternatively blink for each 100 ticks. But this doesn't happen. The second LED blinks for 100 ticks and the control goes to the general exception handler. Why does this happen? Seems like there is no scheduling at all.

like image 973
Laz Avatar asked Nov 29 '22 04:11

Laz


2 Answers

FreeRTOS is a priority based pre-emptive scheduler, tasks of equal priority that do not yield processor time will be round-robin scheduled. Relying on round-robin scheduling is seldom suitable for real-time tasks, and depending on the configured time slice, that may mess up your timing. Time-slicing may even be disabled.

Your tasks must enter the Blocked state waiting on some event (such as elapsed time) to allow each other to run as intended.

That said, entering the exception handler rather than simply one task starving another or not running with the intended timing is a different matter. For that you will need to post additional information, though your first approach should be to deploy your debugger.

like image 196
Clifford Avatar answered Dec 06 '22 10:12

Clifford


The absolute first thing to check is your "tick" interrupt. Often interrupts are not enabled, timers aren't set up right, clocks are not configured properly in the #pragma's that set up the PIC32.. and all those issues manifest themselves first in a lack of a "tick".

This is the #1 cause of not task switching: if you're not getting the tick interrupt. That's where the normal pre-emptive task switching happens.

Assuming you're using the "off the shelf demo", in MPLAB, set a breakpoint in the void vPortIncrementTick( void ) function (around line 177 in FreeRTOS\Source\portable\MPLAB\PIC32MX\port.c) and run your code. If it breakpoints in there, your timer tick is working.

like image 25
Serious Integrated Avatar answered Dec 06 '22 11:12

Serious Integrated