Shop OBEX P1 Docs P2 Docs Learn Events
Multi Threaded SX/B — Parallax Forums

Multi Threaded SX/B

pjvpjv Posts: 1,903
edited 2007-03-09 23:16 in General Discussion
Hello Bean and SX/B Users;

Generally my needs for SX programming require numerous simultaneous timed tasks to be running, and·more often than not, those tasks need to be rather deterministic in their timing.·This need prevents me from using SX/B as it will not permit (I believe) multiple tasks to be run concurrently. So the wonderful work you have done in implementing SX/B effectively cannot be utilized by users with these requirements, and we are relegated to continue to work in SX/Assembler.·What a pity.

So I was musing about this, and started some experimentation in simplifying and adapting one of my (non-preemptive) RTOS methods·the see if·it·could·be integrated into SX/B. At this early point in my tests, I am able to have several timed tasks running concurrently and fairly deterministically by invoking a fairly simple calling method that lends itself to macro instancing, and takes on the behaviour of your blocking "Delay" loops.

In my case the loop is tested, and if not expred, then it is exited to carry on with the next thread in the program sequence. I believe what your·delays need can be served by my approach, but I'm not privy to the internal·operation and requirements·of SX/B, so I'm making assumptions at this time.·Also, it is still early in·my experimentation, and there could be disappointments. However,·if you could successfully incorporate this concept into SX/B, the effect of this would be to make it unblocking, permitting multiple timed threads to operate mostly independently although there will be some restrictions.

I am polling the SX/B community to see if this concept has sufficient interest for me to work out the remaining details - if possible-, and submit it to yourself for consideration.

What is the interest??

Cheers,

Peter (pjv)



·
«13

Comments

  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2006-11-29 10:59
    pjv,
    It would be great to have that in sx/b.
    I remember from MSX basic, it had a ON INTERVAL=nnn GOSUB construct
    which would allow to define a subroutine that would get called at regular intervals.
    Accompanied keywords were INTERVAL ON (start interval timer), INTERVAL STOP
    (suspend interval timer) and·INTERVAL OFF (stop interval timer).
    At the start of such a subroutine was an implied INTERVAL STOP to prevent
    calling the subroutine from within the subroutine in case it took longer
    than the interval time. At the subroutine end the INTERVAL timer resumed
    unless an explicit INTERVAL OFF or INTERVAL STOP was executed in the subroutine
    (nice for a one shot subroutine).
    I can imagine having INTERVAL0 to INTERVAL9 to support 10 scheduled tasks.

    regards peter

    ·

    Post Edited (Peter Verkaik) : 11/29/2006 12:51:09 PM GMT
  • BeanBean Posts: 8,129
    edited 2006-11-29 12:24
    pjv,
    · Currently the delays in SX/B are just calculated from the clock speed.
    · How does the delay loop "give up" it's time slice when in a loop ?
    · So if you have a "PAUSE 1" and the thread is given a time slice every 10uSec, then does it just "give up" it's slice 100 times ?
    · Of course the compiler would need to "know" at compile time that the thread has a 10uSec time slice.
    · How do you handle the __PARAMx variables in global RAM ? Do they need to be swapped for every task at every·time slice ?
    · Can you show some pseduo code of how you think it should be done ?

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Stuff I'm selling on ebay http://search.ebay.com/_W0QQsassZhittconsultingQQhtZ-1

    "People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin


    Post Edited (Bean (Hitt Consulting)) : 11/29/2006 3:02:07 PM GMT
  • RsadeikaRsadeika Posts: 3,824
    edited 2006-11-29 14:42
    Peter (pjv),

    I asked a simillar question, in another post, as to whether SX/B could do something along the lines of what you described. The answer, the SX/B compiler,·at this time, does not have the "horsepower" to do that.

    So, out of curiosity, what are your thoughts on how you would implement some thing like that, in SX/B. Are you thinking inline asm code, super macros, or do you have another solution.

    Yes, I am interested in seeing a solution, but it would have to be whithin an SX/B context. I just started playing around with the Propeller, and it dawned on me, for my application at least, what a powerfull combination a Propeller and an SX52 protoboard make.

    Ray
  • pjvpjv Posts: 1,903
    edited 2006-11-29 17:13
    Hi Bean;

    Please, my testing on this for possible SX/B implementation is still in the early stages, and won't likely proceed if there is not sufficient interest...... I still see a fair bit of work ahead.

    As you know, I have developed a full multi-threaded pre-emptive RTOS for the SX28, as well as a more simple minded non-pre-emptive co-operative RTOS (more like a scheduler really) that consumes less resources. Both of these are written in assembler, and I expect the pre-emptive unit is likely not compatible with SX/B; too many conflicts. It is the simpler co-operative RTOS that has a chance.

    Please correct me if I'm wrong, but my understanding is that SX/B stalls in a delay loop whenever a timing event takes place, such as serial communications. the processor hangs until the loop is completed, and no useful work can be done during this period. In fact, no other tasks can run simultaneous with these delay loops, and that is why SX/B serial communications cannot transmit and eceive at the same time.

    What I'm proposing (and this is a feature of both my RTOS schemes) is that timing is effected by scheduling things to occur, not by waiting for a certain number ol wait loops. What would need to happen is that SX/B be modified to eliminate its delay loops in favor of using a scheduling approach. In such a case, when a timing function (delay) is required, the calling program initiates a timer, and then immediately releases the processor to carry on with the next thread, and the timing function (delay) is performed in the background. When the timer has expired, it picks up the thread that called it at the point where the call was made.

    There will undoubtedly be some restrictions and compromises making this approach not possible for all SX/B applications, but I believe it has a good shot at being reasonable for most.

    Cheers,

    Peter (pjv)
  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2006-11-29 18:03
    pjv,

    I am definitely interested in seeing some multi-threaded support from within SXB! This is something that I keep thinking I am going to need... but so far have always managed a way to serialize my programs to produce a sufficient result. However, I do not expect this will always be the case.

    I have wondered why things like serial communication and sound generation do not “spawn” a separate process and run in the background like processes do in Unix. Yet when I think about how this would need to be accomplished on a device with such limited RAM, I quickly conclude that each application would likely need to be custom designed to maximize the available resources. Or perhaps the compiler would need to be supper-smart in order to figure out how to best optimize everything.

    I have to give kudos to Bean and the others who are contributing to the development of SX/B. I fully intended to delve deep into SX assembly and only expected to dabble in the free BASIC compiler that was available. So far I have found almost the complete opposite to be true. SX/B meets most all of my “basic” needs and I only dabble in assembly language when I need tight control of something or timing is critical.

    So yes, I would like to see a multi-threading option for SX/B. Certainly. I would also enjoy seeing how you are accomplishing multi-threading in assembly even now. I have looked at several examples of how others are doing this and keep thinking, “Someday I will need to do this. Someday!” So the more you care to share, the better for the SX community, I would said.

    I hope you are inspired to do this!

    - Sparks
  • pjvpjv Posts: 1,903
    edited 2006-12-15 04:42
    Hi Terry and All;

    I have been doing considerable further work on this version of multi-threading the SX, and I am more convinced than ever that is could be fairly readily incorporated into SX/B.

    At present I have 8 (probably a reasonable maximum for demanding requirements, but can be easily expanded for mre modest needs) threads operating "simultaneously".... one 9600 baud transmitting UART and one receiving that data (both software bit-banging), one thread triggering the TXUART transmission every 3 milliseconds, one 100 KHz square-wave generator, one 10 KHz square wave generator and one 3.3 KHz square wave generator.

    These are just simple code samples to prove the OS design..... any code could be used as long as there were not too many simultaneous demands on the processor. After all, it is only a co-operative RTOS, not a pre-emptive one. So at very high demand moments, there can be some jitter in the high speed wave generators. The 9600 UARTs are rock solid.

    The consumption of resources is fairly nominal; two registers per thread plus three global·timer registers. Each thread stores the number of ticks unil the thread will run again, and also the point in its thread where it will resume operation. This latter permits convenient branching at specified intervals or events.

    The processor overhead is about 30% when high speed is involved; fairly high for tight and really busy applications, but for modest for most.

    In this version I have chosen the basic clock tick to be 5 uSec, and that is the fastest reasonable speed; from that a 100 uSec and 1 mSec tick are generated, and all threads run their slice of work based on multiples of any of those.

    In the co-operative scheme each thread runs for a short while, such as inputting one bit in a UART, and then, instead of entering a delay loop, it relinquishes the processor back to the OS for another thread to have a go. The relinquishing thread notes where it left off, and when it gets another turn (after it's number of ticks from its chosen 5 uS/100 uS/1mS clocks have expired), it picks up where it left off, or alternately branches to another part of the thread.

    I believe I have most of the bugs worked out, and would like to hear if you are interested in incorporating this concept into SX/B, thereby making it multi-tasking. Frankly though, there has not been much expression of interest in this concept..... perhaps many don't have the need, or don't understand the benefit of this.

    Cheers,

    Peter (pjv)
  • Ken GraceyKen Gracey Posts: 7,386
    edited 2006-12-15 05:54
    Hi Peter,

    I'm interested!

    I have the need and I understand the benefit, but I've had trouble making use of the counters and stack with low-level languages. SX/B gives me enough familiarity with something else I already know (BASIC Stamp) that I can get much closer to the SX architecture. Although I want to make the time to learn, I just can't justify it when Parallax has other priorities for me and my free time goes towards machining. But every now and then, I build something that needs the SX for control and I throw a Proto Board at the project, but I find myself thinking like a Stamp programmer. That's okay from my perspective though, because after small amounts of hands-on experience Guenther's book and the SX/B commands make a lot more sense to me. SX/B is an educational tool of its own and I learn by using it.

    If SX/B were able to provide some kind of multi-threaded support I'd be really happy. Even simple (for you) tasks like counting and generating pulses, running a UART and detecting button presses are examples of some things I'd like to do with SX/B. Even if it's a combination of ASM and SX/B, I could handle it if I didn't need to further tweak the ASM aspects of the OS. I know that you're thinking "no problem in ASM, Ken".

    I think there are other customers in my situation, who've spent lots of their time with BASIC Stamps but would appreciate having far more horsepower and concurrent processing for just a couple of bucks, especially if SX/B took them there.

    Ken Gracey
    Parallax, Inc.
  • Capt. QuirkCapt. Quirk Posts: 872
    edited 2006-12-15 10:03
    Wouldn't it be a lot easier to just use 2 processors?. I've seen a need for such a thing, but I would rather see Parallax make improvements in the SX IDE and some code improvements, similar BS2P series. I know there's another version of sx/b being tested and there was supposed to be an SX/B book coming out this year
  • Capt. QuirkCapt. Quirk Posts: 872
    edited 2006-12-15 10:10
    "I think there are other customers in my situation, who've spent lots of their time with BASIC Stamps but would appreciate having far more horsepower and concurrent processing for just a couple of bucks, especially if SX/B took them there".

    I really liked that statement, but for me, more HP is a learning curve that isn't so steep
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2006-12-15 16:13
    I was looking at multitasking with the SX/B and basically it seems that the multitasker is merely an ISR that divides the currently called ISR amongst a schedule [noparse][[/noparse]usually about sixteen].

    If you want something called more frequently, you give it more slots. Since this specialized ISR jumps to the code, it would seem to me that the code could be in SX/B or assembler. It just cannot be too long and overrun the ISR - 50% or less of the interrupt interval would allow the main program time to get something done.

    While I haven't tried it, I suspect it is quite possible. I refer to an old Ubicom document for a code prototype in SASM. See Dual UART Virtual Peripheral Implementation-AN39 [noparse][[/noparse]Nov 2000]

    Frankly, it seems so simple in SASM that I might be harder in pure SX/B.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "If you want more fiber, eat the package.· Not enough?· Eat the manual."········
    ···················· Tropical regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
  • BeanBean Posts: 8,129
    edited 2006-12-15 16:49
    How about a set of standard VPs for the compiler, much like the Javilin does.

    SEROUT, SERIN, PULSOUT, PULSIN, ANALOGIN, RCTIME, FREQOUT, etc.

    Something like:

    INTERRUPT 200000
    VPSERIN SInPin, "T2400", array_buffer, byte_head, byte_tail, byte_bitCnt
    VPFREQOUT SFreqPin, 1000, byte_progress
    RETURNINT


    Start:
    IF byte_head <> byte_tail THEN
    char = array_buffer[noparse][[/noparse]byte_tail]
    INC byte_tail
    byte_tail = byte_tail AND $0F
    ' Do something with "char"
    ENDIF

    I guess each VP would have to take the same number of cycles no matter what to keep everything sync'd.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Stuff I'm selling on ebay http://search.ebay.com/_W0QQsassZhittconsultingQQhtZ-1

    "USA Today has come out with a new survey - apparently, three out of every four people make up 75% of the population." - David Letterman
  • pjvpjv Posts: 1,903
    edited 2006-12-15 17:01
    Hi Kramer;

    Your suggestion is one way to tackle things, but then the time slot allocations are not dynamic which it needs to be for effective load sharing. In the scheme I'm proposing each thread can dynamically allocate when it needs to run again, (if at all, such as after a boot procedure), and it can also switch tasks in and out. There can be any (reasonable) number of tasks, but ony 8 running at one time in my current set up. That number (8) is not a hard number, just one that I chose. The more concurrent tasks that are running though, the more interaction (jitter) there will be, especially if the tasks are called very frequently, such as 100 KHz and up.

    Achieving this is not as simple as you may think ..... at least that's my experience. But then what do I know. There are a lot of folks more capable than I am out there !

    Cheers,

    Peter (pjv)
  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2006-12-15 18:52
    pjv,

    Will you be sharing your source code with the SX community?

    I think what you are offering could be quite useful. Others more qualified than I will need to weigh in on the feasibility of incorporating it directly in SX/B.



    Bean,


    Virtual peripherals that run in the background in SX/B would be great! I am envisioning a Serin command that receives a specified number of bytes in the background then calls a user-defined subroutine to process the data when it is ready. For Serout, I envision it sending a declared number of bytes from a buffer, then calling a user-defined subroutine when the buffer in empty. The user-defined subroutines could be as simple as setting a flag or more complex such as processing or formating data.

    From my perspective, having the VP call a subroutine when it needs more data or has data ready to be processed is more useful and seems like it would make more efficient use of CPU time. Sure I can always check the registers to see if more data is ready or needed but I think having the VP trigger a call to that section of code is a better approach.


    Other thoughts...

    It seems like a code-generating “Wizard” might be useful here. It could ask you questions about your clock rate, the number of tasks to be run, the required update frequency of each task, etc. and maybe warn you that although you requested an update frequency of X for task Y the best that can be achieved with the current configuration is a rate of Z. When the “Wizard” completes it would generate a section of code to achieve the functions requested.



    pjv again,

    I am clearly more familiar with preemptive multitasking as it has a “set it and forget it” mentality to it. For a cooperative environment, it seems much more likely that a change to subroutine “Z” might suddenly have an adverse effect upon the timing of everything else that is trying to run. It may be a more powerful environment, but if it is not easy to use only power users will benefit from it. This might be ok and in my opinion is better than not having it all. But since you asked for input, I will volunteer my opinion that the easier it is to implement the more useful it will be... to me anyway! [noparse];)[/noparse]

    - Sparks
  • CCraigCCraig Posts: 163
    edited 2006-12-15 19:50
    Peter,

    I think that there is a good response to this. Remember, that there are a lot of people on here that are not too verbal (like myself). I am very interested. I think you're right that some users might not know the power this could bring. It's our job to enlighten them.

    I hope this project is a go. Thanks, Chris
  • pjvpjv Posts: 1,903
    edited 2006-12-15 20:10
    Hi Sparks;

    You are definitely correct in being concerned about interaction in the case of this co-operative O/S. If one permits a thread to run for too long, then the various "tick clocks" well get jitter in them. And in severe cases, ticks could actually be missed; so you are probably right that some sort of "helper" would be useful to keep the unaware from outstripping the processor's capacity unknowingly.

    Regarding your example of receiving a number of bytes, and then calling a routine to process them, the current implementation (although in ASM, not yet in SX/B) already supports that. This is where the task switches to another routine. Tasks can also launch and terminate other tasks, as well as terminate themselves.

    Sure, I'll share this O/S with the community, but I want to do some more develoment and testing first, as well as write a good description of it as well as how to properly use it.... there are some restrictions. For example, the normal CALL/RET instructions cannot be used because different threads could (and certainly would, except for the most trivial cases) screw up the order and data on the call stack. So I have implemented CALL and RETURN macros and a "virtual stack" concept where each thread takes care of its own. This area could still use some further development and improvement...... its a little unelegant.

    In the mean time if anyone wants to try it (with the current warts) before I'm ready to release it globally, please express your interest. I will of course need to make up some descriptive information first.

    Cheers,

    Peter (pjv)
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2006-12-16 17:35
    pjv,
    I am sure you can write something far more sophisticated.
    Nonetheless, having something simple serves more as a bridge for learners to move from PBasic to SASM.
    If people don't want to learn SASM, dynamic allocation is quite convienient.

    It seems to be a split between being the educator or the rapid deployment of commercial uses.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "If you want more fiber, eat the package.· Not enough?· Eat the manual."········
    ···················· Tropical regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
  • RickBRickB Posts: 395
    edited 2006-12-22 03:47
    PJV

    Given the # of people that have asked how to make a BS2 multitask, I am surprised there hasn't been more interest in this thread. Maybe if you changed the title to Multitasking SX/B it would get more attention. A LOT of people would love to have a multitasking module for the Boebot.

    Rick
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2006-12-22 04:14
    Rick,
    Here is something I setup last week. I converted my assembly VP library
    to sx/b. Thanks to sx/b I no longer need macros to define VP code sections.
    The SUB declarations take care of that now, so the library is easier to read.
    Most subroutines however still have assembly. No escape from that for VP
    I expect but there are subroutine·you call from basic that set·and retrieve
    data from the VP's. It is not·finished (or even properly tested) but it
    shows in the test file how one would use the library.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-03-05 15:44
    I did some thinking about how threads could be supported in sx/b.
    The following should apply, I think:
    threads (lets call them tasks) should be coded in sx/b.
    This means the __PARAMx will be used and therefore need
    to be saved on each context switch.
    Let a task be just a subroutine that is declared in advance (like FUNC and SUB)
    with just 1 constant parameter, the task interval time in TASKTICK units.
    eg. myTask TASK 100
    TASKTICK·equals a userdefined constant number·of isr cycles.
    To reduce the required resources, let there be only 1 context switch.
    This calls the taskScheduler (which is generated by sx/b,·based on declared tasks).
    The taskScheduler·executes outside the ISR and is called every TASKTICK.
    It decides which task to call based on task interval time.
    In effect, the mainloop code is interrupted by the taskScheduler.
    It is the responsebility of the programmer to make sure the task subroutines
    return within 1 TASKTICK unit. Using a statemachine in a task subroutine
    will resolve any timing issue, if necessary.
    Having 1 context switch also means the mainloop code continues before another·task is
    called that interrupts the mainloop code.
    An option would be to have a rambyte per task to support on-the-fly task interval time.
    This would allow a task to reschedule itself with a higher priority (could be useful
    in case a statemachine is used inside a task).
    Tasks that need tight timing should be written as drivers, something like my library setup.
    This would mean the interrupt section should not contain sx/b code, as the compiler
    can generate the entire isr code from supplied drivers and tasks.
    Perhaps it is·sufficient to specify a 'task' keyword:
    interrupt task {,rate} 'interrupt line identifies isr used by drivers and tasks
    returnint
    Or perhaps TASKTICK should be passed via interrupt keyword
    interrupt 100,{rate}

    Comments please.

    regards peter

    ·
  • BeanBean Posts: 8,129
    edited 2007-03-05 16:08
    Peter,
    I'm a little worried... because I think I'm actually beginning to understand how the task scheduling thing works!

    It sounds do-able. Let me think about the implementation and I'll post another reply.

    It would be very cool to get this implemented in SX/B.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Coming soon! Propeller based OSD module www.hittconsulting.com
    ·
  • BeanBean Posts: 8,129
    edited 2007-03-05 17:42
    Peter,
    · It is a requirement that the tasks be run-time configurable ?
    · That will make it somewhat harder.

    · Maybe some simple examples would help me.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Coming soon! Propeller based OSD module www.hittconsulting.com


    Post Edited (Bean (Hitt Consulting)) : 3/5/2007 5:47:18 PM GMT
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-03-05 18:07
    What do you mean by runtime configurable?

    regards peter
  • BeanBean Posts: 8,129
    edited 2007-03-05 18:12
    To be able to start/stop/change TASKTICKS at run-time. I guess that would be a requirement wouldn't it ?

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Coming soon! Propeller based OSD module www.hittconsulting.com
    ·
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-03-05 18:27
    Bean,
    I attached a test program I am working on.
    The Reschedule subroutine does not work yet, but I hope it shows
    what I have in mind. I am testing using sx/b for the scheduler.
    Once we have the fastest algorithm to achieve this, it could be
    changed to assembly because in the end the compiler will
    insert the scheduler·code.
    Note that I defined the tasks at this moment just as SUBs
    with predefined interval times in the tasklist.
    Once you have the TASK identifier, the compiler can fill the tasklist.

    regards peter
  • BeanBean Posts: 8,129
    edited 2007-03-05 19:22
    put taskId      , 0, 1, 2, 3, 4, 5, 6, 7
    put taskInterval,10,13,17,23,29,34,37,41
    put taskDelay   ,10, 3, 4, 6, 6, 5, 3, 4
    
    

    Peter,
    · Does this mean that task "0" will run every 10 ticks, and task "1" will run every 13 ticks.
    · What happens if two tasks are scheduled to run on the same tick ?

    Bean.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Coming soon! Propeller based OSD module www.hittconsulting.com
    ·
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-03-05 19:39
    Yes, that is the idea. With a deltalist you only need to decrement the first entry.
    With 2 tasks scheduled for the same time,·the 2nd delay entry in the list is 0.
    Since only 1 task is permitted to run that would give an extra delay of 1 to
    the 2nd task. We need therefore to adjust the 3rd entry next time around
    so other tasks do not have this extra delay. This is easily detected if the first entry
    holds 0 upon TaskSchedule entry.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-03-05 20:35
    I changed Reschedule.
    We need to find the correct entry for the new entry0 value.
    Reschedule still does not work.

    · ' initialization code here
    'init lists in sorted order (this would be done by compiler based on task interval times)
    put taskId····· , 0, 1, 2, 3, 4, 5, 6, 7
    put taskInterval,10,13,17,23,29,34,37,41
    put taskDelay·· ,10, 3, 4, 6, 6, 5, 3, 4

    Main:
    · ' main code here
    · goto main

    'insert new entry0 at correct position in list
    SUB Reschedule
    · index=1
    · sumDelay = taskDelay(1)
    · do while taskDelay(0) > sumDelay
    ··· index = index+1
    ··· sumDelay = sumDelay + taskDelay(index)
    · loop
    · insert = index-1
    · if insert > 0 then
    ··· for index=1 to insert
    ····· indexMinus1 = index-1
    ····· temp = taskId(indexMinus1)
    ····· taskId(indexMinus1) = taskId(index)
    ····· taskId(index) = temp
    ····· temp = taskDelay(indexMinus1)
    ····· taskDelay(indexMinus1) = taskDelay(index)
    ····· taskDelay(index) = temp - taskDelay(indexMinus1)
    ····· temp = taskInterval(indexMinus1)
    ····· taskInterval(indexMinus1) = taskInterval(index)
    ····· taskInterval(index) = temp
    ··· next
    · endif
    · insert = insert+1
    · taskDelay(insert) = taskDelay(insert) - sumDelay
    return


    At first run
    taskId······ =· 0, 1, 2, 3, 4, 5, 6, 7
    taskInterval = 10,13,17,23,29,34,37,41
    taskDelay··· = 10, 3, 4, 6, 6, 5, 3, 4
    The 2nd run should occur in 3 ticks, entry0 (task0) must be rescheduled
    At 2nd run
    taskId······ = ·1, 2, 0, 3, 4, 5, 6, 7
    taskInterval = 13,17,10,23,29,34,37,41
    taskDelay··· =· 3, 4, 3, 3, 6, 5, 3, 4
    The 3rd run should occur in 4 ticks, entry0 (task1) must be rescheduled
    At 3rd run
    taskId······ =· 2, 0, 3, 1, 4, 5, 6, 7
    taskInterval = 17,10,23,13,29,34,37,41
    taskDelay··· =· 4, 3, 3, 3, 3, 5, 3, 4
    The 4th run should occur in 4 ticks, entry0 (task2) must be rescheduled
    etc.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-03-06 09:07
    I got Reschedule working.
    I simulated it using a javelin.
    See the attached text files for timing tables.

    The timing tables show:
    If N tasks are running, the minimal interval time should be N.
    If all tasks have identical interval time, they should have different start delays

    We could define a TASK to take 2 constant parameters: startup delay and interval
    eg. myTask TASK 3,10

    Bean, you mentioned start/stop a task.
    In my test program I support 8 running tasks, but since the taskId are loaded into ram,
    we could define more tasks, but only 8 can run simultaneously. A few bits of the taskId
    could serve as flags (status,suspend,dataready) which the mainloopcode can test.
    Lets say 3 flags (b7-b5), then there still can be 32 tasks.

    Since the arrays must be preloaded by the compiler, I think the task parameters
    are best stored as data, using iread to preload the arrays.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-03-06 12:25
    From a user point of view, it might be better to specify a task interval time as a rate,
    just as with interrupt. The compiler can·calculate the interval time ticks. Also, the
    initial taskDelay can be set to 1 for all tasks, meaning 1st task runs at 1, 2nd task runs at 2, etc.
    After a task has run, it will be rescheduled using its interval tick.
    So we can use

    myTask TASK rate

    where rate equals the number of times per second the task must run.
    The totalTaskRate equals the sum of the 8 tasks with the highest rates.

    From this TASKTICK can be calculated.
    Example:
    interrupt rate is 100_000 (isr cycle time is 10usec)
    8 tasks all with rate 50, then totalTaskRate is 400
    TASKTICK = isrRate/totalTaskRate = 100_000/400 = 250
    TASKTICK should calculate into range·1 to 256, if not, the user must specify another interrupt rate
    or other task rates.
    interval tick = isrRate/taskRate/TASKTICK = 100_000/50/250 = 8
    = totalTaskRate/taskRate = 400/50 = 8

    Bean, you suggested that TASKTICK should be runtime configurable. I don't think that is
    wise, because TASKTICK is global to all tasks. Better to change a task's interval tick to
    adjust the task rate.
    With the given test program, a task can easily change its own interval tick. When a task runs,
    and it alters its interval tick, it will be rescheduled with this new tick upon return.
    The only problem with changing interval ticks (eg. taskrate), is that TASKTICK also should be
    recalculated then, and because of that, also the interval ticks of all tasks. However, if·a task
    changes its interval tick for a short time, and then restores the original value, it may
    not give problems at all.

    regards peter

    Post Edited (Peter Verkaik) : 3/6/2007 12:55:45 PM GMT
  • BeanBean Posts: 8,129
    edited 2007-03-06 15:14
    Peter,
    This is starting to sink in. So here is a dumb question... Is it possible to run two task during 1 tick ? (one after the other, not one interrupting the other).

    I'm thinking what if you had a long tick time (like 100mSec) and really quick tasks (like toggling a pin).

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Coming soon! Propeller based OSD module www.hittconsulting.com
    ·
Sign In or Register to comment.