FreeRtos not running on PIC32MZ

Hi,

I am using FreeRtos v10.5.1 from “git clone --depth 1 --branch v10.5.1 GitHub - ARM-software/CMSIS-FreeRTOS: FreeRTOS adaptation for CMSIS-RTOS Version 2”, but i tried with other versions and same problem.

The FreerRtos is still not running correctly.

Simple test program:
I created two tasks to toggle a led.
Task1 should toggle led1 each 500 ms.
Task2 should toggle led2 each 500 ms.

When the priority of the two tasks is set to 1, a exception occur, calling the function “void attribute((noreturn)) _simple_tlb_refill_exception_handler(void)”, _excep_code = 0x00000002, _excep_addr = 0x00000000 ( null pointer probably ).
_excep_code = 0x02 doesn’t even exist.

When the priority of the two tasks is set to 2 and 3 respectively, a exception not occur, the led1 and led2 lights up and stays lit, meaning that the tasks are being executed only once.

I put a third led to see if the tick is working, and in this case is ok, the led toggle every 500ms ( configTICK_RATE_HZ = 1000 ).

Code:

void vApplicationTickHook( void ) 
{
    static TickType_t c = 0;
    c++;
    if( c == configTICK_RATE_HZ/2 )
    {
        c = 0;
        my_led_toggle_3();
    }
}

void _APP_Tasks( void *pvParameters )
{  
    (void) pvParameters;

    while(1)
    {
        my_led_toggle_1();
        vTaskDelay( pdMS_TO_TICKS(500) );
    }  
}

void teste( void *pvParameters )
{  
    (void) pvParameters; 

    while(1)
    {
        my_led_toggle_2();
        vTaskDelay( pdMS_TO_TICKS(500) );
    }
}

BaseType_t SYS_Tasks( void )
{
    BaseType_t ret = 0;

    ret = xTaskCreate( _APP_Tasks,
                                    "APP_Tasks",
                                    4096, // 4096 * 4 = 16384 bytes.
                                    NULL,
                                    3,
                                    (TaskHandle_t*)NULL
                                  );
    if( ret != pdPASS )
        return -6;

    ret = xTaskCreate(  teste,
                                     "teste",
                                     1024, // 1024 * 4 = 4096 bytes.
                                     NULL,
                                     2,
                                     (TaskHandle_t*)NULL
                                  );
    if( ret != pdPASS )
        return -7;

    vTaskStartScheduler();

    return ret;  // Must never get here..
}

The strange thing is that FreeRtos worked before, i don’t know if the microchip MCC( Mplab Code Configurator ) tool did some wrong code generation or not now.

I had already opened a support ticket on the microchip website with a very similar problem and microchip could not find the problem.
So i needed to get a backup of mine that was running, and i made the necessary changes and it worked, at the time i abandoned the support ticket .
In annex is that “old” bug project that the microchip support didn’t find the problem, i still haven’t had time to clean up this current project to post it here, if you need it, i can do that.

I’m not able to find the problem, maybe something related with interrupt, but what ?

NOTES:
The functions are all enabled and none is called, with the exception of vApplicationTickHook.
The function “void vApplicationIdleHook( void )” are not enabled.
“void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )”
“void vApplicationMallocFailedHook( void )”, “void vApplicationTickHook( void )”
“void vApplicationTickHook( void )”
“void vAssertCalled( const char * pcFile, unsigned long ulLine )”

I am using the dev board DM320007-C.

FrreRtos-Bugado-Again.7z (407.2 KB)

I just did a quick test with the latest MPLAB and this project: FreeRTOS/FreeRTOS/Demo/PIC32MZ_MPLAB at main · FreeRTOS/FreeRTOS · GitHub

My hardware was the old chipKIT Wi-Fire (no longer supported) with a PIC32MZ2048EFH100 so it is not an exact fit for the demo. I selected the SK_SOFT_FLOAT
image
and changed from LATH to LATG and the LED’s to 6 & 15 to match my hardware. I also added #elif defined(__32MZ2048EFM144) || defined(__32MZ2048EFH144) || defined(__32MZ2048EFH100)
to the fuses section of main.c (the EFH100 is compatible with the EFH144 so no changes were needed)

I changed the demo to “blinky” by changing the define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY from 0 to 1. Compiled and loaded this code and the LED is blinking correctly.

I suggest that you start with this demo as that should be fully setup for the PIC32MZ and see how it goes. Good Luck.

Hi,

Now i debugged and the problem came from this address here:

         /* When using preemption tasks of equal priority will be
         * timesliced.  If a task that is sharing the idle priority is ready
         * to run then the idle task should yield before the end of the
         * timeslice.
         *
         * A critical region is not required here as we are just reading from
         * the list, and an occasional incorrect value will not matter.  If
         * the ready list at the idle priority contains more than one task
         * then a task other than the idle task is ready to execute. */

if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )

but this error does not always appear, mostly the address is null.

File “FreeRTOS_tasks.c”

