-
Notifications
You must be signed in to change notification settings - Fork 185
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
Internal temperature sensor #478
Conversation
Code is very rudimentary and still suspect to change. Notably, error handling is not implemented yet.
Thanks a lot! However, the CI fails on a number of chips, you need to look into what is wrong there. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most important feedback is w.r.t. the fact that this driver does not take any peripheral, because it does not even define/model the internal temperature sensor peripheral.
Since every other driver in esp-idf-hal
takes a peripheral, we should do this here as well. Lok in the other drivers as to how to model a peripheral, it is not complex at all, and there are macros that do this.
#[cfg(not(any(esp32)))] | ||
#[derive(Copy, Clone)] | ||
/// Rust wrapper for `temperature_sensor_config_t` | ||
pub struct TemperatureSensorConfig { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Please also provide a
const new()
constructor function so that folks can use aconst
TemperatureSensorConfig
.Default
can then delegate to thisnew
constructor - Please move the
TemperatureSensorConfig
to its own miniconfig
mod, as we do everywhere and rename to justconfig
. You should then also dopub type TemperatureSensorConfig = config::Config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/temp_sensor.rs
Outdated
// -- TemperatureSensorConfig -- | ||
|
||
#[cfg(not(any(esp32)))] | ||
#[derive(Copy, Clone)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Remove the
Copy
derivation - Add a
Debug
derivation and why notPartialEq
,Eq
andHash
src/temp_sensor.rs
Outdated
|
||
// -- TemperatureSensorClockSource -- | ||
|
||
#[derive(Copy, Clone)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add Debug, Eq, PartialEq, Hash
|
||
#[cfg(not(any(esp32)))] | ||
impl TemperatureSensorDriver { | ||
pub fn new(config: TemperatureSensorConfig) -> Result<Self, EspError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take the config by &
as we do everywhere else. You might need to change your From
trait impl after that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done(ish) in 4d34e0e
See #337 (comment) for further discussion.
} | ||
|
||
#[cfg(not(any(esp32)))] | ||
impl TemperatureSensorDriver { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the first driver that does not take any peripheral.
So here's the question: what happens if I try to instantiate the driver twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from the documentation:
In the temperature sensor driver, we do not add any protection to ensure the thread safety, because typically this driver is only supposed to be used in one task. If you have to use this driver in different tasks, please add extra locks to protect it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'm asking for does not have anything to do with thread (un)safety.
Thread unsafety is correctly modeled already by:
- the driver taking
&mut
refs everywhere - the driver containing a raw pointer (
ptr
) which makes it!Sync
(Before I forget: the driver however needs an unsafe impl Send for TemperatureSensorDriver {}
because currently it is also !Send
due to the above mentioned ptr
. However, there is nothing that stops the driver from being Send
so we should mark it as such.)
What I'm talking about is - consider this:
let driver1 = TemperatureSensorDriver::new()?;
let driver2 = TemperatureSensorDriver::new()?; // Will likely fail with a runtime error because the C driver is already installed
// there is a deeper problem here however - what if you try to call `TemperatureSensorDriver::new`
// from TWO separate threads, and thus the two calls race each other?
// If the C call `temperature_sensor_install` is itself thread-safe, that would work and one of these calls will fail,
// while the other will succeed; however if it is not thread-safe, you might end up with memory corruption or even worse things
The fact the second driver instantiation fails is OK because it does not make sense to have multiple drivers for a single peripheral. However, esp-idf-hal
goes one step further than that: every driver takes a peripheral. This way - even if you wanted to instantiate the driver twice, you cannot. At compile time. Including from multiple threads, as only one of the thread can "own" the peripheral at any point in time. I suggest (again) to take a look at the other drivers as to how to model a peripheral.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, and if you are struggling with the "peripheral" thing:
- You only need to copy-paste this line in your
temp_sensor
module. But instead ofHallSensor
of course useTemperatureSensor
for the peripheral name. - Then, you just need to add the
TemperatureSensor
as atemperature_sensor
member in thePeripherals
structure, and then change theTemperatureSensorDriver::new
to take the peripheral, using theimpl Peripheral<P = TemperatureSensor> + 'd
magic you can copy from everywhere (this allows the driver to take the peripheral either by move, or by&mut
). - Update: you'll also need a
_p: PhantomData<&'d mut ()>
in the driver and the driver should becomeTemperatureSensorDriver<'d>
(i.e. lifetimed by'd
). If you don't know what this is - don't worry - just copy-paste it from elsewhere. I'll help if you have compilation issues.
Also, what do you think about renaming TemperatureSensor*
everywhere to just TempSensor*
?
TemperatureSensor
is a bit too long- Module is already named
temp_sensor
(The peripheral instance in the Peripherals
struct can then also be named temp_sensor
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, what do you think about renaming TemperatureSensor* everywhere to just TempSensor*?
Done in 85f6a7c
Ok(val) | ||
} | ||
|
||
pub fn get_fahrenheit(&self) -> Result<f32, EspError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I would not, but I just did the rebase so I'd wait for the original author. @GamerBene19 do you have time to complete it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't follow. :)
Do you plan to finish this PR, or you just rebased and plan to leave it as-is, leaving it in open state? If the latter, it would likely just rot as the original PR did, as nobody else might have the time to complete it for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this?
(Also replying for kelvin below)
Since I "passed through" the naming of the implementation from espressif (which contains "_celcius") I thought it wouldn't hurt to have these functions available to users of the library for convenience.
If that's not a thing you do in this project we can leave it out. I don't have any strong preference in either direction.
do you have time to complete it?
See #337 (comment): TL;DR Yes, but I likely need some assistance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure and I'll assist. As I posted in the other comment - it does not need a huge amount of work anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Peripheral implemented in cd015dc.
Ok((celsius * 1.8) + 32.0) | ||
} | ||
|
||
pub fn get_kelvin(&self) -> Result<f32, EspError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And especially this? This is utility code that probably does not belong in the driver. User can do the math themselves.
It looks like esp32c2/esp32c6/esp32h2 support this feature. |
Fair enough. Looks like the sensor is supported on everything else, but the original esp32. You'll still have to repeat it unfortunately inside |
Also, regardless whether the temp sensor is supported or not on some MCUs, the CI should not fail. In fact, the |
d1953e2
to
83a1e66
Compare
83a1e66
to
189ff77
Compare
Let's move back to #337 |
Rebase of #337