"Main Loop" Task Scheduling Algorithm Discussion

Official FreeEMS vanilla firmware development, the heart and soul of the system!
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

"Main Loop" Task Scheduling Algorithm Discussion

Post by Fred »

I was prompted to post this thread by a member that contacted me regarding using an RTOS as a base for our system. I don't believe that that is a good idea, however some aspects of RTOS code could be very useful with regards scheduling the mundane tasks like idle and boost control and shift lights etc etc etc.

Quite a while ago we had a thread with discussions about minimising latency to the fueling calculations etc. That thread is here :

http://www.diyefi.org/forum/viewtopic.php?f=8&t=77

I want to discuss this in more detail now.

A given block of code will have certain conditions that need to be met for it to run effectively.

Requirements/Properties :
  • Priority level
  • Takes X time to run
  • Must be run AT a fixed frequency
  • Must be run AFTER a fixed period
  • Must be run BEFORE a fixed period
  • Must be run based on some event(s) or condition(s) (the 3 above fall under this broad heading too)
  • Others?
I'm proposing that we have some system with a list of function pointers in an array that keeps track of when each was last run and has a set of information about each one that it can process. This would be easy enough to implement on a PC with an OO language, but not so easy in C on an XDP512.

Additionally, after reviewing the above linked thread, I think maybe the ASM call to the SWI *could* be useful after all. If our scheduling code checks the "calcs flag" before each scheduling operation and subsequent code execution then it could call that and cause the code to run there and then. This isn't much different to what we already have though, so maybe not...

Perhaps sticking with what we have is better and just using the subsequently left over time to do everything else is best?

If we do it how it is now though, at some RPM threshold, all that will run is the math code. That is probably not the best. At the least it should be the case that even under heavy load the other tasks do not get locked out totally. Perhaps something like "always run one task after the math task" or similar. Perhaps use some timer to KNOW how much time we have between desired math executions and run enough stuff to just fill that gap or not quite fill it or something. That wouldn't be tooooo hard either.

Additionally, it would be desirable for certain things to run more often than even the fuel calcs : rpm ign cut, fuel cut, ign retard, range checking of some parameters etc. It would also be desirable for some of these things to take effect immediately. I think the best approach for ign and fuel cut based on RPM is to test this on every revolution or other spot more often decoder dependent with a simple RPM calculation.
At 6000 RPM the motor is accelerating so hard that one revolution of the crank later the motor is turning 6390 RPM.
whittlebeast wrote:I was playing with the ski today and using the 026h8 code I hit 39000 RPM / sec on one of the stabs of the throttle. With a little napkin math I am coming up wth an interesting calculation. At 6000 RPM the motor is accelerating so hard that one revolution of the crank later the motor is turning 6390 RPM. I went from 4900 RPM to 7500 RPM in .067 sec. This should put timing calcs into perspective. PS: I still let Sea-Doo do the ignition timing.
Phil Tobin wrote:I can't post on the beta forum, but my car does 8000-9000 RPM/Sec in 1st gear, a free spin is good for over 30000 RPM/sec.
This is interesting stuff. Andy's setup is one of the most extreme I've read about in the MS world. Even on his setup if we implement this stuff all right we will be very close to correct with no correction/prediction of timing. Just by being fast and scheduled! Much better.

Andy posted this spreadsheet link http://www.ncs-stl.com/ms2/RevErrorCalc.xls in the same thread. (I have it cached if it disappears) He also sent me a data log back then (about 2 years ago) showing the data from his sea doo jet ski. Fairly interesting stuff indeed :-) I just reviewed my own logs and found 7130rpm/sec which isn't that high, but is probably typical of most applications I guess. None of that was free revving though, so I'm sure I could probably double that or more. WTF : http://www.diyefi.org/forum/viewtopic.php?f=6&t=308

Who would ever have thought that those operating system design papers I took years ago would come in handy now!? The were among my favourite papers anyway, but I didn't think it would be particularly useful at the end of the day.

Share your thoughts.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: "Main Loop" Task Scheduling Algorithm Discussion

Post by Fred »

Just to clarify what this is about, priorities of events are :
  • Engine Position/RPM Input - TOP
  • Ignition Output - Second
  • Fuel Output - Third
  • RTC, etc etc etc other ISRs - Fourth
  • Math Code - Fifth
  • "Main Loop" Code - Sixth
Where math code is the stuff that figures out how long the pulsewidth should be, when it should start, how much dwell, when that should start and end etc.
Where "main loop" code is everything else that doesn't run in an ISR like boost control, shift lights, idle control, etc etc etc.

This discussion is about how to minimise the latency to the math code while ensuring the "main loop" code gets run fairly regularly at all RPMs.

I hope that is more clear now.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
shameem
LQFP112 - Up with the play
Posts: 135
Joined: Thu May 01, 2008 6:30 pm
Location: Ann Arbor, MI
Contact:

Re: "Main Loop" Task Scheduling Algorithm Discussion

Post by shameem »

Is the interrupt generated for every tooth for the 36-1 wheel? If yes the timing between each tooth is the issue right?

so if x-> RPM

37*x/60 takes 1 sec

so for 1 tooth - 60/37*x

For 12000 RPM - it is 0.1ms

Is that right - i think i am making a mistake somewhere - i cant figure out any math - i have been working on some DSP problem for the past 6 hours - i need to go get some coffee intravenously......
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: "Main Loop" Task Scheduling Algorithm Discussion

Post by Fred »

OK,
  • The wheel code will just record time stamps and/or difference values.
  • Secondarily it will trigger events on preconfigured teeth as they come by.