static portTASK_FUNCTION( prvIdleTask, pvParameters )
{
    /* Stop warnings. */
    ( void ) pvParameters;

    /** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE
     * SCHEDULER IS STARTED. **/

    /* In case a task that has a secure context deletes itself, in which case
     * the idle task is responsible for deleting the task's secure context, if
     * any. */
    portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE );

    for( ; ; )
    {
        /* See if any tasks have deleted themselves - if so then the idle task
         * is responsible for freeing the deleted task's TCB and stack. */
        prvCheckTasksWaitingTermination();

        #if ( configUSE_PREEMPTION == 0 )
        {
            /* If we are not using preemption we keep forcing a task switch to
             * see if any other task has become available.  If we are using
             * preemption we don't need to do this as any task becoming available
             * will automatically get the processor anyway. */
            taskYIELD();
        }
        #endif /* configUSE_PREEMPTION */

        #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
        {
            /* When using preemption tasks of equal priority will be
             * timesliced.  If a task that is sharing the idle priority is ready
             * to run then the idle task should yield before the end of the
             * timeslice.
             *
             * A critical region is not required here as we are just reading from
             * the list, and an occasional incorrect value will not matter.  If
             * the ready list at the idle priority contains more than one task
             * then a task other than the idle task is ready to execute. */
            if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )
            {
                taskYIELD();
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
        }
        #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */

        #if ( configUSE_IDLE_HOOK == 1 )
        {
            extern void vApplicationIdleHook( void );

            /* Call the user defined function from within the idle task.  This
             * allows the application designer to add background functionality
             * without the overhead of a separate task.
             * NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
             * CALL A FUNCTION THAT MIGHT BLOCK. */
            vApplicationIdleHook();
        }
        #endif /* configUSE_IDLE_HOOK */

        /* This conditional compilation should use inequality to 0, not equality
         * to 1.  This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when
         * user defined low power mode  implementations require
         * configUSE_TICKLESS_IDLE to be set to a value other than 1. */
        #if ( configUSE_TICKLESS_IDLE != 0 )
        {
            TickType_t xExpectedIdleTime;

            /* It is not desirable to suspend then resume the scheduler on
             * each iteration of the idle task.  Therefore, a preliminary
             * test of the expected idle time is performed without the
             * scheduler suspended.  The result here is not necessarily
             * valid. */
            xExpectedIdleTime = prvGetExpectedIdleTime();

            if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
            {
                vTaskSuspendAll();
                {
                    /* Now the scheduler is suspended, the expected idle
                     * time can be sampled again, and this time its value can
                     * be used. */
                    configASSERT( xNextTaskUnblockTime >= xTickCount );
                    xExpectedIdleTime = prvGetExpectedIdleTime();

                    /* Define the following macro to set xExpectedIdleTime to 0
                     * if the application does not want
                     * portSUPPRESS_TICKS_AND_SLEEP() to be called. */
                    configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime );

                    if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
                    {
                        traceLOW_POWER_IDLE_BEGIN();
                        portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
                        traceLOW_POWER_IDLE_END();
                    }
                    else
                    {
                        mtCOVERAGE_TEST_MARKER();
                    }
                }
                ( void ) xTaskResumeAll();
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
        }
        #endif /* configUSE_TICKLESS_IDLE */
    }
}

Hi,

I already did all that.
FreeRtos was working.
I even ran complex projects with FreeRtos on this same platform.
Out of nowhere it stops working.
A simple led blink is not working.

So much so that even microchip support couldn’t find the problem in the attached project.
They told me the same thing as you, to start from scratch, but I’ve done this several times and out of nowhere, something that was working stops working.

I already disabled everything that i think could be a problem and it still doesn’t work.
I’ll try disabling shadow registers now and see what happens.

Where i can selected the “SK_SOFT_FLOAT” ?

Thank’s.

Hi,

I disabled shadow Register Set and worked.

In MCC->Project Graph->System->PIC32MZ Interrupts->Shadow Register Set Configuration:
Enable Shadow Register Set Feature

Shadow registers is a very good feature to decrease interrupt latency.
In this my chip, PIC32MZ2048EFM144, there are 7 sets of shadow registers.

I had problems with these shadow registers on the PIC32MK1024MCF064 as well, i guess i wasn’t using FreeRtos yet, i had writen my own dma library and i used shadow registers.
In the chip PIC32MK1024MCM064, i dont remember if i had problems too.

These shadow registers should work.

I will do some more tests.

Edit:

This way works:

void EVIC_Initialize( void )
{
    NTCONSET = _INTCON_MVEC_MASK;

    /* Set up priority and subpriority of enabled interrupts */
    IPC0SET = 0x4 | 0x0; /* CORE_TIMER: Priority 1 / Subpriority 0 */
    IPC42SET = 0x400 | 0x0; /* SQI1: Priority 1 / Subpriority 0 */   

    PRISSbits.PRI7SS = 7;  // My lib Dma channel 1
    PRISSbits.PRI6SS = 6;  // My lib Dma channel 2
    PRISSbits.PRI5SS = 5;  // My lib Dma channel 0 
}


This way NOT works: 
Code generated by MCC when shadow Registers Set is enabled.

void EVIC_Initialize( void )
{
    INTCONSET = _INTCON_MVEC_MASK;

    /* Set up priority and subpriority of enabled interrupts */
    IPC0SET = 0x4 | 0x0; /* CORE_TIMER: Priority 1 / Subpriority 0 */
    IPC42SET = 0x400 | 0x0; /* SQI1: Priority 1 / Subpriority 0 */

    /* Configure Shadow Register Set */
    PRISS = 0x76543210;

    while (PRISS != 0x76543210)
    {
    /* Wait for PRISS value to take effect */  
    }
}

I think that you are running in the same issue as me:

I recommend that you add #define configLIST_VOLATILE volatile in FreeRTOSConfig.h to err on the safe side, I would randomly get null-pointer de-referenced without it.