HnPOS.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn 0 .data 00000010 00800100 00001f7e 00001ff2 2**0 CONTENTS, ALLOC, LOAD, DATA 1 .text 00001f7e 00000000 00000000 00000074 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .bss 00000069 00800110 00001f8e 00002002 2**0 ALLOC 3 .debug_aranges 00000160 00000000 00000000 00002002 2**0 CONTENTS, READONLY, DEBUGGING 4 .debug_pubnames 00001195 00000000 00000000 00002162 2**0 CONTENTS, READONLY, DEBUGGING 5 .debug_info 00003718 00000000 00000000 000032f7 2**0 CONTENTS, READONLY, DEBUGGING 6 .debug_abbrev 0000112e 00000000 00000000 00006a0f 2**0 CONTENTS, READONLY, DEBUGGING 7 .debug_line 00002420 00000000 00000000 00007b3d 2**0 CONTENTS, READONLY, DEBUGGING 8 .debug_frame 00000600 00000000 00000000 00009f60 2**2 CONTENTS, READONLY, DEBUGGING 9 .debug_str 00000d47 00000000 00000000 0000a560 2**0 CONTENTS, READONLY, DEBUGGING 10 .debug_loc 00001132 00000000 00000000 0000b2a7 2**0 CONTENTS, READONLY, DEBUGGING 11 .debug_ranges 000000a0 00000000 00000000 0000c3d9 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: 00000000 <__vectors>: 0: 0c 94 30 01 jmp 0x260 ; 0x260 <__ctors_end> 4: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 8: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> c: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 10: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 14: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 18: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 1c: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 20: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 24: 0c 94 f0 05 jmp 0xbe0 ; 0xbe0 <__vector_9> 28: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 2c: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 30: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 34: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 38: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 3c: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 40: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 44: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 48: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 4c: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 50: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 54: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 58: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 5c: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 60: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 64: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 68: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 6c: 0c 94 4d 01 jmp 0x29a ; 0x29a <__bad_interrupt> 00000070 : 70: 53 63 68 65 64 75 6c 65 72 20 73 74 61 72 74 21 Scheduler start! ... 00000081 : 81: 41 00 A. 00000083 : 83: 42 00 B. 00000085 : 85: 43 00 C. 00000087 : 87: 44 00 D. 00000089 : 89: 45 00 E. 0000008b : 8b: 46 00 F. 0000008d : 8d: 47 00 G. 0000008f : 8f: 2e 00 .. 00000091 : 91: 45 52 52 3a 20 55 4e 4b 4e 4f 57 4e 00 ERR: UNKNOWN. 0000009e : 9e: 45 52 52 3a 20 46 49 4e 49 53 48 45 44 00 ERR: FINISHED. 000000ac : ac: 45 52 52 3a 20 4d 41 58 5f 54 41 53 4b 53 00 ERR: MAX_TASKS. 000000bb : bb: 45 52 52 3a 20 41 4c 52 45 41 44 59 5f 45 58 00 ERR: ALREADY_EX. 000000cb : cb: 45 52 52 3a 20 4e 4f 5f 54 41 53 4b 53 00 ERR: NO_TASKS. 000000d9 : d9: 45 52 52 3a 20 4e 4f 54 5f 45 58 49 53 54 00 ERR: NOT_EXIST. 000000e8 : e8: 2d 53 59 53 54 45 4d 20 46 52 45 45 5a 45 44 2d -SYSTEM FREEZED- ... 000000f9 : f9: 3a 2d 28 20 3a 2d 28 20 3a 2d 28 20 3a 2d 28 00 :-( :-( :-( :-(. 00000109 : 109: 2d 3e 54 41 53 4b 4d 41 4e 41 47 45 52 3c 2d 00 ->TASKMANAGER<-. 00000119 : 119: 43 75 72 72 65 6e 74 20 54 61 73 6b 3a 20 00 Current Task: . 00000128 : 128: 2d 3e 20 53 74 61 72 74 20 54 61 73 6b 00 -> Start Task. 00000136 : 136: 2d 3e 20 4b 69 6c 6c 20 54 61 73 6b 00 -> Kill Task. 00000143 : 143: 2d 3e 20 43 68 61 6e 67 65 20 50 72 69 6f 2e 00 -> Change Prio.. 00000153 : 153: 2d 3e 20 53 65 6c 65 63 74 20 53 63 68 65 64 2e -> Select Sched. ... 00000164 : 164: 2d 3e 20 50 61 75 73 65 20 54 61 73 6b 00 -> Pause Task. 00000172 : 172: 28 50 52 45 53 53 20 45 4e 54 45 52 29 00 (PRESS ENTER). 00000180 : 180: 2d 2d 3e 20 53 65 6c 65 63 74 20 54 61 73 6b 00 --> Select Task. 00000190 : 190: 2d 2d 3e 20 53 65 74 20 56 61 6c 75 65 00 --> Set Value. 0000019e : 19e: 2d 2d 3e 20 53 65 74 20 53 74 72 61 74 65 67 79 --> Set Strategy ... 000001af : 1af: 2d 3e 20 00 -> . 000001b3 : 1b3: 2d 3e 20 73 65 6c 65 63 74 65 64 3a 20 00 -> selected: . 000001c1 : 1c1: 2d 3e 20 69 6e 76 61 6c 69 64 20 74 61 73 6b 21 -> invalid task! ... 000001d2 : 1d2: 2d 3e 20 6d 61 78 2e 20 65 78 63 65 65 64 21 00 -> max. exceed!. 000001e2 : 1e2: 2d 3e 20 73 75 63 63 65 73 73 66 75 6c 6c 79 21 -> successfully! ... 000001f3 : 1f3: 2d 3e 20 63 61 6e 63 65 6c 65 64 21 00 -> canceled!. 00000200 : 200: 2d 3e 20 6e 6f 20 61 63 74 2e 20 74 61 73 6b 21 -> no act. task! ... 00000211 : 211: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ... 00000222 : 222: 20 28 72 65 61 64 79 29 00 (ready). 0000022b : 22b: 20 28 70 61 75 73 65 64 29 00 (paused). 00000235 : 235: 4e 4f 4e 45 00 NONE. 0000023a : 23a: 45 56 45 4e 00 EVEN. 0000023f : 23f: 52 4f 55 4e 44 5f 52 4f 42 49 4e 00 ROUND_ROBIN. 0000024b : 24b: 49 4e 41 43 54 49 56 45 41 47 49 4e 47 00 INACTIVEAGING. 00000259 : 259: 52 41 4e 44 4f 4d 00 RANDOM. 00000260 <__ctors_end>: 260: 11 24 eor r1, r1 262: 1f be out 0x3f, r1 ; 63 264: cf ef ldi r28, 0xFF ; 255 266: d0 e1 ldi r29, 0x10 ; 16 268: de bf out 0x3e, r29 ; 62 26a: cd bf out 0x3d, r28 ; 61 0000026c <__do_copy_data>: 26c: 11 e0 ldi r17, 0x01 ; 1 26e: a0 e0 ldi r26, 0x00 ; 0 270: b1 e0 ldi r27, 0x01 ; 1 272: ee e7 ldi r30, 0x7E ; 126 274: ff e1 ldi r31, 0x1F ; 31 276: 02 c0 rjmp .+4 ; 0x27c <.do_copy_data_start> 00000278 <.do_copy_data_loop>: 278: 05 90 lpm r0, Z+ 27a: 0d 92 st X+, r0 0000027c <.do_copy_data_start>: 27c: a0 31 cpi r26, 0x10 ; 16 27e: b1 07 cpc r27, r17 280: d9 f7 brne .-10 ; 0x278 <.do_copy_data_loop> 00000282 <__do_clear_bss>: 282: 11 e0 ldi r17, 0x01 ; 1 284: a0 e1 ldi r26, 0x10 ; 16 286: b1 e0 ldi r27, 0x01 ; 1 288: 01 c0 rjmp .+2 ; 0x28c <.do_clear_bss_start> 0000028a <.do_clear_bss_loop>: 28a: 1d 92 st X+, r1 0000028c <.do_clear_bss_start>: 28c: a9 37 cpi r26, 0x79 ; 121 28e: b1 07 cpc r27, r17 290: e1 f7 brne .-8 ; 0x28a <.do_clear_bss_loop> 292: 0e 94 88 03 call 0x710 ; 0x710
296: 0c 94 bd 0f jmp 0x1f7a ; 0x1f7a <_exit> 0000029a <__bad_interrupt>: 29a: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> 0000029e : /*! * Function that may be used to wait for specific time intervals. * \param ms The time to be waited in millisecond. */ void delayMs( unsigned int ms ) { 29e: 9c 01 movw r18, r24 2a0: 36 95 lsr r19 2a2: 27 95 ror r18 2a4: 36 95 lsr r19 2a6: 27 95 ror r18 if (SIMULATION) { ms >>= 2; // speed things up a bit to compensate for the simulation overhead while( ms > 0 ) 2a8: 21 15 cp r18, r1 2aa: 31 05 cpc r19, r1 2ac: 39 f0 breq .+14 ; 0x2bc { TCNT0 = 0; 2ae: 16 bc out 0x26, r1 ; 38 while( TCNT0 < 6 ){;} // 6 Timer-Ticks ~ 1ms on contemporary machines 2b0: 86 b5 in r24, 0x26 ; 38 2b2: 86 30 cpi r24, 0x06 ; 6 2b4: e8 f3 brcs .-6 ; 0x2b0 ms--; 2b6: 21 50 subi r18, 0x01 ; 1 2b8: 30 40 sbci r19, 0x00 ; 0 void delayMs( unsigned int ms ) { if (SIMULATION) { ms >>= 2; // speed things up a bit to compensate for the simulation overhead while( ms > 0 ) 2ba: c9 f7 brne .-14 ; 0x2ae 2bc: 08 95 ret 000002be : i = (i == 1 ? 2 : 1); } } void assert_force (bool exp, const char *errormsg) { 2be: 08 95 ret 000002c0 : /*! * Call this function to irreversibly freeze the whole system */ void freeze( void ) { 2c0: cf 93 push r28 2c2: df 93 push r29 cli(); 2c4: f8 94 cli 2c6: c1 e0 ldi r28, 0x01 ; 1 2c8: d0 e0 ldi r29, 0x00 ; 0 int i = 1; while (1) { lcd_clear(); 2ca: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_goto(i,0); 2ce: 60 e0 ldi r22, 0x00 ; 0 2d0: 8c 2f mov r24, r28 2d2: 0e 94 a5 01 call 0x34a ; 0x34a lcd_progString((i == 1 ? strF1 : strF2)); 2d6: c1 30 cpi r28, 0x01 ; 1 2d8: d1 05 cpc r29, r1 2da: 91 f0 breq .+36 ; 0x300 2dc: 89 ef ldi r24, 0xF9 ; 249 2de: 90 e0 ldi r25, 0x00 ; 0 2e0: 0e 94 2f 03 call 0x65e ; 0x65e 2e4: 26 e9 ldi r18, 0x96 ; 150 2e6: 30 e0 ldi r19, 0x00 ; 0 if (SIMULATION) { ms >>= 2; // speed things up a bit to compensate for the simulation overhead while( ms > 0 ) { TCNT0 = 0; 2e8: 16 bc out 0x26, r1 ; 38 while( TCNT0 < 6 ){;} // 6 Timer-Ticks ~ 1ms on contemporary machines 2ea: 86 b5 in r24, 0x26 ; 38 2ec: 86 30 cpi r24, 0x06 ; 6 2ee: e8 f3 brcs .-6 ; 0x2ea ms--; 2f0: 21 50 subi r18, 0x01 ; 1 2f2: 30 40 sbci r19, 0x00 ; 0 void delayMs( unsigned int ms ) { if (SIMULATION) { ms >>= 2; // speed things up a bit to compensate for the simulation overhead while( ms > 0 ) 2f4: c9 f7 brne .-14 ; 0x2e8 { lcd_clear(); lcd_goto(i,0); lcd_progString((i == 1 ? strF1 : strF2)); delayMs(600); i = (i == 1 ? 2 : 1); 2f6: 21 97 sbiw r28, 0x01 ; 1 2f8: 31 f0 breq .+12 ; 0x306 2fa: c1 e0 ldi r28, 0x01 ; 1 2fc: d0 e0 ldi r29, 0x00 ; 0 2fe: e5 cf rjmp .-54 ; 0x2ca int i = 1; while (1) { lcd_clear(); lcd_goto(i,0); lcd_progString((i == 1 ? strF1 : strF2)); 300: 88 ee ldi r24, 0xE8 ; 232 302: 90 e0 ldi r25, 0x00 ; 0 304: ed cf rjmp .-38 ; 0x2e0 /*! * Call this function to irreversibly freeze the whole system */ void freeze( void ) { cli(); 306: c2 e0 ldi r28, 0x02 ; 2 308: d0 e0 ldi r29, 0x00 ; 0 30a: df cf rjmp .-66 ; 0x2ca 0000030c : /*! * Internally used to turn on LCD Port E for 1us. * \internal */ extern void lcd_enable(void) { 30c: 2d 9a sbi 0x05, 5 ; 5 can be achieved. */ void _delay_loop_1(uint8_t __count) { __asm__ volatile ( 30e: 86 e0 ldi r24, 0x06 ; 6 310: 8a 95 dec r24 312: f1 f7 brne .-4 ; 0x310 sbi(LCD_PORT_DATA,5); //enable _delay_us(1); cbi(LCD_PORT_DATA,5); //disable 314: 2d 98 cbi 0x05, 5 ; 5 return; } 316: 08 95 ret 00000318 : * This function is used by lcd_command and lcd_putByte. * \param firstByte The first value to send. * \param secondByte The second value to send. */ void lcd_sendStream(unsigned char firstByte, unsigned char secondByte) { 318: 9f b7 in r25, 0x3f ; 63 // check if interrupts are set and store that state bool isInterrupt = SREG >> 7; // interrupts off cli(); 31a: f8 94 cli // transmit command: LCD_PORT_DDR = 0xFF; } // send first Byte LCD_PORT_DATA = firstByte; 31c: 85 b9 out 0x05, r24 ; 5 * Internally used to turn on LCD Port E for 1us. * \internal */ extern void lcd_enable(void) { sbi(LCD_PORT_DATA,5); //enable 31e: 2d 9a sbi 0x05, 5 ; 5 320: 86 e0 ldi r24, 0x06 ; 6 322: 28 2f mov r18, r24 324: 2a 95 dec r18 326: f1 f7 brne .-4 ; 0x324 _delay_us(1); cbi(LCD_PORT_DATA,5); //disable 328: 2d 98 cbi 0x05, 5 ; 5 // send first Byte LCD_PORT_DATA = firstByte; lcd_enable(); // send second Byte LCD_PORT_DATA = secondByte; 32a: 65 b9 out 0x05, r22 ; 5 * Internally used to turn on LCD Port E for 1us. * \internal */ extern void lcd_enable(void) { sbi(LCD_PORT_DATA,5); //enable 32c: 2d 9a sbi 0x05, 5 ; 5 32e: 8a 95 dec r24 330: f1 f7 brne .-4 ; 0x32e _delay_us(1); cbi(LCD_PORT_DATA,5); //disable 332: 2d 98 cbi 0x05, 5 ; 5 // send second Byte LCD_PORT_DATA = secondByte; lcd_enable(); // restore interrupt flag if(isInterrupt) 334: 97 ff sbrs r25, 7 336: 08 95 ret sei(); 338: 78 94 sei 33a: 08 95 ret 0000033c : * capsulated within the other functions. * \param command The command to be executed. * \internal */ extern void lcd_command(unsigned char command) { 33c: 68 2f mov r22, r24 33e: 6f 70 andi r22, 0x0F ; 15 340: 82 95 swap r24 342: 8f 70 andi r24, 0x0F ; 15 344: 0e 94 8c 01 call 0x318 ; 0x318 lcd_sendStream((command >> 4) & 0x0F, command & 0x0F); } 348: 08 95 ret 0000034a : * counting at 1, so (1,1) is top left, (2,16) is bottom right. * \param row The row to jump to (may be 1 or 2). * \param column The column to jump to (may be 1...16). */ extern void lcd_goto(unsigned char row, unsigned char column) { 34a: 28 2f mov r18, r24 34c: 21 50 subi r18, 0x01 ; 1 34e: 22 30 cpi r18, 0x02 ; 2 350: 68 f0 brcs .+26 ; 0x36c 352: 80 e8 ldi r24, 0x80 ; 128 354: 20 e0 ldi r18, 0x00 ; 0 // restrict params to valid values if(--row>1) row=0; if(--column>15) 356: 61 50 subi r22, 0x01 ; 1 358: 60 31 cpi r22, 0x10 ; 16 35a: 08 f0 brcs .+2 ; 0x35e 35c: 60 e0 ldi r22, 0x00 ; 0 // calculate position and get command char command = LCD_CURSOR_MOVE_R + column + row*LCD_NEXT_ROW; // update char counter charCtr=row*16+column; 35e: 26 0f add r18, r22 360: 20 93 74 01 sts 0x0174, r18 lcd_command(command); 364: 86 0f add r24, r22 366: 0e 94 9e 01 call 0x33c ; 0x33c return; } 36a: 08 95 ret * \param column The column to jump to (may be 1...16). */ extern void lcd_goto(unsigned char row, unsigned char column) { // restrict params to valid values if(--row>1) 36c: 30 e0 ldi r19, 0x00 ; 0 36e: c9 01 movw r24, r18 370: 00 24 eor r0, r0 372: 96 95 lsr r25 374: 87 95 ror r24 376: 07 94 ror r0 378: 96 95 lsr r25 37a: 87 95 ror r24 37c: 07 94 ror r0 37e: 98 2f mov r25, r24 380: 80 2d mov r24, r0 382: 80 58 subi r24, 0x80 ; 128 384: 22 95 swap r18 386: 20 7f andi r18, 0xF0 ; 240 388: e6 cf rjmp .-52 ; 0x356 0000038a : /*! * Moves the cursor to the first character of the second line of the LCD. */ extern void lcd_line2(void) { 38a: 80 ec ldi r24, 0xC0 ; 192 38c: 0e 94 9e 01 call 0x33c ; 0x33c lcd_command(LCD_LINE_2); charCtr=16; 390: 80 e1 ldi r24, 0x10 ; 16 392: 80 93 74 01 sts 0x0174, r24 return; } 396: 08 95 ret 00000398 : /*! * Moves the cursor to the first character of the first line of the LCD. */ extern void lcd_line1(void) { 398: 80 e8 ldi r24, 0x80 ; 128 39a: 0e 94 9e 01 call 0x33c ; 0x33c lcd_command(LCD_LINE_1); charCtr=0; 39e: 10 92 74 01 sts 0x0174, r1 return; } 3a2: 08 95 ret 000003a4 : /*! * Erases the LCD and positiones the cursor at the top left corner. */ extern void lcd_clear(void) { 3a4: 10 92 74 01 sts 0x0174, r1 charCtr = 0; lcd_command(LCD_CLEAR); 3a8: 81 e0 ldi r24, 0x01 ; 1 3aa: 0e 94 9e 01 call 0x33c ; 0x33c return; } 3ae: 08 95 ret 000003b0 : * Writes an 8-Bit ASCII-value to the LCD. * Features automatic line breaks. * \param character The character to be written. */ extern void lcd_putByte(char character) { 3b0: 0f 93 push r16 3b2: 1f 93 push r17 3b4: 18 2f mov r17, r24 // check if interrupts are set and store that state bool isInterrupt = SREG >> 7; 3b6: 0f b7 in r16, 0x3f ; 63 cli(); 3b8: f8 94 cli // check if line shall be changed if (character=='\n') 3ba: 8a 30 cpi r24, 0x0A ; 10 3bc: 81 f1 breq .+96 ; 0x41e 3be: 80 91 74 01 lds r24, 0x0174 charCtr = (charCtr & 0x10)+0x10; // <16 -> 16, <32 -> 32 if (charCtr == 0x10) 3c2: 80 31 cpi r24, 0x10 ; 16 3c4: a1 f1 breq .+104 ; 0x42e lcd_line2(); if (charCtr == 0x20) 3c6: 80 32 cpi r24, 0x20 ; 32 3c8: c1 f1 breq .+112 ; 0x43a { lcd_clear(); lcd_line1(); } if(character!='\n') 3ca: 1a 30 cpi r17, 0x0A ; 10 3cc: 01 f1 breq .+64 ; 0x40e { // check for non-ASCII characters the LCD knows if(character=='ä') 3ce: 14 3e cpi r17, 0xE4 ; 228 3d0: 21 f1 breq .+72 ; 0x41a character = -31; if(character=='ö') 3d2: 16 3f cpi r17, 0xF6 ; 246 3d4: b9 f1 breq .+110 ; 0x444 character = -17; if(character=='ü') 3d6: 1c 3f cpi r17, 0xFC ; 252 3d8: b9 f5 brne .+110 ; 0x448 3da: 15 ef ldi r17, 0xF5 ; 245 character = -11; if(character=='ß') 3dc: 61 2f mov r22, r17 3de: 6f 70 andi r22, 0x0F ; 15 3e0: 60 61 ori r22, 0x10 ; 16 3e2: 81 2f mov r24, r17 3e4: 99 27 eor r25, r25 3e6: 87 fd sbrc r24, 7 3e8: 90 95 com r25 3ea: 80 7f andi r24, 0xF0 ; 240 3ec: 90 70 andi r25, 0x00 ; 0 3ee: 95 95 asr r25 3f0: 87 95 ror r24 3f2: 95 95 asr r25 3f4: 87 95 ror r24 3f6: 95 95 asr r25 3f8: 87 95 ror r24 3fa: 95 95 asr r25 3fc: 87 95 ror r24 3fe: 80 61 ori r24, 0x10 ; 16 character = -30; lcd_sendStream(0x10 | ((character & 0xF0) >> 4), 0x10 | (character & 0x0F) ); 400: 0e 94 8c 01 call 0x318 ; 0x318 // update char counter ... Do not modulo it down! we need it to become 32 charCtr++; 404: 80 91 74 01 lds r24, 0x0174 408: 8f 5f subi r24, 0xFF ; 255 40a: 80 93 74 01 sts 0x0174, r24 } // restore interrupt flags if(isInterrupt) 40e: 07 ff sbrs r16, 7 410: 01 c0 rjmp .+2 ; 0x414 sei(); 412: 78 94 sei return; } 414: 1f 91 pop r17 416: 0f 91 pop r16 418: 08 95 ret } if(character!='\n') { // check for non-ASCII characters the LCD knows if(character=='ä') 41a: 11 ee ldi r17, 0xE1 ; 225 41c: df cf rjmp .-66 ; 0x3dc bool isInterrupt = SREG >> 7; cli(); // check if line shall be changed if (character=='\n') charCtr = (charCtr & 0x10)+0x10; // <16 -> 16, <32 -> 32 41e: 80 91 74 01 lds r24, 0x0174 422: 80 71 andi r24, 0x10 ; 16 424: 80 5f subi r24, 0xF0 ; 240 426: 80 93 74 01 sts 0x0174, r24 if (charCtr == 0x10) 42a: 80 31 cpi r24, 0x10 ; 16 42c: 61 f6 brne .-104 ; 0x3c6 lcd_line2(); 42e: 0e 94 c5 01 call 0x38a ; 0x38a 432: 80 91 74 01 lds r24, 0x0174 if (charCtr == 0x20) 436: 80 32 cpi r24, 0x20 ; 32 438: 41 f6 brne .-112 ; 0x3ca { lcd_clear(); 43a: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_line1(); 43e: 0e 94 cc 01 call 0x398 ; 0x398 442: c3 cf rjmp .-122 ; 0x3ca if(character!='\n') { // check for non-ASCII characters the LCD knows if(character=='ä') character = -31; if(character=='ö') 444: 1f ee ldi r17, 0xEF ; 239 446: ca cf rjmp .-108 ; 0x3dc character = -17; if(character=='ü') character = -11; if(character=='ß') 448: 1f 3d cpi r17, 0xDF ; 223 44a: 41 f6 brne .-112 ; 0x3dc 44c: 62 e1 ldi r22, 0x12 ; 18 44e: 8e e1 ldi r24, 0x1E ; 30 450: d7 cf rjmp .-82 ; 0x400 00000452 : /*! * Erases one line of the LCD. Cursor will not be changed. * \param line the line which will be erased (may be 1 or 2). */ extern void lcd_erase(unsigned char line) { 452: 0f 93 push r16 454: 1f 93 push r17 // save counter unsigned char i=0, oldCtr = charCtr; 456: 00 91 74 01 lds r16, 0x0174 // restrict param to a valid value if (line > 2) 45a: 83 30 cpi r24, 0x03 ; 3 45c: 08 f0 brcs .+2 ; 0x460 45e: 81 e0 ldi r24, 0x01 ; 1 line = 1; // go to the beginning of line lcd_goto(line, 1); 460: 61 e0 ldi r22, 0x01 ; 1 462: 0e 94 a5 01 call 0x34a ; 0x34a 466: 10 e0 ldi r17, 0x00 ; 0 // clear the line for(i=0; i<16; i++) lcd_putByte(' '); 468: 80 e2 ldi r24, 0x20 ; 32 46a: 0e 94 d8 01 call 0x3b0 ; 0x3b0 if (line > 2) line = 1; // go to the beginning of line lcd_goto(line, 1); // clear the line for(i=0; i<16; i++) 46e: 1f 5f subi r17, 0xFF ; 255 470: 10 31 cpi r17, 0x10 ; 16 472: d1 f7 brne .-12 ; 0x468 lcd_putByte(' '); // restore counter charCtr = oldCtr; 474: 00 93 74 01 sts 0x0174, r16 // restore cursor lcd_goto((charCtr/16)+1, (charCtr%16)+1); 478: 60 2f mov r22, r16 47a: 6f 70 andi r22, 0x0F ; 15 47c: 6f 5f subi r22, 0xFF ; 255 47e: 02 95 swap r16 480: 0f 70 andi r16, 0x0F ; 15 482: 80 2f mov r24, r16 484: 8f 5f subi r24, 0xFF ; 255 486: 0e 94 a5 01 call 0x34a ; 0x34a return; } 48a: 1f 91 pop r17 48c: 0f 91 pop r16 48e: 08 95 ret 00000490 : * Writes a hexadecimal half-byte (one nibble) * \param number The number to be written. * \param prefix Writes 0x as prefix if true. */ extern void lcd_writeHexNibble(unsigned char number, bool prefix) { 490: 1f 93 push r17 492: 18 2f mov r17, r24 if(prefix) 494: 66 23 and r22, r22 496: 71 f4 brne .+28 ; 0x4b4 lcd_putByte('0'); lcd_putByte('x'); } // get low and high nibble unsigned char low = number & 0xF; 498: 81 2f mov r24, r17 49a: 8f 70 andi r24, 0x0F ; 15 if(low<10) 49c: 8a 30 cpi r24, 0x0A ; 10 49e: 28 f0 brcs .+10 ; 0x4aa lcd_putByte(low+'0'); // write as ASCII number else lcd_putByte(low-10 +'A'); // write as ASCII letter 4a0: 89 5c subi r24, 0xC9 ; 201 4a2: 0e 94 d8 01 call 0x3b0 ; 0x3b0 return; } 4a6: 1f 91 pop r17 4a8: 08 95 ret // get low and high nibble unsigned char low = number & 0xF; if(low<10) lcd_putByte(low+'0'); // write as ASCII number 4aa: 80 5d subi r24, 0xD0 ; 208 4ac: 0e 94 d8 01 call 0x3b0 ; 0x3b0 else lcd_putByte(low-10 +'A'); // write as ASCII letter return; } 4b0: 1f 91 pop r17 4b2: 08 95 ret */ extern void lcd_writeHexNibble(unsigned char number, bool prefix) { if(prefix) { lcd_putByte('0'); 4b4: 80 e3 ldi r24, 0x30 ; 48 4b6: 0e 94 d8 01 call 0x3b0 ; 0x3b0 lcd_putByte('x'); 4ba: 88 e7 ldi r24, 0x78 ; 120 4bc: 0e 94 d8 01 call 0x3b0 ; 0x3b0 4c0: eb cf rjmp .-42 ; 0x498 000004c2 : * Writes a hexadecimal byte (equals two chars) * \param number The number to be written. * \param prefix Writes 0x as prefix if true. */ extern void lcd_writeHex(unsigned char number, bool prefix) { 4c2: 0f 93 push r16 4c4: 1f 93 push r17 4c6: 08 2f mov r16, r24 if(prefix) 4c8: 66 23 and r22, r22 4ca: f9 f4 brne .+62 ; 0x50a lcd_putByte('0'); lcd_putByte('x'); } // get low and high nibble unsigned char low = number & 0x0F; 4cc: 10 2f mov r17, r16 4ce: 1f 70 andi r17, 0x0F ; 15 unsigned char high = number >> 4; 4d0: 80 2f mov r24, r16 4d2: 82 95 swap r24 4d4: 8f 70 andi r24, 0x0F ; 15 if(high<10) 4d6: 8a 30 cpi r24, 0x0A ; 10 4d8: 60 f4 brcc .+24 ; 0x4f2 lcd_putByte(high+'0'); // write as ASCII number 4da: 80 5d subi r24, 0xD0 ; 208 4dc: 0e 94 d8 01 call 0x3b0 ; 0x3b0 else lcd_putByte(high-10 +'A'); // write as ASCII letter if(low<10) 4e0: 1a 30 cpi r17, 0x0A ; 10 4e2: 60 f0 brcs .+24 ; 0x4fc lcd_putByte(low+'0'); // write as ASCII number else lcd_putByte(low-10 +'A'); // write as ASCII letter 4e4: 81 2f mov r24, r17 4e6: 89 5c subi r24, 0xC9 ; 201 4e8: 0e 94 d8 01 call 0x3b0 ; 0x3b0 return; } 4ec: 1f 91 pop r17 4ee: 0f 91 pop r16 4f0: 08 95 ret unsigned char high = number >> 4; if(high<10) lcd_putByte(high+'0'); // write as ASCII number else lcd_putByte(high-10 +'A'); // write as ASCII letter 4f2: 89 5c subi r24, 0xC9 ; 201 4f4: 0e 94 d8 01 call 0x3b0 ; 0x3b0 if(low<10) 4f8: 1a 30 cpi r17, 0x0A ; 10 4fa: a0 f7 brcc .-24 ; 0x4e4 lcd_putByte(low+'0'); // write as ASCII number 4fc: 81 2f mov r24, r17 4fe: 80 5d subi r24, 0xD0 ; 208 500: 0e 94 d8 01 call 0x3b0 ; 0x3b0 else lcd_putByte(low-10 +'A'); // write as ASCII letter return; } 504: 1f 91 pop r17 506: 0f 91 pop r16 508: 08 95 ret */ extern void lcd_writeHex(unsigned char number, bool prefix) { if(prefix) { lcd_putByte('0'); 50a: 80 e3 ldi r24, 0x30 ; 48 50c: 0e 94 d8 01 call 0x3b0 ; 0x3b0 lcd_putByte('x'); 510: 88 e7 ldi r24, 0x78 ; 120 512: 0e 94 d8 01 call 0x3b0 ; 0x3b0 516: da cf rjmp .-76 ; 0x4cc 00000518 : /*! * Writes an int as a number */ extern void lcd_writeNumber(unsigned int number) { 518: 0f 93 push r16 51a: 1f 93 push r17 51c: cf 93 push r28 51e: df 93 push r29 520: ec 01 movw r28, r24 if (!number) 522: 00 97 sbiw r24, 0x00 ; 0 524: d1 f1 breq .+116 ; 0x59a lcd_putByte('0'); return; } unsigned int digit = 10000; unsigned int nextDigit; //used for optimisation (division is expensive!) while (digit>number) 526: 87 e2 ldi r24, 0x27 ; 39 528: c0 31 cpi r28, 0x10 ; 16 52a: d8 07 cpc r29, r24 52c: f0 f5 brcc .+124 ; 0x5aa extern void lcd_writeNumber(unsigned int number) { if (!number) { lcd_putByte('0'); return; 52e: 80 e1 ldi r24, 0x10 ; 16 530: 97 e2 ldi r25, 0x27 ; 39 } unsigned int digit = 10000; unsigned int nextDigit; //used for optimisation (division is expensive!) while (digit>number) digit /= 10; //ommit leading zeros 532: 6a e0 ldi r22, 0x0A ; 10 534: 70 e0 ldi r23, 0x00 ; 0 536: 0e 94 03 0f call 0x1e06 ; 0x1e06 <__udivmodhi4> 53a: cb 01 movw r24, r22 lcd_putByte('0'); return; } unsigned int digit = 10000; unsigned int nextDigit; //used for optimisation (division is expensive!) while (digit>number) 53c: c6 17 cp r28, r22 53e: d7 07 cpc r29, r23 540: c0 f3 brcs .-16 ; 0x532 digit /= 10; //ommit leading zeros digit *= 10; 542: 9b 01 movw r18, r22 544: 22 0f add r18, r18 546: 33 1f adc r19, r19 548: 22 0f add r18, r18 54a: 33 1f adc r19, r19 54c: 22 0f add r18, r18 54e: 33 1f adc r19, r19 550: 88 0f add r24, r24 552: 99 1f adc r25, r25 554: 28 0f add r18, r24 556: 39 1f adc r19, r25 while (digit > 1) 558: 22 30 cpi r18, 0x02 ; 2 55a: 31 05 cpc r19, r1 55c: c8 f0 brcs .+50 ; 0x590 { nextDigit = digit / 10; 55e: c9 01 movw r24, r18 560: 6a e0 ldi r22, 0x0A ; 10 562: 70 e0 ldi r23, 0x00 ; 0 564: 0e 94 03 0f call 0x1e06 ; 0x1e06 <__udivmodhi4> 568: 16 2f mov r17, r22 56a: 07 2f mov r16, r23 lcd_putByte('0'+((number % digit) / nextDigit)); 56c: ce 01 movw r24, r28 56e: b9 01 movw r22, r18 570: 0e 94 03 0f call 0x1e06 ; 0x1e06 <__udivmodhi4> 574: 61 2f mov r22, r17 576: 70 2f mov r23, r16 578: 0e 94 03 0f call 0x1e06 ; 0x1e06 <__udivmodhi4> 57c: 86 2f mov r24, r22 57e: 80 5d subi r24, 0xD0 ; 208 580: 0e 94 d8 01 call 0x3b0 ; 0x3b0 584: 81 2f mov r24, r17 586: 90 2f mov r25, r16 588: 9c 01 movw r18, r24 unsigned int digit = 10000; unsigned int nextDigit; //used for optimisation (division is expensive!) while (digit>number) digit /= 10; //ommit leading zeros digit *= 10; while (digit > 1) 58a: 22 30 cpi r18, 0x02 ; 2 58c: 31 05 cpc r19, r1 58e: 38 f7 brcc .-50 ; 0x55e nextDigit = digit / 10; lcd_putByte('0'+((number % digit) / nextDigit)); digit = nextDigit; } return; } 590: df 91 pop r29 592: cf 91 pop r28 594: 1f 91 pop r17 596: 0f 91 pop r16 598: 08 95 ret */ extern void lcd_writeNumber(unsigned int number) { if (!number) { lcd_putByte('0'); 59a: 80 e3 ldi r24, 0x30 ; 48 59c: 0e 94 d8 01 call 0x3b0 ; 0x3b0 nextDigit = digit / 10; lcd_putByte('0'+((number % digit) / nextDigit)); digit = nextDigit; } return; } 5a0: df 91 pop r29 5a2: cf 91 pop r28 5a4: 1f 91 pop r17 5a6: 0f 91 pop r16 5a8: 08 95 ret lcd_putByte('0'); return; } unsigned int digit = 10000; unsigned int nextDigit; //used for optimisation (division is expensive!) while (digit>number) 5aa: 20 ea ldi r18, 0xA0 ; 160 5ac: 36 e8 ldi r19, 0x86 ; 134 5ae: d7 cf rjmp .-82 ; 0x55e 000005b0 : * terminated correctly. * \param text The string to be written (a pointer to the first * character). */ extern void lcd_overwriteString(const char* text) { 5b0: cf 93 push r28 5b2: df 93 push r29 5b4: fc 01 movw r30, r24 char character; while((character = *text++)) 5b6: 80 81 ld r24, Z 5b8: 88 23 and r24, r24 5ba: 39 f0 breq .+14 ; 0x5ca 5bc: ef 01 movw r28, r30 { // write char lcd_putByte(character); 5be: 0e 94 d8 01 call 0x3b0 ; 0x3b0 * character). */ extern void lcd_overwriteString(const char* text) { char character; while((character = *text++)) 5c2: 89 81 ldd r24, Y+1 ; 0x01 5c4: 21 96 adiw r28, 0x01 ; 1 5c6: 88 23 and r24, r24 5c8: d1 f7 brne .-12 ; 0x5be { // write char lcd_putByte(character); } return; } 5ca: df 91 pop r29 5cc: cf 91 pop r28 5ce: 08 95 ret 000005d0 : * terminated correctly. * \param text The string to be written (a pointer to the first * character). */ extern void lcd_writeString(const char* text) { 5d0: 1f 93 push r17 5d2: cf 93 push r28 5d4: df 93 push r29 5d6: fc 01 movw r30, r24 char character; while((character = *text++)) 5d8: 10 81 ld r17, Z 5da: 11 23 and r17, r17 5dc: d9 f0 breq .+54 ; 0x614 5de: ec 01 movw r28, r24 5e0: 07 c0 rjmp .+14 ; 0x5f0 if(charCtr==16 || charCtr==32) { lcd_erase((charCtr/16)+1); } // write char lcd_putByte(character); 5e2: 81 2f mov r24, r17 5e4: 0e 94 d8 01 call 0x3b0 ; 0x3b0 * character). */ extern void lcd_writeString(const char* text) { char character; while((character = *text++)) 5e8: 19 81 ldd r17, Y+1 ; 0x01 5ea: 21 96 adiw r28, 0x01 ; 1 5ec: 11 23 and r17, r17 5ee: 91 f0 breq .+36 ; 0x614 { // start again at line1 if(charCtr==16 || charCtr==32) 5f0: 80 91 74 01 lds r24, 0x0174 5f4: 80 31 cpi r24, 0x10 ; 16 5f6: 11 f0 breq .+4 ; 0x5fc 5f8: 80 32 cpi r24, 0x20 ; 32 5fa: 99 f7 brne .-26 ; 0x5e2 { lcd_erase((charCtr/16)+1); 5fc: 82 95 swap r24 5fe: 8f 70 andi r24, 0x0F ; 15 600: 8f 5f subi r24, 0xFF ; 255 602: 0e 94 29 02 call 0x452 ; 0x452 } // write char lcd_putByte(character); 606: 81 2f mov r24, r17 608: 0e 94 d8 01 call 0x3b0 ; 0x3b0 * character). */ extern void lcd_writeString(const char* text) { char character; while((character = *text++)) 60c: 19 81 ldd r17, Y+1 ; 0x01 60e: 21 96 adiw r28, 0x01 ; 1 610: 11 23 and r17, r17 612: 71 f7 brne .-36 ; 0x5f0 } // write char lcd_putByte(character); } return; } 614: df 91 pop r29 616: cf 91 pop r28 618: 1f 91 pop r17 61a: 08 95 ret 0000061c : /*! * Writes a drawbar * \param percent Percent of drawbar to be drawn */ extern void lcd_drawBar(unsigned char percent) { 61c: 0f 93 push r16 61e: 1f 93 push r17 620: cf 93 push r28 622: df 93 push r29 624: 18 2f mov r17, r24 lcd_clear(); 626: 0e 94 d2 01 call 0x3a4 ; 0x3a4 // calculate number of bars unsigned int val = percent; 62a: 01 2f mov r16, r17 62c: 10 e0 ldi r17, 0x00 ; 0 val *= 16; // 16 Bars are possible on the Display 62e: 02 95 swap r16 630: 12 95 swap r17 632: 10 7f andi r17, 0xF0 ; 240 634: 10 27 eor r17, r16 636: 00 7f andi r16, 0xF0 ; 240 638: 10 27 eor r17, r16 unsigned int i=0; // draw bars for(i=0; i 640: c0 e0 ldi r28, 0x00 ; 0 642: d0 e0 ldi r29, 0x00 ; 0 lcd_putByte(LCD_CHAR_BAR); 644: 8f ef ldi r24, 0xFF ; 255 646: 0e 94 d8 01 call 0x3b0 ; 0x3b0 // calculate number of bars unsigned int val = percent; val *= 16; // 16 Bars are possible on the Display unsigned int i=0; // draw bars for(i=0; i lcd_putByte(LCD_CHAR_BAR); } 654: df 91 pop r29 656: cf 91 pop r28 658: 1f 91 pop r17 65a: 0f 91 pop r16 65c: 08 95 ret 0000065e : * This is a mighty tool for saving SRAM memory. * \param string The string to be written (a pointer to the first * character). */ extern void lcd_progString(const prog_char* string) { 65e: 0f 93 push r16 660: 1f 93 push r17 662: cf 93 push r28 664: df 93 push r29 666: 8c 01 movw r16, r24 668: c0 e0 ldi r28, 0x00 ; 0 66a: d0 e0 ldi r29, 0x00 ; 0 unsigned char i = 0; for (i = 0; i < 32; i++) { char c = (char) pgm_read_byte (string); 66c: f8 01 movw r30, r16 66e: ec 0f add r30, r28 670: fd 1f adc r31, r29 672: 84 91 lpm r24, Z+ if ( c != '\0' ) 674: 88 23 and r24, r24 676: 29 f4 brne .+10 ; 0x682 { i = 32; } string++; } } 678: df 91 pop r29 67a: cf 91 pop r28 67c: 1f 91 pop r17 67e: 0f 91 pop r16 680: 08 95 ret for (i = 0; i < 32; i++) { char c = (char) pgm_read_byte (string); if ( c != '\0' ) { lcd_putByte(c); 682: 0e 94 d8 01 call 0x3b0 ; 0x3b0 delayMs(1); 686: 81 e0 ldi r24, 0x01 ; 1 688: 90 e0 ldi r25, 0x00 ; 0 68a: 0e 94 4f 01 call 0x29e ; 0x29e 68e: 21 96 adiw r28, 0x01 ; 1 * character). */ extern void lcd_progString(const prog_char* string) { unsigned char i = 0; for (i = 0; i < 32; i++) 690: c0 32 cpi r28, 0x20 ; 32 692: d1 05 cpc r29, r1 694: 59 f7 brne .-42 ; 0x66c 696: f0 cf rjmp .-32 ; 0x678 00000698 : /*! * Readies the LCD to be used with the defined output-port. * Delay times as specified with some reserve */ extern void lcd_init(void) { 698: 1f 93 push r17 // write on LCD Port (reading is not needed) LCD_PORT_DDR = 0xFF; 69a: 8f ef ldi r24, 0xFF ; 255 69c: 84 b9 out 0x04, r24 ; 4 // init routine (see specifications) delayMs(15); 69e: 8f e0 ldi r24, 0x0F ; 15 6a0: 90 e0 ldi r25, 0x00 ; 0 6a2: 0e 94 4f 01 call 0x29e ; 0x29e LCD_PORT_DATA = LCD_INIT; 6a6: 83 e0 ldi r24, 0x03 ; 3 6a8: 85 b9 out 0x05, r24 ; 5 * Internally used to turn on LCD Port E for 1us. * \internal */ extern void lcd_enable(void) { sbi(LCD_PORT_DATA,5); //enable 6aa: 2d 9a sbi 0x05, 5 ; 5 6ac: 16 e0 ldi r17, 0x06 ; 6 6ae: 81 2f mov r24, r17 6b0: 8a 95 dec r24 6b2: f1 f7 brne .-4 ; 0x6b0 _delay_us(1); cbi(LCD_PORT_DATA,5); //disable 6b4: 2d 98 cbi 0x05, 5 ; 5 LCD_PORT_DDR = 0xFF; // init routine (see specifications) delayMs(15); LCD_PORT_DATA = LCD_INIT; lcd_enable(); delayMs(5); 6b6: 85 e0 ldi r24, 0x05 ; 5 6b8: 90 e0 ldi r25, 0x00 ; 0 6ba: 0e 94 4f 01 call 0x29e ; 0x29e * Internally used to turn on LCD Port E for 1us. * \internal */ extern void lcd_enable(void) { sbi(LCD_PORT_DATA,5); //enable 6be: 2d 9a sbi 0x05, 5 ; 5 6c0: 81 2f mov r24, r17 6c2: 8a 95 dec r24 6c4: f1 f7 brne .-4 ; 0x6c2 _delay_us(1); cbi(LCD_PORT_DATA,5); //disable 6c6: 2d 98 cbi 0x05, 5 ; 5 delayMs(15); LCD_PORT_DATA = LCD_INIT; lcd_enable(); delayMs(5); lcd_enable(); delayMs(1); 6c8: 81 e0 ldi r24, 0x01 ; 1 6ca: 90 e0 ldi r25, 0x00 ; 0 6cc: 0e 94 4f 01 call 0x29e ; 0x29e * Internally used to turn on LCD Port E for 1us. * \internal */ extern void lcd_enable(void) { sbi(LCD_PORT_DATA,5); //enable 6d0: 2d 9a sbi 0x05, 5 ; 5 6d2: 81 2f mov r24, r17 6d4: 8a 95 dec r24 6d6: f1 f7 brne .-4 ; 0x6d4 _delay_us(1); cbi(LCD_PORT_DATA,5); //disable 6d8: 2d 98 cbi 0x05, 5 ; 5 lcd_enable(); delayMs(5); lcd_enable(); delayMs(1); lcd_enable(); delayMs(1); 6da: 81 e0 ldi r24, 0x01 ; 1 6dc: 90 e0 ldi r25, 0x00 ; 0 6de: 0e 94 4f 01 call 0x29e ; 0x29e ///////////////////////////// // lcd is connected with 4 ports for data LCD_PORT_DATA = LCD_4BIT_MODE; 6e2: 82 e0 ldi r24, 0x02 ; 2 6e4: 85 b9 out 0x05, r24 ; 5 * Internally used to turn on LCD Port E for 1us. * \internal */ extern void lcd_enable(void) { sbi(LCD_PORT_DATA,5); //enable 6e6: 2d 9a sbi 0x05, 5 ; 5 6e8: 1a 95 dec r17 6ea: f1 f7 brne .-4 ; 0x6e8 _delay_us(1); cbi(LCD_PORT_DATA,5); //disable 6ec: 2d 98 cbi 0x05, 5 ; 5 delayMs(1); ///////////////////////////// // lcd is connected with 4 ports for data LCD_PORT_DATA = LCD_4BIT_MODE; lcd_enable(); delayMs(1); 6ee: 81 e0 ldi r24, 0x01 ; 1 6f0: 90 e0 ldi r25, 0x00 ; 0 6f2: 0e 94 4f 01 call 0x29e ; 0x29e // display type is 2 line / 5x7 chars lcd_command(LCD_TWO_LINES | LCD_5X7); 6f6: 88 e2 ldi r24, 0x28 ; 40 6f8: 0e 94 9e 01 call 0x33c ; 0x33c lcd_command(LCD_DISPLAY_ON | LCD_HIDE_CURSOR); 6fc: 8c e0 ldi r24, 0x0C ; 12 6fe: 0e 94 9e 01 call 0x33c ; 0x33c // do not increment DDRAM address or move display lcd_command(LCD_NO_INC_ADDR | LCD_NO_MOVE); 702: 84 e0 ldi r24, 0x04 ; 4 704: 0e 94 9e 01 call 0x33c ; 0x33c lcd_clear(); 708: 0e 94 d2 01 call 0x3a4 ; 0x3a4 return; } 70c: 1f 91 pop r17 70e: 08 95 ret 00000710
: // Operation System Booting //---------------------------------------------------------------------------- //! Program's entry point int main() { 710: e0 e6 ldi r30, 0x60 ; 96 712: f0 e0 ldi r31, 0x00 ; 0 714: 80 81 ld r24, Z 716: 87 7f andi r24, 0xF7 ; 247 718: 80 83 st Z, r24 // disable Watchdog cbi(WDTCSR,WDE); // init timer 0 and 2 os_init_timer(); 71a: 0e 94 cd 06 call 0xd9a ; 0xd9a // Init LCD display lcd_init(); 71e: 0e 94 4c 03 call 0x698 ; 0x698 // Init OS os_init(); 722: 0e 94 52 07 call 0xea4 ; 0xea4 // Let's go! lcd_clear(); 726: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(strSchedulerGo); 72a: 80 e7 ldi r24, 0x70 ; 112 72c: 90 e0 ldi r25, 0x00 ; 0 72e: 0e 94 2f 03 call 0x65e ; 0x65e delayMs(400); 732: 80 e9 ldi r24, 0x90 ; 144 734: 91 e0 ldi r25, 0x01 ; 1 736: 0e 94 4f 01 call 0x29e ; 0x29e lcd_clear(); 73a: 0e 94 d2 01 call 0x3a4 ; 0x3a4 os_startScheduler(); 73e: 0e 94 40 05 call 0xa80 ; 0xa80 // Finished? os_error(OS_ERROR_FINISHED); 742: 80 e0 ldi r24, 0x00 ; 0 744: 90 e0 ldi r25, 0x00 ; 0 746: 0e 94 ef 06 call 0xdde ; 0xdde return 1; }//end main 74a: 81 e0 ldi r24, 0x01 ; 1 74c: 90 e0 ldi r25, 0x00 ; 0 74e: 08 95 ret 00000750 : } } //! clear SRAM in task stack range to avoid undefined behaviour void os_clearStack(void) { 750: ee ed ldi r30, 0xDE ; 222 752: f0 e1 ldi r31, 0x10 ; 16 //! Write to SRAM void os_writeSRAM(unsigned int address, unsigned char value) { unsigned char* write = (unsigned char*)address; *write = (unsigned char)value; 754: 10 82 st Z, r1 756: 31 97 sbiw r30, 0x01 ; 1 //! clear SRAM in task stack range to avoid undefined behaviour void os_clearStack(void) { int j; for(j=0; j < ((MAX_NUMBER_OF_TASKS * STACK_SIZE_TASK)+STACK_SIZE_ISR); j++) 758: 89 e0 ldi r24, 0x09 ; 9 75a: e6 30 cpi r30, 0x06 ; 6 75c: f8 07 cpc r31, r24 75e: d1 f7 brne .-12 ; 0x754 { os_writeSRAM(BOTTOM_OF_ISR_STACK-j,0x00); } } 760: 08 95 ret 00000762 : } //! Write to SRAM void os_writeSRAM(unsigned int address, unsigned char value) { 762: fc 01 movw r30, r24 unsigned char* write = (unsigned char*)address; *write = (unsigned char)value; 764: 60 83 st Z, r22 } 766: 08 95 ret 00000768 : SREG = temp; } //! Returns currently active task. unsigned char os_getCurrentTask (void) { 768: 80 91 12 01 lds r24, 0x0112 return os_currentTask; } 76c: 08 95 ret 0000076e : //! Returns currently active task by active numbering. unsigned char os_getCurrentTaskAsActive (void) { 76e: 80 91 12 01 lds r24, 0x0112 // ? return os_getCurrentTask();; } 772: 08 95 ret 00000774 : //! Returns number currently active tasks. (idle task is not recoginzed! because always active) unsigned char os_getNumberOfActiveTasks (void) { 774: 40 e0 ldi r20, 0x00 ; 0 776: 21 e0 ldi r18, 0x01 ; 1 778: 30 e0 ldi r19, 0x00 ; 0 unsigned char i=1,found=0; // i=1 to except idle task for (;i 798: 80 81 ld r24, Z 79a: 91 81 ldd r25, Z+1 ; 0x01 79c: 04 97 sbiw r24, 0x04 ; 4 79e: 09 f0 breq .+2 ; 0x7a2 found++; 7a0: 4f 5f subi r20, 0xFF ; 255 7a2: 2f 5f subi r18, 0xFF ; 255 7a4: 3f 4f sbci r19, 0xFF ; 255 //! Returns number currently active tasks. (idle task is not recoginzed! because always active) unsigned char os_getNumberOfActiveTasks (void) { unsigned char i=1,found=0; // i=1 to except idle task for (;i if ((os_taskStates[i].state != OS_TASK_UNUSED)&&(os_taskStates[i].state != OS_TASK_KILLED)) found++; return found; } 7ac: 84 2f mov r24, r20 7ae: 08 95 ret 000007b0 : //! Converts active index to array index. unsigned char os_getTaskNumberByActive (unsigned char activeNumber) { 7b0: 90 e0 ldi r25, 0x00 ; 0 7b2: 62 e4 ldi r22, 0x42 ; 66 7b4: 40 e0 ldi r20, 0x00 ; 0 7b6: 50 e0 ldi r21, 0x00 ; 0 7b8: dc 01 movw r26, r24 7ba: aa 0f add r26, r26 7bc: bb 1f adc r27, r27 7be: aa 0f add r26, r26 7c0: bb 1f adc r27, r27 7c2: aa 0f add r26, r26 7c4: bb 1f adc r27, r27 unsigned char i=0,found = INVALID_TASK_MAGIC_NUMBER; for (;i 7d2: 4f 5f subi r20, 0xFF ; 255 7d4: 5f 4f sbci r21, 0xFF ; 255 //! Converts active index to array index. unsigned char os_getTaskNumberByActive (unsigned char activeNumber) { unsigned char i=0,found = INVALID_TASK_MAGIC_NUMBER; for (;i if (os_taskStates[activeNumber].fPtr == os_allTasks[i]) 7dc: 8d 91 ld r24, X+ 7de: 9c 91 ld r25, X 7e0: 11 97 sbiw r26, 0x01 ; 1 7e2: fa 01 movw r30, r20 7e4: ee 0f add r30, r30 7e6: ff 1f adc r31, r31 7e8: ec 59 subi r30, 0x9C ; 156 7ea: fe 4f sbci r31, 0xFE ; 254 7ec: 20 81 ld r18, Z 7ee: 31 81 ldd r19, Z+1 ; 0x01 7f0: 82 17 cp r24, r18 7f2: 93 07 cpc r25, r19 7f4: 71 f7 brne .-36 ; 0x7d2 7f6: 64 2f mov r22, r20 7f8: 4f 5f subi r20, 0xFF ; 255 7fa: 5f 4f sbci r21, 0xFF ; 255 //! Converts active index to array index. unsigned char os_getTaskNumberByActive (unsigned char activeNumber) { unsigned char i=0,found = INVALID_TASK_MAGIC_NUMBER; for (;i if (os_taskStates[activeNumber].fPtr == os_allTasks[i]) found=i; return found; } 802: 86 2f mov r24, r22 804: 08 95 ret 00000806 : //! Returns task's priority. unsigned char os_getTaskTimeSlice (unsigned char task) { 806: 90 e0 ldi r25, 0x00 ; 0 808: fc 01 movw r30, r24 80a: ee 0f add r30, r30 80c: ff 1f adc r31, r31 80e: ee 0f add r30, r30 810: ff 1f adc r31, r31 812: ee 0f add r30, r30 814: ff 1f adc r31, r31 816: e8 0f add r30, r24 818: f9 1f adc r31, r25 81a: e4 5e subi r30, 0xE4 ; 228 81c: fe 4f sbci r31, 0xFE ; 254 81e: 82 81 ldd r24, Z+2 ; 0x02 return os_taskStates[task].maxTimeSlice; } 820: 08 95 ret 00000822 : //! Sets task's priority. void os_setTaskTimeSlice (unsigned char task, unsigned char timeSlice) { 822: 90 e0 ldi r25, 0x00 ; 0 824: fc 01 movw r30, r24 826: ee 0f add r30, r30 828: ff 1f adc r31, r31 82a: ee 0f add r30, r30 82c: ff 1f adc r31, r31 82e: ee 0f add r30, r30 830: ff 1f adc r31, r31 832: e8 0f add r30, r24 834: f9 1f adc r31, r25 836: e4 5e subi r30, 0xE4 ; 228 838: fe 4f sbci r31, 0xFE ; 254 83a: 80 81 ld r24, Z 83c: 91 81 ldd r25, Z+1 ; 0x01 83e: 89 2b or r24, r25 840: 09 f0 breq .+2 ; 0x844 if(os_taskStates[task].state != OS_TASK_UNUSED) os_taskStates[task].maxTimeSlice = timeSlice; 842: 62 83 std Z+2, r22 ; 0x02 844: 08 95 ret 00000846 : } //! Gets the schedulers strategy. enum os_SchedulingStrategy os_getSchedulingStrategy (void) { 846: 20 91 02 01 lds r18, 0x0102 84a: 30 91 03 01 lds r19, 0x0103 return os_strategy; } 84e: c9 01 movw r24, r18 850: 08 95 ret 00000852 : //! Prematurely canceles a task. void os_yield () { 852: 08 95 ret 00000854 : return 0; } //! Sets the schedulers strategy. void os_setSchedulingStrategy (enum os_SchedulingStrategy strategy) { 854: 82 30 cpi r24, 0x02 ; 2 856: 91 05 cpc r25, r1 858: 79 f0 breq .+30 ; 0x878 85a: 83 30 cpi r24, 0x03 ; 3 85c: 91 05 cpc r25, r1 85e: 38 f0 brcs .+14 ; 0x86e 860: 83 30 cpi r24, 0x03 ; 3 862: 91 05 cpc r25, r1 864: 49 f0 breq .+18 ; 0x878 866: 84 30 cpi r24, 0x04 ; 4 868: 91 05 cpc r25, r1 86a: 81 f0 breq .+32 ; 0x88c 86c: 08 95 ret 86e: 00 97 sbiw r24, 0x00 ; 0 870: 41 f0 breq .+16 ; 0x882 872: 81 30 cpi r24, 0x01 ; 1 874: 91 05 cpc r25, r1 876: d1 f7 brne .-12 ; 0x86c os_strategy = OS_SCHED_ROUND_ROBIN; break; } case (OS_SCHED_INACTIVE_AGING) : { os_strategy = OS_SCHED_INACTIVE_AGING; 878: 90 93 03 01 sts 0x0103, r25 87c: 80 93 02 01 sts 0x0102, r24 880: 08 95 ret os_strategy = OS_SCHED_EVEN; break; } case (OS_SCHED_NONE) : { os_strategy = OS_SCHED_NONE; 882: 10 92 03 01 sts 0x0103, r1 886: 10 92 02 01 sts 0x0102, r1 88a: 08 95 ret os_strategy = OS_SCHED_INACTIVE_AGING; break; } case (OS_SCHED_RANDOM) : { os_strategy = OS_SCHED_RANDOM; 88c: 90 93 03 01 sts 0x0103, r25 890: 80 93 02 01 sts 0x0102, r24 894: 08 95 ret 00000896 : // ? } //! gets the next task to be running unsigned char os_getNextTask() { 896: 80 91 02 01 lds r24, 0x0102 89a: 90 91 03 01 lds r25, 0x0103 89e: 82 30 cpi r24, 0x02 ; 2 8a0: 91 05 cpc r25, r1 8a2: 19 f1 breq .+70 ; 0x8ea 8a4: 83 30 cpi r24, 0x03 ; 3 8a6: 91 05 cpc r25, r1 8a8: 38 f0 brcs .+14 ; 0x8b8 8aa: 83 30 cpi r24, 0x03 ; 3 8ac: 91 05 cpc r25, r1 8ae: 21 f1 breq .+72 ; 0x8f8 8b0: 04 97 sbiw r24, 0x04 ; 4 8b2: a1 f0 breq .+40 ; 0x8dc 8b4: 80 e0 ldi r24, 0x00 ; 0 8b6: 08 95 ret 8b8: 00 97 sbiw r24, 0x00 ; 0 8ba: 49 f0 breq .+18 ; 0x8ce 8bc: 01 97 sbiw r24, 0x01 ; 1 8be: d1 f7 brne .-12 ; 0x8b4 } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; 8c0: 60 91 12 01 lds r22, 0x0112 { switch (os_strategy) { case (OS_SCHED_EVEN) : { return os_Scheduler_Even((struct os_TaskAbstract *)os_taskStates, os_getCurrentTask()); 8c4: 8c e1 ldi r24, 0x1C ; 28 8c6: 91 e0 ldi r25, 0x01 ; 1 8c8: 0e 94 47 0d call 0x1a8e ; 0x1a8e 8cc: 08 95 ret } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; 8ce: 60 91 12 01 lds r22, 0x0112 return os_Scheduler_Even((struct os_TaskAbstract *)os_taskStates, os_getCurrentTask()); break; } case (OS_SCHED_NONE) : { return os_Scheduler_None((struct os_TaskAbstract *)os_taskStates,os_getCurrentTask()); 8d2: 8c e1 ldi r24, 0x1C ; 28 8d4: 91 e0 ldi r25, 0x01 ; 1 8d6: 0e 94 a9 0d call 0x1b52 ; 0x1b52 8da: 08 95 ret } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; 8dc: 60 91 12 01 lds r22, 0x0112 return os_Scheduler_InactiveAging((struct os_TaskAbstract *)os_taskStates,os_getCurrentTask()); break; } case (OS_SCHED_RANDOM) : { return os_Scheduler_Random((struct os_TaskAbstract *)os_taskStates,os_getCurrentTask()); 8e0: 8c e1 ldi r24, 0x1C ; 28 8e2: 91 e0 ldi r25, 0x01 ; 1 8e4: 0e 94 c4 0d call 0x1b88 ; 0x1b88 break; } } return 0; } 8e8: 08 95 ret } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; 8ea: 60 91 12 01 lds r22, 0x0112 return os_Scheduler_None((struct os_TaskAbstract *)os_taskStates,os_getCurrentTask()); break; } case (OS_SCHED_ROUND_ROBIN) : { return os_Scheduler_RoundRobin((struct os_TaskAbstract *)os_taskStates,os_getCurrentTask()); 8ee: 8c e1 ldi r24, 0x1C ; 28 8f0: 91 e0 ldi r25, 0x01 ; 1 8f2: 0e 94 60 0d call 0x1ac0 ; 0x1ac0 8f6: 08 95 ret } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; 8f8: 60 91 12 01 lds r22, 0x0112 return os_Scheduler_RoundRobin((struct os_TaskAbstract *)os_taskStates,os_getCurrentTask()); break; } case (OS_SCHED_INACTIVE_AGING) : { return os_Scheduler_InactiveAging((struct os_TaskAbstract *)os_taskStates,os_getCurrentTask()); 8fc: 8c e1 ldi r24, 0x1C ; 28 8fe: 91 e0 ldi r25, 0x01 ; 1 900: 0e 94 f0 0c call 0x19e0 ; 0x19e0 904: 08 95 ret 00000906 : *write = (unsigned char)value; } //! Registers a task to run in our OS void os_registerTask( fptr task, unsigned char timeSlice ) { 906: bf 92 push r11 908: cf 92 push r12 90a: df 92 push r13 90c: ef 92 push r14 90e: ff 92 push r15 910: 0f 93 push r16 912: 1f 93 push r17 914: cf 93 push r28 916: df 93 push r29 918: 8c 01 movw r16, r24 91a: c6 2e mov r12, r22 //disable interrupts to avoid side effects unsigned char temp; temp = SREG; 91c: bf b6 in r11, 0x3f ; 63 cli(); 91e: f8 94 cli // check if task exists if (task == NULL) 920: 00 97 sbiw r24, 0x00 ; 0 922: 09 f4 brne .+2 ; 0x926 924: a8 c0 rjmp .+336 ; 0xa76 os_error(OS_ERROR_TASK_NOT_EXIST); 926: 72 e4 ldi r23, 0x42 ; 66 928: d7 2e mov r13, r23 92a: 20 e0 ldi r18, 0x00 ; 0 92c: 30 e0 ldi r19, 0x00 ; 0 92e: 05 c0 rjmp .+10 ; 0x93a { if (task == os_allTasks[j]) { found = j; } j++; 930: 2f 5f subi r18, 0xFF ; 255 932: 3f 4f sbci r19, 0xFF ; 255 os_error(OS_ERROR_TASK_NOT_EXIST); // check if task is alread registered unsigned char found = INVALID_TASK_MAGIC_NUMBER; int j=0; while (j < MAX_NUMBER_OF_TASKS) 934: 28 30 cpi r18, 0x08 ; 8 936: 31 05 cpc r19, r1 938: 81 f0 breq .+32 ; 0x95a { if (task == os_allTasks[j]) 93a: f9 01 movw r30, r18 93c: ee 0f add r30, r30 93e: ff 1f adc r31, r31 940: ec 59 subi r30, 0x9C ; 156 942: fe 4f sbci r31, 0xFE ; 254 944: 80 81 ld r24, Z 946: 91 81 ldd r25, Z+1 ; 0x01 948: 80 17 cp r24, r16 94a: 91 07 cpc r25, r17 94c: 89 f7 brne .-30 ; 0x930 94e: d2 2e mov r13, r18 { found = j; } j++; 950: 2f 5f subi r18, 0xFF ; 255 952: 3f 4f sbci r19, 0xFF ; 255 os_error(OS_ERROR_TASK_NOT_EXIST); // check if task is alread registered unsigned char found = INVALID_TASK_MAGIC_NUMBER; int j=0; while (j < MAX_NUMBER_OF_TASKS) 954: 28 30 cpi r18, 0x08 ; 8 956: 31 05 cpc r19, r1 958: 81 f7 brne .-32 ; 0x93a 95a: c0 e0 ldi r28, 0x00 ; 0 95c: d0 e0 ldi r29, 0x00 ; 0 //find next free slot in task array int i=0; while (i < MAX_NUMBER_OF_TASKS) { if ((os_taskStates[i].state == OS_TASK_UNUSED)||(os_taskStates[i].state == OS_TASK_KILLED)) 95e: de 01 movw r26, r28 960: aa 0f add r26, r26 962: bb 1f adc r27, r27 964: aa 0f add r26, r26 966: bb 1f adc r27, r27 968: aa 0f add r26, r26 96a: bb 1f adc r27, r27 96c: fd 01 movw r30, r26 96e: ec 0f add r30, r28 970: fd 1f adc r31, r29 972: e4 5e subi r30, 0xE4 ; 228 974: fe 4f sbci r31, 0xFE ; 254 976: 80 81 ld r24, Z 978: 91 81 ldd r25, Z+1 ; 0x01 97a: 89 2b or r24, r25 97c: 09 f4 brne .+2 ; 0x980 97e: 55 c0 rjmp .+170 ; 0xa2a 980: 80 81 ld r24, Z 982: 91 81 ldd r25, Z+1 ; 0x01 984: 04 97 sbiw r24, 0x04 ; 4 986: 09 f4 brne .+2 ; 0x98a 988: 50 c0 rjmp .+160 ; 0xa2a break; i++; 98a: 21 96 adiw r28, 0x01 ; 1 j++; } //find next free slot in task array int i=0; while (i < MAX_NUMBER_OF_TASKS) 98c: c8 30 cpi r28, 0x08 ; 8 98e: d1 05 cpc r29, r1 990: 31 f7 brne .-52 ; 0x95e i++; } //check if maximum number of tasks is reached if (i == MAX_NUMBER_OF_TASKS) os_error(OS_ERROR_MAX_TASK_EXCEED); 992: 82 e0 ldi r24, 0x02 ; 2 994: 90 e0 ldi r25, 0x00 ; 0 996: 0e 94 ef 06 call 0xdde ; 0xdde 99a: 28 e6 ldi r18, 0x68 ; 104 99c: 38 ef ldi r19, 0xF8 ; 248 99e: 95 e0 ldi r25, 0x05 ; 5 9a0: e9 2e mov r14, r25 9a2: 99 e0 ldi r25, 0x09 ; 9 9a4: f9 2e mov r15, r25 9a6: 65 e0 ldi r22, 0x05 ; 5 9a8: 79 e0 ldi r23, 0x09 ; 9 9aa: 44 e0 ldi r20, 0x04 ; 4 9ac: 59 e0 ldi r21, 0x09 ; 9 9ae: a0 e4 ldi r26, 0x40 ; 64 9b0: b0 e0 ldi r27, 0x00 ; 0 //valid task -> set properties if (found == INVALID_TASK_MAGIC_NUMBER) 9b2: 82 e4 ldi r24, 0x42 ; 66 9b4: d8 16 cp r13, r24 9b6: 09 f4 brne .+2 ; 0x9ba 9b8: 4f c0 rjmp .+158 ; 0xa58 { os_allTasks[os_numberOfTasks] = task; os_numberOfTasks++; } os_taskStates[i].fPtr = task; 9ba: fd 01 movw r30, r26 9bc: ec 0f add r30, r28 9be: fd 1f adc r31, r29 9c0: e4 5e subi r30, 0xE4 ; 228 9c2: fe 4f sbci r31, 0xFE ; 254 9c4: 10 87 std Z+8, r17 ; 0x08 9c6: 07 83 std Z+7, r16 ; 0x07 os_taskStates[i].state = OS_TASK_READY; 9c8: 81 e0 ldi r24, 0x01 ; 1 9ca: 90 e0 ldi r25, 0x00 ; 0 9cc: 91 83 std Z+1, r25 ; 0x01 9ce: 80 83 st Z, r24 os_taskStates[i].maxTimeSlice = timeSlice; 9d0: c2 82 std Z+2, r12 ; 0x02 os_taskStates[i].age = timeSlice; 9d2: 8c 2d mov r24, r12 9d4: 90 e0 ldi r25, 0x00 ; 0 9d6: 94 83 std Z+4, r25 ; 0x04 9d8: 83 83 std Z+3, r24 ; 0x03 //! Write to SRAM void os_writeSRAM(unsigned int address, unsigned char value) { unsigned char* write = (unsigned char*)address; *write = (unsigned char)value; 9da: fb 01 movw r30, r22 9dc: 00 83 st Z, r16 // write highbyte on second address of process stack os_writeSRAM((BOTTOM_OF_TASKS_STACK-(i*STACK_SIZE_TASK))-1,(unsigned int)(task)>>8); // write 33 zeros on process stack for register init (SREG + r0..r31) for(j=2; j < 35; j++) 9de: fa 01 movw r30, r20 9e0: 10 83 st Z, r17 9e2: f7 01 movw r30, r14 9e4: 32 97 sbiw r30, 0x02 ; 2 9e6: 82 e0 ldi r24, 0x02 ; 2 9e8: 90 e0 ldi r25, 0x00 ; 0 9ea: 10 82 st Z, r1 9ec: 01 96 adiw r24, 0x01 ; 1 9ee: 31 97 sbiw r30, 0x01 ; 1 9f0: 83 32 cpi r24, 0x23 ; 35 9f2: 91 05 cpc r25, r1 9f4: d1 f7 brne .-12 ; 0x9ea { os_writeSRAM((BOTTOM_OF_TASKS_STACK-(i*STACK_SIZE_TASK))-j,0x00); } // set stackpointer to the next free adress on process stack os_taskStates[i].stackAddress = (BOTTOM_OF_TASKS_STACK-(i*STACK_SIZE_TASK))-35; 9f6: 26 58 subi r18, 0x86 ; 134 9f8: 3f 4e sbci r19, 0xEF ; 239 9fa: ac 0f add r26, r28 9fc: bd 1f adc r27, r29 9fe: a4 5e subi r26, 0xE4 ; 228 a00: be 4f sbci r27, 0xFE ; 254 a02: 16 96 adiw r26, 0x06 ; 6 a04: 3c 93 st X, r19 a06: 2e 93 st -X, r18 a08: 15 97 sbiw r26, 0x05 ; 5 //increase number of registered tasks os_numberOfRegisteredTasks++; a0a: 80 91 11 01 lds r24, 0x0111 a0e: 8f 5f subi r24, 0xFF ; 255 a10: 80 93 11 01 sts 0x0111, r24 //re-enable interrupts SREG = temp; a14: bf be out 0x3f, r11 ; 63 } a16: df 91 pop r29 a18: cf 91 pop r28 a1a: 1f 91 pop r17 a1c: 0f 91 pop r16 a1e: ff 90 pop r15 a20: ef 90 pop r14 a22: df 90 pop r13 a24: cf 90 pop r12 a26: bf 90 pop r11 a28: 08 95 ret //find next free slot in task array int i=0; while (i < MAX_NUMBER_OF_TASKS) { if ((os_taskStates[i].state == OS_TASK_UNUSED)||(os_taskStates[i].state == OS_TASK_KILLED)) a2a: 8d e0 ldi r24, 0x0D ; 13 a2c: 9f ef ldi r25, 0xFF ; 255 a2e: c8 9f mul r28, r24 a30: 90 01 movw r18, r0 a32: c9 9f mul r28, r25 a34: 30 0d add r19, r0 a36: d8 9f mul r29, r24 a38: 30 0d add r19, r0 a3a: 11 24 eor r1, r1 a3c: 4d e9 ldi r20, 0x9D ; 157 a3e: e4 2e mov r14, r20 a40: 40 e1 ldi r20, 0x10 ; 16 a42: f4 2e mov r15, r20 a44: e2 0e add r14, r18 a46: f3 1e adc r15, r19 a48: b7 01 movw r22, r14 a4a: a9 01 movw r20, r18 a4c: 44 56 subi r20, 0x64 ; 100 a4e: 5f 4e sbci r21, 0xEF ; 239 //check if maximum number of tasks is reached if (i == MAX_NUMBER_OF_TASKS) os_error(OS_ERROR_MAX_TASK_EXCEED); //valid task -> set properties if (found == INVALID_TASK_MAGIC_NUMBER) a50: 82 e4 ldi r24, 0x42 ; 66 a52: d8 16 cp r13, r24 a54: 09 f0 breq .+2 ; 0xa58 a56: b1 cf rjmp .-158 ; 0x9ba { os_allTasks[os_numberOfTasks] = task; a58: e0 91 10 01 lds r30, 0x0110 a5c: f0 e0 ldi r31, 0x00 ; 0 a5e: ee 0f add r30, r30 a60: ff 1f adc r31, r31 a62: ec 59 subi r30, 0x9C ; 156 a64: fe 4f sbci r31, 0xFE ; 254 a66: 11 83 std Z+1, r17 ; 0x01 a68: 00 83 st Z, r16 os_numberOfTasks++; a6a: 80 91 10 01 lds r24, 0x0110 a6e: 8f 5f subi r24, 0xFF ; 255 a70: 80 93 10 01 sts 0x0110, r24 a74: a2 cf rjmp .-188 ; 0x9ba temp = SREG; cli(); // check if task exists if (task == NULL) os_error(OS_ERROR_TASK_NOT_EXIST); a76: 85 e0 ldi r24, 0x05 ; 5 a78: 90 e0 ldi r25, 0x00 ; 0 a7a: 0e 94 ef 06 call 0xdde ; 0xdde a7e: 53 cf rjmp .-346 ; 0x926 00000a80 : asm volatile("reti"); } //! Starts execution of tasks via scheduler void os_startScheduler( void ) { a80: 64 e1 ldi r22, 0x14 ; 20 a82: 8b ea ldi r24, 0xAB ; 171 a84: 97 e0 ldi r25, 0x07 ; 7 a86: 0e 94 83 04 call 0x906 ; 0x906 //register tasks os_registerTask(task1, 20); os_registerTask(task2, 20); a8a: 64 e1 ldi r22, 0x14 ; 20 a8c: 84 eb ldi r24, 0xB4 ; 180 a8e: 97 e0 ldi r25, 0x07 ; 7 a90: 0e 94 83 04 call 0x906 ; 0x906 os_allTasks[5] = task5; os_allTasks[6] = task6; os_allTasks[7] = task7; */ //start idle task and init interrupts with "reti" os_taskStates[0].state = OS_TASK_RUNNING; a94: 82 e0 ldi r24, 0x02 ; 2 a96: 90 e0 ldi r25, 0x00 ; 0 a98: 90 93 1d 01 sts 0x011D, r25 a9c: 80 93 1c 01 sts 0x011C, r24 SP = os_taskStates[0].stackAddress; aa0: 80 91 21 01 lds r24, 0x0121 aa4: 90 91 22 01 lds r25, 0x0122 aa8: 9e bf out 0x3e, r25 ; 62 aaa: 8d bf out 0x3d, r24 ; 61 restoreContext(); aac: ff 91 pop r31 aae: ef 91 pop r30 ab0: df 91 pop r29 ab2: cf 91 pop r28 ab4: bf 91 pop r27 ab6: af 91 pop r26 ab8: 9f 91 pop r25 aba: 8f 91 pop r24 abc: 7f 91 pop r23 abe: 6f 91 pop r22 ac0: 5f 91 pop r21 ac2: 4f 91 pop r20 ac4: 3f 91 pop r19 ac6: 2f 91 pop r18 ac8: 1f 91 pop r17 aca: 0f 91 pop r16 acc: ff 90 pop r15 ace: ef 90 pop r14 ad0: df 90 pop r13 ad2: cf 90 pop r12 ad4: bf 90 pop r11 ad6: af 90 pop r10 ad8: 9f 90 pop r9 ada: 8f 90 pop r8 adc: 7f 90 pop r7 ade: 6f 90 pop r6 ae0: 5f 90 pop r5 ae2: 4f 90 pop r4 ae4: 3f 90 pop r3 ae6: 2f 90 pop r2 ae8: 1f 90 pop r1 aea: 0f 90 pop r0 aec: 0f be out 0x3f, r0 ; 63 aee: 0f 90 pop r0 asm volatile("reti"); af0: 18 95 reti } af2: 08 95 ret 00000af4 : } //! Inits scheduler arrays void os_initScheduler( void ) { af4: 80 e0 ldi r24, 0x00 ; 0 af6: 90 e0 ldi r25, 0x00 ; 0 int i = 0; for (i = 0; i < MAX_NUMBER_OF_TASKS; i++) { //init task states array os_taskStates[i].state = OS_TASK_UNUSED; os_taskStates[i].maxTimeSlice = STANDARD_TIME_SLICE; af8: 4a e0 ldi r20, 0x0A ; 10 os_taskStates[i].age = STANDARD_TIME_SLICE; afa: 2a e0 ldi r18, 0x0A ; 10 afc: 30 e0 ldi r19, 0x00 ; 0 //init the schedulers's arrays int i = 0; for (i = 0; i < MAX_NUMBER_OF_TASKS; i++) { //init task states array os_taskStates[i].state = OS_TASK_UNUSED; afe: fc 01 movw r30, r24 b00: ee 0f add r30, r30 b02: ff 1f adc r31, r31 b04: ee 0f add r30, r30 b06: ff 1f adc r31, r31 b08: ee 0f add r30, r30 b0a: ff 1f adc r31, r31 b0c: e8 0f add r30, r24 b0e: f9 1f adc r31, r25 b10: e4 5e subi r30, 0xE4 ; 228 b12: fe 4f sbci r31, 0xFE ; 254 b14: 11 82 std Z+1, r1 ; 0x01 b16: 10 82 st Z, r1 os_taskStates[i].maxTimeSlice = STANDARD_TIME_SLICE; b18: 42 83 std Z+2, r20 ; 0x02 os_taskStates[i].age = STANDARD_TIME_SLICE; b1a: 34 83 std Z+4, r19 ; 0x04 b1c: 23 83 std Z+3, r18 ; 0x03 os_taskStates[i].stackAddress = 0; b1e: 16 82 std Z+6, r1 ; 0x06 b20: 15 82 std Z+5, r1 ; 0x05 os_taskStates[i].fPtr = NULL; b22: 10 86 std Z+8, r1 ; 0x08 b24: 17 82 std Z+7, r1 ; 0x07 //init all tasks array os_allTasks[i] = NULL; b26: fc 01 movw r30, r24 b28: ee 0f add r30, r30 b2a: ff 1f adc r31, r31 b2c: ec 59 subi r30, 0x9C ; 156 b2e: fe 4f sbci r31, 0xFE ; 254 b30: 11 82 std Z+1, r1 ; 0x01 b32: 10 82 st Z, r1 //! Inits scheduler arrays void os_initScheduler( void ) { //init the schedulers's arrays int i = 0; for (i = 0; i < MAX_NUMBER_OF_TASKS; i++) b34: 01 96 adiw r24, 0x01 ; 1 b36: 88 30 cpi r24, 0x08 ; 8 b38: 91 05 cpc r25, r1 b3a: 09 f7 brne .-62 ; 0xafe //init all tasks array os_allTasks[i] = NULL; } //init rand for scheduling strategy OS_SCHED_RANDOM srand(1); b3c: 81 e0 ldi r24, 0x01 ; 1 b3e: 90 e0 ldi r25, 0x00 ; 0 b40: 0e 94 f8 0e call 0x1df0 ; 0x1df0 //init Button Port PORTA = 0b11111111; //enable pull-ups b44: 8f ef ldi r24, 0xFF ; 255 b46: 82 b9 out 0x02, r24 ; 2 #if SIMULATION == 1 PINA = 0b11111111; b48: 80 b9 out 0x00, r24 ; 0 #endif } b4a: 08 95 ret 00000b4c : } } //! Idle Task function void os_idleTask(void) { b4c: cf 93 push r28 b4e: df 93 push r29 while (1) { lcd_progString(strPOINT); delayMs(os_taskOutputDelay); b50: c0 91 04 01 lds r28, 0x0104 b54: d0 91 05 01 lds r29, 0x0105 //! Idle Task function void os_idleTask(void) { while (1) { lcd_progString(strPOINT); b58: 8f e8 ldi r24, 0x8F ; 143 b5a: 90 e0 ldi r25, 0x00 ; 0 b5c: 0e 94 2f 03 call 0x65e ; 0x65e delayMs(os_taskOutputDelay); b60: ce 01 movw r24, r28 b62: 0e 94 4f 01 call 0x29e ; 0x29e b66: f8 cf rjmp .-16 ; 0xb58 00000b68 : asm volatile("reti"); } //! The GarbageCollector. Resets all KILLED tasks to UNUSED and free's their allocated memory void os_garbageCollector() { b68: df 92 push r13 b6a: ef 92 push r14 b6c: ff 92 push r15 b6e: 0f 93 push r16 b70: 1f 93 push r17 b72: cf 93 push r28 b74: df 93 push r29 b76: 01 e0 ldi r16, 0x01 ; 1 b78: 10 e0 ldi r17, 0x00 ; 0 for (;i < MAX_NUMBER_OF_TASKS;i++) if(os_taskStates[i].state == OS_TASK_KILLED) { os_freeTaskMem(i); os_taskStates[i].fPtr = NULL; os_taskStates[i].maxTimeSlice = STANDARD_TIME_SLICE; b7a: 2a e0 ldi r18, 0x0A ; 10 b7c: d2 2e mov r13, r18 os_taskStates[i].age = STANDARD_TIME_SLICE; b7e: 9a e0 ldi r25, 0x0A ; 10 b80: e9 2e mov r14, r25 b82: f1 2c mov r15, r1 b84: 05 c0 rjmp .+10 ; 0xb90 os_taskStates[i].stackAddress = 0; os_taskStates[i].state = OS_TASK_UNUSED; b86: 0f 5f subi r16, 0xFF ; 255 b88: 1f 4f sbci r17, 0xFF ; 255 //! The GarbageCollector. Resets all KILLED tasks to UNUSED and free's their allocated memory void os_garbageCollector() { unsigned char i = 1; for (;i < MAX_NUMBER_OF_TASKS;i++) b8a: 08 30 cpi r16, 0x08 ; 8 b8c: 11 05 cpc r17, r1 b8e: 01 f1 breq .+64 ; 0xbd0 if(os_taskStates[i].state == OS_TASK_KILLED) b90: e8 01 movw r28, r16 b92: cc 0f add r28, r28 b94: dd 1f adc r29, r29 b96: cc 0f add r28, r28 b98: dd 1f adc r29, r29 b9a: cc 0f add r28, r28 b9c: dd 1f adc r29, r29 b9e: c0 0f add r28, r16 ba0: d1 1f adc r29, r17 ba2: c4 5e subi r28, 0xE4 ; 228 ba4: de 4f sbci r29, 0xFE ; 254 ba6: 88 81 ld r24, Y ba8: 99 81 ldd r25, Y+1 ; 0x01 baa: 04 97 sbiw r24, 0x04 ; 4 bac: 61 f7 brne .-40 ; 0xb86 { os_freeTaskMem(i); bae: 80 2f mov r24, r16 bb0: 0e 94 fd 0b call 0x17fa ; 0x17fa os_taskStates[i].fPtr = NULL; bb4: 18 86 std Y+8, r1 ; 0x08 bb6: 1f 82 std Y+7, r1 ; 0x07 os_taskStates[i].maxTimeSlice = STANDARD_TIME_SLICE; bb8: da 82 std Y+2, r13 ; 0x02 os_taskStates[i].age = STANDARD_TIME_SLICE; bba: fc 82 std Y+4, r15 ; 0x04 bbc: eb 82 std Y+3, r14 ; 0x03 os_taskStates[i].stackAddress = 0; bbe: 1e 82 std Y+6, r1 ; 0x06 bc0: 1d 82 std Y+5, r1 ; 0x05 os_taskStates[i].state = OS_TASK_UNUSED; bc2: 19 82 std Y+1, r1 ; 0x01 bc4: 18 82 st Y, r1 bc6: 0f 5f subi r16, 0xFF ; 255 bc8: 1f 4f sbci r17, 0xFF ; 255 //! The GarbageCollector. Resets all KILLED tasks to UNUSED and free's their allocated memory void os_garbageCollector() { unsigned char i = 1; for (;i < MAX_NUMBER_OF_TASKS;i++) bca: 08 30 cpi r16, 0x08 ; 8 bcc: 11 05 cpc r17, r1 bce: 01 f7 brne .-64 ; 0xb90 os_taskStates[i].maxTimeSlice = STANDARD_TIME_SLICE; os_taskStates[i].age = STANDARD_TIME_SLICE; os_taskStates[i].stackAddress = 0; os_taskStates[i].state = OS_TASK_UNUSED; } } bd0: df 91 pop r29 bd2: cf 91 pop r28 bd4: 1f 91 pop r17 bd6: 0f 91 pop r16 bd8: ff 90 pop r15 bda: ef 90 pop r14 bdc: df 90 pop r13 bde: 08 95 ret 00000be0 <__vector_9>: // Function implementation //---------------------------------------------------------------------------- //! The Scheduler ISR (TIMER2_COMPA_vect) { be0: 0f 92 push r0 be2: 0f b6 in r0, 0x3f ; 63 be4: f8 94 cli be6: 0f 92 push r0 be8: 1f 92 push r1 bea: 11 24 eor r1, r1 bec: 2f 92 push r2 bee: 3f 92 push r3 bf0: 4f 92 push r4 bf2: 5f 92 push r5 bf4: 6f 92 push r6 bf6: 7f 92 push r7 bf8: 8f 92 push r8 bfa: 9f 92 push r9 bfc: af 92 push r10 bfe: bf 92 push r11 c00: cf 92 push r12 c02: df 92 push r13 c04: ef 92 push r14 c06: ff 92 push r15 c08: 0f 93 push r16 c0a: 1f 93 push r17 c0c: 2f 93 push r18 c0e: 3f 93 push r19 c10: 4f 93 push r20 c12: 5f 93 push r21 c14: 6f 93 push r22 c16: 7f 93 push r23 c18: 8f 93 push r24 c1a: 9f 93 push r25 c1c: af 93 push r26 c1e: bf 93 push r27 c20: cf 93 push r28 c22: df 93 push r29 c24: ef 93 push r30 c26: ff 93 push r31 } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; c28: 80 91 12 01 lds r24, 0x0112 //! The Scheduler ISR (TIMER2_COMPA_vect) { //backup context and stackpointer and change state of current task saveContext(); os_taskStates[os_getCurrentTask()].stackAddress = SP; c2c: 90 e0 ldi r25, 0x00 ; 0 c2e: 2d b7 in r18, 0x3d ; 61 c30: 3e b7 in r19, 0x3e ; 62 c32: fc 01 movw r30, r24 c34: ee 0f add r30, r30 c36: ff 1f adc r31, r31 c38: ee 0f add r30, r30 c3a: ff 1f adc r31, r31 c3c: ee 0f add r30, r30 c3e: ff 1f adc r31, r31 c40: e8 0f add r30, r24 c42: f9 1f adc r31, r25 c44: e4 5e subi r30, 0xE4 ; 228 c46: fe 4f sbci r31, 0xFE ; 254 c48: 36 83 std Z+6, r19 ; 0x06 c4a: 25 83 std Z+5, r18 ; 0x05 //switch to ISR Stack SP = os_ISRstackpointer; c4c: 80 91 00 01 lds r24, 0x0100 c50: 90 91 01 01 lds r25, 0x0101 c54: 9e bf out 0x3e, r25 ; 62 c56: 8d bf out 0x3d, r24 ; 61 //update button array os_updateInput(); c58: 0e 94 3b 0e call 0x1c76 ; 0x1c76 //check if TaskMan is called #if SIMULATION == 0 if (os_buttonStates[OS_ESC] && os_buttonStates[OS_ENTER]) os_taskManMain(); #else if (os_buttonStates[OS_ENTER]) //for easy usage in simulation c5c: 80 91 18 01 lds r24, 0x0118 c60: 88 23 and r24, r24 c62: 09 f0 breq .+2 ; 0xc66 <__vector_9+0x86> c64: 97 c0 rjmp .+302 ; 0xd94 <__vector_9+0x1b4> } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; c66: 80 91 12 01 lds r24, 0x0112 if (os_buttonStates[OS_ENTER]) //for easy usage in simulation os_taskManMain(); #endif //reset runnning task to ready if not killed or paused in TaskMan if ((os_taskStates[os_getCurrentTask()].state != OS_TASK_KILLED)&&(os_taskStates[os_getCurrentTask()].state != OS_TASK_PAUSED)) c6a: 90 e0 ldi r25, 0x00 ; 0 c6c: fc 01 movw r30, r24 c6e: ee 0f add r30, r30 c70: ff 1f adc r31, r31 c72: ee 0f add r30, r30 c74: ff 1f adc r31, r31 c76: ee 0f add r30, r30 c78: ff 1f adc r31, r31 c7a: e8 0f add r30, r24 c7c: f9 1f adc r31, r25 c7e: e4 5e subi r30, 0xE4 ; 228 c80: fe 4f sbci r31, 0xFE ; 254 c82: 80 81 ld r24, Z c84: 91 81 ldd r25, Z+1 ; 0x01 c86: 04 97 sbiw r24, 0x04 ; 4 c88: 21 f1 breq .+72 ; 0xcd2 <__vector_9+0xf2> } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; c8a: 80 91 12 01 lds r24, 0x0112 if (os_buttonStates[OS_ENTER]) //for easy usage in simulation os_taskManMain(); #endif //reset runnning task to ready if not killed or paused in TaskMan if ((os_taskStates[os_getCurrentTask()].state != OS_TASK_KILLED)&&(os_taskStates[os_getCurrentTask()].state != OS_TASK_PAUSED)) c8e: 90 e0 ldi r25, 0x00 ; 0 c90: fc 01 movw r30, r24 c92: ee 0f add r30, r30 c94: ff 1f adc r31, r31 c96: ee 0f add r30, r30 c98: ff 1f adc r31, r31 c9a: ee 0f add r30, r30 c9c: ff 1f adc r31, r31 c9e: e8 0f add r30, r24 ca0: f9 1f adc r31, r25 ca2: e4 5e subi r30, 0xE4 ; 228 ca4: fe 4f sbci r31, 0xFE ; 254 ca6: 80 81 ld r24, Z ca8: 91 81 ldd r25, Z+1 ; 0x01 caa: 03 97 sbiw r24, 0x03 ; 3 cac: 91 f0 breq .+36 ; 0xcd2 <__vector_9+0xf2> } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; cae: 80 91 12 01 lds r24, 0x0112 os_taskManMain(); #endif //reset runnning task to ready if not killed or paused in TaskMan if ((os_taskStates[os_getCurrentTask()].state != OS_TASK_KILLED)&&(os_taskStates[os_getCurrentTask()].state != OS_TASK_PAUSED)) os_taskStates[os_getCurrentTask()].state = OS_TASK_READY; cb2: 90 e0 ldi r25, 0x00 ; 0 cb4: fc 01 movw r30, r24 cb6: ee 0f add r30, r30 cb8: ff 1f adc r31, r31 cba: ee 0f add r30, r30 cbc: ff 1f adc r31, r31 cbe: ee 0f add r30, r30 cc0: ff 1f adc r31, r31 cc2: e8 0f add r30, r24 cc4: f9 1f adc r31, r25 cc6: e4 5e subi r30, 0xE4 ; 228 cc8: fe 4f sbci r31, 0xFE ; 254 cca: 81 e0 ldi r24, 0x01 ; 1 ccc: 90 e0 ldi r25, 0x00 ; 0 cce: 91 83 std Z+1, r25 ; 0x01 cd0: 80 83 st Z, r24 //Garbage collection os_garbageCollector(); cd2: 0e 94 b4 05 call 0xb68 ; 0xb68 //find next os_currentTask os_currentTask = os_getNextTask(); cd6: 0e 94 4b 04 call 0x896 ; 0x896 cda: 80 93 12 01 sts 0x0112, r24 } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; cde: 80 91 12 01 lds r24, 0x0112 //find next os_currentTask os_currentTask = os_getNextTask(); //set timeslice and state of new task os_taskStates[os_getCurrentTask()].state = OS_TASK_RUNNING; ce2: 90 e0 ldi r25, 0x00 ; 0 ce4: fc 01 movw r30, r24 ce6: ee 0f add r30, r30 ce8: ff 1f adc r31, r31 cea: ee 0f add r30, r30 cec: ff 1f adc r31, r31 cee: ee 0f add r30, r30 cf0: ff 1f adc r31, r31 cf2: e8 0f add r30, r24 cf4: f9 1f adc r31, r25 cf6: e4 5e subi r30, 0xE4 ; 228 cf8: fe 4f sbci r31, 0xFE ; 254 cfa: 82 e0 ldi r24, 0x02 ; 2 cfc: 90 e0 ldi r25, 0x00 ; 0 cfe: 91 83 std Z+1, r25 ; 0x01 d00: 80 83 st Z, r24 } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; d02: 80 91 12 01 lds r24, 0x0112 //find next os_currentTask os_currentTask = os_getNextTask(); //set timeslice and state of new task os_taskStates[os_getCurrentTask()].state = OS_TASK_RUNNING; timeSlice = os_taskStates[os_getCurrentTask()].maxTimeSlice; d06: 90 e0 ldi r25, 0x00 ; 0 d08: fc 01 movw r30, r24 d0a: ee 0f add r30, r30 d0c: ff 1f adc r31, r31 d0e: ee 0f add r30, r30 d10: ff 1f adc r31, r31 d12: ee 0f add r30, r30 d14: ff 1f adc r31, r31 d16: e8 0f add r30, r24 d18: f9 1f adc r31, r25 d1a: e4 5e subi r30, 0xE4 ; 228 d1c: fe 4f sbci r31, 0xFE ; 254 d1e: 82 81 ldd r24, Z+2 ; 0x02 d20: 90 e0 ldi r25, 0x00 ; 0 d22: 90 93 14 01 sts 0x0114, r25 d26: 80 93 13 01 sts 0x0113, r24 } //! Returns currently active task. unsigned char os_getCurrentTask (void) { return os_currentTask; d2a: 80 91 12 01 lds r24, 0x0112 //set timeslice and state of new task os_taskStates[os_getCurrentTask()].state = OS_TASK_RUNNING; timeSlice = os_taskStates[os_getCurrentTask()].maxTimeSlice; //restore stackpointer and context of next task and chage state SP = os_taskStates[os_getCurrentTask()].stackAddress; d2e: 90 e0 ldi r25, 0x00 ; 0 d30: fc 01 movw r30, r24 d32: ee 0f add r30, r30 d34: ff 1f adc r31, r31 d36: ee 0f add r30, r30 d38: ff 1f adc r31, r31 d3a: ee 0f add r30, r30 d3c: ff 1f adc r31, r31 d3e: e8 0f add r30, r24 d40: f9 1f adc r31, r25 d42: e4 5e subi r30, 0xE4 ; 228 d44: fe 4f sbci r31, 0xFE ; 254 d46: 85 81 ldd r24, Z+5 ; 0x05 d48: 96 81 ldd r25, Z+6 ; 0x06 d4a: 9e bf out 0x3e, r25 ; 62 d4c: 8d bf out 0x3d, r24 ; 61 restoreContext(); d4e: ff 91 pop r31 d50: ef 91 pop r30 d52: df 91 pop r29 d54: cf 91 pop r28 d56: bf 91 pop r27 d58: af 91 pop r26 d5a: 9f 91 pop r25 d5c: 8f 91 pop r24 d5e: 7f 91 pop r23 d60: 6f 91 pop r22 d62: 5f 91 pop r21 d64: 4f 91 pop r20 d66: 3f 91 pop r19 d68: 2f 91 pop r18 d6a: 1f 91 pop r17 d6c: 0f 91 pop r16 d6e: ff 90 pop r15 d70: ef 90 pop r14 d72: df 90 pop r13 d74: cf 90 pop r12 d76: bf 90 pop r11 d78: af 90 pop r10 d7a: 9f 90 pop r9 d7c: 8f 90 pop r8 d7e: 7f 90 pop r7 d80: 6f 90 pop r6 d82: 5f 90 pop r5 d84: 4f 90 pop r4 d86: 3f 90 pop r3 d88: 2f 90 pop r2 d8a: 1f 90 pop r1 d8c: 0f 90 pop r0 d8e: 0f be out 0x3f, r0 ; 63 d90: 0f 90 pop r0 //jump to next tasks programmcounter asm volatile("reti"); d92: 18 95 reti } d94: 0e 94 4c 0b call 0x1698 ; 0x1698 d98: 66 cf rjmp .-308 ; 0xc66 <__vector_9+0x86> 00000d9a : /*! * Initializes the used timers. */ void os_init_timer() { d9a: e0 eb ldi r30, 0xB0 ; 176 d9c: f0 e0 ldi r31, 0x00 ; 0 d9e: 80 81 ld r24, Z da0: 82 60 ori r24, 0x02 ; 2 da2: 80 83 st Z, r24 if (SIMULATION) { // the AVR simulatorV1 cannot deal with a prescaler > 128 for timer 2 // AND, by choosing a prescaler of 32 instead of 1024 we can almost compensate // time shifts caused by the simulation overhead cbi(TCCR2B,CS22); // Prescaler 32 0 da4: e1 eb ldi r30, 0xB1 ; 177 da6: f0 e0 ldi r31, 0x00 ; 0 da8: 80 81 ld r24, Z daa: 8b 7f andi r24, 0xFB ; 251 dac: 80 83 st Z, r24 sbi(TCCR2B,CS21); // Prescaler 32 1 dae: 80 81 ld r24, Z db0: 82 60 ori r24, 0x02 ; 2 db2: 80 83 st Z, r24 sbi(TCCR2B,CS20); // Prescaler 32 1 db4: 80 81 ld r24, Z db6: 81 60 ori r24, 0x01 ; 1 db8: 80 83 st Z, r24 { sbi(TCCR2B,CS22); // Prescaler 1024 1 sbi(TCCR2B,CS21); // Prescaler 1024 1 sbi(TCCR2B,CS20); // Prescaler 1024 1 } sbi(TIMSK2,OCIE2A); // Enable interrupt dba: e0 e7 ldi r30, 0x70 ; 112 dbc: f0 e0 ldi r31, 0x00 ; 0 dbe: 80 81 ld r24, Z dc0: 82 60 ori r24, 0x02 ; 2 dc2: 80 83 st Z, r24 OCR2A = 60; dc4: 8c e3 ldi r24, 0x3C ; 60 dc6: 80 93 b3 00 sts 0x00B3, r24 // Init timer 0 with prescaler 256 cbi(TCCR0B,CS00); dca: 85 b5 in r24, 0x25 ; 37 dcc: 8e 7f andi r24, 0xFE ; 254 dce: 85 bd out 0x25, r24 ; 37 cbi(TCCR0B,CS01); dd0: 85 b5 in r24, 0x25 ; 37 dd2: 8d 7f andi r24, 0xFD ; 253 dd4: 85 bd out 0x25, r24 ; 37 sbi(TCCR0B,CS02); dd6: 85 b5 in r24, 0x25 ; 37 dd8: 84 60 ori r24, 0x04 ; 4 dda: 85 bd out 0x25, r24 ; 37 } ddc: 08 95 ret 00000dde : /*! * Freezes the OS and displays a corresponding error on the LCD. * \param e The error to be displayed */ void os_error( enum os_ErrorCode e ) { dde: f8 94 cli cli(); //disable interrupts to avoid ISR ticking //handle error case switch (e) de0: 82 30 cpi r24, 0x02 ; 2 de2: 91 05 cpc r25, r1 de4: 09 f4 brne .+2 ; 0xde8 de6: 51 c0 rjmp .+162 ; 0xe8a de8: 83 30 cpi r24, 0x03 ; 3 dea: 91 05 cpc r25, r1 dec: a0 f0 brcs .+40 ; 0xe16 dee: 84 30 cpi r24, 0x04 ; 4 df0: 91 05 cpc r25, r1 df2: 09 f4 brne .+2 ; 0xdf6 df4: 3d c0 rjmp .+122 ; 0xe70 df6: 84 30 cpi r24, 0x04 ; 4 df8: 91 05 cpc r25, r1 dfa: 58 f5 brcc .+86 ; 0xe52 break; } case(OS_ERROR_TASK_ALREADY_EXISTS): { lcd_clear(); dfc: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(strERR_ALREADY_EX); e00: 8b eb ldi r24, 0xBB ; 187 e02: 90 e0 ldi r25, 0x00 ; 0 e04: 0e 94 2f 03 call 0x65e ; 0x65e break; } default: break; } delayMs(5000); e08: 88 e8 ldi r24, 0x88 ; 136 e0a: 93 e1 ldi r25, 0x13 ; 19 e0c: 0e 94 4f 01 call 0x29e ; 0x29e //irreversible freeze whole system #if (FREEZE_ON_ERROR == 1) freeze(); e10: 0e 94 60 01 call 0x2c0 ; 0x2c0 #endif }//end os_error e14: 08 95 ret void os_error( enum os_ErrorCode e ) { cli(); //disable interrupts to avoid ISR ticking //handle error case switch (e) e16: 00 97 sbiw r24, 0x00 ; 0 e18: 79 f0 breq .+30 ; 0xe38 e1a: 01 97 sbiw r24, 0x01 ; 1 e1c: 31 f4 brne .+12 ; 0xe2a { case(OS_ERROR_UNKNOWN): { lcd_clear(); e1e: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(strERR_UNKNOWN); e22: 81 e9 ldi r24, 0x91 ; 145 e24: 90 e0 ldi r25, 0x00 ; 0 e26: 0e 94 2f 03 call 0x65e ; 0x65e break; } default: break; } delayMs(5000); e2a: 88 e8 ldi r24, 0x88 ; 136 e2c: 93 e1 ldi r25, 0x13 ; 19 e2e: 0e 94 4f 01 call 0x29e ; 0x29e //irreversible freeze whole system #if (FREEZE_ON_ERROR == 1) freeze(); e32: 0e 94 60 01 call 0x2c0 ; 0x2c0 #endif }//end os_error e36: 08 95 ret break; } case(OS_ERROR_FINISHED): { lcd_clear(); e38: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(strERR_FINISHED); e3c: 8e e9 ldi r24, 0x9E ; 158 e3e: 90 e0 ldi r25, 0x00 ; 0 e40: 0e 94 2f 03 call 0x65e ; 0x65e break; } default: break; } delayMs(5000); e44: 88 e8 ldi r24, 0x88 ; 136 e46: 93 e1 ldi r25, 0x13 ; 19 e48: 0e 94 4f 01 call 0x29e ; 0x29e //irreversible freeze whole system #if (FREEZE_ON_ERROR == 1) freeze(); e4c: 0e 94 60 01 call 0x2c0 ; 0x2c0 #endif }//end os_error e50: 08 95 ret void os_error( enum os_ErrorCode e ) { cli(); //disable interrupts to avoid ISR ticking //handle error case switch (e) e52: 05 97 sbiw r24, 0x05 ; 5 e54: 51 f7 brne .-44 ; 0xe2a lcd_progString(strERR_NO_TASKS); break; } case(OS_ERROR_TASK_NOT_EXIST): { lcd_clear(); e56: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(strERR_NOT_EXIST); e5a: 89 ed ldi r24, 0xD9 ; 217 e5c: 90 e0 ldi r25, 0x00 ; 0 e5e: 0e 94 2f 03 call 0x65e ; 0x65e break; } default: break; } delayMs(5000); e62: 88 e8 ldi r24, 0x88 ; 136 e64: 93 e1 ldi r25, 0x13 ; 19 e66: 0e 94 4f 01 call 0x29e ; 0x29e //irreversible freeze whole system #if (FREEZE_ON_ERROR == 1) freeze(); e6a: 0e 94 60 01 call 0x2c0 ; 0x2c0 #endif }//end os_error e6e: 08 95 ret break; } case(OS_ERROR_NOTASK): { lcd_clear(); e70: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(strERR_NO_TASKS); e74: 8b ec ldi r24, 0xCB ; 203 e76: 90 e0 ldi r25, 0x00 ; 0 e78: 0e 94 2f 03 call 0x65e ; 0x65e break; } default: break; } delayMs(5000); e7c: 88 e8 ldi r24, 0x88 ; 136 e7e: 93 e1 ldi r25, 0x13 ; 19 e80: 0e 94 4f 01 call 0x29e ; 0x29e //irreversible freeze whole system #if (FREEZE_ON_ERROR == 1) freeze(); e84: 0e 94 60 01 call 0x2c0 ; 0x2c0 #endif }//end os_error e88: 08 95 ret break; } case(OS_ERROR_MAX_TASK_EXCEED): { lcd_clear(); e8a: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(strERR_MAX_TASKS); e8e: 8c ea ldi r24, 0xAC ; 172 e90: 90 e0 ldi r25, 0x00 ; 0 e92: 0e 94 2f 03 call 0x65e ; 0x65e break; } default: break; } delayMs(5000); e96: 88 e8 ldi r24, 0x88 ; 136 e98: 93 e1 ldi r25, 0x13 ; 19 e9a: 0e 94 4f 01 call 0x29e ; 0x29e //irreversible freeze whole system #if (FREEZE_ON_ERROR == 1) freeze(); e9e: 0e 94 60 01 call 0x2c0 ; 0x2c0 #endif }//end os_error ea2: 08 95 ret 00000ea4 : /*! * Readies stack, scheduler and heap for first use. */ void os_init() { ea4: 0e 94 a8 03 call 0x750 ; 0x750 //clear stack os_clearStack(); //init scheduler os_initScheduler(); ea8: 0e 94 7a 05 call 0xaf4 ; 0xaf4 //init heap os_initHeapMap(); eac: 0e 94 db 0b call 0x17b6 ; 0x17b6 //register idle task os_registerTask(os_idleTask,1); eb0: 61 e0 ldi r22, 0x01 ; 1 eb2: 86 ea ldi r24, 0xA6 ; 166 eb4: 95 e0 ldi r25, 0x05 ; 5 eb6: 0e 94 83 04 call 0x906 ; 0x906 }//end OSInit eba: 08 95 ret 00000ebc : } } //! Task 7 (writes "G" to LCD) void task7() { ebc: cf 93 push r28 ebe: df 93 push r29 //implement something in here while (1) { lcd_progString(strG); delayMs(os_taskOutputDelay); ec0: c0 91 04 01 lds r28, 0x0104 ec4: d0 91 05 01 lds r29, 0x0105 void task7() { //implement something in here while (1) { lcd_progString(strG); ec8: 8d e8 ldi r24, 0x8D ; 141 eca: 90 e0 ldi r25, 0x00 ; 0 ecc: 0e 94 2f 03 call 0x65e ; 0x65e delayMs(os_taskOutputDelay); ed0: ce 01 movw r24, r28 ed2: 0e 94 4f 01 call 0x29e ; 0x29e ed6: f8 cf rjmp .-16 ; 0xec8 00000ed8 : } } //! Task 6 (writes "F" to LCD) void task6() { ed8: cf 93 push r28 eda: df 93 push r29 //implement something in here while (1) { lcd_progString(strF); delayMs(os_taskOutputDelay); edc: c0 91 04 01 lds r28, 0x0104 ee0: d0 91 05 01 lds r29, 0x0105 void task6() { //implement something in here while (1) { lcd_progString(strF); ee4: 8b e8 ldi r24, 0x8B ; 139 ee6: 90 e0 ldi r25, 0x00 ; 0 ee8: 0e 94 2f 03 call 0x65e ; 0x65e delayMs(os_taskOutputDelay); eec: ce 01 movw r24, r28 eee: 0e 94 4f 01 call 0x29e ; 0x29e ef2: f8 cf rjmp .-16 ; 0xee4 00000ef4 : } //! Task 3 (writes "C" to LCD) void task3() { ef4: cf 93 push r28 ef6: df 93 push r29 //implement something in here while (1) { lcd_progString(strC); delayMs(os_taskOutputDelay); ef8: c0 91 04 01 lds r28, 0x0104 efc: d0 91 05 01 lds r29, 0x0105 void task3() { //implement something in here while (1) { lcd_progString(strC); f00: 85 e8 ldi r24, 0x85 ; 133 f02: 90 e0 ldi r25, 0x00 ; 0 f04: 0e 94 2f 03 call 0x65e ; 0x65e delayMs(os_taskOutputDelay); f08: ce 01 movw r24, r28 f0a: 0e 94 4f 01 call 0x29e ; 0x29e f0e: f8 cf rjmp .-16 ; 0xf00 00000f10 : } } //! Task 5 (writes "E" to LCD) void task5() { f10: cf 93 push r28 f12: df 93 push r29 { lcd_writeUint(os_buttonStates[0]); lcd_writeUint(os_buttonStates[1]); lcd_writeUint(os_buttonStates[2]); lcd_writeUint(os_buttonStates[3]); delayMs(os_taskOutputDelay); f14: c0 91 04 01 lds r28, 0x0104 f18: d0 91 05 01 lds r29, 0x0105 void task5() { //implement something in here while (1) { lcd_writeUint(os_buttonStates[0]); f1c: 80 91 18 01 lds r24, 0x0118 f20: 90 e0 ldi r25, 0x00 ; 0 f22: 0e 94 8c 02 call 0x518 ; 0x518 lcd_writeUint(os_buttonStates[1]); f26: 80 91 19 01 lds r24, 0x0119 f2a: 90 e0 ldi r25, 0x00 ; 0 f2c: 0e 94 8c 02 call 0x518 ; 0x518 lcd_writeUint(os_buttonStates[2]); f30: 80 91 1a 01 lds r24, 0x011A f34: 90 e0 ldi r25, 0x00 ; 0 f36: 0e 94 8c 02 call 0x518 ; 0x518 lcd_writeUint(os_buttonStates[3]); f3a: 80 91 1b 01 lds r24, 0x011B f3e: 90 e0 ldi r25, 0x00 ; 0 f40: 0e 94 8c 02 call 0x518 ; 0x518 delayMs(os_taskOutputDelay); f44: ce 01 movw r24, r28 f46: 0e 94 4f 01 call 0x29e ; 0x29e f4a: e8 cf rjmp .-48 ; 0xf1c 00000f4c : } } //! Task 4 (Testsuite for os_Memory.c) void task4() { f4c: 82 e0 ldi r24, 0x02 ; 2 f4e: 90 e0 ldi r25, 0x00 ; 0 f50: 0e 94 cc 0c call 0x1998 ; 0x1998 f54: fb cf rjmp .-10 ; 0xf4c 00000f56 : void task1() { f56: 84 e1 ldi r24, 0x14 ; 20 f58: 90 e0 ldi r25, 0x00 ; 0 f5a: 0e 94 cc 0c call 0x1998 ; 0x1998 f5e: 90 93 76 01 sts 0x0176, r25 f62: 80 93 75 01 sts 0x0175, r24 f66: ff cf rjmp .-2 ; 0xf66 00000f68 : void task2() { f68: cf 93 push r28 f6a: df 93 push r29 while (!((int)shared)); f6c: 80 91 75 01 lds r24, 0x0175 f70: 90 91 76 01 lds r25, 0x0176 f74: 89 2b or r24, r25 f76: 81 f0 breq .+32 ; 0xf98 while (1) { lcd_putByte((int)shared); lcd_writeString("wippy"); delayMs(os_taskOutputDelay); f78: c0 91 04 01 lds r28, 0x0104 f7c: d0 91 05 01 lds r29, 0x0105 while (!((int)shared)); while (1) { lcd_putByte((int)shared); f80: 80 91 75 01 lds r24, 0x0175 f84: 0e 94 d8 01 call 0x3b0 ; 0x3b0 lcd_writeString("wippy"); f88: 86 e0 ldi r24, 0x06 ; 6 f8a: 91 e0 ldi r25, 0x01 ; 1 f8c: 0e 94 e8 02 call 0x5d0 ; 0x5d0 delayMs(os_taskOutputDelay); f90: ce 01 movw r24, r28 f92: 0e 94 4f 01 call 0x29e ; 0x29e f96: f4 cf rjmp .-24 ; 0xf80 f98: ff cf rjmp .-2 ; 0xf98 00000f9a : asm volatile("ret"); } //! prints the strategy to the lcd void strategyToString(enum os_SchedulingStrategy strategy) { f9a: 82 30 cpi r24, 0x02 ; 2 f9c: 91 05 cpc r25, r1 f9e: e1 f0 breq .+56 ; 0xfd8 fa0: 83 30 cpi r24, 0x03 ; 3 fa2: 91 05 cpc r25, r1 fa4: 30 f0 brcs .+12 ; 0xfb2 fa6: 83 30 cpi r24, 0x03 ; 3 fa8: 91 05 cpc r25, r1 faa: d9 f0 breq .+54 ; 0xfe2 fac: 04 97 sbiw r24, 0x04 ; 4 fae: 79 f0 breq .+30 ; 0xfce fb0: 08 95 ret fb2: 00 97 sbiw r24, 0x00 ; 0 fb4: 39 f0 breq .+14 ; 0xfc4 fb6: 01 97 sbiw r24, 0x01 ; 1 fb8: d9 f7 brne .-10 ; 0xfb0 lcd_progString(strNONE); break; } case (OS_SCHED_EVEN): { lcd_progString(strEVEN); fba: 8a e3 ldi r24, 0x3A ; 58 fbc: 92 e0 ldi r25, 0x02 ; 2 fbe: 0e 94 2f 03 call 0x65e ; 0x65e fc2: 08 95 ret { switch(strategy) { case (OS_SCHED_NONE): { lcd_progString(strNONE); fc4: 85 e3 ldi r24, 0x35 ; 53 fc6: 92 e0 ldi r25, 0x02 ; 2 fc8: 0e 94 2f 03 call 0x65e ; 0x65e fcc: 08 95 ret lcd_progString(strINACTIVE_AGING); break; } case (OS_SCHED_RANDOM): { lcd_progString(strRANDOM); fce: 89 e5 ldi r24, 0x59 ; 89 fd0: 92 e0 ldi r25, 0x02 ; 2 fd2: 0e 94 2f 03 call 0x65e ; 0x65e fd6: 08 95 ret lcd_progString(strEVEN); break; } case (OS_SCHED_ROUND_ROBIN): { lcd_progString(strROUND_ROBIN); fd8: 8f e3 ldi r24, 0x3F ; 63 fda: 92 e0 ldi r25, 0x02 ; 2 fdc: 0e 94 2f 03 call 0x65e ; 0x65e fe0: 08 95 ret break; } case (OS_SCHED_INACTIVE_AGING): { lcd_progString(strINACTIVE_AGING); fe2: 8b e4 ldi r24, 0x4B ; 75 fe4: 92 e0 ldi r25, 0x02 ; 2 fe6: 0e 94 2f 03 call 0x65e ; 0x65e fea: 08 95 ret 00000fec : } } //! displays the result of task operations void os_taskManErrCode(enum os_PageResult type) { fec: cf 93 push r28 fee: df 93 push r29 ff0: ec 01 movw r28, r24 //clears line 2 of the lcd display lcd_line2(); ff2: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(pageTaskClearLine); ff6: 81 e1 ldi r24, 0x11 ; 17 ff8: 92 e0 ldi r25, 0x02 ; 2 ffa: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); ffe: 0e 94 c5 01 call 0x38a ; 0x38a switch (type) 1002: c2 30 cpi r28, 0x02 ; 2 1004: d1 05 cpc r29, r1 1006: a1 f1 breq .+104 ; 0x1070 1008: c3 30 cpi r28, 0x03 ; 3 100a: d1 05 cpc r29, r1 100c: 60 f0 brcs .+24 ; 0x1026 100e: c3 30 cpi r28, 0x03 ; 3 1010: d1 05 cpc r29, r1 1012: c9 f1 breq .+114 ; 0x1086 1014: 24 97 sbiw r28, 0x04 ; 4 1016: 09 f1 breq .+66 ; 0x105a case(OS_PG_NOACTIVE): // no active tasks exist so we cant do such an operation { lcd_progString(pageTaskNoActive); } } delayMs(500); 1018: 84 ef ldi r24, 0xF4 ; 244 101a: 91 e0 ldi r25, 0x01 ; 1 101c: 0e 94 4f 01 call 0x29e ; 0x29e } 1020: df 91 pop r29 1022: cf 91 pop r28 1024: 08 95 ret //clears line 2 of the lcd display lcd_line2(); lcd_progString(pageTaskClearLine); lcd_line2(); switch (type) 1026: 20 97 sbiw r28, 0x00 ; 0 1028: 69 f0 breq .+26 ; 0x1044 102a: 21 97 sbiw r28, 0x01 ; 1 102c: a9 f7 brne .-22 ; 0x1018 lcd_progString(pageTaskSuccess); break; } case(OS_PG_INVALID): // given task ID was invalid { lcd_progString(pageTaskInvalid); 102e: 81 ec ldi r24, 0xC1 ; 193 1030: 91 e0 ldi r25, 0x01 ; 1 1032: 0e 94 2f 03 call 0x65e ; 0x65e case(OS_PG_NOACTIVE): // no active tasks exist so we cant do such an operation { lcd_progString(pageTaskNoActive); } } delayMs(500); 1036: 84 ef ldi r24, 0xF4 ; 244 1038: 91 e0 ldi r25, 0x01 ; 1 103a: 0e 94 4f 01 call 0x29e ; 0x29e } 103e: df 91 pop r29 1040: cf 91 pop r28 1042: 08 95 ret switch (type) { case(OS_PG_SUCCESS): // operation was successfull { lcd_progString(pageTaskSuccess); 1044: 82 ee ldi r24, 0xE2 ; 226 1046: 91 e0 ldi r25, 0x01 ; 1 1048: 0e 94 2f 03 call 0x65e ; 0x65e case(OS_PG_NOACTIVE): // no active tasks exist so we cant do such an operation { lcd_progString(pageTaskNoActive); } } delayMs(500); 104c: 84 ef ldi r24, 0xF4 ; 244 104e: 91 e0 ldi r25, 0x01 ; 1 1050: 0e 94 4f 01 call 0x29e ; 0x29e } 1054: df 91 pop r29 1056: cf 91 pop r28 1058: 08 95 ret lcd_progString(pageTaskCancel); break; } case(OS_PG_NOACTIVE): // no active tasks exist so we cant do such an operation { lcd_progString(pageTaskNoActive); 105a: 80 e0 ldi r24, 0x00 ; 0 105c: 92 e0 ldi r25, 0x02 ; 2 105e: 0e 94 2f 03 call 0x65e ; 0x65e } } delayMs(500); 1062: 84 ef ldi r24, 0xF4 ; 244 1064: 91 e0 ldi r25, 0x01 ; 1 1066: 0e 94 4f 01 call 0x29e ; 0x29e } 106a: df 91 pop r29 106c: cf 91 pop r28 106e: 08 95 ret lcd_progString(pageTaskInvalid); break; } case(OS_PG_EXCEED): // maximum number of tasks is exceeded so no more can be started { lcd_progString(pageTaskMaxExceed); 1070: 82 ed ldi r24, 0xD2 ; 210 1072: 91 e0 ldi r25, 0x01 ; 1 1074: 0e 94 2f 03 call 0x65e ; 0x65e case(OS_PG_NOACTIVE): // no active tasks exist so we cant do such an operation { lcd_progString(pageTaskNoActive); } } delayMs(500); 1078: 84 ef ldi r24, 0xF4 ; 244 107a: 91 e0 ldi r25, 0x01 ; 1 107c: 0e 94 4f 01 call 0x29e ; 0x29e } 1080: df 91 pop r29 1082: cf 91 pop r28 1084: 08 95 ret lcd_progString(pageTaskMaxExceed); break; } case(OS_PG_CANCEL): // the operation was canceled { lcd_progString(pageTaskCancel); 1086: 83 ef ldi r24, 0xF3 ; 243 1088: 91 e0 ldi r25, 0x01 ; 1 108a: 0e 94 2f 03 call 0x65e ; 0x65e case(OS_PG_NOACTIVE): // no active tasks exist so we cant do such an operation { lcd_progString(pageTaskNoActive); } } delayMs(500); 108e: 84 ef ldi r24, 0xF4 ; 244 1090: 91 e0 ldi r25, 0x01 ; 1 1092: 0e 94 4f 01 call 0x29e ; 0x29e } 1096: df 91 pop r29 1098: cf 91 pop r28 109a: 08 95 ret 0000109c : // Local Functions //---------------------------------------------------------------------------- //! Exits the task manager void os_taskManExit() { 109c: 0e 94 d2 01 call 0x3a4 ; 0x3a4 //clears the lcd lcd_clear(); //resets the currentKilled flag currentKilled = 0; 10a0: 10 92 15 01 sts 0x0115, r1 //sets the stackpointer back to the point when the taskManMain function was called SP = taskManEntry; 10a4: 80 91 77 01 lds r24, 0x0177 10a8: 90 91 78 01 lds r25, 0x0178 10ac: 9e bf out 0x3e, r25 ; 62 10ae: 8d bf out 0x3d, r24 ; 61 //return to the ISR asm volatile("ret"); 10b0: 08 95 ret } 10b2: 08 95 ret 000010b4 : } //! Ressource overview loop. void os_taskManRessources () { 10b4: 0e 94 64 0e call 0x1cc8 ; 0x1cc8 { //wait until all buttons are released os_waitForNoInput(); //wait until next button is pressed os_waitForInput(); 10b8: 0e 94 77 0e call 0x1cee ; 0x1cee switch (os_getLastButton()) 10bc: 0e 94 8a 0e call 0x1d14 ; 0x1d14 10c0: 04 97 sbiw r24, 0x04 ; 4 10c2: c0 f7 brcc .-16 ; 0x10b4 } default : break; } } } 10c4: 08 95 ret 000010c6 : } } //! The SubmenuLoop unsigned char os_taskManSubmenu (enum os_PageType type, unsigned char value) { 10c6: 1f 93 push r17 10c8: cf 93 push r28 10ca: df 93 push r29 10cc: ec 01 movw r28, r24 10ce: 16 2f mov r17, r22 while (1) { //init lcd text lcd_clear(); 10d0: 0e 94 d2 01 call 0x3a4 ; 0x3a4 switch(type) 10d4: c1 30 cpi r28, 0x01 ; 1 10d6: d1 05 cpc r29, r1 10d8: 09 f4 brne .+2 ; 0x10dc 10da: 45 c0 rjmp .+138 ; 0x1166 <__stack+0x67> 10dc: c1 30 cpi r28, 0x01 ; 1 10de: d1 05 cpc r29, r1 10e0: 50 f5 brcc .+84 ; 0x1136 <__stack+0x37> { case(OS_PG_TASK): // All Tasks { lcd_progString(page7_1a); 10e2: 80 e8 ldi r24, 0x80 ; 128 10e4: 91 e0 ldi r25, 0x01 ; 1 strategyToString(value); break; } case(OS_PG_VALUE):// Priority Value { lcd_progString(page7_1b); 10e6: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); 10ea: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(page7_2); 10ee: 8f ea ldi r24, 0xAF ; 175 10f0: 91 e0 ldi r25, 0x01 ; 1 10f2: 0e 94 2f 03 call 0x65e ; 0x65e lcd_writeUint(value); 10f6: 81 2f mov r24, r17 10f8: 90 e0 ldi r25, 0x00 ; 0 10fa: 0e 94 8c 02 call 0x518 ; 0x518 break; } } //wait until all buttons are released os_waitForNoInput(); 10fe: 0e 94 64 0e call 0x1cc8 ; 0x1cc8 //wait until next button is pressed os_waitForInput(); 1102: 0e 94 77 0e call 0x1cee ; 0x1cee //handle input switch (os_getLastButton()) 1106: 0e 94 8a 0e call 0x1d14 ; 0x1d14 110a: 81 30 cpi r24, 0x01 ; 1 110c: 91 05 cpc r25, r1 110e: 09 f4 brne .+2 ; 0x1112 <__stack+0x13> 1110: 8b c0 rjmp .+278 ; 0x1228 <__stack+0x129> 1112: 81 30 cpi r24, 0x01 ; 1 1114: 91 05 cpc r25, r1 1116: 50 f0 brcs .+20 ; 0x112c <__stack+0x2d> 1118: 82 30 cpi r24, 0x02 ; 2 111a: 91 05 cpc r25, r1 111c: 09 f4 brne .+2 ; 0x1120 <__stack+0x21> 111e: 48 c0 rjmp .+144 ; 0x11b0 <__stack+0xb1> 1120: 03 97 sbiw r24, 0x03 ; 3 1122: b1 f6 brne .-84 ; 0x10d0 return value; break; } case (OS_ESC): // ESC cancels the input and returns to the calling main Menu { if (type != OS_PG_SCHED) 1124: 23 97 sbiw r28, 0x03 ; 3 1126: 09 f4 brne .+2 ; 0x112a <__stack+0x2b> 1128: b6 c0 rjmp .+364 ; 0x1296 <__stack+0x197> 112a: 10 e0 ldi r17, 0x00 ; 0 default : break; } } } 112c: 81 2f mov r24, r17 112e: df 91 pop r29 1130: cf 91 pop r28 1132: 1f 91 pop r17 1134: 08 95 ret { while (1) { //init lcd text lcd_clear(); switch(type) 1136: c2 30 cpi r28, 0x02 ; 2 1138: d1 05 cpc r29, r1 113a: 91 f0 breq .+36 ; 0x1160 <__stack+0x61> 113c: c3 30 cpi r28, 0x03 ; 3 113e: d1 05 cpc r29, r1 1140: f1 f6 brne .-68 ; 0x10fe lcd_progString(pageTaskActive); break; } case(OS_PG_SCHED): // Scheduling Strategy { lcd_progString(page7_1c); 1142: 8e e9 ldi r24, 0x9E ; 158 1144: 91 e0 ldi r25, 0x01 ; 1 1146: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); 114a: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(page7_2); 114e: 8f ea ldi r24, 0xAF ; 175 1150: 91 e0 ldi r25, 0x01 ; 1 1152: 0e 94 2f 03 call 0x65e ; 0x65e strategyToString(value); 1156: 81 2f mov r24, r17 1158: 90 e0 ldi r25, 0x00 ; 0 115a: 0e 94 cd 07 call 0xf9a ; 0xf9a 115e: cf cf rjmp .-98 ; 0x10fe break; } case(OS_PG_VALUE):// Priority Value { lcd_progString(page7_1b); 1160: 80 e9 ldi r24, 0x90 ; 144 1162: 91 e0 ldi r25, 0x01 ; 1 1164: c0 cf rjmp .-128 ; 0x10e6 lcd_writeUint(value); break; } case(OS_PG_ACTIVE_TASK): //Only active Tasks { lcd_progString(page7_1a); 1166: 80 e8 ldi r24, 0x80 ; 128 1168: 91 e0 ldi r25, 0x01 ; 1 116a: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); 116e: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(page7_2); 1172: 8f ea ldi r24, 0xAF ; 175 1174: 91 e0 ldi r25, 0x01 ; 1 1176: 0e 94 2f 03 call 0x65e ; 0x65e lcd_writeUint(value); 117a: 81 2f mov r24, r17 117c: 90 e0 ldi r25, 0x00 ; 0 117e: 0e 94 8c 02 call 0x518 ; 0x518 if (os_taskStates[value].state == OS_TASK_PAUSED) 1182: 81 2f mov r24, r17 1184: 90 e0 ldi r25, 0x00 ; 0 1186: fc 01 movw r30, r24 1188: ee 0f add r30, r30 118a: ff 1f adc r31, r31 118c: ee 0f add r30, r30 118e: ff 1f adc r31, r31 1190: ee 0f add r30, r30 1192: ff 1f adc r31, r31 1194: e8 0f add r30, r24 1196: f9 1f adc r31, r25 1198: e4 5e subi r30, 0xE4 ; 228 119a: fe 4f sbci r31, 0xFE ; 254 119c: 80 81 ld r24, Z 119e: 91 81 ldd r25, Z+1 ; 0x01 11a0: 03 97 sbiw r24, 0x03 ; 3 11a2: 09 f4 brne .+2 ; 0x11a6 <__stack+0xa7> 11a4: 8f c0 rjmp .+286 ; 0x12c4 <__stack+0x1c5> lcd_progString(pageTaskPaused); else lcd_progString(pageTaskActive); 11a6: 82 e2 ldi r24, 0x22 ; 34 11a8: 92 e0 ldi r25, 0x02 ; 2 11aa: 0e 94 2f 03 call 0x65e ; 0x65e 11ae: a7 cf rjmp .-178 ; 0x10fe } break; } case (OS_UP): // increase actual value with correct rings { switch(type) 11b0: c1 30 cpi r28, 0x01 ; 1 11b2: d1 05 cpc r29, r1 11b4: a9 f0 breq .+42 ; 0x11e0 <__stack+0xe1> 11b6: c1 30 cpi r28, 0x01 ; 1 11b8: d1 05 cpc r29, r1 11ba: 08 f4 brcc .+2 ; 0x11be <__stack+0xbf> 11bc: 72 c0 rjmp .+228 ; 0x12a2 <__stack+0x1a3> 11be: c2 30 cpi r28, 0x02 ; 2 11c0: d1 05 cpc r29, r1 11c2: 09 f4 brne .+2 ; 0x11c6 <__stack+0xc7> 11c4: 84 c0 rjmp .+264 ; 0x12ce <__stack+0x1cf> 11c6: c3 30 cpi r28, 0x03 ; 3 11c8: d1 05 cpc r29, r1 11ca: 09 f0 breq .+2 ; 0x11ce <__stack+0xcf> 11cc: 81 cf rjmp .-254 ; 0x10d0 value = ((value+1)%256 == 0 ? 1 : (value+1)%256); // 1..255 break; } case(OS_PG_SCHED): { value = (value+1)%5; 11ce: 81 2f mov r24, r17 11d0: 90 e0 ldi r25, 0x00 ; 0 11d2: 01 96 adiw r24, 0x01 ; 1 11d4: 65 e0 ldi r22, 0x05 ; 5 11d6: 70 e0 ldi r23, 0x00 ; 0 11d8: 0e 94 17 0f call 0x1e2e ; 0x1e2e <__divmodhi4> 11dc: 18 2f mov r17, r24 11de: 78 cf rjmp .-272 ; 0x10d0 } case(OS_PG_ACTIVE_TASK): //only active tasks are shown { do { value = ((value+1)%MAX_NUMBER_OF_TASKS == 0 ? 1 : (value+1)%MAX_NUMBER_OF_TASKS); 11e0: 61 2f mov r22, r17 11e2: 70 e0 ldi r23, 0x00 ; 0 11e4: 6f 5f subi r22, 0xFF ; 255 11e6: 7f 4f sbci r23, 0xFF ; 255 11e8: 67 70 andi r22, 0x07 ; 7 11ea: 70 70 andi r23, 0x00 ; 0 11ec: 61 15 cp r22, r1 11ee: 71 05 cpc r23, r1 11f0: b9 f4 brne .+46 ; 0x1220 <__stack+0x121> 11f2: 11 e0 ldi r17, 0x01 ; 1 11f4: 81 e0 ldi r24, 0x01 ; 1 11f6: 90 e0 ldi r25, 0x00 ; 0 } while ((os_taskStates[value].state == OS_TASK_UNUSED)||(os_taskStates[value].state == OS_TASK_KILLED)); 11f8: fc 01 movw r30, r24 11fa: ee 0f add r30, r30 11fc: ff 1f adc r31, r31 11fe: ee 0f add r30, r30 1200: ff 1f adc r31, r31 1202: ee 0f add r30, r30 1204: ff 1f adc r31, r31 1206: e8 0f add r30, r24 1208: f9 1f adc r31, r25 120a: e4 5e subi r30, 0xE4 ; 228 120c: fe 4f sbci r31, 0xFE ; 254 120e: 80 81 ld r24, Z 1210: 91 81 ldd r25, Z+1 ; 0x01 1212: 89 2b or r24, r25 1214: 29 f3 breq .-54 ; 0x11e0 <__stack+0xe1> 1216: 80 81 ld r24, Z 1218: 91 81 ldd r25, Z+1 ; 0x01 121a: 04 97 sbiw r24, 0x04 ; 4 121c: 09 f3 breq .-62 ; 0x11e0 <__stack+0xe1> 121e: 58 cf rjmp .-336 ; 0x10d0 } case(OS_PG_ACTIVE_TASK): //only active tasks are shown { do { value = ((value+1)%MAX_NUMBER_OF_TASKS == 0 ? 1 : (value+1)%MAX_NUMBER_OF_TASKS); 1220: 16 2f mov r17, r22 1222: 86 2f mov r24, r22 1224: 90 e0 ldi r25, 0x00 ; 0 1226: e8 cf rjmp .-48 ; 0x11f8 <__stack+0xf9> //handle input switch (os_getLastButton()) { case (OS_DOWN): // decrease actual value with correct rings { switch(type) 1228: c1 30 cpi r28, 0x01 ; 1 122a: d1 05 cpc r29, r1 122c: 89 f0 breq .+34 ; 0x1250 <__stack+0x151> 122e: c1 30 cpi r28, 0x01 ; 1 1230: d1 05 cpc r29, r1 1232: 08 f4 brcc .+2 ; 0x1236 <__stack+0x137> 1234: 41 c0 rjmp .+130 ; 0x12b8 <__stack+0x1b9> 1236: c2 30 cpi r28, 0x02 ; 2 1238: d1 05 cpc r29, r1 123a: 09 f4 brne .+2 ; 0x123e <__stack+0x13f> 123c: 50 c0 rjmp .+160 ; 0x12de <__stack+0x1df> 123e: c3 30 cpi r28, 0x03 ; 3 1240: d1 05 cpc r29, r1 1242: 09 f0 breq .+2 ; 0x1246 <__stack+0x147> 1244: 45 cf rjmp .-374 ; 0x10d0 value = ((value-1) < 1 ? 255 : (value-1)); //1..255 break; } case(OS_PG_SCHED): { value = ((value-1) < 0 ? 4 : (value -1)); //0..4 1246: 11 23 and r17, r17 1248: 09 f4 brne .+2 ; 0x124c <__stack+0x14d> 124a: 50 c0 rjmp .+160 ; 0x12ec <__stack+0x1ed> 124c: 11 50 subi r17, 0x01 ; 1 124e: 40 cf rjmp .-384 ; 0x10d0 } case(OS_PG_ACTIVE_TASK): //only active tasks are shown { do { value = ((value-1) < 1 ? MAX_NUMBER_OF_TASKS-1 : (value -1) ); 1250: 81 2f mov r24, r17 1252: 90 e0 ldi r25, 0x00 ; 0 1254: 02 97 sbiw r24, 0x02 ; 2 1256: dc f0 brlt .+54 ; 0x128e <__stack+0x18f> 1258: 11 50 subi r17, 0x01 ; 1 125a: 81 2f mov r24, r17 125c: 90 e0 ldi r25, 0x00 ; 0 } while ((os_taskStates[value].state == OS_TASK_UNUSED)||(os_taskStates[value].state == OS_TASK_KILLED)); 125e: fc 01 movw r30, r24 1260: ee 0f add r30, r30 1262: ff 1f adc r31, r31 1264: ee 0f add r30, r30 1266: ff 1f adc r31, r31 1268: ee 0f add r30, r30 126a: ff 1f adc r31, r31 126c: e8 0f add r30, r24 126e: f9 1f adc r31, r25 1270: e4 5e subi r30, 0xE4 ; 228 1272: fe 4f sbci r31, 0xFE ; 254 1274: 80 81 ld r24, Z 1276: 91 81 ldd r25, Z+1 ; 0x01 1278: 89 2b or r24, r25 127a: 51 f3 breq .-44 ; 0x1250 <__stack+0x151> 127c: 80 81 ld r24, Z 127e: 91 81 ldd r25, Z+1 ; 0x01 1280: 04 97 sbiw r24, 0x04 ; 4 1282: 09 f0 breq .+2 ; 0x1286 <__stack+0x187> 1284: 25 cf rjmp .-438 ; 0x10d0 } case(OS_PG_ACTIVE_TASK): //only active tasks are shown { do { value = ((value-1) < 1 ? MAX_NUMBER_OF_TASKS-1 : (value -1) ); 1286: 81 2f mov r24, r17 1288: 90 e0 ldi r25, 0x00 ; 0 128a: 02 97 sbiw r24, 0x02 ; 2 128c: 2c f7 brge .-54 ; 0x1258 <__stack+0x159> 128e: 17 e0 ldi r17, 0x07 ; 7 1290: 87 e0 ldi r24, 0x07 ; 7 1292: 90 e0 ldi r25, 0x00 ; 0 1294: e4 cf rjmp .-56 ; 0x125e <__stack+0x15f> return value; break; } case (OS_ESC): // ESC cancels the input and returns to the calling main Menu { if (type != OS_PG_SCHED) 1296: 15 e0 ldi r17, 0x05 ; 5 default : break; } } } 1298: 81 2f mov r24, r17 129a: df 91 pop r29 129c: cf 91 pop r28 129e: 1f 91 pop r17 12a0: 08 95 ret { switch(type) { case(OS_PG_TASK): { value = ((value+1)%MAX_NUMBER_OF_TASKS == 0 ? 1 : (value+1)%MAX_NUMBER_OF_TASKS); // 1..MAX_TASKS-1 12a2: 61 2f mov r22, r17 12a4: 70 e0 ldi r23, 0x00 ; 0 12a6: 6f 5f subi r22, 0xFF ; 255 12a8: 7f 4f sbci r23, 0xFF ; 255 12aa: 67 70 andi r22, 0x07 ; 7 12ac: 70 70 andi r23, 0x00 ; 0 12ae: 61 15 cp r22, r1 12b0: 71 05 cpc r23, r1 12b2: 99 f0 breq .+38 ; 0x12da <__stack+0x1db> } while ((os_taskStates[value].state == OS_TASK_UNUSED)||(os_taskStates[value].state == OS_TASK_KILLED)); break; } case(OS_PG_VALUE): { value = ((value+1)%256 == 0 ? 1 : (value+1)%256); // 1..255 12b4: 16 2f mov r17, r22 12b6: 0c cf rjmp .-488 ; 0x10d0 { switch(type) { case(OS_PG_TASK): { value = ((value-1) < 1 ? MAX_NUMBER_OF_TASKS-1 : (value -1) ); // 1..MAX_TASKS-1 12b8: 81 2f mov r24, r17 12ba: 90 e0 ldi r25, 0x00 ; 0 12bc: 02 97 sbiw r24, 0x02 ; 2 12be: 34 f6 brge .-116 ; 0x124c <__stack+0x14d> } } //! The SubmenuLoop unsigned char os_taskManSubmenu (enum os_PageType type, unsigned char value) { 12c0: 17 e0 ldi r17, 0x07 ; 7 12c2: 06 cf rjmp .-500 ; 0x10d0 lcd_progString(page7_1a); lcd_line2(); lcd_progString(page7_2); lcd_writeUint(value); if (os_taskStates[value].state == OS_TASK_PAUSED) lcd_progString(pageTaskPaused); 12c4: 8b e2 ldi r24, 0x2B ; 43 12c6: 92 e0 ldi r25, 0x02 ; 2 12c8: 0e 94 2f 03 call 0x65e ; 0x65e 12cc: 18 cf rjmp .-464 ; 0x10fe } while ((os_taskStates[value].state == OS_TASK_UNUSED)||(os_taskStates[value].state == OS_TASK_KILLED)); break; } case(OS_PG_VALUE): { value = ((value+1)%256 == 0 ? 1 : (value+1)%256); // 1..255 12ce: 61 2f mov r22, r17 12d0: 70 e0 ldi r23, 0x00 ; 0 12d2: 6f 5f subi r22, 0xFF ; 255 12d4: 7f 4f sbci r23, 0xFF ; 255 12d6: 66 23 and r22, r22 12d8: 69 f7 brne .-38 ; 0x12b4 <__stack+0x1b5> } } //! The SubmenuLoop unsigned char os_taskManSubmenu (enum os_PageType type, unsigned char value) { 12da: 11 e0 ldi r17, 0x01 ; 1 12dc: f9 ce rjmp .-526 ; 0x10d0 } while ((os_taskStates[value].state == OS_TASK_UNUSED)||(os_taskStates[value].state == OS_TASK_KILLED)); break; } case(OS_PG_VALUE): { value = ((value-1) < 1 ? 255 : (value-1)); //1..255 12de: 81 2f mov r24, r17 12e0: 90 e0 ldi r25, 0x00 ; 0 12e2: 02 97 sbiw r24, 0x02 ; 2 12e4: 0c f0 brlt .+2 ; 0x12e8 <__stack+0x1e9> 12e6: b2 cf rjmp .-156 ; 0x124c <__stack+0x14d> 12e8: 1f ef ldi r17, 0xFF ; 255 12ea: f2 ce rjmp .-540 ; 0x10d0 break; } case(OS_PG_SCHED): { value = ((value-1) < 0 ? 4 : (value -1)); //0..4 12ec: 14 e0 ldi r17, 0x04 ; 4 12ee: f0 ce rjmp .-544 ; 0x10d0 000012f0 : } } //! 6: The "pause task" loop of the Task Manager. void os_taskManPauseTask () { 12f0: 0e 94 d2 01 call 0x3a4 ; 0x3a4 while (1) { //write initial text lcd_clear(); lcd_progString(page6_1); 12f4: 84 e6 ldi r24, 0x64 ; 100 12f6: 91 e0 ldi r25, 0x01 ; 1 12f8: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); 12fc: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(pageEnter); 1300: 82 e7 ldi r24, 0x72 ; 114 1302: 91 e0 ldi r25, 0x01 ; 1 1304: 0e 94 2f 03 call 0x65e ; 0x65e //wait until all buttons are released os_waitForNoInput(); 1308: 0e 94 64 0e call 0x1cc8 ; 0x1cc8 //wait until next button is pressed os_waitForInput(); 130c: 0e 94 77 0e call 0x1cee ; 0x1cee switch (os_getLastButton()) 1310: 0e 94 8a 0e call 0x1d14 ; 0x1d14 1314: 82 30 cpi r24, 0x02 ; 2 1316: 91 05 cpc r25, r1 1318: 81 f1 breq .+96 ; 0x137a 131a: 83 30 cpi r24, 0x03 ; 3 131c: 91 05 cpc r25, r1 131e: 51 f1 breq .+84 ; 0x1374 1320: 89 2b or r24, r25 1322: 31 f7 brne .-52 ; 0x12f0 return; //return to previous page break; } case (OS_ENTER): { if (os_getNumberOfActiveTasks() != 0) 1324: 0e 94 ba 03 call 0x774 ; 0x774 1328: 88 23 and r24, r24 132a: 41 f1 breq .+80 ; 0x137c { //get task to pause unsigned char taskSelect = 0; taskSelect = os_taskManSubmenu (OS_PG_ACTIVE_TASK, (currentKilled ? 0 : os_getCurrentTask())); 132c: 80 91 15 01 lds r24, 0x0115 1330: 88 23 and r24, r24 1332: 71 f1 breq .+92 ; 0x1390 1334: 60 e0 ldi r22, 0x00 ; 0 1336: 81 e0 ldi r24, 0x01 ; 1 1338: 90 e0 ldi r25, 0x00 ; 0 133a: 0e 94 63 08 call 0x10c6 ; 0x10c6 if (taskSelect!=0) 133e: 88 23 and r24, r24 1340: 11 f1 breq .+68 ; 0x1386 { //if taskSelect is active pause it if (os_taskStates[taskSelect].state!= OS_TASK_PAUSED) 1342: 90 e0 ldi r25, 0x00 ; 0 1344: fc 01 movw r30, r24 1346: ee 0f add r30, r30 1348: ff 1f adc r31, r31 134a: ee 0f add r30, r30 134c: ff 1f adc r31, r31 134e: ee 0f add r30, r30 1350: ff 1f adc r31, r31 1352: e8 0f add r30, r24 1354: f9 1f adc r31, r25 1356: e4 5e subi r30, 0xE4 ; 228 1358: fe 4f sbci r31, 0xFE ; 254 135a: 80 81 ld r24, Z 135c: 91 81 ldd r25, Z+1 ; 0x01 135e: 03 97 sbiw r24, 0x03 ; 3 1360: d9 f0 breq .+54 ; 0x1398 { os_taskStates[taskSelect].state = OS_TASK_PAUSED; 1362: 83 e0 ldi r24, 0x03 ; 3 1364: 90 e0 ldi r25, 0x00 ; 0 1366: 91 83 std Z+1, r25 ; 0x01 1368: 80 83 st Z, r24 else // re-enable it { os_taskStates[taskSelect].state = OS_TASK_READY; } os_taskManErrCode(OS_PG_SUCCESS); 136a: 80 e0 ldi r24, 0x00 ; 0 136c: 90 e0 ldi r25, 0x00 ; 0 136e: 0e 94 f6 07 call 0xfec ; 0xfec 1372: be cf rjmp .-132 ; 0x12f0 } break; } case (OS_ESC): // exit TaskMan { os_taskManExit(); 1374: 0e 94 4e 08 call 0x109c ; 0x109c 1378: bb cf rjmp .-138 ; 0x12f0 137a: 08 95 ret break; } } else { os_taskManErrCode(OS_PG_NOACTIVE); 137c: 84 e0 ldi r24, 0x04 ; 4 137e: 90 e0 ldi r25, 0x00 ; 0 1380: 0e 94 f6 07 call 0xfec ; 0xfec 1384: b5 cf rjmp .-150 ; 0x12f0 os_taskManErrCode(OS_PG_SUCCESS); break; } else { os_taskManErrCode(OS_PG_CANCEL); 1386: 83 e0 ldi r24, 0x03 ; 3 1388: 90 e0 ldi r25, 0x00 ; 0 138a: 0e 94 f6 07 call 0xfec ; 0xfec 138e: b0 cf rjmp .-160 ; 0x12f0 { if (os_getNumberOfActiveTasks() != 0) { //get task to pause unsigned char taskSelect = 0; taskSelect = os_taskManSubmenu (OS_PG_ACTIVE_TASK, (currentKilled ? 0 : os_getCurrentTask())); 1390: 0e 94 b4 03 call 0x768 ; 0x768 1394: 68 2f mov r22, r24 1396: cf cf rjmp .-98 ; 0x1336 { os_taskStates[taskSelect].state = OS_TASK_PAUSED; } else // re-enable it { os_taskStates[taskSelect].state = OS_TASK_READY; 1398: 81 e0 ldi r24, 0x01 ; 1 139a: 90 e0 ldi r25, 0x00 ; 0 139c: 91 83 std Z+1, r25 ; 0x01 139e: 80 83 st Z, r24 13a0: e4 cf rjmp .-56 ; 0x136a 000013a2 : } } //! 5: The "scheduling strategy" loop of the Task Manager. void os_taskManScheduling () { 13a2: 0e 94 d2 01 call 0x3a4 ; 0x3a4 while (1) { //write initial text lcd_clear(); lcd_progString(page5_1); 13a6: 83 e5 ldi r24, 0x53 ; 83 13a8: 91 e0 ldi r25, 0x01 ; 1 13aa: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); 13ae: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(pageEnter); 13b2: 82 e7 ldi r24, 0x72 ; 114 13b4: 91 e0 ldi r25, 0x01 ; 1 13b6: 0e 94 2f 03 call 0x65e ; 0x65e //wait until all buttons are released os_waitForNoInput(); 13ba: 0e 94 64 0e call 0x1cc8 ; 0x1cc8 //wait until next button is pressed os_waitForInput(); 13be: 0e 94 77 0e call 0x1cee ; 0x1cee switch (os_getLastButton()) 13c2: 0e 94 8a 0e call 0x1d14 ; 0x1d14 13c6: 81 30 cpi r24, 0x01 ; 1 13c8: 91 05 cpc r25, r1 13ca: e1 f0 breq .+56 ; 0x1404 13cc: 81 30 cpi r24, 0x01 ; 1 13ce: 91 05 cpc r25, r1 13d0: 40 f0 brcs .+16 ; 0x13e2 13d2: 82 30 cpi r24, 0x02 ; 2 13d4: 91 05 cpc r25, r1 13d6: c9 f0 breq .+50 ; 0x140a 13d8: 03 97 sbiw r24, 0x03 ; 3 13da: 19 f7 brne .-58 ; 0x13a2 break; } } case (OS_ESC): { os_taskManExit(); 13dc: 0e 94 4e 08 call 0x109c ; 0x109c 13e0: e0 cf rjmp .-64 ; 0x13a2 break; } case (OS_ENTER): //selects the scheduling strategy { unsigned char valueSelect = 5; valueSelect = os_taskManSubmenu(OS_PG_SCHED,os_getSchedulingStrategy()); 13e2: 0e 94 23 04 call 0x846 ; 0x846 13e6: 68 2f mov r22, r24 13e8: 83 e0 ldi r24, 0x03 ; 3 13ea: 90 e0 ldi r25, 0x00 ; 0 13ec: 0e 94 63 08 call 0x10c6 ; 0x10c6 if (valueSelect != 5) 13f0: 85 30 cpi r24, 0x05 ; 5 13f2: 61 f0 breq .+24 ; 0x140c { os_setSchedulingStrategy(valueSelect); 13f4: 90 e0 ldi r25, 0x00 ; 0 13f6: 0e 94 2a 04 call 0x854 ; 0x854 os_taskManErrCode(OS_PG_SUCCESS); 13fa: 80 e0 ldi r24, 0x00 ; 0 13fc: 90 e0 ldi r25, 0x00 ; 0 13fe: 0e 94 f6 07 call 0xfec ; 0xfec 1402: cf cf rjmp .-98 ; 0x13a2 switch (os_getLastButton()) { case (OS_DOWN): // switch to pause task { os_taskManPauseTask(); 1404: 0e 94 78 09 call 0x12f0 ; 0x12f0 1408: cc cf rjmp .-104 ; 0x13a2 140a: 08 95 ret os_taskManErrCode(OS_PG_SUCCESS); break; } else { os_taskManErrCode(OS_PG_CANCEL); 140c: 83 e0 ldi r24, 0x03 ; 3 140e: 90 e0 ldi r25, 0x00 ; 0 1410: 0e 94 f6 07 call 0xfec ; 0xfec 1414: c6 cf rjmp .-116 ; 0x13a2 00001416 : } //! 4: The "priorities" loop of the Task Manager. void os_taskManPriorities () { 1416: cf 93 push r28 1418: df 93 push r29 while (1) { //write initial text lcd_clear(); 141a: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(page4_1); 141e: 83 e4 ldi r24, 0x43 ; 67 1420: 91 e0 ldi r25, 0x01 ; 1 1422: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); 1426: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(pageEnter); 142a: 82 e7 ldi r24, 0x72 ; 114 142c: 91 e0 ldi r25, 0x01 ; 1 142e: 0e 94 2f 03 call 0x65e ; 0x65e //wait until all buttons are released os_waitForNoInput(); 1432: 0e 94 64 0e call 0x1cc8 ; 0x1cc8 //wait until next button is pressed os_waitForInput(); 1436: 0e 94 77 0e call 0x1cee ; 0x1cee switch (os_getLastButton()) 143a: 0e 94 8a 0e call 0x1d14 ; 0x1d14 143e: 81 30 cpi r24, 0x01 ; 1 1440: 91 05 cpc r25, r1 1442: c1 f1 breq .+112 ; 0x14b4 1444: 81 30 cpi r24, 0x01 ; 1 1446: 91 05 cpc r25, r1 1448: 48 f5 brcc .+82 ; 0x149c return; break; } case (OS_ENTER): { if (os_getNumberOfActiveTasks() != 0) 144a: 0e 94 ba 03 call 0x774 ; 0x774 144e: 88 23 and r24, r24 1450: 09 f4 brne .+2 ; 0x1454 1452: 41 c0 rjmp .+130 ; 0x14d6 { //get task to change prio unsigned char taskSelect = 0; taskSelect = os_taskManSubmenu (OS_PG_ACTIVE_TASK, (currentKilled ? 0 : os_getCurrentTask())); 1454: 80 91 15 01 lds r24, 0x0115 1458: 88 23 and r24, r24 145a: 79 f1 breq .+94 ; 0x14ba 145c: 60 e0 ldi r22, 0x00 ; 0 145e: 81 e0 ldi r24, 0x01 ; 1 1460: 90 e0 ldi r25, 0x00 ; 0 1462: 0e 94 63 08 call 0x10c6 ; 0x10c6 if (taskSelect!=0) 1466: 88 23 and r24, r24 1468: 89 f1 breq .+98 ; 0x14cc { // get the value to be set unsigned char valueSelect = 0; valueSelect = os_taskManSubmenu(OS_PG_VALUE,os_taskStates[taskSelect].maxTimeSlice); 146a: 90 e0 ldi r25, 0x00 ; 0 146c: ec 01 movw r28, r24 146e: cc 0f add r28, r28 1470: dd 1f adc r29, r29 1472: cc 0f add r28, r28 1474: dd 1f adc r29, r29 1476: cc 0f add r28, r28 1478: dd 1f adc r29, r29 147a: c8 0f add r28, r24 147c: d9 1f adc r29, r25 147e: c4 5e subi r28, 0xE4 ; 228 1480: de 4f sbci r29, 0xFE ; 254 1482: 6a 81 ldd r22, Y+2 ; 0x02 1484: 82 e0 ldi r24, 0x02 ; 2 1486: 90 e0 ldi r25, 0x00 ; 0 1488: 0e 94 63 08 call 0x10c6 ; 0x10c6 if (valueSelect != 0) 148c: 88 23 and r24, r24 148e: f1 f0 breq .+60 ; 0x14cc { // set the value if all input is valid os_taskStates[taskSelect].maxTimeSlice = valueSelect; 1490: 8a 83 std Y+2, r24 ; 0x02 os_taskManErrCode(OS_PG_SUCCESS); 1492: 80 e0 ldi r24, 0x00 ; 0 1494: 90 e0 ldi r25, 0x00 ; 0 1496: 0e 94 f6 07 call 0xfec ; 0xfec 149a: bf cf rjmp .-130 ; 0x141a //wait until all buttons are released os_waitForNoInput(); //wait until next button is pressed os_waitForInput(); switch (os_getLastButton()) 149c: 82 30 cpi r24, 0x02 ; 2 149e: 91 05 cpc r25, r1 14a0: 31 f0 breq .+12 ; 0x14ae 14a2: 03 97 sbiw r24, 0x03 ; 3 14a4: 09 f0 breq .+2 ; 0x14a8 14a6: b9 cf rjmp .-142 ; 0x141a } break; } case (OS_ESC): // exit the taskman { os_taskManExit(); 14a8: 0e 94 4e 08 call 0x109c ; 0x109c 14ac: b6 cf rjmp .-148 ; 0x141a } default: break; } } } 14ae: df 91 pop r29 14b0: cf 91 pop r28 14b2: 08 95 ret os_waitForInput(); switch (os_getLastButton()) { case (OS_DOWN): // switch to scheduling types { os_taskManScheduling(); 14b4: 0e 94 d1 09 call 0x13a2 ; 0x13a2 14b8: b0 cf rjmp .-160 ; 0x141a { if (os_getNumberOfActiveTasks() != 0) { //get task to change prio unsigned char taskSelect = 0; taskSelect = os_taskManSubmenu (OS_PG_ACTIVE_TASK, (currentKilled ? 0 : os_getCurrentTask())); 14ba: 0e 94 b4 03 call 0x768 ; 0x768 14be: 68 2f mov r22, r24 14c0: 81 e0 ldi r24, 0x01 ; 1 14c2: 90 e0 ldi r25, 0x00 ; 0 14c4: 0e 94 63 08 call 0x10c6 ; 0x10c6 if (taskSelect!=0) 14c8: 88 23 and r24, r24 14ca: 79 f6 brne .-98 ; 0x146a break; } } else { os_taskManErrCode(OS_PG_CANCEL); 14cc: 83 e0 ldi r24, 0x03 ; 3 14ce: 90 e0 ldi r25, 0x00 ; 0 14d0: 0e 94 f6 07 call 0xfec ; 0xfec 14d4: a2 cf rjmp .-188 ; 0x141a break; } } else { os_taskManErrCode(OS_PG_NOACTIVE); 14d6: 84 e0 ldi r24, 0x04 ; 4 14d8: 90 e0 ldi r25, 0x00 ; 0 14da: 0e 94 f6 07 call 0xfec ; 0xfec 14de: 9d cf rjmp .-198 ; 0x141a 000014e0 : } //! 3: The "kill task" loop of the Task Manager. void os_taskManKillTask () { 14e0: 0f 93 push r16 14e2: 1f 93 push r17 //reduce number of registered tasks os_numberOfRegisteredTasks--; //if currentTask was killed remember it if (taskSelect == os_getCurrentTask()) currentKilled = 1; 14e4: 01 e0 ldi r16, 0x01 ; 1 void os_taskManKillTask () { while (1) { //write initial text lcd_clear(); 14e6: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(page3_1); 14ea: 86 e3 ldi r24, 0x36 ; 54 14ec: 91 e0 ldi r25, 0x01 ; 1 14ee: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); 14f2: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(pageEnter); 14f6: 82 e7 ldi r24, 0x72 ; 114 14f8: 91 e0 ldi r25, 0x01 ; 1 14fa: 0e 94 2f 03 call 0x65e ; 0x65e //wait until all buttons are released os_waitForNoInput(); 14fe: 0e 94 64 0e call 0x1cc8 ; 0x1cc8 //wait until next button is pressed os_waitForInput(); 1502: 0e 94 77 0e call 0x1cee ; 0x1cee switch (os_getLastButton()) 1506: 0e 94 8a 0e call 0x1d14 ; 0x1d14 150a: 81 30 cpi r24, 0x01 ; 1 150c: 91 05 cpc r25, r1 150e: 09 f4 brne .+2 ; 0x1512 1510: 42 c0 rjmp .+132 ; 0x1596 1512: 81 30 cpi r24, 0x01 ; 1 1514: 91 05 cpc r25, r1 1516: 98 f5 brcc .+102 ; 0x157e return; break; } case (OS_ENTER): { if (os_getNumberOfActiveTasks() != 0) 1518: 0e 94 ba 03 call 0x774 ; 0x774 151c: 88 23 and r24, r24 151e: 09 f4 brne .+2 ; 0x1522 1520: 4c c0 rjmp .+152 ; 0x15ba { //get task to kill unsigned char taskSelect = 0; taskSelect = os_taskManSubmenu (OS_PG_ACTIVE_TASK, (currentKilled ? 0 : os_getCurrentTask())); 1522: 80 91 15 01 lds r24, 0x0115 1526: 88 23 and r24, r24 1528: c9 f1 breq .+114 ; 0x159c 152a: 60 e0 ldi r22, 0x00 ; 0 152c: 81 e0 ldi r24, 0x01 ; 1 152e: 90 e0 ldi r25, 0x00 ; 0 1530: 0e 94 63 08 call 0x10c6 ; 0x10c6 1534: 18 2f mov r17, r24 if (taskSelect!=0) 1536: 88 23 and r24, r24 1538: d9 f1 breq .+118 ; 0x15b0 { //kill the task os_taskStates[taskSelect].state = OS_TASK_KILLED; 153a: 90 e0 ldi r25, 0x00 ; 0 153c: fc 01 movw r30, r24 153e: ee 0f add r30, r30 1540: ff 1f adc r31, r31 1542: ee 0f add r30, r30 1544: ff 1f adc r31, r31 1546: ee 0f add r30, r30 1548: ff 1f adc r31, r31 154a: e8 0f add r30, r24 154c: f9 1f adc r31, r25 154e: e4 5e subi r30, 0xE4 ; 228 1550: fe 4f sbci r31, 0xFE ; 254 1552: 84 e0 ldi r24, 0x04 ; 4 1554: 90 e0 ldi r25, 0x00 ; 0 1556: 91 83 std Z+1, r25 ; 0x01 1558: 80 83 st Z, r24 //reset its timeslice if (taskSelect == os_getCurrentTask()) 155a: 0e 94 b4 03 call 0x768 ; 0x768 155e: 18 17 cp r17, r24 1560: 89 f1 breq .+98 ; 0x15c4 timeSlice = 0; //reduce number of registered tasks os_numberOfRegisteredTasks--; 1562: 80 91 11 01 lds r24, 0x0111 1566: 81 50 subi r24, 0x01 ; 1 1568: 80 93 11 01 sts 0x0111, r24 //if currentTask was killed remember it if (taskSelect == os_getCurrentTask()) 156c: 0e 94 b4 03 call 0x768 ; 0x768 1570: 18 17 cp r17, r24 1572: 69 f1 breq .+90 ; 0x15ce currentKilled = 1; os_taskManErrCode(OS_PG_SUCCESS); 1574: 80 e0 ldi r24, 0x00 ; 0 1576: 90 e0 ldi r25, 0x00 ; 0 1578: 0e 94 f6 07 call 0xfec ; 0xfec 157c: b4 cf rjmp .-152 ; 0x14e6 //wait until all buttons are released os_waitForNoInput(); //wait until next button is pressed os_waitForInput(); switch (os_getLastButton()) 157e: 82 30 cpi r24, 0x02 ; 2 1580: 91 05 cpc r25, r1 1582: 31 f0 breq .+12 ; 0x1590 1584: 03 97 sbiw r24, 0x03 ; 3 1586: 09 f0 breq .+2 ; 0x158a 1588: ae cf rjmp .-164 ; 0x14e6 } break; } case (OS_ESC): { os_taskManExit(); 158a: 0e 94 4e 08 call 0x109c ; 0x109c 158e: ab cf rjmp .-170 ; 0x14e6 } default : break; } } } 1590: 1f 91 pop r17 1592: 0f 91 pop r16 1594: 08 95 ret switch (os_getLastButton()) { case (OS_DOWN): { os_taskManPriorities(); 1596: 0e 94 0b 0a call 0x1416 ; 0x1416 159a: a5 cf rjmp .-182 ; 0x14e6 { if (os_getNumberOfActiveTasks() != 0) { //get task to kill unsigned char taskSelect = 0; taskSelect = os_taskManSubmenu (OS_PG_ACTIVE_TASK, (currentKilled ? 0 : os_getCurrentTask())); 159c: 0e 94 b4 03 call 0x768 ; 0x768 15a0: 68 2f mov r22, r24 15a2: 81 e0 ldi r24, 0x01 ; 1 15a4: 90 e0 ldi r25, 0x00 ; 0 15a6: 0e 94 63 08 call 0x10c6 ; 0x10c6 15aa: 18 2f mov r17, r24 if (taskSelect!=0) 15ac: 88 23 and r24, r24 15ae: 29 f6 brne .-118 ; 0x153a os_taskManErrCode(OS_PG_SUCCESS); break; } else { os_taskManErrCode(OS_PG_CANCEL); 15b0: 83 e0 ldi r24, 0x03 ; 3 15b2: 90 e0 ldi r25, 0x00 ; 0 15b4: 0e 94 f6 07 call 0xfec ; 0xfec 15b8: 96 cf rjmp .-212 ; 0x14e6 break; } } else { os_taskManErrCode(OS_PG_NOACTIVE); 15ba: 84 e0 ldi r24, 0x04 ; 4 15bc: 90 e0 ldi r25, 0x00 ; 0 15be: 0e 94 f6 07 call 0xfec ; 0xfec 15c2: 91 cf rjmp .-222 ; 0x14e6 //kill the task os_taskStates[taskSelect].state = OS_TASK_KILLED; //reset its timeslice if (taskSelect == os_getCurrentTask()) timeSlice = 0; 15c4: 10 92 14 01 sts 0x0114, r1 15c8: 10 92 13 01 sts 0x0113, r1 15cc: ca cf rjmp .-108 ; 0x1562 //reduce number of registered tasks os_numberOfRegisteredTasks--; //if currentTask was killed remember it if (taskSelect == os_getCurrentTask()) currentKilled = 1; 15ce: 00 93 15 01 sts 0x0115, r16 15d2: d0 cf rjmp .-96 ; 0x1574 000015d4 : } } //! 2: The "start task" loop of the Task Manager. void os_taskManStartTask () { 15d4: 1f 93 push r17 while (1) { //write initial text lcd_clear(); 15d6: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(page2_1); 15da: 88 e2 ldi r24, 0x28 ; 40 15dc: 91 e0 ldi r25, 0x01 ; 1 15de: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); 15e2: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(pageEnter); 15e6: 82 e7 ldi r24, 0x72 ; 114 15e8: 91 e0 ldi r25, 0x01 ; 1 15ea: 0e 94 2f 03 call 0x65e ; 0x65e //wait until all buttons are released os_waitForNoInput(); 15ee: 0e 94 64 0e call 0x1cc8 ; 0x1cc8 //wait until next button is pressed os_waitForInput(); 15f2: 0e 94 77 0e call 0x1cee ; 0x1cee switch (os_getLastButton()) 15f6: 0e 94 8a 0e call 0x1d14 ; 0x1d14 15fa: 81 30 cpi r24, 0x01 ; 1 15fc: 91 05 cpc r25, r1 15fe: d1 f1 breq .+116 ; 0x1674 1600: 81 30 cpi r24, 0x01 ; 1 1602: 91 05 cpc r25, r1 1604: 60 f5 brcc .+88 ; 0x165e return; break; } case (OS_ENTER): { if (os_numberOfRegisteredTasks < MAX_NUMBER_OF_TASKS) //check if exceed 1606: 80 91 11 01 lds r24, 0x0111 160a: 88 30 cpi r24, 0x08 ; 8 160c: b0 f5 brcc .+108 ; 0x167a { unsigned char taskSelect = 0; taskSelect = os_taskManSubmenu (OS_PG_TASK, os_getCurrentTask()); 160e: 0e 94 b4 03 call 0x768 ; 0x768 1612: 68 2f mov r22, r24 1614: 80 e0 ldi r24, 0x00 ; 0 1616: 90 e0 ldi r25, 0x00 ; 0 1618: 0e 94 63 08 call 0x10c6 ; 0x10c6 161c: 18 2f mov r17, r24 // check if valid if (taskSelect != 0) 161e: 88 23 and r24, r24 1620: 89 f1 breq .+98 ; 0x1684 { lcd_clear(); 1622: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(pageTaskSel); 1626: 83 eb ldi r24, 0xB3 ; 179 1628: 91 e0 ldi r25, 0x01 ; 1 162a: 0e 94 2f 03 call 0x65e ; 0x65e lcd_writeUint(taskSelect); 162e: 81 2f mov r24, r17 1630: 90 e0 ldi r25, 0x00 ; 0 1632: 0e 94 8c 02 call 0x518 ; 0x518 //check if task is known by our OS if (os_allTasks[taskSelect] != NULL) 1636: e1 2f mov r30, r17 1638: f0 e0 ldi r31, 0x00 ; 0 163a: ee 0f add r30, r30 163c: ff 1f adc r31, r31 163e: ec 59 subi r30, 0x9C ; 156 1640: fe 4f sbci r31, 0xFE ; 254 1642: 80 81 ld r24, Z 1644: 91 81 ldd r25, Z+1 ; 0x01 1646: 89 2b or r24, r25 1648: 11 f1 breq .+68 ; 0x168e { //register the task with standard timeslice os_registerTask(os_allTasks[taskSelect], STANDARD_TIME_SLICE); 164a: 80 81 ld r24, Z 164c: 91 81 ldd r25, Z+1 ; 0x01 164e: 6a e0 ldi r22, 0x0A ; 10 1650: 0e 94 83 04 call 0x906 ; 0x906 os_taskManErrCode(OS_PG_SUCCESS); 1654: 80 e0 ldi r24, 0x00 ; 0 1656: 90 e0 ldi r25, 0x00 ; 0 1658: 0e 94 f6 07 call 0xfec ; 0xfec 165c: bc cf rjmp .-136 ; 0x15d6 os_waitForNoInput(); //wait until next button is pressed os_waitForInput(); switch (os_getLastButton()) 165e: 82 30 cpi r24, 0x02 ; 2 1660: 91 05 cpc r25, r1 1662: 31 f0 breq .+12 ; 0x1670 1664: 03 97 sbiw r24, 0x03 ; 3 1666: 09 f0 breq .+2 ; 0x166a 1668: b6 cf rjmp .-148 ; 0x15d6 os_taskManErrCode(OS_PG_EXCEED); break; } } case (OS_ESC): os_taskManExit(); //exit taskMan 166a: 0e 94 4e 08 call 0x109c ; 0x109c 166e: b3 cf rjmp .-154 ; 0x15d6 default: break; } } } 1670: 1f 91 pop r17 1672: 08 95 ret switch (os_getLastButton()) { case (OS_DOWN): { os_taskManKillTask(); //switch to kill tasks 1674: 0e 94 70 0a call 0x14e0 ; 0x14e0 1678: ae cf rjmp .-164 ; 0x15d6 break; } } else { os_taskManErrCode(OS_PG_EXCEED); 167a: 82 e0 ldi r24, 0x02 ; 2 167c: 90 e0 ldi r25, 0x00 ; 0 167e: 0e 94 f6 07 call 0xfec ; 0xfec 1682: a9 cf rjmp .-174 ; 0x15d6 break; } } else { os_taskManErrCode(OS_PG_CANCEL); 1684: 83 e0 ldi r24, 0x03 ; 3 1686: 90 e0 ldi r25, 0x00 ; 0 1688: 0e 94 f6 07 call 0xfec ; 0xfec 168c: a4 cf rjmp .-184 ; 0x15d6 os_taskManErrCode(OS_PG_SUCCESS); break; } else { os_taskManErrCode(OS_PG_INVALID); 168e: 81 e0 ldi r24, 0x01 ; 1 1690: 90 e0 ldi r25, 0x00 ; 0 1692: 0e 94 f6 07 call 0xfec ; 0xfec 1696: 9f cf rjmp .-194 ; 0x15d6 00001698 : // Implementation //---------------------------------------------------------------------------- //! 1: Main loop for the TaskManager. void os_taskManMain () { 1698: 8d b7 in r24, 0x3d ; 61 169a: 9e b7 in r25, 0x3e ; 62 169c: 90 93 78 01 sts 0x0178, r25 16a0: 80 93 77 01 sts 0x0177, r24 taskManEntry = SP; while (1) { //write welcome string and current task lcd_clear(); 16a4: 0e 94 d2 01 call 0x3a4 ; 0x3a4 lcd_progString(page1_1); 16a8: 89 e0 ldi r24, 0x09 ; 9 16aa: 91 e0 ldi r25, 0x01 ; 1 16ac: 0e 94 2f 03 call 0x65e ; 0x65e lcd_line2(); 16b0: 0e 94 c5 01 call 0x38a ; 0x38a lcd_progString(page1_2); 16b4: 89 e1 ldi r24, 0x19 ; 25 16b6: 91 e0 ldi r25, 0x01 ; 1 16b8: 0e 94 2f 03 call 0x65e ; 0x65e lcd_writeUint(os_getCurrentTask()); 16bc: 0e 94 b4 03 call 0x768 ; 0x768 16c0: 90 e0 ldi r25, 0x00 ; 0 16c2: 0e 94 8c 02 call 0x518 ; 0x518 //wait until all buttons are released os_waitForNoInput(); 16c6: 0e 94 64 0e call 0x1cc8 ; 0x1cc8 //wait until next button is pressed os_waitForInput(); 16ca: 0e 94 77 0e call 0x1cee ; 0x1cee switch (os_getLastButton()) 16ce: 0e 94 8a 0e call 0x1d14 ; 0x1d14 16d2: 81 30 cpi r24, 0x01 ; 1 16d4: 91 05 cpc r25, r1 16d6: 29 f0 breq .+10 ; 0x16e2 16d8: 03 97 sbiw r24, 0x03 ; 3 16da: 21 f7 brne .-56 ; 0x16a4 case (OS_UP): // stay in Main loop break; case (OS_ENTER): // stay in Main loop break; case (OS_ESC): // exit taskMan os_taskManExit(); 16dc: 0e 94 4e 08 call 0x109c ; 0x109c 16e0: e1 cf rjmp .-62 ; 0x16a4 switch (os_getLastButton()) { case (OS_DOWN): // switch to Start tasks { os_taskManStartTask(); 16e2: 0e 94 ea 0a call 0x15d4 ; 0x15d4 16e6: de cf rjmp .-68 ; 0x16a4 000016e8 : // Function implementation //---------------------------------------------------------------------------- //! Read the map entry for the specified address. (correct) unsigned char os_getMapEntry (unsigned char *heapPosition) { 16e8: 86 55 subi r24, 0x56 ; 86 16ea: 94 40 sbci r25, 0x04 ; 4 16ec: 9c 01 movw r18, r24 16ee: 97 fd sbrc r25, 7 16f0: 0e c0 rjmp .+28 ; 0x170e 16f2: f9 01 movw r30, r18 16f4: f5 95 asr r31 16f6: e7 95 ror r30 16f8: e0 50 subi r30, 0x00 ; 0 16fa: fe 4f sbci r31, 0xFE ; 254 //calculate the heap map position of the given heapPosition unsigned char *entryAddr = (unsigned char*)(HEAP_MAP_START+(((int)heapPosition-HEAP_START)/2)); //we have to return the highbyte nibble if the byte on the heap was even if(((int)heapPosition-HEAP_START) % 2 == 0) 16fc: 80 ff sbrs r24, 0 16fe: 03 c0 rjmp .+6 ; 0x1706 return (*entryAddr >> 4); return (*entryAddr & 0b00001111); 1700: 80 81 ld r24, Z 1702: 8f 70 andi r24, 0x0F ; 15 } 1704: 08 95 ret //calculate the heap map position of the given heapPosition unsigned char *entryAddr = (unsigned char*)(HEAP_MAP_START+(((int)heapPosition-HEAP_START)/2)); //we have to return the highbyte nibble if the byte on the heap was even if(((int)heapPosition-HEAP_START) % 2 == 0) return (*entryAddr >> 4); 1706: 80 81 ld r24, Z 1708: 82 95 swap r24 170a: 8f 70 andi r24, 0x0F ; 15 170c: 08 95 ret //! Read the map entry for the specified address. (correct) unsigned char os_getMapEntry (unsigned char *heapPosition) { //calculate the heap map position of the given heapPosition unsigned char *entryAddr = (unsigned char*)(HEAP_MAP_START+(((int)heapPosition-HEAP_START)/2)); 170e: 2f 5f subi r18, 0xFF ; 255 1710: 3f 4f sbci r19, 0xFF ; 255 1712: ef cf rjmp .-34 ; 0x16f2 00001714 : return (*entryAddr & 0b00001111); } //! Write the map entry for the specified address. (correct) void os_setMapEntry (unsigned char *heapPosition, unsigned char value) { 1714: 86 55 subi r24, 0x56 ; 86 1716: 94 40 sbci r25, 0x04 ; 4 1718: 9c 01 movw r18, r24 171a: 97 fd sbrc r25, 7 171c: 13 c0 rjmp .+38 ; 0x1744 171e: f9 01 movw r30, r18 1720: f5 95 asr r31 1722: e7 95 ror r30 1724: e0 50 subi r30, 0x00 ; 0 1726: fe 4f sbci r31, 0xFE ; 254 //calculate the heap map position of the given heapPosition unsigned char * entryAddr = (unsigned char*)(HEAP_MAP_START+(((int)heapPosition-HEAP_START)/2)); //we have to write the highbyte nibble if the byte on the heap was even if (((int)heapPosition-HEAP_START) % 2 == 0 ) 1728: 80 ff sbrs r24, 0 172a: 05 c0 rjmp .+10 ; 0x1736 else { //delete the old lowbyte *entryAddr &= 0b11110000; //write the new lowebyte *entryAddr |= value; 172c: 80 81 ld r24, Z 172e: 80 7f andi r24, 0xF0 ; 240 1730: 86 2b or r24, r22 1732: 80 83 st Z, r24 1734: 08 95 ret if (((int)heapPosition-HEAP_START) % 2 == 0 ) { //delete the old highbyte *entryAddr &= 0b00001111; //write the new highbyte *entryAddr |= (value << 4); 1736: 80 81 ld r24, Z 1738: 8f 70 andi r24, 0x0F ; 15 173a: 62 95 swap r22 173c: 60 7f andi r22, 0xF0 ; 240 173e: 86 2b or r24, r22 1740: 80 83 st Z, r24 1742: 08 95 ret //! Write the map entry for the specified address. (correct) void os_setMapEntry (unsigned char *heapPosition, unsigned char value) { //calculate the heap map position of the given heapPosition unsigned char * entryAddr = (unsigned char*)(HEAP_MAP_START+(((int)heapPosition-HEAP_START)/2)); 1744: 2f 5f subi r18, 0xFF ; 255 1746: 3f 4f sbci r19, 0xFF ; 255 1748: ea cf rjmp .-44 ; 0x171e 0000174a : } } //! Find first address of the chunk referred to by ptr. (correct) unsigned char * os_firstByteOfChunk (unsigned char *ptr) { 174a: 0f 93 push r16 174c: 1f 93 push r17 174e: cf 93 push r28 1750: df 93 push r29 1752: ec 01 movw r28, r24 //as long we read "F" we have to check the lower position while(os_getMapEntry(ptr--) == 0x0F) 1754: 8e 01 movw r16, r28 1756: 01 50 subi r16, 0x01 ; 1 1758: 10 40 sbci r17, 0x00 ; 0 175a: ce 01 movw r24, r28 175c: 0e 94 74 0b call 0x16e8 ; 0x16e8 1760: 2c 2f mov r18, r28 1762: 9d 2f mov r25, r29 1764: e8 01 movw r28, r16 1766: 8f 30 cpi r24, 0x0F ; 15 1768: a9 f3 breq .-22 ; 0x1754 176a: 82 2f mov r24, r18 ; //finally return ++ptr return ++ptr; } 176c: df 91 pop r29 176e: cf 91 pop r28 1770: 1f 91 pop r17 1772: 0f 91 pop r16 1774: 08 95 ret 00001776 : //! Compute a chunk's size in byte (chunk: TASK 0x0F 0x0F ... 0x0F) chunksize of freebytes = 1 (correct) unsigned int os_getChunkSize (unsigned char *ptr) { 1776: ef 92 push r14 1778: ff 92 push r15 177a: 0f 93 push r16 177c: 1f 93 push r17 177e: cf 93 push r28 1780: df 93 push r29 //to compute the chunks size we first need to know where the chunk begins unsigned char *startAddr = os_firstByteOfChunk(ptr); 1782: 0e 94 a5 0b call 0x174a ; 0x174a 1786: 7c 01 movw r14, r24 1788: c1 e0 ldi r28, 0x01 ; 1 178a: d0 e0 ldi r29, 0x00 ; 0 //the size is at least 1 so we start with i = 1 unsigned int i = 1; //if the map entry of the next address is an F it belongs to the chunk while(os_getMapEntry((unsigned char*)((unsigned int)startAddr+i++)) == 0x0F) 178c: 8e 01 movw r16, r28 178e: 0f 5f subi r16, 0xFF ; 255 1790: 1f 4f sbci r17, 0xFF ; 255 1792: c7 01 movw r24, r14 1794: 8c 0f add r24, r28 1796: 9d 1f adc r25, r29 1798: 0e 94 74 0b call 0x16e8 ; 0x16e8 179c: 2c 2f mov r18, r28 179e: 9d 2f mov r25, r29 17a0: e8 01 movw r28, r16 17a2: 8f 30 cpi r24, 0x0F ; 15 17a4: 99 f3 breq .-26 ; 0x178c 17a6: 82 2f mov r24, r18 ; //finally return --i return --i; } 17a8: df 91 pop r29 17aa: cf 91 pop r28 17ac: 1f 91 pop r17 17ae: 0f 91 pop r16 17b0: ff 90 pop r15 17b2: ef 90 pop r14 17b4: 08 95 ret 000017b6 : //! Initialize memory management map. (correct) void os_initHeapMap () { 17b6: e0 e0 ldi r30, 0x00 ; 0 17b8: f2 e0 ldi r31, 0x02 ; 2 //write zero to all entries of the heap map unsigned int i = HEAP_MAP_START; for(; i <= END_OF_HEAP_MAP; i++) *(unsigned char*)i = 0; 17ba: 11 92 st Z+, r1 //! Initialize memory management map. (correct) void os_initHeapMap () { //write zero to all entries of the heap map unsigned int i = HEAP_MAP_START; for(; i <= END_OF_HEAP_MAP; i++) 17bc: 84 e0 ldi r24, 0x04 ; 4 17be: e6 35 cpi r30, 0x56 ; 86 17c0: f8 07 cpc r31, r24 17c2: d9 f7 brne .-10 ; 0x17ba *(unsigned char*)i = 0; } 17c4: 08 95 ret 000017c6 : //! Returns the amount of free Heap memory. (correct) unsigned int os_countFreeHeap () { 17c6: 0f 93 push r16 17c8: 1f 93 push r17 17ca: cf 93 push r28 17cc: df 93 push r29 17ce: c6 e5 ldi r28, 0x56 ; 86 17d0: d4 e0 ldi r29, 0x04 ; 4 17d2: 00 e0 ldi r16, 0x00 ; 0 17d4: 10 e0 ldi r17, 0x00 ; 0 //iterate through the whole heap map and count free cells (0) unsigned int i = HEAP_START; unsigned int result = 0; for(; i <= END_OF_HEAP; i++) if(os_getMapEntry((unsigned char*)i) == 0) 17d6: ce 01 movw r24, r28 17d8: 0e 94 74 0b call 0x16e8 ; 0x16e8 17dc: 88 23 and r24, r24 17de: 11 f4 brne .+4 ; 0x17e4 result++; 17e0: 0f 5f subi r16, 0xFF ; 255 17e2: 1f 4f sbci r17, 0xFF ; 255 unsigned int os_countFreeHeap () { //iterate through the whole heap map and count free cells (0) unsigned int i = HEAP_START; unsigned int result = 0; for(; i <= END_OF_HEAP; i++) 17e4: 21 96 adiw r28, 0x01 ; 1 17e6: 89 e0 ldi r24, 0x09 ; 9 17e8: c1 30 cpi r28, 0x01 ; 1 17ea: d8 07 cpc r29, r24 17ec: a1 f7 brne .-24 ; 0x17d6 if(os_getMapEntry((unsigned char*)i) == 0) result++; return result; } 17ee: c8 01 movw r24, r16 17f0: df 91 pop r29 17f2: cf 91 pop r28 17f4: 1f 91 pop r17 17f6: 0f 91 pop r16 17f8: 08 95 ret 000017fa : SREG = temp; } //! Garbage collection of a single task (correct) void os_freeTaskMem (unsigned char task) { 17fa: cf 92 push r12 17fc: df 92 push r13 17fe: ef 92 push r14 1800: ff 92 push r15 1802: 0f 93 push r16 1804: 1f 93 push r17 1806: cf 93 push r28 1808: df 93 push r29 180a: d8 2e mov r13, r24 //disable interrupts to avoid side effects unsigned char temp; temp = SREG; 180c: cf b6 in r12, 0x3f ; 63 cli(); 180e: f8 94 cli 1810: 06 e5 ldi r16, 0x56 ; 86 1812: 14 e0 ldi r17, 0x04 ; 4 1814: 06 c0 rjmp .+12 ; 0x1822 //iterate through the heap map and find allocate memory of the task unsigned int i = HEAP_START; for(; i <= END_OF_HEAP; i++) 1816: 0f 5f subi r16, 0xFF ; 255 1818: 1f 4f sbci r17, 0xFF ; 255 181a: 89 e0 ldi r24, 0x09 ; 9 181c: 01 30 cpi r16, 0x01 ; 1 181e: 18 07 cpc r17, r24 1820: 08 f5 brcc .+66 ; 0x1864 //if a chunk start of the task was found clear it with the same method of os_memfree if(os_getMapEntry((unsigned char*)i) == task) 1822: c8 01 movw r24, r16 1824: 0e 94 74 0b call 0x16e8 ; 0x16e8 1828: 8d 15 cp r24, r13 182a: a9 f7 brne .-22 ; 0x1816 { unsigned int size = os_getChunkSize((unsigned char*)i); 182c: c8 01 movw r24, r16 182e: 0e 94 bb 0b call 0x1776 ; 0x1776 1832: 7c 01 movw r14, r24 unsigned int j = 0; for(; j < size; j++) 1834: 00 97 sbiw r24, 0x00 ; 0 1836: 61 f0 breq .+24 ; 0x1850 1838: c0 e0 ldi r28, 0x00 ; 0 183a: d0 e0 ldi r29, 0x00 ; 0 os_setMapEntry((unsigned char *)(i+j), 0); 183c: 60 e0 ldi r22, 0x00 ; 0 183e: ce 01 movw r24, r28 1840: 80 0f add r24, r16 1842: 91 1f adc r25, r17 1844: 0e 94 8a 0b call 0x1714 ; 0x1714 //if a chunk start of the task was found clear it with the same method of os_memfree if(os_getMapEntry((unsigned char*)i) == task) { unsigned int size = os_getChunkSize((unsigned char*)i); unsigned int j = 0; for(; j < size; j++) 1848: 21 96 adiw r28, 0x01 ; 1 184a: ce 15 cp r28, r14 184c: df 05 cpc r29, r15 184e: b0 f3 brcs .-20 ; 0x183c os_setMapEntry((unsigned char *)(i+j), 0); //we can skip the rest of the chunk to enhance speed i += (size-1); 1850: 01 50 subi r16, 0x01 ; 1 1852: 10 40 sbci r17, 0x00 ; 0 1854: 0e 0d add r16, r14 1856: 1f 1d adc r17, r15 temp = SREG; cli(); //iterate through the heap map and find allocate memory of the task unsigned int i = HEAP_START; for(; i <= END_OF_HEAP; i++) 1858: 0f 5f subi r16, 0xFF ; 255 185a: 1f 4f sbci r17, 0xFF ; 255 185c: 89 e0 ldi r24, 0x09 ; 9 185e: 01 30 cpi r16, 0x01 ; 1 1860: 18 07 cpc r17, r24 1862: f8 f2 brcs .-66 ; 0x1822 //we can skip the rest of the chunk to enhance speed i += (size-1); } //re-enable interrupts SREG = temp; 1864: cf be out 0x3f, r12 ; 63 } 1866: df 91 pop r29 1868: cf 91 pop r28 186a: 1f 91 pop r17 186c: 0f 91 pop r16 186e: ff 90 pop r15 1870: ef 90 pop r14 1872: df 90 pop r13 1874: cf 90 pop r12 1876: 08 95 ret 00001878 : //! Count the used chunks.(correct) unsigned int os_getUsedMemoryChunkCount () { 1878: 0f 93 push r16 187a: 1f 93 push r17 187c: cf 93 push r28 187e: df 93 push r29 1880: c6 e5 ldi r28, 0x56 ; 86 1882: d4 e0 ldi r29, 0x04 ; 4 1884: 00 e0 ldi r16, 0x00 ; 0 1886: 10 e0 ldi r17, 0x00 ; 0 unsigned int i = HEAP_START; unsigned int result = 0; unsigned char entry = 0; for(; i <= END_OF_HEAP; i++) { entry = os_getMapEntry((unsigned char*)i); 1888: ce 01 movw r24, r28 188a: 0e 94 74 0b call 0x16e8 ; 0x16e8 //if the entry in the heap map represents the start of a chunk increase the result if((entry >= 0x01) && (entry <= 0x07)) 188e: 81 50 subi r24, 0x01 ; 1 1890: 87 30 cpi r24, 0x07 ; 7 1892: 10 f4 brcc .+4 ; 0x1898 result++; 1894: 0f 5f subi r16, 0xFF ; 255 1896: 1f 4f sbci r17, 0xFF ; 255 { //iterate through the heap map and find task identifiers unsigned int i = HEAP_START; unsigned int result = 0; unsigned char entry = 0; for(; i <= END_OF_HEAP; i++) 1898: 21 96 adiw r28, 0x01 ; 1 189a: 89 e0 ldi r24, 0x09 ; 9 189c: c1 30 cpi r28, 0x01 ; 1 189e: d8 07 cpc r29, r24 18a0: 99 f7 brne .-26 ; 0x1888 //if the entry in the heap map represents the start of a chunk increase the result if((entry >= 0x01) && (entry <= 0x07)) result++; } return result; } 18a2: c8 01 movw r24, r16 18a4: df 91 pop r29 18a6: cf 91 pop r28 18a8: 1f 91 pop r17 18aa: 0f 91 pop r16 18ac: 08 95 ret 000018ae : //! Count the used memory. (correct) unsigned int os_getUsedMemorySize () { 18ae: 0f 93 push r16 18b0: 1f 93 push r17 18b2: cf 93 push r28 18b4: df 93 push r29 18b6: c6 e5 ldi r28, 0x56 ; 86 18b8: d4 e0 ldi r29, 0x04 ; 4 18ba: 00 e0 ldi r16, 0x00 ; 0 18bc: 10 e0 ldi r17, 0x00 ; 0 //iterate through the heap map and count values != 0 unsigned int i = HEAP_START; unsigned int result = 0; for(; i <= END_OF_HEAP; i++) { if(os_getMapEntry((unsigned char*)i) > 0) 18be: ce 01 movw r24, r28 18c0: 0e 94 74 0b call 0x16e8 ; 0x16e8 18c4: 88 23 and r24, r24 18c6: 11 f0 breq .+4 ; 0x18cc result++; 18c8: 0f 5f subi r16, 0xFF ; 255 18ca: 1f 4f sbci r17, 0xFF ; 255 unsigned int os_getUsedMemorySize () { //iterate through the heap map and count values != 0 unsigned int i = HEAP_START; unsigned int result = 0; for(; i <= END_OF_HEAP; i++) 18cc: 21 96 adiw r28, 0x01 ; 1 18ce: 89 e0 ldi r24, 0x09 ; 9 18d0: c1 30 cpi r28, 0x01 ; 1 18d2: d8 07 cpc r29, r24 18d4: a1 f7 brne .-24 ; 0x18be { if(os_getMapEntry((unsigned char*)i) > 0) result++; } return result; } 18d6: c8 01 movw r24, r16 18d8: df 91 pop r29 18da: cf 91 pop r28 18dc: 1f 91 pop r17 18de: 0f 91 pop r16 18e0: 08 95 ret 000018e2 : //! Change the memory management strategy. (correct) void os_setAllocationStrategy (enum os_AllocationStrategy allocStrat) { 18e2: 90 93 17 01 sts 0x0117, r25 18e6: 80 93 16 01 sts 0x0116, r24 os_allocStrat = allocStrat; } 18ea: 08 95 ret 000018ec : //! Get the current memory management strategy. (correct) enum os_AllocationStrategy os_getAllocationStrategy () { 18ec: 20 91 16 01 lds r18, 0x0116 18f0: 30 91 17 01 lds r19, 0x0117 return os_allocStrat; } 18f4: c9 01 movw r24, r18 18f6: 08 95 ret 000018f8 : //! Tests the whole memory, returns 0 if there are no errors. (correct) unsigned char * os_memcheck () { 18f8: cf 93 push r28 18fa: df 93 push r29 18fc: 86 e5 ldi r24, 0x56 ; 86 18fe: 94 e0 ldi r25, 0x04 ; 4 1900: 06 c0 rjmp .+12 ; 0x190e //iterate throught the heap map and check if a unknown nibble state is found unsigned int i = HEAP_START; unsigned char entry = 0; for(; i <= END_OF_HEAP; i++) 1902: ce 01 movw r24, r28 1904: 01 96 adiw r24, 0x01 ; 1 1906: 29 e0 ldi r18, 0x09 ; 9 1908: 81 30 cpi r24, 0x01 ; 1 190a: 92 07 cpc r25, r18 190c: 51 f0 breq .+20 ; 0x1922 return os_allocStrat; } //! Tests the whole memory, returns 0 if there are no errors. (correct) unsigned char * os_memcheck () { 190e: ec 01 movw r28, r24 //iterate throught the heap map and check if a unknown nibble state is found unsigned int i = HEAP_START; unsigned char entry = 0; for(; i <= END_OF_HEAP; i++) { entry = os_getMapEntry((unsigned char*)i); 1910: 0e 94 74 0b call 0x16e8 ; 0x16e8 if((entry > 0x07) && (entry < 0x0F)) 1914: 88 50 subi r24, 0x08 ; 8 1916: 87 30 cpi r24, 0x07 ; 7 1918: a0 f7 brcc .-24 ; 0x1902 return (unsigned char*)i; } return 0; } 191a: ce 01 movw r24, r28 191c: df 91 pop r29 191e: cf 91 pop r28 1920: 08 95 ret unsigned char * os_memcheck () { //iterate throught the heap map and check if a unknown nibble state is found unsigned int i = HEAP_START; unsigned char entry = 0; for(; i <= END_OF_HEAP; i++) 1922: c0 e0 ldi r28, 0x00 ; 0 1924: d0 e0 ldi r29, 0x00 ; 0 entry = os_getMapEntry((unsigned char*)i); if((entry > 0x07) && (entry < 0x0F)) return (unsigned char*)i; } return 0; } 1926: ce 01 movw r24, r28 1928: df 91 pop r29 192a: cf 91 pop r28 192c: 08 95 ret 0000192e : //! Count cells according to the checkMapValue function (if checkMapValue(cell) is true). unsigned int os_countSpecificCells (FnUCharToBool checkMapValue) { 192e: 80 e0 ldi r24, 0x00 ; 0 1930: 90 e0 ldi r25, 0x00 ; 0 1932: 08 95 ret 00001934 : return result; } //! Frees a memory chunk from heap. (correct) void os_memfree (unsigned char *ptr) { 1934: df 92 push r13 1936: ef 92 push r14 1938: ff 92 push r15 193a: 0f 93 push r16 193c: 1f 93 push r17 193e: cf 93 push r28 1940: df 93 push r29 1942: 8c 01 movw r16, r24 //disable interrupts to avoid side effects unsigned char temp; temp = SREG; 1944: df b6 in r13, 0x3f ; 63 cli(); 1946: f8 94 cli //compute the chunks size unsigned int size = os_getChunkSize(ptr); 1948: 0e 94 bb 0b call 0x1776 ; 0x1776 194c: 7c 01 movw r14, r24 //compute the chunks start address unsigned int start = (unsigned int)os_firstByteOfChunk(ptr); 194e: c8 01 movw r24, r16 1950: 0e 94 a5 0b call 0x174a ; 0x174a 1954: ec 01 movw r28, r24 //only the the calling task has the permission to clear its memory if (os_getMapEntry((unsigned char*)start)==os_getCurrentTask()) 1956: 0e 94 74 0b call 0x16e8 ; 0x16e8 195a: 18 2f mov r17, r24 195c: 0e 94 b4 03 call 0x768 ; 0x768 1960: 18 17 cp r17, r24 1962: 49 f0 breq .+18 ; 0x1976 os_setMapEntry((unsigned char *)(start+i), 0); } } //re-enable interrupts SREG = temp; 1964: df be out 0x3f, r13 ; 63 } 1966: df 91 pop r29 1968: cf 91 pop r28 196a: 1f 91 pop r17 196c: 0f 91 pop r16 196e: ff 90 pop r15 1970: ef 90 pop r14 1972: df 90 pop r13 1974: 08 95 ret //only the the calling task has the permission to clear its memory if (os_getMapEntry((unsigned char*)start)==os_getCurrentTask()) { //iterate through the chunk and write zeros into the map unsigned int i = 0; for(; i < size; i++) 1976: e1 14 cp r14, r1 1978: f1 04 cpc r15, r1 197a: a1 f3 breq .-24 ; 0x1964 197c: 00 e0 ldi r16, 0x00 ; 0 197e: 10 e0 ldi r17, 0x00 ; 0 { os_setMapEntry((unsigned char *)(start+i), 0); 1980: 60 e0 ldi r22, 0x00 ; 0 1982: ce 01 movw r24, r28 1984: 80 0f add r24, r16 1986: 91 1f adc r25, r17 1988: 0e 94 8a 0b call 0x1714 ; 0x1714 //only the the calling task has the permission to clear its memory if (os_getMapEntry((unsigned char*)start)==os_getCurrentTask()) { //iterate through the chunk and write zeros into the map unsigned int i = 0; for(; i < size; i++) 198c: 0f 5f subi r16, 0xFF ; 255 198e: 1f 4f sbci r17, 0xFF ; 255 1990: 0e 15 cp r16, r14 1992: 1f 05 cpc r17, r15 1994: a8 f3 brcs .-22 ; 0x1980 1996: e6 cf rjmp .-52 ; 0x1964 00001998 : } //! Allocates some bytes (max 65536) on the heap. (correct) unsigned char * os_malloc (unsigned int size) { 1998: 1f 93 push r17 199a: cf 93 push r28 199c: df 93 push r29 199e: ec 01 movw r28, r24 //check if input is valid and if enough free size on heap if ((size == 0) || (os_countFreeHeap() < size)) 19a0: 00 97 sbiw r24, 0x00 ; 0 19a2: 39 f4 brne .+14 ; 0x19b2 //re-enable interrupts SREG = temp; //returns the result of malloc. NULL if no success return result; 19a4: 20 e0 ldi r18, 0x00 ; 0 19a6: 30 e0 ldi r19, 0x00 ; 0 } 19a8: c9 01 movw r24, r18 19aa: df 91 pop r29 19ac: cf 91 pop r28 19ae: 1f 91 pop r17 19b0: 08 95 ret //! Allocates some bytes (max 65536) on the heap. (correct) unsigned char * os_malloc (unsigned int size) { //check if input is valid and if enough free size on heap if ((size == 0) || (os_countFreeHeap() < size)) 19b2: 0e 94 e3 0b call 0x17c6 ; 0x17c6 19b6: 8c 17 cp r24, r28 19b8: 9d 07 cpc r25, r29 19ba: a0 f3 brcs .-24 ; 0x19a4 return 0; //disable interrupts to avoid side effects unsigned char temp; temp = SREG; 19bc: 1f b7 in r17, 0x3f ; 63 cli(); 19be: f8 94 cli } //! Get the current memory management strategy. (correct) enum os_AllocationStrategy os_getAllocationStrategy () { return os_allocStrat; 19c0: 80 91 16 01 lds r24, 0x0116 19c4: 90 91 17 01 lds r25, 0x0117 temp = SREG; cli(); //decide which memory management strategy is used unsigned char * result = NULL; switch(os_getAllocationStrategy()) 19c8: 89 2b or r24, r25 19ca: 31 f4 brne .+12 ; 0x19d8 { case(OS_MEM_FIRST_FIT): { result = os_Memory_FirstFit(size); 19cc: ce 01 movw r24, r28 19ce: 0e 94 f0 0d call 0x1be0 ; 0x1be0 19d2: 9c 01 movw r18, r24 break; } } //re-enable interrupts SREG = temp; 19d4: 1f bf out 0x3f, r17 ; 63 19d6: e8 cf rjmp .-48 ; 0x19a8 temp = SREG; cli(); //decide which memory management strategy is used unsigned char * result = NULL; switch(os_getAllocationStrategy()) 19d8: 20 e0 ldi r18, 0x00 ; 0 19da: 30 e0 ldi r19, 0x00 ; 0 break; } } //re-enable interrupts SREG = temp; 19dc: 1f bf out 0x3f, r17 ; 63 19de: e4 cf rjmp .-56 ; 0x19a8 000019e0 : #include "allHeaders.h" //! inactive-aging strategy unsigned char os_Scheduler_InactiveAging (struct os_TaskAbstract *taskStates, unsigned char currentTask) { 19e0: 1f 93 push r17 19e2: cf 93 push r28 19e4: df 93 push r29 19e6: bc 01 movw r22, r24 19e8: dc 01 movw r26, r24 19ea: fc 01 movw r30, r24 19ec: 10 e0 ldi r17, 0x00 ; 0 19ee: 20 e0 ldi r18, 0x00 ; 0 unsigned char i = 0; unsigned char select = 0; for (;i taskStates[select].age) 19f0: 39 e0 ldi r19, 0x09 ; 9 19f2: 04 c0 rjmp .+8 ; 0x19fc unsigned char os_Scheduler_InactiveAging (struct os_TaskAbstract *taskStates, unsigned char currentTask) { //find oldest age unsigned char i = 0; unsigned char select = 0; for (;i if ((taskStates[i].state == OS_TASK_READY)/*|(taskStates[i].state == OS_TASK_PAUSED)*/) 19fc: 80 81 ld r24, Z 19fe: 91 81 ldd r25, Z+1 ; 0x01 1a00: 01 97 sbiw r24, 0x01 ; 1 1a02: c1 f7 brne .-16 ; 0x19f4 { if (taskStates[i].age > taskStates[select].age) 1a04: 43 81 ldd r20, Z+3 ; 0x03 1a06: 54 81 ldd r21, Z+4 ; 0x04 1a08: 13 9f mul r17, r19 1a0a: e0 01 movw r28, r0 1a0c: 11 24 eor r1, r1 1a0e: c6 0f add r28, r22 1a10: d7 1f adc r29, r23 1a12: 8b 81 ldd r24, Y+3 ; 0x03 1a14: 9c 81 ldd r25, Y+4 ; 0x04 1a16: 84 17 cp r24, r20 1a18: 95 07 cpc r25, r21 1a1a: 38 f0 brcs .+14 ; 0x1a2a select = i; else if (taskStates[i].age == taskStates[select].age) // if age is equal, additionally check priority 1a1c: 48 17 cp r20, r24 1a1e: 59 07 cpc r21, r25 1a20: 49 f7 brne .-46 ; 0x19f4 if(taskStates[i].maxTimeSlice > taskStates[select].maxTimeSlice) 1a22: 92 81 ldd r25, Z+2 ; 0x02 1a24: 8a 81 ldd r24, Y+2 ; 0x02 1a26: 89 17 cp r24, r25 1a28: 28 f7 brcc .-54 ; 0x19f4 1a2a: 12 2f mov r17, r18 unsigned char os_Scheduler_InactiveAging (struct os_TaskAbstract *taskStates, unsigned char currentTask) { //find oldest age unsigned char i = 0; unsigned char select = 0; for (;i 1a34: 30 e0 ldi r19, 0x00 ; 0 1a36: 04 c0 rjmp .+8 ; 0x1a40 if(taskStates[i].maxTimeSlice > taskStates[select].maxTimeSlice) select = i; } //update ages for (i=0;i if ((taskStates[i].state == OS_TASK_READY)/*|(taskStates[i].state == OS_TASK_PAUSED)*/) 1a40: 8d 91 ld r24, X+ 1a42: 9c 91 ld r25, X 1a44: 11 97 sbiw r26, 0x01 ; 1 1a46: 01 97 sbiw r24, 0x01 ; 1 1a48: b9 f7 brne .-18 ; 0x1a38 { if(i == select) // reset age of selected to priority 1a4a: 31 17 cp r19, r17 1a4c: b1 f0 breq .+44 ; 0x1a7a taskStates[i].age = taskStates[i].maxTimeSlice; else // else add priority to age taskStates[i].age += taskStates[i].maxTimeSlice; 1a4e: 12 96 adiw r26, 0x02 ; 2 1a50: 2c 91 ld r18, X 1a52: 12 97 sbiw r26, 0x02 ; 2 1a54: 13 96 adiw r26, 0x03 ; 3 1a56: 8d 91 ld r24, X+ 1a58: 9c 91 ld r25, X 1a5a: 14 97 sbiw r26, 0x04 ; 4 1a5c: 82 0f add r24, r18 1a5e: 91 1d adc r25, r1 1a60: 14 96 adiw r26, 0x04 ; 4 1a62: 9c 93 st X, r25 1a64: 8e 93 st -X, r24 1a66: 13 97 sbiw r26, 0x03 ; 3 if(taskStates[i].maxTimeSlice > taskStates[select].maxTimeSlice) select = i; } //update ages for (i=0;i taskStates[i].age += taskStates[i].maxTimeSlice; } //return selected return select; } 1a70: 81 2f mov r24, r17 1a72: df 91 pop r29 1a74: cf 91 pop r28 1a76: 1f 91 pop r17 1a78: 08 95 ret //update ages for (i=0;i 00001a8e : return os_Scheduler_Even((struct os_TaskAbstract *)taskStates,currentTask);; } //! even strategy unsigned char os_Scheduler_Even (struct os_TaskAbstract *taskStates, unsigned char currentTask) { 1a8e: ac 01 movw r20, r24 1a90: 70 e0 ldi r23, 0x00 ; 0 do { currentTask = (currentTask+1)%MAX_NUMBER_OF_TASKS; 1a92: 9b 01 movw r18, r22 1a94: 2f 5f subi r18, 0xFF ; 255 1a96: 3f 4f sbci r19, 0xFF ; 255 1a98: 27 70 andi r18, 0x07 ; 7 1a9a: 30 70 andi r19, 0x00 ; 0 } while (taskStates[currentTask].state != OS_TASK_READY); 1a9c: b9 01 movw r22, r18 1a9e: f9 01 movw r30, r18 1aa0: ee 0f add r30, r30 1aa2: ff 1f adc r31, r31 1aa4: ee 0f add r30, r30 1aa6: ff 1f adc r31, r31 1aa8: ee 0f add r30, r30 1aaa: ff 1f adc r31, r31 1aac: e2 0f add r30, r18 1aae: f3 1f adc r31, r19 1ab0: e4 0f add r30, r20 1ab2: f5 1f adc r31, r21 1ab4: 80 81 ld r24, Z 1ab6: 91 81 ldd r25, Z+1 ; 0x01 1ab8: 01 97 sbiw r24, 0x01 ; 1 1aba: 59 f7 brne .-42 ; 0x1a92 return currentTask; } 1abc: 82 2f mov r24, r18 1abe: 08 95 ret 00001ac0 : return select; } //! round-robin strategy unsigned char os_Scheduler_RoundRobin (struct os_TaskAbstract *taskStates, unsigned char currentTask) { 1ac0: 9c 01 movw r18, r24 //handle timeslice if (timeSlice > 0) 1ac2: 80 91 13 01 lds r24, 0x0113 1ac6: 90 91 14 01 lds r25, 0x0114 1aca: 89 2b or r24, r25 1acc: 09 f4 brne .+2 ; 0x1ad0 1ace: 3d c0 rjmp .+122 ; 0x1b4a { timeSlice--; 1ad0: 80 91 13 01 lds r24, 0x0113 1ad4: 90 91 14 01 lds r25, 0x0114 1ad8: 01 97 sbiw r24, 0x01 ; 1 1ada: 90 93 14 01 sts 0x0114, r25 1ade: 80 93 13 01 sts 0x0113, r24 SP = taskStates[currentTask].stackAddress; 1ae2: 86 2f mov r24, r22 1ae4: 90 e0 ldi r25, 0x00 ; 0 1ae6: fc 01 movw r30, r24 1ae8: ee 0f add r30, r30 1aea: ff 1f adc r31, r31 1aec: ee 0f add r30, r30 1aee: ff 1f adc r31, r31 1af0: ee 0f add r30, r30 1af2: ff 1f adc r31, r31 1af4: e8 0f add r30, r24 1af6: f9 1f adc r31, r25 1af8: e2 0f add r30, r18 1afa: f3 1f adc r31, r19 1afc: 85 81 ldd r24, Z+5 ; 0x05 1afe: 96 81 ldd r25, Z+6 ; 0x06 1b00: 9e bf out 0x3e, r25 ; 62 1b02: 8d bf out 0x3d, r24 ; 61 restoreContext(); 1b04: ff 91 pop r31 1b06: ef 91 pop r30 1b08: df 91 pop r29 1b0a: cf 91 pop r28 1b0c: bf 91 pop r27 1b0e: af 91 pop r26 1b10: 9f 91 pop r25 1b12: 8f 91 pop r24 1b14: 7f 91 pop r23 1b16: 6f 91 pop r22 1b18: 5f 91 pop r21 1b1a: 4f 91 pop r20 1b1c: 3f 91 pop r19 1b1e: 2f 91 pop r18 1b20: 1f 91 pop r17 1b22: 0f 91 pop r16 1b24: ff 90 pop r15 1b26: ef 90 pop r14 1b28: df 90 pop r13 1b2a: cf 90 pop r12 1b2c: bf 90 pop r11 1b2e: af 90 pop r10 1b30: 9f 90 pop r9 1b32: 8f 90 pop r8 1b34: 7f 90 pop r7 1b36: 6f 90 pop r6 1b38: 5f 90 pop r5 1b3a: 4f 90 pop r4 1b3c: 3f 90 pop r3 1b3e: 2f 90 pop r2 1b40: 1f 90 pop r1 1b42: 0f 90 pop r0 1b44: 0f be out 0x3f, r0 ; 63 1b46: 0f 90 pop r0 asm volatile("reti"); 1b48: 18 95 reti } //if timeslice is gone get the next task with even strategy return os_Scheduler_Even((struct os_TaskAbstract *)taskStates,currentTask);; 1b4a: c9 01 movw r24, r18 1b4c: 0e 94 47 0d call 0x1a8e ; 0x1a8e } 1b50: 08 95 ret 00001b52 : return currentTask; } //! no strategy (just keep whatever it was) , except currentTask was killed unsigned char os_Scheduler_None (struct os_TaskAbstract *taskStates, unsigned char currentTask) { 1b52: 9c 01 movw r18, r24 if ((taskStates[currentTask].state != OS_TASK_KILLED)&&(taskStates[currentTask].state != OS_TASK_PAUSED)) 1b54: 86 2f mov r24, r22 1b56: 90 e0 ldi r25, 0x00 ; 0 1b58: fc 01 movw r30, r24 1b5a: ee 0f add r30, r30 1b5c: ff 1f adc r31, r31 1b5e: ee 0f add r30, r30 1b60: ff 1f adc r31, r31 1b62: ee 0f add r30, r30 1b64: ff 1f adc r31, r31 1b66: e8 0f add r30, r24 1b68: f9 1f adc r31, r25 1b6a: e2 0f add r30, r18 1b6c: f3 1f adc r31, r19 1b6e: 80 81 ld r24, Z 1b70: 91 81 ldd r25, Z+1 ; 0x01 1b72: 03 97 sbiw r24, 0x03 ; 3 1b74: 02 97 sbiw r24, 0x02 ; 2 1b76: 10 f0 brcs .+4 ; 0x1b7c return currentTask; else return os_Scheduler_Even((struct os_TaskAbstract *)taskStates,currentTask); //get next READY task to avoid a killed task to be RUNNING again } 1b78: 86 2f mov r24, r22 1b7a: 08 95 ret unsigned char os_Scheduler_None (struct os_TaskAbstract *taskStates, unsigned char currentTask) { if ((taskStates[currentTask].state != OS_TASK_KILLED)&&(taskStates[currentTask].state != OS_TASK_PAUSED)) return currentTask; else return os_Scheduler_Even((struct os_TaskAbstract *)taskStates,currentTask); //get next READY task to avoid a killed task to be RUNNING again 1b7c: c9 01 movw r24, r18 1b7e: 0e 94 47 0d call 0x1a8e ; 0x1a8e 1b82: 68 2f mov r22, r24 } 1b84: 86 2f mov r24, r22 1b86: 08 95 ret 00001b88 : //! random strategy unsigned char os_Scheduler_Random(struct os_TaskAbstract *taskStates, unsigned char currentTask) { 1b88: 1f 93 push r17 1b8a: cf 93 push r28 1b8c: df 93 push r29 1b8e: ec 01 movw r28, r24 1b90: 16 2f mov r17, r22 unsigned char n = rand() % MAX_NUMBER_OF_TASKS; 1b92: 0e 94 f3 0e call 0x1de6 ; 0x1de6 1b96: 68 e0 ldi r22, 0x08 ; 8 1b98: 70 e0 ldi r23, 0x00 ; 0 1b9a: 0e 94 17 0f call 0x1e2e ; 0x1e2e <__divmodhi4> 1b9e: 78 2f mov r23, r24 1ba0: 60 e0 ldi r22, 0x00 ; 0 1ba2: 21 2f mov r18, r17 1ba4: 30 e0 ldi r19, 0x00 ; 0 // find n times the next ready task unsigned char i=0; for (; i<=n;i++) do { currentTask = (currentTask+1)%MAX_NUMBER_OF_TASKS; 1ba6: a9 01 movw r20, r18 1ba8: 4f 5f subi r20, 0xFF ; 255 1baa: 5f 4f sbci r21, 0xFF ; 255 1bac: 47 70 andi r20, 0x07 ; 7 1bae: 50 70 andi r21, 0x00 ; 0 } while (taskStates[currentTask].state != OS_TASK_READY); 1bb0: 9a 01 movw r18, r20 1bb2: fa 01 movw r30, r20 1bb4: ee 0f add r30, r30 1bb6: ff 1f adc r31, r31 1bb8: ee 0f add r30, r30 1bba: ff 1f adc r31, r31 1bbc: ee 0f add r30, r30 1bbe: ff 1f adc r31, r31 1bc0: e4 0f add r30, r20 1bc2: f5 1f adc r31, r21 1bc4: ec 0f add r30, r28 1bc6: fd 1f adc r31, r29 1bc8: 80 81 ld r24, Z 1bca: 91 81 ldd r25, Z+1 ; 0x01 1bcc: 01 97 sbiw r24, 0x01 ; 1 1bce: 59 f7 brne .-42 ; 0x1ba6 unsigned char n = rand() % MAX_NUMBER_OF_TASKS; // find n times the next ready task unsigned char i=0; for (; i<=n;i++) 1bd0: 6f 5f subi r22, 0xFF ; 255 1bd2: 76 17 cp r23, r22 1bd4: 40 f7 brcc .-48 ; 0x1ba6 { currentTask = (currentTask+1)%MAX_NUMBER_OF_TASKS; } while (taskStates[currentTask].state != OS_TASK_READY); return currentTask; } 1bd6: 84 2f mov r24, r20 1bd8: df 91 pop r29 1bda: cf 91 pop r28 1bdc: 1f 91 pop r17 1bde: 08 95 ret 00001be0 : #include "allHeaders.h" //! first-fit strategy unsigned char * os_Memory_FirstFit (unsigned int size) { 1be0: cf 92 push r12 1be2: df 92 push r13 1be4: ef 92 push r14 1be6: ff 92 push r15 1be8: 0f 93 push r16 1bea: 1f 93 push r17 1bec: cf 93 push r28 1bee: df 93 push r29 1bf0: 6c 01 movw r12, r24 1bf2: 00 e0 ldi r16, 0x00 ; 0 1bf4: 10 e0 ldi r17, 0x00 ; 0 1bf6: c6 e5 ldi r28, 0x56 ; 86 1bf8: d4 e0 ldi r29, 0x04 ; 4 1bfa: ee 24 eor r14, r14 1bfc: ff 24 eor r15, r15 1bfe: 09 c0 rjmp .+18 ; 0x1c12 unsigned int start=0; unsigned int count=0; //find a fitting free block in heap for(; i <= END_OF_HEAP; i++) if(os_getMapEntry((unsigned char*)i)==0) 1c00: 00 e0 ldi r16, 0x00 ; 0 1c02: 10 e0 ldi r17, 0x00 ; 0 1c04: ee 24 eor r14, r14 1c06: ff 24 eor r15, r15 unsigned int i = HEAP_START; unsigned int start=0; unsigned int count=0; //find a fitting free block in heap for(; i <= END_OF_HEAP; i++) 1c08: 21 96 adiw r28, 0x01 ; 1 1c0a: 89 e0 ldi r24, 0x09 ; 9 1c0c: c1 30 cpi r28, 0x01 ; 1 1c0e: d8 07 cpc r29, r24 1c10: 21 f1 breq .+72 ; 0x1c5a if(os_getMapEntry((unsigned char*)i)==0) 1c12: ce 01 movw r24, r28 1c14: 0e 94 74 0b call 0x16e8 ; 0x16e8 1c18: 88 23 and r24, r24 1c1a: 91 f7 brne .-28 ; 0x1c00 { //if we find a zero it could be the start of the block so we save it if (count == 0) 1c1c: 01 15 cp r16, r1 1c1e: 11 05 cpc r17, r1 1c20: 09 f4 brne .+2 ; 0x1c24 1c22: 7e 01 movw r14, r28 start=i; //we increase count until it matches the needed size and then break if (++count==size) 1c24: 0f 5f subi r16, 0xFF ; 255 1c26: 1f 4f sbci r17, 0xFF ; 255 1c28: 0c 15 cp r16, r12 1c2a: 1d 05 cpc r17, r13 1c2c: 69 f7 brne .-38 ; 0x1c08 //if a fitting block was found reserve the block for the task if (count == size) { //set task identifier os_setMapEntry((unsigned char*)start,os_currentTask); 1c2e: 60 91 12 01 lds r22, 0x0112 1c32: 67 01 movw r12, r14 1c34: c7 01 movw r24, r14 1c36: 0e 94 8a 0b call 0x1714 ; 0x1714 //set the "F"s i = start+1; 1c3a: e7 01 movw r28, r14 1c3c: 21 96 adiw r28, 0x01 ; 1 for(; i < (start+size); i++) 1c3e: 0e 0d add r16, r14 1c40: 1f 1d adc r17, r15 1c42: c0 17 cp r28, r16 1c44: d1 07 cpc r29, r17 1c46: 68 f4 brcc .+26 ; 0x1c62 { os_setMapEntry((unsigned char *)(i), 0x0F); 1c48: 6f e0 ldi r22, 0x0F ; 15 1c4a: ce 01 movw r24, r28 1c4c: 0e 94 8a 0b call 0x1714 ; 0x1714 //set task identifier os_setMapEntry((unsigned char*)start,os_currentTask); //set the "F"s i = start+1; for(; i < (start+size); i++) 1c50: 21 96 adiw r28, 0x01 ; 1 1c52: c0 17 cp r28, r16 1c54: d1 07 cpc r29, r17 1c56: c0 f3 brcs .-16 ; 0x1c48 1c58: 04 c0 rjmp .+8 ; 0x1c62 count = 0; start = 0; } //if a fitting block was found reserve the block for the task if (count == size) 1c5a: 0c 15 cp r16, r12 1c5c: 1d 05 cpc r17, r13 1c5e: 39 f3 breq .-50 ; 0x1c2e 1c60: 67 01 movw r12, r14 } } //returns start adress of reserved block and otherwise NULL return (unsigned char *)start; } 1c62: c6 01 movw r24, r12 1c64: df 91 pop r29 1c66: cf 91 pop r28 1c68: 1f 91 pop r17 1c6a: 0f 91 pop r16 1c6c: ff 90 pop r15 1c6e: ef 90 pop r14 1c70: df 90 pop r13 1c72: cf 90 pop r12 1c74: 08 95 ret 00001c76 : // Function headers //---------------------------------------------------------------------------- //! Refreshes the button states. void os_updateInput (void) { 1c76: 80 b1 in r24, 0x00 ; 0 1c78: 21 e0 ldi r18, 0x01 ; 1 1c7a: 30 e0 ldi r19, 0x00 ; 0 1c7c: 82 27 eor r24, r18 1c7e: 81 70 andi r24, 0x01 ; 1 1c80: 80 93 18 01 sts 0x0118, r24 os_buttonStates[OS_ENTER] = ( PINA & ( 1<< PINA0 ) ? 0 : 1 ); //button 1 os_buttonStates[OS_DOWN] = ( PINA & ( 1<< PINA1 ) ? 0 : 1 ); //button 2 1c84: 80 b1 in r24, 0x00 ; 0 1c86: 90 e0 ldi r25, 0x00 ; 0 1c88: 96 95 lsr r25 1c8a: 87 95 ror r24 1c8c: 82 27 eor r24, r18 1c8e: 93 27 eor r25, r19 1c90: 81 70 andi r24, 0x01 ; 1 1c92: 80 93 19 01 sts 0x0119, r24 os_buttonStates[OS_UP] = ( PINA & ( 1<< PINA2 ) ? 0 : 1 ); //button 3 1c96: 80 b1 in r24, 0x00 ; 0 1c98: 90 e0 ldi r25, 0x00 ; 0 1c9a: 96 95 lsr r25 1c9c: 87 95 ror r24 1c9e: 96 95 lsr r25 1ca0: 87 95 ror r24 1ca2: 82 27 eor r24, r18 1ca4: 93 27 eor r25, r19 1ca6: 81 70 andi r24, 0x01 ; 1 1ca8: 80 93 1a 01 sts 0x011A, r24 os_buttonStates[OS_ESC] = ( PINA & ( 1<< PINA3 ) ? 0 : 1 ); //button 4 1cac: 80 b1 in r24, 0x00 ; 0 1cae: 90 e0 ldi r25, 0x00 ; 0 1cb0: 96 95 lsr r25 1cb2: 87 95 ror r24 1cb4: 96 95 lsr r25 1cb6: 87 95 ror r24 1cb8: 96 95 lsr r25 1cba: 87 95 ror r24 1cbc: 82 27 eor r24, r18 1cbe: 93 27 eor r25, r19 1cc0: 81 70 andi r24, 0x01 ; 1 1cc2: 80 93 1b 01 sts 0x011B, r24 } 1cc6: 08 95 ret 00001cc8 : //! Waits for all buttons to be released. void os_waitForNoInput (void) { 1cc8: 0e 94 3b 0e call 0x1c76 ; 0x1c76 do os_updateInput(); while ((os_buttonStates[0]!=0) || (os_buttonStates[1]!=0) || (os_buttonStates[2]!=0) || (os_buttonStates[3]!=0)); 1ccc: 80 91 18 01 lds r24, 0x0118 1cd0: 88 23 and r24, r24 1cd2: d1 f7 brne .-12 ; 0x1cc8 1cd4: 80 91 19 01 lds r24, 0x0119 1cd8: 88 23 and r24, r24 1cda: b1 f7 brne .-20 ; 0x1cc8 1cdc: 80 91 1a 01 lds r24, 0x011A 1ce0: 88 23 and r24, r24 1ce2: 91 f7 brne .-28 ; 0x1cc8 1ce4: 80 91 1b 01 lds r24, 0x011B 1ce8: 88 23 and r24, r24 1cea: 71 f7 brne .-36 ; 0x1cc8 } 1cec: 08 95 ret 00001cee : //! Waits for at least one button to be pressed. void os_waitForInput (void) { 1cee: 0e 94 3b 0e call 0x1c76 ; 0x1c76 do os_updateInput(); while (!((os_buttonStates[0]==1) || (os_buttonStates[1]==1) || (os_buttonStates[2]==1) || (os_buttonStates[3]==1))); 1cf2: 80 91 18 01 lds r24, 0x0118 1cf6: 81 30 cpi r24, 0x01 ; 1 1cf8: 61 f0 breq .+24 ; 0x1d12 1cfa: 80 91 19 01 lds r24, 0x0119 1cfe: 81 30 cpi r24, 0x01 ; 1 1d00: 41 f0 breq .+16 ; 0x1d12 1d02: 80 91 1a 01 lds r24, 0x011A 1d06: 81 30 cpi r24, 0x01 ; 1 1d08: 21 f0 breq .+8 ; 0x1d12 1d0a: 80 91 1b 01 lds r24, 0x011B 1d0e: 81 30 cpi r24, 0x01 ; 1 1d10: 71 f7 brne .-36 ; 0x1cee 1d12: 08 95 ret 00001d14 : } enum os_Buttons os_getLastButton(void) { 1d14: 20 e0 ldi r18, 0x00 ; 0 1d16: 30 e0 ldi r19, 0x00 ; 0 int i=0; for (;i<4;i++) if(os_buttonStates[i]==1) 1d18: f9 01 movw r30, r18 1d1a: e8 5e subi r30, 0xE8 ; 232 1d1c: fe 4f sbci r31, 0xFE ; 254 1d1e: 80 81 ld r24, Z 1d20: 81 30 cpi r24, 0x01 ; 1 1d22: 69 f0 breq .+26 ; 0x1d3e enum os_Buttons os_getLastButton(void) { int i=0; for (;i<4;i++) 1d24: 2f 5f subi r18, 0xFF ; 255 1d26: 3f 4f sbci r19, 0xFF ; 255 1d28: 24 30 cpi r18, 0x04 ; 4 1d2a: 31 05 cpc r19, r1 1d2c: a9 f7 brne .-22 ; 0x1d18 if(os_buttonStates[i]==1) return i; os_error(OS_ERROR_UNKNOWN); 1d2e: 81 e0 ldi r24, 0x01 ; 1 1d30: 90 e0 ldi r25, 0x00 ; 0 1d32: 0e 94 ef 06 call 0xdde ; 0xdde 1d36: e0 e0 ldi r30, 0x00 ; 0 1d38: f0 e0 ldi r31, 0x00 ; 0 return 0; } 1d3a: cf 01 movw r24, r30 1d3c: 08 95 ret enum os_Buttons os_getLastButton(void) { int i=0; for (;i<4;i++) if(os_buttonStates[i]==1) return i; 1d3e: f9 01 movw r30, r18 os_error(OS_ERROR_UNKNOWN); return 0; } 1d40: cf 01 movw r24, r30 1d42: 08 95 ret 00001d44 : 1d44: a0 e0 ldi r26, 0x00 ; 0 1d46: b0 e0 ldi r27, 0x00 ; 0 1d48: e8 ea ldi r30, 0xA8 ; 168 1d4a: fe e0 ldi r31, 0x0E ; 14 1d4c: 0c 94 6c 0f jmp 0x1ed8 ; 0x1ed8 <__prologue_saves__+0x10> 1d50: ec 01 movw r28, r24 1d52: a8 80 ld r10, Y 1d54: b9 80 ldd r11, Y+1 ; 0x01 1d56: ca 80 ldd r12, Y+2 ; 0x02 1d58: db 80 ldd r13, Y+3 ; 0x03 1d5a: a1 14 cp r10, r1 1d5c: b1 04 cpc r11, r1 1d5e: c1 04 cpc r12, r1 1d60: d1 04 cpc r13, r1 1d62: 41 f4 brne .+16 ; 0x1d74 1d64: 84 e2 ldi r24, 0x24 ; 36 1d66: a8 2e mov r10, r24 1d68: 89 ed ldi r24, 0xD9 ; 217 1d6a: b8 2e mov r11, r24 1d6c: 8b e5 ldi r24, 0x5B ; 91 1d6e: c8 2e mov r12, r24 1d70: 87 e0 ldi r24, 0x07 ; 7 1d72: d8 2e mov r13, r24 1d74: c6 01 movw r24, r12 1d76: b5 01 movw r22, r10 1d78: 2d e1 ldi r18, 0x1D ; 29 1d7a: 33 ef ldi r19, 0xF3 ; 243 1d7c: 41 e0 ldi r20, 0x01 ; 1 1d7e: 50 e0 ldi r21, 0x00 ; 0 1d80: 0e 94 49 0f call 0x1e92 ; 0x1e92 <__divmodsi4> 1d84: 27 ea ldi r18, 0xA7 ; 167 1d86: 31 e4 ldi r19, 0x41 ; 65 1d88: 40 e0 ldi r20, 0x00 ; 0 1d8a: 50 e0 ldi r21, 0x00 ; 0 1d8c: 0e 94 2a 0f call 0x1e54 ; 0x1e54 <__mulsi3> 1d90: 7b 01 movw r14, r22 1d92: 8c 01 movw r16, r24 1d94: c6 01 movw r24, r12 1d96: b5 01 movw r22, r10 1d98: 2d e1 ldi r18, 0x1D ; 29 1d9a: 33 ef ldi r19, 0xF3 ; 243 1d9c: 41 e0 ldi r20, 0x01 ; 1 1d9e: 50 e0 ldi r21, 0x00 ; 0 1da0: 0e 94 49 0f call 0x1e92 ; 0x1e92 <__divmodsi4> 1da4: ca 01 movw r24, r20 1da6: b9 01 movw r22, r18 1da8: 2c ee ldi r18, 0xEC ; 236 1daa: 34 ef ldi r19, 0xF4 ; 244 1dac: 4f ef ldi r20, 0xFF ; 255 1dae: 5f ef ldi r21, 0xFF ; 255 1db0: 0e 94 2a 0f call 0x1e54 ; 0x1e54 <__mulsi3> 1db4: 6e 0d add r22, r14 1db6: 7f 1d adc r23, r15 1db8: 80 1f adc r24, r16 1dba: 91 1f adc r25, r17 1dbc: 97 ff sbrs r25, 7 1dbe: 04 c0 rjmp .+8 ; 0x1dc8 1dc0: 61 50 subi r22, 0x01 ; 1 1dc2: 70 40 sbci r23, 0x00 ; 0 1dc4: 80 40 sbci r24, 0x00 ; 0 1dc6: 90 48 sbci r25, 0x80 ; 128 1dc8: 68 83 st Y, r22 1dca: 79 83 std Y+1, r23 ; 0x01 1dcc: 8a 83 std Y+2, r24 ; 0x02 1dce: 9b 83 std Y+3, r25 ; 0x03 1dd0: 9b 01 movw r18, r22 1dd2: 3f 77 andi r19, 0x7F ; 127 1dd4: c9 01 movw r24, r18 1dd6: cd b7 in r28, 0x3d ; 61 1dd8: de b7 in r29, 0x3e ; 62 1dda: ea e0 ldi r30, 0x0A ; 10 1ddc: 0c 94 88 0f jmp 0x1f10 ; 0x1f10 <__epilogue_restores__+0x10> 00001de0 : 1de0: 0e 94 a2 0e call 0x1d44 ; 0x1d44 1de4: 08 95 ret 00001de6 : 1de6: 8c e0 ldi r24, 0x0C ; 12 1de8: 91 e0 ldi r25, 0x01 ; 1 1dea: 0e 94 a2 0e call 0x1d44 ; 0x1d44 1dee: 08 95 ret 00001df0 : 1df0: a0 e0 ldi r26, 0x00 ; 0 1df2: b0 e0 ldi r27, 0x00 ; 0 1df4: 80 93 0c 01 sts 0x010C, r24 1df8: 90 93 0d 01 sts 0x010D, r25 1dfc: a0 93 0e 01 sts 0x010E, r26 1e00: b0 93 0f 01 sts 0x010F, r27 1e04: 08 95 ret 00001e06 <__udivmodhi4>: 1e06: aa 1b sub r26, r26 1e08: bb 1b sub r27, r27 1e0a: 51 e1 ldi r21, 0x11 ; 17 1e0c: 07 c0 rjmp .+14 ; 0x1e1c <__udivmodhi4_ep> 00001e0e <__udivmodhi4_loop>: 1e0e: aa 1f adc r26, r26 1e10: bb 1f adc r27, r27 1e12: a6 17 cp r26, r22 1e14: b7 07 cpc r27, r23 1e16: 10 f0 brcs .+4 ; 0x1e1c <__udivmodhi4_ep> 1e18: a6 1b sub r26, r22 1e1a: b7 0b sbc r27, r23 00001e1c <__udivmodhi4_ep>: 1e1c: 88 1f adc r24, r24 1e1e: 99 1f adc r25, r25 1e20: 5a 95 dec r21 1e22: a9 f7 brne .-22 ; 0x1e0e <__udivmodhi4_loop> 1e24: 80 95 com r24 1e26: 90 95 com r25 1e28: bc 01 movw r22, r24 1e2a: cd 01 movw r24, r26 1e2c: 08 95 ret 00001e2e <__divmodhi4>: 1e2e: 97 fb bst r25, 7 1e30: 09 2e mov r0, r25 1e32: 07 26 eor r0, r23 1e34: 0a d0 rcall .+20 ; 0x1e4a <__divmodhi4_neg1> 1e36: 77 fd sbrc r23, 7 1e38: 04 d0 rcall .+8 ; 0x1e42 <__divmodhi4_neg2> 1e3a: e5 df rcall .-54 ; 0x1e06 <__udivmodhi4> 1e3c: 06 d0 rcall .+12 ; 0x1e4a <__divmodhi4_neg1> 1e3e: 00 20 and r0, r0 1e40: 1a f4 brpl .+6 ; 0x1e48 <__divmodhi4_exit> 00001e42 <__divmodhi4_neg2>: 1e42: 70 95 com r23 1e44: 61 95 neg r22 1e46: 7f 4f sbci r23, 0xFF ; 255 00001e48 <__divmodhi4_exit>: 1e48: 08 95 ret 00001e4a <__divmodhi4_neg1>: 1e4a: f6 f7 brtc .-4 ; 0x1e48 <__divmodhi4_exit> 1e4c: 90 95 com r25 1e4e: 81 95 neg r24 1e50: 9f 4f sbci r25, 0xFF ; 255 1e52: 08 95 ret 00001e54 <__mulsi3>: 1e54: 62 9f mul r22, r18 1e56: d0 01 movw r26, r0 1e58: 73 9f mul r23, r19 1e5a: f0 01 movw r30, r0 1e5c: 82 9f mul r24, r18 1e5e: e0 0d add r30, r0 1e60: f1 1d adc r31, r1 1e62: 64 9f mul r22, r20 1e64: e0 0d add r30, r0 1e66: f1 1d adc r31, r1 1e68: 92 9f mul r25, r18 1e6a: f0 0d add r31, r0 1e6c: 83 9f mul r24, r19 1e6e: f0 0d add r31, r0 1e70: 74 9f mul r23, r20 1e72: f0 0d add r31, r0 1e74: 65 9f mul r22, r21 1e76: f0 0d add r31, r0 1e78: 99 27 eor r25, r25 1e7a: 72 9f mul r23, r18 1e7c: b0 0d add r27, r0 1e7e: e1 1d adc r30, r1 1e80: f9 1f adc r31, r25 1e82: 63 9f mul r22, r19 1e84: b0 0d add r27, r0 1e86: e1 1d adc r30, r1 1e88: f9 1f adc r31, r25 1e8a: bd 01 movw r22, r26 1e8c: cf 01 movw r24, r30 1e8e: 11 24 eor r1, r1 1e90: 08 95 ret 00001e92 <__divmodsi4>: 1e92: 97 fb bst r25, 7 1e94: 09 2e mov r0, r25 1e96: 05 26 eor r0, r21 1e98: 0e d0 rcall .+28 ; 0x1eb6 <__divmodsi4_neg1> 1e9a: 57 fd sbrc r21, 7 1e9c: 04 d0 rcall .+8 ; 0x1ea6 <__divmodsi4_neg2> 1e9e: 4b d0 rcall .+150 ; 0x1f36 <__udivmodsi4> 1ea0: 0a d0 rcall .+20 ; 0x1eb6 <__divmodsi4_neg1> 1ea2: 00 1c adc r0, r0 1ea4: 38 f4 brcc .+14 ; 0x1eb4 <__divmodsi4_exit> 00001ea6 <__divmodsi4_neg2>: 1ea6: 50 95 com r21 1ea8: 40 95 com r20 1eaa: 30 95 com r19 1eac: 21 95 neg r18 1eae: 3f 4f sbci r19, 0xFF ; 255 1eb0: 4f 4f sbci r20, 0xFF ; 255 1eb2: 5f 4f sbci r21, 0xFF ; 255 00001eb4 <__divmodsi4_exit>: 1eb4: 08 95 ret 00001eb6 <__divmodsi4_neg1>: 1eb6: f6 f7 brtc .-4 ; 0x1eb4 <__divmodsi4_exit> 1eb8: 90 95 com r25 1eba: 80 95 com r24 1ebc: 70 95 com r23 1ebe: 61 95 neg r22 1ec0: 7f 4f sbci r23, 0xFF ; 255 1ec2: 8f 4f sbci r24, 0xFF ; 255 1ec4: 9f 4f sbci r25, 0xFF ; 255 1ec6: 08 95 ret 00001ec8 <__prologue_saves__>: 1ec8: 2f 92 push r2 1eca: 3f 92 push r3 1ecc: 4f 92 push r4 1ece: 5f 92 push r5 1ed0: 6f 92 push r6 1ed2: 7f 92 push r7 1ed4: 8f 92 push r8 1ed6: 9f 92 push r9 1ed8: af 92 push r10 1eda: bf 92 push r11 1edc: cf 92 push r12 1ede: df 92 push r13 1ee0: ef 92 push r14 1ee2: ff 92 push r15 1ee4: 0f 93 push r16 1ee6: 1f 93 push r17 1ee8: cf 93 push r28 1eea: df 93 push r29 1eec: cd b7 in r28, 0x3d ; 61 1eee: de b7 in r29, 0x3e ; 62 1ef0: ca 1b sub r28, r26 1ef2: db 0b sbc r29, r27 1ef4: 0f b6 in r0, 0x3f ; 63 1ef6: f8 94 cli 1ef8: de bf out 0x3e, r29 ; 62 1efa: 0f be out 0x3f, r0 ; 63 1efc: cd bf out 0x3d, r28 ; 61 1efe: 09 94 ijmp 00001f00 <__epilogue_restores__>: 1f00: 2a 88 ldd r2, Y+18 ; 0x12 1f02: 39 88 ldd r3, Y+17 ; 0x11 1f04: 48 88 ldd r4, Y+16 ; 0x10 1f06: 5f 84 ldd r5, Y+15 ; 0x0f 1f08: 6e 84 ldd r6, Y+14 ; 0x0e 1f0a: 7d 84 ldd r7, Y+13 ; 0x0d 1f0c: 8c 84 ldd r8, Y+12 ; 0x0c 1f0e: 9b 84 ldd r9, Y+11 ; 0x0b 1f10: aa 84 ldd r10, Y+10 ; 0x0a 1f12: b9 84 ldd r11, Y+9 ; 0x09 1f14: c8 84 ldd r12, Y+8 ; 0x08 1f16: df 80 ldd r13, Y+7 ; 0x07 1f18: ee 80 ldd r14, Y+6 ; 0x06 1f1a: fd 80 ldd r15, Y+5 ; 0x05 1f1c: 0c 81 ldd r16, Y+4 ; 0x04 1f1e: 1b 81 ldd r17, Y+3 ; 0x03 1f20: aa 81 ldd r26, Y+2 ; 0x02 1f22: b9 81 ldd r27, Y+1 ; 0x01 1f24: ce 0f add r28, r30 1f26: d1 1d adc r29, r1 1f28: 0f b6 in r0, 0x3f ; 63 1f2a: f8 94 cli 1f2c: de bf out 0x3e, r29 ; 62 1f2e: 0f be out 0x3f, r0 ; 63 1f30: cd bf out 0x3d, r28 ; 61 1f32: ed 01 movw r28, r26 1f34: 08 95 ret 00001f36 <__udivmodsi4>: 1f36: a1 e2 ldi r26, 0x21 ; 33 1f38: 1a 2e mov r1, r26 1f3a: aa 1b sub r26, r26 1f3c: bb 1b sub r27, r27 1f3e: fd 01 movw r30, r26 1f40: 0d c0 rjmp .+26 ; 0x1f5c <__udivmodsi4_ep> 00001f42 <__udivmodsi4_loop>: 1f42: aa 1f adc r26, r26 1f44: bb 1f adc r27, r27 1f46: ee 1f adc r30, r30 1f48: ff 1f adc r31, r31 1f4a: a2 17 cp r26, r18 1f4c: b3 07 cpc r27, r19 1f4e: e4 07 cpc r30, r20 1f50: f5 07 cpc r31, r21 1f52: 20 f0 brcs .+8 ; 0x1f5c <__udivmodsi4_ep> 1f54: a2 1b sub r26, r18 1f56: b3 0b sbc r27, r19 1f58: e4 0b sbc r30, r20 1f5a: f5 0b sbc r31, r21 00001f5c <__udivmodsi4_ep>: 1f5c: 66 1f adc r22, r22 1f5e: 77 1f adc r23, r23 1f60: 88 1f adc r24, r24 1f62: 99 1f adc r25, r25 1f64: 1a 94 dec r1 1f66: 69 f7 brne .-38 ; 0x1f42 <__udivmodsi4_loop> 1f68: 60 95 com r22 1f6a: 70 95 com r23 1f6c: 80 95 com r24 1f6e: 90 95 com r25 1f70: 9b 01 movw r18, r22 1f72: ac 01 movw r20, r24 1f74: bd 01 movw r22, r26 1f76: cf 01 movw r24, r30 1f78: 08 95 ret 00001f7a <_exit>: 1f7a: f8 94 cli 00001f7c <__stop_program>: 1f7c: ff cf rjmp .-2 ; 0x1f7c <__stop_program>