In last month’s newsletter I talked about analyzing the size of buffers. Now I will discuss the importance of proper management support for buffers – support in terms of status, interrupts, and errors.
For example, when should an interrupt be generated on the receiving buffer? When one byte arrives? When the buffer is half full? Or when it is completely full? The answer could be yes to all three. The required support for the buffer depends on its application. Here are a few suggested support features:
Status and Control |
Read the current level of the buffer. |
---|---|
Set the size of the buffer. | |
Reset the buffer, pointers, and counters. | |
Interrupts | Receive buffer is not empty, half full, almost full, etc. |
Transmit buffer is half empty, almost empty, empty, etc. | |
The specified data has arrived. | |
A specified time period has expired since last data arrived. | |
An error has occurred. | |
Errors | Transmission errors causing the buffer to stall. |
Buffer overflow or underflow. | |
A buffer overflow caused the newest (or oldest) data to be dropped. | |
Test and Debug |
Read the current positions of the buffer beginning and end pointers. |
Inspect the whole buffer, even the empty positions, without altering the buffer contents or level. | |
Read the current state of state machines and/or handshaking signals. |
As you design buffers for your application, you may think of other factors to consider.
The more methods you can provide for buffer management, the more ways firmware engineers have to use and manage the buffer. The more methods you can provide for buffer management, the more ways firmware engineers have to use and manage the buffer. For example:
Once I worked on a drivers for a CAN I/O block used for communication between a laser printer and its external paper handling devices. The block was generous in its support and flexibility on how to manage CAN traffic. We set it up so our transmission buffer was handled different from our receive buffer. For transmission, the driver simply wrote the next CAN packet to registers in the block and waited for the transmission-done interrupt before writing the next.
Since we did not want to lose incoming packets, we allocated a buffer in memory, for the CAN block to send the packets there using a DMA. In a typical busy-system condition, two or three packets could arrive before the driver could respond. So the external buffer helps. There are several receive interrupts available, such as every packet, half full, a specified threshold level, full, etc. After some experimentation, we determined that the best one for our application was to use the interrupt that fires for every packet that arrives so the driver (and system) can respond in a timely manner.
Last month and this month, I provided guidelines for enhancing and customizing buffers on I/O blocks. However, if you are using an I/O block that is based on a standard, it is much better to keep it standard. Enhancing it with non-standard sizes, interrupts, and controls would require you to write your own test suites and drivers (which is very prone to introducing defects) instead of using off-the-shelf components.
Until the next buffered issue…