ftrias / TeensyThreads

MIT License
184 stars 26 forks source link

Use of delay in libraries #24

Open steinerlein opened 3 years ago

steinerlein commented 3 years ago

Hi, I am observing an issue where a thread locks up when a library I want to use in it uses delay(). Here's what I have:

#include "Arduino.h"
#include <TeensyThreads.h>
#include "SSD1327.h"

#define PIN_CS  10
#define PIN_DC  9
#define PIN_RST 6

volatile int count = 0;

void thread_func(int data){
  while(1){
    count += data;
    delay(250);
  }
}

void draw(int arg){
    SSD1327 disp(PIN_CS, PIN_DC, PIN_RST);
    disp.init(); // <----------------------------------------Thread hangs in here

    while(1){ //Draw
        disp.clearBuffer();
        disp.drawString(3, 8, count, 0xF, 16);
        disp.writeFullBuffer();
        delay(25);
    }
}

void setup() {
    Serial.begin(115200);

    threads.setSliceMillis(1);
    threads.addThread(thread_func, 1);
    threads.addThread(draw, 0, 8704);
}

void loop() {

}

And then in the SSD1327 library:

void SSD1327::init() {
    pinMode(_cs, OUTPUT);
    pinMode(_dc, OUTPUT);
    pinMode(_rst, OUTPUT);

    SPI.setDataMode(SPI_MODE0);
    SPI.setBitOrder(MSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV2);
    SPI.begin();

    digitalWrite(_rst, HIGH); //Reset display
    Serial.println("one");// <---------------------------------------- This is reached
    delay(100);
    Serial.println("two");// <---------------------------------------- This isn't reached
    digitalWrite(_rst, LOW);
    delay(100);
    digitalWrite(_rst, HIGH);
    delay(100);

    initRegs();
}

I'd be thankful for any pointers on what I'm doing wrong. Thanks!

ftrias commented 3 years ago

Can you try using "threads.delay()"? The basic "delay()" function is a loop that eats up the CPU time and interferes with thread swapping.

On Mon, May 3, 2021 at 5:43 AM steinerlein @.***> wrote:

Hi, I am observing an issue where a thread locks up when a library I want to use in it uses delay(). Here's what I have:

`#include "Arduino.h"

include

include "SSD1327.h"

define PIN_CS 10

define PIN_DC 9

define PIN_RST 6

volatile int count = 0;

void thread_func(int data){ while(1){ count += data; delay(250); } }

void draw(int arg){ SSD1327 disp(PIN_CS, PIN_DC, PIN_RST); disp.init(); // <----------------------------------------Thread hangs in here

while(1){ //Draw disp.clearBuffer(); disp.drawString(3, 8, count, 0xF, 16); disp.writeFullBuffer(); delay(25); }

}

void setup() { Serial.begin(115200);

threads.setSliceMillis(1); threads.addThread(thread_func, 1); threads.addThread(draw, 0, 8704);

}

void loop() {

}`

And then in the SSD1327 library: `void SSD1327::init() { pinMode(_cs, OUTPUT); pinMode(_dc, OUTPUT); pinMode(_rst, OUTPUT);

SPI.setDataMode(SPI_MODE0); SPI.setBitOrder(MSBFIRST); SPI.setClockDivider(SPI_CLOCK_DIV2); SPI.begin();

digitalWrite(_rst, HIGH); //Reset display Serial.println("one");// <---------------------------------------- This is reached delay(100); Serial.println("two");// <---------------------------------------- This isn't reached digitalWrite(_rst, LOW); delay(100); digitalWrite(_rst, HIGH); delay(100);

initRegs();

}`

I'd be thankful for any pointers on what I'm doing wrong. Thanks!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ftrias/TeensyThreads/issues/24, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABRWXIUZLISKFNLCTRHNFQLTLZV5VANCNFSM44AQDZAA .

playaspec commented 3 years ago

Without digging through the code, I've got an idea as to what the problem is. The readme warns of library functions that may require adding locks, probably for the same reason you can't use Serial.print() within an ISR. Serial.print() is off doing it's thing, talking with hardware that is more than likely relying on interrupts of it's own, and it's execution is preempted by a context switch.

Try wrapping using the helper function mentioned in the readme.