Errata for PTTES

This thread contains all known errata for the book “Patterns for Time-Triggered Embedded Systems”.

If you have found a typo or bug in the book that is not yet listed here, please either submit a new thread to this forum, or contact us directly.

Page 11

Figure 1.5 has the labels for ‘Background’ and ‘Foreground’ the wrong way round.

Page 89

The first line in Table 6.1 should read “64k x 8-bit data” (not 640 x 8-bit).

Pages 96-107

[Thanks to Gary Kennedy]

The label ‘74x573’ has been mixed-up during the production process, and has been consistently replaced with ‘74x375’. This occurs in several places.

The first error is on Page 96, in Figure 6.3: here the latch should read 74x373/573.

The error is repeated on Page 96 (in the text), Page 97 (Table 9.2), Page 99 (Figures 6.4 and 6.5), Page 100 (Table 6.3), Page 101 (Table 6.3 cont.) and Page 104 (Figure 6.6, Figure 6.7) and Page 107 (Figure 6.10).

Page 120

[Thanks to Javier Vega]

There are some errors in Figure 7.11.

Page 140

[Thanks to Javier Vega]

The first paragraph is repeated from the page before.

Page 154

[Thanks to Javier Vega]

In Figure 8.6 the capacitor in the snubber is not shown (although the label is present).

Page 178

There are some errors in Figure 10.1.

Page 264

[Thanks to Mohammad Attari]

The SCH_Update function sets the delay incorrectly when it must be reset. The updated function should look like this:

  1. void SCH_Update(void) interrupt INTERRUPT_Timer_2_Overflow
  2. {
  3. tByte Index;
  4.  
  5. TF2 = 0; // Have to manually clear this.
  6.  
  7. // NOTE: calculations are in *TICKS* (not milliseconds)
  8. for (Index = 0; Index < SCH_MAX_TASKS; Index++)
  9. {
  10. // Check if there is a task at this location
  11. if (SCH_tasks_G[Index].pTask)
  12. {
  13. if (SCH_tasks_G[Index].Delay == 0)
  14. {
  15. // The task is due to run
  16. SCH_tasks_G[Index].RunMe += 1; // Inc. the 'RunMe' flag
  17.  
  18. if (SCH_tasks_G[Index].Period)
  19. {
  20. // Schedule periodic tasks to run again - zero based so dec.
  21. SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period - 1;
  22. }
  23. }
  24. else
  25. {
  26. // Not yet ready to run: just decrement the delay
  27. SCH_tasks_G[Index].Delay -= 1;
  28. }
  29. }
  30. }
  31. }

Page 291 onwards

Listing “2_01_12g.c” is printed twice.

Page 299

[Thanks to Yeow Heng Seow]

On the third line, the code should read:

  1. unsigned int Timeout_loop = 0;

Pages 337 and 346

[Thanks to Ayman Gendy]

This line in Listing 17.3 does no harm but is NOT required:

  1. hSCH_tasks_G[Index].RunMe -= 1; // Reset / reduce RunMe flag

Page 381

The code on the CD is a later (and better) version than that reproduced in the book.

Page 402

[Thanks to Javier Vega]

The caption should read “normally open”.

Page 497

[Thanks to Chisanga Mwelwa]

Figure 23.4 shows a DS1621 (incorrectly labelled 24C64).

Pages 614-615

[Thanks to Chisanga Mwelwa]

The captions for Figures 27.5a and 27.5b have been swapped during the production process.

Pages 694-695

[Thanks to Tim Edwards and Balasubramanya Bellur Hiriyannaiah]

I have confused the IDs for “slaves” and “previous slaves” in this code section.

The correct version is as follows:

  1. // Check that the appropriate slave responded to the previous message:
  2. // (if it did, store the data sent by this slave)
  3. if (SCC_A_MASTER_Process_Ack(Previous_slave_index) == RETURN_ERROR)
  4. {
  5. Error_code_G = ERROR_SCH_LOST_SLAVE;
  6. Network_error_pin = NETWORK_ERROR;
  7.  
  8. // If we have lost contact with a slave, we attempt to
  9. // switch to a backup device (if one is available)
  10. if (Current_Slave_IDs_G[Previous_slave_index] != BACKUP_SLAVE_IDs[Previous_slave_index])
  11. {
  12. // There is a backup available: switch to backup and try again
  13. Current_Slave_IDs_G[Previous_slave_index] = BACKUP_SLAVE_IDs[Previous_slave_index];
  14. }
  15. else
  16. {
  17. // There is no backup available (or we are already using it)
  18. // Try main device.
  19. Current_Slave_IDs_G[Previous_slave_index] = MAIN_SLAVE_IDs[Previous_slave_index];
  20. }
  21.  
  22. // Try to connect to the slave
  23. Slave_replied_correctly = SCC_A_MASTER_Start_Slave(Current_Slave_IDs_G[Previous_slave_index]);
  24.  
  25. if (!Slave_replied_correctly)
  26. {
  27. // No backup available (or backup failed too) - we shut down
  28. // OTHER BEHAVIOUR MAY BE MORE APPROPRIATE IN YOUR APPLICATION
  29. SCC_A_MASTER_Shut_Down_the_Network();
  30. }
  31. }
  32.  
  33. // Send 'tick' message to all connected slaves
  34. // (sends data to the current slave)
  35. SCC_A_MASTER_Send_Tick_Message(Slave_index_G);

Page 706

First line should read: “This Slave is triggered by CAN interrupts”.

Page 715

[Thanks to Trent Lillehaugen]

The last line of the example code:

  1. printf("Original data is %f\n", X.Float);

should read:

  1. printf("Transferred data is %f\n", Y.Float);

Page 721

[Thanks to Trent Lillehaugen]

“Worse, if we make the reasonable assume that…”

should read:

“Worse, if we make the reasonable assumption that…”

Also on this page:

In Figure 29.6, Processor 1 should be shown to run Task A, Task A, Task A, Task A, …

Page 764

[Thanks to Chisanga Mwelwa and Andrew Norman]

There is an error in the file “Port.H” The file should read as follows:

  1. /*------------------------------------------------------------------*-
  2.  
  3. Port.H (v1.00)
  4.  
  5. ------------------------------------------------------------------
  6.  
  7. 'Port Header' (see Chap 10) for project SPI_ADC (see Chap 32)
  8.  
  9. -*------------------------------------------------------------------*/
  10.  
  11. // ------ SPI_Core.C -----------------------------------------------
  12.  
  13. // Create sbits for all required chip selects here
  14.  
  15. sbit SPI_CS = P1^3; // ***** NB ******
  16.  
  17. // NOTE: pins P1.4, P1.5, P1.6 and P1.7 also used - see text
  18.  
  19. /*------------------------------------------------------------------*-
  20.  
  21. ---- END OF FILE -------------------------------------------------
  22.  
  23. -*------------------------------------------------------------------*/

Pages 777-781

[Thanks to John Moyer and Yukuan Jiang]

The pattern ADC Pre-Amp contains a number of errors and inconsistencies.

Pages 778-780

[Thanks to John Moyer]

The circuit diagrams in Figure 32.11, Figure 32.12 and Figure 32.13 have the positive and negative terminals of the op amps reversed.

Page 811

[Thanks to Trent Lillehaugen]

csnubber is missing in Figure 33.2.

Page 866

[Thanks to Trent Lillehaugen]

In Figure 35.9, the box should be labelled “Closed-loop controller” (not “Open-loop controller”).

Page 867

[Thanks to Trent Lillehaugen]

The second sentence in the 4th paragraph is a mess.

It will make a little more sense as follows:

Specifically, we measure the error between the desired system output (that is, the desired speed of the vehicle in this case) and the current system output (the current vehicle speed in this case).

Pages 871-872

[Thanks to John Moyer]

John correctly spotted that the description of the technique used to calculate the sample rate (based on the system rise time) contains an arithmetic error.

In addition, the equation on p.871 provides a sample rate that is close to the minimum required to ensure stability for many systems.

To solve both problems, the text beginning “Having determined the rise time …” (at the bottom of p.871) through to the start of the “Hardware Resources” section (on p.873) will be more useful if replaced with the following:

Having determined the rise time (measured in seconds), we can approximate the required sample rate as follows:

Sample rate (Hz) = 40 / Rise time (seconds)

Thus, if the rise time measured in Figure 35-11 was 0.1 second, the required sample frequency would be around 400 Hz.

Please note that this value is approximate, and involves several assumptions about the nature of the system. See Franklin et al. (1994), for further details.

Pages 928-930

[Thanks to Wang GuoYun]

The function “Check_Switch()” should include a call to the “Timer_1_Manual_Reload()

Adding this function call at the end of “Check_Switch()” will address this problem.