-
Notifications
You must be signed in to change notification settings - Fork 7.6k
[2.0.0] Adds the setRXInterrupt #4656
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
Conversation
Update of code
I'll take a look at the failing tests after X-mass |
Thanks for doing this! I've wanted this feature for awhile |
I'm working on a rewrite, which makes it easier to manage the interrupt functions. |
Please note my comments and revers all code style changes. Stick to the style in the files and change only what is necessary for this to work. I can not review this request as-is. |
Are you able to merge it? |
it looks good - and when this issue was first raised (in another post, a year or two ago) I got so frustrated I just junked the whole serial class and did my own.. Polling for input in your top program is just so not the way to go.. |
Coming in 2.0.0 almost everything will be event based. I'm thinking that events are probably the best solution here also. They are thread-safe and can still access the RX Queue. Events can come based on different factors (byte received, transmission done, queue full, etc.). What do you think? |
Yes, Yes, and Yes. Events are the way to go (not interrupts, that was OK for a short term solution) - the one I wrote to replace the arduino-esp32 one was event based, with a queue. We have to get everyone away from thinking about a single task with polling, it simply isn't the way to use hardware this powerful, let alone the way to use more than 1 core, and all those nice hardware bits.. And events are much nicer than interrupts in most cases. |
For the sake of unified code, I think that is good practice. Are you going to change it up to events? |
@timkoers yes I will :) do not close this PR so it reminds me of it. |
|
Serial.begin(115200); | ||
Serial2.begin(115200); | ||
|
||
Serial2.setRxInterrupt(onSerialRX, NULL); |
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.
@timkoers I tested the code and it is working fine. I have only one issue at this point during Setup initilization... it sometimes stop at setrxInterrupt function. When I delete Serial2.begin and Serial2.setRxInterrupt -> upload the code -> then add Serial2.begin and Serial2.setRxInterrupt -> upload the code, everything starts to work fine again... I'm trying to figure out why this is happening...
SerialHardware and HAL have changed to work over IDF 4.4 layer. Another way to solve it would be creating Example: A potential solution is being implemented. As soon as any data arrives UART RX, Example: void UART_RX_IRQ(){
uint16_t size = Serial.available();
Serial.printf("Got %d bytes on Serial to read\n", size);
while(Serial.available()) {
Serial.write(Serial.read());
}
Serial.printf("\nSerial data processed!\n");
}
void setup() {
Serial.begin(115200);
Serial.onReceive(UART_RX_IRQ);
Serial.println("Send data to UART0 in order to activate the RX callback");
}
void loop() {
Serial.println("Sleeping for 10 seconds...");
delay(10000);
} |
I I said above - it shouldn't be an interrupt, it should be either a queue that you can wait on ie xQueueReceive, or an event that you can also wait on. I wrote my own quite a while ago, you do a uart_driver_install, then have a task waiting on that queue, then a task that waits on that to copy it over to another queue for the user program (doing a logical packet at a time), with an optional event. Works great and NO polling OR interrupts.. Waiting on something is much better than interrupts for these types of things, though maybe I think that because I've been writing multi threaded programs for 40 years... It's too limiting trying to process things in an interrupt, which often means you'd just have to raise an event in that anyway... (And I don't mean a volatile bool that you do polling on type of event!!) |
Hi @ianr34 The Arduino API will be the So everything will be done exactly as you described above. It will work correctly with FreeRTOS, IDF and Arduino. Thanks for your contribution! |
thanks - I'd missed the fact it was a callback, not an interrupt (or a callback from an interrupt) - which means they can spend as much time in it as they need to.. Though of course they will need to be processing fast enough that the serial queue doesn't fill up waiting for this callback to return (I assume in most cases they will be reading the queue in this callback) .. :-) |
Yes, exactly. The only potential issue is when the callback never returns and blocks the UART Event Task. But it won't cause any issue to the UART ISR and neither to the regular Arduino Sketch that is running in a separated task as well (or to any other task running within the application). Maybe some WDT will complain about the UART Event Task in the FreeRTOS runtime. I think it's a safe solution. Let me know if you think about any other potential issue in order to consider it when implementing it. |
Should fix pull request #3376
I haven't tested the code yet myself, but feel free to review