From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ken To: egcs@cygnus.com Cc: c++-embedded@cygnus.com Subject: Re: timer idioms in embedded system Date: Fri, 03 Jul 1998 00:49:00 -0000 Message-id: <359C1778.55B0@well.com> References: <35931852.1509@compuserve.com> <359B0170.D922E2B9@agt.net> X-SW-Source: 1998/msg00020.html Aerospace Software wrote: > > Hi Ken, > > From a code maintenance point of view, it is better to have a separate SW > timer for each and every event that needs timing. In order to get a picture > of what the system is doing, simply take a snapshot of the timers. This > method is akin to a finite state machine and has the same good > characteristics - all events and states are defined and nothing unexpected > can possibly happen. > > I infer from you example that you are probably using a single code > thread/task -whatever you want to call it. If you are using a multi tasking > system, then waiting for a timer to expire in a tight loop is not a good > idea, since the system could have used the time to do something else. Correct. The current system is a single thread that updates several state machines (eg. command parser, system state). > Consider implementing a simple scheduler - round robin, run to completion is > usually good enough. Let the tasks communicate with each other through > either message passing and queues (if it is important that the sequence of > event be preserved) or with a bulletin board of semaphores/flags (if the > sequence of events are not important). Keep the system exclusively event > driven based upon these inputs and never ever make it sit in a wait loop. That's my ultimate plan when I ultimately change platforms, but the current platform is severely memory-limited and there's no room for an RTOS. > Your timer interrupt handler could then communicate with the tasks either by > posting a message to a queue, or setting a flag, or calling a procedure (for > regular repetitive events). > > Note that you already have a 'single counter' as you were thinking of. This > is non other than the HW counter used to create the interrupt tick and it is > rather inconvenient to use from a SW point of view. Therefore, it is safe to > assume that if you simply use the HW counter as a prescaler to another SW > timer, it will remain equally inconvenient! > > The trick is to optimise the timer code such that the system can scan the > active timers very quickly and only spend appreciable time on the ones that > are active. For limited memory, it's actually pretty optimized now. With more RAM, I could implement separate tasks with their own stacks and timer delta lists as described in the 2nd volume of _Internetworking with TCP/IP_. > Ken wrote: > > > I'm trying to come up with a good timer idiom that doesn't use much > > interrupt time. > > > > My current code (single-threaded, no RTOS) uses an array of words to > > represent global timers. The timer interrupt decrements any non-zero > > timers. Code that wants to use a timer sets it to a non-zero tick count > > and then waits for it to decrement to zero with a simple "while (timer) > > ;". > > > > I'd like to change this to use a single counter incremented by the > > interrupt. Client code would wait for the counter to increment to a > > desired value. Example wait code might be > > > > unsigned long expire_time = clock() + delay; > > while (clock() < expire_time) /* wait */; > > > > How should I handle rollover? I expect the counter to be 32-bit, and the > > interrupt tick to be 1 millisecond. The rollover should occur about > > every 46 days. > > > > It seems like I could declare the 32-bit values as signed and do > > something like > > > > long clock(); > > long expire_time = clock() + delay; > > while ((clock() - expire_time) < 0) /* wait */; > > > > Is this reasonable? -- Ken mailto:shiva@well.com mailto:shiva@CompuServe.COM http://www.well.com/user/shiva/ http://sewnsurf.home.ml.org/ http://www.e-scrub.com/cgi-bin/wpoison/wpoison.cgi (Death to Spam!)