solarwind wrote: > I'm trying to design a multi master protocol for RS485 networks Why RS485? That's so 1990s. Unless that is something specific to the requirements (and it doesn't sound that way since you seem to be free to design the protocol), you should seriously look at CAN. CAN hardware is now readily available in a variety of microcontrollers (18F4580 just to name one). All nodes on a CAN bus are equal, and the collision detection and resolution is handled in the hardware transparently to the firmware. In other words, multi-master just works, whereas it's not trivial to do with RS-485. > The MCU will have an ISR as follows, which will be called every time a > byte is received: > > ISR() { > if buffer not full > push byte into a FIFO buffer > start(processing_thread) > } Why start the receiving thread in the ISR? That sounds more complicated than necessary. The logic above is also imcomplete because you don't check for and handle the case of the thread still running from last time. And then how can a thread reasonable handle a communication protocol if it is run separately for each byte? This makes no sense. All the interrupt routine should do, if you use interrupts at all, is to get the data and leave it lying around someplace the receiving thread can find it, usually in a FIFO is the data is just a byte stream. The receiving thread runs all the time, but the call to get the next byte blocks until one is available. Now the receiving thread can do a computed GOTO on the opcode byte and run a separate routine per command. These command routines can get parameter bytes as appropriate and don't jump back to the start of the main command loop until their command has been processed. This is essentially using a state machine to processes a state-dependent input stream, with the PC being the state variable. I find that sort of architecture works well for handling asynchronous input streams. > I would imagine that using an interrupt (rather than consistently > polling for data) is far more efficient. Probably not, but efficiency isn't the issue. Once you buy into the separate receiving thread concept with blocking GET calls, those GET calls can just as well check a hardware flag to see if there is new data than to check the software flag that says there is at least one byte in the FIFO. Things look the same to the receiving thread. Note that while the GET call appears to block to the receiving thread, "blocking" in this context really means checking for new data in a tight look that calls TASK_YIELD whenever it doesn't find data. This is how threads "block" in a cooperative multi-tasking system. I have done this sort of thing many times with PICs, and found it to work well and the input processing to fall out rather naturally. The issue with using interrupts for each piece of input data versus polling the hardware by the receiving thread is not one of efficiency but of responsiveness to the hardware. Depending on what the system is doing, there might be too much time between successive invocations of the receiving thread such that the UART (or whatever your input hardware is) gets overrun. Interrupt receiving followed by a FIFO is a bit more complicated and therefore slightly less efficient, but allows averaging the processing power over multiple input bytes to be applied to the stream. Usually the problem with the input overrunning the receiving thread is one of latency and burstiness, not of overall cycles. If you don't have enough cycles long term, you're screwed anyway. The FIFO allows you to go to lunch for several characters at a time, then catch up by draining a whole bunch of characters from the FIFO in a burst later. Unless you are using a slow baud rate and know exactly what's going on in the CPU, I would go with a interrupt driven input FIFO. Often just 8 bytes is enough to smooth out the burstiness of the thread scheduling, but of course you'll have to do your own math to determine what you need. For example, if you think a thread may be held off for as long as 1mS (quite a long time actually) and input is via UART at 115.2Kbaud, then the FIFO needs to be at least 12 bytes. In that case 16 sounds like a nice round number. 16 bytes plus maybe another 2 for FIFO control isn't a big deal on most PICs. If you are using CAN, you may well want to use the polled approach. CAN data comes in larger chunks called frames. These frames have some header information plus 0-8 data bytes. The receiving thread waits for the next whole frame to be received, processes it, then goes back to get the next frame. You could set up a FIFO of CAN frames, but so far I have not done this in my CAN implementations. ******************************************************************** Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products (978) 742-9014. Gold level PIC consultants since 2000. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist