Skip to content
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

Slow serial baudrates cause exceptions / WDT #7746

Closed
5 of 6 tasks
HakamSaffour opened this issue Dec 6, 2020 · 16 comments · Fixed by #7799
Closed
5 of 6 tasks

Slow serial baudrates cause exceptions / WDT #7746

HakamSaffour opened this issue Dec 6, 2020 · 16 comments · Fixed by #7799
Labels
waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.

Comments

@HakamSaffour
Copy link

HakamSaffour commented Dec 6, 2020

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [ESP-12]
  • Core Version: [framework-arduinoespressif8266 2.7.4]
  • Development Env: [Platformio]
  • Operating System: [Windows]

Settings in IDE

  • Module: [WeMos D1 R2 and mini]
  • Flash Mode: [dio]
  • Flash Size: [4MB]
  • lwip Variant: [v1.4|v2 Lower Memory|Higher Bandwidth]
  • Reset Method: [clk]
  • Flash Frequency: [40Mhz]
  • CPU Frequency: [80Mhz]
  • Upload Using: [SERIAL]
  • Upload Speed: [115200] (serial upload only)
  • PlatformIO - ini file:
[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
board_build.filesystem = littlefs

; COM1 or COM3
upload_port = COM[4]
upload_speed = 115200

monitor_port = COM[4]
monitor_speed = 115200
monitor_flags=
    --parity
    N

Problem Description

I want to use LittleFS to save some data coming from serial port at baudrate 110, N81
I tested the provided example in:
https://github.com/esp8266/Arduino/tree/master/libraries/LittleFS/examples/LittleFS_Timestamp
and it works fine at baudrate 115200
but when changing baudrate to 110, the code seems to retart (exception)

I need to have a running FS at baudrate of 110, because I can not change the baudrate of the device I am connected to.

Sketch

https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/examples/LittleFS_Timestamp/LittleFS_Timestamp.ino

Debug Messages

@ Baudrate 110
FS with 110 baudrate

@baudrate 115200
FS with 115200 baudrate

@devyte
Copy link
Collaborator

devyte commented Dec 6, 2020

Note: probably yield() needed in this while:

while(uart_tx_fifo_full(uart_nr));

@devyte
Copy link
Collaborator

devyte commented Dec 6, 2020

or this one (might be lighter):

while (size--)

@earlephilhower
Copy link
Collaborator

Adding yield()s in the UART code needs to be careful about IRQ and SYS context safety. I believe both can perform UART writes.

@HakamSaffour
Copy link
Author

@devyte
so you mean it is related to uart code?
why then the code restart at:

if(!LittleFS.begin())

@d-a-v
Copy link
Collaborator

d-a-v commented Dec 7, 2020

@HakamSaffour
110 bauds is 11 printed chars per second.
yield() or loop() calling frequency must be much more higher than once per second.
You may try and add a call to yield() after every Serial.print.
Or you may try and use an alternative print function:

void myPrint (const String& toPrint) {
    for (int i = 0; i < toPrint.length(); i++) {
        Serial.print(toPrint[i]);
        yield();
    }
}

...
    myPrint("I hope this works better\n"); // Serial.println("I hope this works");

@d-a-v d-a-v added the waiting for feedback Waiting on additional info. If it's not received, the issue may be closed. label Dec 7, 2020
@HakamSaffour
Copy link
Author

HakamSaffour commented Dec 7, 2020

@HakamSaffour
110 bauds is 11 printed chars per second.
yield() or loop() calling frequency must be much more higher than once per second.
You may try and add a call to yield() after every Serial.print.
Or you may try and use an alternative print function:

void myPrint (const String& toPrint) {
    for (int i = 0; i < toPrint.length(); i++) {
        Serial.print(toPrint[i]);
        yield();
    }
}

...
    myPrint("I hope this works better\n"); // Serial.println("I hope this works");

it seems to be working (using the alternative print function), no crash any more.
But I need to write a wrapper for each print type, ex: Print, PrintIn, print(int, etc.)

@d-a-v
Copy link
Collaborator

d-a-v commented Dec 7, 2020

But I need to write a wrapper for each print type, ex: Print, PrintIn, print(int, etc.)

True.

Would it be wise to do that in

while (size--)

    while (size--)
        uart_do_write_char(uart_nr, pgm_read_byte(buf++));

=>

    if (can_yield() && 100*size/(baud/10) > 0) {
        // it takes more than 0.01s to print this string => yielding between chars
        // ( <=> (1000*size)/baud>0 <~> (size<<10)/baud > 0 )
        while (size--) {
            uart_do_write_char(uart_nr, pgm_read_byte(buf++));
            yield();
        }
    } else {
        while (size--) {
            uart_do_write_char(uart_nr, pgm_read_byte(buf++));
        }
    }

@HakamSaffour
Copy link
Author

I replaced 'baud' with 'baud_rate' but I did not find 'can_yield', any hint?

if (can_yield() && 100*size/(uart->baud_rate/10) > 0) {

@d-a-v
Copy link
Collaborator

d-a-v commented Dec 8, 2020

any hint?

In coredecls.h, sorry for the lack of clarity

@d-a-v d-a-v changed the title LittleFS: code restarting by slow serial baudrate of 110 Slow serial baudrates cause exceptions / WDT Dec 9, 2020
@HakamSaffour
Copy link
Author

Hello @d-a-v

Thank you for your solution.

I made the modifications in uart.cpp - as mentioned by you - and I tried this code

Sketch

https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/examples/LittleFS_Timestamp/LittleFS_Timestamp.ino

and it looks to be working without any problem at baudrate = 110 and also at baud rate = 115200

image

shall I make a merge request to uart.cpp ?

@earlephilhower
Copy link
Collaborator

@HakamSaffour sure, please throw a PR our way. I'm not sure the exact changes, but this might also fix a problem w/MDNS debugging at 9600 baud (another issue open to document it) where I think it has the same overflow due to its chattiness.

@Tech-TX
Copy link
Contributor

Tech-TX commented Dec 10, 2020

Wow... welcome to the 1970s! I haven't seen 110baud since I used an ASR33 Teletype over an acoustic-coupled modem time-sharing on an old Sperry Univac 9000 computer.

Two tin cans and a piece of string is a more efficient method of data transfer... no wonder the issue never came up until now.

@TD-er
Copy link
Contributor

TD-er commented Dec 10, 2020

Last week I had an user report WDT crashes when running software serial at 1200 baud.
Maybe also add some similar fix there?

@d-a-v
Copy link
Collaborator

d-a-v commented Dec 10, 2020

Maybe also add some similar fix there?

cc @dok-net

HakamSaffour added a commit to HakamSaffour/Arduino that referenced this issue Dec 10, 2020
fix for Slow serial baudrates cause exceptions / WDT
credit goes to @d-a-v 
Reference issue: esp8266#7746

Signed-off-by: Hakam Saffour <[email protected]>
@HakamSaffour
Copy link
Author

A PR is created.

@dok-net
Copy link
Contributor

dok-net commented Dec 29, 2020

@d-a-v I've provided a ready-to-merge PR #7799 to fix this. It should call yield() at a usefully lower frequency in those cases where not only the low bitrate, but a large buffer is the culprit that's causing a long interval without wdt resets before. Please check it off if you agree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants