Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ticker computation use shift-by-0 #14532

Merged
merged 1 commit into from
Apr 13, 2021
Merged

Conversation

kjbracey
Copy link
Contributor

@kjbracey kjbracey commented Apr 12, 2021

Summary of changes

Runtime code that analysed clock frequency to determine numerator and denominator for conversion to standard 1MHz failed to handle the case of either being 1 correctly.

Although it would spot other values that could be performed as shifts, it failed to spot that 1 is "shift by 0", so would end up doing runtime multiply and/or divide by 1. The runtime divide by 1 could be slow on a Cortex-M0 device, increasing interrupt latency.

UART character loss on STM32F0 devices has been traced to this incorrect code.

Correct the exact_log2 routine so that exact_log2(1) returns 0 to fix this.

Original code had a single special no-multiply-or-divide case for hardware clock frequency being exactly 1MHz, as USTICKER is on STM32F0 - this code lacks that but has a more general special case that covers all shift-convertible frequencies like 500kHz or 8MHz, which should be similar speed as shifts are cheap.

Impact of changes

Fixes #14489.

Documentation

None


Pull request type

[X] Patch update (Bug fix / Target update / Docs update / Test update / Refactor)
[] Feature update (New feature / Functionality change / New API)
[] Major update (Breaking change E.g. Return code change / API behaviour change)

Test results

[] No Tests required for this change (E.g docs only update)
[X] Covered by existing mbed-os tests (Greentea or Unittest)
[] Tests / results supplied as part of this PR

Reviewers

@SibertEnovates @jeromecoutant


Runtime code that analysed clock frequency to determine numerator and
denominator for conversion to standard 1MHz failed to handle the case
of either being 1 correctly.

Although it would spot other values that could be performed as shifts,
it failed to spot that 1 is "shift by 0", so would end up doing runtime
multiply and/or divide by 1. The runtime divide by 1 could be slow on a
Cortex-M0 device, increasing interrupt latency.

UART character loss on STM32F0 devices has been traced to this incorrect
code.

Correct the `exact_log2` routine so that `exact_log2(1)` returns 0 to
fix this.

Original code had a single special no-multiply-or-divide case for
hardware clock frequency being exactly 1MHz, as USTICKER is on STM32F0 -
this code lacks that but has a more general special case that covers all
shift-convertible frequencies like 500kHz or 8MHz, which should be
similar speed as shifts are cheap.
@ciarmcom ciarmcom added the release-type: patch Indentifies a PR as containing just a patch label Apr 12, 2021
@ciarmcom ciarmcom requested review from jeromecoutant and a team April 12, 2021 07:00
@ciarmcom
Copy link
Member

@kjbracey-arm, thank you for your changes.
@jeromecoutant @ARMmbed/mbed-os-maintainers please review.

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 12, 2021

Nice find !

Shall this add a test case for this bugfix?

Copy link
Collaborator

@jeromecoutant jeromecoutant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes hal-tests-tests-mbed_hal-common_tickers OK for STM32F0!
Thx

@kjbracey
Copy link
Contributor Author

kjbracey commented Apr 12, 2021

Shall this add a test case for this bugfix?

Well, @jeromecoutant was reporting a failure in an existing test on one platform - see #12897, but that was rather indirect, and it's actually possible it isn't fixed by this.

We already have a bunch of stuff that checks that timers run at the right speed - that we get the correct answer, but those only run with custom-tickers true. So the gaps are "are runtime optimisations kicking in correctly" and "does compile-time-optimised code activate or work at all?".

The runtime optimisations can be checked with a single test that creates a bunch of custom tickers with different frequencies and checks the ticker_event_queue_t members period_num, period_den, period_num_shifts and period_den_shifts. That would pick up this fix.

Going beyond that, testing compile-time stuff is tougher. You'd need particular custom targets with particular frequencies to fully exercise it.

At the minute the compile-time optimisations are not exercised by tests at all, except that we cross-check targets to ensure they have their defines set correctly (if they provide them - they're not currently required to).

A start would be to have at least some us_ticker tests compiled with custom-tickers: false to give them a chance to activate. Strip down the existing us_ticker tests to do just whatever they can without the custom ticker wrappers they use, and perform the same sort of timer cross-checks.

Then to check if compile-time optimisation is kicking in as expected, I don't know - you'd want to check that certain members of ticker_event_queue_t didn't exist, or you'd have to monitor the various result macros. And you'd have to know what to expect for each target in a set of targets.

Copy link
Contributor

@Patater Patater left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mergify mergify bot added needs: CI and removed needs: review labels Apr 12, 2021
@0xc0170
Copy link
Contributor

0xc0170 commented Apr 12, 2021

CI started

@mbed-ci
Copy link

mbed-ci commented Apr 12, 2021

Jenkins CI Test : ❌ FAILED

Build Number: 1 | 🔒 Jenkins CI Job | 🌐 Logs & Artifacts

CLICK for Detailed Summary

jobs Status
jenkins-ci/mbed-os-ci_unittests ✔️
jenkins-ci/mbed-os-ci_cmake-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-test ✔️
jenkins-ci/mbed-os-ci_greentea-test

@mergify mergify bot added needs: work and removed needs: CI labels Apr 12, 2021
jeromecoutant added a commit to jeromecoutant/mbed that referenced this pull request Apr 12, 2021
@0xc0170
Copy link
Contributor

0xc0170 commented Apr 13, 2021

CI restarted

@mbed-ci
Copy link

mbed-ci commented Apr 13, 2021

Jenkins CI Test : ✔️ SUCCESS

Build Number: 2 | 🔒 Jenkins CI Job | 🌐 Logs & Artifacts

CLICK for Detailed Summary

jobs Status
jenkins-ci/mbed-os-ci_unittests ✔️
jenkins-ci/mbed-os-ci_cmake-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_greentea-test ✔️
jenkins-ci/mbed-os-ci_cmake-example-test ✔️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Changes in Ticker cause UART to fail
8 participants