Browse Source

changed all timers to count-down, prose cleanup

Pat Beirne 1 month ago
parent
commit
f83c0bc355
2 changed files with 26 additions and 24 deletions
  1. 21 19
      CooperativeMultitasking.md
  2. 5 5
      build/demo.stm32f0xx.c

+ 21 - 19
CooperativeMultitasking.md

@@ -1245,7 +1245,7 @@ void stateCode(char event) {
     // ....
     // ....
   }
   }
 }
 }
-
+```
 
 
 In the above example, you could equally well have set the timer to start at zero
 In the above example, you could equally well have set the timer to start at zero
 and increment until it hits the desired limit (100 in this case).
 and increment until it hits the desired limit (100 in this case).
@@ -1262,7 +1262,8 @@ behalf of the tasks......
 Let's create a centralized service called `setTimer(timer_index, timer_count)`. 
 Let's create a centralized service called `setTimer(timer_index, timer_count)`. 
 
 
 A task can call this service with a unique `timer_index` and a requested count. The
 A task can call this service with a unique `timer_index` and a requested count. The
-`timer_irq()` will then count out the ticks on behalf of the task, and when the tick
+`timer_irq()` uses a pool of timer registers, and will count out the ticks 
+on behalf of the task, and when the tick
 count is finished, the `timer_irq()` code can generate a unique event, perhaps
 count is finished, the `timer_irq()` code can generate a unique event, perhaps
 `EVT_TIMER_n`. 
 `EVT_TIMER_n`. 
 
 
@@ -1290,14 +1291,14 @@ void stateCode(char event) {
 }
 }
 ```
 ```
 
 
-This makes the state code much simpler to read, 
+This makes the state code simpler to read, 
 hiding all the increments/decrements and limit testing.
 hiding all the increments/decrements and limit testing.
 
 
 The overhead for this ends up in the `timer_irq()` code, 
 The overhead for this ends up in the `timer_irq()` code, 
 and might look something like this:
 and might look something like this:
 
 
 ```C
 ```C
-static unsigned int timers[NUM_TIMERS];
+static uint16 timers[NUM_TIMERS];
 #define EVT_TIMER_OFFSET 100
 #define EVT_TIMER_OFFSET 100
 enum {EVENT_TIMER_1=EVT_TIMER_OFFSET, EVENT_TIMER_2, EVENT_TIMER_3}; // 100, 101...
 enum {EVENT_TIMER_1=EVT_TIMER_OFFSET, EVENT_TIMER_2, EVENT_TIMER_3}; // 100, 101...
 enum {TIMER_1, TIMER_2, TIMER_3};   // 0,1,2,....
 enum {TIMER_1, TIMER_2, TIMER_3};   // 0,1,2,....
@@ -1321,7 +1322,7 @@ void setTimer(int timerIndex, unsigned int timerCount) {
 <details><summary>Reality Check</summary>
 <details><summary>Reality Check</summary>
 On a typical microcontroller running at 24MHz, with 5 timers, this adds about
 On a typical microcontroller running at 24MHz, with 5 timers, this adds about
 2 microseconds of extra time to the `timer_irq()` code, which typically runs every 
 2 microseconds of extra time to the `timer_irq()` code, which typically runs every 
-10 or 100msec. It considerably simplifies the task code, makes it more legible
+10 or 100msec. It simplifies the task code, makes it more legible
 and probably reduces bugs that may appear by duplication of code.
 and probably reduces bugs that may appear by duplication of code.
 
 
 Another possible design for timers is to have the main `timer_isr()` increment
 Another possible design for timers is to have the main `timer_isr()` increment
@@ -1502,22 +1503,22 @@ void main(void) {
 /*********** task code, with states ************/
 /*********** task code, with states ************/
 enum {LED_ON, LED_OFF};
 enum {LED_ON, LED_OFF};
 enum {RTB_IDLE, RTB_ON};    // states
 enum {RTB_IDLE, RTB_ON};    // states
-static uint8 rtbState           = RTB_IDLE;
-static uint16 rtbTimerCount     = 0;
-const uint16 BUTTON_LED_ON_TIME = 150;
+static uint8 rtbState            = RTB_IDLE;
+static uint16 rtbTimerCount      = 0;
+const  uint16 BUTTON_LED_ON_TIME = 150;
 
 
 void respondToButtonTask(uint8 evt) {
 void respondToButtonTask(uint8 evt) {
   switch(rtbState) {
   switch(rtbState) {
     case RTB_IDLE:
     case RTB_IDLE:
       if (evt == EVT_BUTTON) {
       if (evt == EVT_BUTTON) {
         rtbState      = RTB_ON;
         rtbState      = RTB_ON;
-        rtbTimerCount = 0;
+        rtbTimerCount = BUTTON_LED_ON_TIME;
         gpio_set(LED, LED_ON);
         gpio_set(LED, LED_ON);
       }
       }
       break;
       break;
     case RTB_ON:
     case RTB_ON:
       if (evt == EVT_TICK) {
       if (evt == EVT_TICK) {
-        if (++rtbTimerCount > BUTTON_LED_ON_TIME) {
+        if (--rtbTimerCount == 0) {
           gpio_set(LED, LED_OFF);
           gpio_set(LED, LED_OFF);
           rtbState = RTB_IDLE;
           rtbState = RTB_IDLE;
         }
         }
@@ -1526,9 +1527,9 @@ void respondToButtonTask(uint8 evt) {
     }
     }
 }
 }
 
 
-const uint16 LED_ON_TIME  = 150;
-const uint16 LED_OFF_TIME = 50;
-static uint8 ledState       = LED_OFF;
+const int LED_ON_TIME  = 150;
+const int LED_OFF_TIME = 50;
+static uint8  ledState      = LED_OFF;
 static uint16 ledTimerCount = 0;
 static uint16 ledTimerCount = 0;
 
 
 void ledTask(uint8 evt) {
 void ledTask(uint8 evt) {
@@ -1537,14 +1538,14 @@ void ledTask(uint8 evt) {
       if (evt == EVT_TICK) {
       if (evt == EVT_TICK) {
         if (++ledTimerCount > LED_OFF_TIME) {
         if (++ledTimerCount > LED_OFF_TIME) {
           gpio_set(LED2, LED_ON);
           gpio_set(LED2, LED_ON);
-          ledTimerCount = 0;
+          ledTimerCount = LED_ON_TIME;
           ledState      = LED_ON;
           ledState      = LED_ON;
         }
         }
       }
       }
       break;
       break;
     case LED_ON:
     case LED_ON:
       if (evt == EVT_TICK) {
       if (evt == EVT_TICK) {
-        if (++ledTimerCount > LED_ON_TIME) {
+        if (--ledTimerCount == 0) {
           gpio_set(LED2, LED_OFF);
           gpio_set(LED2, LED_OFF);
           ledTimerCount = 0;
           ledTimerCount = 0;
           ledState      = LED_OFF;
           ledState      = LED_OFF;
@@ -1631,6 +1632,7 @@ void rtbTaskCode(char event) {
       break;
       break;
     case STATE_FLASHING:
     case STATE_FLASHING:
       // count down flashCount, toggle LED halfway through
       // count down flashCount, toggle LED halfway through
+      // effectively creating a substate
       if (event == EVT_TICK) {
       if (event == EVT_TICK) {
         if (--flashCount == 0) {
         if (--flashCount == 0) {
           setLED(OFF);
           setLED(OFF);
@@ -1728,7 +1730,7 @@ a subroutine, it's allowed to return a value
 
 
 ![cd-eject task uses sendMessage() to call a sibling task](sendMessage.png)
 ![cd-eject task uses sendMessage() to call a sibling task](sendMessage.png)
 
 
-This of course means that the prototype for task functions would change from 
+To return a value means that the prototype for task functions would change from 
 
 
 ```C
 ```C
 void taskCode(uint8 event);
 void taskCode(uint8 event);
@@ -1746,12 +1748,12 @@ uint8 SendMessage(int8 taskPointer(uint8), uint8 message) {
 
 
 ### Usage
 ### Usage
 
 
-Why might one want to send a *message* between tasks?
+Why might one want to *send a message* between tasks?
 
 
 Suppose you have a rotary encoder, which sends quadrant signals, which need
 Suppose you have a rotary encoder, which sends quadrant signals, which need
 to be interpreted as *clockwise* and *counter clockwise*. You could have one
 to be interpreted as *clockwise* and *counter clockwise*. You could have one
 task devoted to determining the direction of the knob 
 task devoted to determining the direction of the knob 
-(and [debouncing](#debouncing)), and have it send clean 
+(and [debouncing](#debouncing)), and have it *send* (or *post*) clean 
 EVT_CW and EVT_CCW *messages* to its sibgling tasks.
 EVT_CW and EVT_CCW *messages* to its sibgling tasks.
 
 
 Another possible use of *messages* is to create alternate souces of input.
 Another possible use of *messages* is to create alternate souces of input.
@@ -1774,7 +1776,7 @@ assignment was to code up a simulated automobile entertainment system, which inc
 - task blue light to show bluetooth connectivity
 - task blue light to show bluetooth connectivity
 - volume up/down sense and display
 - volume up/down sense and display
 - radio channel select buttons
 - radio channel select buttons
-  - step single freq, or high-speed scan
+  - step single the radio frequency, or high-speed scan
 - power on/off management
 - power on/off management
 - remote control of volume/radio-select from the steering wheel (uart link)
 - remote control of volume/radio-select from the steering wheel (uart link)
 - backlight for night-time viewing (auto sense from a light sensor)
 - backlight for night-time viewing (auto sense from a light sensor)

+ 5 - 5
build/demo.stm32f0xx.c

@@ -127,13 +127,13 @@ void respondToButtonTask(uint8 evt) {
     case RTB_IDLE:
     case RTB_IDLE:
       if (evt == EVT_BUTTON) {
       if (evt == EVT_BUTTON) {
         rtbState      = RTB_ON;
         rtbState      = RTB_ON;
-        rtbTimerCount = 0;
+        rtbTimerCount = BUTTON_LED_ON_TIME;
         gpio_set(LED, LED_ON);
         gpio_set(LED, LED_ON);
       }
       }
       break;
       break;
     case RTB_ON:
     case RTB_ON:
       if (evt == EVT_TICK) {
       if (evt == EVT_TICK) {
-        if (++rtbTimerCount > BUTTON_LED_ON_TIME) {
+        if (--rtbTimerCount == 0) {
           gpio_set(LED, LED_OFF);
           gpio_set(LED, LED_OFF);
           rtbState = RTB_IDLE;
           rtbState = RTB_IDLE;
         }
         }
@@ -144,7 +144,7 @@ void respondToButtonTask(uint8 evt) {
 
 
 const int LED_ON_TIME  = 150;
 const int LED_ON_TIME  = 150;
 const int LED_OFF_TIME = 50;
 const int LED_OFF_TIME = 50;
-static uint8 ledState       = LED_OFF;
+static uint8  ledState      = LED_OFF;
 static uint16 ledTimerCount = 0;
 static uint16 ledTimerCount = 0;
 
 
 void ledTask(uint8 evt) {
 void ledTask(uint8 evt) {
@@ -153,14 +153,14 @@ void ledTask(uint8 evt) {
       if (evt == EVT_TICK) {
       if (evt == EVT_TICK) {
         if (++ledTimerCount > LED_OFF_TIME) {
         if (++ledTimerCount > LED_OFF_TIME) {
           gpio_set(LED2, LED_ON);
           gpio_set(LED2, LED_ON);
-          ledTimerCount = 0;
+          ledTimerCount = LED_ON_TIME;
           ledState      = LED_ON;
           ledState      = LED_ON;
         }
         }
       }
       }
       break;
       break;
     case LED_ON:
     case LED_ON:
       if (evt == EVT_TICK) {
       if (evt == EVT_TICK) {
-        if (++ledTimerCount > LED_ON_TIME) {
+        if (--ledTimerCount == 0) {
           gpio_set(LED2, LED_OFF);
           gpio_set(LED2, LED_OFF);
           ledTimerCount = 0;
           ledTimerCount = 0;
           ledState      = LED_OFF;
           ledState      = LED_OFF;