Comments (5)
Is there any reason why you want to count the edge interrupts in the interrupt routine? If not, then the routine can just notify a regular (yet maybe high priority) task/thread which can do the counting and the re-enablement of the interrupt for you?
from esp-idf-hal.
I'm using this for checking a fan tachometer signal generating one pulse per revolution. I don't know why I ended up using InterruptType::AnyEdge
in the first place but even with just checking for a positive or negative edge, at a speed of 3,000 rpm the interrupt still fires at 3 kHz. This already feels like being on the heavy side.
Using a separate task for counting and re-enabling the interrupt would add two context switches for each interrupt. I have not done the exact numbers yet. But wouldn't this be an an order of magnitude more instructions which need to be executed in this case?
What's the reason behind making it no longer possible to re-enable an interrupt from its handler?
Nevertheless, this was already a workaround in the first place on the ESP32-C3. As I don't need to monitor fan speed continuously, I would nowadays go for using the RMT peripheral in time sharing mode between driving the smart LED and checking the pulses from the fan tachometer in my application. And with the new ESP32-C6 i would just use the dedicated pulse counter.
from esp-idf-hal.
Is there any reason why you want to count the edge interrupts in the interrupt routine? If not, then the routine can just notify a regular (yet maybe high priority) task/thread which can do the counting and the re-enablement of the interrupt for you?
@ivmarkov I think this is not the intended use-case here by sirhcel. While it is possible to do that with a notify_and_yield(), the former way of just let it run and get notified eventually with notify is effected here. He wants to count it fast with as little overhead as possible, but don't need live updates for it, just wants to receive it sometime later ( using our async code would also relight on notify_and_yield so no direct option).
IIRC you introduced the changes to automatically disable interrupts, because of LEVEL_INTERRUPTS correct? Because a level interrupt will always trigger as long as the pin is held in that defined level ( That can lead to the system crashing if one stays in isr for to long).
I personally think we just crippled EDGE_INTERRUPTS, to make LEVEL_INTERRUPTS work like you would expect form a EDGE_INTERRUPT. But i think that is wrong because the initial assumption, that one just can use LEVEL_INTERRUPTS willy nilly is wrong. The purpose of them is they force the mcu in an interrupt as long as the line is hold and in my opinion serve a pretty specific niche. Obviously we can do with them whatever we want, as long as we make it workable. If i understand correctly your use-case is you want to trigger on something where you know that the line did potentially already switched level before you enabled the routine and just want to asynchronously now the level once?
I see three paths forward here:
- We make it depended on the type of INTERRUPT the user proved. On edge-trigger it does not disable interrupts. on level trigger disabling it and bending the definition of it to our own opinionated view of it.
- Don't disable INTERRUPT at all, and clearly communicate to the user what one should expect from a LEVEL_INTERRUPT.
- Don't change anything and stay on this highly opinionated implementation and force the users to always yield and re-enable with the extra overhead.
from esp-idf-hal.
- We make it depended on the type of INTERRUPT the user proved. On edge-trigger it does not disable interrupts. on level trigger disabling it and bending the definition of it to our own opinionated view of it.
- Don't disable INTERRUPT at all, and clearly communicate to the user what one should expect from a LEVEL_INTERRUPT.
The problem with these two is that if - for whatever reason - the user would like to disable/enable interrupts from the subscribe
callback, she would have no way of doing that as the driver is not available in the interrupt closure, and cannot be made available by e.g. a mutex protection, because, well, you are in an interrupt. While for (1) this might or might not be a problem, for (2) this is a show-stopper.
I think these two can only work if we extend the signature of the subscribe
closure in a way where it takes *mut PinDriver
. And yes, I do mean *mut
and not &mut
as the user would be potentially aliasing a mutable ref to the driver, as in "user space" the code might be mutably (or immutably) operating on the driver already, when the interrupt happens.
Other than that, I have to look whether the async code will continue to work correctly under the new constellation of not disabling the interrupts once the first one hits.
from esp-idf-hal.
I'm struggling with this too. Admittedly, I'm rather new to ESP32 and Rust and esp-idf-hal, so it is entirely possible I'm misunderstanding how to use the APIs and how the board works, etc.. Apologies in advance if that is the case. However, what I want to do is fairly simple, and the decision to make subscribe
effectively one-shot seems to be getting in the way of using what would otherwise be a really convenient API.
There is an independently changing variable (AtomicI32
shared with subscribe
callback via Arc
, say) that I want to read from in a subscribe
callback a when a GPIO gets driven high and then read again when it goes back to low, then report the change in the variable between those two events. The separation between these events is maybe rather small. I can subscribe
with AnyEdge
and the callback will capture the first transition, but the interrupt becomes disabled by processing the first edge, and my controlling logic (which maybe hasn't even gotten scheduled again and is still sitting in Notification::wait
) is now in a race to re-enable the interrupt and re-subscribe before the second transition arrives, which it loses. So I never see the falling edge.
If the interrupt was not auto-disabled after firing, I could just have the subscribe
callback stash the the value seen on the first interrupt somewhere, then do the notification to wake the waiter with the computed delta only after the second interrupt arrives.
Perhaps subscribe
and subscribe_nonstatic
should be restored to the original behavior, and new subscribe_once
and subscribe_once_nonstatic
could be added with the current semantics, if those are still considered desirable? Or maybe the one-shot-ness could remain be default-on but configurable and therefore you could opt out? Something like PinDriver::disable_oneshot
.
I'm also a little curious about the intended behavior of subscribe
with AnyEdge
, since you don't actually know in the interrupt callback whether you are there because of a PosEdge
or a NegEdge
type event, as far as I can see. It'd be nice to be able to, instead, subscribe to both PosEdge
and NegEdge
. That isn't possible though, as far as I can tell, because I believe you can only set_interrupt_type
once, then call subscribe
. So you can't subscribe separately to PosEdge
and NegEdge
if you need or want to tell them apart. And since the current implementation makes subscribe
one-shot, you can't reliably build a little state machine that'd track it for you from a known starting state.
from esp-idf-hal.
Related Issues (20)
- Problem with CHANGELOG.md in v0.43.0 release: Unable to find valid link for esp-ulp-riscv-hal crate. HOT 2
- Spi has some problems. or clk needs to pull up resistors、or other...(esp32c2 rust-std) HOT 3
- spi async need some config in the Cargo.toml and sdkconfig.defaults?
- Example uart_loopback does not compile. TX buffer managment in Uart is broken sending garbage characters. HOT 1
- Pin Direction Change compiles but does not seem to be working and produces weird Info Log messages that I can not supress: HOT 6
- I2C timeout calculated wrong for MCU !esp32 HOT 3
- AsyncCanDriver is not Sync HOT 7
- ESP32C6 analog read working wonky HOT 4
- Potential wrong core type conversion in cpu.rs
- [Discussed] SPI DMA,can it be used now? HOT 1
- UART read line example HOT 1
- esp32 - Spi Drivers freeze app and triggers TG1WDT_SYS_RESET HOT 3
- LEDC on ESP32: `SpeedMode` is currently a config, but it should actually be modelled as a peripheral HOT 2
- esp32c2 doesn't define XTAL_CFK_FREQ in esp-idf HOT 1
- esp32c2 generated bindgen doesn't include APB_CLK_FREQ correctly
- Uart rx buffer length error HOT 8
- Zigbee Support HOT 4
- rmt_neopixel.rs example doesn't work on ESP32-C3-DevKitC-02 when used in esp32-idf-template HOT 1
- When `feature = "std"` is enabled, implement std::io::Read and/or std::io::Write for all drivers where this makes sense HOT 2
- Add an option to set SPI clock pin to None HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from esp-idf-hal.