Skip to content

sensors-api: add lookup tables from SensorID to component ID/name - #2645

Open
hawkw wants to merge 6 commits into
masterfrom
eliza/turn-an-id-into-a-refdes
Open

sensors-api: add lookup tables from SensorID to component ID/name#2645
hawkw wants to merge 6 commits into
masterfrom
eliza/turn-an-id-into-a-refdes

Conversation

@hawkw

@hawkw hawkw commented Aug 17, 2026

Copy link
Copy Markdown
Member

As I described in #2364, there are several places (mostly in the thermal task for now, but this may change) where it is necessary to be able to go from a numeric, build-specific SensorId to a sensor name (stable, defined in the app.toml), or a ComponentId (the same, but also used for SP/MGS communication). This branch implements such a mechanism by enhancing the task-sensor-api build script with the (optional) ability to generate lookup tables mapping a sensor ID index to the corresponding component ID and/or sensor name strings. This is feature flagged so that only tasks that depend on the ability to look up these values can generate the LUTs.

While working on this, I also did a bit of refactoring to build-i2c; in particular, I changed it up so that we are now storing DeviceSensor in an Arc and using iddqd::IdOrdMap to store them, so that the ID field defined in the DeviceSensor struct need not be duplicated to serve as the map key. I think there's room to continue along these lines by adding newtypes that wrap an Arc<DeviceSensor> and implement IdOrdItem with all of the different key types by which we might look up a sensor, and replace some of the other maps with a similar pattern. I didn't do that here to keep the change fairly minimal, but I think there are a lot of places where we might benefit from using Rain's work on iddqd in the I2C codegen datastructures.

Also, it was necessary to add refdes strings to a few sensors in app.tomls that didn't previously have one. So I did that too.

Fixes #2364

@hawkw
hawkw requested a review from jamesmunns August 17, 2026 19:23
@hawkw

hawkw commented Aug 17, 2026

Copy link
Copy Markdown
Member Author

This is currently a draft because I need to figure out what to put in the (now mandatory) refdes field for Sidecar's QSFP temperature sensors.

@hawkw

hawkw commented Aug 17, 2026

Copy link
Copy Markdown
Member Author

using @jamesmunns's new xtask from #2644, we can see that there's no actual change to the build-i2c codegen. of course, the task-sensors-api will now include the new LUTs, if they're enabled:

eliza@hekate ~/Code/oxide/hubris $ cargo xtask i2c-codegen -d sensors --fmt --output cosmo-i2c-before.rs app/cosmo/rev-b.toml
    Finished `dev` profile [optimized + debuginfo] target(s) in 0.13s
     Running `target/debug/xtask i2c-codegen -d sensors --fmt --output cosmo-i2c-before.rs app/cosmo/rev-b.toml`
will invoke: /home/eliza/.rustup/toolchains/1.95.0-x86_64-unknown-linux-gnu/bin/rustfmt

eliza@hekate ~/Code/oxide/hubris $ git co eliza/turn-an-id-into-a-refdes
Switched to branch 'eliza/turn-an-id-into-a-refdes'
Your branch is ahead of 'origin/eliza/turn-an-id-into-a-refdes' by 4 commits.
  (use "git push" to publish your local commits)

eliza@hekate ~/Code/oxide/hubris $ cargo xtask i2c-codegen -d sensors --fmt --output cosmo-i2c-after.rs app/cosmo/rev-b.toml
   Compiling build-i2c v0.1.0 (/home/eliza/Code/oxide/hubris/build/i2c)
   Compiling xtask v1.0.0 (/home/eliza/Code/oxide/hubris/build/xtask)
    Finished `dev` profile [optimized + debuginfo] target(s) in 0.90s
     Running `target/debug/xtask i2c-codegen -d sensors --fmt --output cosmo-i2c-after.rs app/cosmo/rev-b.toml`
will invoke: /home/eliza/.rustup/toolchains/1.95.0-x86_64-unknown-linux-gnu/bin/rustfmt

eliza@hekate ~/Code/oxide/hubris $ diff cosmo-i2c-before.rs cosmo-i2c-after.rs

eliza@hekate ~/Code/oxide/hubris $ 

@hawkw
hawkw marked this pull request as ready for review August 17, 2026 21:31
@hawkw
hawkw requested a review from evan-oxide August 17, 2026 21:31

@jamesmunns jamesmunns left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall looks reasonable to me, added some suggestions.

At some point, I wonder if we should move the sensor-api and validate codegen into build-i2c, if for no other reason than to benefit from any refactoring and the ability to snapshot the output. I don't think that needs to be done in this PR, but might be something to keep in mind for #501.

Comment thread build/i2c/src/lib.rs
self.generate_footer()?;

Ok(self.output)
Ok((self.output, outputs))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it maybe make more sense to make CodegenOutputs contain both the output string as well as the sensors contents?

That way we could return a single struct instead of a tuple.

I guess then codegen_to_string doesn't make as much sense, but I'm open to other names.

Comment thread task/sensor-api/build.rs
build_i2c::codegen(build_i2c::Disposition::Sensors)?;
let i2c_outputs = build_i2c::codegen(build_i2c::Disposition::Sensors)?;

let i2c_sensors = i2c_outputs.sensors.expect(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't love that we have an Option field vs a different codegen method, but I also don't know if it's worth a more invasive change (yet).

It might be worth documenting that CodegenOutputs.sensors is only populated in Disposition::Sensors.

I do wonder if at some point we want to get rid of the disposition enum and have one codegen method per disposition instead.

Mostly thinking out loud, feel free to ignore for this PR if it's not worth it.

Comment thread task/sensor-api/build.rs
"{}_{}_{sensor_type}",
d.device.to_ascii_uppercase(),
d.name.to_ascii_uppercase(),
sensor_type.to_ascii_uppercase()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does it matter we lost the to_ascii_uppercase()?

#[cfg(feature = "component-id-lookup")]
pub fn component_id(
&self,
) -> fixedstr::FixedStr<'static, { config::MAX_COMPONENT_ID_LEN }> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could we get away with returning &'static fixedstr::FixedStr<'static, { config::MAX_COMPONENT_ID_LEN } here to avoid making a stack copy, if we're likely going to just copy this into some output structure anyway?

@jamesmunns

Copy link
Copy Markdown
Contributor

re-kicked CI, it looks like it timed out, likely due to github jank during the outage yesterday.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

unfortunately, a way to turn a SensorId into a refdes is probably required

2 participants