Hardware Interface Design Patterns

Download Report

Transcript Hardware Interface Design Patterns

Hardware Interface Design Patterns
Ahmet Selman Bozkır – Hacettepe Univ.
Subjects
•
•
•
•
Serial Port Design Pattern
High Speed Serial Port Design Pattern
Hardware Device Design Pattern
Synchronizer Design Pattern
Serial Port Design Pattern
• Embedded software has to interact with
hardware devices of various types. In this
article we will consider a design pattern for
handling hardware interfaces for a serial port.
• HDLC, RS-232, RS-422
Serial Port Design Pattern
Intent
The Serial Port design pattern defines a generic
interface with a serial port device. The main intention
here is to completely encapsulate the interface with
the serial port hardware device.
All classes interfacing with the serial port will not be
impacted by change in the hardware device.
Serial Port Design Pattern
What we’ll get?
To minimize dependency on hardware.
Because; changing the interface due to:
• Cost
• End-of-life functionality
• Improvements
Serial Port Design Pattern
Serial port design pattern encapsulates the
register and interrupt handling specific to a
device. Change in the device will just result in
changes to just the classes involved in
implementing this design pattern.
Serial Port Design Pattern
Applicability
This pattern is applicable to all serial devices that
involve direct byte transfers to and from the device
using program instructions.
In such devices, serial transmission is implemented by
the device interrupting the processor for data bytes.
When data is received on the serial link, the device
interrupts the processor to transfer data.
Serial Port Design Pattern
Serial Port is implemented with the SerialPort and
SerialPortManager classes. The SerialPortManager
maintains an array of SerialPort objects. Each SerialPort
object manages the transmit and receive buffers. The
SerialPortManager class also implements the interrupt
service routine.
Serial Port Manager:
Manages all the Serial Ports on
the board.
Interrupt Service Routine:
Implemented as a static method
in Serial Port Manager.
Serial Port:
Handles the interface with a
single serial port device.
Transmit Queue:
This queue contains messages
awaiting transmission on the
serial port.
Receive Queue:
Messages received on the serial
link are stored in this queue.
Serial Port Design Pattern
Known Uses
This pattern can be used to implement serial
interfaces where data handling is handled in
interrupt service routines. It is not suitable for
direct memory access (DMA) based serial
devices.
DMA based High Speed Serial Port Design
Pattern
High Speed Serial Port Design Pattern
Embedded processors now-a-days are connected with
each other via high speed serial links. There links can
range from 1 Mbps to 1000 Mbps.
At these high link speeds, the byte by byte transfers
described in the serial port design pattern prove
inadequate.
High speed transfers require devices that can directly
transfer data to and from memory without interrupting
the processor.
High Speed Serial Port Design Pattern
This design pattern covers interfacing techniques with
high speed serial communication devices. The main
objective is to encapsulate the interface with the
device and provide a hardware independent interface
to the high speed serial port.
High speed serial port design pattern encapsulates
DMA configuration, register interfacing and interrupt
handling specific to a device. Change in the device will
just result in changes to just the classes involved in
implementing this design pattern.
High Speed Serial Port Design Pattern
Applicability
This pattern is applicable to all serial devices that
involve DMA (direct memory access) transfers to and
from the device.
In such devices serial transmission and reception are
completely handled by the serial device. The device
operates as a bus master and transfers data to and
from the memory without main processor intervention.
High Speed Serial Port Design Pattern
Structure
• Serial Port is implemented with the SerialPort and SerialPortManager
classes. The SerialPortManager maintains an array of SerialPort objects.
Each SerialPort object manages the transmit and receive buffers. The
SerialPortManager class also implements the interrupt service routine.
• As mentioned earlier, the serial port is intelligent. The device needs to be
programmed with the addresses of the transmit and receive message
queues. Once these addresses have been programmed, the device
automatically reads the buffer header to determine the current state of the
buffer. For example, when the device finishes transmission of a buffer, it
reads the buffer header for the next buffer to determine there is a new
message ready for transmission. If a new message is found, the device
initiates transmission immediately, without involving the processor.
High Speed Serial Port Design Pattern
High Speed Serial Port Design Pattern
• So what?
This pattern is used to design serial port
interfaces with intelligent devices which are
capable of performing DMA operations to
manage buffers in the memory. These devices
only interrupt the processor when complete
messages have been received/transmitted.
Hardware Device Design Pattern
Hardware Device Design Pattern
• We have already looked at classes that provide
a high level interface to the underlying
hardware (e.g. Serial Port).
• Here we will look at the design of classes
corresponding to the individual devices. The
main objective is to keep all register
programming information at one place.
Hardware Device Design Pattern
Aim:
• Very often the lowest level of code that interfaces with the hardware is
difficult to understand and maintain. One of the main reasons for this is the
idiosyncrasies of register level programming model of hardware
devices. Very often devices require registers to be accessed in a certain
sequence. Defining a class to represent the device can go a long way in
simplifying the code by decoupling the low level code and register
manipulation.
• Another motivation for this design pattern is skill sets. Often details about
intricacies of register programming in devices are understood only by the
persons familiar with the hardware design. Many times other low level code
might be written by software engineers with just basic understanding of
hardware.
• Also note that separating the device programming and logic simplifies
porting of the code to a different hardware platform.
Hardware Device Design Pattern
Structure:
• The structure of class in this design pattern
largely depends upon the register programming
model of the device being programmed. In most
cases, this design pattern would be
implemented as a single class representing the
device. In case of complex devices, the device
might be modeled as a main device class and
other subclasses modeling different parts of the
device.
Hardware Device Design Pattern
Sample Implementation:
•
Status Register (STAT): This read only register contains the following status bits:
•
•
•
•
Bit 0: Transmit Buffer Has Empty Space
Bit 1: Receive Buffer Has Data
Bit 2: Transmit under run
Bit 3: Receive overrun
•
Action Register (ACT): Bits in this write only register correspond to the bits in the
status register. A condition in the status register can be cleared by writing the
corresponding bit as 1. Note that bit 0 automatically gets cleared when writes are
performed to the transmit buffer. Bit 1 is cleared automatically when reads are
performed from the receive buffer. Bit 2 and 3 however need to be cleared explicitly.
•
Transmit Buffer (TXBUF): Write only buffer in which bytes meant for transmission
should be written.
Receive Buffer (RXBUF): Read only buffer in which received bytes are stored.
•
Hardware Device Design Pattern
• class Serial_Device
{
enum Register_Offsets {
STAT_REG_OFFSET = 0, ACT_REG_OFFSET = 0,
TXBUF_OFFSET = 1, RXBUF_OFFSET = 2
};
enum Status_Register_Bits {
TX_EMPTY, RX_DATA, TX_UNDERRUN, RX_OVERRUN
};
const
const
const
const
long
long
long
long
m_status_Register;
m_action_Register;
m_transmit_Register;
m_receive_Register;
public: Serial_Device(long baseAddress) :
m_status_Register(baseAddress + STAT_REG_OFFSET),
m_action_Register(baseAddress + ACT_REG_OFFSET),
m_transmit_Register(baseAddress + TXBUF_OFFSET),
m_receive_Register(baseAddress + RXBUF_OFFSET) { }
Hardware Device Design Pattern
bool Transmitter_Has_Space() const { return
((io_read(m_status_Register) & TX_EMPTY) == TX_EMPTY); }
// This method returns true if a receive interrupt is pending
bool Receiver_Has_Data() const { return
((io_read(m_status_Register) & RX_DATA) == RX_DATA); }
// Returns true if transmit error interrupt is active
bool Transmitter_Has_Error() const { return
((io_read(m_status_Register) & TX_UNDERRUN) == TX_UNDERRUN); }
// Returns true if receive error interrupt is active
bool Receiver_Has_Error() const { return
((io_read(m_status_Register) & RX_OVERRUN) == RX_OVERRUN); }
// Clear all the error conditions
void Clear_Errors() const { io_write(m_action_Register,
TX_UNDERRUN | TX_OVERRUN); }
Synchronizer Design Pattern
Synchronizer Design Pattern
Aim:
• Many systems used in digital communication send data in synchronous
back-to-back frames. When a receiver tunes to such a data stream, it has no
knowledge of the frame boundaries. The Synchronizer Design Pattern is
used to look at the raw incoming bit or byte stream and detect and align to
the frame structure. The frame structure is detected by searching for a sync
pattern in the frame.
• Once the synchronization is achieved, the Synchronizer confirms the
presence of the sync pattern in every frame. If the sync pattern in missed a
certain number of times, loss of sync is declared.
Synchronizer Design Pattern
• On many occasions there is need to maintain
synchronization between two entities connected
at opposite ends of a link. This design pattern
provides mechanisms for:
• Achieving initial synchronization (sync)
• Once sync is achieved, confirming the presence of the sync framing
• Initiating loss of sync procedures
Synchronizer state machine class is the key
participant in this pattern. The state machine
uses state classes to keep track of state.
Synchronizer Design Pattern
•
It is clear from the figure below that the state machine is organized into two high-level
states, synchronized and unsynchronized. These states act as the base class for the
following sub-states:
Synchronizer Design Pattern
The implementation is explained in terms of
the following scenarios:
• Attaining Synchronization
• Loosing Synchronization
Synchronizer Design Pattern
Attaining Synchronization
1.
2.
3.
4.
5.
System starts up in "Searching For Sync" state. In this state, the incoming
data stream is being analyzed bit by bit, looking for the occurrence of the
sync pattern.
As a soon as a first sync pattern is detected, the system transitions to the
"Confirming Sync Pattern" state.
Now the system checks if the sync pattern is repeating as expected. This
check is made according to the specified periodicity.
If the sync pattern is repeating, the system transitions to the "In Sync"
state. (If the sync pattern was not found, the system would have
transitioned back to the "Searching For Sync" state)
At this point, the system is considered to be synchronized.
Loosing Synchronization
1. When the system is synchronized, it is in the "In Sync" state. In this state,
the system is constantly monitoring the periodic occurrence of the sync
pattern.
2. If an expected sync pattern is found to be missing, the system transitions to
the "Confirming Sync Loss". The system is still in a synchronized state. The
main purpose of the "Confirming Sync Loss" state is to check if the loss of
sync was an isolated event or it represents complete loss of sync.
3. In the "Confirming Sync Loss" state, the system looks for the sync pattern
at the expected time interval. If the sync pattern is seen again, the system
transitions back to the "In Sync" state.
4. In this case, the sync pattern is not detected for a preconfigured number of
times.
5. The system is now in sync loss state. The system is transitioned to the
"Searching For Sync" state.
Synchronizer Design Pattern
Synchronizer Design Pattern
So what?
Use of this pattern has the following benefits:
• Provides a common framework for implementing
synchronization logic
• Use of hierarchical state machine reduces the amount of
code by reducing code duplication in various states.
• Use of a state machine forces the developer to handle all
possible cases of synchronization events.
Resources
• http://www.eventhelix.com/RealtimeMantra/Patterns/
• Visio 2003
• Thanks for listening me!