1. Real-time Systems Development
                         Dr Rob Williams



                                             ...
18/6/09                                                                  2




                • Specified limit on system ...
18/6/09                                                                                 3

1 ms, a millisecond, one thousa...
18/6/09                                                                         4

               Desired
                ...
18/6/09                                         5




                Fig. 1.5h Uncertainty


                            ...
18/6/09                                                           6



                                   •SEQ
           ...
18/6/09                                                                                          7

                      ...
18/6/09                                                        8


            V
                 v2f




      loop for 1...
18/6/09                                                                                                                   ...
18/6/09                                                               10



                      • Dedicated and Periodic...
18/6/09                                                  11




                                         ?
               ...
18/6/09                                                                         12

             2. Implementing a Simple ...
18/6/09                                                              13




                                       Brr Brr...
18/6/09                                                                   14




                 • Disable task switching...
18/6/09                                                                       15




/* Outputs slow binary count to print...
18/6/09                                                                                            16
                   S...
18/6/09                                                 17



             Stator Coil Excitation Sequence
               ...
18/6/09                                                            18




                                 1. Bodge
      ...
18/6/09                                                          19

/* Example driver routine for a dual, two phase stepp...
18/6/09                                                                                       20

                   3. Ba...
18/6/09                                                               21




                       Addr1        Addr2    ...
18/6/09                                                                                                                   ...
18/6/09                                                          23

                Port address   Function
             ...
18/6/09                                                                                                24



          D7 ...
18/6/09                                                    25




                                              Dedicated
...
18/6/09                                                                       26

/* duckshoot.c,
 * demo of parallel port...
18/6/09                                                27

      if (direction)                 // rotate flock
          ...
18/6/09                                                           28

   /* Example of Linux tcsetattr( ) function to disa...
18/6/09                                                         29


                                         Interrupt
  ...
18/6/09                                                                                  30



                           ...
18/6/09                                                                              31



                        • Devic...
18/6/09                                                                                               32


               ...
18/6/09                                                                       33
                                         ...
18/6/09                                                                       34



                         • I/O data tr...
18/6/09                                                                   35




                            • disable int...
18/6/09                                                                                   36




                         ...
18/6/09                                                                                   37



                          ...
18/6/09                                                                      38



                                       ...
18/6/09                                                                                   39

     4. Cyclic Executives on...
18/6/09                                                                                  40



                           ...
18/6/09                                                                  41

                                             ...
18/6/09                                                                       42

/* Demo table-based cyclic task dispatch...
18/6/09                                                                                43




           Fig. 4.8b Optical...
18/6/09                                                             44

/* Keypad (16 switches) scanner and 7-seg digit LE...
18/6/09                                                                        45

BYTE colscan(void) {
  int i;
  BYTE kn...
18/6/09                                                                   46

          5. Finite State machines - design ...
18/6/09                                                                           47

                                    ...
18/6/09                                                                                           48



                  ...
18/6/09                                                                                                 49

              ...
18/6/09                                                                                     50

kettle weight sensor.
Tea ...
18/6/09                                                           51


            Filling
          Open valve



       ...
18/6/09                                                                             52



      NEXT                      ...
18/6/09                                                                   53

          6. Finite state machines - impleme...
18/6/09                                                         54

                                  Init




           ...
18/6/09                                                                   55

/* toaster1.c, direct sequential coding of F...
18/6/09                                                                    56

/* toaster2.c, a keyboard/screen simulation...
18/6/09                                                  57
main() {
      state = 0;
      printf("nn");
      initscr();...
18/6/09                                                                                                             58


 ...
18/6/09                                                                    59

/* toaster3.c, a keyboard/screen simulation...
18/6/09                                                            60

main() {
struct tms n;
      initscr();
      cbrea...
18/6/09                                                     61




                           states
                     ...
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Real-time Systems Design (part I)
Upcoming SlideShare
Loading in …5
×

Real-time Systems Design (part I)

2,740 views

Published on

The slides for the first half of my final year BSc module in Real-time Systems Design. Based on RTSDev 2006 Elsevier.

Published in: Technology
1 Comment
2 Likes
Statistics
Notes
  • rob williams
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
2,740
On SlideShare
0
From Embeds
0
Number of Embeds
93
Actions
Shares
0
Downloads
211
Comments
1
Likes
2
Embeds 0
No embeds

No notes for slide

Real-time Systems Design (part I)

  1. 1. 1. Real-time Systems Development Dr Rob Williams P 12 : 01 Enter car number first Tariff 1hr 40p Press for Sun free ticket Sat free Coins Fig. 1.2 Real-time Systems can seem like juggling Fig. 1.3 A familiar real-time application Fig. 1.4 Complexity management is essential
  2. 2. 18/6/09 2 • Specified limit on system response latency • Event-driven scheduling • Low-level programming • Software tightly coupled to special hardware • Dedicated specialised function • The computer may be inside a control loop • Volatile variables • Multi-tasking implementation • Run-time scheduling • Unpredictable environment • System intended to run continuously • Life-critical applications Fig. 1.5a Features of real-time systems Now! Fig. 1.5b Response time sensitivity Fig. 1.5c Interrupt preemption start: clr.w iflag *clear down interrupt flag pea bisr * MFPint() move.w #mfpCTS,-(sp) *insert new ISR address into the move.w #13,-(sp) *assumes 16 mfp vectors from $100 trap #XBIOS addq.l #8,sp move.w #mfpCTS,-(sp) *Jenabint() move.w #27,-(sp) *enable the CTS interrupt on the trap #XBIOS addq.l #4,sp Fig. 1.5d Low level programming
  3. 3. 18/6/09 3 1 ms, a millisecond, one thousandth of a second, 10-3 1 µs, a microsecond, one millionth of a second, 10-6 -9 1 ns, a nanosecond, one thousandth of a millionth of a second, 10 1 ps, a picosecond, one millionth of a millionth of a second, 10-12 -15 1 fs, a femtosecond, one thousandth of a millionth of a millionth of a second, 10 1 year 32 nHz year number roll over 6 months 64 nHz GMT < - > BST changeover 8 hrs 30 µHz AGA coal stove cycle time 10 s 0.1 Hz photocopier page printing 1s 1 Hz time-of-day rate 300 ms 3 Hz typing speed 300 ms human reaction time 150 ms 7 Hz mechanical switch bounce time 15 ms 70 Hz motor car engine speed 260 Hz middle C 440 Hz Concer t pitch A 1 ms 1 khz serial line data rate 125 µs 8 khz digitized speech, telephone quality 64 µs 15.6 kHz TV line rate 50 µs Mc68000 interrupt latency 0.5 µs 2 MHz Mc68000 instruction rate 0.074 µs 13.5 MHz video data rate 0.050 µs semiconductor RAM access time 0.01 µs 100 MHz Ethernet data rate 10 ns 100 MHz memor y cycle, PC motherboard 2.5 ns 400 MHz logic gate delay 555 ps 1.8 GHz cellular telephone transmissions 500 ps 2 Gz single instruction issue, Pentium IV 0.3 ps 3 THz infra-red radiation 16 fs 600 THz visible light 10 3 2 ≈ 10 1000, known as 1 Kilo 220 ≈ 106 1000_000, known as 1 Mega 230 ≈ 109 1000_000_000, known as 1 Giga 240 ≈ 1012 1000_000_000_000, known as 1 Tera 50 15 1000_000_000_000_000, known as 1 Peta 2 ≈ 10 260 ≈ 1018 1000_000_000_000_000_000, known as 1 Exa Fig. 1.5x Timing parameters, slow to fast
  4. 4. 18/6/09 4 Desired temp - Heater DAC Oven + Driver ADC Temperature value Signal Condn Fig. 1.5e Specialized hardware, feedback control loops CPU System Bus data volatile I/O Subsystem source data count Main Memory DMA Controller data Fig. 1.5f Volatile variables with a DMA controller T2 T3 T1 T4 Fig. 1.5g Real-time Systems = Deferred Scheduling, or: "Late Sequencing"
  5. 5. 18/6/09 5 Fig. 1.5h Uncertainty BT Fig. 1.5i Non-stop service Fig. 1.5j Life risking applications
  6. 6. 18/6/09 6 •SEQ •IT •SEL •PAR •CRIT Fig. 1.6 Structures in r-t programs Asynchronous Synchronous Unpredictable Scheduled events Processing Fig. 1.7 Rapid response is compromised for processing efficiency Y:2.00V/div X:0.1 ms/div Single A1 STOP Fig. 1.8a Voltage from a key switch showing a contact bounce of nearly 1ms Light beam Fig. 1.8b Mechanical and Optical switches
  7. 7. 18/6/09 7 5v 10 k 0V switch Fig. 1.8c Switch debouncing logic Sampling Pulses missed! Events A B C Fig. 1.8d Sampling too infrequently A B 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Fig. 1.8e Aliasing error through sampling too slowly: only 20 sample points in 12 cycles Y:0.1V/div X:10ms/div Single A1 STOP Fig. 1.8f A light sensor showing 100 Hz mains flicker
  8. 8. 18/6/09 8 V v2f loop for 100 msec { if (input_bit) h_count++; else l_count++; } temp1 = tempX*h_count/(l_count+h_count) loop for 100 msec { if (!input_bit) h_count++; else l_count++; } temp2 = tempX*h_count/(l_count+h_count) Fig. 1.9 Voltage to Frequency Converter 170 ns laser pulse echo returning emerging from 50m Fig. 1.10 Light travels very fast!
  9. 9. 18/6/09 9 Fig. 1.11 Motor drive timing issues Hewlett 546455D Measure Packard Storage Volts Time Curses RunStop Single Auto Erase Trace Setup Horizontal Trigger Edge Auto Display Print Main Pattern Mode Analogl Volts/Div Volts/Div Advanced A1 A2 Digitall Position Position + D0-D15 − A1 A2 ON Fig. 1.12 Oscilloscopes can display timing information for debugging Application Operating Hard- ware System Programs Fig. 1.13 Direct access to hardware
  10. 10. 18/6/09 10 • Dedicated and Periodic polling • Interrupt driven • Direct Memory Access (DMA) Fig. 1.14a Different I/O Techniques User Code HLL librar y O/S Routines HAL Hardware Polling Loop Fig. 1.14b Software access to hardware RxRDY Spin polling do { while (!(INP(STATUS) & RXRDY)) { }; * wait for data * } while (*pch++ = INP(RXDATA)); * NULL ? * MOV EDI,PCH ;init pointer to start of data buffer TLOOP: IN AL,STATUS ;read status port TEST AL,RXRDY ;test device status bit JZ TLOOP ;blocking: if no data, go again DATAIN: IN AL,RXDATA ;data from Rx port & clr RXRDY flag OR AL,AL ;test for EOS marker JZ COMPLETE ;jmp out if finished MOV [EDI],AL ;save character in data buffer INC EDI JMP TLOOP ;back for more input COMPLETE: .... ;character string input complete Fig. 1.15 Example input polling loop in C and asm code
  11. 11. 18/6/09 11 ? 5 Fig. 1.16a Expensive software failures "Hardware degrades despite maintenance, software degrades because of it." Fig. 1.16b A depressing aphorism
  12. 12. 18/6/09 12 2. Implementing a Simple RTS rob > ps -A | wc -l 66 rob> Fig. 2.2 Linux workstation multi-tasking init task1 isr 1 isr 2 isr 3 task2 task3 task4 Fig. 2.3 simple task loop with interrupt routines accumulated jitter from interrupts & IF-ELSE task1 task2 task3 task4 t5 Fig. 2.4 Jitter: code runtime uncertainty
  13. 13. 18/6/09 13 Brr Brr! Brr Brr Fig. 2.5 Telephonic interruptions • How? • When? • Which? Fig. 2.6 Scheduling issues Fig. 2.7 Task Rentry, restoring the volatile environment • Explicit coding, cooperative scheduling, • R-t hll, co-routining support, • RTE, preemptive and cooperative scheduling, • O/S, priority-based tasking through system calls. Fig. 2.8 Multi-tasking implementation options
  14. 14. 18/6/09 14 • Disable task switching during a critical access, • Serialize all critical data accesses, • Semaphore process queues for access control. Fig. 2.9 Techniques for protecting critical data |< Outputs >| | Inputs | 2 3 4 5 6 7 8 9 25 10 11 12 13 Parallel Por t pin numbers 220Ω Switch LED 1 14 Fig. 2.10 Using the PC parallel port for i/o programming
  15. 15. 18/6/09 15 /* Outputs slow binary count to printer port (Centronics lines 2-9), while waiting for printer status bit 0x40 (Centronics line 10) to be set. Must be run as root */ #include <asm/io.h> #include <time.h> #define SLOW 500000000 #define CONTROL_REG 0x37A #define STATUS_REG 0x379 #define DATA_REG 0x378 #define SWITCH1 0x40 main () { int i; unsigned char c; struct timespec tr, tt={ 0, SLOW }; iopl(3); while ((inb(STATUS_REG) & SWITCH1)) { // check an input switch for a quit i++; outb(0xff&i, DATA_REG); // output pattern to LEDS nanosleep( &tt, &tr); } } Fig. 2.10b Basic programmed I/O under Linux • Stepper • DC with brushed commutator • AC Brushless Induction (Squirrel Cage) • DC Brushless • Servo • Universal with Commutator Fig. 2.11 Types of electric motor
  16. 16. 18/6/09 16 S N 1 2 4 Motor N S N N N N N S Top 3 N S S N 3 Motor Bottom S N S S S S S N Stator 2 4 1 coil N S Rotating Armature Position 1 Position 2 Position 3 Position 4 Fig. 2.12a Three steps in the operation of a stepper motor (based on Lawrence and Mauch, 1987) Rotor cog Stator coil Axle N S Fig. 2.12b Cross-section of stepper motor Magnetic Coil 1 Coil 2 rotor Stator ABC DEF magnetic poles Fig. 2.12c Exploded view of a small stepper motor Coil 1 Coil 2 S N S N A B C D E F V+ V+ Fig. 2.12d Activation of bifilar stator coils
  17. 17. 18/6/09 17 Stator Coil Excitation Sequence A C D F B&E Full Stepping Mode, single excitation Position 1 On Off Off Off V+ Position 2 Off Off On Off V+ Position 3 Off On Off Off V+ Position 4 Off Off Off On V+ Full Stepping Mode, double excitation Position 1 On Off Off On V+ Position 2 On Off On Off V+ Position 3 Off On On Off V+ Position 4 Off On Off On V+ Half Stepping Mode, double excitation Position 1 On Off Off Off V+ Position 1.5 On Off On Off V+ Position 2 Off Off On Off V+ Position 2.5 Off On On Off V+ Position 3 Off On Off Off V+ Position 3.5 Off On Off On V+ Position 4 Off Off Off On V+ Position 4.5 On Off Off On V+ Fig. 2.12e Driving a Stepper Motor
  18. 18. 18/6/09 18 1. Bodge 2. Bloat 3. Buy Fig. 2.13 Psychology or Life-cycle of a Systems Programmer 1. Entrepreneur - innovation, risk, speed 2. Bureaucrat - planned, documented, thorough 3. Technician - product maintenance, stability, care Fig. 2.14 Engineering Styles
  19. 19. 18/6/09 19 /* Example driver routine for a dual, two phase stepper motor */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include "../PIO.h" //gcc keypad.c -L. -lfab -o keypad #include <sys/time.h> #include <ctype.h> typedef unsigned char BYTE; typedef unsigned int DWORD; // alternative driving patterns for a dual, two phase stepper motor const BYTE steptab1[] = {8, 4, 2, 1, 8, 4, 2, 1, 8, 4, 2, 1, 8, 4, 2, 1}; const BYTE steptab2[] = {9,12, 6, 3, 9,12, 6, 3, 9,12, 6, 3, 9,12, 6, 3}; const BYTE steptab3[] = {8,12, 4, 6, 2, 3, 1, 9, 8,12, 4, 6, 2, 3, 1, 9}; int control, portA, portB, portC; int portCstatus = 0; // motor attached to C0-C3 of 8255 PIO void inithw(void) { int x=0x90; initFAB(&control, &portA, &portB, &portC); write(control, &x, 1); // 8255 mode 0 } void stepit(void) { static int step; int s; step = (step++)&0x0F; s = steptab2[step]; portCstatus = (s & 9)|((s&2)<<1)|((s&4)>>1); write(portC, &portCstatus, 1); } int main () { struct timeval tim; BYTE key; DWORD then, now, rround; initFAB(&control, &portA, &portB, &portC); gettimeofday(&tim, 0); now = tim.tv_sec*1000000 + tim.tv_usec; while (1) { rround =0; then = now+4000; if (now > then) rround = 1; // roll round flag while (rround ? (now > then):(then > now)) { gettimeofday(&tim, 0); now = tim.tv_sec*1000000 + tim.tv_usec; //printf("%d pc=%x r", then, portCstatus); } stepit(); } // while closeFAB(&control, &portA, &portB, &portC); return 0; }
  20. 20. 18/6/09 20 3. Basic Input and Output CPU A0-A23 D0-D7 System Bus A0-A19 A0-A20 D0-D7 R/W D0-D7 D0-D7 A0-A1 ALE A21-A23 1 MB PROM 2 MB RAM status reg I/O command reg C/S chip 0 C/S data regs I/O C/S 7 1 from 8 address decoder Fig. 3.2a Memory-mapped I/O, showing the address decoding for a 24 bit CPU Address Device Size Pins 24 bit Address bus Address range PROM1 1MB 20 000x ++++ ++++ ++++ ++++ ++++ 00 0000 - 0F FFFF RAM1 2MB 21 001+ ++++ ++++ ++++ ++++ ++++ 20 0000 - 3F FFFF RAM2 2MB 21 010+ ++++ ++++ ++++ ++++ ++++ 40 0000 - 5F FFFF RAM3 2MB 21 011+ ++++ ++++ ++++ ++++ ++++ 60 0000 - 7F FFFF I/O 4B 2 111x xxxx xxxx xxxx xxxx xx++ E0 0000 - E0 0003  E0 0004 - E0 0007 aliases  E0 0008 - E0 000B  E0 000C - E0 000F . . . + - used internally by device x - unused, don’t care 1 - needs to be a 1 for memory decoding 0 - needs to be a 0 for memory decoding Fig. 3.2b Memory map for the previous system
  21. 21. 18/6/09 21 Addr1 Addr2 Addr3 Address ALE valid valid valid data Read fetch read por t Write write M/IO instr data data Data 10 ns time-base Fig. 3.2c Bus activity while accessing memory-mapped ports Addr1 Addr2 Addr3 Address ALE valid valid valid data Read fetch read por t Write write M/IO instr data data Data 10 ns time-base Fig. 3.3 Bus activity while accessing I/O-mapped ports
  22. 22. 18/6/09 22 • Command • Status • Data Fig. 3.4a Types of Port Register 82C55A Functional Description I/O PA7- +5V GROUP A PA0 Data Bus Buffer POWER GROUP A PORT A SUPPLIES GND CONTROL (8) This three-state bi-directional 8-bit buffer is used to interface the 82C55A to the system data bus. Data is transmitted or I/O PC7- received by the buffer upon execution of input or output GROUP A PC4 BI-DIRECTIONAL PORT C instructions by the CPU. Control words and status informa- DATA BUS UPPER (4) I/O tion are also transferred through the data bus buffer. DATA PC3- D7-D0 BUS GROUP B PC0 BUFFER 8-BIT PORT C Read/Write and Control Logic INTERNAL LOWER DATA BUS (4) The function of this block is to manage all of the internal and external transfers of both Data and Control or Status words. I/O RD READ PB7- WR GROUP B PB0 It accepts inputs from the CPU Address and Control busses A1 WRITE CONTROL GROUP B CONTROL PORT B and in turn, issues commands to both of the Control Groups. A0 LOGIC (8) RESET (CS) Chip Select. A “low” on this input pin enables the communcation between the 82C55A and the CPU. (RD) Read. A “low” on this input pin enables 82C55A to send CS the data or status information to the CPU on the data bus. In FIGURE 1. 82C55A BLOCK DIAGRAM. DATA BUS BUFFER, essence, it allows the CPU to “read from” the 82C55A. READ/WRITE, GROUP A & B CONTROL LOGIC FUNCTIONS (WR) Write. A “low” on this input pin enables the CPU to write data or control words into the 82C55A. (RESET) Reset. A “high” on this input initializes the control (A0 and A1) Port Select 0 and Port Select 1. These input register to 9Bh and all ports (A, B, C) are set to the input signals, in conjunction with the RD and WR inputs, control mode. “Bus hold” devices internal to the 82C55A will hold the selection of one of the three ports or the control word the I/O port inputs to a logic “1” state with a maximum hold register. They are normally connected to the least significant current of 400µA. bits of the address bus (A0 and A1). Group A and Group B Controls 82C55A BASIC OPERATION The functional configuration of each port is programmed by the systems software. In essence, the CPU “outputs” a con- INPUT OPERATION trol word to the 82C55A. The control word contains A1 A0 RD WR CS (READ) information such as “mode”, “bit set”, “bit reset”, etc., that ini- tializes the functional configuration of the 82C55A. 0 0 0 1 0 Port A → Data Bus Each of the Control blocks (Group A and Group B) accepts 0 1 0 1 0 Port B → Data Bus “commands” from the Read/Write Control logic, receives “control words” from the internal data bus and issues the 1 0 0 1 0 Port C → Data Bus proper commands to its associated ports. Control Group A - Port A and Port C upper (C7 - C4) 1 1 0 1 0 Control Word → Data Bus Control Group B - Port B and Port C lower (C3 - C0) OUTPUT OPERATION The control word register can be both written and read as (WRITE) shown in the “Basic Operation” table. Figure 4 shows the control word format for both Read and Write operations. 0 0 1 0 0 Data Bus → Port A When the control word is read, bit D7 will always be a logic “1”, as this implies control word mode information. 0 1 1 0 0 Data Bus → Port B 1 0 1 0 0 Data Bus → Port C 1 1 1 0 0 Data Bus → Control DISABLE FUNCTION X X X X 1 Data Bus → Three-State X X 1 1 0 Data Bus → Three-State 3 Fig. 3.4b Data Sheet (page 3) for a Harris 82C55A, Parallel Port I/O Chip
  23. 23. 18/6/09 23 Port address Function 3F8-3FFH COM1 3F0-3F7H FDC 3C0-3DFH Graphics card 3B0-3BFH Graphics card 3A0-3AFH 380-38CH SDLC controller 378-37FH LPT1 300-31FH 2F8-2FFH COM2 278-27FH LPT2 210-217H Expansion unit 200-20FH Games por t 1F0-1F8H Primar y IDE controller 170-178H Secondary IDE controller 0E0-0FFH 8087 coprocessor slot 0C0-0DFH DMA controller (4 channels) 0A0-0BFH NNI reset 080-09FH DMA controller (4 channels) 060-07FH Digital i/o 040-05FH Counter/timer 020-02FH PIC 000-01FH DMA Fig. 3.4c A Listing of PC I/O-mapped Port Addresses with Standard Function Mode 0 - basic byte-wide input and output ports Mode 1 - bytes passed by strobed (async) handshake Mode 2 - tri-state bus action Fig. 3.4d Modes of Activity for an i8255 PIO
  24. 24. 18/6/09 24 D7 D6 D5 D4 D3 D2 D1 D0 Control Register C0 - C3: 1 - input, 0 - output B0 - B7: 1 - input, 0 - output Mode: 0 - basic, 1 - strobed C4 - C7: 1 - input, 0 - output A0 - A7: 1 - input, 0 - output Mode: 00 - basic, 01 - strobed, 10 - bus 1 - set port modes Fig. 3.4e Control Register Functions for the 8255 PPI // Win-98 init an 8255 at 0x1f3: Port A IN; B OUT; C OUT outp((short)0x1F3, 0x90); // Initialize 8255 Command Register System buses operate at 500 Mbyte/sec Blocks of characters moved at 100 Mbyte/sec Ethernet transfers data at 10 Mbytes/sec Telephone call needs 8 Kbyte/sec Serial lines frequently run at 1 Kbyte/sec Epson printers operate at 100 byte/sec Keyboards send at 4 byte/sec Fig. 3.5a Relative speeds of operation
  25. 25. 18/6/09 25 Dedicated Intermittant spin timed polling polling Fig. 3.5b Dedicated and Intermittent Polling rob> su Password: ****** root> ls -al duckshoot root> -rwxr-xr-x 1 rob rob 14336 Apr 17 11:26 duckshoot root> chown root:root duckshoot root> ls -al duckshoot root> -rwxr-xr-x 1 root root 14336 Apr 17 11:26 duckshoot root> chmod +s duckshoot root> ls -al duckshoot root> -rwsr-sr-x 1 root root 14336 Apr 17 11:27 duckshoot root> exit rob> ./duckshoot Fig. 3.6a Root access to ports Fig. 3.6b Duckshoot sequence
  26. 26. 18/6/09 26 /* duckshoot.c, * demo of parallel port facilities for I/O * Trigger button has to be relaxed between shots */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <parapin.h> // gcc -O duckshoot.c -lparapin -o duckshoot #define OUTPUT_PINS 0x00FF #define INPUT_PINS 0xF000 // obtained from parapins.h void right_rot(unsigned char * f) { unsigned char t = *f; *f = (*f>>1) | ((t & 1) ? 0x80 : 0); } void left_rot(unsigned char * f) { unsigned char t = *f; *f = (*f<<1) | ((t & 0x80) ? 1 : 0); } void put_byte(unsigned char b) { unsigned int i, mask=1; for (i=0; i<8; i++) if (b & mask<<i) set_pin(LP_PIN[i+2]); else clear_pin(LP_PIN[i+2]); } int main() { unsigned char flock = 0x0f; // initial flock of 4 ducks int i, snore, trigger, direction; if (pin_init_user(LPT1) < 0) exit(0); pin_output_mode(OUTPUT_PINS); // 8 LEDs to display current state of flock pin_input_mode(INPUT_PINS); // direction, speed, and trigger while (flock && flock<0xFF) { // continue until flock empty or full put_byte(flock); // update LED display printf(" %2x n", flock); if (pin_is_set(LP_PIN12) ) snore=250000; else snore=50000; trigger = pin_is_set(LP_PIN10); // get state of trigger direction = pin_is_set(LP_PIN13); // get direction of flight usleep(snore); if(trigger && !pin_is_set(LP_PIN10)) flock /= direction ? 0x01 : 0x80;
  27. 27. 18/6/09 27 if (direction) // rotate flock right_rot(&flock); else left_rot(&flock); }; if (flock==0) // end of game! printf("You won!nn"); else printf("You lost!nn"); for (i=0; i<10; i++) { set_pin(OUTPUT_PINS); usleep(100000); clear_pin(OUTPUT_PINS); usleep(100000); } clear_pin(OUTPUT_PINS); return 0; }
  28. 28. 18/6/09 28 /* Example of Linux tcsetattr( ) function to disable keyboard blocking & buffering, for single char entry */ #include <stdio.h> #include <sys/termios.h> #include <ctype.h> void setterm(void) { struct termios kbd; tcgetattr(0, &kbd); // file descriptor 0 = stdin kbd.c_lflag &= ∼(ICANON); kbd.c_cc[VTIME] = 1; kbd.c_cc[VMIN] = 0; tcsetattr(0, TCSANOW, &kbd); //console device } main ( ) { int letter = ’a’; setterm( ); while (letter != ’q’) { letter = getchar( ); putchar(’.’); } } Fig. 3.7a Reconfiguring Keyboard Input on Linux int fd; struct termios tty; fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd <0) {perror("failed to open /dev/ttyS0"); exit(-1); } tcgetattr(fd, &tty); tty.c_lflag &= ∼(ICANON); tty.c_cc[VTIME] = 1; tty.c_cc[VMIN] = 0; tcsetattr(fd, TCSANOW, &tty); Fig. 3.7b Setting the Linux COM port #include <unistd.h> #include <fcntl.h> main( ) { int fd; fd = open("/dev/ttyS0", O_RDWR); if (fd <0) {perror("failed to open /dev/lp0"); exit(-1); } fcntl(fd, F_SETFL, O_NONBLOCK); .... } Fig. 3.7c Setting non-blocking devices using fcntl( )
  29. 29. 18/6/09 29 Interrupt Request CPU Int Ack System Bus Main I/O Memor y Fig. 3.8a Using the CPU Interrupt Req and Ack Lines • External interrupts • System errors • TRAP instructions Fig. 3.8b Exception Types
  30. 30. 18/6/09 30 Interrupt Request CPU System Bus Main Memor y I/O A I/O B I/O C Fig. 3.9a Many interrupting devices on one Int Req Interrupt Request CPU Int Ack System Bus Main IVR IVR IVR Memor y I/O A I/O B I/O C Fig. 3.9b Vectored Interrupts with daisy-chain prioritization Line Programmable Interrupt Controller IVR table Interrupt Requests CPU System Bus Main I/O A I/O B I/O C Memor y Fig. 3.9c Vectored Interrupts Using PIC hardware
  31. 31. 18/6/09 31 • Device Polling • Device Returns Vector • Interrupt Controller (PIC) Fig. 3.9d Device Identification Interrupt request CPU Intr Ack IVR main() I/O chip isr IVT Device Memor y Fig. 3.9e Locating ISRs using IVR facilities Retriggerable 100 Hz monostable 10k 50 Hz line Power fail frequency interrupt 50 Hz interrupt 1 2 2 1 J-K flip-flop Opto-couplers Fig. 3.10 Sources of power line interrupt signals
  32. 32. 18/6/09 32 IRQ0 Int Function Source IRQ1 Number 77 Hard Disk2 IRQ15 IRQ3 PIC 1 76 Hard Disk1 IRQ14 to IRQ4 75 8087 IRQ13 Pentium IRQ5 interrupt 74 PS/2 Mouse IRQ12 IRQ6 IRQ7 73 Soundcard IRQ11 72 Network IRQ10 71 Redirected IRQ2 IRQ8 70 RTC IRQ8 IRQ9 IRQ10 ........... IRQ11 PIC 2 IRQ12 18 BIOS/TOD INT IRQ13 17 BIOS/softboot INT IRQ14 16 BIOS/print INT IRQ15 15 BIOS/KBD INT 14 BIOS/comms INT 13 BIOS/disk INT 12 BIOS/msize INT 11 BIOS/check INT 10 BIOS/Video INT IRQ7 IRQ6 IRQ5 IRQ4 IRQ3 IRQ2 IRQ1 IRQ0 0F LPT1: IRQ7 0E FDC IRQ6 PIC Interrupt Mask Register (21H) 0D SoundCard IRQ5 1 -disable 0C COM1: IRQ4 0 - enable 0B COM2: IRQ3 EOI 0 0 I2 I1 I0 0A ---- IRQ2 09 KBD: IRQ1 PIC Interrupt Control Register (20H) 08 System Timer IRQ0 EOI - write 1, reenable interrupts 07 I0-I2 - read, current interrupt number 06 05 Screen dump to printer 04 Numeric Overflow 03 Breakpoint 02 NMI, Power fail 01 Single Step Trace 00 Integer Divide Error Fig. 3.11a Part of the PC IVT and related PIC connections
  33. 33. 18/6/09 33 PIC IVR table CPU Interrupt request main() I/O chip isr Device IVT Memor y Fig. 3.11b Locating Interrupt Service Routines prioritised deferred isr 1 isr 2 isr 3 Top Half ser vice immediate routine queue Bottom Half deferred CPU Fig. 3.12 Deferred Interrupt Processing
  34. 34. 18/6/09 34 • I/O data transfer request • Software TRAP (SVC) • Machine Failure • Real-time Tick • Run-time Software Error • System Reset or Watchdog Fig. 3.13a Possible Sources of Interrupts User System Privilege Privileged facilities Interrupt request Fig. 3.13b How interrupts assist operating system security Global data main() isr() Fig. 3.15a Using global data for communication
  35. 35. 18/6/09 35 • disable interrupts • serialise the access • use a semaphore Fig. 3.15b Alternative solutions to protecting a critical resource
  36. 36. 18/6/09 36 Data Variables Display Routines ISR in Memory Interrupt request msecs++ msecs 990 Display secs secs 59 Display mins msecs = 0 mins 59 secs++ hrs 01 Display hrs secs = 0 mins++ mins = 0 Hours Mins Secs hrs++ hrs = 0 rte Fig. 3.15c Real-time Clock and Time-of-day Display
  37. 37. 18/6/09 37 Tick Flag Interrupt No tick request tickF++ tickF=0 msecs++ ISR Data Variables in Memory N msecs 990 msecs = 0 secs++ secs 59 N mins 59 secs = 0 Fig. 3.15d Using a Tick Flag hrs 01 mins++ N mins = 0 hrs++ N hrs = 0 N Display secs Display mins Display hrs
  38. 38. 18/6/09 38 Transmit Data Buffer Tx Tx Interrupt putc( ) Dev request Driver Tx ISR Tx data User Receive UART Applctn Data Buffer Rx ISR Rx Rx data getc( ) Dev Rx Interrupt Driver request Fig. 3.16 Using Buffered, Interrupt-driven I/O
  39. 39. 18/6/09 39 4. Cyclic Executives on Bare Hardware clock interrupt rtc isr tick flag task 1 task 2 task 3 task 4 Burn ? Test for 20 msec tick Fig. 4.2 Timed Cyclic Loop with Burn Task 20 ms Fig. 4.3a The 50 Hz R-t Clock, or Tick System CPU Clock RTC Interrupt Request System Bus Main CTC Memory Fig. 4.3b Generating the R-t Tick Interrupt - event driven preemption, rapid response Clock - periodic scanning with fixed runtime Base - no strict requirements, background activity Fig. 4.3c Task priority levels for a cyclic executive
  40. 40. 18/6/09 40 task 3.odd task 1 task 2 task 4 Burn ? task 3.even Test for tick Fig. 4.4 Cyclic Loop with a Split Clock Task 2 ms allocated per slot t1 t1 t1 t1 t1 t1 t1 t1 t2 t3 t2 t3 t2 t3 t2 t3 t4 t4 t4 t4 t4 t4 t4 t4 t5 burn burn burn burn burn burn burn t6 t7 burn 0 1 2 3 4 5 6 7 Fig. 4.5a A 16 ms Time Frame with 8 execution slots Clock Base Sched Sched RTC Rx Tx •• ISRs Base tasks Slot 0 Slot 1 Slot 7 Frame for Clock Tasks Fig. 4.5b Cyclic Executive Task Scheme
  41. 41. 18/6/09 41 Interrupt RTC RxRdy Level isr isr Clock Slot 0 Slot 1 Slot 2 Slot 3 Level Base Level 20 ms Time interrupts Fig. 4.6 Execution with Interrupt, Clock & Base Tasks
  42. 42. 18/6/09 42 /* Demo table-based cyclic task dispatcher for Linux with multiple task slots*/ #include <stdio.h> #include <ctype.h> #include <unistd.h> #include <sys/times.h> #define SLOTX 4 #define CYCLEX 5 #define SLOT_T 5000 // 5 sec slot time int tps, cycle=0, slot=0; clock_t now, then; struct tms n; void one() { // task code printf("task 1 runningn"); sleep(1); } void two() { printf("task 2 runningn"); sleep(2); } void three() { printf("task 3 runningn"); sleep(3); } void four() { printf("task 4 runningn"); sleep(4); } void five() { printf("task 5 runningn"); sleep(5); } void burn() { clock_t bstart = times(&n); while ( ((now=times(&n))-then) < SLOT_T*tps/1000 ) { /* burn time here */ } printf("burn time = %2.2dmsnn", (times(&n)-bstart)*1000/tps); then = now; cycle = CYCLEX; } void (*ttable[SLOTX][CYCLEX])() = { {one, two, burn, burn, burn}, {one, three, burn, burn, burn}, {one, four, burn, burn, burn}, {burn, burn, burn, burn, burn} }; main () { tps = sysconf(_SC_CLK_TCK); printf("clock ticks/sec = %dnn", tps)); while (1) { for(slot=0; slot<SLOTX; slot++) for(cycle=0; cycle<CYCLEX; cycle++) (*ttable[slot][cycle])(); // dispatch next task from table } }
  43. 43. 18/6/09 43 Fig. 4.8b Optical or Manual Crosspoint Switch 5v 10K 16 Button Keypad 3 1 0 1 2 3 0 A 2 4 5 6 7 4 bit 1 i/p 1 8 9 10 11 Microprocessor System Bus 1 0 12 13 14 15 3 1 1 C 2 4 bit 0 o/p 1 1 0 5v B 8 bit o/p 330Ω 4 Digit LED Display Fig. 4.8a Engineer’s Console: Keypad and Display
  44. 44. 18/6/09 44 /* Keypad (16 switches) scanner and 7-seg digit LED refresh tasks * needs to be run at least every 20ms (50Hz minimum) * Linux version, 28-2-04 */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include "../PIO.h" #include <sys/termios.h> #include <ctype.h> #define COLSX 4 #define ROWSX 4 typedef unsigned char BYTE; typedef unsigned int DWORD; DWORD keyflags; BYTE colsel=0; BYTE kpd0[COLSX]; BYTE kpd1[COLSX]; BYTE kpd2[COLSX]; BYTE ktrue[COLSX]; //current true keypad status BYTE kedge[COLSX]; BYTE kchange[COLSX]; //1 - key status changed BYTE digits[COLSX] ={3,2,1,0}; const BYTE segtab[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82, 0xF8,0x80,0x90,0x88,0x83,0xA7,0xA1,0x86,0x8E,0xFF}; const BYTE keytab[] = {1,2,3, 15,4,5,6,14,7,8,9,13,10,0,11,12}; int control, portA, portB, portC; int portAstatus = 0; int portBstatus = 0; int portCstatus = 0; void initFAB(int *control, int *porta, int *portb, int *portc); void closeFAB (int *control, int *porta, int *portb, int *portc); void inithw(void) { int x; setterm(); initFAB(&control, &portA, &portB, &portC); x = 0x90; write(control, &x, 1); // mode 0 }
  45. 45. 18/6/09 45 BYTE colscan(void) { int i; BYTE know; colsel = (++colsel) % COLSX; portCstatus = (BYTE) (01 << colsel); portBstatus = segtab[digits[colsel]]; write(portB, &portBstatus, 1); write(portC, &portCstatus, 1); for(i=0;i<1000;i++); read(portA, &portAstatus, 1); kpd2[colsel] = kpd1[colsel]; kpd1[colsel] = kpd0[colsel]; kpd0[colsel] = (BYTE)portAstatus; kchange[colsel] = (kpd0[colsel] / kpd1[colsel]) | (kpd1[colsel] / kpd2[colsel]); know = (kpd2[colsel] & ∼kchange[colsel]) | (ktrue[colsel] & kchange[colsel]); kedge[colsel] = (know / ktrue[colsel]) & know; ktrue[colsel] = know; keyflags = 0; keyflags |= ktrue[0] & 0x0F; keyflags |= (ktrue[1] & 0x0F) << 4; keyflags |= (ktrue[2] & 0x0F) << 8; keyflags |= (ktrue[3] & 0x0F) << 12; keyflags &= 0x0000ffff; for(i=0; keyflags&1; keyflags>>=1) i++; return i; } int main () { struct tms *tim; BYTE key; DWORD then; inithw(); while (1) { key = colscan(); if (key <16) { digits[0]= keytab[key]; digits[1]= 16; digits[2]= key % 10; digits[3]= key / 10; } else { digits[0]= 16; digits[1]= 16; digits[2]= 16; digits[3]= 16; } printf(" key = %x n", key); then = (DWORD)times(&tim)+1; while (then > (DWORD)times(&tim)) { }; } closeFAB(&control, &portA, &portB, &portC); return 0; }
  46. 46. 18/6/09 46 5. Finite State machines - design tool INPUTS OUTPUTS sources sinks micro- timer alarm controller bread loaded cooking element bread lowered buzzer cooking time star t timer release button warming element warm button smoke sensor Fig. 5.2a Context diagram for a toaster Input Type Rate Hz timer alarm bool 0.2 bread loaded bool 0.01 bread lowered bool 0.01 cooking time BYTE - release button bool ? warm button bool ? smoke sensor bool ? Output cooking element bit 0.01 buzzer bit 0.2 star t timer bit 0.2 warming element bit 0.01 Fig. 5.2b Fully specifying I/O
  47. 47. 18/6/09 47 Toggle keepwarmSetCooktime bread loaded Waiting Holding cooking 0 1 time i/p Buzz Heater off no bread bread lowered Warmer off Release bread Buzz Heater on Toggle Set timer release Star t timer keepwarm button time alarm OR smoke OR release timer Warming Cooking warm alarm 3 2 button pressed Buzz time alarm & warm Heater off OR release & warm Warmer on Set timer Fig. 5.3 Example FSD: the toaster Transition Trigger Action State 0 event State 1 Fig. 5.4a States, Transitions, Trigger Events and Actions state: unchanging, waiting condition transition: valid routes between states, triggered by events event: triggers transition between states, often an input action: activity/procedure undertaken on entry to a new state Fig. 5.4b Component Parts of Finite State Diagrams
  48. 48. 18/6/09 48 Entr y Exit Action St1 Action Action Fig. 5.4c Entry, State and Exit Actions Star t pressed Timed out & door shut Trigger Event Unlock Door Loading Open fill valve cnt=0 Action list Holding Filling Water low Full & cnt<2 & cnt==0 open water valve Close fill valve Drain pump off Heater on Full & cnt>0 wc=0 Heating Timed out Set timer close water valve Motor off Water hot Set timer Heater off Nrot=0 Set Timer Nrot>4 Spinning Drain on Pause1 cnt++ Tumbling Draining Timed out (cw) Water low motor on CW & cnt>=2 Timed out Timed out Set timer Drain pump off motor off motor off Fan on Set timer Set timer Timer set Nrot++ ATumbling Pause2 (ccw) Timed out motor on CCW Set timer Fig. 5.5 FSD for a Washing Machine
  49. 49. 18/6/09 49 Induction Loop c-- L1 Detectors OFF .......... . ........... .. . .. ......... .. . .......................................................... ... .... .. c-- ............................................................ . .. . . . .. . . ...... ...... ...... ....... .... ... . . . . . 00 10 11 00 L2 00 Vehicles S5 S1 S9 11 11 10 10 10 00 00 10 S4 S2 S6 S10 S8 01 00 00 01 00 01 01 11 11 S3 S11 S7 00 00 c++ 00 c++ 01 OFF c++ Fig. 5.6a FSD for a Vehicle Induction Loop Detector Unit Data Conditions Exiting from Go to State State Star t pressed & Door Shut Waiting Filling Water Full & cnt==0 Filling Heating Water Hot Heating Pause1 Time Out Pause1 TumbleCCW Time Out TumbleCCW Pause2 Time Out Pause2 TumbleCW Time Out TumbleCW Pause1 Nrot>4 Pause1 Draining Water Low & cnt<2 Draining Filling Water Low & cnt>=2 Draining Spinning Time Out Spinning Holding Time Out Holding Waiting Fig. 5.6b An Event Table, with data values and conditions
  50. 50. 18/6/09 50 kettle weight sensor. Tea pot weight sensor. Water heater control relay. Radio power control relay. Aler t buzzer. Reading light relay. User control panel with selection buttons. Press Next Press Forward advance digit value++ Setting Press Next Timed out | cancel Waiting radio off Morning Tea Radio On set timer radio on Timing Timed out & Radio only Timed out & Buzz selected Radio on, set timer star t buzzer Timed out & Tea kettle on Boiling Buzzing Kettle empty kettle off, radio on, set timer Radio Cancel Alarm Buzz off, Radio on, set timer Fig. 5.9 FSD for a Teas-made Bedside Alarm
  51. 51. 18/6/09 51 Filling Open valve Washing Pause1 TumbleCCW Pause2 TumbleCW motor off motor CCW motor off motor CW Set timer Set timer Set timer Set timer Heating Draining Cancel pressed Heater On Pump on Fig. 5.10a Washing Machine as a Hierarchical FSD
  52. 52. 18/6/09 52 NEXT SET INCR END Fig. 5.10b Digital watch buttons Setting set Display h Clock TOD set minAlarm next next min incr set hour next Alarm hour incr alarm set day next Alarm next day incr Cleared Set month next next month incr year next Fig. 5.10c Hierarchical statechart for the digital watch year incr next Display Alarm AppClass aState Setting Silent Bell State1 StateN Fig. 5.12 OO state design pattern Fig. 5.11 Parallel statecharts
  53. 53. 18/6/09 53 6. Finite state machines - implementation • sequential code closely following the FSD, used by OOP • multiple CASE: case/switch statement to model the FSD • based on goto-labels • FST: Finite State Table method • Object oriented design pattern with dynamic states Fig. 6.2a Implementation Techniques for FSDs Toggle SetCooktim keepwarm SetCooktim Bread in Cook Waiting Holding Bread Cook time 0 1 No Bread time Buzz Warmer off Heater off Cook Request Release bread Buzz Heater on Toggle Set timer Bread Set timer keepwarm raised Time up OR Smoke OR Raised Timeup Warming Cooking 3 2 Warm button pressed Buzz Time up & warm Heater off OR Raised & warm Warmer on Set timer Fig. 6.2b Finite State Diagram for the Toaster
  54. 54. 18/6/09 54 Init Waiting SetCooktime 0 Holding Toggle SetCooktime keepwarm 1 Heater on Set timer Buzz Heater off Cooking Toggle Release bread 2 keepwarm Buzz Heater off Warm on Warming Buzz Warm off Set timer 3 Fig. 6.3 Algorithmic State Machine for a Toaster
  55. 55. 18/6/09 55 /* toaster1.c, direct sequential coding of FSD for Linux */ #include <stdio.h> #include <ctype.h> #include <ncurses.h> #include <sys/times.h> #include <unistd.h> #define BREADIN ’B’ #define BREADUP ’N’ #define RELEASE ’R’ #define WARMTOGGLE ’T’ #define COOKRQ ’C’ #define BUZZTIME 5 main() { clock_t delay, cooktime=1; struct tms n; int key = ’0’; unsigned int warm = 0; unsigned int tps; initscr(); cbreak(); nodelay(stdscr, TRUE); tps = sysconf(_SC_CLK_TCK); // ticks per second while (1) { do { do { putchar(’n’); do { if (isdigit(key)) cooktime = (key - ’0’); printf("WAITING 0, Cook time=%2d secs r", cooktime); // State 0 key = getch(); } while (toupper(key) != BREADIN); putchar(’n’); do { if (isdigit(key)) cooktime = (key - ’0’); if (key==WARMTOGGLE) warm=!warm; printf("HOLDING 1, Cook time=%2d secs, Warming %s, r",cooktime,(warm)?"ON":"OFF"); key = toupper(getch()); //State 1 } while (key!=COOKRQ && key!=BREADUP); } while (key != COOKRQ); printf("nheater turned onn"); delay = times(&n) + cooktime*tps; do { if (key == WARMTOGGLE) warm = !warm; printf("COOKING 2, Warming %s, time=%3.1d r",(warm)?"ON":"OFF",(delay-times(&n))/tps); key = toupper(getch()); } while ((delay > times(&n)) && (key!=RELEASE)); //State 2 } while (!warm); putchar(’n’); do { putchar(’007’); delay = times(&n) + BUZZTIME*tps; do { printf("WARMING 3 r"); } while (delay > times(&n)); //State 3 } while (toupper(getch()) != RELEASE); } }
  56. 56. 18/6/09 56 /* toaster2.c, a keyboard/screen simulation using Linux timing & i/o Implemented using switch/case with centralised input scanning */ #include <stdio.h> #include <ctype.h> #include <ncurses.h> // compile with: gcc toaster2.c -lncurses -otoaster2 #include <sys/times.h> #include <unistd.h> #define FOREVER 1 #define COOKRQ ’C’ #define BREADIN ’B’ #define BREADUP ’N’ #define RELEASE ’R’ #define WARMTOGGLE ’T’ #define BUZZTIME 5 #define WAITING 0 #define HOLDING 1 #define COOKING 2 #define WARMING 3 unsigned int events, state, state_events; clock_t cooktime, targettick; struct tms n; int keep_warm; unsigned int ccount, tps; int key; void wait() { printf("Waitingnr"); } void hold() { printf("Holding breadnr"); } void cook() { printf("Heater on full, set delay for cooking timenr"); printf("Cooking toast for %d secsnr", cooktime); targettick = times(&n) + cooktime*tps; // setting cooking period } void warm() { printf("07 07 07 Buzz, Heater on half, set delay for buzznr"); targettick = times(&n) + BUZZTIME*tps; // 5sec interval on buzzer printf("Toast ready and warmingnr"); } void off() { printf("007 007 007 Buzz, Timer off, Heater Offnr"); printf("Toast readynr"); } void buzz() { printf("007 007 007 BUZZ, BUZZ, Warming, set delay for next buzznr"); targettick = times(&n) + BUZZTIME*tps; // 5sec interval on buzzer } void setcooktime() { cooktime = key - ’0’; printf("ncooking time set to %d secsnr", cooktime); } void toggle() { keep_warm = !keep_warm; printf("ntoggle warming status to %snr", (keep_warm ? "ON":"OFF")); }
  57. 57. 18/6/09 57 main() { state = 0; printf("nn"); initscr(); cbreak(); nodelay(stdscr, TRUE); tps = sysconf(_SC_CLK_TCK); while (FOREVER) { key = 0; key = toupper(getch()); printf("State = %2d r",state); switch (state) { case WAITING: if (key == BREADIN) { state = HOLDING; } else if (isdigit(key) ){ setcooktime(); } else if (key == WARMTOGGLE) { toggle(); } break; case HOLDING: if (key == BREADUP) { state = WAITING; } else if (isdigit(key) ){ setcooktime(); } else if (key == WARMTOGGLE) { toggle(); } else if (key == COOKRQ) { cook(); state = COOKING; } break; case COOKING: if (key == WARMTOGGLE) { toggle(); break; } if ( targettick < times(&n) || key == BREADUP) { off(); if (keep_warm) { warm(); state = WARMING; } else { state = WAITING; } } break; case WARMING: if ( targettick < times(&n) ){ buzz(); } if(key == RELEASE) { off(); state = WAITING; } break; } } }
  58. 58. 18/6/09 58 Toaster Init Toasting * forever 1 slice state Operation ° ° ° ° Waiting 0 Holding 1 Cooking 2 Warming 3 event event event event * * * * time ° toggle ° timeup ° timeup ° input input input input do state do state do set do set action =0 action =1 action index action index time toggle nobread bread ° ° ° ° do state do state do set do set action =1 action =1 action index action index cook wtimeup ° ° do state do set action =2 action index nobread ° do state action =0 Fig. 6.4 Structure chart equivalent for the toaster FSD
  59. 59. 18/6/09 59 /* toaster3.c, a keyboard/screen simulation for Linux timing & i/o. Implemented using goto/label jump structure */ #include <stdio.h> #include <ncurses.h> //link to libcurses.so: gcc toaster3.c -lncurses -otoastie #include <sys/times.h> #include <unistd.h> #define COOKRQ ’C’ #define BREADIN ’B’ #define BREADUP ’N’ #define RELEASE ’R’ #define WARMTOGGLE ’T’ #define BUZZTIME 5 clock_t targettick, cooktime; struct tms n; int keep_warm = ∼0; int key, tps; void wait() { printf("Waiting nr"); } void hold() { printf("Holding bread nr"); } void cook() { printf("Heater on full, set delay for cooking timenr"); printf("Cooking toast for %d secsrn", cooktime); targettick = times(&n) + cooktime*tps; // setting cooking period } void warm() { printf("Buzz, Heater on half, set delay for buzznr"); printf("Toast ready and warmingnr"); targettick = times(&n) + BUZZTIME*tps; // 5sec interval on buzzer } void off() { printf("Buzz, Timer off, Heater Offnr"); printf("Toast ready and coolingnr"); } void buzz() { targettick = times(&n) + BUZZTIME*tps; // 5sec interval on buzzer putchar(’007’); } void setcooktime() { cooktime = key - ’0’; targettick = times(&n) + cooktime*tps; printf("ncooking time set to %d secsnr", cooktime); } void toggle() { keep_warm = !keep_warm; printf("ntoggle warming status to %snr", (keep_warm ? "ON":"OFF")); }
  60. 60. 18/6/09 60 main() { struct tms n; initscr(); cbreak(); nodelay(stdscr, TRUE); noecho(); tps = sysconf(_SC_CLK_TCK); Waiting: printf("WAITING 0 r"); key = toupper(getch()); if (key == BREADIN) { hold(); goto Holding; } if (isdigit(key)) { setcooktime(); } goto Waiting; Holding: printf("HOLDING 1, Warming is %s r", (keep_warm) ? "ON":"OFF"); key = toupper(getch()); if (key == BREADUP) { wait(); goto Waiting; } if (key == COOKRQ) { cook(); goto Cooking; } if (key == WARMTOGGLE) keep_warm = ∼keep_warm; if (isdigit(key)) setcooktime(); goto Holding; Cooking: printf("COOKING 2 r"); key = toupper(getch()); if ( (targettick < times(&n)) || (key == RELEASE)) { if (keep_warm) { warm(); goto Warming; } else { off(); goto Waiting; } } if (key == WARMTOGGLE) { toggle(); } goto Cooking; Warming: printf("WARMING 3 r"); if (targettick > times(&n)) { key = getch(); if (toupper(key) == RELEASE) { off(); goto Waiting; } } else { buzz(); } goto Warming; }
  61. 61. 18/6/09 61 states 0 STATESX-1 0 events FST {VALID, NEXT_STATE, ACTION} EVENTSX-1 Fig. 6.6 Finite State Table layout

×