The math code will look at all the variables, decide which teeth to trigger events from, and how long after that tooth to delay it by etc etc.

So you don't need to care about that 0.1ms time. Those chunks of runtime occur in the middle of everything else and we don't want or need to know when.

It doesn't matter, you just get data out of it, and put data into it. It's independent.

I hope that helps.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
shameem
LQFP112 - Up with the play
Posts: 135
Joined: Thu May 01, 2008 6:30 pm
Location: Ann Arbor, MI
Contact:

Re: "Main Loop" Task Scheduling Algorithm Discussion

Post by shameem »

Yes - i was thinking more along the lines of - an interrupt is generated every "X" milliseconds - so the runtime for main loop has to be less than "X" milliseconds so that the variables dont change in the middle of a calculation.... Otherwise unnecessary complications like semaphores and mutexes have to be involved...

The other thought is - after the sync process - the code knows which tooth is where and hence "knows" when to pay attention to the interrupt and when to just increment a counter and jump back into the main loop....... So the main loop can go on for a slightly longer time.....
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: "Main Loop" Task Scheduling Algorithm Discussion

Post by Fred »

The math code will take how long it takes unfortunately. Currently it's looking really good though.

The variables ARE banked already, there are currently 4 regions in two pairs. ADC in and ADC out with calcs in and calcs out.

The sampler is dumping stuff into the ADC bank constantly, each time it does this, it sets a flag.

Each time the main loop IF sees the flag, it masks interrupts, swaps the ADC bank number such that the fresh ones are now fixed and the old ones can be over written with new values. At the same time, the output stuff keeps reading the old ones until the calcs are done when the interrupts are masked again, the output bank swapped such that the things using the numbers get a fresh CONTIGUOUS set of variables to work from and the old ones are free to be over written by the math routine again.

At low rpm the math runs once per sample and sits idle till the next sample. At higher rpm by the time you get done doing the calcs you already have a new set of readings to calculate from and the process repeats. At higher RPMs some samples will be lost. This was deemed to be OK recently by a number of people.

It's funny though, my original motivation for coding that banked system was the following :

MegaSquirt logs always have mixed data in them!! When you get VE = 100% out of the log, you migh find map at 20kpa and rpm at 7000 where ve is actually 30% but there the numbers are and they don't match. I find that frustrating. You should either get the full story, or none of it! Hence, the logs are also reading static data that is contiguous and a matching set. Everyone wins :-)

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
shameem
LQFP112 - Up with the play
Posts: 135
Joined: Thu May 01, 2008 6:30 pm
Location: Ann Arbor, MI
Contact:

Re: "Main Loop" Task Scheduling Algorithm Discussion

Post by shameem »

Fred wrote:At higher rpm by the time you get done doing the calcs you already have a new set of readings to calculate from and the process repeats. At higher RPMs some samples will be lost. This was deemed to be OK recently by a number of people.
What if - the main loop was terminated when it finds a that a new value is in? Like when you set flag make it slightly intelligent like

Code: Select all

if current_value != prev_value then flag=1
or

Code: Select all

if abs(current_value - prev_value) > x then flag=1
and then the main loop sees the flag and jumps back to beginning. Also there has to be counter for the jumpbacks - like no more than 3 contiguous jumpbacks are allowed..... just to prevent the loop from constantly jumping back....
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: "Main Loop" Task Scheduling Algorithm Discussion

Post by Fred »

Quite simply because if you start doing it with fresh numbers and find that something has changed in the middle, it means that the engine is turning fast enough that that WILL happen again if you retry. So, you should carry on with the first one because every time you restart your old data is being used a little longer and you are delaying the arrival of new data for zero gain. Interesting idea though :-) Got that caffeine into you yet? :-)

Let's have some ideas about the other tasks as well. if it were just the math code, the present implementation would already be optimal. Because it's not just the math code we need something flexible and better to allow the other tasks to be executed effectively.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
User avatar
BenFenner
LQFP144 - On Top Of The Game
Posts: 360
Joined: Wed Jul 09, 2008 3:15 pm

Re: "Main Loop" Task Scheduling Algorithm Discussion

Post by BenFenner »

The math related to idle control doesn't need to take place above x where x is the user-entered value for idle rpm + the amount of rpm needed to soften the transition to idle.

Low hanging fruit I know... =/
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: "Main Loop" Task Scheduling Algorithm Discussion

Post by Fred »

Actually, that is a very good point!

If the scheduler (which doesn't know or care about rpm) runs the idle control block and finds that it runs too quickly (because it's wrapped with an "if rpm less than 1500" statement then there is time to run something else as well. Perhaps the runtime of each block or total blocks could be monitored.

Idea : the scheduler sits in a nested loop of it's own and records a start time before running the first task, then after each task, it checks the time elapsed and if its still too small, runs something else, and if not, exits to the beginning of the main loop where the requirement for the calcs to be done is tested again.

I was also thinking about IO for each block. It may make sense to extend my banking scheme to allow say ignition calcs to finish and that data to be "switched on" then and there, then let fuel calcs run and do the same, ditto all other blocks. Picture a long row of toggle switches where as you run code for each one and complete the switch is thrown and the fresh data becomes accessible to for example the logger if it were to run using interrupts for some reason. If the logging is just another task then such banking is unrequired because it's a one way street, although it would still be nice to have a single history field for each calculated value giving you literally twice the chance to catch spikes and bugs etc.

With regards fuel and ignition, it probably make sense to do it that way because it shouldn't be running so slow as to get any advantage from that.

Cheers Ben! You see, even something unsuspecting like idle control rpm threshold could trigger another idea or two :-) Keep it up.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
Post Reply