Hi... Been Playing with ideas of how best to write a RT OS for underpowered pics like the 1654, or 12c508 don't know how practical it is.... But I am playing with an idea that might reduce the code size for the following, at the cost of 1 data file register. (Psuedo code allert [achem... sorry it isn't C] Var int x one register for the thread index Main x:=0 Loop reset_dog do_task[x] indirect call to task managers x=((x + 1) and 3) (in assembly language you might want to use a decrement and bit test for zero and add the max index instead of the increment and AND approach.) loop end. routine do_task[index] caseof index then 0;do_task1_next 1;do_task2_next 2;do_task3_next 3;error ("task-overflow") endcase This can be changed to do any odd number of tasks by increasing the size of the number after the & sign. I am playing around with this concept, but the indirect addressing is quite ugly in PICASM. The nice thing about this approach, is that you don't need interrupts to regulate the program flow/timing (which is good since the low end pics don't have them) as long as you go to a Macro-Cycle approach where each task snippet you run, is the same length of time. (Pad it out with Nops if nothing else). I have a quicky little delay loop that will delay a set period of time, but I need to feed that delay time to the loop automagically if I don't use standardized cycle sizes. Using a standard Macro-Cycle approach allows you to set your timing loops as if you had an interrupt, and allows you to manage your dog a little easier, since you reset it always to the same length of time. If your dog actually bites, then you know that the previous snippet of code was corrupted, or poorly written and overflowed its macro-cycle. if you keep a register to keep track of which snippet you are on, for each task, you can use multiple length tasks instead of trying to match their lengths. As long as you don't exceed 256 snippets, you can index a common library making your code more re-useable. My main problem is figuring out just how much infrastructure I want to include in the design of my general case, since each little bit of ram I use in the OS, is that much less ram for the application. GRAEME SMITH email: grysmith@freenet.edmonton.ab.ca YMCA Edmonton Address has changed with little warning! (I moved across the hall! :) ) Email will remain constant... at least for now. On Sun, 9 May 1999, Mark Willis wrote: > To build a real time operating system like this, the usual approach is > to do this (Time-Slicing Real Time OS idea; Pseudo-Code warning ): > > Setup_Task1(); > Setup_Task2(); > Setup_Task3(); > Main_Loop: > Do_Part_of_Task1(); > Do_Part_of_Task2(); > Do_Part_of_Task3(); > Do_Short_Delay(); > goto Main_Loop; > > The main idea here is to split each task into little tiny "time slice" > pieces - i.e. the first time you call Do_Part_of_Task1(), for example, > it just does one small part of it's job - the next time through it does > the next part of it's job, and so on. Something like: > > Proc Do_Part_of_Task1() > { > Static Int WhichSlice1=0; /* Initialize only at startup, not with > each call to this procedure */ > Const n = 3; /* number of total time slices for this task, arbitrarily > 3 here. */ > > WhichSlice1 = (WhichSlice1 + 1) mod n; > Case WhichSlice of > { > 1: Do_Task1_TinyPart1(); break; > 2: Do_Task1_TinyPart2(); break; > 3: Do_Task1_TinyPart3(); > } > }; > > There is no "Wrong" way to do something like this, so long as your > code works, it's "right". Do it the way that makes sense to you! > > Mark > > erik wrote: > > > > Roland, > > I've been giving this alot of thought but don't think I can do things > > entirely with an interrupt on > > TMR0 rollover. I would like to simulate a printing press running at > > 3000 ft/min which would require a pulse > > once every 43usec with a 2500 pulse encoder. There are other signals > > whose frequency is directly > > proportional to the press speed. I could have TMR0 overflow at 43usec > > and in the ISR I would turn on the > > "encoder output". Three switches would be used to set the "press speed" > > and would directly correlate > > to the prescaler bits. This way, if all timing was based on the TMR0, > > the whole "machine" would slow > > down. > > > > My problem is: that on some machines (and therefore my simulator) there > > are 2500 and 1200 pulse per rev encoders and > > either a 2:1 or 4:1 shaft to encoder ratio. To facilitate this > > functionality I think I would need a routine > > independent of the interrupt that determines if it is time to turn on > > the "encoder output" based on the > > "machine configuration" ie. configuration switches. > > > > My original intent was to have TMR0 interrupt every 1 msec as a means of > > incrementing a "global timer register". The various routines in the > > program would then check with the "global timer" to see if it was > > time for an output. The "global timer" could easily be slowed down and > > all the machine functions would > > slow as well. Unfortunately I've found that with a press speed of > > 3000ft/min with a 4:1 1200 pulse encoder > > I'll need to output an encoder pulse once every 23 usec. At 20MHz OSC I > > could load the TMR0 with 141 so that > > 115 cycles would generate an interrupt at 23 usec. Now keeping track of > > the machine speed has become more > > difficult. There is a once per revolution pulse from paper roll that > > obviously is dependent on the machine > > speed but also has to increase in frequency as the paper roll gets > > smaller. That part is easy enough if I can > > establish a "metronome" or "heart beat" of the machine. I'm just not > > sure how I'd do that if my "heart beat" > > changes with different encoder configurations. > > > > 23usec pulse at [(1200 pulse/rev)*4] and > > 43usec pulse at [(2500 pulse/rev)*1] > > both = 3000ft/min > > depending on which machine configuration I'd like to simulate. > > i.e. while the encoder output pulse changes with the configuration > > switches, the other signals must not. > > All this said, am I correct in thinking that I cannot manipulate the > > "global timer"/"heartbeat". Instead I must establish a "heartbeat" and > > change the encoder frequency for different configurations. > > > > Maybe I'm just not thinking sneaky enough. I'm still very new at this. > > If you use a 20 usec Macro-Cycle with a 3 usec delay, in setting one you would use 1 macrocycle plus delay to impliment the pulse timing in setting 2 you could use two Macro-Cycles with a 3 usec delay to implement the 43 usec pulse timing. Because the Macro-Cycle architecture does not respond to an interrupt, it can slip in time when that is what is needed. In a 4Mhz clock, a 3 usec delay can be achieved by calling to a routine that consists of a single nop. In a faster clock, you might have to pad it out a bit.... ;) all in all I think you simply need to think a little sneakier, or get more familiar with sequencer design. I hope this helps Grey