Presentation is loading. Please wait.

Presentation is loading. Please wait.

The right and wrong ways for constructing tasks for the Labs and Assignment.

Similar presentations


Presentation on theme: "The right and wrong ways for constructing tasks for the Labs and Assignment."— Presentation transcript:

1 The right and wrong ways for constructing tasks for the Labs and Assignment

2 Assignment 1 – What I suggested #define ULL unsigned long long int // Place in include / header file void main(void) { ULL currentCycleCount = ReadCycleCounter( ); ULL nextLED1ExecutionTime = currentCycleCount + ONE_SECOND ULL nextLED2ExecutionTime = currentCycleCount + TWO_SECONDS while (1) { currentCycleCount = ReadCycleCounter( ); if (nextLED1ExecutionTime < currentCycleCount) { nextLED1ExecutionTime = nextLED1ExecutionTime + ONE_SECOND LED1Task( ); } if (nextLED2ExecutionTime < currentCycleCount) { nextLED2ExecutionTime = nextLED2ExecutionTime + TWO_SECONDS LED2Task( ); } } 2 /18

3 Assignment 1 – What many did! Why is this bad programming? ULL currentCycleCount = ReadCycleCounter( ); ULL nextLED1ExecutionTime = currentCycleCount + ONE_SECOND ULL nextLED2ExecutionTime = currentCycleCount + TWO_SECONDS int led1 = 0; int led2 = 0; while (1) { currentCycleCount = ReadCycleCounter( ); if (nextLED1ExecutionTime < currentCycleCount) { nextLED1ExecutionTime = nextLED1ExecutionTime + ONE_SECOND if (led1 == 0) { My_LEDWrite(1, 1); // If off, turn on led1 = 1; } else { My_LedWrite(1, 0); // If on, turn off led1 = 0; } } 3 /18

4 Bad programming because Imagine what this code would look like with 15 tasks Too complicated – all the detail is in one piece of code Somebody reading / maintaining main( ) does not need all this detail.  That person could be you in your internship position SOLUTION Profound Procrastination Programming Proper words – Abstraction – Hide details 4 /18

5 Define CODE ERROR and CODE DEFECT Everybody is likely to make mistakes  Keep track of mistakes you make  Identify the two most common  Do code review looking for those particular errors Every project is made up of phases  If you make a mistake and find it BEFORE moving onto the next phase – CODE ERROR and EASY to find as the mistake is in last twenty lines or so  If you make a mistake and DON’T find it BEFORE moving onto the next phase – CODE DEFECT and HARD to find and fix 5 /18

6 Assignment 1 – Why does this code contain a CODE DEFECT #define ULL unsigned long long int // Place in include / header file void main(void) { ULL currentCycleCount = ReadCycleCounter( ); ULL nextLED1ExecutionTime = currentCycleCount + ONE_SECOND ULL nextLED2ExecutionTime = currentCycleCount + TWO_SECONDS while (1) { currentCycleCount = ReadCycleCounter( ); if (nextLED1ExecutionTime < currentCycleCount) { nextLED1ExecutionTime = nextLED1ExecutionTime + ONE_SECOND LED1Task( ); } if (nextLED2ExecutionTime < currentCycleCount) { nextLED2ExecutionTime = currentCycleCount + ONE_SECOND LED2Task( ); } } 6 /18

7 Define LIFE ERROR and LIFE DEFECT Everybody is likely to make mistakes  Keep track of mistakes you make  Identify the two most common  Do life review looking for those particular errors Every project is made up of phases  If you make a mistake and find it BEFORE moving onto the next phase – LIFE ERROR and EASY to find as the mistake is in last twenty minutes or so  If you make a mistake and DON’T find it BEFORE moving onto the next phase – LIFE DEFECT and HARD to fix 7 /18

8 Define DESIGN ERROR and DESIGN DEFECT Everybody is likely to make mistakes  Keep track of mistakes you make  Identify the two most common  Do design review looking for those particular errors Every project is made up of phases  If you make a mistake and find it BEFORE moving onto the next phase – DESIGN ERROR and EASY to find as the mistake is in last twenty lines or so  If you make a mistake and DON’T find it BEFORE moving onto the next phase – DESIGN DEFECT and HARD to find and fix 8 /18

9 Design and implementation of code void LED3_Task( ) // DESIGN Uses Read LED( ) and WriteLED( ) from Lab. 1 if LED3 is on turn it off if LED3 is off turn it on } WHY DOES THIS IMPLEMENTATION NOT WORK – DEFECT QUICKLY FOUND void LED3_Task( ) { bool LED3_on = true; currentLED = ReadLED_ASM( ); if (LED3_on == true) // turn off LED 3 WriteLED_ASM(currentLED & 0x4); // 0x4 is magic number for LED 3 %0100 else WriteLED_ASM(currentLED | 0x4); // 0x4 is magic number for LED 3 %0100 LED3_on = ! LED3_on } 12/19/2015TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada 9 / 28

10 Design and implementation of code void LED3_Task( ) // DESIGN Uses Read LED( ) and WriteLED( ) from Lab. 1 if LED3 is on turn it off if LED3 is off turn it on } FIXED void LED3_Task( ) { static bool LED3_on = true; // Variable is a private permaneant variable (not on stack) currentLED = ReadLED_ASM( ); if (LED3_on == true) // turn off LED 3 WriteLED_ASM(currentLED & 0x4); // 0x4 is magic number for LED 3 %0100 else WriteLED_ASM(currentLED | 0x4); // 0x4 is magic number for LED 3 %0100 LED3_on = ! LED3_on } 12/19/2015TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada 10 / 28

11 Design and implementation of code void LED3_Task( ) // DESIGN Uses Read LED( ) and WriteLED( ) from Lab. 1 if LED3 is on turn it off if LED3 is off turn it on } WHY DOES THIS IMPLEMENTATION MOST OF THE TIME void LED3_Task( ) { currentLED = ReadLED_ASM( ); int LED3_on = currentLED & 0x4; // Check if current LED is on if (LED3_on == 1) // turn off LED 3 WriteLED_ASM(currentLED & 0x4); // 0x4 is magic number for LED 3 %0100 else WriteLED_ASM(currentLED | 0x4); // 0x4 is magic number for LED 3 %0100 } 12/19/2015TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada 11 / 28

12 Why I don’t like this sort of coding void LED3_Task( ) { static bool LED3_on = true; // Variable is a private permanent variable (not on stack) currentLED = ReadLED_ASM( ); if (LED3_on == true) // turn off LED 3 WriteLED_ASM(currentLED & 0x4); // 0x4 is magic number for LED 3 %0100 else WriteLED_ASM(currentLED | 0x4); // 0x4 is magic number for LED 3 %0100 LED3_on = ! LED3_on } // Main answer – not easy to generalize when the coding gets more complicated // I want to see ‘STATES’ 12/19/2015TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada 12 / 28

13 Rewritten as States enum {UNKNOWN, LED_ON, LED_OFF} void LED3_Task( ) { static unsigned int LED3_state = LED_OFF; // Assume InitLED( ) turns LED3 off unsigned int LED3_nextState = UNKNOWN; // NOT static – very important unsigned int currentLED = ReadLEDASM( ); switch (LED3_state ) { case LED_ON: // Move from state ON to state OFF WriteLED_ASM(currentLED & 0x4); // 0x4 is magic number for LED 3 %0100 LED3_nextState = LED_OFF; break; case LED_OFF: // Move from state ON to state OFF WriteLED_ASM(currentLED | 0x4); // 0x4 is magic number for LED 3 %0100 LED3_nextState = LED_ON; break; default: SendErrorMessage(‘Should not get here\n”); } LED3_state = LED3_nextState; // Update the state } 12/19/2015TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada 13 / 28

14 Is this – a state of being ‘too clever’? #define BEGIN_STATE case #define END_STATE break #define ERROR_STATE default void LED3_Task( ) { static unsigned int LED3_state = LED_OFF; // Assume InitLED( ) turns LED3 off unsigned int LED3_nextState = UNKNOWN; // NOT static – very important unsigned int currentLED = ReadLEDASM( ); switch (LED3_state ) { BEGIN_STATE: LED_ON: // Move from state ON to state OFF WriteLED_ASM(currentLED & 0x4); // 0x4 is magic number for LED 3 %0100 LED3_nextState = LED_OFF; END_STATE; BEGIN_STATE: LED_OFF: // Move from state ON to state OFF WriteLED_ASM(currentLED | 0x4); // 0x4 is magic number for LED 3 %0100 LED3_nextState = LED_ON; END_STATE; ERROR_STATE: SendErrorMessage(‘Should not get here\n”); } LED3_state = LED3_nextState; // Update the state } 12/19/2015TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada 14 / 28

15 Design defect – too much detail Hide the detail behind an operating system #define ULL unsigned long long int // Place in include / header file void main(void) { ULL currentCycleCount = ReadCycleCounter( ); ULL nextLED1ExecutionTime = currentCycleCount + ONE_SECOND ULL nextLED2ExecutionTime = currentCycleCount + TWO_SECONDS while (1) { currentCycleCount = ReadCycleCounter( ); if (nextLED1ExecutionTime < currentCycleCount) { nextLED1ExecutionTime = nextLED1ExecutionTime + ONE_SECOND LED1Task( ); } if (nextLED2ExecutionTime < currentCycleCount) { nextLED2ExecutionTime = nextLED2ExecutionTime + TWO_SECONDS LED2Task( ); } } 15 /18

16 Using a co-operative scheduler which is responsible for handling the timing #define ONE_SECOND (44100) // Audio interrupts / sec #define TWO_SECONDS (ONE_SECOND) #define NO_DELAY (0) int main(int) { TTCOS_511Init( ); TTCOS_AddTask(InitFlash_Task, NO_DELAY, RUN_ONCE); TTCOS_AddTask(LED1Task, NO_DELAY, EVERY_SECOND); TTCOS_AddTask(LED2Task, NO_DELAY, TWO_SECONDS); TTCOS_Start( 10 + 5 ); // Allow 10 user (max 15) and 5 system threads while (1) {// Super loop TTCOS_GoToSleep( ); TTCOS_DispatchTasks( ); // Run tasks if time delay } return 0; } 12/19/2015TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada 16 / 28

17 Rules for task Two types of tasks  Pre-emptive –special, very, very time critical E.g. Store audio sample every 1 / 44000 Only pre-emptive task in our labs is ProcessData  Normal – not time critical E.g. read switch presses – every 1/ 30 is fast enough NO TASK CAN INCLUDE A WAIT All tasks must have this format void Task(void) 17 /18

18 Write tasks that change LEDs with switch presses void BadSwitchTask( ) { unsigned int switch1 = ReadSwitchASM(1); while (switch1 == 0) { switch1 = ReadSwitchASM(1); } WriteLED(1, 1); // Switch is pressed – LED on while (switch1 == 1) { switch1 = ReadSwitchASM(1); } WriteLED(1, 0); // Switch is released – LED off } // This task is said to BLOCK other tasks from running 18 /18

19 Write tasks that change LEDs with switch presses TTCOS_AddTask(BadSwitchTask, NO_DELAY; EVERY_SECOND / 30) void BadSwitchTask(void ) { unsigned int switch1 = ReadSwitchASM(1); while (switch1 == 0) { switch1 = ReadSwitchASM(1); } WriteLED(1, 1); // Switch is pressed – LED on while (switch1 == 1) { switch1 = ReadSwitchASM(1); } WriteLED(1, 0); // Switch is released – LED off } // This task is said to BLOCK other tasks from running 19 /18

20 Write tasks that change LEDs with switch presses – this code version does not block enum {PRESSED, NOT_PRESSED} void SwitchTask_NoWait(void ) { static unsigned int currentSwitch1 = NOT_PRESSED; unsigned int switch1 = ReadSwitchASM(1); // Nothing has changed – so don’t wait if ((switch1 == 0) && (currentSwitch1 = NOT_PRESSED) ) return; if ((switch1 ==1) && (currentSwitch1 = PRESSED) ) return; switch (currentSwitch1) { case NOT_PRESSED: WriteLED(1, 1); // Switch is pressed – LED on nextState = PRESSED; break; case PRESSED: WriteLED(1, 0); // Switch is released – LED off nextState = NOT_PRESSED; break; } currentSwitch1 = nextState ; } 20 /18


Download ppt "The right and wrong ways for constructing tasks for the Labs and Assignment."

Similar presentations


Ads by Google