Thanks Bill,
First, a thread is activated when it is the highest priority thread and runable. Threads are not runable while they wait for events. Threads wait on mutexes, semaphores, sleeping for an interval or until a set time, until a Boolean condition on event flags. ISRs and other threads can trigger events. For example, a semaphore may be associated with a queue and a consumer thread waits on the semaphore. When another
thread inserts an item in the queue, the semaphore is signaled and the consumer thread becomes runable.
I am actually aware of this stuff. I have worked on large machines (IBM, Amdahl, Prime, ...), Workstations (Sun, Apollo) and wrote a protect mode kernel (30+ years ago) for Intel 286/386, that we were working on distributed OS, project canceled, kernel taken over by another group doing Air Defense system... And I have been playing with lots of linux boards (RPI, Odroid, UP, Intel Edison, Galileo)
What I was trying to ask, are there places in the current Teensy Arduino code base that we should consider changing to make it more compatible with your RTOSs or other threaded systems. Currently I am more interested in making it work better with Teensy Threads, not because it is necessarily better but simply because it now ships with Teensyduino...
One option which I am not advocating is to do like Edison, where you are actually running Linux, but you have a version of the Arduino build, which simply compiles to an app that gets downloaded to the main storage and runs like any other app in user space... All system level stuff is done in Kernel space...
I have studied and timed SPI implementations for almost 10 years. Spinning while waiting for the receive data in transfer(dataByte) is a minor problem. Since shift out and shift in happen in parallel and access to even simple devices involves several transfers, the complexity to optimize this is not worth it. If you do 5-6 SPI accesses to write an SPI device you save at most a fraction of a microsecond. Often a sequence of transfers to a device ends with a read so you save nothing. At 8 MHz a byte takes a microsecond so two context switches would use all of that.
Yes, this is very true in some simple byte/word transfers. However maybe not so necessarily true of some usages so SPI. Example updating an TFT display. If you are using a backing frame buffer for example with ILI9341 display you setup the SPI with a few short commands: Set columns, set Rows, <start memory write> then you output 240*320*2 bytes, and you don't care about what is returned... Also remember with the T3.x boards we also have 4 item queue, that also allows us to encode the CS pin(s) state for each command, such that we don't need to wait until one command completes before queuing the next command.
A more simple update example is for the SSD1306(?)/TeensyView - Where you update the display with outputting either 512 bytes (32 lines), or 1024 bytes (64 lines), again you don't care what comes back as this one does not have a MISO pin...
Over the last few builds have added support to improve this, including now the Async version (DMA) using the new events... But for many setups having a thread wait for display update to complete makes sense and is simple.
But again asking, what issues are you having with different subsystems like SPI. When I hear things like they are not thread safe... Would help to know more, like: You can not use the SPI object in multiple threads (example multiple devices on the same SPI buss), But can you use different SPI busses in different threads? Where are the hangups? Again maybe we can not solve for all old code, but for example on same buss, could we maybe have way for beginTransaction/endTransaction - be augmented such that in a multiple thread case one thread will know that another thread owns the SPI object and wait for it to be available...
Also SPI was just an example, what about issues in SerialX, ...
Threads are great for unexpected events like external interrupts where processing the event takes longer than a few microseconds so an ISR isn't the best answer but the event is urgent so polling is too long.
...
- Yep I do use threads when working on Linux and the like...
I have a feeling that you can't really understand an RTOS without real world examples. Perhaps there are good tutorials somewhere but just reading the ones I know about often doesn't clear things up.
Often several threads run with little interaction, a display thread, read sensor thread that queues data for a logger thread can be a very simple program.
Threads at the same priority run round-robin with typically about a 20 ms time slice. A collection of threads can act like applications on a PC.
Again I, and I assume many/most others up here have used systems with threads or the like and understand their usefulness.
Side tract - After I retired from developing software on PCs and the like, I was attracted to working on machines like the Arduino as it was refreshing to be in total control and to be able to see all of the code and if does not work for you, you can fix it. You are pretty much into control of when things like IOs happen, which makes it great for things like controlling servos of a robot to get nice smooth walking gaits and the like. Small Linux boards are fun to play with, but for at least most of us you lose the concept of fully understanding all of the code that is happening. You also also often loose control of the ability to finely control the timings. That is why for example when several people have moved from using an Arduino to something like an RPI, they might end up with a jerkiness in their servo movements... Yes I know there are ways around this...
So again I would like to help make it easier to use some simple RTOS or other threading systems, that we can all use, when we wish to use it. But I also understand the requirement for many that especially on the smaller chips (T-LC, T3.2), that adding this support should not take away the ability to control it the way they currently do. i.e - they already use up most/all of the memory and have timings worked out for their stuff... Again I know that it is a hard line to walk.
It would be great if we could setup a list of things that would help, and as several of us work through different subsystems we can hopefully converge to a better system.