Jump to content
vladn

[Energia Library] Arduino "Scheduler" port to Energia Qs

Recommended Posts

I have ported the Arduino cooperative scheduler described here:

http://arduino.cc/en/Reference/Scheduler

to Energia (Tiva Launchpad) platform.

 

However, being new to both Arduino and Energia I need some help from Energia guys, specifically:

1. Check the copyright issues - is it OK to port this thing to Energia (the code seem to have an Android Open Source Project Copyright) ?

2. It required some minor mods to few Energia files (wiring.c Energia.h). Not sure where should I post it.

3. If #1 is OK I'll post the library for testing here.

Share this post


Link to post
Share on other sites

@@vladn

According to the Scheduler page, it's made available under http://creativecommons.org/licenses/by-sa/3.0/ license. You are free to do what you want provided you:

 

Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.

 

ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.

 

 

I suggest posting it in this thread, with instructions regarding the modifications necessary to Energia. It may be something the Energia team may want to include in a future release, provided it doesn't break any existing functionality or compatibility.

Share this post


Link to post
Share on other sites

Ok, here is the first attempt. I kept the Copyright headers intact. My background is in EE, I have zero experience with open software project management tools in general and github in particular.

 

Here is the library. It is a true cooperative context switcher. The default context stack size for the new task is 1024 (defined in Scheduler.h).

It worked with almost no changes.

Scheduler.zip

 

However it needs changes to the delay function in the wiring.c and an empty "hook" from the Arduino source distribution for the yield() (so that the modified delay is backwards compatible and works without the scheduler).

changes.zip

These need to be placed in the ../hardware/lm4f/cores/lm4f/ directory (hooks.c is a new file, wiring.c is a replacement).

 

The test code works on my Tiva Launchpad as it should. So does the delay in a plain (non-scheduler) code. Please let me know if I messed up something.

Share this post


Link to post
Share on other sites

Great work! I will give it a spin this week!

 

The Scheduler lib is actually under the Apache License V2 and the initial implementation was done by the Google as part of the Android Open Source Project.

Either way you are fine. Just make sure that you keep the copyright headers in tact. Don't forget to put a line in the header that states that you have modified it for the Energia project.

Share this post


Link to post
Share on other sites

I did another mod to the code for automatic yield at the end of all loops. This is a minor convenience improvement and should not break any code that uses the scheduler. However it is a slight concept deviation (hidden yields) from the Arduino variant (no hidden yields). This could be a #define option in the Energia.h  Let me know what you think guys.

Share this post


Link to post
Share on other sites

Below is the variant with the automatic yield at the end of all loops. You can defeat it by defining NO_AUTO_YIELD in the Energia.h.

Also included is an additional example how to spawn a task (not a loop). It does the job then exits, the context descriptor is then deallocated by the "scheduler".

 

I really like this task switcher, it is clean and minimalistic. Perhaps adding power management (going to sleep if all threads are suspended with a wakep on timer) would help, but for 95% hobbby apps this is not critical.

 

Again to run it you need both the library and the changes to the Energia core files (in ./hardware/lm4f/cores/lm4f/ directory):

Scheduler_v02.zip

core_changes_v02.zip

Share this post


Link to post
Share on other sites

@@energia

One more question - does the Energia ARM compiler perform global/interprocedural register allocation ?

The original scheduler code does not save the floating point registers in a task context (Arduino Duo is M3 core I think). Hence if global global/interprocedural register allocation is used I need to add floating point registers to the task context. On the other hand if it is not used in Energia I can do the opposite - reduce the task switching context to the stack pointer and link registers only :-).

Share this post


Link to post
Share on other sites

According to the "Procedure Call Standard for the ARM® Architecture" document the floating point registers S16-S31 should be saved by the callee. Hence to be fully compliant, the coop scheduler for the M4F core should have these saved in the task context. For efficiency reasons perhaps an explicit flag should be used during the loop/task spawn (so that S16-S31 saving occurs only if the loop/task uses the FPU).

 

This is a fairly easy mod to the Scheduler library. I'll probably do that when I get some spare time.

Share this post


Link to post
Share on other sites

@@vladn would it be possible to add a statistical output per thread that shows the maximum observed execution time, would be rather helpful when designing a system for threads not to be too long and/or detect unwanted blocking.

Share this post


Link to post
Share on other sites

It is technically possible, however since it is a cooperative scheduler such measurements can be easily done outside the scheduler library if required.

 

Task scheduling, prioritization and time stamping in a serious RT system is a complex issue and IMHO is outside the scope of the simple cooperative context switcher. This is a realm of RTOS and system design.

Share this post


Link to post
Share on other sites

Makes sense, I have it implemented outside at the moment and works ok.

 

I have implemented an UART parser, that spawns task when commands come. The problem arises when the task has not yet finished and the two instances run concurrently. Should this be something handled by the scheduler? As a workaround I am implementing a safety flag for it.

Share this post


Link to post
Share on other sites

The beauty of a coop task switcher for simple projects is that there is no true concurrency :). If you are inside a loop or a task - nothing else executes, unless you call yield or exit the loop. Hence you can use simple flags and not worry about reentrant functions, atomic operations, mutexes and such...

 

There is a more sophisticated task switcher code in the Arduino external libraries. I personally like the minimalistic approach of this simple switcher. The next step is too serious IMHO and somewhat specific to the chosen RT paradigm.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×