Mbed-os: Issue with clock speed for STM32 16 bits targets

Created on 25 Jun 2018  路  6Comments  路  Source: ARMmbed/mbed-os

Description

Since #7106, some RTC tests are now FAILED with targets supporting only 16 bits systick timer.

tests-mbed_hal-rtc | RTC - persist | 0 | 1 | FAIL | 8.08

First analysis:
During test, the "wait(4)" is expiring after 8 seconds

Currently, we don't understand the impact of this #7106 ,
but maybe the wait function have some issue with us_ticker using 16 bits counter ?

@c1728p9 @geky @bulislaw

Thx

Issue request type

  • [X] Bug
closed_in_jira drivers mirrored bug

All 6 comments

ARM Internal Ref: MBOTRIAGE-907

I made this trial:

I have replaced this:

uint32_t HAL_GetTick()
{
     return ticker_read_us(get_us_ticker_data()) / 1000; // 1 ms tick is required for ST HAL
}

with this:

uint32_t HAL_GetTick()
{
     return 0;
}

And all RTC tests are PASS again on NUCLEO_F103RB (use a 16-bit timer).

Unfortunately we can't do this as the HAL_GetTick function is called in the ST HAL driver for calculating timeouts. The main thing is that I don't understand what happens in here ?...

Hi @bcostm I took a more detailed look into this and it appears to be caused by HAL_InitTick resetting the ticker interrupt enable register - specifically TIM4_DIER from 0x2 to 0x0 on the stm32f103. This disables the interrupt that ticker_read_us uses to handle overflows. Because of this, any overflows that would normally be counted towards elapsed time are dropped while sleeping. This problem likely effects the 32 bit timer as well, its just overflows take so long you would need a really long delay to see it.

The reason the first call to us_ticker_set_interrupt() causes problems is because this is where the overflow handling is setup. If this is called after HAL_InitTick has been called then everything works normally. Since your code calls it before the second HAL_InitTick the interrupt it sets is turned off. For reference this is the callstack for where the overflow interrupt is initially set:

us_ticker_set_interrupt() at us_ticker.c:54
schedule_interrupt() at mbed_ticker_api.c:263
initialize() at mbed_ticker_api.c:75
ticker_read_us() at mbed_ticker_api.c:401
HAL_GetTick() at hal_tick_common.c:22
HAL_RCC_OscConfig() at stm32f1xx_hal_rcc.c:296
SetSysClock_PLL_HSE() at system_clock.c:182
SetSysClock() at system_clock.c:135
mbed_sdk_init() at mbed_overrides.c:5
software_init_hook() at mbed_boot.c:646
_start()

To fix this there are a couple of options I can think of:

  1. In HAL_GetTick use us_ticker_read directly rather than ticker_read_us(get_us_ticker_data()) so the overflow interrupt is never called during boot. Overflow will need to be handled manually
  2. Restore the interrupt enable flags and counter value on the second call to HAL_InitTick
  3. Use a mixed approach and use us_ticker_read directly until the SDK is ready and then switch to ticker_read_us(get_us_ticker_data()) so it handles rollover for you

Thanks for your analysis and proposals. Unfortunately I have checked all of them but there are always one or more RTC tests which fail... It's maybe because I didn't write it correctly or there are other things.
@jeromecoutant can you please check also ?

Update: the proposal 3 is working fine (the RTC tests are PASS and the HAL_Delay is OK). So, I'll send a PR with this fix. Thanks again !

@bcostm @c1728p9 馃嵕 馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hasnainvirk picture hasnainvirk  路  3Comments

ccchang12 picture ccchang12  路  4Comments

pilotak picture pilotak  路  3Comments

rbonghi picture rbonghi  路  3Comments

neilt6 picture neilt6  路  4Comments