Download presentation
Presentation is loading. Please wait.
Published byGiles Carroll Modified over 9 years ago
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.