SysTick Timer ARM Cortex M0 and configTICK_RATE_HZ

Howdy — I’m an experienced 8 bit embedded designer, who is porting a project over to a STM32 CM0 and using FreeRTOS 9. I’ve currently got my SysTick configured to trigger the SysTick interrupt every 1ms. (I can set it to whatever value, changing reload the value… but just for example). I’m not clear on what configTICKRATEHZ is clocked too. If I went through the code base for my FreeRTOS 9 CM0 port (my port is just right from the KEIL Pack Installer), would I find that the value I set for configTICKRATEHZ actually overwrites any previous reload value in the SysTick register, when I activate the kernel? Or is configTICKRATEHZ some value of HZ after the SysTick interrupt (not even certain how that would work…). Thanks, -Tim

SysTick Timer ARM Cortex M0 and configTICK_RATE_HZ

Okay this was a bit easier to find, than I thought. If you check the port.c, under …RVDSARM_CM0: You’ll find a line, at 345. ~~~ void prvSetupTimerInterrupt( void ) { /* Configure SysTick to interrupt at the requested rate. / *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) – 1UL; *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE; } /———————————————————–*/ ~~~ Just coming to Cortex M (and never having used FreeRTOS), I’m not familiar with all of the NVIC functions. But I’m guessing NVICSYSTICKLOAD changes the load value of the SysTick register. (EDIT: Nope, NVICSYSTICKLOAD is just a pointer to the SysTick register where the reload value goes…)
Is there any documentation, or could you provide any direction, on where you would look in the code to change the timer being used? Is there anywhere else that are “hot spots” where you’d need to rewire things to change the timer from SysTick? (Sorry I literally know nothing about the underlying source code!). Is this all handled in port.c, so you’d just have to rewire the constants in port.c? ~~~ /* Constants required to manipulate the NVIC. */

define portNVICSYSTICKCTRL ( ( volatile uint32_t *) 0xe000e010 )

define portNVICSYSTICKLOAD ( ( volatile uint32_t *) 0xe000e014 )

define portNVICINTCTRL ( ( volatile uint32_t *) 0xe000ed04 )

define portNVICSYSPRI2 ( ( volatile uint32t *) 0xe000ed20 )

define portNVICSYSTICKCLK 0x00000004

define portNVICSYSTICKINT 0x00000002

define portNVICSYSTICKENABLE 0x00000001

define portNVIC_PENDSVSET 0x10000000

define portMININTERRUPTPRIORITY ( 255UL )

define portNVICPENDSVPRI ( portMININTERRUPTPRIORITY << 16UL )

define portNVICSYSTICKPRI ( portMININTERRUPTPRIORITY << 24UL )

~~~

SysTick Timer ARM Cortex M0 and configTICK_RATE_HZ

The SysTick timer is intended for use by an RTOS. It normally runs at the same frequency as the core. Set configCPUCLOCKHZ to the frequency the core will be executing at, then configTICKRATEHZ to the rate at which you want the RTOS tick interrupt to execute at, and the RTOS will setup the SysTick timer for you when the scheduler is started. Typing on my phone so I can’t give you the links, but the config parameters are documented on the FreeRTOS.org website, where you will also find a free to download (if a little out of date) book.

SysTick Timer ARM Cortex M0 and configTICK_RATE_HZ

Here you can find a summary of the clocks in an STM32F. The systick frequency is obtained by dividing the CPU clock frequency.
Is there any documentation, or could you provide any direction, on where you would look in the code to change the timer being used?
It is possible, but why would you want to use a different timer for this? You would have to make sure the the priorities are set correctly. In most ports, the code for the SysTick_handler() is provided directly by the port itself (see xPortSysTickHandler() ). But beware that the STM32F HAL drivers also wants to define a systick handler in a file called stm32f4xx_it.c: ~~~ void SysTickHandler(void) { /* USER CODE BEGIN SysTickIRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )
{
    xPortSysTickHandler();
}
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */

/* USER CODE END SysTick_IRQn 1 */
} /* And defined in stm32f4xx_hal.c: */ __weak void HAL_IncTick(void) { uwTick++; } __weak uint32t HALGetTick(void) { return uwTick; } ~~~ FreeRTOSConfig.h will often have this comment: ~~~ /* IMPORTANT: This define MUST be commented when used with STM32Cube firmware, to prevent overwriting SysTickHandler defined within STM32Cube HAL */ /* #define xPortSysTickHandler SysTickHandler */ ~~~ In my own projects, I tend to :
  • enable the above #define
  • remove the HAL version of SysTick_Handler()
  • provide my own version of HAL_GetTick().
Note that a working HAL_GetTick() is important for some of the HAL drivers. Therefore some drivers can only be started up once the systick interrupt is active. Good luck!

SysTick Timer ARM Cortex M0 and configTICK_RATE_HZ

Is there any documentation, or could you provide any direction, on where you would look in the code to change the timer being used? It is possible, but why would you want to use a different timer for this? You would have to make sure the the priorities are set correctly.
In case you also want to use the systick, there is an application hook that you can use: ~~~

if ( configUSETICKHOOK == 1 )

void vApplicationTickHook()
{
    /* This function will be called at a rate of "configTICK_RATE_HZ" */
}

endif

~~~ If you want your handler to be called at a higher frequency, I would use some Time-Counter interrupt. Remind that your ISR code is not supposed to call normal FreeRTOS API’s. From an interrupt service routine, you should call functions that end with FromISR(). When configASSERT() is defined, the NVIC priorities will be checked for. When the priorities are not OK, the program will be kept in an infinite loop in vAssertCalled().

SysTick Timer ARM Cortex M0 and configTICK_RATE_HZ

Guys, I appreciate the guidance. I’m racking my brain for a reason why you wouldn’t use the SysTick, I think my primary motivation is in learning the Cortex architecture for the first time and eventually looking at tickless and the whole assortment of other timers on a CM0, and mixing it up with optimal power management. [I’m not familiar enough yet, to articulate entirely what I’m thinking — but it’s not a pipe dream 😉 ]. That’s a VERY GOOD call out on the ISR, because I have ane existing project that I am porting (just to power profile a CM0 vs. our current 8 bit MCU), that samples data at rates faster than 1ms. In this case, maybe you dial the RTOS to 20ms a tick for housekeeping, and sample independetly in the ISR. This will be the learning curve to put all of that together. I saw that earlier with the HAL. Honestly it is kind of weird a peripheral driver library would use the SysTick handler, but hey what do I know… I’m coming from a pretty bare-metal approach. Like for me the NVIC functions where they modify several registers at a time, seem exotic! I’m using the LL (“low level”) library from STM, which I don’t think has this dependency? I do remember having to clean out a SysTick handler in the STM library in any case.

SysTick Timer ARM Cortex M0 and configTICK_RATE_HZ

@Richard — I also, just wanna give you a shout-out for such an outstanding project. I own a small business and get how things go. This is crazy you guys have built this good of a system and then released the whole thing as a freebie! Good karma, my man…. hopefully the Amazon thing worked out well!