SparkFun Electronics Commentsurn:uuid:214d0e4e-f1b1-d287-ce26-ac5b4c9f82492024-03-28T16:33:40-06:00SparkFun Electronicsawootton on Enginursday: Doing Away with Delay() in a Different Wayawoottonurn:uuid:bcaba9b6-175b-1f04-3cec-245236cf3f212015-11-13T19:41:38-07:00<p>I know there's an esp8266 port for rtos (expressif,mattcallow) but does anyone know if it's been made into an Arduino Library like the avr and amd versions here? Is anyone working on that?</p>
Byron J. on Enginursday: Doing Away with Delay() in a Different WayByron J.urn:uuid:45b69ca5-e467-73d4-361a-ab5610c410dd2015-11-02T10:37:42-07:00<p>I got bored after 8 tasks on an R3. Each of those tasks was pretty trivial, not calling any further functions that would put a bunch more on the stack (IE: not calling <code>printf()</code>). This was using only the <code>MINIMAL</code> stack size, which I believe is 100 bytes.<p>The stacks are allocated on the heap when the task is started.</p><p>One of the nice things about this FreeRTOS port is that it's distributed as source code. If you want to see how something is implemented, you can go read it. Actually reading it can be a little challenging, though, because it uses several layers of macros to keep it portable, and sometimes you have to unravel a bunch of nested references to find out what something really is (thus my hedge on the actual size of minimal stacks...).</p></p>
awootton on Enginursday: Doing Away with Delay() in a Different Wayawoottonurn:uuid:35b9c943-b46b-8ab4-e22c-3a9fd57e6b7a2015-10-30T19:42:38-06:00<p>Watson, I think I get it. Mind blown. It's like there are threads now on an Arduino and somehow, magically, they all have stacks. Wow. How is that done? I suppose the whole rest of of the program after vTaskStartScheduler() is a series of interupts that schedule more interrupts but I'm still working on how a single cpu stack is managed to do that. Greatest hack ever my vote you have.
This means that kids can write simple controllers to run stepper motors in a coordinate way. Robot time.
But, I must ask. Will it run two tasks on an Uno R3? 4 tasks?</p>
ZedLep on Enginursday: Doing Away with Delay() in a Different WayZedLepurn:uuid:ec48f686-0eb3-b114-5bc0-154624a947202015-10-24T10:10:59-06:00<p>Good discussion. I'm surprised the <a href="http://playground.arduino.cc/Code/TimedAction" rel="nofollow">TimedAction</a> library hasn't come up in this or last week's post. Definitely not an RTOS solution, but it's insanely simple and 'good enough' for many timed task scenarios. It basically abstracts the execution of tasks on a regular period (ms) using only a handful of simple methods.<pre><code>#include <TimedAction.h>
TimedAction actionLED1 = TimedAction( 1000, blinkLED1 ); // Execute every 1000ms
TimedAction actionLED2 = TimedAction( 1200, blinkLED2 ); // Execute every 1200ms
#define pinLED1 12
#define pinLED2 13
boolean stateLED1 = false;
boolean stateLED2 = false;
void setup( )
{
pinMode( pinLED1, OUTPUT );
pinMode( pinLED2, OUTPUT );
digitalWrite( pinLED1, stateLED1 );
digitalWrite( pinLED2, stateLED2 );
}
void loop( )
{
actionLED1.check( );
actionLED2.check( );
:
:
// Do other stuff
}
void blinkLED1( )
{
stateLED1 = stateLED1 ? false : true; // Toggle LED1 state
digitalWrite( pinLED1, stateLED1 );
}
void blinkLED2( )
{
stateLED2 = stateLED2 ? false : true; // Toggle LED2 state
digitalWrite( pinLED2, stateLED2 );
}
</code></pre></p>
rei_vilo on Enginursday: Doing Away with Delay() in a Different Wayrei_vilourn:uuid:7540325c-a400-938c-a82a-0ab557bd86bb2015-10-19T14:02:40-06:00<p>Energia, the fork of Arduino for Texas Instruments' boards, features the TI-RTOS on the MSP432 and CC3200 LaunchPads.<p>Learn more at <a href="http://embeddedcomputing.weebly.com/launchpad-msp432-rtos-for-everyone.html" rel="nofollow">LaunchPad MSP432: RTOS for Everyone</a> and <a href="http://embeddedcomputing.weebly.com/exploring-rtos-with-galaxia.html" rel="nofollow">Exploring RTOS with Galaxia on Energia MT</a>.</p></p>
Customer #450404 on Enginursday: Doing Away with Delay() in a Different WayCustomer #450404urn:uuid:75c5d27c-704f-92c7-d7fc-22a9457046a52015-10-19T07:58:27-06:00<p>For the initial setup I used Atmel Studio 6, but then exported the project to a normal makefile setup (finding the correct build arguments requred a bit of work). One thing i found frustrating was to get a tool that could upload the binary to the board. I ended up using the bossa binary delivered with arduino IDE. It was somehow different from the other bossa versions I found elsewhere.<p>I used the freeRTOS website <a href="http://www.freertos.org" rel="nofollow">freeRTOS.org</a> for documentation, and I also bought the freeRTOS tutorial book for cortex-m3.</p><p>Unfortunately I never used the RTOS analysis tools included in Atmel Studio that you talked about in another comment to this post, but that seems very convenient. Please let us know if you get it working!</p></p>
Briscoe on Enginursday: Doing Away with Delay() in a Different WayBriscoeurn:uuid:900d7694-316d-06f1-d40a-607de0485a932015-10-17T11:14:10-06:00<p>I would like to see this topic continued! RTOS are used in so many things, you got to start somewhere right :-)<p>I have been meaning to download Atmel Studio, there is a plugin to include FreeRtos to the IDE with some fancy analysis tools showing the time slicing of the tasks and the simulated load on the processor. It might be worth checking out and writing a article on it :-)</p></p>
Briscoe on Enginursday: Doing Away with Delay() in a Different WayBriscoeurn:uuid:0049f134-c023-0d56-a269-08703705617d2015-10-17T11:10:25-06:00<p>This has been on my todo list for months now! Glad to hear it works well! :-)<p>Could you post the link to what you used for your initial RTOS setup and documentation? Also, did you get it setup with the Arduino IDE or Atmel Studio?</p></p>
BeerCannon on Enginursday: Doing Away with Delay() in a Different WayBeerCannonurn:uuid:d0d87410-7a09-e2f0-4a01-676ac5bb34942015-10-16T12:53:59-06:00<p>Cool write-up.. it inspired me to take a look into this RTOS in the very near future. Thanks!</p>
172pilot on Enginursday: Doing Away with Delay() in a Different Way172piloturn:uuid:9445fa57-a993-926c-1b2c-ff869e7b25482015-10-16T12:17:21-06:00<p>Wow.. that is pretty mature.. Amazing to think that such things have been ported down to be available on something like an Arduino.. If only there were more hours in the day, I could someday hope to play with all of that!! :-) (where is that winning lottery ticket, anyway!!) Thanks for a great explanation, and all the links!</p>
Byron J. on Enginursday: Doing Away with Delay() in a Different WayByron J.urn:uuid:142d924f-395a-8bb7-ba95-7e8af163ca342015-10-16T12:02:50-06:00<p>This is actually a <em>huge</em> topic in RTOS programming -- big enough that I didn't want to even try to touch it in the post.<p>You're correct to assume that chaos can ensue if the data is freely accessible by any task. A given RTOS will have a number of features to allow data to safely move between threads. Different types of interaction call for different schemes, and learning how to use them is a big part of RTOS programming. The FreeRTOS structors for this are documented in their <a href="http://www.freertos.org/Inter-Task-Communication.html" rel="nofollow">Inter Task Communication</a> document.</p><p>If the data in question is flowing unidirectionally from the one thread to the other, the monitoring thread could send a message to the other thread when data is ready. Messages can flow through <a href="http://www.freertos.org/a00018.html" rel="nofollow">queues</a> (somewhat akin to pipes in unix/posix).</p><p>Threads can also send simple binary indications between one another using <a href="http://www.freertos.org/a00113.html" rel="nofollow">semaphores</a> -- a semaphore being a more rigorous version of a flag. The frBlink demo sketch has an example of two threads using a semaphore.</p><p>If the system is a free-for-all, with multiple threads all trying to read and write the global data, you can protect the data using a <a href="http://www.freertos.org/Real-time-embedded-RTOS-mutexes.html" rel="nofollow">mutex</a>, so that only one thread has access to it at a time. In my mind, A situation like this is an indication that the design might need further refinement -- perhaps the data needs a thread of it's own, with a more formal interface.</p></p>
Customer #394180 on Enginursday: Doing Away with Delay() in a Different WayCustomer #394180urn:uuid:3288e1bc-60c1-985e-2f71-3572e23a668a2015-10-16T09:32:09-06:00<p>In multi-threaded programs, the threads share the same address space so global variables can simply be declared and accessed from either thread. It's the simplest approach, but not necessarily a good idea. If both threads are only reading, that's usually OK, but if either is writing that can cause trouble. In that case you have to synchronize the threads' accesses with semaphores and/or mutexes.</p>
172pilot on Enginursday: Doing Away with Delay() in a Different Way172piloturn:uuid:2f47acee-4168-9a17-c352-402fa3007ca12015-10-16T08:28:57-06:00<p>Very cool article.. I can see many arduino apps that would benefit from a structure like this.. One question that I'll ask here to maybe inspire a more complex example code, but then probably go just read about myself, is how variables are managed between threads? If thread 1 is monitoring a couple sensors and making calculations, are the variables all global in nature, so they can be monitored, acted upon, or adjusted by the other threads?</p>
Customer #450404 on Enginursday: Doing Away with Delay() in a Different WayCustomer #450404urn:uuid:c8c20fcb-2010-ae40-adc3-7f05bfca587c2015-10-16T03:10:40-06:00<p>Awesome post! I have been using freeRTOS for a while, running on an arduino DUE, and i really like it! It has extensive documentation and the forum is very active!<p>There are a number of example freeRTOS projects for the DUE (cortexM3), so I based my project on one of them and stuck to using a setup with a makefile. I think that this is a good solution for many projects, but it is awesome that freeRTOS now is easily available for the arduino community, the learning curve for my setup was kind of steep... I can not wait to try this library, so many ideas!</p></p>
Byron J. on Enginursday: Doing Away with Delay() in a Different WayByron J.urn:uuid:9600f6b5-2d87-2b9d-27b2-50ab464bf7602015-10-15T15:22:22-06:00<p>I think it's a perfectly fair criticism of the example. Bringing familiarity of Arduino, and reading the example I posted, you reached what appears to be the obvious conclusion.<p>FreeRTOS under Arduino quickly reaches a point where two very different approaches to structuring applications are coexisting, and we need to understand some of the subtleties of both approaches to get them to work together effectively.</p></p>
Sembazuru on Enginursday: Doing Away with Delay() in a Different WaySembazuruurn:uuid:6820b40a-09f6-d97f-7879-8d2de07be1532015-10-15T14:36:51-06:00<p>Nevermind, see the sub-thread on Byron J's comment. FreeRTOS does call it.</p>
Sembazuru on Enginursday: Doing Away with Delay() in a Different WaySembazuruurn:uuid:390043f0-21b6-a9e3-7a2c-4544ddc8bfb52015-10-15T14:33:36-06:00<p>Ah. I didn't go into depth reading about how FreeRTOS works. My bad for not researching before I commented.</p>
Sembazuru on Enginursday: Doing Away with Delay() in a Different WaySembazuruurn:uuid:e5d97f53-07d5-9413-910d-ff38497f19952015-10-15T14:32:36-06:00<p>Sorry, after babbling I forgot to finish my thought...<p>Shouldn't that comment instead read something to the effect of:</p><pre><code>//loop is empty because it will never be reached
</code></pre></p>
Byron J. on Enginursday: Doing Away with Delay() in a Different WayByron J.urn:uuid:f9c84744-07fa-09b6-82c4-106a38545ed72015-10-15T14:30:14-06:00<p>There's one little piece of trickery in FreeRTOS you've missed.<p>FreeRTOS has some hooks that allow the user to add functionality to the heart of the system. You can read a bit more about it in their <a href="http://www.freertos.org/a00016.html" rel="nofollow">Hook Functions</a> page.</p><p>This port assigns the <code>loop()</code> function to the idle task (in FreeRTOS_AVR/idlehook.c). It's not called by the Arduino boilerplate, instead by the scheduler when no other tasks are ready to run.</p></p>
Sembazuru on Enginursday: Doing Away with Delay() in a Different WaySembazuruurn:uuid:51d7b8b8-84d2-21fc-283e-f5db352cca1c2015-10-15T14:00:03-06:00<p>In the comments of your example, right before the loop() you have<pre><code>// loop must never block
</code></pre><p>It doesn't really matter as loop() will never be reached (unless freeRTOS calls it). This is because of two reasons, both in setup(). If vTaskStartScheduler() never returns as expected, then setup() will never return. Even if vTaskStartScheduler() does return, the next line is</p><pre><code>while(1);
</code></pre><p>which will never end. Thus, because loop() is never reached, who cares what it is in loop(), even if it is blocking? It's just dead code.</p><p>Remember, when compiling in the ArduinoIDE, the middleware creates a .h file that enumerates all the functions, and includes main.cpp that contains the following main() function:</p><pre><code>int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
}
</code></pre><p>So you can see that as far as the C++ compiler is concerned, if setup() never returns then loop() is never reached.</p></p>
Customer #73768 on Enginursday: Doing Away with Delay() in a Different WayCustomer #73768urn:uuid:d28192e8-519e-7d0f-5729-4a4527392d2e2015-10-15T13:33:37-06:00<p>These last two Enginursdays have been great! These topics are a little more on the advanced side, but they are good introductions on how to handle timing issues. These days I default to using a RTOS whenever I'm dealing with multiple events. My 'simple' programs always seem to grow and it's easier to start with an RTOS then to try to manage multiple threads manually.</p>
Byron J. on Enginursday: Doing Away with Delay() in a Different WayByron J.urn:uuid:7298e7a3-9ff2-53bc-8d03-3086e470a8842015-10-15T13:28:16-06:00<p>I've used it with a RedBoard (Uno equivalent) and ProMini, under Arduino 1.6.5.<p>I haven't looked any closer at the ARM side of the family, so we'll have to take the readme at it's word.</p></p>
Byron J. on Enginursday: Doing Away with Delay() in a Different WayByron J.urn:uuid:02751421-d52e-fa84-7e1d-6f665b31f8812015-10-15T13:20:46-06:00<p>A funny effect of intermixing markdown and raw HTML.<p>The text is correct in our CMS.</p><p>Apparently the pointy brackets were being translated as an HTML tag, and not displayed by the page rendering code. I've replaced them with \> and \<, and it seems to be OK.</p></p>
Byron J. on Enginursday: Doing Away with Delay() in a Different WayByron J.urn:uuid:6a96d4c6-d69c-5d91-99e3-3379857ca30a2015-10-15T13:11:36-06:00<p>Try <code><FreeRTOS_AVR.h></code><p>Somehow it fell off in the cut/paste.
I'll go fix the example.</p></p>
Sembazuru on Enginursday: Doing Away with Delay() in a Different WaySembazuruurn:uuid:52749127-6f2a-7ec0-72fc-7b720fc12e7d2015-10-15T12:57:21-06:00<p>If you are going to go through all that, why stick with the ArduinoIDE? All the hidden middle-end work that the ArduinoIDE does is pointless if you are going to "use C++ in all its glory". May as well us an actual C++ IDE that supports avrdude (either internally or through plugins) and skip using .ino files altogether.</p>
Wayne on Enginursday: Doing Away with Delay() in a Different WayWayneurn:uuid:aacfd03f-e832-1623-57c2-8d58c2b2e1552015-10-15T11:24:23-06:00<p>Is there a mistake in the code example? I see a line that reads, simply:<p>#include</p><p>Looks like what's supposed to be included is missing...</p><p>Wayne</p></p>
NorseEngineer on Enginursday: Doing Away with Delay() in a Different WayNorseEngineerurn:uuid:9fc9e061-9bde-5f1b-c304-16c283bd91792015-10-15T10:57:53-06:00<p>From the ReadMe.md on GitHub<p>"This is a port of FreeRTOS as Arduino libraries.
The documentation for FreeRTOS is located here:
http://www.freertos.org/
FreeRTOS is version 8.0.1</p><p>These libraries were tested with Arduino 1.05 for AVR boards, Arduino 1.5.7
for Due and the 1.20RC2/1.0.5 version of the Teensy 3 software."</p></p>
Customer #260321 on Enginursday: Doing Away with Delay() in a Different WayCustomer #260321urn:uuid:0e0916eb-c8c8-d349-70da-e1c0644f468b2015-10-15T10:35:47-06:00<p>That's nice, but why not get rid of the Setup/Loop paradigm altogether?<p>Empty your .ino file and add a .cpp file to your project that has the main() program, this file must have a different name than your .ino file.
Four caveats:
(1) Your .cpp file(s) must (each) #include <Arduino.h>
(2) To use the Arduino timer libraries you must call init() first thing in main().
(3) Your .ino file must have the includes for all the Arduino libraries you are using, otherwise they won't be brought in, e.g., #include <SPI.h> and nothing else, no setup() or loop()
(4) To use C++ in all its glory you will need .h files to declare all your classes and functions, and .cpp files for the implementations. This means 2 or 3 times the lines of code over the simplistic Arduino approach, but your executable image size won't increase.</p></p>
Customer #304820 on Enginursday: Doing Away with Delay() in a Different WayCustomer #304820urn:uuid:56755c4c-5447-2700-afaa-bdf51e66ea8d2015-10-15T09:53:19-06:00<p>I just published a state machine based framework for Arduino called Automaton that can do this kind of thing very elegantly as well. I guess it could fit your round hole a little better.<p>Have a look on github if you're interested: https://github.com/tinkerspy/Automaton (docs in the github wiki)</p><p>A Sparkfun article on state machines was one of the things that inspired me.</p></p>
Dragon88 on Enginursday: Doing Away with Delay() in a Different WayDragon88urn:uuid:8dd5a1fc-3044-ffb1-41ab-d7070978eb3c2015-10-15T09:53:01-06:00<p>Good article, thanks for your work and research.<p>This seems like overkill for an 8-bit AVR though. Going down the road of more and more libraries and layers of abstraction, you eventually end up with something that is more complicated than the original starting point. Configuring a timer and ISR in Atmel Studio is no more complicated-looking than the code shown above, and actually teaches the programmer what the AVR is doing behind the scenes. It's the difference between having control over the device, and relying on someone else's abstraction to gain the appearance of control.</p><p>You might also considering doing one of these articles on ARM devices and showing off the SysTick timer.</p></p>
Ted M on Enginursday: Doing Away with Delay() in a Different WayTed Murn:uuid:f810b717-05eb-941f-3f69-f2f9bbae59282015-10-15T09:31:44-06:00<p>Great article.
The first line of code in the example is:<h1>include</h1><p>Shouldn't there be something included?</p><p>Also, what version(s) of arduino does RTOS run on, Uno, Leonardo, Teensy?</p></p>
Jamo on Enginursday: Doing Away with Delay() in a Different WayJamourn:uuid:bcd378b2-e178-0305-682a-83ef48a920a32015-10-15T09:02:18-06:00<p>Good little intro to an arduino friendly RTOS. Although putting one on an 8 bit micro seems like a square peg, round hole situation to me. There is a small error/typo in the paragraph immediately after task image. "The real trick is to make the waiting <strong>less</strong> inexpensive."</p>
Customer #589493 on Enginursday: Doing Away with Delay() in a Different WayCustomer #589493urn:uuid:c79bb6f2-4448-67a4-6d9d-5dd228d0f6dc2015-10-15T07:54:34-06:00<p>I'd like to run MicroC OS on an arduino. The priority based task structure lends itself well to embedded systems I think.</p>
Customer #535711 on Enginursday: Doing Away with Delay() in a Different WayCustomer #535711urn:uuid:fb1e62fe-f3e7-21ef-0d4d-98643b09cfc02015-10-15T07:45:36-06:00<p>This is an awesome post, I really loved it. Can wait to get home and put my hands on it. It would be very nice to have more RTOS posts! :-)</p>