Does anyone know what or where in the code that ser8250 will output the transmit buffer and deal with the transmitting interrupts?
Has anyone came into an issue when using a 4 port serial board with shared interrupts that the devc-ser8250 will not get all receive buffers from the board if there happens to be two or more receive buffers with data on one fired interrupt?
I’m not quite sure what you are asking here, but I’ll try. The ser8250 code does not output the transmit buffer. It merely loads it. It is the hardware’s job to transmit the data. In non-buffered mode, the transmit-interrupt fires when it is ok to load another byte into the transmit buffer. I forget exactly when this occurs, but I think it is actually before the entire serial packet is sent. It doesn’t really matter, all the programmer needs to know is that when the interrupt fires the transmit buffer empty bit is turned on, and you can safely load another byte. In buffered mode, things are a little more complicated. You can adjust when the interrupt fires. The interrupt can indicate that the FIFO buffer isn’t empty, but merely that it has room for more bytes. The driver should just fill as many bytes as there is room for, or that the driver has to send. There are some synchronization issues I recall as it is hard for a application to know exactly when all serial data is flushed. This enhances throughput over latency. You can set the interrupt to fire just as in non-buffered mode, when the FIFO is completely empty.
Interrupts have no attached properties, so when an interrupt occurs there may be no immediate way for a driver to know what it means. In the case of an 8250, the driver reads a register that indicates what interrupt conditions have occured. This register nicely works even if the hardware interrupt is detached and you are running in a polled mode. When there are multiple serial ports on the board sharing an interrrupt, the driver has to check each serial chip on every interrupt. If there are multiple devices on the interrupt, then multiple interrupt handlers must be called and each driver cannot assume that the interrupt was caused by its own hardware.
A related problem has to do with interrupt events occuring while an interrupt handler is active. While the interrupt handler is active, either all interrupts are turned off or that particular interrupt (and probably lower priority ones) is/are masked. So the interrupt handler will not be interrupt by its own interrupt. This requires some carefully thought out coding. If an interrupt handler finds a condition it must handle, and then does a general reset without checking the hardware carefully, it might leave another condition set, but not handled. This is less of a problem with level triggered interrupts than edge triggered ones, as a level triggered interrupt will re-trigger.
I’ve never heard of a problem related to two or more receive buffers with data on one fired interrupt. Such a problem would probably be a software bug. It is possible to read most of the 8250’s registers non-destructively from a separate process, so you could monitor things and try to diagnose a problem when it occurs.
If all else fails, you could hire a QNX driver expert to find your problem. There are at least two or three out there who monitor this website.
I have never encountered this.
You can debug this easily with the System Profiler. Just add a single user trace (see: TraceEvent) in the interrupt handler for devc-ser8250 where it reads the uart into the buffer (the TraceEvent will take 2 integer args, so output the port address and what is read). Have a simple program open all four ports and look for a known data pattern on each, when it notices a missing character from the pattern on any port, have it also output a user TraceEvent.
Start the instrumented driver with the FIFO disabled, then blast all four ports with a known data pattern at 115200, while capturing a trace (see: tracelogger).
Once you have the trace, load the .kev file into the System Profiler, and you’ll be able to see clearly what the problem is…