410 likes | 528 Views
Design & Implementation of Telecommunication Protocols. Design of State Machines. In a proper state machine design you should be able to identify from the code one to one equivalents to the following FSM components. Events States The current state Event handler functions for each state.
E N D
Design of State Machines • In a proper state machine design you should be able to identify from the code one to one equivalents to the following FSM components. • Events • States • The current state • Event handler functions for each state
Implementation in C/C++ using case statements • One way to implement FSM in a structured language like “C” is to use nested case statements • Switch on state first then switch on event type • Better way is to create a State Jump Table which will contain array of states, events and pointers to functions to be called in each states. • Then common FSM code will when event is raised search to the table to find a function that has to be called depending on the current state
Example: Telephone and user We will use an example a simple telephone handset and user Model of the telephone: • rings when a call comes in, • provides dial tone, • provides engaged signal when a number is engaged
Model of User The user: • Will either be near the phone or away from it. • If the phone rings when the user is near he will answer it, otherwise the ring will be ignored • When the user wants to make a call, he will lift the handset, wait for dial tone and dial the number
Example: Telephone Process States • Process Telephone has the following States: • NoCall Call is not in progress • Ringing Incoming call attempt • Active Call is in progress
Signal Ring, Dialtone, Engaged, LiftHandset, ReplaceHandset, DialNumber(PhoneNumber); Example Block Diagram block phone [Ring, Dialtone, Engaged] [Setup, Disconnect, Connect] G1 G2 Telephone PhoneUser G3 G4 [Setup, Alerting, NoAnswer, Disconnect, Connect] [LiftHandset, ReplaceHandset, DialNumber]
PROCESS Telephone PAGE 2( 2) TIMER AnswerTimer; Ringing Example SDL Diagrams PROCESS Telephone PAGE 1( 2) NoCall Setup LiftHandset AnswerTimer SET(3mins, AnswerTimer) RESET (AnswerTimer) NoAnswer Ring Connect NoCall Alert Active Ringing
C implementation of FSMs • Extract the message from input device. • Find what transition function has to be called based on the current state and input type • In transition function perform required tasks, message output etc in the transition function • Change the state if required • Events such as Timer expiries which don’t map to messages should be modelled using the same structure as messages
C implementation of FSMs • Create enumerations for states and events. enum MessageType { Setup, Ring, Alert, ... }; etc. • Create a structure to represent the event. struct Message { enum MessageType message_type; char contents[MSGLEN]; }; • Create a structure to represent the FSM struct FSM { enum State current_state; /* There would also normally be such things as counters call reference Ids etc. related to this particular FSM stored here. */ };
Example of State Jump Table (Not Very Good) void process_event(struct FSM* fsm, struct Message* in_mess){ switch(fsm->current_state) { case NoCall : switch(in_mess->message_type) { case Setup: fsm.current_state = proc_Setup_in_NoCall(in_mess,fsm); } case Ringing : switch(in_mess->mess_type) { ... ...
Example of C++ SJT //The Memeber Pointer Macro (ACTION). This macro is used to make the jump table more readable #define ACTION(mfn) new MbrFn<PSTNProtocolFSM>(&PSTNProtocolFSM::mfn) EventTableEntry PSTNProtocolFSM::_PSTNjumpTable[] = { // == STATE AN0 {AN0_OUT_OF_SERVICE, DL_STATUS_ENQUIRY, ACTION(sendStatus)}, {AN0_OUT_OF_SERVICE, DL_PROTOCOL_PARAMETER, ACTION(sendStatus)}, {AN0_OUT_OF_SERVICE, DL_DISCONNECT_COMPLETE, ACTION(AN0DisconnectComplete)}, {AN0_OUT_OF_SERVICE, DL_ESTABLISH, ACTION(sendStatus)}, {AN0_OUT_OF_SERVICE, DL_ESTABLISH_ACK, ACTION(sendStatus)}, // == STATE AN1 {AN1_NULL, DL_ESTABLISH, ACTION(AN1Establish)}, {AN1_NULL, DL_ESTABLISH_ACK, ACTION(sendStatus)}, {AN1_NULL, DL_PROTOCOL_PARAMETER, ACTION(sendStatus)}, {AN1_NULL, DL_DISCONNECT_COMPLETE, ACTION(doNothing)}, // error condition {ANY_STATE, ANY_EVENT, ACTION(jumpTableError)}, // Clean up {END_OF_STATE_EVENT_TABLE, 0, 0} };
Transition Functions • Transition Functions shall be kept outside of transition table function as may be common to other transitions enum State proc_Setup_in_NoCall(struct Message* in_mess,struct FSM* fsm) { struct Message outmess; /* OUTPUT Ring */ outmess.message_type = Ring; output_message(&outmess); return Ringing; } • Always consider the default and error transition functions.
Message/Event Processing • Main loop includes the following while(get_input(&in_mess) != EOF) { process_event(&telephone, &in_mess) ; } • This approach is truly state based, and can be automatically generated from SDL.
Bad Implementation of FSM • The following C code is not acceptable; send_setup(); wait_for_alert(); wait_for_noanswer(); • Does not implement a FSM it only implements one scenario. • Suitable for test stubs however, to automate testing of code.
Event Driven Programming There are two ways to write code that responds to events • Event driven programming • Polling
Polling • Polling is when you sit in an endless loop, constantly checking an input queue • For example: void EventDispatcher::loop() { while(1) { pause(10MS); // Pause the thread 10 milliseconds Event* event = getevent(); if(event) { process_event(event); } } }
Disadvantages of Polling • Task has to pause between polls to allow time for other tasks to be scheduled in • Response time - between event occurring and action being performed depends on duration of the pause • If fast response time is required this method consumes significant processor time (power) • Polling should be avoided in most cases. Instead of polling an event driven (for example interrupt driven) approach should be used.
Valid excuses for using Polling • Operating System limitations • Hardware limitations - no interrupts available • Writing low level device drivers and hardware interrupts are not available
Event Driven Programming • The alternative is to use a blocking routines that waits for one of several events you have signified • The way in which this is done and the API to do this is operating system specific • We will consider the case of Unix which is a very common OS for telecommunications applications.
What is an Event ? • An event is anything that needs the attention of the system. • Real Time (or Embedded) Systems exist to service events • When an event occurs in the real world, an embedded system must recognize the event and take some action in a timely fashion. • Embedded systems are often called "event-driven" systems.
Is a signal the same thing as an event? • The words event, interrupt, signal, and exception all refer to the same thing: something important happened and we have to take care of it. • UNIX software signal is the same thing as a Motorola 68040 hardware interrupt: something happened "out there" and our system needs to respond to that time-critical event.
How do Interrupts Get Generated and Serviced? • Microprocessors have a special input pin or pins which are used by external hardware to signal the microprocessor that some external event needs attention. These are the interrupt pins. • For example: when a message arrives on a network device such as an Ethernet chip, it applies a signal to an interrupt pin on the microprocessor to interrupt whatever software is currently running. • The microprocessor then saves whatever program thread was running and vectors to the interrupt handler which is associated with the interrupt. • The Ethernet interrupt service routine (ISR) runs to completion, doing whatever work needs to be done to take care of the arrival of the packet from the network. • When the ISR is finished, the control returns to the program thread.
Typical Interrupts • External (pin) Interrupts • Timer Interrupts • SW Interrupts • Power Down (Dying Gasp) Interrupt • Processor Exception Interrupt
Multiprocessing Concepts • Synonyms: process, task, job, thread • Process consist of • a program • a “private” data area • a private thread of execution • Operating System manage multiple threads of execution at the same time by sharing the processor time between them • FSMs can be implemented • in same process • separate processes on same CPU • different CPUs
Why to Use Multiple Processes • Breaking a large job into smaller tasks and then performing the tasks one by one is a technique we all use to manage complexity • This has several advantages: • Small tasks are easier to code, debug, and fix than is monolithic software. • Interface between tasks is limited to pre-defined set of methods thus minimizing hidden dependencies between functions. • The uniformity provided of the interfaces is especially important if tasks are created by different programmers. • A preemptive multitasking OS allows tasks handling urgent events to interrupt less urgent tasks. (Such as when the phone rings while you are reading.) • New features can easily be added by adding new tasks
Multiple Processes Example • Suppose we need to control an engine using several measured parameters and a complex control algorithm. Also, assume there is an operator interface which displays information and allows operator control and assume that the system must communicate with a remote host computer. • It is natural to implement the application using multiple tasks: • Operator Interface (Low Priority Task) • Engine Control (High Priority Task) • Host Computer Interface (Medium Priority Task)
Context Switching • Context of the task consist from • values of all processor registers (including PC) • stack • task related variables • When OS has to stop one task and start another it: • saves complete context of the currently running task into private data area • restores context of the task to be started • hands the thread of execution to new task • Reasons for Context Switch • Task gives up the processor voluntarily • It is forced out by task of higher priority • In round robin scheme tasks of equal priority can be switched
Context Switching • Two mechanisms for the OS to gain the control from executing thread: Preemption and Cooperation • In case of preemption context switch is triggered by hardware event/interrupt like: reception of character from modem, completion of disc operation or clock interrupt • In case of cooperation each running thread voluntarily leaves control of the computer as soon as possible
Task Priority • The priority of the task determines whether it should have precedence over other task • High priority tasks usually • require little processing time to run • cannot tolerate long delays • are close to hardware (low layers) • Low priority tasks usually • take longer time to execute • there is no impacts if they are delayed • Tasks may have same priority and they are then usually served in round robin fashion • Some OS allow task priorities to be modified dynamically (in Run Time)
Multiprocessing Models • Heavyweight Processes with separate data segments • Execute in data segments which are kept isolated from each other by memory protection hardware • Communication between processes requires explicit use of OS facilities for inter-process communications (IPC) • Advantage of isolation is independence of other processes from malfunction of one process • Disadvantage is difficulty in sharing common data and lot of context switching (which may be expensive in regards to time)
Multiprocessing Models • Lightweight Processes within a data segment • They share data segment with other lightweight processes • Advantage is efficient use of memory and fast context switch • Disadvantage is reduced reliability and if there is no pre-emption one process can “steal” the processor • Reentrancy problem occurs when same global variable is use by more then one process
Inter Process Communication (IPC) • Common OS Resources • Disk Files • Pipes: they look like files but are in fact FIFO queues which allow two processes to communicate • Sockets: similar to pipes, but processes may be on different machines of the same network • Shared Memory • Semaphores: prevent simultaneous access to the memory area by more then one lightweight process • Shared Memory Segments: chunk of memory mapped to virtual address space which allows access to more then one heavyweight process • Messages & Mailboxes • Mailbox is a FIFO queue in which sending tasks places the messages. Receiving task may wait on the mailbox if there are no messages or it can just check a mailbox end continue execution
Inter Process Coordination • Execution between processes can be coordinated by • Event Flags • One process is waiting for the “event flag” which can be set by any other process • Counting Semaphores • One process waits for semaphore which may signalled by other task. If wait is called n times then signal has to be sent n times. • Mailboxes • If there are no messages in mailbox queue the process execution may be suspended until new message is received
Memory Allocation • Static Memory Allocation • Memory allocated for objects during compilation or boot-time (static objects) • Faster then dynamic allocation • Total required memory size is sum of all size required for all static objects (though they may not be used at same time) • Dynamic Memory Allocation • Memory allocated on need bases (objects dynamically created and destroyed) • Useful when object are of short life span (not used frequently) • Required memory size smaller • Memory Fragmentation may be a problem (telecomm SW has very long running time) • Slow allocation time required to search for free block to allocate
CPU SW Watch-Dog • Worst thing that can happen to embedded SW is to freeze (lock-up) • because it requires human intervention for recovery • It is better for SW to reset in case of failure then to freeze • To prevent lock-ups most CPU provide SW Watch Dog timers • counters counting down from pre-set value • when they come to zero whole CPU is reset • Application SW has periodically to re-initialise counters to prevent reset (to kick the watch-dog)
House Keeping Task • In case of multi-task FW one task can lock, while other are happily running • If this task doesn’t have responsibility for kicking the watch-dog this will not cause CPU reset • Solution to this problem is to have House Keeping task responsible for kicking the watch-dog also pooling other tasks to see if they are alive • House Keeping task can also keep an eye on available Heap space, Memory pools, Stack over/under-flows … • In case of any detected problems House Keeping Task will stop kicking the Watch Dog and CPU (Unit) will reset
Inter Layer Communication • All OSI and ITU protocols are layered protocols • In OSI the communication between layers is modelled as primitives • Primitives are like messages in that they are input events to state machines • When a message is extracted from an input buffer and passed through code, the message shouldn’t be copied as this is resource intensive. Instead references to the message should be passed.