ATSAML21, FreeRTOS works at 4MHz for my application. Breaks when frequency updated to 48MHZ

Discription: When the clock is running on default 4MHz and SYSTEMCLOCK = 4000000U in systemsaml21.c the task scheduler executes and starts the temp_task. Problem: When the clock is configured to 48MHz through dpll48MHzinit(), and SYSTEMCLOCK = 48000000U, it breaks to signal handler in vPortExitCritical() which is called eventually from xTaskCreate(). Please check callstack in attached file to understand this better. ~~~ void main() {
/* Update clock freq to 48MHz */ 
dpll_48MHz_init();

// Initialize pin MUX
HW::init();

xTaskCreate(temp_task, "temp_task", configMINIMAL_STACK_SIZE, NULL, 1, NULL);

//vTaskStartScheduler();

while (1) {

    for(int i = 0; i < 10; i++)
    {
        if(i%2 == 0)
        PORT->Group[1].OUTSET.reg |= PORT_PB10;
        else
        PORT->Group[1].OUTCLR.reg |= PORT_PB10;
        for(int j = 0 ; j < 1000000; j++);
    }
    //USART_0_example();
}
} ~~~ vTaskStartScheduler() is disabled for debugging purpose. I tried to look for the soultion online somewhere it said stack overflow might be the cause which is not the case i think, i treid different stack sizes. Also it would’nt work with 4MHz if that was the case!!! Also, it was suggested that changing SVCInt priority would help. But I think it was specific to M3s so i dint put much efforts to it. I am unable to figure this out, any help or ideas are appriciated. Thanks Rishit

ATSAML21, FreeRTOS works at 4MHz for my application. Breaks when frequency updated to 48MHZ

Looks like you are getting an interrupt [that does not have a handler installed for it] executing as soon as you exit the critical section. Calling xTaskCreate() should mask interrupts over configMAXSYSCALLINTERRUPTPRIORITY until the scheduler has started – so either the initial critical section nesting count is not being initialised correctly in your start up code (you can verify this by checking what value the uxCriticalNesting variable in port.c has when you are in main()) – or you have an interrupt at a priority above configMAXSYSCALLINTERRUPTPRIORITY executing. Finding out which interrupt it is would be a good starting point – if it is a peripheral you will now where to look – if it is a hard or other fault then it would seem to be a configuration problem. The only way I could see that this would be dependent on the clock frequency is that when the frequency is higher the interrupt might occur much sooner.

ATSAML21, FreeRTOS works at 4MHz for my application. Breaks when frequency updated to 48MHZ

Thanks Richard for a quick reply. I implmented handlers and only the HardFault() is being executed. Stepping through, there is no perticular point where it fails i think. Because once it faild when vTaskStartScheduler() is creating an idle task and it makes a call to xTimerCreateTimerTask on line 1948 in tasks.c. What is consistent is it is always a hard fault. is it really configuration issue? What should i look into more? i tried manipulating configMAXSYSCALLINTERRUPTPRIORITY to no avail, it is set at 2 currently i tried from 0 to 4. I am not sure how to figure out if there are any interrupts with priority above configMAXSYSCALLINTERRUPTPRIORITY. What surprises me is everything works fine at 4MHz, its 48MHz causing the trouble. Thanks again. Regards, Rishit

ATSAML21, FreeRTOS works at 4MHz for my application. Breaks when frequency updated to 48MHZ

I think the SAML21 is a Cortex-M0 so configMAXSYSCALLINTERRUPT_PRIORITY won’t have any effect (as the M0 does not have a basepri register). Are you saying the interrupt handler you end up in is the hardfault handler? Which version of FreeRTOS are you using?

ATSAML21, FreeRTOS works at 4MHz for my application. Breaks when frequency updated to 48MHZ

I am using RTOS V10.0.1. I also tried FreeRTOSConfig.h for v10.0.0 from Microchip’s example project to no avail. And yes I implemented hardFault with a while(1) for the sake of checking if the program ends up there there and it does everytime. Also, no peripheral except Clock is configured in the project (code above is all i am doing). What are the chances of other interrupts triggering!! I implemented interrupt that handles clock related interrupt but the PC never went there. Also interrupts for the clock are not enabled. I have attached my FreeRTOSConfig.h file. It has two configs for a version each (V10.0.0 (enabled) & V10.0.1 (disabled)) in case you want to take a look.

ATSAML21, FreeRTOS works at 4MHz for my application. Breaks when frequency updated to 48MHZ

You may have to step through at the assembly level to find the instruction that results in the fault. In addition – these instructions are for the Cortex-M3/4/7, not sure how applicable they are to the M0: https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

ATSAML21, FreeRTOS works at 4MHz for my application. Breaks when frequency updated to 48MHZ

Thanks Richard for pointing a direction. While i am reading it, I have some more information. I was trying to step thorugh the program (not in assembly) and below are few observations when I am stepping inside the vTaskStartScheduler() 1. Can not step over these functions, all the calls to these functions gets me to hardfault() if I try to step over. – pvPortMalloc() – prvAddnewTaskToReadyList() – prvProcessTimerOrBlockTask() – pvPortMalloc() Once I step inside these functions and then steping over eachline in the function works just fine. 2. Stepping into prvProcessReceivedCommands() generates hardfault directly. 3. Luckily I was able to run my temp_task() only once by stepping into for a while and run after, I think, vPortStartFirstTask() function. I guess timing was right for that one time. Doesanything here sound like race condition? I am just driving blind at this point (but working hard). Now I am going to finish reading the documents in your link. Thanks for you time. UPDATE: Same FreeRTOS configuration with a different clock scheme works at 48MHz. The configuration I am trying to work here is using Fractional DPLL. While the one that works at 48MHz uses DFLL. Does that mean its not a freeRTOS issue but clocking issue? UPDATE2: In reference to UPDATE above, one of the difference I see in two case i mentiond is PRIMASK is set to 0x01 when the program breaking while it is set to 0x00 when the program running fine. UPDATE3: Update2 doesnt matter, PRIMASK prevents handling of lower priority (lower than hard_fault?!) exceptions.

ATSAML21, FreeRTOS works at 4MHz for my application. Breaks when frequency updated to 48MHZ

Turns out with ATSAML21, there are different power domains (default PD0). if the CPU clock frequency is more than 12MHz PD2 should be turned on otherwise what I think is bus fault occurs and CPU ends up in the Hard_Fault() (I am assuming, I might be wrong). **Switching on PD2 when running the CPU clock at 48MHz worked for me **(not assuming here :p). Turn on PD2 before configureing the clocks to 48MHz. Information/numbers here might be wrong, refer to the datasheet for accurate information.

ATSAML21, FreeRTOS works at 4MHz for my application. Breaks when frequency updated to 48MHZ

Turns out with ATSAML21, there are different power domains (default PD0). if the CPU clock frequency is more than 12MHz PD2 should be turned on otherwise what I think is bus fault occurs and CPU ends up in the Hard_Fault() (I am assuming, I might be wrong). **Switching on PD2 when running the CPU clock at 48MHz worked for me **(not assuming here :p). Turn on PD2 before configureing the clocks to 48MHz. Information/numbers here might be wrong, refer to the datasheet for accurate information.