Presentation is loading. Please wait.

Presentation is loading. Please wait.

Embedded Systems Programming Examples and Comparison

Similar presentations


Presentation on theme: "Embedded Systems Programming Examples and Comparison"— Presentation transcript:

1 Embedded Systems Programming Examples and Comparison
Assembly language Vs Embedded C Examples and Comparison

2 First example: A very simple program - ‘Switches and lights’

3 Simple Example Program
‘Switches and Lights’ Assembly Version Page 1

4 Simple Example Program
‘Switches and Lights’ Assembly Version Page 2

5 Memory Image ‘Switches and Lights’ Assembly version
Reset vector (program starts here), rjmp INIT The first four instructions load the stack pointer value Org 0x020 ‘INIT’ label Set port B (ldi, out, out) Set port D (ldi, out, ldi, out) rjmp main Main loop (in, out, rcall delay, rjmp main) Delay subroutine (ldi, ldi, ldi, dec, brne, dec, brne, dec, brne, ret) Assembly code instructions are converted into ‘machine code’. One assembly instruction = 2 byte machine code instruction (op-code). Examples: ldi = 0xE, val (hi byte) RegNum -16, val (lo byte) out = 0xB, Port addr (hi byte) RegNum -16, Port addr (lo byte) ret = 0x95 (hi byte) 0x08 (lo byte)

6 Simple Example Program ‘Switches and Lights’ Embedded ‘C’ (1)

7 Simple Example Program ‘Switches and Lights’ Embedded ‘C’ (2)

8 Assembly version of Program ‘Switches and Lights’ (1)
Automatically generated from the Embedded ‘C’ version (.lss file) Note that this is much longer than the hand-crafted assembly version <__vectors>: 0: 14 c rjmp ; 0x2a <__ctors_end> 2: 1b c rjmp ; 0x3a <__bad_interrupt> 4: 1a c rjmp ; 0x3a <__bad_interrupt> (some vectors skipped for brevity) 24: 0a c rjmp ; 0x3a <__bad_interrupt> 26: 09 c rjmp ; 0x3a <__bad_interrupt> 28: 08 c rjmp ; 0x3a <__bad_interrupt> a <__ctors_end>: 2a: eor r1, r1 2c: 1f be out 0x3f, r1 ; 63 2e: cf e ldi r28, 0x5F ; 95 30: d2 e ldi r29, 0x02 ; 2 32: de bf out 0x3e, r29 ; 62 34: cd bf out 0x3d, r28 ; 61 36: 02 d rcall ; 0x3c <main> 38: 57 c rjmp ; 0xe8 <_exit> a <__bad_interrupt>: 3a: e2 cf rjmp ; 0x0 <__vectors> These four statements set the stack pointer, they are placed here automatically by the C compiler so the programmer does not need to do it manually All unused interrupt vectors are pointed to the same place, which in turn points back to the reset vector

9 Assembly version of Program ‘Switches and Lights’ (2)
Automatically generated from the Embedded ‘C’ version (.lss file) First part of main() c <main>: // Declare functions (these will be in a separate header file in larger programs) void InitialiseGeneral(); int main( void ) { 3c: df push r29 3e: cf push r28 40: 0f push r0 42: cd b in r28, 0x3d ; 61 44: de b in r29, 0x3e ; 62 unsigned char Switches_Value; // Declare a local variable InitialiseGeneral(); 46: 0f d rcall ; 0x66 <InitialiseGeneral>

10 Assembly version of Program ‘Switches and Lights’ (3)
Automatically generated from the Embedded ‘C’ version (.lss file) Second part of main() while(1) // Loop { Switches_Value = PIND; // Read value from the switches into the variable 48: 80 e ldi r24, 0x30 ; 48 4a: 90 e ldi r25, 0x00 ; 0 4c: fc movw r30, r24 4e: ld r24, Z 50: std Y+1, r24 ; 0x01 PORTB = Switches_Value; // Output the value from the variable onto the LEDs 52: 88 e ldi r24, 0x38 ; 56 54: 90 e ldi r25, 0x00 ; 0 56: ldd r18, Y+1 ; 0x01 58: fc movw r30, r24 5a: st Z, r18 Delay(); 5c: 8d e ldi r24, 0x4D ; 77 5e: 90 e ldi r25, 0x00 ; 0 60: fc movw r30, r24 62: icall } 64: f1 cf rjmp ; 0x48 <__SREG__+0x9>

