arduino / ArduinoCore-renesas

MIT License
109 stars 74 forks source link

[UNO R4 WIFI] - periodicCallback() does not seem to work correctly as long as it includes Serial.println(). #138

Open eMUQI opened 12 months ago

eMUQI commented 12 months ago

Hello everyone, when I tried to run the example in https://docs.arduino.cc/tutorials/uno-r4-wifi/rtc#Periodic-Interrupt, I found some errors in it.

In order to make the code run correctly, I made modifications to the code. The modified code is as follows:

// Include the RTC library
#include "RTC.h"

const int led = LED_BUILTIN;

void setup() {
  pinMode(led, OUTPUT);

  Serial.begin(9600);

  // Initialize the RTC
  RTC.begin();

  // RTC.setTime() must be called for RTC.setPeriodicCallback to work, but it doesn't matter
  // what date and time it's set to
  RTCTime mytime(30, Month::JUNE, 2023, 13, 37, 00, DayOfWeek::WEDNESDAY, SaveLight::SAVING_TIME_ACTIVE);
  RTC.setTime(mytime);

  if (!RTC.setPeriodicCallback(periodicCallback, Period::ONCE_EVERY_2_SEC)) {
    Serial.println("ERROR: periodic callback not set");
  }
}

void loop() {
}

// This is the callback function to be passed to RTC.setPeriodicCallback()
void periodicCallback()
{
  static bool ledState = false;
  if (ledState == true) {
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else {
    digitalWrite(LED_BUILTIN, LOW);
  }
  ledState = !ledState;

  Serial.println("PERIODIC INTERRUPT");
}

Unfortunately, when I uploaded the code to my Arduino R4 WiFi, its performance did not meet expectations.The LED did not blink at a two-second interval and it was unable to print the complete message on the serial monitor. However, when I uploaded this code to Uno R4 Minima, everything worked fine. (Additional information: The firmware version of Arduino R4 WiFi is 0.3.0, and the library version displayed in the board manager is 1.0.4.)

Another strange thing is that when I comment out the line of code Serial.println("PERIODIC INTERRUPT"); in the periodicCallback() function, the LED can blink once every two seconds as expected.

Does anyone know why this is? Or has anyone done the same test on the R4 wifi board? Thank you very much for any help.

156372dc3448e24e7c88397cd2bde6d6286fe72d_2_664x499

I also reported this issue on the Arduino community forum, see this link.

A kind-hearted person tested my code and obtained the same result. https://forum.arduino.cc/t/there-may-be-some-conflict-between-rtc-and-the-serial/1169836/5?u=wulu

Fashion-Corp commented 12 months ago

Dear Arduino'ers

Yes this is a very known problem related to that many codes written are not reentrant.

Meaning.

When you do Serial.print() in your particular context from your main code and then an interrupt arrives which also calls the same print statement, then the print algorithm messes up.

You are at dire risk of that your entire code screws up.

What you will do is to create a code which queues all print requests and then that code you make it reentrant or make it do it's shared value updates during non interrupted code.

If you switch off the interrupts though, then you will on most processors at some point be missing an interrupt if it occurs at the time when interrupts are switched off.

This depends on hardware and software architecture.

Some architectures remembers the interrupt so that when you switch back on interrupts then right there the interrupt is then triggered.

The literature is full of conversations on how to deal with this. There is no "one size fits all" here... However if you have particular questions you are warmly welcome.

I have a code which does the queued printing with a microscopic interrupt protected zone, likely taking up an instruction only. If you can guide me as to how I create a library out of it, I will do that even right away and upload it so everyone can benefit.

If you can guide me so as to how I can make modifications to the Serial.print and Serial.println so as to make them reentrant then I will do so.

But I do not know enough about the development policies of Arduino. I've seen that a great champ Mr. Faccine I think his name is, is in charge, it appears, but I would not know how to approach it.

Sincerely David Svarrer

On Tue, 19 Sep 2023, 10:16 Wulu, @.***> wrote:

Hello everyone, when I tried to run the example in https://docs.arduino.cc/tutorials/uno-r4-wifi/rtc#Periodic-Interrupt, I found some errors in it.

In order to make the code run correctly, I made modifications to the code. The modified code is as follows:

// Include the RTC library

include "RTC.h"

const int led = LED_BUILTIN;

void setup() { pinMode(led, OUTPUT);

Serial.begin(9600);

// Initialize the RTC RTC.begin();

// RTC.setTime() must be called for RTC.setPeriodicCallback to work, but it doesn't matter // what date and time it's set to RTCTime mytime(30, Month::JUNE, 2023, 13, 37, 00, DayOfWeek::WEDNESDAY, SaveLight::SAVING_TIME_ACTIVE); RTC.setTime(mytime);

if (!RTC.setPeriodicCallback(periodicCallback, Period::ONCE_EVERY_2_SEC)) { Serial.println("ERROR: periodic callback not set"); } }

void loop() { }

// This is the callback function to be passed to RTC.setPeriodicCallback() void periodicCallback() { static bool ledState = false; if (ledState == true) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } ledState = !ledState;

Serial.println("PERIODIC INTERRUPT"); }

