Frequency Switching STM32F

Opps… I just read the comments, it tells me what might be the problem… the GDB window was small and I didn’t look…
    /* *** NOTE ***********************************************************
    If you find your application is crashing here then likely causes are:
        1) Stack overflow -
           see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
        2) Incorrect interrupt priority assignment, especially on Cortex-M3
           parts where numerically high priority values denote low actual
           interrupt priorities, which can seem counter intuitive.  See
           configMAX_SYSCALL_INTERRUPT_PRIORITY on http://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?).
    See http://www.freertos.org/FAQHelp.html for more tips, and ensure
    configASSERT() is defined!  http://www.freertos.org/a00110.html#configASSERT
    **********************************************************************/
Using STM32F4 with FreeRTOS 8.1, and trying to dynamically switch frequency. Background: I can setup the target to run at any desired frequency and the target runs fine. In particular I am using 12 and 48 MHz. Selecting either of those two frequencies and doing a cold boot, the target runs fine. However if I switch frequency, the target runs for only a brief time and fails. Note that at either frequency I keep the peripheral bus clock constant at 12MHz, to avoid having to reconfigure peripherals. I created a non-FreeRTOS build and used the same frequency switching code, and the target works fine. Note that this build is very simplified, no tasks, and no interrupts, but it does use the uart for debugging (similar to the FreeRTOS build). The frequency switching implementation looks like this,
taskENTER_CRITICAL(); 
// run the switch frequency code here 
taskEXIT_CRITICAL();
The STM32 has a clock management library, and I use the HALRCCClockConfig() api to switch frequencies. This api also manages the systick, to keep it at 1ms. Failure: After the frequency switch, the target “runs” for a brief time before it seems to halt. After the frequency switch, the target has all tasks blocked waiting for an event. If I press a button, or send a command thru uart, that event will partially process before the target halts. Sometimes the target will actually process more than one event before the halt. Using GDB I can pause the target, and it shows that the target is in an infinite loop at this line, from list.c, vListInsert(), line 159. for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ { /* There is nothing to do here, we are just iterating to the wanted insertion position. */ }

Frequency Switching STM32F

Provided the tick frequency remains the same I can’t think of any reason why the RTOS would care what frequency the core was running at. Do you have configASSERT() defined? Maybe that would highlight where it goes wrong before you get stuck in the loop. Where is the frequency switch code executed from? Is it trying to use any resources that the RTOS is using? Systick for example – I think some of the ST libraries require their own handler which then chains with the FreeRTOS handler. Regards.

Frequency Switching STM32F

Thank you for the comment. Yes, configASSERT() is defined, it will toggle an LED. I have seen configASSERT() called in other circumstances, so I believe it to be working. But in this case, its not being triggered. The frequency switching code I am 99% sure is not using any FreeRTOS resources… I am calling into the STM HAL library, with HALRCCClockConfig() and HALRCCOscConfig(). These functions poke registers. Of the 4 reasons for the loop to get stuck, I have ruled out #1 and #4. #3 I am 95% sure is not happening. But #4, I am not sure how to prove. The failure is 100% reproducible. I might have some random interrupts from other components happening, but I would assume in some cases there would be no interrupt and the target would “work”. I will keep plugging away…

Frequency Switching STM32F

Update, Within the HALRCCClockConfig() function there is a call to, HALInitTick(TICKINT_PRIORITY); If I comment out that line, the target seems to behave, although now the systick interrupt is at the wrong frequency. There would seem to be some coupling between the HAL tick and the FreeRTOS kernel that is the root cause of the issue…. this is what the commenter above suspected…

Frequency Switching STM32F

I think in STM32Cube ST install an interrupt handler for the Systick that performs the processing necessary for their drivers, then call the FreeRTOS handler, effectively chaining the two. In a FreeRTOS application it would normally be the other way around – the FreeRTOS tick hook would be used to call third party code. Does HAL_InitTick() try to install a new handler? Or change the vector base register? Those could cause you problems. Otherwise you could leave the call commented out then re-configure the tick interrupt yourself. You will find the code necessary in whichever port.c file you are using. The function is normally called prvSetupTimerInterrupt(), or something similar.

Frequency Switching STM32F

It seems to be a priority issue. STM HAL wants to set the sys tick int priority to 0 (highest priority), whereas FreeRTOS wants to set the priority to 15 (lowest priority). The function to re-init the systick interrupt frequency/priority is a __weak function, so I have overridden and I remove the code that set the priority. This seems to work. It also violates comments in HAL where they indicate they need priority 0 for systick for some of the HAL driver…