void HAL_SYSTICK_IRQHandler(void) that calls HAL_SYSTICK_Callback(). The HAL_SYSTICK_Callback() routine is defined as follows:
/**
* @brief SYSTICK callback.
* @retval None
*/
__weak void HAL_SYSTICK_Callback(void)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_SYSTICK_Callback could be implemented in the user file
*/
}
For the GCC compiler the “__weak” attribute means that the GCC compile is to use this code for this routine’s default definition, UNLESS the user supplies their own definition for this routine (i.e. without the __weak attribute), in which case GCC compiler is to use the user’s definition. This capability used extensively for defining default/place holder interrupt routines for populating a STM32 microprocessor interrupt vector locations.
What I and others use this STM32 microprocessor capability for is to schedule tasks based on time without having to waste any other timers.
Thus my simple HAL_SYSTICK_Callback routine sets the oneSecFlag once every second and my main loop routine tests this flag to see if it’s time to do something and then clears this flag.
As an example: to properly control a motor it’s important to periodically measure the motor’s shaft rotation and update the motor’s drive. This can best be done by using a timing interrupt to read the motor’s shaft position, update the motor’s drive value, and set a flag which schedules the routine that uses the shaft position to compute the motor’s next drive value.
This is exactly what I want to use the HAL_SYSTICK_Callback for. That is, every 50 ticks (i.e. 20Hz) read a motor’s shaft position (using STM32’s builtin timer quadrature decoder capabilities) and update the motor’s PWM value.
Sorry for being so long winded with more information than I’m sure you’re interested in.
volatile bool oneSecFlag = false;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(100);
Serial.println("Hello World");
Serial.print("HAL Version = "); Serial.println(HAL_GetHalVersion());
}
void loop() {
process();
// put your main code here, to run repeatedly:
if (oneSecFlag) {
Serial.println("One Second Event");
Serial.print("millis() = "); Serial.println(millis());
oneSecFlag = false;
}
}
void process() {
static unsigned next_ms = 1000;
unsigned curr = millis();
if ( curr >= next_ms ) {
next_ms = (curr + 1000) - (curr % 1000);
oneSecFlag = true;
}
}
Assuming you are not already using all the other hardware timers, why don’t you just use one of the timers and configure it to interrupt every 50mS
Isn’t SerialEvent a complete misnomer in the Arduino API.
It just gets called in main after loop() returns
I checked STM’s core and thats how they handle it
https://github.com/stm32duino/Arduino_C … in.cpp#L54
i.e this has been a long standing issue, where people (me included) presumed that SerialEvent was an asynchronous call handler for Serial, but its not that at all.
extern "C" void HAL_SYSTICK_Callback(void) {...
SysTick_Handler is used, it is defined in clock.c:
/**
* @brief Function called when t he tick interruption falls
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
HAL_IncTick();
}In fact:
SysTick_Handler() call HAL_SYSTICK_IRQHandler() which call the HAL_SYSTICK_Callback()
So, as we need to define the SysTick_Handler to call the HAL_IncTick() (time base) I think it is not a good idea to try to change this behavior.
One solution could be to add the call of the HAL_SYSTICK_Callback() in the SysTick_Handler()
void SysTick_Handler(void)
{
HAL_IncTick();
HAL_SYSTICK_Callback();
}
Plus I use HAL_SYSTICK_Callback in FreeRTOS for xPortSysTickHandler too so it works out nicely.
I will raise a PR.
https://github.com/stm32duino/Arduino_C … /issues/98

