[SOLVED]HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Please post bugs and enhancements for the STM core here
dackley
Posts: 12
Joined: Mon Jul 17, 2017 9:43 pm

[SOLVED]HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by dackley » Sun Sep 03, 2017 10:47 pm

The HAL_SYSTICK_Callback works on Nucleo-F103RB using STM32CubeMX/TrueSTUDIO, but not when using Arduino IDE with STM32Cores by ST-Microelectronics version 2017.8.31. The attached Arduino Sketch compiles without generating any error message, but the oneSecCount variable never gets decremented as shown in the Serial Monitor. My guess is that the GCC compiler in the Arduino IDE doesn't support the __weak attribute associated with the HAL_SYSTICK_Callback routine in the stm32f1xx_hal_cortex.c file.
Attachments
Serial Monitor.docx
Serial monitor output
(29.83 KiB) Downloaded 4 times
test_hal_systick_callback.ino
Arduino HAL_SYSTICK_Callback sketch
(625 Bytes) Downloaded 9 times

User avatar
RogerClark
Posts: 6681
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by RogerClark » Sun Sep 03, 2017 11:09 pm

Normally SYSTICK is used by millis() and delay() etc by the Arduino core, but I'm not sure if thats the case with STM's core.

dackley
Posts: 12
Joined: Mon Jul 17, 2017 9:43 pm

Re: HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by dackley » Mon Sep 04, 2017 1:28 am

Yes Arduino cores use one of it's timers for millis() and delay() while the STM32 cores have a dedicated SysTick timer for generating 1 msec interrupts. There are a number of HAL routines that support using this SysTick timer for managing scheduling tasks and one of them is the HAL_SYSTICK_Callback() function. For example if you at the C:\Users\<userName>\AppData\Local\Arduino15\packages\STM32\hardware\stm32\2017.8.31\system\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c file, you'll find the code for series of NVIC and SysTick related routines, including
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.

User avatar
Rick Kimball
Posts: 989
Joined: Tue Apr 28, 2015 1:26 am
Location: Eastern NC, US
Contact:

Re: HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by Rick Kimball » Mon Sep 04, 2017 1:35 am

While your approach might work with the HAL based core it really isn't very Arduino friendly. You could accomplish the same thing by making a call from your loop() function or by adding a SerialEvent handler function.

Code: Select all

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;
  }
}
-rick

User avatar
RogerClark
Posts: 6681
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by RogerClark » Mon Sep 04, 2017 2:50 am

@dackley

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

User avatar
RogerClark
Posts: 6681
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by RogerClark » Mon Sep 04, 2017 2:57 am

Rick

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.

danieleff
Posts: 336
Joined: Thu Sep 01, 2016 8:52 pm
Location: Hungary
Contact:

Re: HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by danieleff » Mon Sep 04, 2017 7:52 am

.ino files are compiled with cpp, so the names are mangled, try with C linkage:

Code: Select all

extern "C" void HAL_SYSTICK_Callback(void) {...

fpiSTM
Posts: 172
Joined: Fri Sep 16, 2016 12:33 pm
Location: Le Mans, France

Re: HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by fpiSTM » Mon Sep 04, 2017 9:31 am

In fact, HAL_SYSTICK_Callback is not used.
SysTick_Handler is used, it is defined in clock.c:

Code: Select all

/**
  * @brief  Function called when t he tick interruption falls
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
  HAL_IncTick();
}
Issue is not link to a WEAK issue.

I've comment the one in clock.c then defined new one in the sketch:

Code: Select all

extern "C" void SysTick_Handler(void)
{
  HAL_IncTick();
  if (oneSecCount-- <= 0) {
    oneSecFlag = true;
    oneSecCount = 1000;
  }
}
Then it's called.

fpiSTM
Posts: 172
Joined: Fri Sep 16, 2016 12:33 pm
Location: Le Mans, France

Re: HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by fpiSTM » Mon Sep 04, 2017 12:29 pm

I've checked how HAL_SYSTICK_Callback() is used on cube project:

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()

Code: Select all

void SysTick_Handler(void)
{
  HAL_IncTick();
  HAL_SYSTICK_Callback();
}
Then user can define it to extend the callback as it is a weak function.
But I don't know if it is a good idea to call one extra function in this handler.
I don't remember if the compiler will remove this call if function do nothing (weak one is empty) and this will be the most use case.

What do you think about this?

danieleff
Posts: 336
Joined: Thu Sep 01, 2016 8:52 pm
Location: Hungary
Contact:

Re: HAL_SYSTICK_Callback not working on Nucleo-F103RB in Arduino IDE

Post by danieleff » Mon Sep 04, 2017 12:39 pm

I have that SysTick_Handler() { HAL_IncTick();HAL_SYSTICK_Callback(); }, and had no problems so far.
Plus I use HAL_SYSTICK_Callback in FreeRTOS for xPortSysTickHandler too so it works out nicely.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest