SlideShare uma empresa Scribd logo
1 de 349
Baixar para ler offline
I
                                                                                                       [v1.1]
                                          University of Leicester
                                          Michael J. Pont
              A 10-week course, using C
Programming

Systems II
Embedded

                                                                    1    P1.0              VCC    40
                                                                    2    P1.1             P0.0    39
                                                                    3    P1.2              P0.1   38
                                                                    4    P1.3              P0.2   37
                                                                    5    P1.4              P0.3   36
                                                                    6    P1.5              P0.4   35
                                                                    7    P1.6              P0.5   34
                                                                    8    P1.7              P0.6   33




                                                                                ‘8051’
                                                                    9    RST               P0.7   32
                                                                    10   P3.0              / EA   31
                                                                    11   P3.1              ALE    30
                                                                    12   P3.2            / PSEN   29
                                                                    13   P3.3              P2.7   28
                                                                    14   P3.4              P2.6   27
                                                                    15   P3.5              P2.5   26
                                                                    16   P3.6              P2.4   25
                                                                    17   P3.7              P2.3   24
                                                                    18   XTL2              P2.2   23
                                                                    19   XTL1              P2.1   22
                                                                    20   VSS               P2.0   21
Copyright © Michael J. Pont, 2002-2003

This document may be freely distributed and copied, provided that copyright notice at
the foot of each OHP page is clearly visible in all copies.




                                                                                        II
Seminar 1: A flexible scheduler for single-processor embedded systems   1
  Overview of this seminar                                               2
  Overview of this course                                                3
  By the end of the course you’ll be able to …                           4
  Main course text                                                       5
  IMPORTANT: Course prerequisites                                        6
  Review: Why use C?                                                     7
  Review: The 8051 microcontroller                                       8
  Review: The “super loop” software architecture                         9
  Review: An introduction to schedulers                                 10
  Review: Building a scheduler                                          11
  Overview of this seminar                                              12
  The Co-operative Scheduler                                            13
  Overview                                                              14
  The scheduler data structure and task array                           15
  The size of the task array                                            16
  One possible initialisation function:                                 17
  IMPORTANT: The ‘one interrupt per microcontroller’ rule!              18
  The ‘Update’ function                                                 19
  The ‘Add Task’ function                                               20
  The ‘Dispatcher’                                                      22
  Function arguments                                                    24
  Function pointers and Keil linker options                             25
  The ‘Start’ function                                                  28
  The ‘Delete Task’ function                                            29
  Reducing power consumption                                            30
  Reporting errors                                                      31
  Displaying error codes                                                34
  Hardware resource implications                                        35
  What is the CPU load of the scheduler?                                36
  Determining the required tick interval                                38
  Guidelines for predictable and reliable scheduling                    40
  Overall strengths and weaknesses of the scheduler                     41
  Preparations for the next seminar                                     42




                                                                        III
Seminar 2: A closer look at co-operative task scheduling (and some alternatives)   43
  Overview of this seminar                                                         44
  Review: Co-operative scheduling                                                  45
  The pre-emptive scheduler                                                        46
  Why do we avoid pre-emptive schedulers in this course?                           47
  Why is a co-operative scheduler (generally) more reliable?                       48
  Critical sections of code                                                        49
  How do we deal with critical sections in a pre-emptive system?                   50
  Building a “lock” mechanism                                                      51
  The “best of both worlds” - a hybrid scheduler                                   55
  Creating a hybrid scheduler                                                      56
  The ‘Update’ function for a hybrid scheduler.                                    58
  Reliability and safety issues                                                    61
  The safest way to use the hybrid scheduler                                       63
  Other forms of co-operative scheduler                                            65
  PATTERN: 255-TICK SCHEDULER                                                      66
  PATTERN: ONE-TASK SCHEDULER                                                      67
  PATTERN: ONE-YEAR SCHEDULER                                                      68
  PATTERN: STABLE SCHEDULER                                                        69
  Mix and match …                                                                  70
  Preparations for the next seminar                                                71




                                                                                   IV
Seminar 3: Shared-clock schedulers for multi-processor systems   73
  Overview of this seminar                                        74
  Why use more than one processor?                                75
  Additional CPU performance and hardware facilities              76
  The benefits of modular design                                  78
  The benefits of modular design                                  79
  So - how do we link more than one processor?                    80
  Synchronising the clocks                                        81
  Synchronising the clocks                                        82
  Synchronising the clocks - Slave nodes                          83
  Transferring data                                               84
  Transferring data (Master to Slave)                             85
  Transferring data (Slave to Master)                             86
  Transferring data (Slave to Master)                             87
  Detecting network and node errors                               88
  Detecting errors in the Slave(s)                                89
  Detecting errors in the Master                                  90
  Handling errors detected by the Slave                           91
  Handling errors detected by the Master                          92
  Enter a safe state and shut down the network                    93
  Reset the network                                               94
  Engage a backup Slave                                           95
  Why additional processors may not improve reliability           96
  Redundant networks do not guarantee increased reliability       97
  Replacing the human operator - implications                     98
  Are multi-processor designs ever safe?                          99
  Preparations for the next seminar                              100




                                                                   V
Seminar 4: Linking processors using RS-232 and RS-485 protocols   101
  Review: Shared-clock scheduling                                 102
  Overview of this seminar                                        103
  Review: What is ‘RS-232’?                                       104
  Review: Basic RS-232 Protocol                                   105
  Review: Transferring data to a PC using RS-232                  106
  PATTERN: SCU SCHEDULER (LOCAL)                                  107
  The message structure                                           108
  Determining the required baud rate                              111
  Node Hardware                                                   113
  Network wiring                                                  114
  Overall strengths and weaknesses                                115
  PATTERN: SCU Scheduler (RS-232)                                 116
  PATTERN: SCU Scheduler (RS-485)                                 117
  RS-232 vs RS-485 [number of nodes]                              118
  RS-232 vs RS-485 [range and baud rates]                         119
  RS-232 vs RS-485 [cabling]                                      120
  RS-232 vs RS-485 [transceivers]                                 121
  Software considerations: enable inputs                          122
  Overall strengths and weaknesses                                123
  Example: Network with Max489 transceivers                       124
  Preparations for the next seminar                               125




                                                                   VI
Seminar 5: Linking processors using the Controller Area Network (CAN) bus   127
  Overview of this seminar                                                  128
  PATTERN: SCC Scheduler                                                    129
  What is CAN?                                                              130
  CAN 1.0 vs. CAN 2.0                                                       132
  Basic CAN vs. Full CAN                                                    133
  Which microcontrollers have support for CAN?                              134
  S-C scheduling over CAN                                                   135
  The message structure - Tick messages                                     136
  The message structure - Ack messages                                      137
  Determining the required baud rate                                        138
  Transceivers for distributed networks                                     140
  Node wiring for distributed networks                                      141
  Hardware and wiring for local networks                                    142
  Software for the shared-clock CAN scheduler                               143
  Overall strengths and weaknesses                                          144
  Example: Creating a CAN-based scheduler using the Infineon C515c          145
  Master Software                                                           146
  Slave Software                                                            159
  What about CAN without on-chip hardware support?                          166
  Preparations for the next seminar                                         168




                                                                             VII
Seminar 6: Case study: Intruder alarm system using CAN   169
  Overview of this seminar                               170
  Overview of the required system                        171
  System Operation                                       172
  How many processors?                                   173
  The Controller node                                    174
  Patterns for the Controller node                       175
  The Sensor / Sounder node                              176
  Patterns for the Sensor / Sounder node                 177
  Meeting legal requirements                             178
  Processor decisions                                    179
  Hardware foundation                                    181
  Summary                                                182
  The code: Controller node (List of files)              183
  The code: Controller node (Main.c)                     184
  The code: Controller node (Intruder.c)                 185
  The code: Controller node (Sounder.c)                  197
  The code: Controller node (SCC_m89S53.c)               198
  The code: Sensor / Sounder node (List of files)        212
  The code: Sensor / Sounder node (Main.c)               213
  The code: Sensor / Sounder node (Intruder.c)           214
  The code: Sensor / Sounder node (Sounder.c)            216
  The code: Sensor / Sounder node (SCC_s89S53.c)         218
  Preparations for the next seminar                      228




                                                          VIII
Seminar 7: Processing sequences of analogue values       229
  Overview of this seminar                               230
  PATTERN: One-Shot ADC                                  231
  Using a microcontroller with on-chip ADC               232
  Using an external parallel ADC                         233
  Example: Using a Max150 ADC                            234
  Using an external serial ADC                           235
  Example: Using an external SPI ADC                     236
  Example: Using an external I2C ADC                     237
  Using a current-mode ADC?                              238
  PATTERN: SEQUENTIAL ADC                                239
  Key design stages                                      241
  Sample rate (monitoring and signal proc. apps)         242
  Sample rate (control systems)                          243
  Determining the required bit rate                      244
  Impact on the software architecture                    245
  Example: Using the c515c internal ADC                  247
  PATTERN: ADC PRE-AMP                                   248
  PATTERN: A-A FILTER                                    249
  Example: Speech-recognition system                     250
  Alternative: “Over sampling”                           251
  PATTERN: CURRENT SENSOR                                252
  PWM revisited                                          253
  Software PWM                                           254
  Using Digital-to-Analogue Converters (DACs)            255
  Decisions …                                            256
  General implications for the software architecture     257
  Example: Speech playback using a 12-bit parallel DAC   258
  Example: Digital telephone system                      260
  Preparations for the next seminar                      261




                                                          IX
Seminar 8: Applying “Proportional Integral Differential” (PID) control   263
  Overview of this seminar                                               264
  Why do we need closed-loop control?                                    265
  Closed-loop control                                                    269
  What closed-loop algorithm should you use?                             270
  What is PID control?                                                   271
  A complete PID control implementation                                  272
  Another version                                                        273
  Dealing with ‘windup’                                                  274
  Choosing the controller parameters                                     275
  What sample rate?                                                      276
  Hardware resource implications                                         277
  PID: Overall strengths and weaknesses                                  278
  Why open-loop controllers are still (sometimes) useful                 279
  Limitations of PID control                                             280
  Example: Tuning the parameters of a cruise-control system              281
  Open-loop test                                                         283
  Tuning the PID parameters: methodology                                 284
  First test                                                             285
  Example: DC Motor Speed Control                                        287
  Alternative: Fuzzy control                                             290
  Preparations for the next seminar                                      291




                                                                           X
Seminar 9: Case study: Automotive cruise control using PID and CAN   293
  Overview of this seminar                                           294
  Single-processor system: Overview                                  295
  Single-processor system: Code                                      296
  Multi-processor design: Overview                                   297
  Multi-processor design: Code (PID node)                            298
  Multi-processor design: Code (Speed node)                          299
  Multi-processor design: Code (Throttle node)                       300
  Exploring the impact of network delays                             301
  Example: Impact of network delays on the CCS system                302
  Preparations for the next seminar                                  303




                                                                      XI
Seminar 10: Improving system reliability using watchdog timers    305
  Overview of this seminar                                        306
  The watchdog analogy                                            307
  PATTERN: Watchdog Recovery                                      308
  Choice of hardware                                              309
  Time-based error detection                                      310
  Other uses for watchdog-induced resets                          311
  Recovery behaviour                                              312
  Risk assessment                                                 313
  The limitations of single-processor designs                     314
  Time, time, time …                                              315
  Watchdogs: Overall strengths and weaknesses                     316
  PATTERN: Scheduler Watchdog                                     317
  Selecting the overflow period - “hard” constraints              318
  Selecting the overflow period - “soft” constraints              319
  PATTERN: Program-Flow Watchdog                                  320
  Dealing with errors                                             322
  Hardware resource implications                                  323
  Speeding up the response                                        324
  PATTERN: Reset Recovery                                         326
  PATTERN: Fail-Silent Recovery                                   327
  Example: Fail-Silent behaviour in the Airbus A310               328
  Example: Fail-Silent behaviour in a steer-by-wire application   329
  PATTERN: Limp-Home Recovery                                     330
  Example: Limp-home behaviour in a steer-by-wire application     331
  PATTERN: Oscillator Watchdog                                    334
  Conclusions                                                     336
  Acknowledgements                                                337




                                                                   XII
PES II - 1
A flexible scheduler
for single-processor
  embedded systems

                       1                             40
     Seminar 1:




                            P1.0              VCC
                       2    P1.1             P0.0    39
                       3    P1.2              P0.1   38
                       4                             37




                                                          Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
                            P1.3              P0.2
                       5    P1.4              P0.3   36
                       6    P1.5              P0.4   35




                                                          COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:
                       7    P1.6              P0.5   34
                       8    P1.7              P0.6   33




                                   ‘8051’
                       9    RST               P0.7   32
                       10   P3.0              / EA   31
                       11   P3.1              ALE    30
                       12   P3.2            / PSEN   29
                       13   P3.3              P2.7   28
                       14   P3.4              P2.6   27
                       15   P3.5              P2.5   26
                       16   P3.6              P2.4   25
                       17   P3.7              P2.3   24
                       18   XTL2              P2.2   23
                       19   XTL1              P2.1   22
                       20   VSS               P2.0   21
Overview of this seminar

This introductory seminar will:
• Provide an overview of this course

• Describe the design and implementation of a flexible
    scheduler




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 2
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Overview of this course

This course is primarily concerned with the implementation of
software (and a small amount of hardware) for embedded systems
constructed using more than one microcontroller.

The processors examined in detail will be from the 8051 family.

All programming will be in the ‘C’ language
(using the Keil C51 compiler)




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 3
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
By the end of the course you’ll be able to …

By the end of the course, you will be able to:
1. Design software for multi-processor embedded applications
   based on small, industry standard, microcontrollers;
2. Implement the above designs using a modern, high-level
   programming language (‘C’), and
3. Understand more about the effect that software design and
   programming designs can have on the reliability and safety
   of multi-processor embedded systems.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 4
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Main course text


Throughout this course, we will be making heavy use of this book:


Patterns for time-triggered embedded
systems: Building reliable applications with
the 8051 family of microcontrollers,

by Michael J. Pont (2001)

Addison-Wesley / ACM Press.
[ISBN: 0-201-331381]


For further details, please see:

http://www.engg.le.ac.uk/books/Pont/pttes.htm




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 5
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
IMPORTANT: Course prerequisites


• It is assumed that - before taking this course - you have
    previously completed “Programming Embedded Systems I”
    (or a similar course).

    See:

    www.le.ac.uk/engineering/mjp9/pttesguide.htm




                                                                                                                                                                                                           4V - 6V (battery)


                                                                                     10 µF
                                                                                                                          1       RST                  VCC       20

                                                                                      10 KΩ                               2       P3.0                 P1.7      19

                                                                                                                          3       P3.1                 P1.6      18                 5.5V, 0.3A lamp

                                                                                                                          4                                      17



                                                                                                                                          Atmel 2051
                                                                                                                                  XTL2                 P1.5
                                                                                                                                                                                                              E
                                                                                                     4 MHz
                                                                                                                          5       XTL1                 P1.4      16
                                                                                                                                                                                              B
                                                                                                                          6       P3.2                 P1.3      15                                                 ZTX751

                                                                                                                          7       P3.3                 P1.2      14
                                                                                                                                                                                                               C
                                                                                                                          8       P3.4                 P1.1      13

                                                                                                                          9       P3.5                 P1.0      12

                                                                                                                         10       GND                  P3.7      11
                                                                17
                                                                16
                                                                15
                                                                14
                                                                13
                                                                12
                                                                11
                                                                                                                                                10
                                                                20
                                                                19
                                                                18




                                                                                                                                                7

                                                                                                                                                5
                                                                                                                                                4
                                                                                                                                                3
                                                                                                                                                2
                                                                                                                                                1
                                                                                                                                                6
                                                                                                                                                8
                                                                                                                                                9
                                                                VSS

                                                                       XTL1

                                                                              XTL2

                                                                                     P3.7

                                                                                             P3.6
                                                                                                    P3.5

                                                                                                           P3.4

                                                                                                                  P3.3

                                                                                                                          P3.2

                                                                                                                                   P3.1

                                                                                                                                                P3.0

                                                                                                                                                          RST

                                                                                                                                                                      P1.7

                                                                                                                                                                             P1.6

                                                                                                                                                                                      P1.5
                                                                                                                                                                                             P1.4

                                                                                                                                                                                                    P1.3

                                                                                                                                                                                                             P1.2

                                                                                                                                                                                                                     P1.1

                                                                                                                                                                                                                            P1.0


                                                                                                                                  ‘8051’
                                                                                                                         / PSEN




                                                                                                                                                                                                                     P0.0

                                                                                                                                                                                                                            VCC
                                                                P2.0

                                                                       P2.1

                                                                              P2.2

                                                                                     P2.3

                                                                                            P2.4
                                                                                                    P2.5

                                                                                                           P2.6

                                                                                                                  P2.7




                                                                                                                                                          P0.7

                                                                                                                                                                      P0.6

                                                                                                                                                                             P0.5

                                                                                                                                                                                      P0.4
                                                                                                                                                                                             P0.3

                                                                                                                                                                                                    P0.2

                                                                                                                                                                                                            P0.1
                                                                                                                                   ALE

                                                                                                                                                / EA




                                                                                                                                                34



                                                                                                                                                37
                                                                                                                                                38
                                                                                                                                                39
                                                                24
                                                                25



                                                                28

                                                                30




                                                                                                                                                35
                                                                                                                                                36




                                                                                                                                                40
                                                                26
                                                                27

                                                                29


                                                                                                                                                31
                                                                                                                                                32
                                                                                                                                                33
                                                                21
                                                                22
                                                                23




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                                                                                                                 PES II - 6
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Review: Why use C?

• It is a ‘mid-level’ language, with ‘high-level’ features (such
   as support for functions and modules), and ‘low-level’
   features (such as good access to hardware via pointers);
• It is very efficient;

• It is popular and well understood;

• Even desktop developers who have used only Java or C++
   can soon understand C syntax;
• Good, well-proven compilers are available for every
   embedded processor (8-bit to 32-bit or more);
• Experienced staff are available;

• Books, training courses, code samples and WWW sites
   discussing the use of the language are all widely available.


Overall, C may not be an ideal language for developing embedded
systems, but it is a good choice (and is unlikely that a ‘perfect’ language
will ever be created).




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 7
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Review: The 8051 microcontroller




                               16



                               13
                               17

                               15
                               14

                               12
                               11
                               20

                               18




                                                                                                       10
                               19




                                                                                                       4

                                                                                                       2
                                                                                                       1
                                                                                                       7
                                                                                                       6
                                                                                                       5

                                                                                                       3
                                                                                                       9
                                                                                                       8
                               VSS
                                      XTL1

                                             XTL2
                                                    P3.7

                                                           P3.6
                                                                  P3.5

                                                                         P3.4

                                                                                P3.3
                                                                                        P3.2
                                                                                                P3.1

                                                                                                       P3.0
                                                                                                              RST

                                                                                                                     P1.7
                                                                                                                            P1.6

                                                                                                                                   P1.5
                                                                                                                                          P1.4

                                                                                                                                                 P1.3

                                                                                                                                                        P1.2
                                                                                                                                                               P1.1

                                                                                                                                                                      P1.0
                                                                                                ‘8051’




                                                                                       / PSEN




                                                                                                                                                               P0.0

                                                                                                                                                                      VCC
                               P2.0
                                      P2.1

                                             P2.2
                                                    P2.3
                                                           P2.4
                                                                  P2.5

                                                                         P2.6

                                                                                P2.7




                                                                                                              P0.7

                                                                                                                     P0.6
                                                                                                                            P0.5

                                                                                                                                   P0.4
                                                                                                                                          P0.3

                                                                                                                                                 P0.2

                                                                                                                                                        P0.1
                                                                                                ALE

                                                                                                       / EA




                                                                                                       34



                                                                                                       37
                                                                                                       38
                                                                                                       39
                                                                                                       35
                                                                                                       36




                                                                                                       40
                               24
                               25
                               26
                               27
                               28
                               29
                               30


                                                                                                       32
                                                                                                       33
                                                                                                       31
                               21

                               23
                               22




Typical features of a modern 8051:
• Thirty-two input / output lines.

• Internal data (RAM) memory - 256 bytes.

• Up to 64 kbytes of ROM memory (usually flash)

• Three 16-bit timers / counters

• Nine interrupts (two external) with two priority levels.

• Low-power Idle and Power-down modes.


The different members of the 8051 family are suitable for a huge range
of projects - from automotive and aerospace systems to TV “remotes”.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                                                                                                              PES II - 8
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Review: The “super loop” software architecture

Problem

What is the minimum software environment you need to create an
embedded C program?
Solution

void main(void)
   {
   /* Prepare for Task X */
   X_Init();

    while(1) /* 'for ever' (Super Loop) */
       {
       X(); /* Perform the task */
       }
    }




Crucially, the ‘super loop’, or ‘endless loop’, is required because we
have no operating system to return to: our application will keep looping
until the system power is removed.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 9
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Review: An introduction to schedulers

                    Word Processor
                                                       OS provides ‘common code’ for:
                                                       • Graphics
                   Operating System
                                                       • Printing
                                                       • File storage
                                                       • Sound
                          BIOS
                                                       • ...


                        Hardware




Many embedded systems must carry out tasks at particular instants
of time. More specifically, we have two kinds of activity to
perform:
• Repeated tasks, to be performed (say) once every 100 ms,
    and - less commonly -
• One-shot tasks, to be performed once after a delay of (say)
    50 ms.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                     PES II - 10
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Review: Building a scheduler
void main(void)
   {
   Timer_2_Init();               /* Set up Timer 2 */

    EA = 1;                      /* Globally enable interrupts */

    while(1);                    /* An empty Super Loop */
    }


void Timer_2_Init(void)
   {
   /* Timer 2 is configured as a 16-bit timer,
      which is automatically reloaded when it overflows
      With these setting, timer will overflow every 1 ms */
   T2CON   = 0x04;   /* Load T2 control register */
   T2MOD   = 0x00;   /* Load T2 mode register */

    TH2           =   0xFC;       /*   Load     T2   high byte */
    RCAP2H        =   0xFC;       /*   Load     T2   reload capt. reg. high byte */
    TL2           =   0x18;       /*   Load     T2   low byte */
    RCAP2L        =   0x18;       /*   Load     T2   reload capt. reg. low byte */

    /* Timer 2 interrupt is enabled, and ISR will be called
        whenever the timer overflows - see below. */
    ET2      = 1;

    /* Start Timer 2 running */
    TR2   = 1;
    }


void X(void) interrupt INTERRUPT_Timer_2_Overflow
   {
   /* This ISR is called every 1 ms */
   /* Place required code here... */
   }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                 PES II - 11
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Overview of this seminar

This seminar will consider the design of a very flexible scheduler.


      THE CO-OPERATIVE SCHEDULER
      • A co-operative scheduler provides a single-tasking system architecture
      Operation:
      •   Tasks are scheduled to run at specific times (either on a one-shot or regular basis)
      •   When a task is scheduled to run it is added to the waiting list
      •   When the CPU is free, the next waiting task (if any) is executed
      •   The task runs to completion, then returns control to the scheduler
      Implementation:
      •   The scheduler is simple, and can be implemented in a small amount of code.
      •   The scheduler must allocate memory for only a single task at a time.
      •   The scheduler will generally be written entirely in a high-level language (such as ‘C’).
      •   The scheduler is not a separate application; it becomes part of the developer’s code
      Performance:
      • Obtain rapid responses to external events requires care at the design stage.
      Reliability and safety:
      • Co-operate scheduling is simple, predictable, reliable and safe.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                                      PES II - 12
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The Co-operative Scheduler

A scheduler has the following key components:
• The scheduler data structure.

• An initialisation function.

• A single interrupt service routine (ISR), used to update the
    scheduler at regular time intervals.
• A function for adding tasks to the scheduler.

• A dispatcher function that causes tasks to be executed when
    they are due to run.
• A function for removing tasks from the scheduler (not
    required in all applications).


We will consider each of the required components in turn.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 13
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Overview

/*--------------------------------------------------------*/
void main(void)
   {
   /* Set up the scheduler */
   SCH_Init_T2();

    /* Prepare for the 'Flash_LED' task */
    LED_Flash_Init();

    /* Add the 'Flash LED' task (on for ~1000 ms, off for ~1000 ms)
       Timings are in ticks (1 ms tick interval)
       (Max interval / delay is 65535 ticks) */
    SCH_Add_Task(LED_Flash_Update, 0, 1000);

    /* Start the scheduler */
    SCH_Start();

    while(1)
       {
       SCH_Dispatch_Tasks();
       }
    }

/*--------------------------------------------------------*/
void SCH_Update(void) interrupt INTERRUPT_Timer_2_Overflow
   {
   /* Update the task list */
   ...
   }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 14
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The scheduler data structure and task array


/* Store in DATA area, if possible, for rapid access
   Total memory per task is 7 bytes */
typedef data struct
   {
   /* Pointer to the task (must be a 'void (void)' function) */
   void (code * pTask)(void);

    /* Delay (ticks) until the function will (next) be run
       - see SCH_Add_Task() for further details */
    tWord Delay;

    /* Interval (ticks) between subsequent runs.
       - see SCH_Add_Task() for further details */
    tWord Repeat;

    /* Set to 1 (by scheduler) when task is due to execute */
    tByte RunMe;
    } sTask;



File Sch51.H also includes the constant SCH_MAX_TASKS:
/* The maximum number of tasks required at any one time
   during the execution of the program

   MUST BE ADJUSTED FOR EACH NEW PROJECT */
#define SCH_MAX_TASKS   (1)


Both the sTask data type and the SCH_MAX_TASKS constant are
used to create - in the file Sch51.C - the array of tasks that is
referred to throughout the scheduler:
/* The array of tasks */
sTask SCH_tasks_G[SCH_MAX_TASKS];




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 15
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The size of the task array


You must ensure that the task array is sufficiently large to store the
tasks required in your application, by adjusting the value of
SCH_MAX_TASKS.

For example, if you schedule three tasks as follows:
   SCH_Add_Task(Function_A, 0, 2);
   SCH_Add_Task(Function_B, 1, 10);
   SCH_Add_Task(Function_C, 3, 15);



…then SCH_MAX_TASKS must have a value of 3 (or more) for
correct operation of the scheduler.

Note also that - if this condition is not satisfied, the scheduler will
generate an error code (more on this later).




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 16
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
One possible initialisation function:


/*--------------------------------------------------------*/

void SCH_Init_T2(void)
   {
   tByte i;

    for (i = 0; i < SCH_MAX_TASKS; i++)
       {
       SCH_Delete_Task(i);
       }

    /* SCH_Delete_Task() will generate an error code,
       because the task array is empty.
       -> reset the global error variable. */
    Error_code_G = 0;

    /* Now set up Timer 2
       16-bit timer function with automatic reload

          Crystal is assumed to be 12 MHz
          The Timer 2 resolution is 0.000001 seconds (1 µs)
          The required Timer 2 overflow is 0.001 seconds (1 ms)
          - this takes 1000 timer ticks
          Reload value is 65536 - 1000 = 64536 (dec) = 0xFC18 */

    T2CON = 0x04;              /* Load Timer 2 control register */
    T2MOD = 0x00;              /* Load Timer 2 mode register */

    TH2         =   0xFC;      /*   Load    Timer     2   high byte */
    RCAP2H      =   0xFC;      /*   Load    Timer     2   reload capture reg, high byte */
    TL2         =   0x18;      /*   Load    Timer     2   low byte */
    RCAP2L      =   0x18;      /*   Load    Timer     2   reload capture reg, low byte */

    ET2       = 1;             /* Timer 2 interrupt is enabled */

    TR2       = 1;             /* Start Timer 2 */
    }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                   PES II - 17
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
IMPORTANT:
The ‘one interrupt per microcontroller’ rule!


The scheduler initialisation function enables the generation of interrupts
associated with the overflow of one of the microcontroller timers.

For reasons discussed in Chapter 1 of PTTES, it is assumed
throughout this course that only the ‘tick’ interrupt source is
active: specifically, it is assumed that no other interrupts are
enabled.

If you attempt to use the scheduler code with additional interrupts
enabled, the system cannot be guaranteed to operate at all: at best,
you will generally obtain very unpredictable - and unreliable - system
behaviour.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 18
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The ‘Update’ function

/*--------------------------------------------------------*/
void SCH_Update(void) interrupt INTERRUPT_Timer_2_Overflow
   {
   tByte Index;

    TF2 = 0; /* Have to manually clear this.                              */

    /* NOTE: calculations are in *TICKS* (not milliseconds) */
    for (Index = 0; Index < SCH_MAX_TASKS; Index++)
       {
       /* Check if there is a task at this location */
       if (SCH_tasks_G[Index].pTask)
          {
          if (--SCH_tasks_G[Index].Delay == 0)
             {
             /* The task is due to run */
             SCH_tasks_G[Index].RunMe += 1; /* Inc. 'RunMe' flag */

                   if (SCH_tasks_G[Index].Period)
                      {
                      /* Schedule regular tasks to run again */
                      SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
                      }
                   }
              }
         }
    }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 19
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The ‘Add Task’ function


                                                            Initial_Delay
                                                            the delay (in ticks)
                                                            before task is first
                                                            executed. If set to 0,
                                                            the task is executed
                                                            immediately.


               Sch_Add_Task(Task_Name, Initial_Delay, Task_Interval);

                                 Task_Name                                       Task_Interval
                                 the name of the function                        the interval (in ticks)
                                 (task) that you wish to                         between repeated
                                 schedule                                        executions of the task.
                                                                                 If set to 0, the task is
                                                                                 executed only once.




Examples:
SCH_Add_Task(Do_X,1000,0);

Task_ID = SCH_Add_Task(Do_X,1000,0);

SCH_Add_Task(Do_X,0,1000);



This causes the function Do_X() to be executed regularly, every
1000 scheduler ticks; task will be first executed at T = 300 ticks,
then 1300, 2300, etc:
SCH_Add_Task(Do_X,300,1000);




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                                             PES II - 20
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
/*--------------------------------------------------------*-

   SCH_Add_Task()

   Causes a task (function) to be executed at regular
   intervals, or after a user-defined delay.

-*--------------------------------------------------------*/
tByte SCH_Add_Task(void (code * pFunction)(),
                    const tWord DELAY,
                    const tWord PERIOD)
   {
   tByte Index = 0;

    /* First find a gap in the array (if there is one) */
    while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
       {
       Index++;
       }

    /* Have we reached the end of the list?     */
    if (Index == SCH_MAX_TASKS)
       {
       /* Task list is full
          -> set the global error variable */
       Error_code_G = ERROR_SCH_TOO_MANY_TASKS;

         /* Also return an error code */
         return SCH_MAX_TASKS;
         }

    /* If we're here, there is a space in the task array */
    SCH_tasks_G[Index].pTask = pFunction;

    SCH_tasks_G[Index].Delay = DELAY + 1;
    SCH_tasks_G[Index].Period = PERIOD;

    SCH_tasks_G[Index].RunMe                    = 0;

    return Index; /* return pos. of task (to allow deletion) */
    }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 21
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The ‘Dispatcher’

/*--------------------------------------------------------*-

   SCH_Dispatch_Tasks()

   This is the 'dispatcher' function. When a task (function)
   is due to run, SCH_Dispatch_Tasks() will run it.
   This function must be called (repeatedly) from the main loop.

-*--------------------------------------------------------*/
void SCH_Dispatch_Tasks(void)
   {
   tByte Index;

    /* Dispatches (runs) the next task (if one is ready) */
    for (Index = 0; Index < SCH_MAX_TASKS; Index++)
       {
       if (SCH_tasks_G[Index].RunMe > 0)
          {
          (*SCH_tasks_G[Index].pTask)(); /* Run the task */

              SCH_tasks_G[Index].RunMe -= 1;                        /* Reduce RunMe count */

              /* Periodic tasks will automatically run again
                 - if this is a 'one shot' task, delete it */
              if (SCH_tasks_G[Index].Period == 0)
                 {
                 SCH_Delete_Task(Index);
                 }
              }
         }

    /* Report system status */
    SCH_Report_Status();

    /* The scheduler enters idle mode at this point                            */
    SCH_Go_To_Sleep();
    }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                       PES II - 22
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The dispatcher is the only component in the Super Loop:

/* ----------------------------------------------------- */
void main(void)
   {

    ...

    while(1)
       {
       SCH_Dispatch_Tasks();
       }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 23
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Function arguments

• On desktop systems, function arguments are generally
    passed on the stack using the push and pop assembly
    instructions.
• Since the 8051 has a size limited stack (only 128 bytes at
    best and as low as 64 bytes on some devices), function
    arguments must be passed using a different technique.
• In the case of Keil C51, these arguments are stored in fixed
    memory locations.
• When the linker is invoked, it builds a call tree of the
    program, decides which function arguments are mutually
    exclusive (that is, which functions cannot be called at the
    same time), and overlays these arguments.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 24
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Function pointers and Keil linker options

When we write:
SCH_Add_Task(Do_X,1000,0);

…the first parameter of the ‘Add Task’ function is a pointer to the
function Do_X().

This function pointer is then passed to the Dispatch function and it
is through this function that the task is executed:
if (SCH_tasks_G[Index].RunMe > 0)
   {
   (*SCH_tasks_G[Index].pTask)();                         /* Run the task */




BUT
The linker has difficulty determining the correct call tree when function
pointers are used as arguments.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 25
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
To deal with this situation, you have two realistic options:
1. You can prevent the compiler from using the OVERLAY
   directive by disabling overlays as part of the linker options
   for your project.

      Note that, compared to applications using overlays, you will
      generally require more RAM to run your program.


2. You can tell the linker how to create the correct call tree for
   your application by explicitly providing this information in
   the linker ‘Additional Options’ dialogue box.

      This approach is used in most of the examples in the
      “PTTES” book.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 26
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
void main(void)
   {
   ...

    /* Read the ADC regularly   */
    SCH_Add_Task(AD_Get_Sample, 10, 1000);

    /* Simply display the count here (bargraph display) */
    SCH_Add_Task(BARGRAPH_Update, 12, 1000);

    /* All tasks added: start running the scheduler */
    SCH_Start();




The corresponding OVERLAY directive would take this form:
OVERLAY (main ~ (AD_Get_Sample,Bargraph_Update),
sch_dispatch_tasks ! (AD_Get_Sample,Bargraph_Update))




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 27
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The ‘Start’ function

/*--------------------------------------------------------*/

void SCH_Start(void)
   {
   EA = 1;
   }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 28
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The ‘Delete Task’ function


When tasks are added to the task array, SCH_Add_Task() returns
the position in the task array at which the task has been added:
Task_ID = SCH_Add_Task(Do_X,1000,0);

Sometimes it can be necessary to delete tasks from the array.

You can do so as follows: SCH_Delete_Task(Task_ID);

bit SCH_Delete_Task(const tByte TASK_INDEX)
   {
   bit Return_code;

    if (SCH_tasks_G[TASK_INDEX].pTask == 0)
       {
       /* No task at this location...
          -> set the global error variable */
       Error_code_G = ERROR_SCH_CANNOT_DELETE_TASK;

       /* ...also return an error code */
       Return_code = RETURN_ERROR;
       }
    else
       {
       Return_code = RETURN_NORMAL;
       }

    SCH_tasks_G[TASK_INDEX].pTask                         = 0x0000;
    SCH_tasks_G[TASK_INDEX].Delay                         = 0;
    SCH_tasks_G[TASK_INDEX].Period                        = 0;

    SCH_tasks_G[TASK_INDEX].RunMe                         = 0;

    return Return_code;                         /* return status */
    }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 29
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Reducing power consumption


/*--------------------------------------------------------*/
void SCH_Go_To_Sleep()
   {
   PCON |= 0x01;    /* Enter idle mode (generic 8051 version) */

    /* Entering idle mode requires TWO consecutive instructions
       on 80c515 / 80c505 - to avoid accidental triggering.
       E.g:
       PCON |= 0x01;
       PCON |= 0x20; */
    }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 30
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Reporting errors

/* Used to display the error code */
tByte Error_code_G = 0;


To record an error we include lines such as:
Error_code_G         =   ERROR_SCH_TOO_MANY_TASKS;
Error_code_G         =   ERROR_SCH_WAITING_FOR_SLAVE_TO_ACK;
Error_code_G         =   ERROR_SCH_WAITING_FOR_START_COMMAND_FROM_MASTER;
Error_code_G         =   ERROR_SCH_ONE_OR_MORE_SLAVES_DID_NOT_START;
Error_code_G         =   ERROR_SCH_LOST_SLAVE;
Error_code_G         =   ERROR_SCH_CAN_BUS_ERROR;
Error_code_G         =   ERROR_I2C_WRITE_BYTE_AT24C64;


To report these error code, the scheduler has a function
SCH_Report_Status(), which is called from the Update function.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 31
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
/*--------------------------------------------------------*/

void SCH_Report_Status(void)
   {
#ifdef SCH_REPORT_ERRORS
   /* ONLY APPLIES IF WE ARE REPORTING ERRORS */

    /* Check for a new error code */
    if (Error_code_G != Last_error_code_G)
       {
       /* Negative logic on LEDs assumed */
       Error_port = 255 - Error_code_G;

         Last_error_code_G = Error_code_G;

       if (Error_code_G != 0)
          {
          Error_tick_count_G = 60000;
          }
       else
          {
          Error_tick_count_G = 0;
          }
       }
   else
       {
       if (Error_tick_count_G != 0)
          {
          if (--Error_tick_count_G == 0)
             {
             Error_code_G = 0; /* Reset error code */
             }
          }
       }
#endif
   }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 32
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Note that error reporting may be disabled via the Port.H header
file:
/* Comment next line out if error reporting is NOT required */
/* #define SCH_REPORT_ERRORS */


Where error reporting is required, the port on which error codes will
be displayed is also determined via Port.H:
#ifdef SCH_REPORT_ERRORS
/* The port on which error codes will be displayed
   (ONLY USED IF ERRORS ARE REPORTED) */
#define Error_port P1

#endif

Note that, in this implementation, error codes are reported for
60,000 ticks (1 minute at a 1 ms tick rate).




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 33
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Displaying error codes


                                                                                                                                          Vcc

                        For 25mA LEDs, Rled = 120 Ohms

                                                                    Rled       Rled      Rled      Rled      Rled     Rled      Rled      Rled
                                P2.0 - Pin 8
                                P2.1 - Pin 7
                                P2.2 - Pin 6
                                P2.3 - Pin 5
                                P2.4 - Pin 4
                                P2.5 - Pin 3


                                               ULN2803A
                                P2.6 - Pin 2
                                P2.7 - Pin 1               LED 7       LED 6     LED 5     LED 4     LED 3    LED 2     LED 1     LED 0
                     Port 2
                                                          Pin 11 - LED 0
            8051 Device                                   Pin 12 - LED 1
                                                          Pin 13 - LED 2
                                                          Pin 14 - LED 3
                                                          Pin 15 - LED 4
                                                     9
                                                          Pin 16 - LED 5
                                                          Pin 17 - LED 6
                                                          Pin 18 - LED 7




The forms of error reporting discussed here are low-level in nature and
are primarily intended to assist the developer of the application, or a
qualified service engineer performing system maintenance.

An additional user interface may also be required in your application to
notify the user of errors, in a more user-friendly manner.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                                                                 PES II - 34
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Hardware resource implications

Timer

The scheduler requires one hardware timer. If possible, this should
be a 16-bit timer, with auto-reload capabilities (usually Timer 2).

Memory

This main scheduler memory requirement is 7 bytes of memory per
task.

Most applications require around six tasks or less. Even in a
standard 8051/8052 with 256 bytes of internal memory the total
memory overhead is small.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 35
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
What is the CPU load of the scheduler?




• A scheduler with 1ms ticks

• 12 Mhz, 12 osc / instruction 8051

• One task is being executed.

• The test reveals that the CPU is 86% idle and that the
    maximum possible task duration is therefore approximately
    0.86 ms.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 36
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
A scheduler with 1ms ticks,
running on a 32 Mhz (4 oscillations per instruction) 8051.




• One task is being executed.

• The CPU is 97% idle and that the maximum possible task
    duration is therefore approximately 0.97 ms.




• Twelve tasks are being executed.

• The CPU is 85% idle and that the maximum possible task
    duration is therefore approximately 0.85 ms.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 37
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Determining the required tick interval


In most instances, the simplest way of meeting the needs of the
various task intervals is to allocate a scheduler tick interval of 1 ms.

To keep the scheduler load as low as possible (and to reduce the
power consumption), it can help to use a long tick interval.

If you want to reduce overheads and power consumption to a
minimum, the scheduler tick interval should be set to match the
‘greatest common factor’ of all the task (and offset intervals).




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 38
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Suppose we have three tasks (X,Y,Z), and Task X is to be run every
10 ms, Task Y every 30 ms and Task Z every 25 ms. The scheduler
tick interval needs to be set by determining the relevant factors, as
follows:
• The factors of the Task X interval (10 ms) are: 1 ms, 2ms, 5
    ms, 10 ms.
• Similarly, the factors of the Task Y interval (30 ms) are as
    follows: 1 ms, 2 ms, 3 ms, 5 ms, 6 ms, 10 ms, 15 ms and 30
    ms.
• Finally, the factors of the Task Z interval (25 ms) are as
    follows: 1 ms, 5 ms and 25 ms.


In this case, therefore, the greatest common factor is 5 ms: this is
the required tick interval.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 39
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Guidelines for predictable and reliable scheduling


1. For precise scheduling, the scheduler tick interval should be
   set to match the ‘greatest common factor’ of all the task
   intervals.
2. All tasks should have a duration less than the schedule tick
   interval, to ensure that the dispatcher is always free to call
   any task that is due to execute. Software simulation can
   often be used to measure the task duration.
3. In order to meet Condition 2, all tasks must ‘timeout’ so
   that they cannot block the scheduler under any
   circumstances.
4. The total time required to execute all of the scheduled tasks
   must be less than the available processor time. Of course,
   the total processor time must include both this ‘task time’
   and the ‘scheduler time’ required to execute the scheduler
   update and dispatcher operations.
5. Tasks should be scheduled so that they are never required to
   execute simultaneously: that is, task overlaps should be
   minimised. Note that where all tasks are of a duration much
   less than the scheduler tick interval, and that some task jitter
   can be tolerated, this problem may not be significant.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 40
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Overall strengths and weaknesses of the scheduler


☺ The scheduler is simple, and can be implemented in a small amount of
  code.
☺ The scheduler is written entirely in ‘C’: it is not a separate application,
  but becomes part of the developer’s code
☺ The applications based on the scheduler are inherently predictable,
  safe and reliable.
☺ The scheduler supports team working, since individual tasks can
  often be developed largely independently and then assembled into the
  final system.



     Obtain rapid responses to external events requires care at the design
     stage.
     The tasks cannot safely use interrupts: the only interrupt that should be
     used in the application is the timer-related interrupt that drives the
     scheduler itself.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 41
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Preparations for the next seminar


Please read “PTTES” Chapter 13 and Chapter 14 before the next
seminar.
16



13
17

15
14

12
11
20

18




                                                                        10
19




                                                                        7
                                                                        6
                                                                        5
                                                                        4
                                                                        3
                                                                        2
                                                                        1
                                                                        9
                                                                        8
VSS

       XTL1

              XTL2

                     P3.7

                            P3.6
                                   P3.5

                                          P3.4

                                                 P3.3

                                                         P3.2

                                                                 P3.1

                                                                        P3.0

                                                                               RST

                                                                                      P1.7

                                                                                             P1.6

                                                                                                    P1.5
                                                                                                           P1.4

                                                                                                                  P1.3

                                                                                                                         P1.2

                                                                                                                                P1.1

                                                                                                                                       P1.0




                                                                 ‘8051’
                                                        / PSEN




                                                                                                                                P0.0

                                                                                                                                       VCC
P2.0

       P2.1

              P2.2

                     P2.3

                            P2.4
                                   P2.5

                                          P2.6

                                                 P2.7




                                                                               P0.7

                                                                                      P0.6

                                                                                             P0.5

                                                                                                    P0.4
                                                                                                           P0.3

                                                                                                                  P0.2

                                                                                                                         P0.1
                                                                 ALE

                                                                        / EA




                                                                        34



                                                                        37
                                                                        38
                                                                        39
24
25
26
27
28
29
30


                                                                        32
                                                                        33

                                                                        35
                                                                        36




                                                                        40
21

23




                                                                        31
22




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                                                                               PES II - 42
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Seminar 2:
       A closer look at co-
          operative task
       scheduling (and some
           alternatives)




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 43
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Overview of this seminar

• In this seminar, we’ll review some of the features of the co-
    operative scheduler discussed in Seminar 1.
• We’ll then consider the features of a pre-emptive scheduler

• We’ll go on to develop a hybrid scheduler, which has
    many of the useful features of both co-operative and pre-
    emptive schedulers (but is simpler to build - and generally
    more reliable - than a fully pre-emptive design)
• Finally, we’ll look at a range of different designs for other
    forms of (co-operative) scheduler.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 44
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Review: Co-operative scheduling

      THE CO-OPERATIVE SCHEDULER
      • A co-operative scheduler provides a single-tasking system architecture
      Operation:
      •   Tasks are scheduled to run at specific times (either on a one-shot or regular basis)
      •   When a task is scheduled to run it is added to the waiting list
      •   When the CPU is free, the next waiting task (if any) is executed
      •   The task runs to completion, then returns control to the scheduler
      Implementation:
      •   The scheduler is simple, and can be implemented in a small amount of code.
      •   The scheduler must allocate memory for only a single task at a time.
      •   The scheduler will generally be written entirely in a high-level language (such as ‘C’).
      •   The scheduler is not a separate application; it becomes part of the developer’s code
      Performance:
      • Obtain rapid responses to external events requires care at the design stage.
      Reliability and safety:
      • Co-operate scheduling is simple, predictable, reliable and safe.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                                      PES II - 45
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The pre-emptive scheduler

Overview:


      THE PRE-EMPTIVE SCHEDULER
      • A pre-emptive scheduler provides a multi-tasking system architecture
      Operation:
      • Tasks are scheduled to run at specific times (either on a one-shot or regular basis)
      • When a task is scheduled to run it is added to the waiting list
      • Waiting tasks (if any) are run for a fixed period then - if not completed - are paused and placed back in
        the waiting list. The next waiting task is then run for a fixed period, and so on.
      Implementation:
      • The scheduler is comparatively complicated, not least because features such as semaphores must be
        implemented to avoid conflicts when ‘concurrent’ tasks attempt to access shared resources.
      • The scheduler must allocate memory is to hold all the intermediate states of pre-empted tasks.
      • The scheduler will generally be written (at least in part) in assembly language.
      • The scheduler is generally created as a separate application.
      Performance:
      • Rapid responses to external events can be obtained.
      Reliability and safety:
      • Generally considered to be less predictable, and less reliable, than co-operative approaches.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                                       PES II - 46
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Why do we avoid pre-emptive schedulers in this course?

Various research studies have demonstrated that, compared to pre-
emptive schedulers, co-operative schedulers have a number of
desirable features, particularly for use in safety-related systems.

   “[Pre-emptive] schedules carry greater runtime overheads
   because of the need for context switching - storage and retrieval
   of partially computed results. [Co-operative] algorithms do not
   incur such overheads. Other advantages of [co-operative]
   algorithms include their better understandability, greater
   predictability, ease of testing and their inherent capability for
   guaranteeing exclusive access to any shared resource or data.”.
   Nissanke (1997, p.237)

   “Significant advantages are obtained when using this [co-
   operative] technique. Since the processes are not interruptable,
   poor synchronisation does not give rise to the problem of
   shared data. Shared subroutines can be implemented without
   producing re-entrant code or implementing lock and unlock
   mechanisms”.
   Allworth (1981, p.53-54)

   Compared to pre-emptive alternatives, co-operative schedulers
   have the following advantages: [1] The scheduler is simpler; [2]
   The overheads are reduced; [3] Testing is easier; [4]
   Certification authorities tend to support this form of scheduling.
   Bate (2000)

                                                                               [See PTTES, Chapter 13]



COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                          PES II - 47
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Why is a co-operative scheduler (generally) more reliable?

• The key reason why the co-operative schedulers are both
    reliable and predictable is that only one task is active at any
    point in time: this task runs to completion, and then returns
    control to the scheduler.
• Contrast this with the situation in a fully pre-emptive system
    with more than one active task.
• Suppose one task in such a system which is reading from a
    port, and the scheduler performs a ‘context switch’, causing
    a different task to access the same port: under these
    circumstances, unless we take action to prevent it, data may
    be lost or corrupted.


This problem arises frequently in multi-tasking environments where
we have what are known as ‘critical sections’ of code.

Such critical sections are code areas that - once started - must be
allowed to run to completion without interruption.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 48
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Critical sections of code

Examples of critical sections include:
• Code which modifies or reads variables, particularly global
    variables used for inter-task communication. In general, this
    is the most common form of critical section, since inter-task
    communication is often a key requirement.
• Code which interfaces to hardware, such as ports, analogue-
    to-digital converters (ADCs), and so on. What happens, for
    example, if the same ADC is used simultaneously by more
    than one task?
• Code which calls common functions. What happens, for
    example, if the same function is called simultaneously by
    more than one task?


In a co-operative system, problems with critical sections do not arise,
since only one task is ever active at the same time.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 49
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
How do we deal with critical sections in a pre-emptive
system?

To deal with such critical sections of code in a pre-emptive system,
we have two main possibilities:
• ‘Pause’ the scheduling by disabling the scheduler interrupt
    before beginning the critical section; re-enable the scheduler
    interrupt when we leave the critical section, or;
• Use a ‘lock’ (or some other form of ‘semaphore
    mechanism’) to achieve a similar result.


The first solution can be implemented as follows:
• When Task A (say) starts accessing the shared resource (say
    Port X), we disable the scheduler.
• This solves the immediate problem since Task A will be
    allowed to run without interruption until it has finished with
    Port X.
• However, this ‘solution’ is less than perfect. For one thing,
    by disabling the scheduler, we will no longer be keeping
    track of the elapsed time and all timing functions will begin
    to drift - in this case by a period up to the duration of Task A
    every time we access Port X. This is not acceptable in most
    applications.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 50
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Building a “lock” mechanism

The use of locks is a better solution.

Before entering the critical section of code, we ‘lock’ the associated
resource; when we have finished with the resource we ‘unlock’ it.
While locked, no other process may enter the critical section.

This is one way we might try to achieve this:
    1. Task A checks the ‘lock’ for Port X it wishes to access.
    2. If the section is locked, Task A waits.
    3. When the port is unlocked, Task A sets the lock and then uses
       the port.
    4. When Task A has finished with the port, it leaves the critical
       section and unlocks the port.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 51
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Implementing this algorithm in code also seems straightforward:
     #define UNLOCKED       0
     #define LOCKED         1

     bit Lock;    // Global lock flag

     // ...

     // Ready to enter critical section
     // - Wait for lock to become clear
     // (FOR SIMPLICITY, NO TIMEOUT CAPABILITY IS SHOWN)
     while(Lock == LOCKED);

     // Lock is clear
     // Enter critical section
                                                    A
     // Set the lock
     Lock = LOCKED;

     // CRITICAL CODE HERE //

     // Ready to leave critical section
     // Release the lock
     Lock = UNLOCKED;

     // ...




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 52
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
However, the above code cannot be guaranteed to work correctly
under all circumstances.

Consider the part of the code labelled ‘A’. If our system is fully
pre-emptive, then our task can reach this point at the same time as
the scheduler performs a context switch and allows (say) Task B
access to the CPU. If Task Y also wants to access the Port X, we
can then have a situation as follows:
• Task A has checked the lock for Port X and found that the
    port is available; Task A has, however, not yet changed the
    lock flag.
• Task B is then ‘switched in’. Task B checks the lock flag
    and it is still clear. Task B sets the lock flag and begins to
    use Port X.
• Task A is ‘switched in’ again. As far as Task A is
    concerned, the port is not locked; this task therefore sets the
    flag, and starts to use the port, unaware that Task B is
    already doing so.
• …


As we can see, this simple lock code violates the principal of
mutual exclusion: that is, it allows more than one task to access a
critical code section. The problem arises because it is possible for
the context switch to occur after a task has checked the lock flag but
before the task changes the lock flag. In other words, the lock
‘check and set code’ (designed to control access to a critical
section of code), is itself a critical section.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 53
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
• This problem can be solved.

• For example, because it takes little time to ‘check and set’
    the lock code, we can disable interrupts for this period.
• However, this is not in itself a complete solution: because
    there is a chance that an interrupt may have occurred even in
    the short period of ‘check and set’, we then need to check
    the relevant interrupt flag(s) and - if necessary - call the
    relevant ISR(s). This can be done, but it adds substantially
    to the complexity of the operating environment.


Even if we build a working lock mechanism, this is only a partial solution
to the problems caused by multi-tasking. If the purpose of Task A is to
read from an ADC, and Task B has locked the ADC when the Task A is
invoked, then Task A cannot carry out its required activity. Use of locks
(or any other mechanism), can prevent the system from crashing, but
cannot allow two tasks to have access to the ADC simultaneously.

When using a co-operative scheduler, such problems do not arise.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 54
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The “best of both worlds” - a hybrid scheduler

      THE HYBRID SCHEDULER
      • A hybrid scheduler provides limited multi-tasking capabilities
      Operation:
      • Supports any number of co-operatively-scheduled tasks
      • Supports a single pre-emptive task (which can interrupt the co-operative tasks)
      Implementation:
      •   The scheduler is simple, and can be implemented in a small amount of code.
      •   The scheduler must allocate memory for - at most - two tasks at a time.
      •   The scheduler will generally be written entirely in a high-level language (such as ‘C’).
      •   The scheduler is not a separate application; it becomes part of the developer’s code
      Performance:
      • Rapid responses to external events can be obtained.
      Reliability and safety:
      • With careful design, can be as reliable as a (pure) co-operative scheduler.




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                                      PES II - 55
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
Creating a hybrid scheduler

The ‘update’ function from a co-operative scheduler:
void SCH_Update(void) interrupt INTERRUPT_Timer_2_Overflow
   {
   tByte Index;

    TF2 = 0; /* Have to manually clear this.                              */

    /* NOTE: calculations are in *TICKS* (not milliseconds) */
    for (Index = 0; Index < SCH_MAX_TASKS; Index++)
       {
       /* Check if there is a task at this location */
       if (SCH_tasks_G[Index].Task_p)
          {
          if (--SCH_tasks_G[Index].Delay == 0)
             {
             /* The task is due to run */
             SCH_tasks_G[Index].RunMe += 1; /* Inc. RunMe */

                   if (SCH_tasks_G[Index].Period)
                      {
                      /* Schedule periodic tasks to run again */
                      SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
                      }
                   }
              }
         }
    }




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 56
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
The co-operative version assumes a scheduler data type as follows:
/* Store in DATA area, if possible, for rapid access
   [Total memory per task is 7 bytes] */
typedef data struct
   {
   /* Pointer to the task (must be a 'void (void)' function) */
   void (code * Task_p)(void);

    /* Delay (ticks) until the function will (next) be run
       - see SCH_Add_Task() for further details */
    tWord Delay;

    /* Interval (ticks) between subsequent runs.
       - see SCH_Add_Task() for further details */
    tWord Period;

    /* Set to 1 (by scheduler) when task is due to execute */
    tByte RunMe;
    } sTask;




COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from:                PES II - 57
Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems
C Programming Course for Embedded Systems

Mais conteúdo relacionado

Destaque

training_presentation
training_presentationtraining_presentation
training_presentationAniket Pawar
 
Epoxy flux a low cost high reliability approach for pop assembly-imaps 2011
Epoxy flux  a low cost high reliability approach for pop assembly-imaps 2011Epoxy flux  a low cost high reliability approach for pop assembly-imaps 2011
Epoxy flux a low cost high reliability approach for pop assembly-imaps 2011nclee715
 
New Algorithms to Improve X-Ray Inspection
New Algorithms to Improve X-Ray InspectionNew Algorithms to Improve X-Ray Inspection
New Algorithms to Improve X-Ray InspectionBill Cardoso
 
A solder joint reliability model for the philips lumileds luxeon rebel led c...
A solder joint reliability model for the philips lumileds luxeon rebel led  c...A solder joint reliability model for the philips lumileds luxeon rebel led  c...
A solder joint reliability model for the philips lumileds luxeon rebel led c...Greg Caswell
 
Managing input and output operation in c
Managing input and output operation in cManaging input and output operation in c
Managing input and output operation in cyazad dumasia
 
Mesics lecture 4 c operators and experssions
Mesics lecture  4   c operators and experssionsMesics lecture  4   c operators and experssions
Mesics lecture 4 c operators and experssionseShikshak
 
Mesics lecture 5 input – output in ‘c’
Mesics lecture 5   input – output in ‘c’Mesics lecture 5   input – output in ‘c’
Mesics lecture 5 input – output in ‘c’eShikshak
 
Smt notes
Smt notesSmt notes
Smt notesabishus
 
Prerna sharma
Prerna sharmaPrerna sharma
Prerna sharmaRCET
 
LED, BGA, and QFN assembly and inspection case studies
LED, BGA, and QFN assembly and inspection case studiesLED, BGA, and QFN assembly and inspection case studies
LED, BGA, and QFN assembly and inspection case studiesBill Cardoso
 
Micro controller based projects
Micro controller based projectsMicro controller based projects
Micro controller based projectsFajar Isnanto
 
Chapter13 pcb design
Chapter13 pcb designChapter13 pcb design
Chapter13 pcb designVin Voro
 

Destaque (16)

training_presentation
training_presentationtraining_presentation
training_presentation
 
Epoxy flux a low cost high reliability approach for pop assembly-imaps 2011
Epoxy flux  a low cost high reliability approach for pop assembly-imaps 2011Epoxy flux  a low cost high reliability approach for pop assembly-imaps 2011
Epoxy flux a low cost high reliability approach for pop assembly-imaps 2011
 
New Algorithms to Improve X-Ray Inspection
New Algorithms to Improve X-Ray InspectionNew Algorithms to Improve X-Ray Inspection
New Algorithms to Improve X-Ray Inspection
 
PIC_ARM_AVR
PIC_ARM_AVRPIC_ARM_AVR
PIC_ARM_AVR
 
A solder joint reliability model for the philips lumileds luxeon rebel led c...
A solder joint reliability model for the philips lumileds luxeon rebel led  c...A solder joint reliability model for the philips lumileds luxeon rebel led  c...
A solder joint reliability model for the philips lumileds luxeon rebel led c...
 
Managing input and output operation in c
Managing input and output operation in cManaging input and output operation in c
Managing input and output operation in c
 
Basic Input and Output
Basic Input and OutputBasic Input and Output
Basic Input and Output
 
Mesics lecture 4 c operators and experssions
Mesics lecture  4   c operators and experssionsMesics lecture  4   c operators and experssions
Mesics lecture 4 c operators and experssions
 
Mesics lecture 5 input – output in ‘c’
Mesics lecture 5   input – output in ‘c’Mesics lecture 5   input – output in ‘c’
Mesics lecture 5 input – output in ‘c’
 
Embedded system
Embedded systemEmbedded system
Embedded system
 
Smt notes
Smt notesSmt notes
Smt notes
 
Prerna sharma
Prerna sharmaPrerna sharma
Prerna sharma
 
LED, BGA, and QFN assembly and inspection case studies
LED, BGA, and QFN assembly and inspection case studiesLED, BGA, and QFN assembly and inspection case studies
LED, BGA, and QFN assembly and inspection case studies
 
Micro controller based projects
Micro controller based projectsMicro controller based projects
Micro controller based projects
 
Chapter13 pcb design
Chapter13 pcb designChapter13 pcb design
Chapter13 pcb design
 
Book ppt
Book pptBook ppt
Book ppt
 

Semelhante a C Programming Course for Embedded Systems

IJERD (www.ijerd.com) International Journal of Engineering Research and Devel...
IJERD (www.ijerd.com) International Journal of Engineering Research and Devel...IJERD (www.ijerd.com) International Journal of Engineering Research and Devel...
IJERD (www.ijerd.com) International Journal of Engineering Research and Devel...IJERD Editor
 
8051 smd kit_manual
8051 smd kit_manual8051 smd kit_manual
8051 smd kit_manualanishgoel
 
Dt user guide_sv8100
Dt user guide_sv8100Dt user guide_sv8100
Dt user guide_sv8100daviscontrols
 
Ei502microprocessorsmicrtocontrollerspart4 8051 Microcontroller
Ei502microprocessorsmicrtocontrollerspart4 8051 MicrocontrollerEi502microprocessorsmicrtocontrollerspart4 8051 Microcontroller
Ei502microprocessorsmicrtocontrollerspart4 8051 MicrocontrollerDebasis Das
 
GPQS Eclipse An Introduction
GPQS Eclipse An IntroductionGPQS Eclipse An Introduction
GPQS Eclipse An IntroductionColin Ritchie
 
14157565 embedded-programming
14157565 embedded-programming14157565 embedded-programming
14157565 embedded-programmingPRADEEP
 
Testo - Stationary measurement compressed air
Testo - Stationary measurement compressed airTesto - Stationary measurement compressed air
Testo - Stationary measurement compressed airTesto Limited
 
AutomatingManufacturingSystemsWithPLCs.pdf
AutomatingManufacturingSystemsWithPLCs.pdfAutomatingManufacturingSystemsWithPLCs.pdf
AutomatingManufacturingSystemsWithPLCs.pdfMahamad Jawhar
 
EDEN - Pps6 Eden Project Description
EDEN - Pps6 Eden Project DescriptionEDEN - Pps6 Eden Project Description
EDEN - Pps6 Eden Project Descriptionh2portugal
 
Automatización de sistemas de fabricación con PLC.pdf
Automatización de sistemas de fabricación con PLC.pdfAutomatización de sistemas de fabricación con PLC.pdf
Automatización de sistemas de fabricación con PLC.pdfSANTIAGO PABLO ALBERTO
 
2008 Cleantech VC Investing Report
2008 Cleantech VC Investing Report2008 Cleantech VC Investing Report
2008 Cleantech VC Investing ReportJohnBalbach
 
Pic16f877a microcontroller based projects list _ PIC Microcontroller.pdf
Pic16f877a microcontroller based projects list _ PIC Microcontroller.pdfPic16f877a microcontroller based projects list _ PIC Microcontroller.pdf
Pic16f877a microcontroller based projects list _ PIC Microcontroller.pdfIsmailkhan77481
 
Pic microcontrollers for_beginners
Pic microcontrollers for_beginnersPic microcontrollers for_beginners
Pic microcontrollers for_beginnersPraveen Chary
 

Semelhante a C Programming Course for Embedded Systems (20)

Atmel
AtmelAtmel
Atmel
 
At89s8252
At89s8252At89s8252
At89s8252
 
IJERD (www.ijerd.com) International Journal of Engineering Research and Devel...
IJERD (www.ijerd.com) International Journal of Engineering Research and Devel...IJERD (www.ijerd.com) International Journal of Engineering Research and Devel...
IJERD (www.ijerd.com) International Journal of Engineering Research and Devel...
 
8051 MICROCONTROLLER
8051 MICROCONTROLLER 8051 MICROCONTROLLER
8051 MICROCONTROLLER
 
8051 smd kit_manual
8051 smd kit_manual8051 smd kit_manual
8051 smd kit_manual
 
Dt user guide_sv8100
Dt user guide_sv8100Dt user guide_sv8100
Dt user guide_sv8100
 
Ei502microprocessorsmicrtocontrollerspart4 8051 Microcontroller
Ei502microprocessorsmicrtocontrollerspart4 8051 MicrocontrollerEi502microprocessorsmicrtocontrollerspart4 8051 Microcontroller
Ei502microprocessorsmicrtocontrollerspart4 8051 Microcontroller
 
GPQS Eclipse An Introduction
GPQS Eclipse An IntroductionGPQS Eclipse An Introduction
GPQS Eclipse An Introduction
 
14157565 embedded-programming
14157565 embedded-programming14157565 embedded-programming
14157565 embedded-programming
 
Scm branching diagram
Scm branching diagramScm branching diagram
Scm branching diagram
 
Integratedbook
IntegratedbookIntegratedbook
Integratedbook
 
Testo - Stationary measurement compressed air
Testo - Stationary measurement compressed airTesto - Stationary measurement compressed air
Testo - Stationary measurement compressed air
 
At89c51 datasheet
At89c51 datasheetAt89c51 datasheet
At89c51 datasheet
 
AutomatingManufacturingSystemsWithPLCs.pdf
AutomatingManufacturingSystemsWithPLCs.pdfAutomatingManufacturingSystemsWithPLCs.pdf
AutomatingManufacturingSystemsWithPLCs.pdf
 
EDEN - Pps6 Eden Project Description
EDEN - Pps6 Eden Project DescriptionEDEN - Pps6 Eden Project Description
EDEN - Pps6 Eden Project Description
 
Automatización de sistemas de fabricación con PLC.pdf
Automatización de sistemas de fabricación con PLC.pdfAutomatización de sistemas de fabricación con PLC.pdf
Automatización de sistemas de fabricación con PLC.pdf
 
2008 Cleantech VC Investing Report
2008 Cleantech VC Investing Report2008 Cleantech VC Investing Report
2008 Cleantech VC Investing Report
 
Libro ilustrate dstevens tcpip
Libro ilustrate dstevens tcpipLibro ilustrate dstevens tcpip
Libro ilustrate dstevens tcpip
 
Pic16f877a microcontroller based projects list _ PIC Microcontroller.pdf
Pic16f877a microcontroller based projects list _ PIC Microcontroller.pdfPic16f877a microcontroller based projects list _ PIC Microcontroller.pdf
Pic16f877a microcontroller based projects list _ PIC Microcontroller.pdf
 
Pic microcontrollers for_beginners
Pic microcontrollers for_beginnersPic microcontrollers for_beginners
Pic microcontrollers for_beginners
 

Último

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 

Último (20)

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 

C Programming Course for Embedded Systems

  • 1. I [v1.1] University of Leicester Michael J. Pont A 10-week course, using C Programming Systems II Embedded 1 P1.0 VCC 40 2 P1.1 P0.0 39 3 P1.2 P0.1 38 4 P1.3 P0.2 37 5 P1.4 P0.3 36 6 P1.5 P0.4 35 7 P1.6 P0.5 34 8 P1.7 P0.6 33 ‘8051’ 9 RST P0.7 32 10 P3.0 / EA 31 11 P3.1 ALE 30 12 P3.2 / PSEN 29 13 P3.3 P2.7 28 14 P3.4 P2.6 27 15 P3.5 P2.5 26 16 P3.6 P2.4 25 17 P3.7 P2.3 24 18 XTL2 P2.2 23 19 XTL1 P2.1 22 20 VSS P2.0 21
  • 2. Copyright © Michael J. Pont, 2002-2003 This document may be freely distributed and copied, provided that copyright notice at the foot of each OHP page is clearly visible in all copies. II
  • 3. Seminar 1: A flexible scheduler for single-processor embedded systems 1 Overview of this seminar 2 Overview of this course 3 By the end of the course you’ll be able to … 4 Main course text 5 IMPORTANT: Course prerequisites 6 Review: Why use C? 7 Review: The 8051 microcontroller 8 Review: The “super loop” software architecture 9 Review: An introduction to schedulers 10 Review: Building a scheduler 11 Overview of this seminar 12 The Co-operative Scheduler 13 Overview 14 The scheduler data structure and task array 15 The size of the task array 16 One possible initialisation function: 17 IMPORTANT: The ‘one interrupt per microcontroller’ rule! 18 The ‘Update’ function 19 The ‘Add Task’ function 20 The ‘Dispatcher’ 22 Function arguments 24 Function pointers and Keil linker options 25 The ‘Start’ function 28 The ‘Delete Task’ function 29 Reducing power consumption 30 Reporting errors 31 Displaying error codes 34 Hardware resource implications 35 What is the CPU load of the scheduler? 36 Determining the required tick interval 38 Guidelines for predictable and reliable scheduling 40 Overall strengths and weaknesses of the scheduler 41 Preparations for the next seminar 42 III
  • 4. Seminar 2: A closer look at co-operative task scheduling (and some alternatives) 43 Overview of this seminar 44 Review: Co-operative scheduling 45 The pre-emptive scheduler 46 Why do we avoid pre-emptive schedulers in this course? 47 Why is a co-operative scheduler (generally) more reliable? 48 Critical sections of code 49 How do we deal with critical sections in a pre-emptive system? 50 Building a “lock” mechanism 51 The “best of both worlds” - a hybrid scheduler 55 Creating a hybrid scheduler 56 The ‘Update’ function for a hybrid scheduler. 58 Reliability and safety issues 61 The safest way to use the hybrid scheduler 63 Other forms of co-operative scheduler 65 PATTERN: 255-TICK SCHEDULER 66 PATTERN: ONE-TASK SCHEDULER 67 PATTERN: ONE-YEAR SCHEDULER 68 PATTERN: STABLE SCHEDULER 69 Mix and match … 70 Preparations for the next seminar 71 IV
  • 5. Seminar 3: Shared-clock schedulers for multi-processor systems 73 Overview of this seminar 74 Why use more than one processor? 75 Additional CPU performance and hardware facilities 76 The benefits of modular design 78 The benefits of modular design 79 So - how do we link more than one processor? 80 Synchronising the clocks 81 Synchronising the clocks 82 Synchronising the clocks - Slave nodes 83 Transferring data 84 Transferring data (Master to Slave) 85 Transferring data (Slave to Master) 86 Transferring data (Slave to Master) 87 Detecting network and node errors 88 Detecting errors in the Slave(s) 89 Detecting errors in the Master 90 Handling errors detected by the Slave 91 Handling errors detected by the Master 92 Enter a safe state and shut down the network 93 Reset the network 94 Engage a backup Slave 95 Why additional processors may not improve reliability 96 Redundant networks do not guarantee increased reliability 97 Replacing the human operator - implications 98 Are multi-processor designs ever safe? 99 Preparations for the next seminar 100 V
  • 6. Seminar 4: Linking processors using RS-232 and RS-485 protocols 101 Review: Shared-clock scheduling 102 Overview of this seminar 103 Review: What is ‘RS-232’? 104 Review: Basic RS-232 Protocol 105 Review: Transferring data to a PC using RS-232 106 PATTERN: SCU SCHEDULER (LOCAL) 107 The message structure 108 Determining the required baud rate 111 Node Hardware 113 Network wiring 114 Overall strengths and weaknesses 115 PATTERN: SCU Scheduler (RS-232) 116 PATTERN: SCU Scheduler (RS-485) 117 RS-232 vs RS-485 [number of nodes] 118 RS-232 vs RS-485 [range and baud rates] 119 RS-232 vs RS-485 [cabling] 120 RS-232 vs RS-485 [transceivers] 121 Software considerations: enable inputs 122 Overall strengths and weaknesses 123 Example: Network with Max489 transceivers 124 Preparations for the next seminar 125 VI
  • 7. Seminar 5: Linking processors using the Controller Area Network (CAN) bus 127 Overview of this seminar 128 PATTERN: SCC Scheduler 129 What is CAN? 130 CAN 1.0 vs. CAN 2.0 132 Basic CAN vs. Full CAN 133 Which microcontrollers have support for CAN? 134 S-C scheduling over CAN 135 The message structure - Tick messages 136 The message structure - Ack messages 137 Determining the required baud rate 138 Transceivers for distributed networks 140 Node wiring for distributed networks 141 Hardware and wiring for local networks 142 Software for the shared-clock CAN scheduler 143 Overall strengths and weaknesses 144 Example: Creating a CAN-based scheduler using the Infineon C515c 145 Master Software 146 Slave Software 159 What about CAN without on-chip hardware support? 166 Preparations for the next seminar 168 VII
  • 8. Seminar 6: Case study: Intruder alarm system using CAN 169 Overview of this seminar 170 Overview of the required system 171 System Operation 172 How many processors? 173 The Controller node 174 Patterns for the Controller node 175 The Sensor / Sounder node 176 Patterns for the Sensor / Sounder node 177 Meeting legal requirements 178 Processor decisions 179 Hardware foundation 181 Summary 182 The code: Controller node (List of files) 183 The code: Controller node (Main.c) 184 The code: Controller node (Intruder.c) 185 The code: Controller node (Sounder.c) 197 The code: Controller node (SCC_m89S53.c) 198 The code: Sensor / Sounder node (List of files) 212 The code: Sensor / Sounder node (Main.c) 213 The code: Sensor / Sounder node (Intruder.c) 214 The code: Sensor / Sounder node (Sounder.c) 216 The code: Sensor / Sounder node (SCC_s89S53.c) 218 Preparations for the next seminar 228 VIII
  • 9. Seminar 7: Processing sequences of analogue values 229 Overview of this seminar 230 PATTERN: One-Shot ADC 231 Using a microcontroller with on-chip ADC 232 Using an external parallel ADC 233 Example: Using a Max150 ADC 234 Using an external serial ADC 235 Example: Using an external SPI ADC 236 Example: Using an external I2C ADC 237 Using a current-mode ADC? 238 PATTERN: SEQUENTIAL ADC 239 Key design stages 241 Sample rate (monitoring and signal proc. apps) 242 Sample rate (control systems) 243 Determining the required bit rate 244 Impact on the software architecture 245 Example: Using the c515c internal ADC 247 PATTERN: ADC PRE-AMP 248 PATTERN: A-A FILTER 249 Example: Speech-recognition system 250 Alternative: “Over sampling” 251 PATTERN: CURRENT SENSOR 252 PWM revisited 253 Software PWM 254 Using Digital-to-Analogue Converters (DACs) 255 Decisions … 256 General implications for the software architecture 257 Example: Speech playback using a 12-bit parallel DAC 258 Example: Digital telephone system 260 Preparations for the next seminar 261 IX
  • 10. Seminar 8: Applying “Proportional Integral Differential” (PID) control 263 Overview of this seminar 264 Why do we need closed-loop control? 265 Closed-loop control 269 What closed-loop algorithm should you use? 270 What is PID control? 271 A complete PID control implementation 272 Another version 273 Dealing with ‘windup’ 274 Choosing the controller parameters 275 What sample rate? 276 Hardware resource implications 277 PID: Overall strengths and weaknesses 278 Why open-loop controllers are still (sometimes) useful 279 Limitations of PID control 280 Example: Tuning the parameters of a cruise-control system 281 Open-loop test 283 Tuning the PID parameters: methodology 284 First test 285 Example: DC Motor Speed Control 287 Alternative: Fuzzy control 290 Preparations for the next seminar 291 X
  • 11. Seminar 9: Case study: Automotive cruise control using PID and CAN 293 Overview of this seminar 294 Single-processor system: Overview 295 Single-processor system: Code 296 Multi-processor design: Overview 297 Multi-processor design: Code (PID node) 298 Multi-processor design: Code (Speed node) 299 Multi-processor design: Code (Throttle node) 300 Exploring the impact of network delays 301 Example: Impact of network delays on the CCS system 302 Preparations for the next seminar 303 XI
  • 12. Seminar 10: Improving system reliability using watchdog timers 305 Overview of this seminar 306 The watchdog analogy 307 PATTERN: Watchdog Recovery 308 Choice of hardware 309 Time-based error detection 310 Other uses for watchdog-induced resets 311 Recovery behaviour 312 Risk assessment 313 The limitations of single-processor designs 314 Time, time, time … 315 Watchdogs: Overall strengths and weaknesses 316 PATTERN: Scheduler Watchdog 317 Selecting the overflow period - “hard” constraints 318 Selecting the overflow period - “soft” constraints 319 PATTERN: Program-Flow Watchdog 320 Dealing with errors 322 Hardware resource implications 323 Speeding up the response 324 PATTERN: Reset Recovery 326 PATTERN: Fail-Silent Recovery 327 Example: Fail-Silent behaviour in the Airbus A310 328 Example: Fail-Silent behaviour in a steer-by-wire application 329 PATTERN: Limp-Home Recovery 330 Example: Limp-home behaviour in a steer-by-wire application 331 PATTERN: Oscillator Watchdog 334 Conclusions 336 Acknowledgements 337 XII
  • 13. PES II - 1 A flexible scheduler for single-processor embedded systems 1 40 Seminar 1: P1.0 VCC 2 P1.1 P0.0 39 3 P1.2 P0.1 38 4 37 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley. P1.3 P0.2 5 P1.4 P0.3 36 6 P1.5 P0.4 35 COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: 7 P1.6 P0.5 34 8 P1.7 P0.6 33 ‘8051’ 9 RST P0.7 32 10 P3.0 / EA 31 11 P3.1 ALE 30 12 P3.2 / PSEN 29 13 P3.3 P2.7 28 14 P3.4 P2.6 27 15 P3.5 P2.5 26 16 P3.6 P2.4 25 17 P3.7 P2.3 24 18 XTL2 P2.2 23 19 XTL1 P2.1 22 20 VSS P2.0 21
  • 14. Overview of this seminar This introductory seminar will: • Provide an overview of this course • Describe the design and implementation of a flexible scheduler COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 2 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 15. Overview of this course This course is primarily concerned with the implementation of software (and a small amount of hardware) for embedded systems constructed using more than one microcontroller. The processors examined in detail will be from the 8051 family. All programming will be in the ‘C’ language (using the Keil C51 compiler) COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 3 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 16. By the end of the course you’ll be able to … By the end of the course, you will be able to: 1. Design software for multi-processor embedded applications based on small, industry standard, microcontrollers; 2. Implement the above designs using a modern, high-level programming language (‘C’), and 3. Understand more about the effect that software design and programming designs can have on the reliability and safety of multi-processor embedded systems. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 4 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 17. Main course text Throughout this course, we will be making heavy use of this book: Patterns for time-triggered embedded systems: Building reliable applications with the 8051 family of microcontrollers, by Michael J. Pont (2001) Addison-Wesley / ACM Press. [ISBN: 0-201-331381] For further details, please see: http://www.engg.le.ac.uk/books/Pont/pttes.htm COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 5 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 18. IMPORTANT: Course prerequisites • It is assumed that - before taking this course - you have previously completed “Programming Embedded Systems I” (or a similar course). See: www.le.ac.uk/engineering/mjp9/pttesguide.htm 4V - 6V (battery) 10 µF 1 RST VCC 20 10 KΩ 2 P3.0 P1.7 19 3 P3.1 P1.6 18 5.5V, 0.3A lamp 4 17 Atmel 2051 XTL2 P1.5 E 4 MHz 5 XTL1 P1.4 16 B 6 P3.2 P1.3 15 ZTX751 7 P3.3 P1.2 14 C 8 P3.4 P1.1 13 9 P3.5 P1.0 12 10 GND P3.7 11 17 16 15 14 13 12 11 10 20 19 18 7 5 4 3 2 1 6 8 9 VSS XTL1 XTL2 P3.7 P3.6 P3.5 P3.4 P3.3 P3.2 P3.1 P3.0 RST P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 ‘8051’ / PSEN P0.0 VCC P2.0 P2.1 P2.2 P2.3 P2.4 P2.5 P2.6 P2.7 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 ALE / EA 34 37 38 39 24 25 28 30 35 36 40 26 27 29 31 32 33 21 22 23 COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 6 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 19. Review: Why use C? • It is a ‘mid-level’ language, with ‘high-level’ features (such as support for functions and modules), and ‘low-level’ features (such as good access to hardware via pointers); • It is very efficient; • It is popular and well understood; • Even desktop developers who have used only Java or C++ can soon understand C syntax; • Good, well-proven compilers are available for every embedded processor (8-bit to 32-bit or more); • Experienced staff are available; • Books, training courses, code samples and WWW sites discussing the use of the language are all widely available. Overall, C may not be an ideal language for developing embedded systems, but it is a good choice (and is unlikely that a ‘perfect’ language will ever be created). COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 7 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 20. Review: The 8051 microcontroller 16 13 17 15 14 12 11 20 18 10 19 4 2 1 7 6 5 3 9 8 VSS XTL1 XTL2 P3.7 P3.6 P3.5 P3.4 P3.3 P3.2 P3.1 P3.0 RST P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 ‘8051’ / PSEN P0.0 VCC P2.0 P2.1 P2.2 P2.3 P2.4 P2.5 P2.6 P2.7 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 ALE / EA 34 37 38 39 35 36 40 24 25 26 27 28 29 30 32 33 31 21 23 22 Typical features of a modern 8051: • Thirty-two input / output lines. • Internal data (RAM) memory - 256 bytes. • Up to 64 kbytes of ROM memory (usually flash) • Three 16-bit timers / counters • Nine interrupts (two external) with two priority levels. • Low-power Idle and Power-down modes. The different members of the 8051 family are suitable for a huge range of projects - from automotive and aerospace systems to TV “remotes”. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 8 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 21. Review: The “super loop” software architecture Problem What is the minimum software environment you need to create an embedded C program? Solution void main(void) { /* Prepare for Task X */ X_Init(); while(1) /* 'for ever' (Super Loop) */ { X(); /* Perform the task */ } } Crucially, the ‘super loop’, or ‘endless loop’, is required because we have no operating system to return to: our application will keep looping until the system power is removed. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 9 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 22. Review: An introduction to schedulers Word Processor OS provides ‘common code’ for: • Graphics Operating System • Printing • File storage • Sound BIOS • ... Hardware Many embedded systems must carry out tasks at particular instants of time. More specifically, we have two kinds of activity to perform: • Repeated tasks, to be performed (say) once every 100 ms, and - less commonly - • One-shot tasks, to be performed once after a delay of (say) 50 ms. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 10 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 23. Review: Building a scheduler void main(void) { Timer_2_Init(); /* Set up Timer 2 */ EA = 1; /* Globally enable interrupts */ while(1); /* An empty Super Loop */ } void Timer_2_Init(void) { /* Timer 2 is configured as a 16-bit timer, which is automatically reloaded when it overflows With these setting, timer will overflow every 1 ms */ T2CON = 0x04; /* Load T2 control register */ T2MOD = 0x00; /* Load T2 mode register */ TH2 = 0xFC; /* Load T2 high byte */ RCAP2H = 0xFC; /* Load T2 reload capt. reg. high byte */ TL2 = 0x18; /* Load T2 low byte */ RCAP2L = 0x18; /* Load T2 reload capt. reg. low byte */ /* Timer 2 interrupt is enabled, and ISR will be called whenever the timer overflows - see below. */ ET2 = 1; /* Start Timer 2 running */ TR2 = 1; } void X(void) interrupt INTERRUPT_Timer_2_Overflow { /* This ISR is called every 1 ms */ /* Place required code here... */ } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 11 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 24. Overview of this seminar This seminar will consider the design of a very flexible scheduler. THE CO-OPERATIVE SCHEDULER • A co-operative scheduler provides a single-tasking system architecture Operation: • Tasks are scheduled to run at specific times (either on a one-shot or regular basis) • When a task is scheduled to run it is added to the waiting list • When the CPU is free, the next waiting task (if any) is executed • The task runs to completion, then returns control to the scheduler Implementation: • The scheduler is simple, and can be implemented in a small amount of code. • The scheduler must allocate memory for only a single task at a time. • The scheduler will generally be written entirely in a high-level language (such as ‘C’). • The scheduler is not a separate application; it becomes part of the developer’s code Performance: • Obtain rapid responses to external events requires care at the design stage. Reliability and safety: • Co-operate scheduling is simple, predictable, reliable and safe. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 12 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 25. The Co-operative Scheduler A scheduler has the following key components: • The scheduler data structure. • An initialisation function. • A single interrupt service routine (ISR), used to update the scheduler at regular time intervals. • A function for adding tasks to the scheduler. • A dispatcher function that causes tasks to be executed when they are due to run. • A function for removing tasks from the scheduler (not required in all applications). We will consider each of the required components in turn. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 13 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 26. Overview /*--------------------------------------------------------*/ void main(void) { /* Set up the scheduler */ SCH_Init_T2(); /* Prepare for the 'Flash_LED' task */ LED_Flash_Init(); /* Add the 'Flash LED' task (on for ~1000 ms, off for ~1000 ms) Timings are in ticks (1 ms tick interval) (Max interval / delay is 65535 ticks) */ SCH_Add_Task(LED_Flash_Update, 0, 1000); /* Start the scheduler */ SCH_Start(); while(1) { SCH_Dispatch_Tasks(); } } /*--------------------------------------------------------*/ void SCH_Update(void) interrupt INTERRUPT_Timer_2_Overflow { /* Update the task list */ ... } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 14 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 27. The scheduler data structure and task array /* Store in DATA area, if possible, for rapid access Total memory per task is 7 bytes */ typedef data struct { /* Pointer to the task (must be a 'void (void)' function) */ void (code * pTask)(void); /* Delay (ticks) until the function will (next) be run - see SCH_Add_Task() for further details */ tWord Delay; /* Interval (ticks) between subsequent runs. - see SCH_Add_Task() for further details */ tWord Repeat; /* Set to 1 (by scheduler) when task is due to execute */ tByte RunMe; } sTask; File Sch51.H also includes the constant SCH_MAX_TASKS: /* The maximum number of tasks required at any one time during the execution of the program MUST BE ADJUSTED FOR EACH NEW PROJECT */ #define SCH_MAX_TASKS (1) Both the sTask data type and the SCH_MAX_TASKS constant are used to create - in the file Sch51.C - the array of tasks that is referred to throughout the scheduler: /* The array of tasks */ sTask SCH_tasks_G[SCH_MAX_TASKS]; COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 15 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 28. The size of the task array You must ensure that the task array is sufficiently large to store the tasks required in your application, by adjusting the value of SCH_MAX_TASKS. For example, if you schedule three tasks as follows: SCH_Add_Task(Function_A, 0, 2); SCH_Add_Task(Function_B, 1, 10); SCH_Add_Task(Function_C, 3, 15); …then SCH_MAX_TASKS must have a value of 3 (or more) for correct operation of the scheduler. Note also that - if this condition is not satisfied, the scheduler will generate an error code (more on this later). COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 16 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 29. One possible initialisation function: /*--------------------------------------------------------*/ void SCH_Init_T2(void) { tByte i; for (i = 0; i < SCH_MAX_TASKS; i++) { SCH_Delete_Task(i); } /* SCH_Delete_Task() will generate an error code, because the task array is empty. -> reset the global error variable. */ Error_code_G = 0; /* Now set up Timer 2 16-bit timer function with automatic reload Crystal is assumed to be 12 MHz The Timer 2 resolution is 0.000001 seconds (1 µs) The required Timer 2 overflow is 0.001 seconds (1 ms) - this takes 1000 timer ticks Reload value is 65536 - 1000 = 64536 (dec) = 0xFC18 */ T2CON = 0x04; /* Load Timer 2 control register */ T2MOD = 0x00; /* Load Timer 2 mode register */ TH2 = 0xFC; /* Load Timer 2 high byte */ RCAP2H = 0xFC; /* Load Timer 2 reload capture reg, high byte */ TL2 = 0x18; /* Load Timer 2 low byte */ RCAP2L = 0x18; /* Load Timer 2 reload capture reg, low byte */ ET2 = 1; /* Timer 2 interrupt is enabled */ TR2 = 1; /* Start Timer 2 */ } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 17 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 30. IMPORTANT: The ‘one interrupt per microcontroller’ rule! The scheduler initialisation function enables the generation of interrupts associated with the overflow of one of the microcontroller timers. For reasons discussed in Chapter 1 of PTTES, it is assumed throughout this course that only the ‘tick’ interrupt source is active: specifically, it is assumed that no other interrupts are enabled. If you attempt to use the scheduler code with additional interrupts enabled, the system cannot be guaranteed to operate at all: at best, you will generally obtain very unpredictable - and unreliable - system behaviour. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 18 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 31. The ‘Update’ function /*--------------------------------------------------------*/ void SCH_Update(void) interrupt INTERRUPT_Timer_2_Overflow { tByte Index; TF2 = 0; /* Have to manually clear this. */ /* NOTE: calculations are in *TICKS* (not milliseconds) */ for (Index = 0; Index < SCH_MAX_TASKS; Index++) { /* Check if there is a task at this location */ if (SCH_tasks_G[Index].pTask) { if (--SCH_tasks_G[Index].Delay == 0) { /* The task is due to run */ SCH_tasks_G[Index].RunMe += 1; /* Inc. 'RunMe' flag */ if (SCH_tasks_G[Index].Period) { /* Schedule regular tasks to run again */ SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period; } } } } } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 19 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 32. The ‘Add Task’ function Initial_Delay the delay (in ticks) before task is first executed. If set to 0, the task is executed immediately. Sch_Add_Task(Task_Name, Initial_Delay, Task_Interval); Task_Name Task_Interval the name of the function the interval (in ticks) (task) that you wish to between repeated schedule executions of the task. If set to 0, the task is executed only once. Examples: SCH_Add_Task(Do_X,1000,0); Task_ID = SCH_Add_Task(Do_X,1000,0); SCH_Add_Task(Do_X,0,1000); This causes the function Do_X() to be executed regularly, every 1000 scheduler ticks; task will be first executed at T = 300 ticks, then 1300, 2300, etc: SCH_Add_Task(Do_X,300,1000); COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 20 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 33. /*--------------------------------------------------------*- SCH_Add_Task() Causes a task (function) to be executed at regular intervals, or after a user-defined delay. -*--------------------------------------------------------*/ tByte SCH_Add_Task(void (code * pFunction)(), const tWord DELAY, const tWord PERIOD) { tByte Index = 0; /* First find a gap in the array (if there is one) */ while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS)) { Index++; } /* Have we reached the end of the list? */ if (Index == SCH_MAX_TASKS) { /* Task list is full -> set the global error variable */ Error_code_G = ERROR_SCH_TOO_MANY_TASKS; /* Also return an error code */ return SCH_MAX_TASKS; } /* If we're here, there is a space in the task array */ SCH_tasks_G[Index].pTask = pFunction; SCH_tasks_G[Index].Delay = DELAY + 1; SCH_tasks_G[Index].Period = PERIOD; SCH_tasks_G[Index].RunMe = 0; return Index; /* return pos. of task (to allow deletion) */ } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 21 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 34. The ‘Dispatcher’ /*--------------------------------------------------------*- SCH_Dispatch_Tasks() This is the 'dispatcher' function. When a task (function) is due to run, SCH_Dispatch_Tasks() will run it. This function must be called (repeatedly) from the main loop. -*--------------------------------------------------------*/ void SCH_Dispatch_Tasks(void) { tByte Index; /* Dispatches (runs) the next task (if one is ready) */ for (Index = 0; Index < SCH_MAX_TASKS; Index++) { if (SCH_tasks_G[Index].RunMe > 0) { (*SCH_tasks_G[Index].pTask)(); /* Run the task */ SCH_tasks_G[Index].RunMe -= 1; /* Reduce RunMe count */ /* Periodic tasks will automatically run again - if this is a 'one shot' task, delete it */ if (SCH_tasks_G[Index].Period == 0) { SCH_Delete_Task(Index); } } } /* Report system status */ SCH_Report_Status(); /* The scheduler enters idle mode at this point */ SCH_Go_To_Sleep(); } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 22 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 35. The dispatcher is the only component in the Super Loop: /* ----------------------------------------------------- */ void main(void) { ... while(1) { SCH_Dispatch_Tasks(); } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 23 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 36. Function arguments • On desktop systems, function arguments are generally passed on the stack using the push and pop assembly instructions. • Since the 8051 has a size limited stack (only 128 bytes at best and as low as 64 bytes on some devices), function arguments must be passed using a different technique. • In the case of Keil C51, these arguments are stored in fixed memory locations. • When the linker is invoked, it builds a call tree of the program, decides which function arguments are mutually exclusive (that is, which functions cannot be called at the same time), and overlays these arguments. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 24 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 37. Function pointers and Keil linker options When we write: SCH_Add_Task(Do_X,1000,0); …the first parameter of the ‘Add Task’ function is a pointer to the function Do_X(). This function pointer is then passed to the Dispatch function and it is through this function that the task is executed: if (SCH_tasks_G[Index].RunMe > 0) { (*SCH_tasks_G[Index].pTask)(); /* Run the task */ BUT The linker has difficulty determining the correct call tree when function pointers are used as arguments. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 25 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 38. To deal with this situation, you have two realistic options: 1. You can prevent the compiler from using the OVERLAY directive by disabling overlays as part of the linker options for your project. Note that, compared to applications using overlays, you will generally require more RAM to run your program. 2. You can tell the linker how to create the correct call tree for your application by explicitly providing this information in the linker ‘Additional Options’ dialogue box. This approach is used in most of the examples in the “PTTES” book. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 26 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 39. void main(void) { ... /* Read the ADC regularly */ SCH_Add_Task(AD_Get_Sample, 10, 1000); /* Simply display the count here (bargraph display) */ SCH_Add_Task(BARGRAPH_Update, 12, 1000); /* All tasks added: start running the scheduler */ SCH_Start(); The corresponding OVERLAY directive would take this form: OVERLAY (main ~ (AD_Get_Sample,Bargraph_Update), sch_dispatch_tasks ! (AD_Get_Sample,Bargraph_Update)) COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 27 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 40. The ‘Start’ function /*--------------------------------------------------------*/ void SCH_Start(void) { EA = 1; } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 28 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 41. The ‘Delete Task’ function When tasks are added to the task array, SCH_Add_Task() returns the position in the task array at which the task has been added: Task_ID = SCH_Add_Task(Do_X,1000,0); Sometimes it can be necessary to delete tasks from the array. You can do so as follows: SCH_Delete_Task(Task_ID); bit SCH_Delete_Task(const tByte TASK_INDEX) { bit Return_code; if (SCH_tasks_G[TASK_INDEX].pTask == 0) { /* No task at this location... -> set the global error variable */ Error_code_G = ERROR_SCH_CANNOT_DELETE_TASK; /* ...also return an error code */ Return_code = RETURN_ERROR; } else { Return_code = RETURN_NORMAL; } SCH_tasks_G[TASK_INDEX].pTask = 0x0000; SCH_tasks_G[TASK_INDEX].Delay = 0; SCH_tasks_G[TASK_INDEX].Period = 0; SCH_tasks_G[TASK_INDEX].RunMe = 0; return Return_code; /* return status */ } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 29 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 42. Reducing power consumption /*--------------------------------------------------------*/ void SCH_Go_To_Sleep() { PCON |= 0x01; /* Enter idle mode (generic 8051 version) */ /* Entering idle mode requires TWO consecutive instructions on 80c515 / 80c505 - to avoid accidental triggering. E.g: PCON |= 0x01; PCON |= 0x20; */ } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 30 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 43. Reporting errors /* Used to display the error code */ tByte Error_code_G = 0; To record an error we include lines such as: Error_code_G = ERROR_SCH_TOO_MANY_TASKS; Error_code_G = ERROR_SCH_WAITING_FOR_SLAVE_TO_ACK; Error_code_G = ERROR_SCH_WAITING_FOR_START_COMMAND_FROM_MASTER; Error_code_G = ERROR_SCH_ONE_OR_MORE_SLAVES_DID_NOT_START; Error_code_G = ERROR_SCH_LOST_SLAVE; Error_code_G = ERROR_SCH_CAN_BUS_ERROR; Error_code_G = ERROR_I2C_WRITE_BYTE_AT24C64; To report these error code, the scheduler has a function SCH_Report_Status(), which is called from the Update function. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 31 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 44. /*--------------------------------------------------------*/ void SCH_Report_Status(void) { #ifdef SCH_REPORT_ERRORS /* ONLY APPLIES IF WE ARE REPORTING ERRORS */ /* Check for a new error code */ if (Error_code_G != Last_error_code_G) { /* Negative logic on LEDs assumed */ Error_port = 255 - Error_code_G; Last_error_code_G = Error_code_G; if (Error_code_G != 0) { Error_tick_count_G = 60000; } else { Error_tick_count_G = 0; } } else { if (Error_tick_count_G != 0) { if (--Error_tick_count_G == 0) { Error_code_G = 0; /* Reset error code */ } } } #endif } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 32 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 45. Note that error reporting may be disabled via the Port.H header file: /* Comment next line out if error reporting is NOT required */ /* #define SCH_REPORT_ERRORS */ Where error reporting is required, the port on which error codes will be displayed is also determined via Port.H: #ifdef SCH_REPORT_ERRORS /* The port on which error codes will be displayed (ONLY USED IF ERRORS ARE REPORTED) */ #define Error_port P1 #endif Note that, in this implementation, error codes are reported for 60,000 ticks (1 minute at a 1 ms tick rate). COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 33 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 46. Displaying error codes Vcc For 25mA LEDs, Rled = 120 Ohms Rled Rled Rled Rled Rled Rled Rled Rled P2.0 - Pin 8 P2.1 - Pin 7 P2.2 - Pin 6 P2.3 - Pin 5 P2.4 - Pin 4 P2.5 - Pin 3 ULN2803A P2.6 - Pin 2 P2.7 - Pin 1 LED 7 LED 6 LED 5 LED 4 LED 3 LED 2 LED 1 LED 0 Port 2 Pin 11 - LED 0 8051 Device Pin 12 - LED 1 Pin 13 - LED 2 Pin 14 - LED 3 Pin 15 - LED 4 9 Pin 16 - LED 5 Pin 17 - LED 6 Pin 18 - LED 7 The forms of error reporting discussed here are low-level in nature and are primarily intended to assist the developer of the application, or a qualified service engineer performing system maintenance. An additional user interface may also be required in your application to notify the user of errors, in a more user-friendly manner. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 34 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 47. Hardware resource implications Timer The scheduler requires one hardware timer. If possible, this should be a 16-bit timer, with auto-reload capabilities (usually Timer 2). Memory This main scheduler memory requirement is 7 bytes of memory per task. Most applications require around six tasks or less. Even in a standard 8051/8052 with 256 bytes of internal memory the total memory overhead is small. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 35 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 48. What is the CPU load of the scheduler? • A scheduler with 1ms ticks • 12 Mhz, 12 osc / instruction 8051 • One task is being executed. • The test reveals that the CPU is 86% idle and that the maximum possible task duration is therefore approximately 0.86 ms. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 36 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 49. A scheduler with 1ms ticks, running on a 32 Mhz (4 oscillations per instruction) 8051. • One task is being executed. • The CPU is 97% idle and that the maximum possible task duration is therefore approximately 0.97 ms. • Twelve tasks are being executed. • The CPU is 85% idle and that the maximum possible task duration is therefore approximately 0.85 ms. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 37 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 50. Determining the required tick interval In most instances, the simplest way of meeting the needs of the various task intervals is to allocate a scheduler tick interval of 1 ms. To keep the scheduler load as low as possible (and to reduce the power consumption), it can help to use a long tick interval. If you want to reduce overheads and power consumption to a minimum, the scheduler tick interval should be set to match the ‘greatest common factor’ of all the task (and offset intervals). COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 38 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 51. Suppose we have three tasks (X,Y,Z), and Task X is to be run every 10 ms, Task Y every 30 ms and Task Z every 25 ms. The scheduler tick interval needs to be set by determining the relevant factors, as follows: • The factors of the Task X interval (10 ms) are: 1 ms, 2ms, 5 ms, 10 ms. • Similarly, the factors of the Task Y interval (30 ms) are as follows: 1 ms, 2 ms, 3 ms, 5 ms, 6 ms, 10 ms, 15 ms and 30 ms. • Finally, the factors of the Task Z interval (25 ms) are as follows: 1 ms, 5 ms and 25 ms. In this case, therefore, the greatest common factor is 5 ms: this is the required tick interval. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 39 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 52. Guidelines for predictable and reliable scheduling 1. For precise scheduling, the scheduler tick interval should be set to match the ‘greatest common factor’ of all the task intervals. 2. All tasks should have a duration less than the schedule tick interval, to ensure that the dispatcher is always free to call any task that is due to execute. Software simulation can often be used to measure the task duration. 3. In order to meet Condition 2, all tasks must ‘timeout’ so that they cannot block the scheduler under any circumstances. 4. The total time required to execute all of the scheduled tasks must be less than the available processor time. Of course, the total processor time must include both this ‘task time’ and the ‘scheduler time’ required to execute the scheduler update and dispatcher operations. 5. Tasks should be scheduled so that they are never required to execute simultaneously: that is, task overlaps should be minimised. Note that where all tasks are of a duration much less than the scheduler tick interval, and that some task jitter can be tolerated, this problem may not be significant. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 40 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 53. Overall strengths and weaknesses of the scheduler ☺ The scheduler is simple, and can be implemented in a small amount of code. ☺ The scheduler is written entirely in ‘C’: it is not a separate application, but becomes part of the developer’s code ☺ The applications based on the scheduler are inherently predictable, safe and reliable. ☺ The scheduler supports team working, since individual tasks can often be developed largely independently and then assembled into the final system. Obtain rapid responses to external events requires care at the design stage. The tasks cannot safely use interrupts: the only interrupt that should be used in the application is the timer-related interrupt that drives the scheduler itself. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 41 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 54. Preparations for the next seminar Please read “PTTES” Chapter 13 and Chapter 14 before the next seminar. 16 13 17 15 14 12 11 20 18 10 19 7 6 5 4 3 2 1 9 8 VSS XTL1 XTL2 P3.7 P3.6 P3.5 P3.4 P3.3 P3.2 P3.1 P3.0 RST P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 ‘8051’ / PSEN P0.0 VCC P2.0 P2.1 P2.2 P2.3 P2.4 P2.5 P2.6 P2.7 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 ALE / EA 34 37 38 39 24 25 26 27 28 29 30 32 33 35 36 40 21 23 31 22 COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 42 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 55. Seminar 2: A closer look at co- operative task scheduling (and some alternatives) COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 43 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 56. Overview of this seminar • In this seminar, we’ll review some of the features of the co- operative scheduler discussed in Seminar 1. • We’ll then consider the features of a pre-emptive scheduler • We’ll go on to develop a hybrid scheduler, which has many of the useful features of both co-operative and pre- emptive schedulers (but is simpler to build - and generally more reliable - than a fully pre-emptive design) • Finally, we’ll look at a range of different designs for other forms of (co-operative) scheduler. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 44 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 57. Review: Co-operative scheduling THE CO-OPERATIVE SCHEDULER • A co-operative scheduler provides a single-tasking system architecture Operation: • Tasks are scheduled to run at specific times (either on a one-shot or regular basis) • When a task is scheduled to run it is added to the waiting list • When the CPU is free, the next waiting task (if any) is executed • The task runs to completion, then returns control to the scheduler Implementation: • The scheduler is simple, and can be implemented in a small amount of code. • The scheduler must allocate memory for only a single task at a time. • The scheduler will generally be written entirely in a high-level language (such as ‘C’). • The scheduler is not a separate application; it becomes part of the developer’s code Performance: • Obtain rapid responses to external events requires care at the design stage. Reliability and safety: • Co-operate scheduling is simple, predictable, reliable and safe. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 45 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 58. The pre-emptive scheduler Overview: THE PRE-EMPTIVE SCHEDULER • A pre-emptive scheduler provides a multi-tasking system architecture Operation: • Tasks are scheduled to run at specific times (either on a one-shot or regular basis) • When a task is scheduled to run it is added to the waiting list • Waiting tasks (if any) are run for a fixed period then - if not completed - are paused and placed back in the waiting list. The next waiting task is then run for a fixed period, and so on. Implementation: • The scheduler is comparatively complicated, not least because features such as semaphores must be implemented to avoid conflicts when ‘concurrent’ tasks attempt to access shared resources. • The scheduler must allocate memory is to hold all the intermediate states of pre-empted tasks. • The scheduler will generally be written (at least in part) in assembly language. • The scheduler is generally created as a separate application. Performance: • Rapid responses to external events can be obtained. Reliability and safety: • Generally considered to be less predictable, and less reliable, than co-operative approaches. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 46 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 59. Why do we avoid pre-emptive schedulers in this course? Various research studies have demonstrated that, compared to pre- emptive schedulers, co-operative schedulers have a number of desirable features, particularly for use in safety-related systems. “[Pre-emptive] schedules carry greater runtime overheads because of the need for context switching - storage and retrieval of partially computed results. [Co-operative] algorithms do not incur such overheads. Other advantages of [co-operative] algorithms include their better understandability, greater predictability, ease of testing and their inherent capability for guaranteeing exclusive access to any shared resource or data.”. Nissanke (1997, p.237) “Significant advantages are obtained when using this [co- operative] technique. Since the processes are not interruptable, poor synchronisation does not give rise to the problem of shared data. Shared subroutines can be implemented without producing re-entrant code or implementing lock and unlock mechanisms”. Allworth (1981, p.53-54) Compared to pre-emptive alternatives, co-operative schedulers have the following advantages: [1] The scheduler is simpler; [2] The overheads are reduced; [3] Testing is easier; [4] Certification authorities tend to support this form of scheduling. Bate (2000) [See PTTES, Chapter 13] COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 47 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 60. Why is a co-operative scheduler (generally) more reliable? • The key reason why the co-operative schedulers are both reliable and predictable is that only one task is active at any point in time: this task runs to completion, and then returns control to the scheduler. • Contrast this with the situation in a fully pre-emptive system with more than one active task. • Suppose one task in such a system which is reading from a port, and the scheduler performs a ‘context switch’, causing a different task to access the same port: under these circumstances, unless we take action to prevent it, data may be lost or corrupted. This problem arises frequently in multi-tasking environments where we have what are known as ‘critical sections’ of code. Such critical sections are code areas that - once started - must be allowed to run to completion without interruption. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 48 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 61. Critical sections of code Examples of critical sections include: • Code which modifies or reads variables, particularly global variables used for inter-task communication. In general, this is the most common form of critical section, since inter-task communication is often a key requirement. • Code which interfaces to hardware, such as ports, analogue- to-digital converters (ADCs), and so on. What happens, for example, if the same ADC is used simultaneously by more than one task? • Code which calls common functions. What happens, for example, if the same function is called simultaneously by more than one task? In a co-operative system, problems with critical sections do not arise, since only one task is ever active at the same time. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 49 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 62. How do we deal with critical sections in a pre-emptive system? To deal with such critical sections of code in a pre-emptive system, we have two main possibilities: • ‘Pause’ the scheduling by disabling the scheduler interrupt before beginning the critical section; re-enable the scheduler interrupt when we leave the critical section, or; • Use a ‘lock’ (or some other form of ‘semaphore mechanism’) to achieve a similar result. The first solution can be implemented as follows: • When Task A (say) starts accessing the shared resource (say Port X), we disable the scheduler. • This solves the immediate problem since Task A will be allowed to run without interruption until it has finished with Port X. • However, this ‘solution’ is less than perfect. For one thing, by disabling the scheduler, we will no longer be keeping track of the elapsed time and all timing functions will begin to drift - in this case by a period up to the duration of Task A every time we access Port X. This is not acceptable in most applications. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 50 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 63. Building a “lock” mechanism The use of locks is a better solution. Before entering the critical section of code, we ‘lock’ the associated resource; when we have finished with the resource we ‘unlock’ it. While locked, no other process may enter the critical section. This is one way we might try to achieve this: 1. Task A checks the ‘lock’ for Port X it wishes to access. 2. If the section is locked, Task A waits. 3. When the port is unlocked, Task A sets the lock and then uses the port. 4. When Task A has finished with the port, it leaves the critical section and unlocks the port. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 51 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 64. Implementing this algorithm in code also seems straightforward: #define UNLOCKED 0 #define LOCKED 1 bit Lock; // Global lock flag // ... // Ready to enter critical section // - Wait for lock to become clear // (FOR SIMPLICITY, NO TIMEOUT CAPABILITY IS SHOWN) while(Lock == LOCKED); // Lock is clear // Enter critical section A // Set the lock Lock = LOCKED; // CRITICAL CODE HERE // // Ready to leave critical section // Release the lock Lock = UNLOCKED; // ... COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 52 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 65. However, the above code cannot be guaranteed to work correctly under all circumstances. Consider the part of the code labelled ‘A’. If our system is fully pre-emptive, then our task can reach this point at the same time as the scheduler performs a context switch and allows (say) Task B access to the CPU. If Task Y also wants to access the Port X, we can then have a situation as follows: • Task A has checked the lock for Port X and found that the port is available; Task A has, however, not yet changed the lock flag. • Task B is then ‘switched in’. Task B checks the lock flag and it is still clear. Task B sets the lock flag and begins to use Port X. • Task A is ‘switched in’ again. As far as Task A is concerned, the port is not locked; this task therefore sets the flag, and starts to use the port, unaware that Task B is already doing so. • … As we can see, this simple lock code violates the principal of mutual exclusion: that is, it allows more than one task to access a critical code section. The problem arises because it is possible for the context switch to occur after a task has checked the lock flag but before the task changes the lock flag. In other words, the lock ‘check and set code’ (designed to control access to a critical section of code), is itself a critical section. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 53 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 66. • This problem can be solved. • For example, because it takes little time to ‘check and set’ the lock code, we can disable interrupts for this period. • However, this is not in itself a complete solution: because there is a chance that an interrupt may have occurred even in the short period of ‘check and set’, we then need to check the relevant interrupt flag(s) and - if necessary - call the relevant ISR(s). This can be done, but it adds substantially to the complexity of the operating environment. Even if we build a working lock mechanism, this is only a partial solution to the problems caused by multi-tasking. If the purpose of Task A is to read from an ADC, and Task B has locked the ADC when the Task A is invoked, then Task A cannot carry out its required activity. Use of locks (or any other mechanism), can prevent the system from crashing, but cannot allow two tasks to have access to the ADC simultaneously. When using a co-operative scheduler, such problems do not arise. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 54 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 67. The “best of both worlds” - a hybrid scheduler THE HYBRID SCHEDULER • A hybrid scheduler provides limited multi-tasking capabilities Operation: • Supports any number of co-operatively-scheduled tasks • Supports a single pre-emptive task (which can interrupt the co-operative tasks) Implementation: • The scheduler is simple, and can be implemented in a small amount of code. • The scheduler must allocate memory for - at most - two tasks at a time. • The scheduler will generally be written entirely in a high-level language (such as ‘C’). • The scheduler is not a separate application; it becomes part of the developer’s code Performance: • Rapid responses to external events can be obtained. Reliability and safety: • With careful design, can be as reliable as a (pure) co-operative scheduler. COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 55 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 68. Creating a hybrid scheduler The ‘update’ function from a co-operative scheduler: void SCH_Update(void) interrupt INTERRUPT_Timer_2_Overflow { tByte Index; TF2 = 0; /* Have to manually clear this. */ /* NOTE: calculations are in *TICKS* (not milliseconds) */ for (Index = 0; Index < SCH_MAX_TASKS; Index++) { /* Check if there is a task at this location */ if (SCH_tasks_G[Index].Task_p) { if (--SCH_tasks_G[Index].Delay == 0) { /* The task is due to run */ SCH_tasks_G[Index].RunMe += 1; /* Inc. RunMe */ if (SCH_tasks_G[Index].Period) { /* Schedule periodic tasks to run again */ SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period; } } } } } COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 56 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.
  • 69. The co-operative version assumes a scheduler data type as follows: /* Store in DATA area, if possible, for rapid access [Total memory per task is 7 bytes] */ typedef data struct { /* Pointer to the task (must be a 'void (void)' function) */ void (code * Task_p)(void); /* Delay (ticks) until the function will (next) be run - see SCH_Add_Task() for further details */ tWord Delay; /* Interval (ticks) between subsequent runs. - see SCH_Add_Task() for further details */ tWord Period; /* Set to 1 (by scheduler) when task is due to execute */ tByte RunMe; } sTask; COPYRIGHT © MICHAEL J. PONT, 2001-2003. Contains material from: PES II - 57 Pont, M.J. (2001) “Patterns for triggered embedded systems”, Addison-Wesley.