Saturday, December 20, 2008

Timekeeping

Recently I've been designing an embedded hard real-time environment for controls purposes in my head. I've gotten somewhat detailed with it and you can see some of the plans I've made here: http://steves-wiki.wikispaces.com/ Look at the microcontroller architecture headings (and look at everything else while you're there). It's not finished yet but I think I have some good ideas down there. One of the major issues in a hard real-time system is timekeeping. If you have two or more chips of any type (microcontrollers, programmable logic, RTC, etc) that need to keep or be aware of time then you have a problem.

Ideally there is a 'time' right now. December 20, 2008 7:22:33.44 PM. We humans need to coordinate times on the level of minutes usually. Our clocks are always minutes off of each other and we still function well enough, but control systems need to keep accurate timing on the order of hundredths of a second if not less. As my mentor likes to say "In a real-time system if it's late, it's wrong." We have accurate timekeeping hardware for embedded chips. Crystals are very accurate if used correctly, so just attach it to your controller chip and go. There's only a problem when your system consists of multiple chips with multiple clocks. Even if they all have accurate crystals still all have to be accurate to each other. One chip is doing the controlling and if it needs data from different chips or systems then it MUST be there before it has to send out its next control update or at the very least you'll have degraded performance. Not only must each part have an accurate clock, they all must have the SAME clock.

How do you do this? Off the top of my head I envision a timekeeper, maybe a small microcontroller with an RTC. It will keep accurate time and transmit the current time to each subsystem that needs it. Great! Except not. Serial messages take time to create and send, that's delay. That means when you send your message with the 'time' in it, it's not the real time anymore. If you can characterize this delay and you know that it's insignificant compared to your timekeeping rate then you might be OK. But then you need to have a dedicated serial port for the timekeeper, or use a bus (but then you have to deal with bus contention, possibly delayed time messages, etc). Further, what happens if your messages don't get through? You'd need some kind of ACK response from each sub system, then your timekeeper has to process those. Even then if you don't get an ACK what do you do? Resend and hope for the best. Throw a fault to your superior if you consistently don't get a response.

Alright, let's go a little deeper into this serial idea - I like it. Let's assume that the time is represented with a 16-bit value that is the count of milliseconds since the system started keeping track of time. Our control system's sample time is 10ms, so we'll send time updates every .5ms. With a message structure of 8 bits, no parity and one stop bit, that will be 10 bits total for every data byte, and two bytes of data equals 20 bits. 20 bits times 2 is 40 bits every millisecond, and then multiply that by 1000 for the number of bits per second, and it's 40kbits. That's doable, but we need some overhead and some time in between messages to respond and process, so at least double and probably triple it, find the nearest baud rate and you've probably got 115.2Kbits. Still doable.

Of course every subsystem still has to have a crystal to support serial communication, you use up a serial port, and generally I just don't like this solution too much. Too kludgy, too imprecise, too wasteful. So naturally I'm about to propose a more wasteful but not kludgy and imprecise method (and it will be somewhat more robust).

My method involves a unit that is the timekeeper unit. It has a very accurate crystal and RTC. It will be especially protected from temperature variations. It keeps accurate time and generates a clock signal of say 100KHz. It will be a square wave, probably made differential or somesuch to improve transmission characteristics. Each subsystem will use this signal as the clock into a timer which it will use to keep track of the current timestamp. The timekeeper will have a control line with a pullup that the timekeeper holds low. Each subsystem monitors this line and keep count with the clock signal as long as it's low. Each subsystem is also tied to an open-collector ACK line. Whenever they lose the clock signal they pull it low and the timekeeper signals a fault or does something to correct the situation. If the timekeeper goes away then the control line will go high and let all of the subsystems know. At this point the subsystems go independent: they've been measuring the clock signal with respect to their own internal clocks and can keep fairly accurate time now without the timekeeper (for a while anyhow). When the timekeeper comes back it sends a special signal on the control line and the subsystems know to reset their timestamps to 0 and pick the clock signal up again.

Is this a great system? No. It only works in specific situations - if you have multiple subsystems in a control system that are all actively involved in the process of creating a control signal, you need to know absolute time and not just absolute time differences, and all of the subsystems are far removed enough from each other to make this worthwhile (probably not on the same PCB). Otherwise this could be a cute four-wire timekeeping system.

No comments: