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

sensors: Fix overflow in default decoder #61186

Merged
merged 1 commit into from
Aug 9, 2023

Conversation

yperess
Copy link
Collaborator

@yperess yperess commented Aug 6, 2023

The default decoder would take the micro-unit value of the old sensor
value and multiply it by INT32_MAX. This would, at times, cause an
overflow for the int64_t which is the cause of some bugs like when
-7952 was used (-7952000000 * INT32_MAX < INT64_MIN). Instead the new
math converts:

  • value_u * INT32_MAX / ((1 << header->shift) * 1000000)

to a bitmap:

  • sample.val1 consumes the upper N bits
  • sample.val2 * BIT(32 - N) / 1000000 consumes the lower 32-N
    bits

This both improves the accuracy, and avoids the overflow since
shift is guaranteed to be between 0 and 31.

@yperess
Copy link
Collaborator Author

yperess commented Aug 6, 2023

@bperseghetti this is the hotfix. I'm going to work on unit tests, but I wanted to get the fix for you ASAP.

@yperess yperess force-pushed the peress/sensor_value branch from 537dca5 to 85ccedf Compare August 6, 2023 06:31
@yperess
Copy link
Collaborator Author

yperess commented Aug 6, 2023

Math for computing the Q value was updated with slight improved accuracy.

The default decoder would take the micro-unit value of the old sensor
value and multiply it by INT32_MAX. This would, at times, cause an
overflow for the int64_t which is the cause of some bugs like when
-7952 was used (-7952000000 * INT32_MAX < INT64_MIN). Instead the new
math converts:
- `value_u * INT32_MAX / ((1 << header->shift) * 1000000)`

to a bitmap:
- `sample.val1` consumes the upper `N` bits
- `sample.val2 * BIT(32 - N) / 1000000` consumes the lower `32-N`
    bits

This both improves the accuracy, and avoids the overflow since
`shift` is guaranteed to be between 0 and 31.

Signed-off-by: Yuval Peress <peress@google.com>
@teburd
Copy link
Collaborator

teburd commented Aug 7, 2023

Is there an easy edge case that can be tested for this?

@yperess
Copy link
Collaborator Author

yperess commented Aug 7, 2023

Is there an easy edge case that can be tested for this?

I want to set up a test for the default decoder separate from the sensor tests that @tristan-google is working on, but to be completely transparent I'm on vacation and I wanted to do the bare minimum to fix the issue that was found.

I manually tested it by overriding the value from the akm sensor on the TDK board and checking several values at different orders of magnitude.

drivers/sensor/default_rtio_sensor.c Show resolved Hide resolved
@fabiobaltieri fabiobaltieri merged commit b2a78ff into zephyrproject-rtos:main Aug 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants