Skip to content

Conversation

@tullom
Copy link
Contributor

@tullom tullom commented Jan 14, 2026

Add support for examples with the pico-de-gallo development board.

This PR sets up a new workspace for pico-de-gallo examples and adds an example that runs the battery service with the bq40z50-r5 fuel gauge connected to the pico-de-gallo's I2C bus.

@tullom tullom self-assigned this Jan 14, 2026
@tullom tullom added the enhancement New feature or request label Jan 14, 2026
@github-actions
Copy link

github-actions bot commented Jan 14, 2026

Cargo Vet Audit Passed

cargo vet has passed in this PR. No new unvetted dependencies were found.

@github-actions github-actions bot added the cargo vet PRs pending auditor review label Jan 14, 2026
@tullom tullom force-pushed the pico-de-gallo-examples branch from 24a1cf5 to 4a630c5 Compare January 14, 2026 01:40
@tullom tullom moved this to In review in Embedded Controller Jan 14, 2026
@tullom tullom force-pushed the pico-de-gallo-examples branch from 08cc2a3 to b4db5a7 Compare January 14, 2026 17:56
@tullom tullom force-pushed the pico-de-gallo-examples branch from 7f0f011 to c925d15 Compare January 21, 2026 23:04

/// Platform specific battery controller.
struct Battery {
pub driver: Bq40z50R5<pico_de_gallo_hal::I2c, pico_de_gallo_hal::Delay>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't you use embedded_hal::i2c::I2c and embedded_hal::delay::DelayNs instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could make this struct generic on those traits but I consider this app level code, so the types should be resolved at this level. We don't want to construct multiple instances of Battery with differing types in this example.

@tullom tullom force-pushed the pico-de-gallo-examples branch from c925d15 to 6ef312a Compare January 22, 2026 18:52
@tullom tullom marked this pull request as ready for review January 22, 2026 21:03
@tullom tullom requested review from a team as code owners January 22, 2026 21:03
@tullom tullom requested a review from a team as a code owner January 22, 2026 23:36
kurtjd
kurtjd previously approved these changes Jan 23, 2026
@tullom
Copy link
Contributor Author

tullom commented Jan 23, 2026

Is the unsafe impl necessary now? Data might now be auto Send since its fields are Send. If it still is then disregard.

Yeah i tried without the unsafe impl but it is still needed. Not sure why because all its fields are Send but ¯\_(ツ)_/¯

@kurtjd
Copy link
Contributor

kurtjd commented Jan 23, 2026

Is the unsafe impl necessary now? Data might now be auto Send since its fields are Send. If it still is then disregard.

Yeah i tried without the unsafe impl but it is still needed. Not sure why because all its fields are Send but ¯_(ツ)_/¯

Not to beat a dead horse but I think actually the reason is because you take a reference. So for Data to be Send, the trait object in contents needs to be Sync as well (since an &T is Send only if T is Sync). So the unsafe impl may not necessarily be sound.

@tullom tullom force-pushed the pico-de-gallo-examples branch from daba71f to e2e9b0a Compare January 23, 2026 03:40
@tullom
Copy link
Contributor Author

tullom commented Jan 23, 2026

Is the unsafe impl necessary now? Data might now be auto Send since its fields are Send. If it still is then disregard.

Yeah i tried without the unsafe impl but it is still needed. Not sure why because all its fields are Send but ¯_(ツ)_/¯

Not to beat a dead horse but I think actually the reason is because you take a reference. So for Data to be Send, the trait object in contents needs to be Sync as well (since an &T is Send only if T is Sync). So the unsafe impl may not necessarily be sound.

Nah no dead horse, the horse is still alive and well. Reading more into Send and Sync, you are correct. T needs to be Sync for &T to be Send. Thus, i have put a Send + Sync bound on any data that is sent over the comms system. I can now remove the unsafe impl! Thanks for your resilience!

kurtjd
kurtjd previously approved these changes Jan 23, 2026
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Data<'a> {
contents: &'a dyn Any,
contents: &'a (dyn Any + Send + Sync),
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a breaking change, could you make sure to announce it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this necessary now?

Copy link
Contributor Author

@tullom tullom Jan 28, 2026

Choose a reason for hiding this comment

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

This is necessary because tokio's spawn function requires the spawned future to implement not just Future, but also Send. All our services use the comms service to enable message passing. Comms sends a static reference to a dyn Any. dyn will make the type opaque so adding the Send bound is required to ensure the object is thread safe. Furthermore, it needs to be Sync because we are sending a reference, and &T is Send iff T is Sync. Embassy doesn't have the same bound, maybe because it assumes a singly threaded environment?

RobertZ2011
RobertZ2011 previously approved these changes Jan 23, 2026
@tullom tullom dismissed stale reviews from RobertZ2011 and kurtjd via 268bd11 January 28, 2026 19:37
@tullom tullom force-pushed the pico-de-gallo-examples branch from 268bd11 to 3b49a5b Compare January 28, 2026 19:37

/// Use the battery service endpoint to send data to other subsystems and services.
pub async fn comms_send(endpoint_id: EndpointID, data: &impl Any) -> Result<(), Infallible> {
pub async fn comms_send(endpoint_id: EndpointID, data: &(impl Any + Send + Sync)) -> Result<(), Infallible> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: probably better to add a where clause there. Can be done in a follow-up PR.

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

Labels

cargo vet PRs pending auditor review enhancement New feature or request

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

6 participants