Work around SysTick bug for QEMU ARMv8-M #724
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Work around SysTick bug for QEMU ARMv8-M
Description
QEMU versions older than 7.0.0 contain a bug which causes an emulation error and application failure if port code enables SysTick without first selecting a valid clock source. Prior to this PR, the port code triggered the bug by attempting to change clock sources from a clock with a zero clock period (the "alternate" clock) to one with a nonzero clock period (the core clock) and enable SysTick at the same time. After this PR, the port configures the CLKSOURCE bit first and then sets the ENABLE bit. This workaround avoids the bug in QEMU versions older than 7.0.0.
QEMU versions 7.0.0 and newer are not (easily) available to the current LTS version of Ubuntu (22.04). So a workaround is appropriate.
It seems this QEMU bug does not affect ARMv6-M and ARMv7-M targets. Apparently that is because QEMU forces the CLKSOURCE bit to 1 for any write by the port code for those targets. The port code attempts to write a zero before enabling the SysTick so QEMU is setting the CLKSOURCE bit early for us on those ports.
Note that the QEMU bug cannot be triggered by the tickless-idle code, even though that code enables/disables SysTick freely and even changes the clock source temporarily when the user's FreeRTOS configuration selects the "alternate" clock. The tickless-idle code avoids the bug for both clock configurations:
vPortSetupTimerInterrupt()
indicating the selected clock has a zero clock period, which is the right message for the user's invalid FreeRTOS config. It's important to note that the bug is not triggered by merely changing the CLKSOURCE bit while simultaneously enabling SysTick. Instead, the bug is triggered by changing from an invalid clock to a valid clock while simultaneously enabling SysTick.Test Steps
Checklist:
Related Issue
If merged, should probably close #660.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.