11 Assembly version of Program ‘Switches and Lights’ (4)
void InitialiseGeneral() { 66: df push r29 68: cf push r28 6a: cd b in r28, 0x3d ; 61 6c: de b in r29, 0x3e ; 62 DDRB = 0xFF; // Configure PortB direction for Output 6e: 87 e ldi r24, 0x37 ; 55 70: 90 e ldi r25, 0x00 ; 0 72: 2f ef ldi r18, 0xFF ; 255 74: fc movw r30, r24 76: st Z, r18 PORTB = 0xFF; // Set all LEDs initially off (inverted on the board, so '1' = off) 78: 88 e ldi r24, 0x38 ; 56 7a: 90 e ldi r25, 0x00 ; 0 7c: 2f ef ldi r18, 0xFF ; 255 7e: fc movw r30, r24 80: st Z, r18 DDRD = 0x00; // Configure PortD direction for Input 82: 81 e ldi r24, 0x31 ; 49 84: 90 e ldi r25, 0x00 ; 0 86: fc movw r30, r24 88: st Z, r1 PORTD = 0xFF; // Set pullup resistors on 8a: 82 e ldi r24, 0x32 ; 50 8c: 90 e ldi r25, 0x00 ; 0 8e: 2f ef ldi r18, 0xFF ; 255 90: fc movw r30, r24 92: st Z, r18 // (ensures switches cause change from a '1' to a '0' when pressed) } 94: cf pop r28 96: df pop r29 98: ret

12 Assembly version of Program ‘Switches and Lights’ (5)
void Delay() { 9a: df push r29 9c: cf push r28 9e: 00 d rcall ; 0xa0 <Delay+0x6> a0: 0f push r0 a2: cd b in r28, 0x3d ; 61 a4: de b in r29, 0x3e ; 62 unsigned char DelayCount1, DelayCount2, DelayCount3; // Declare local variables for(DelayCount1 = 0X04; DelayCount1 > 0; DelayCount1--) a6: 84 e ldi r24, 0x04 ; 4 a8: std Y+1, r24 ; 0x01 aa: 15 c rjmp ; 0xd6 <Delay+0x3c> for(DelayCount2 = 0XFF; DelayCount2 > 0; DelayCount2--) ac: 8f ef ldi r24, 0xFF ; 255 ae: 8a std Y+2, r24 ; 0x02 b0: 0c c rjmp ; 0xca <Delay+0x30> for(DelayCount3 = 0XFF; DelayCount3 > 0; DelayCount3--); b2: 8f ef ldi r24, 0xFF ; 255 b4: 8b std Y+3, r24 ; 0x03 b6: 03 c rjmp ; 0xbe <Delay+0x24> b8: 8b ldd r24, Y+3 ; 0x03 ba: subi r24, 0x01 ; 1 bc: 8b std Y+3, r24 ; 0x03 be: 8b ldd r24, Y+3 ; 0x03 c0: and r24, r24 c2: d1 f brne ; 0xb8 <Delay+0x1e> c4: 8a ldd r24, Y+2 ; 0x02 c6: subi r24, 0x01 ; 1 c8: 8a std Y+2, r24 ; 0x02 ca: 8a ldd r24, Y+2 ; 0x02 cc: and r24, r24 ce: 89 f brne ; 0xb2 <Delay+0x18>

13 Memory Image ‘Switches and Lights’ C version
Reset vector Main() While loop InitialiseGeneral() Delay()

14 Advantages of Assembly language
Code is more concise – requires less storage space (can be very important e.g. ATmega8535 only has enough program memory for 4000 instructions, ATtiny25 holds only 1000 instructions. Code executes faster – the programmer can avoid some surplus code that a C compiler automatically inserts, and thus some unnecessary run time steps are removed. Simpler instructions and syntax (but more instructions needed). Can achieve precise timing, and can determine the timing of code execution by examining the instruction sequence (each instruction takes exactly 1, 2 or 3 clock cycles). Examples of the need for such precision: PWM, Pulsing an ultrasonic transmitter, serial communications handler (clocking bits in / out).

15 Advantages of Embedded C
Derived from C – a well known, sophisticated standard. Simpler to develop (general opinion) because the instructions are at a ‘higher level’ and generally need less instructions because each one covers more functionality. Potentially less error prone (syntactically), because fewer statements. Potentially less error prone (semantically), as the higher level language is a closer representation of the application logic than assembly is, and the compiler enforces structure. It is possible to insert assembly code functions into Embedded C programs, using the ASM keyword. Large programs can be modularised more easily, using headers and libraries. Programs are more portable (i.e. Movable from one platform to another).

16 Second example: Configuring a programmable timer to generate a 1Hz pulse – and flash an LED at that rate

17 ‘TimerDemo1_SingleTimerSingleLEDFlash’ - Assembly version (1)

18 ‘TimerDemo1_SingleTimerSingleLEDFlash’ - Assembly version (2)

19 ‘TimerDemo1_SingleTimerSingleLEDFlash’ - Assembly version (3)

20 ‘TimerDemo1_SingleTimerSingleLEDFlash’ - Assembly version (4)

21 Memory image for TimerDemo1_SingleTimerSingleLEDFlash.asm

22 ‘TimerDemo1_SingleTimerSingleLEDFlash’ - ‘C’ version (1)

23 ‘TimerDemo1_SingleTimerSingleLEDFlash’ - ‘C’ version (2)

24 ‘TimerDemo1_SingleTimerSingleLEDFlash’ - ‘C’ version (3)

25 ‘TimerDemo1_SingleTimerSingleLEDFlash’ - ‘C’ version (4)

26 Memory image for C_TimerDemo1_SingleTimerSingleLEDFlash.c


Download ppt "Embedded Systems Programming Examples and Comparison"

Similar presentations


Ads by Google