I'm going to top post this because I want to keep the following response from Matthais but want to make a couple of short comments concerning the use of the cooperative tasker.
1) it is possible to wait for an event in a task and still allow other tasks to run. Use a construct like: while (waiting for keystroke) swap(); 2) I almost always do use timers with the tasker. Typically I will setup the main counter so it rolls over about every 5mSec (you can choose your own value). In the ISR for the rollover I increment a volatile uint16_t I call sysTICs. Then I create a couple of timer handler functions; getSysTICs() returns the current value of sysTICs; uint16_t getElapsedSysTICs(uint16_t startTICs) returns the number of rollovers from startTICs to now (the current value of sysTICs). These two functions can be used in a number of ways: a) int ch; uint16_t startTICs = getSysTICs(); while ((ch = getKey()) < 0) && (getElaspedSysTICs(startTICS) < timeoutTICs)) swap(); b) void sleep(uint16_t duartionTICs) { uint16_t startTICs = getSysTICs(); while (getElapsedTICs(startTICs) < durationTICs) swap(); } Several tasks can have different timeout timers active at the same time while only using the rollover interrupt from a single timer channel. Regards -Bill Knight R O SoftWare On Fri, 12 Dec 2003 15:37:00 +0100, Matthias Weingart wrote: On Mon, Dec 08, 2003 at 11:45:16PM +0800, Steve Underwood wrote: > Hi all, > > The tasker code in examples, is function but very basic. Oleg's SOS is > rather more functional, but doesn't really address the needs of an > MSP430 user - it does nothing about power management. Hi Steve, I have analysed my code, and in most cases my routines are hanging around in sleep() or busy? statements, waiting for something to get ready. Most of that sleeps() are not time critical; it does not really matter if the sleep takes little longer than specified. Most of the time you have all your tasks sitting in sleep(); the CPU can switched off, until the time elapsed (or you got an interrupt, and there is some work for you tasks). The cooperative multitasker is a good idea to use that idle time in other parts (tasks) of the firmware. The tasker has one advantage: it does not need any timer. Timers are a very rare ressource (I wished TI is spending more timers to their MSP's; timers should not need much silicon, why not 5 timers?), but with a sleep() function (waiting at least xx ms), we need a piece of code that is executed periodically. The user of the OS should add this code to one of his timer interrupt routines. If no timer with a fixed timing is available, one can use a simple 555 like timer at 2 (or 1) interrupt port pins (slaa119). However, if you do not need sleeps() you can drop that code, and tasks are switched as long as there is not task ready then it goes to LPM until the next interrupt. Another advantage of the tasker is that the tasks are switched when everything in your task is finished and ready to switch to another task (no critical sections, no headache with hwmul). Disadvantage of the cooperative tasker, however, is that you dead lock the OS if one task is blocking. You should never use while( busy ) statements, it should always be a while( busy and not timeout() ). There should also be a possibility to get a task running immediately (wake up a task). Example: You get a ADC interrupt. All your tasks are sleeping. In the ADC interrupt you specify the task that is executed after RETI, and your ADC results are processed right away (the same implies for other tasks). summary, extensions to tasker: - sleep(ms) (until time elapsed) - sleepinfinitely() (until interrupt, until another task has finished) - timeout() - code for a timer interrupt - some possibilities to prioritize tasks - if all tasks are sleeping switch to LPM However this tasker would only work if all your tasks are sleeping periodically and you can broke your code in pieces that are shorter than your minimal timing requirements (e.g. ADC interrupt intervals). Next point is non thread save code (e.g. access to hardware). With a cooperative multitasker, not thread save code is no problem, as long as it is not using sleep() itself (switching to other tasks), it does not use globals and you call it from only one task. But is this possible, really? Sometimes, maybe; then there should be a mechanism that could tell you that you do not call non thread save code from different tasks (is gcc able to list a call tree for all function calls?). Probably we need semaphores and events here. I have written this from the view of a firmware programmer (not from the theoretical view of a OS programmer). Ok, lets compare my list with the features of SOS or uCOS. Oops, I think I reinvented the wheel. ;-) Make it sense to reinvent the wheel? Maybe making it modular, let the coder only use the parts he really needs... Matthias ------------------------------------------------------- This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click _______________________________________________ Mspgcc-users mailing list Mspgcc-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mspgcc-users