Você está na página 1de 35

Hardware Interface Design Patterns

Ahmet Selman Bozkr 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 well 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 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:
Serial Port is implemented with the SerialPort and Messages received on the serial
SerialPortManager classes. The SerialPortManager link are stored in this queue.
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 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 long m_status_Register;


const long m_action_Register;
const long m_transmit_Register;
const long 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. 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.
2. As a soon as a first sync pattern is detected, the system transitions to the
"Confirming Sync Pattern" state.
3. Now the system checks if the sync pattern is repeating as expected. This
check is made according to the specified periodicity.
4. 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)
5. 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!

Você também pode gostar