cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5A5: AZURE RTOS and 1ms ticks - how to set?

tjaekel
Lead

I am confused: I want to have 1ms AZURE RTOS tick timer - but no idea how to set.

What I see:

  1. AZURE RTOS defines 10ms tick timer (UX_PERIOD_RATE, TX_TIMER_TICK_PER_SECOND)
  2. I see as well, when using tx_thread_sleep(1000); - it sleeps 10 second (not 1) - OK, obvious with 100 set for all the AZURE RTOS timer configs (macros)
  3. But I cannot force to get 1ms ticks: even I change all macros I could find, e.g. UX_PERIODIC_RATE, TX_TIMER_TICKS_PER_SECOND to 1000 - this happens:

I see the TIM6 INT comes fast, assuming with 1ms period (I debug with toggling a LED in TIM6 INT). But after a short period of time (approx. 1...2sec) the TIM6 INT changes to something like 10Hz (much slower now and I can see the LED toggle).
I can clearly see the LED toggling and my "delay" command (which should wait for X milli-seconds) is still wrong.

Questions:

  • how to change to a 1ms tick timer (for AZURE RTOS)?
  • can it be that the TIM is reconfigured by a LIB function? (to a much slower rate)
    It do not find anything in source code which touches TIM6 (just: the initialization is called twice, OK, I see where and why: 1st: HAL_Init(), 2nd: SystemClock_Config() - but both are needed to do!

Very strange. If I do not call MX_ThreadX_Init(); - the TIM6 seems to be configure properly and seems to come with 1KHz. But later, the AZURE RTOS seems to change to a much slower frequency.

Why?
And where to change to 1KHz timer tick (for RTOS, using TIM6)?

 

1 ACCEPTED SOLUTION

Accepted Solutions

Thank you.
Yes, searching for SYSTEM_CLOCK in all files, including assembler files! and changing everywhere to:

SYSTEM_CLOCK      =   160000000
SYSTICK_CYCLES    =   ((SYSTEM_CLOCK / 1000) -1)

(see the change from 100 to 1000)

has solved the issue:
Now, my systick for AZURE RTOS seems to come with 1 KHz frequency: my LEDs, toggling between both with systick, are now on (not visible to see they toggle). 

And my "delay" function on command line (wait x ms) is now correct.

Cool. Thank you.

View solution in original post

4 REPLIES 4
tjaekel
Lead

Just to add:

I assume this "behavior" comes from the LIB file: the LIB I use is: "USBPDCORE_NOPD_CM33_wc32.a"

I assume: the code enters a "low power mode" which changes also the SysTick timer frequency:

  • if I keep the FW busy, e.g. sending permanently something via VCP UART (project is using ACM/VCP UART) - it works fine (the TIM6 INT comes very fast, I cannot resolve LED toggling with my eyes anymore)
  • Just if MCU FW (AZURE RTOS) sees large gaps between activated threads (not sending, not receiving on USB) - it seems to change the timing for ticks

Even I see a file "tx_thread_schedule.S" with a macro used as TX_LOW_POWER, calling function tx_low_power_enter():

  • I cannot see that the macro TX_LOW_POWER is defined anywhere (I do not find it anywhere in project settings and source code)
  • even doing an undef (via project setting) - it does not change anything.

Therefore, I assume: this "behavior" (that TIM6 frequency and tick INT frequency is changed to a much slower rate) sits somewhere in a LIB code (without to have a look how and where, no source code provided).

It remains this question:

How to configure AZURE RTOS to keep going with 1ms tick counters, to have a delay function based on 1KHz and to see TIM6 INT (used as Tick Timer) remains on 1 KHz? (all the time)

Sarra.S
ST Employee

Hello @tjaekel

I'm not an expert in this, but I can suggest something, maybe instead of changing #define BSP_TICKS_PER_SECOND to 1000 instead of 100, try changing the period register of the timer you're using (TIM6), and once you do that, you'll have to also change the define to be consistent with the new period 

maybe the inconsistency is what makes TIM6 slower 

>>I cannot see that the macro TX_LOW_POWER is defined anywhere (I do not find it anywhere in project settings and source code)

I think TX_LOW_POWER is in threadx/utility/low_power/ file and it should be imported to the project, this wiki talks about the low power feature, I think it's quite clear and helpful 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi

Some hints:

If you use Azure RTOS, there are two ticks: the STM32 HAL tick and Azure RTOS / ThreadX tick.

When the HAL is alone (no RTOS) it uses ARM Cortex M's "Systick" timer.

When Azure RTOS / ThreadX is present, it requires Systick. So the HAL has to use another timer (for example TIM6 ).

If your code uses tx_thread_sleep(), then it depends from ThreadX tick (Systick).

If your code uses HAL_Delay() then it depends from HAL tick (TIM6).

Azure RTOS configures Systick in tx_initialize_low_level.S. It can come from  Middlewares\ST\threadx\ports\cortex_m33\gnu\src\tx_initialize_low_level.S or you can make a copy in your own project source directories to modify it. This assembler file uses  SYSTICK_CYCLES and SYSTEM_CLOCK constants. Example:

SYSTEM_CLOCK = 160000000    // 160 MHz
SYSTICK_CYCLES = ((SYSTEM_CLOCK / 100) -1)

if you change the Azure RTOS tick to 1000 Hz then you must change SYSTICK_CYCLES definition in tx_initialize_low_level.S : SYSTICK_CYCLES = ((SYSTEM_CLOCK / 1000) -1). Of course, TX_TIMER_TICK_PER_SECOND must also be updated.

Also, SYSTEM_CLOCK must correspond to the system clock . See SystemClock_Config() in main.c and SystemCoreClock global variable. If you use STM32CubeMX to generate the sources, the clock configuration tool may help to know the actual system clock.

 

Another point: ThreadX uses PendSV interrupt for scheduling. it sets PendSV interrupt priority to lowest (15). Make sure to set TIM6 to higher priority (for example :14 (14 is higher priority than 15)).

It's TICK_INT_PRIORITY in stm32u5xx_hal_conf.h.

If PendSV and TIM6 have same priority they will fight for CPU.

 

Thank you.
Yes, searching for SYSTEM_CLOCK in all files, including assembler files! and changing everywhere to:

SYSTEM_CLOCK      =   160000000
SYSTICK_CYCLES    =   ((SYSTEM_CLOCK / 1000) -1)

(see the change from 100 to 1000)

has solved the issue:
Now, my systick for AZURE RTOS seems to come with 1 KHz frequency: my LEDs, toggling between both with systick, are now on (not visible to see they toggle). 

And my "delay" function on command line (wait x ms) is now correct.

Cool. Thank you.