Unfortunately, when I uploaded the code to my Arduino R4 WiFi, its performance did not meet expectations.The LED did not blink at a two-second interval and it was unable to print the complete message on the serial monitor. However, when I uploaded this code to Uno R4 Minimal, everything worked fine. (Additional information: The firmware version of Arduino R4 WiFi is 0.3.0, and the library version displayed in the board manager is 1.0.4.)

Another strange thing is that when I comment out the line of code Serial.println("PERIODIC INTERRUPT"); in the periodicCallback() function, the LED can blink once every two seconds as expected.

Does anyone know why this is? Or has anyone done the same test on the R4 wifi board? Thank you very much for any help.

[image: 156372dc3448e24e7c88397cd2bde6d6286fe72d_2_664x499] https://user-images.githubusercontent.com/32332228/268870445-f2a23c73-15ee-4b81-9abe-258e4b552ca1.png

I also reported this issue on the Arduino community forum, see this link https://forum.arduino.cc/t/there-may-be-some-conflict-between-rtc-and-the-serial/1169836 .

A kind-hearted person tested my code and obtained the same result. https://forum.arduino.cc/t/there-may-be-some-conflict-between-rtc-and-the-serial/1169836/5?u=wulu

— Reply to this email directly, view it on GitHub https://github.com/arduino/ArduinoCore-renesas/issues/138, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUI6JVXZI5EX2DOLJ5YANLDX3FBELANCNFSM6AAAAAA452MZPM . You are receiving this because you are subscribed to this thread.Message ID: @.***>

eMUQI commented 12 months ago

Other related issues and pull requests: #38 #90

Fashion-Corp commented 12 months ago

Dear Colleagues,

The problem is that Serial.print and Serial.println are not reentrant.

I can make them reentrant if you want but then you have to assist me on how you have organized your version control, which of the methods for pulling you use, and whom to coordinate with, in terms of configuration management.

Furthermore we would need to know which strategy you have for your development in terms of where the libraries are heading to.

There are various drawbacks too on various strategies for multiprocessing, reentrance and interrupt control, which also depends a bit on the hardware.

Sincerely David Svarrer

On Wed, 20 Sep 2023, 04:15 Wulu, @.***> wrote:

Other related issues and pull requests: #38 https://github.com/arduino/ArduinoCore-renesas/issues/38 #90 https://github.com/arduino/ArduinoCore-renesas/pull/90

— Reply to this email directly, view it on GitHub https://github.com/arduino/ArduinoCore-renesas/issues/138#issuecomment-1726741703, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUI6JVXEHYGJX5524TD5AJTX3I7UVANCNFSM6AAAAAA452MZPM . You are receiving this because you commented.Message ID: @.***>

delta-G commented 4 months ago

Currently the UART class sends what you print directly to the HAL layer by pointer. The HAL layer sends the characters out one by one on the Serial line in the TXI interrupt. If you modify the data pointed to by the pointer that the HAL has while it is still being used to print, then it will corrupt the output.

I have submitted PR #304 which modifies the UART class to make use of the 512 byte ring buffer that is already allocated in the code but not used. This means that a copy of the data is made into the ring buffer and the HAL layer is getting a pointer to that. This will solve the particular issue you reference.