Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 16 1 2 3 11 ... LastLast
Results 1 to 25 of 379

Thread: Teensy 3.x multithreading library first release

  1. #1
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    109

    Teensy 3.x multithreading library first release

    I created a preemptive threading library for the Teensy 3.x and am releasing it here in case anyone needs it and for comments and suggestions. It's a first release, so I would expect some bugs.

    Source code: https://github.com/ftrias/TeensyThreads

    Direct link to ZIP: https://github.com/ftrias/TeensyThre...er/Threads.zip

    This library follows the strategy recommended in the Corex-M4 reference guide. It uses the built-in threading support of the Teensy's Cortex-M4 to implement basic threading. It supports a Teensy-like interface and a minimal std::thread interface from the C++11 standard. More technical information in the source code.

    Examples:

    Code:
    #include <Threads.h>
    volatile int count = 0;
    void thread_func(int data){
      while(1) count += data;
    }
    void setup() {
      threads.addThread(thread_func, 1);
    }
    void loop() {
      Serial.println(count);
    }
    Using std::thread

    Code:
    #include <Threads.h>
    volatile int count = 0;
    void thread_func(int data){
      while(1) count += data;
    }
    void setup() {
      std::thread th1(thread_func, 1);
      th1.detach();
    }
    void loop() {
      Serial.println(count);
    }
    This project came about because I was coding a Teensy application with multiple things happening at the same time and really missed
    multithreading available in other OSs. I searched for threading systems, but found nothing.

    This combined with boredom and excess free time led to complete overkill for the solution and thus the implementation of simple threads.

    For more info and documentation see the Git repository.

  2. #2
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,537
    This seems to be very interesting - i'm sure it's useful and, if I have time, I'll take a closer look next weekend.

  3. #3
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    109
    Thanks Frank B for looking at it if you have time! I forgot to mention that I only tested this on a Teensy 3.2, and not the newer Teensy 3.5 or 3.6.

  4. #4
    Senior Member
    Join Date
    Oct 2013
    Posts
    252
    Just downloaded latest, running "tests" on a 3.2 everything looks good, on a 3.6 get "Error while setting serial port parameters: 115,200 N 8 1" everytime the sketch tries to print to TeensyMonitor. Running 1.8.0 on Windows 10.

  5. #5
    Senior Member
    Join Date
    Oct 2013
    Posts
    252
    Oddly enough the "Print" example works on the 3.6.

  6. #6
    Looks very interesting, thanks for sharing

  7. #7
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    109
    Quote Originally Posted by cartere View Post
    on a 3.6 get "Error while setting serial port parameters: 115,200 N 8 1" everytime the sketch tries to print to TeensyMonitor. Running 1.8.0 on Windows 10.
    I'll be getting a 3.6 in the next few days and will see what the problem is and post my results here.

  8. #8
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,746
    i would see a problem if both threads were accessing same hardware (i2c/spi/canbus) however, this looks indeed interesting when one thread can do spi/i2c/canbus polling while the other runs the rest of the program

  9. #9
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,839
    Just wanted to confirm that I am getting a similar error on the "tests" example when running a 3.5, "Error while setting serial port parameters: 9,600 N 8 1". Running 1.6.12 on Windows 10. As cartere says the "Print" example works on the 3.5 as well. Also posted on GITHUB.

  10. #10
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    109
    Thanks for the feedback on the Teensy 3.5. I just got a Teensy 3.6. I am waiting for a 3.5 to test. There are two issues:

    1. The new Teensy has a floating point unit and its state must be saved between threads. That should not be to difficult to add.

    2. The yield() function is not thread-safe because of some of the functions it calls. That is, it can't be called from two threads at the same time. Unfortunately, it is called by "delay()" and after every "loop()" call. Because of this, you will cause a crash if you use delay() within a thread. The Test example makes copious use of delay() and thus fails, whereas the Print example does not. I'm not sure why this isn't a problem for the Teensy 3.2, but maybe I just haven't seen it yet.

    As a workaround, you can use threading library's "threads.delay()" function to yield CPU time to other threads. This should work fine and is probably preferred anyway. I will look into the root cause of why yield() is not thread-safe to see if there is a more universal solution.

  11. #11
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,839
    Just to confirm are you saying that I should just substitute threads.delay() for delay() in the "tests" sketch? I gave it a try it anyway and it did run but all the test thread speed failed:
    Code:
    Test thread start ok
    Test thread run state ok
    Test thread return ok
    Test thread speed ***FAIL***
    Speed no threads: 7995502
    Speed 1 thread: 8560480
    Ratio: 1.07
    Test set time slice ***FAIL***
    Speed default ticks: 8558685
    Speed 10 ticks: 8556003
    Expected: 799550.25
    Ratio with expected: 10.70
    Test delay yield ok
    Yield wait ratio: 1.07
    Test thread end state ok
    Test thread reinitialize ok
    Test thread suspend ok
    Test thread restart ok
    Test thread stop

  12. #12
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    109
    Quote Originally Posted by mjs513 View Post
    Just to confirm are you saying that I should just substitute threads.delay() for delay() in the "tests" sketch? I gave it a try it anyway and it did run but all the test thread speed failed
    Yes, exactly. But looking at your output, only two test failed. The others were "ok". I'll have to fix up the wording to make it clearer. The tests that fail have to do with run time, which is affected by using "threads.delay()". I'll have to patch the code tomorrow to account for this problem. Thanks for trying it out.

  13. #13
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,839
    My pleasure. Been looking for something like this for a long time. You put in a lot of effort into making this lib and it promises to be resolve a few challenges that I have been having. Great job on the lib.

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,860
    If a local " void yield() {} " is defined it will override the 'weak' default system yield() - including calls from delay(). The ZILCH system uses this as its task switch mechanism. You can redefine it to empty or whatever would be useful and thread safe.

  15. #15
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,839
    Took your suggestion and added void yield(){} to the "tests" sketch using just delay() and it just froze.

  16. #16
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    109
    Quote Originally Posted by mjs513 View Post
    Took your suggestion and added void yield(){} to the "tests" sketch using just delay() and it just froze.
    After looking more closely, I think there was more to this problem. I just finished adding support for the FPU on the Teensy 3.5 & 3.6. I also added a small fix for context switching within interrupts. This fixes some sporadic problems.

    It seems to work on my Teensy 3.2 and 3.6. I don't have a 3.5 to test on at the moment, but one is on the way.

    Do you mind downloading the latest from github and seeing if it works for you?

  17. #17
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,839
    Sorry for the delay but I was out. I just downloaded and ran the tests.ino sketch and it seems to work no problem. Ran it at 120mHz. Here is the output from the monitor:
    Code:
    Test thread start OK
    Test thread run state OK
    Test thread return OK
    Test thread speed OK
    Speed no threads: 7993733
    Speed 1 thread: 4318147
    Ratio: 0.54
    Test set time slice OK
    Speed default ticks: 4317751
    Speed 200 ticks: 5968047
    Expected: 5757001.50
    Ratio with expected: 1.04
    Test delay yield OK
    Yield wait ratio: 1.07
    Test thread end state OK
    Test thread reinitialize OK
    Test stack usage OK
    Test thread suspend OK
    Test thread restart OK
    Test thread stop OK
    Test thread start OK
    Test thread wait OK
    Test thread wait time OK
    Test thread kill OK
    Test std::thread scope OK
    Test infinite loop (will not end)
    0: 0 sec 48357370
    1: 5 sec 91535425
    I will keep you posted as I incorporate it into applications. May be a while though. Have a couple of other coals in the fire as they say. Thanks for getting the issue fixed.

    Mike

  18. #18
    Hello! I am a beginner in programing and i have a problem with one of my projects. I need to run my loop very fast and also write data on an lcd. The lcd is blocking my other functions.
    Can this library be used to run the LCD part of the program?
    Thank you!

  19. #19
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,746
    thats the idea of multithreading so yes

  20. #20
    I tried it like the example.. But nothing... Like it doesn't control the outputs... I will try with something simpler. Can someone explain me the thread.delay() function? And what if I woul use delay instead of thread.delay()? Woul it stop both threads?
    I am sorry for such stupid questions. I hope you can understand

  21. #21
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,653
    @Tady, sometimes hard to know depending on what your hardware setup is. Like what type of LCD or how fast you need things, what do you need to do fast in your main loop?

    With my Well monitor code, I want to read sensors reasonably often and update a PJRC screen. What I am doing is using an IntervalTimer (https://www.pjrc.com/teensy/td_timin...rvalTimer.html), which I use to read my sensors (mostly analogReads) and set start variables.

    Then the main code in the loop checks for state changes and updates the display...

  22. #22
    I'm making a 3 axis servo driver for a car racing simulator (roll, pitch, traction loss). The regulator gets it position commands over UDP and I can make adjustments via a webpage. Now i have added a 20x4 lcd and a dashboard from a motorcycle. The motorcycle gauge cluster needs variable frequency for speed and RPM. Here I use a simple blink without delay example and I am varying the period lenght. Here is the problem. When the refresh LCD function is triggered the time the CPU spends on refreshing the LCD is so big that the needle of the RPM gauge jitters and the speed is all over the place. The motors aren't affected that much but the gauge is no good. I tryed the LiquidCrystalFast library. I wired the extra RW pin but the LCD gives me strange characters it seems that RW doesn't do much, i should be checking the LCD busy flag... i tried the Tone library ( it only works with one pin, so no good), I tried analogWriteFrequency and then analogWrite with abou 50% duty cycle again not working.
    My only two options are to fix the lcd with the liquidCrystalFast of use multithreading...
    So far no luck

  23. #23
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,653
    Good luck: I have not used one of these type of displays (Parallel ) in a long long time. The last 2xsomething or 4xsomething displays I used what I think was called Serial backpack...

    A quick look at the Liquid...Fast library, it looks like the RW pin keeps it from doing a delayMicroseconds(320) and instead do lots of pinMode, digitalWrites and digitalReads to figure out when the display is not busy.

    The only other option I can think of is if possible not update all of your display at once. But try to break it up into small chunks...

  24. #24
    What kind of displays do you use is not these? Graphical? I have a ili9341 laying around maybe i can adapt the code

  25. #25
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,746
    i use 2 displays @ 200,000 baud, i did a few photoshop animations on one of them https://m.youtube.com/watch?feature=...&v=zDfCgHun_4E

    host is a teensy 3.5

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •