• Keine Ergebnisse gefunden

Programmspeicher: Programmspeicher: Datenspeicher: Datenspeicher: Getrennter Programm-/Datenspeicher Getrennter Programm-/Datenspeicher Harvard-Architektur

N/A
N/A
Protected

Academic year: 2021

Aktie "Programmspeicher: Programmspeicher: Datenspeicher: Datenspeicher: Getrennter Programm-/Datenspeicher Getrennter Programm-/Datenspeicher Harvard-Architektur"

Copied!
28
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

1

Harvard-Architektur

Getrennter Programm-/Datenspeicher

Datenspeicher:

SRAM

EEPROM

Programmspeicher:

Flash

Getrennter Programm-/Datenspeicher

Datenspeicher:

SRAM

EEPROM

Programmspeicher:

Flash

(2)

2

Datenspeicher

Registerfile

Arbeitsregister,

Steuerregister/Ports Sram (static Ram)

1kByte bei ATmega8

4kByte bei ATmega128

Ram für statische Variable, (Literale), Texte, Stack EEPROM

512 Byte

langsamer Zugriff, insbes. Beim Schreiben

Registerfile

Arbeitsregister,

Steuerregister/Ports Sram (static Ram)

1kByte bei ATmega8

4kByte bei ATmega128

Ram für statische Variable, (Literale), Texte, Stack EEPROM

512 Byte

langsamer Zugriff, insbes. Beim Schreiben

(3)

3

Adresse

Register

I/O

SRAM

$0000-$001F (32 Byte)

$0020-$005F (64 Byte)

$0060-$045F (1024 Byte)

$0000-$045F (1120 Byte)

SRam und Adressbereiche

(4)

Arbeitsregister

General Purpose Working Registers

R0 0x00 Eingeschränkt, kein Laden von Direktwerten

R1 0x01 (Literalen)

R2 0x02

R13 0x0D R14 0x0E R15 0x0F

R16 0x10 Uneingeschränkt

R17 0x11

R26 0x1A X-register Low Byte Als 16-bit Adressregister nutzbar R27 0x1B X-register High Byte

R28 0x1C Y-register Low Byte R29 0x1D Y-register High Byte R30 0x1E Z-register Low Byte R31 0x1F Z-register High Byte

R0 0x00 Eingeschränkt, kein Laden von Direktwerten

R1 0x01 (Literalen)

R2 0x02

R13 0x0D R14 0x0E R15 0x0F

R16 0x10 Uneingeschränkt

R17 0x11

R26 0x1A X-register Low Byte Als 16-bit Adressregister nutzbar R27 0x1B X-register High Byte

R28 0x1C Y-register Low Byte R29 0x1D Y-register High Byte R30 0x1E Z-register Low Byte R31 0x1F Z-register High Byte

4

(5)

Register Summary

Address Name Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Page

0x3F (0x5F) SREG I T H S V N Z C 11

0x3E (0x5E) SPH SP10 SP9 SP8 13

0x3D(0x5D) SPL SP7 SP6 SP5 SP4 SP3 SP2 SP1 SP0 13

0x3C(0x5C) Reserved

0x3B(0x5B) GICR INT1 IVSEL IVCE 49,67

0x3A(0x5A) GIFR INTF1 INTF0 INTF0 68

0x39(0x59) TIMSK OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 TOIE0 72,102,122

0x38(0x58) TIFR OCF2 TOV2 ICF1 OCF1A OCF1B TOV1 TOV0 73,103,123

0x37(0x57) SPMCR SPMIE RWWSB – RWWSRE BLBSET PGWRT PGERS SPMEN 213

0x36(0x56) TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN TWIE 171

0x35(0x55) MCUCR SE SM2 SM1 SM0 ISC11 ISC10 ISC01 ISC00 33,66

0x34(0x54) MCUCSR – WDRF BORF EXTRF PORF 41

0x33(0x53) TCCR0 CS02 CS01 CS00 72

0x32(0x52) TCNT0 Timer/Counter0 (8 Bits) 72

0x31(0x51) OSCCAL Oscillator Calibration Register 31

0x30(0x50) SFIOR ACME PUD PSR2 PSR10 58, 75, 123,193

0x2F(0x4F) TCCR1A COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10 97

0x2E(0x4E) TCCR1B ICNC1 ICES1 WGM13 WGM12 CS12 CS11 CS10 100

0x2D(0x4D) TCNT1H Timer/Counter1 – Counter Register High byte 101

0x2C(0x4C) TCNT1L Timer/Counter1 – Counter Register Low byte 101

0x2B(0x4B) OCR1AH Timer/Counter1 – Output Compare Register A High byte 101

0x2A(0x4A) OCR1AL Timer/Counter1 – Output Compare Register A Low byte 101

0x29(0x49) OCR1BH Timer/Counter1 – Output Compare Register B High byte 101

0x28(0x48) OCR1BL Timer/Counter1 – Output Compare Register B Low byte 101

0x27(0x47) ICR1H Timer/Counter1 – Input Capture Register High byte 102

0x26(0x46) ICR1L Timer/Counter1 – Input Capture Register Low byte 102

0x25(0x45) TCCR2 FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20 117

0x24(0x44) TCNT2 Timer/Counter2 (8 Bits) 119

0x23(0x43) OCR2 Timer/Counter2 Output Compare Register 119

0x22(0x42) ASSR AS2 TCN2UB OCR2UB TCR2UB 119

0x21(0x41) WDTCR WDCE WDE WDP2 WDP1 WDP0 43

Register Summary

Address Name Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Page

0x3F (0x5F) SREG I T H S V N Z C 11

0x3E (0x5E) SPH SP10 SP9 SP8 13

0x3D(0x5D) SPL SP7 SP6 SP5 SP4 SP3 SP2 SP1 SP0 13

0x3C(0x5C) Reserved

0x3B(0x5B) GICR INT1 IVSEL IVCE 49,67

0x3A(0x5A) GIFR INTF1 INTF0 INTF0 68

0x39(0x59) TIMSK OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 TOIE0 72,102,122

0x38(0x58) TIFR OCF2 TOV2 ICF1 OCF1A OCF1B TOV1 TOV0 73,103,123

0x37(0x57) SPMCR SPMIE RWWSB – RWWSRE BLBSET PGWRT PGERS SPMEN 213

0x36(0x56) TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN TWIE 171

0x35(0x55) MCUCR SE SM2 SM1 SM0 ISC11 ISC10 ISC01 ISC00 33,66

0x34(0x54) MCUCSR – WDRF BORF EXTRF PORF 41

0x33(0x53) TCCR0 CS02 CS01 CS00 72

0x32(0x52) TCNT0 Timer/Counter0 (8 Bits) 72

0x31(0x51) OSCCAL Oscillator Calibration Register 31

0x30(0x50) SFIOR ACME PUD PSR2 PSR10 58, 75, 123,193

0x2F(0x4F) TCCR1A COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10 97

0x2E(0x4E) TCCR1B ICNC1 ICES1 WGM13 WGM12 CS12 CS11 CS10 100

0x2D(0x4D) TCNT1H Timer/Counter1 – Counter Register High byte 101

0x2C(0x4C) TCNT1L Timer/Counter1 – Counter Register Low byte 101

0x2B(0x4B) OCR1AH Timer/Counter1 – Output Compare Register A High byte 101

0x2A(0x4A) OCR1AL Timer/Counter1 – Output Compare Register A Low byte 101

0x29(0x49) OCR1BH Timer/Counter1 – Output Compare Register B High byte 101

0x28(0x48) OCR1BL Timer/Counter1 – Output Compare Register B Low byte 101

0x27(0x47) ICR1H Timer/Counter1 – Input Capture Register High byte 102

0x26(0x46) ICR1L Timer/Counter1 – Input Capture Register Low byte 102

0x25(0x45) TCCR2 FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20 117

0x24(0x44) TCNT2 Timer/Counter2 (8 Bits) 119

0x23(0x43) OCR2 Timer/Counter2 Output Compare Register 119

0x22(0x42) ASSR AS2 TCN2UB OCR2UB TCR2UB 119

0x21(0x41) WDTCR WDCE WDE WDP2 WDP1 WDP0 5 43

Ram-Adresse I/O-Controll-

Register (von in/out verwendet)

SpecialFunctionRegister

(SFR)

(6)

0x20(0x40) UBRRH URSEL UBRR[11:8] 156

UCSRC URSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL 153

0x1F(0x3F) EEARH EEAR8 20

0x1E(0x3E) EEARL EEAR7 EEAR6 EEAR5 EEAR4 EEAR3 EEAR2 EEAR1 EEAR0 20

0x1D(0x3D) EEDR EEPROM Data Register 20

0x1C(0x3C) EECR EERIE EEMWE EEWE EERE 20

0x1B(0x3B) Reserved 0x1A(0x3A) Reserved 0x19(0x39) Reserved

0x18(0x38) PORTB PORTB7 PORTB6 PORTB5 PORTB4 PORTB3 PORTB2 PORTB1 PORTB0 65

0x17(0x37) DDRB DDB7 DDB6 DDB5 DDB4 DDB3 DDB2 DDB1 DDB0 65

0x16(0x36) PINB PINB7 PINB6 PINB5 PINB4 PINB3 PINB2 PINB1 PINB0 65

0x15(0x35) PORTC PORTC6 PORTC5 PORTC4 PORTC3 PORTC2 PORTC1 PORTC0 65

0x14(0x34) DDRC DDC6 DDC5 DDC4 DDC3 DDC2 DDC1 DDC0 65

0x13(0x33) PINC PINC6 PINC5 PINC4 PINC3 PINC2 PINC1 PINC0 65

0x12(0x32) PORTD PORTD7 PORTD6 PORTD5 PORTD4 PORTD3 PORTD2 PORTD1 PORTD0 65

0x11(0x31) DDRD DDD7 DDD6 DDD5 DDD4 DDD3 DDD2 DDD1 DDD0 65

0x10(0x30) PIND PIND7 PIND6 PIND5 PIND4 PIND3 PIND2 PIND1 PIND0 65

0x0F(0x2F) SPDR SPI Data Register 131

0x0E(0x2E) SPSR SPIF WCOL SPI2X 131

0x0D(0x2D) SPCR SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0 129

0x0C(0x2C) UDR USART I/O Data Register 153

0x0B(0x2B) UCSRA RXC TXC UDRE FE DOR PE U2X MPCM 154

0x0A(0x2A) UCSRB RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RXB8 TXB8 155

0x09(0x29) UBRRL USART Baud Rate Register Low byte 158

0x08(0x28) ACSR ACD ACBG ACO ACI ACIE ACIC ACIS1 ACIS0 194

0x07(0x27) ADMUX REFS1 REFS0 ADLAR MUX3 MUX2 MUX1 MUX0 205

0x06(0x26) ADCSRA ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0 207

0x05(0x25) ADCH ADC Data Register High byte 208

0x04(0x24) ADCL ADC Data Register Low byte 208

0x03(0x23) TWDR Two-wire Serial Interface Data Register 173

0x02(0x22) TWAR TWA6 TWA5 TWA4 TWA3 TWA2 TWA1 TWA0 TWGCE 17

0x01(0x21) TWSR TWS7 TWS6 TWS5 TWS4 TWS3 TWPS1 TWPS0 170

0x00(0x20) TWBR TWBRTwo-wire Serial Interface Bit Rate Register 171

0x20(0x40) UBRRH URSEL UBRR[11:8] 156

UCSRC URSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL 153

0x1F(0x3F) EEARH EEAR8 20

0x1E(0x3E) EEARL EEAR7 EEAR6 EEAR5 EEAR4 EEAR3 EEAR2 EEAR1 EEAR0 20

0x1D(0x3D) EEDR EEPROM Data Register 20

0x1C(0x3C) EECR EERIE EEMWE EEWE EERE 20

0x1B(0x3B) Reserved 0x1A(0x3A) Reserved 0x19(0x39) Reserved

0x18(0x38) PORTB PORTB7 PORTB6 PORTB5 PORTB4 PORTB3 PORTB2 PORTB1 PORTB0 65

0x17(0x37) DDRB DDB7 DDB6 DDB5 DDB4 DDB3 DDB2 DDB1 DDB0 65

0x16(0x36) PINB PINB7 PINB6 PINB5 PINB4 PINB3 PINB2 PINB1 PINB0 65

0x15(0x35) PORTC PORTC6 PORTC5 PORTC4 PORTC3 PORTC2 PORTC1 PORTC0 65

0x14(0x34) DDRC DDC6 DDC5 DDC4 DDC3 DDC2 DDC1 DDC0 65

0x13(0x33) PINC PINC6 PINC5 PINC4 PINC3 PINC2 PINC1 PINC0 65

0x12(0x32) PORTD PORTD7 PORTD6 PORTD5 PORTD4 PORTD3 PORTD2 PORTD1 PORTD0 65

0x11(0x31) DDRD DDD7 DDD6 DDD5 DDD4 DDD3 DDD2 DDD1 DDD0 65

0x10(0x30) PIND PIND7 PIND6 PIND5 PIND4 PIND3 PIND2 PIND1 PIND0 65

0x0F(0x2F) SPDR SPI Data Register 131

0x0E(0x2E) SPSR SPIF WCOL SPI2X 131

0x0D(0x2D) SPCR SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0 129

0x0C(0x2C) UDR USART I/O Data Register 153

0x0B(0x2B) UCSRA RXC TXC UDRE FE DOR PE U2X MPCM 154

0x0A(0x2A) UCSRB RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RXB8 TXB8 155

0x09(0x29) UBRRL USART Baud Rate Register Low byte 158

0x08(0x28) ACSR ACD ACBG ACO ACI ACIE ACIC ACIS1 ACIS0 194

0x07(0x27) ADMUX REFS1 REFS0 ADLAR MUX3 MUX2 MUX1 MUX0 205

0x06(0x26) ADCSRA ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0 207

0x05(0x25) ADCH ADC Data Register High byte 208

0x04(0x24) ADCL ADC Data Register Low byte 208

0x03(0x23) TWDR Two-wire Serial Interface Data Register 173

0x02(0x22) TWAR TWA6 TWA5 TWA4 TWA3 TWA2 TWA1 TWA0 TWGCE 17

0x01(0x21) TWSR TWS7 TWS6 TWS5 TWS4 TWS3 TWPS1 TWPS0 170

0x00(0x20) TWBR TWBRTwo-wire Serial Interface Bit Rate Register 171

6

(7)

7

sts statt out

// aus Blink/main.S loop:

eor mp,mp inc mp

// Store statt out scheint zu funktionieren // out PORTB,mp

sts 0x38,mp

rcall waitabit rcall waitabit

// Store statt out scheint zu funktionieren // out PORTB,r19

sts 0x38,r19

rcall waitabit lsl mp

// aus Blink/main.S loop:

eor mp,mp inc mp

// Store statt out scheint zu funktionieren // out PORTB,mp

sts 0x38,mp

rcall waitabit rcall waitabit

// Store statt out scheint zu funktionieren // out PORTB,r19

sts 0x38,r19

rcall waitabit lsl mp

Store Direct To Sram An Stelle von

out

(8)

8

Die Arbeitsregister

(general purpose Register)

Adresse Reg Bemerkungen

0x0 R0

0x1 R1

… …

0xD R13

0xE R14

0xF R15

0x10 R16

ohne Einschränku 0x11 R17

… …

0x1A R26 X LowByte

16-Bit Adressreg.

0x1B R27 X HighByte 0x1C R28 Y LowByte

16-Bit Adressreg.

0x1D R29 Y HighByte 0x1E R31 Z LowByte

16-Bit Adressreg.

0x1F R31 Z HighByte

keine Literale Erlaubt

Adressregister für SRAM

Adresse Reg Bemerkungen

0x0 R0

0x1 R1

… …

0xD R13

0xE R14

0xF R15

0x10 R16

ohne Einschränku 0x11 R17

… …

0x1A R26 X LowByte

16-Bit Adressreg.

0x1B R27 X HighByte 0x1C R28 Y LowByte

16-Bit Adressreg.

0x1D R29 Y HighByte 0x1E R31 Z LowByte

16-Bit Adressreg.

0x1F R31 Z HighByte

keine Literale Erlaubt

Adressregister

für SRAM

(9)

9

Befehle, für R0 ..R15 nicht erlaubt

LDI Rx,K ; load immideate

ANDI Rx,K ; bitwise AND imm.

SER Rx ; Set all Bits to 1 CBR Rx,M ; clear maskbits

SBR Rx,M ; set maskbits CPI Rx,K ; compare imm.

SUBI Rx,K ; Subtract imm.

SBCI Rx,K ; Subtract imm. carry LDI Rx,K ; load immideate

ANDI Rx,K ; bitwise AND imm.

SER Rx ; Set all Bits to 1 CBR Rx,M ; clear maskbits

SBR Rx,M ; set maskbits CPI Rx,K ; compare imm.

SUBI Rx,K ; Subtract imm.

SBCI Rx,K ; Subtract imm. carry

(10)

10

Programmspeicher

Flash

Wortweise organisiert

Befehle sind 16/32 bit groß

8 kByte bei ATmega8

128 kByte bei ATmega128

Beinhaltet ggf. Bootloader am oberen Ende

Konstanten (Zeichenketten, KonstantenArrays) können direkt aus dem Flash veratbeitet wertden.

Spezielle Adressierungsmodi über Z-(R30/R31) -Regis- ter

Spezielle C-Standardfunktionen / Macros verwenden

Flash

Wortweise organisiert

Befehle sind 16/32 bit groß

8 kByte bei ATmega8

128 kByte bei ATmega128

Beinhaltet ggf. Bootloader am oberen Ende

Konstanten (Zeichenketten, KonstantenArrays) können direkt aus dem Flash veratbeitet wertden.

Spezielle Adressierungsmodi über Z-(R30/R31) -Regis- ter

Spezielle C-Standardfunktionen / Macros verwenden

(11)

11

Das leere Programm - was will es uns sagen?

#include <avr/io.h>

char * GloblText="Goethes Faust";

int main(){

while (1);

return 0;

}

#include <avr/io.h>

char * GloblText="Goethes Faust";

int main(){

while (1);

return 0;

} Seine Geheimnisse entlocken wir ihm mit

avr-objdump -D main.elf > main.dump

(12)

12

main.elf: file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:

0: 12 c0 rjmp.+36 ; 0x26 <__ctors_end>

2: 2c c0 rjmp.+88 ; 0x5c <__bad_interrupt>

4: 2b c0 rjmp.+86 ; 0x5c <__bad_interrupt>

6: 2a c0 rjmp.+84 ; 0x5c <__bad_interrupt>

8: 29 c0 rjmp.+82 ; 0x5c <__bad_interrupt>

a: 28 c0 rjmp.+80 ; 0x5c <__bad_interrupt>

c: 27 c0 rjmp.+78 ; 0x5c <__bad_interrupt>

e: 26 c0 rjmp.+76 ; 0x5c <__bad_interrupt>

10:25 c0 rjmp.+74 ; 0x5c <__bad_interrupt>

12:24 c0 rjmp.+72 ; 0x5c <__bad_interrupt>

14:23 c0 rjmp.+70 ; 0x5c <__bad_interrupt>

16:22 c0 rjmp.+68 ; 0x5c <__bad_interrupt>

18:21 c0 rjmp.+66 ; 0x5c <__bad_interrupt>

1a:20 c0 rjmp.+64 ; 0x5c <__bad_interrupt>

1c:1f c0 rjmp.+62 ; 0x5c <__bad_interrupt>

1e:1e c0 rjmp.+60 ; 0x5c <__bad_interrupt>

20:1d c0 rjmp.+58 ; 0x5c <__bad_interrupt>

22:1c c0 rjmp.+56 ; 0x5c <__bad_interrupt>

24:1b c0 rjmp.+54 ; 0x5c <__bad_interrupt>

main.elf: file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:

0: 12 c0 rjmp.+36 ; 0x26 <__ctors_end>

2: 2c c0 rjmp.+88 ; 0x5c <__bad_interrupt>

4: 2b c0 rjmp.+86 ; 0x5c <__bad_interrupt>

6: 2a c0 rjmp.+84 ; 0x5c <__bad_interrupt>

8: 29 c0 rjmp.+82 ; 0x5c <__bad_interrupt>

a: 28 c0 rjmp.+80 ; 0x5c <__bad_interrupt>

c: 27 c0 rjmp.+78 ; 0x5c <__bad_interrupt>

e: 26 c0 rjmp.+76 ; 0x5c <__bad_interrupt>

10:25 c0 rjmp.+74 ; 0x5c <__bad_interrupt>

12:24 c0 rjmp.+72 ; 0x5c <__bad_interrupt>

14:23 c0 rjmp.+70 ; 0x5c <__bad_interrupt>

16:22 c0 rjmp.+68 ; 0x5c <__bad_interrupt>

18:21 c0 rjmp.+66 ; 0x5c <__bad_interrupt>

1a:20 c0 rjmp.+64 ; 0x5c <__bad_interrupt>

1c:1f c0 rjmp.+62 ; 0x5c <__bad_interrupt>

1e:1e c0 rjmp.+60 ; 0x5c <__bad_interrupt>

20:1d c0 rjmp.+58 ; 0x5c <__bad_interrupt>

22:1c c0 rjmp.+56 ; 0x5c <__bad_interrupt>

24:1b c0 rjmp.+54 ; 0x5c <__bad_interrupt>

Die Interruptvektor- tabelle

Start des

Programms

(13)

13

00000026 <__ctors_end>:

26:11 24 eor r1, r1

28:1f be out 0x3f, r1 ; 63 2a:cf e5 ldi r28, 0x5F ; 95 2c:d4 e0 ldi r29, 0x04 ; 4 2e:de bf out 0x3e, r29 ; 62 30:cd bf out 0x3d, r28 ; 61 00000032 <__do_copy_data>:

32:10 e0 ldi r17, 0x00 ; 0 34:a0 e6 ldi r26, 0x60 ; 96 36:b0 e0 ldi r27, 0x00 ; 0 38:e2 e6 ldi r30, 0x62 ; 98 3a:f0 e0 ldi r31, 0x00 ; 0

3c:02 c0 rjmp.+4 ; 0x42 <.do_copy_data_start>

0000003e <.do_copy_data_loop>:

3e:05 90 lpm r0, Z+

40:0d 92 st X+, r0

00000042 <.do_copy_data_start>:

42:a0 37 cpi r26, 0x70 ; 112 44:b1 07 cpc r27, r17

46:d9 f7 brne .-10 ; 0x3e <.do_copy_data_loop>

00000026 <__ctors_end>:

26:11 24 eor r1, r1

28:1f be out 0x3f, r1 ; 63 2a:cf e5 ldi r28, 0x5F ; 95 2c:d4 e0 ldi r29, 0x04 ; 4 2e:de bf out 0x3e, r29 ; 62 30:cd bf out 0x3d, r28 ; 61 00000032 <__do_copy_data>:

32:10 e0 ldi r17, 0x00 ; 0 34:a0 e6 ldi r26, 0x60 ; 96 36:b0 e0 ldi r27, 0x00 ; 0 38:e2 e6 ldi r30, 0x62 ; 98 3a:f0 e0 ldi r31, 0x00 ; 0

3c:02 c0 rjmp.+4 ; 0x42 <.do_copy_data_start>

0000003e <.do_copy_data_loop>:

3e:05 90 lpm r0, Z+

40:0d 92 st X+, r0

00000042 <.do_copy_data_start>:

42:a0 37 cpi r26, 0x70 ; 112 44:b1 07 cpc r27, r17

46:d9 f7 brne .-10 ; 0x3e <.do_copy_data_loop>

Flags löschen

Stackpointer auf Ramende setzen

Kopieren des Daten-

segmentes in den SRAM X(R26,R27)=Ziel im SRAM Z(R30,R31)=Source im Flash

R0:=[Z]

[x]:=R0

Test auf Ende

(0x70)

(14)

14

00000048 <__do_clear_bss>:

48:10 e0 ldi r17, 0x00 ; 0 4a:a0 e7 ldi r26, 0x70 ; 112 4c:b0 e0 ldi r27, 0x00 ; 0

4e:01 c0 rjmp.+2 ; 0x52 <.do_clear_bss_start>

00000050 <.do_clear_bss_loop>:

50:1d 92 st X+, r1

00000052 <.do_clear_bss_start>:

52:a0 37 cpi r26, 0x70 ; 112 54:b1 07 cpc r27, r17

56:e1 f7 brne .-8 ; 0x50 <.do_clear_bss_loop>

58:02 d0 rcall .+4 ; 0x5e <main>

5a:02 c0 rjmp.+4 ; 0x60 <_exit>

0000005c <__bad_interrupt>:

5c:d1 cf rjmp.-94 ; 0x0 <__vectors>

0000005e <main>:

5e:ff cf rjmp.-2 ; 0x5e <main>

00000060 <_exit>:

60:ff cf rjmp.-2 ; 0x60 <_exit>

00000048 <__do_clear_bss>:

48:10 e0 ldi r17, 0x00 ; 0 4a:a0 e7 ldi r26, 0x70 ; 112 4c:b0 e0 ldi r27, 0x00 ; 0

4e:01 c0 rjmp.+2 ; 0x52 <.do_clear_bss_start>

00000050 <.do_clear_bss_loop>:

50:1d 92 st X+, r1

00000052 <.do_clear_bss_start>:

52:a0 37 cpi r26, 0x70 ; 112 54:b1 07 cpc r27, r17

56:e1 f7 brne .-8 ; 0x50 <.do_clear_bss_loop>

58:02 d0 rcall .+4 ; 0x5e <main>

5a:02 c0 rjmp.+4 ; 0x60 <_exit>

0000005c <__bad_interrupt>:

5c:d1 cf rjmp.-94 ; 0x0 <__vectors>

0000005e <main>:

5e:ff cf rjmp.-2 ; 0x5e <main>

00000060 <_exit>:

60:ff cf rjmp.-2 ; 0x60 <_exit>

Löschen statischer Variablen auf 0

Interruptroutinen

main

(15)

15

Disassembly of section .data:

00800060 <__data_start>:

800060: 47 6f ori r20, 0xF7 ; 247 800062: 65 74 andir22, 0x45 ; 69 800064: 68 65 ori r22, 0x58 ; 88 800066: 73 20 and r7, r3

800068: 46 61 ori r20, 0x16 ; 22 80006a: 75 73 andir23, 0x35 ; 53 80006c: 74 00 .word 0x0074 ; ????

0080006e <GloblText>:

80006e: 60 00 .word 0x0060 ; ????

Disassembly of section .stab:

00000000 <_end-0x800070>:

0: 01 00 .word 0x0001 ; ????

2: 00 00 nop 4: 00 00 nop

6: 8b 00 .word 0x008b ; ????

8: 91 07 cpc r25, r17 a: 00 00 nop

c: 01 00 .word 0x0001 ; ????

e: 00 00 nop

10:64 00 .word 0x0064 ; ????

12:00 00 nop

Disassembly of section .data:

00800060 <__data_start>:

800060: 47 6f ori r20, 0xF7 ; 247 800062: 65 74 andir22, 0x45 ; 69 800064: 68 65 ori r22, 0x58 ; 88 800066: 73 20 and r7, r3

800068: 46 61 ori r20, 0x16 ; 22 80006a: 75 73 andir23, 0x35 ; 53 80006c: 74 00 .word 0x0074 ; ????

0080006e <GloblText>:

80006e: 60 00 .word 0x0060 ; ????

Disassembly of section .stab:

00000000 <_end-0x800070>:

0: 01 00 .word 0x0001 ; ????

2: 00 00 nop 4: 00 00 nop

6: 8b 00 .word 0x008b ; ????

8: 91 07 cpc r25, r17 a: 00 00 nop

c: 01 00 .word 0x0001 ; ????

e: 00 00 nop

10:64 00 .word 0x0064 ; ????

12:00 00 nop

Das ist der Text

"Goethes Faust“

(kaum wiederzuerkennen)

Die Adresse vom Faust

.stab und .stabstr wird nicht Auf den AVR geladen

(16)

16

Interruptvectoren

Initialisierung der Flags und des Stackpointers

(Flags Port 0x3F, Stackpointer Port 0x3E,0x3D)

Kopieren initialisierter statischer Daten Flash → SRAM

Löschen nicht initialisierter statischer Daten

Interruptroutinen Programm

Interruptvectoren

Initialisierung der Flags und des Stackpointers

(Flags Port 0x3F, Stackpointer Port 0x3E,0x3D)

Kopieren initialisierter statischer Daten Flash → SRAM

Löschen nicht initialisierter statischer Daten

Interruptroutinen Programm

Segment Inhalt

.text Programm

.data Statische

initialisierte Daten

.bss Nicht

initialisierte statische Daten

.eeprom Daten im

eeprom

Segment Inhalt

.text Programm

.data Statische

initialisierte Daten

.bss Nicht

initialisierte statische Daten

.eeprom Daten im

eeprom

(17)

17

Aufbau des SRam zur Laufzeit

0x0000 Register 0x0020 Ports 0x0060

0x045F

initialisierte

statische Daten nicht

initialisierte

statische Daten Heap ↓

Stack ↑ 0x0000 Register 0x0020 Ports 0x0060

0x045F

initialisierte

statische Daten nicht

initialisierte

statische Daten Heap ↓

Stack ↑

(18)

18

PROGMEM

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Um wertvollen Platz im SRAM zu sparen, können konstante Werte, wie Strings direkt aus dem Programmspeicher ver- arbeitet werden.

Vereinbarung erfordert das Attribut PROGMEM Beispiel:

#include <avr/progmem.h>

static const char pgmTestStringLocal[] PROGMEM = "im Flash";

Daten müssen extern/global und mit dem Attribut const ver- sehen sein.

Zur Verwendung dieser Daten sind spezielle Funktionen notwendig

Daten können nur lesend verarbeitet werden

Um wertvollen Platz im SRAM zu sparen, können konstante Werte, wie Strings direkt aus dem Programmspeicher ver- arbeitet werden.

Vereinbarung erfordert das Attribut PROGMEM Beispiel:

#include <avr/progmem.h>

static const char pgmTestStringLocal[] PROGMEM = "im Flash";

Daten müssen extern/global und mit dem Attribut const ver- sehen sein.

Zur Verwendung dieser Daten sind spezielle Funktionen notwendig

Daten können nur lesend verarbeitet werden

(19)

19

Datenvereinbarung im ProgMem

http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

Typedefs für

Standarddatentypen im Progmem

prog_void prog_char prog_uchar prog_int8_t prog_uint8_t prog_int16_t prog_uint16_t prog_int32_t prog_uint32_t Allgemein gilt:

const int myi PROGMEM=67;

#include <avr/pgmspace.h>

. . .

const unsigned char mydata[11][10] PROGMEM = {

{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09}, {0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13}, . . .

{0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59}, {0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,0x62,0x63}, {0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D}

};

#define PGM_P const prog_char *

#define PGM_VOID_P const prog_void * Literale können wie folgt vereinbart werden:

const char *ps1 = PSTR("String from:\n");

(20)

20

Hammingcode

const uint8_t hamminge[16 ]={

0x15,0x02,0x49,0x5E,0x64,0x73,0x38,0x2F,0xD0,0xC7,0x8C,0x9B,0xA1,0xB6,0xFD,0xEA};

const uint8_t hammingd[256]/*PROGMEM*/={

/*0*/ 0x01,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x02,0x02,0x01,0x03,0x0A,0x02,0x03,0x07, /*1*/ 0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x06,0x02,0x03,0x0B,0x02,0x00,0x03,0x03, /*2*/ 0x04,0x0C,0x01,0x05,0x04,0x04,0x05,0x07,0x06,0x06,0x07,0x07,0x06,0x07,0x07,0x07, /*3*/ 0x06,0x04,0x05,0x05,0x04,0x00,0x0D,0x05,0x06,0x06,0x06,0x07,0x06,0x06,0x07,0x07, /*4*/ 0x00,0x02,0x01,0x01,0x04,0x00,0x01,0x09,0x02,0x02,0x03,0x02,0x02,0x02,0x03,0x03, /*5*/ 0x08,0x00,0x01,0x05,0x00,0x00,0x03,0x01,0x02,0x02,0x03,0x03,0x03,0x02,0x03,0x03, /*6*/ 0x04,0x04,0x05,0x05,0x04,0x04,0x04,0x05,0x06,0x02,0x0F,0x07,0x04,0x06,0x07,0x07, /*7*/ 0x04,0x05,0x05,0x05,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x05,0x06,0x0E,0x03,0x07, /*8*/ 0x08,0x0C,0x01,0x09,0x0A,0x08,0x09,0x09,0x0A,0x0A,0x0B,0x0B,0x0A,0x0A,0x0A,0x0B, /*9*/ 0x08,0x08,0x09,0x0B,0x08,0x00,0x0D,0x09,0x0A,0x0B,0x0B,0x0B,0x0A,0x0A,0x0B,0x0B, /*A*/ 0x0C,0x0C,0x0D,0x0C,0x0C,0x0C,0x0D,0x0D,0x0E,0x0C,0x0F,0x0F,0x0A,0x0E,0x0F,0x07, /*B*/ 0x0C,0x0C,0x0D,0x0D,0x0D,0x0C,0x0D,0x0D,0x06,0x0E,0x0F,0x0B,0x0E,0x0E,0x0D,0x0F, /*C*/ 0x08,0x08,0x09,0x09,0x08,0x09,0x09,0x09,0x0A,0x02,0x0F,0x0B,0x0A,0x0A,0x0B,0x09, /*D*/ 0x08,0x08,0x08,0x09,0x08,0x08,0x09,0x09,0x08,0x0A,0x0B,0x0B,0x0A,0x0E,0x03,0x0B, /*E*/ 0x0C,0x0C,0x0F,0x0D,0x04,0x0C,0x0D,0x09,0x0F,0x0E,0x0F,0x0F,0x0E,0x0E,0x0F,0x0F, /*F*/ 0x08,0x0C,0x0D,0x05,0x0C,0x0E,0x0D,0x0D,0x0E,0x0E,0x0F,0x0F,0x0E,0x0E,0x0F,0x0E};

//---

Im SRAM

Im Progmem (Flash)

(21)

21

const char strings[][9] PROGMEM=

{

"Zeile 1\n", "Zeile 2\n", "Zeile 3\n", "Zeile 4\n", "Zeile 5\n"

};

const char string1 []PROGMEM= "Zeile 1\n";

const char string2 []PROGMEM= "Zeile 2\n";

const char string3 []PROGMEM= "Zeile 3\n";

const char string4 []PROGMEM= "Zeile 4\n";

const char string5 []PROGMEM= "Zeile 5\n";

PGM_P strings [] PROGMEM=

{

string1,string2,string3,string4,string5 };

const char *str[] PROGMEM = {

"String 1", "String 2", "String 3", "String 4", "String 5"

};

WRONG !!!

(22)

22

Macros zum Lesen aus Progmem

#include <avr/pgmspace.h>

pgm_read_byte(address_short)

pgm_read_word(address_short)

pgm_read_dword(address_short)

Die Varianten near und far sind nur für atmega128 relevant.

far erfordert die Verwendung einer 32 bit Adresse, wenn die Daten in den oberen 64 kByte liegen

#include <avr/pgmspace.h>

pgm_read_byte(address_short)

pgm_read_word(address_short)

pgm_read_dword(address_short)

Die Varianten near und far sind nur für atmega128 relevant.

far erfordert die Verwendung einer 32 bit

Adresse, wenn die Daten in den oberen 64

kByte liegen

(23)

23

extern PGM_VOID_P memchr_P (PGM_VOID_P s, int val, size_t len);

extern int memcmp_P (const void *, PGM_VOID_P, size_t);

extern void * memcpy_P (void *, PGM_VOID_P, size_t);

extern void * memmem_P (const void *, size_t, PGM_VOID_P, size_t);

extern PGM_VOID_P memrchr_P (PGM_VOID_P s, int val, size_t len);

extern char * strcat_P (char *, PGM_P);

extern PGM_P strchr_P (PGM_P s, int val);

extern PGM_P strchrnul_P (PGM_P s, int val);

extern int strcmp_P (const char *, PGM_P) ; extern char * strcpy_P (char *, PGM_P);

extern int strcasecmp_P(const char *, PGM_P) ; extern char * strcasestr_P (const char *, PGM_P);

extern size_t strcspn_P (const char *s, PGM_P reject) ; extern size_t strlcat_P (char *, PGM_P, size_t );

extern size_t strlcpy_P (char *, PGM_P, size_t );

extern size_t strlen_P (PGM_P);

extern size_t strnlen_P (PGM_P, size_t);

extern int strncmp_P (const char *, PGM_P, size_t) ; extern int strncasecmp_P(const char *, PGM_P, size_t) ; extern char * strncat_P (char *, PGM_P, size_t);

extern char * strncpy_P (char *, PGM_P, size_t);

extern char * strpbrk_P (const char *s, PGM_P accept) ; extern PGM_P strrchr_P (PGM_P s, int val) ;

extern char * strsep_P (char **sp, PGM_P delim);

extern size_t strspn_P (const char *s, PGM_P accept) ; extern char * strstr_P (const char *, PGM_P) ;

extern PGM_VOID_P memchr_P (PGM_VOID_P s, int val, size_t len);

extern int memcmp_P (const void *, PGM_VOID_P, size_t);

extern void * memcpy_P (void *, PGM_VOID_P, size_t);

extern void * memmem_P (const void *, size_t, PGM_VOID_P, size_t);

extern PGM_VOID_P memrchr_P (PGM_VOID_P s, int val, size_t len);

extern char * strcat_P (char *, PGM_P);

extern PGM_P strchr_P (PGM_P s, int val);

extern PGM_P strchrnul_P (PGM_P s, int val);

extern int strcmp_P (const char *, PGM_P) ; extern char * strcpy_P (char *, PGM_P);

extern int strcasecmp_P(const char *, PGM_P) ; extern char * strcasestr_P (const char *, PGM_P);

extern size_t strcspn_P (const char *s, PGM_P reject) ; extern size_t strlcat_P (char *, PGM_P, size_t );

extern size_t strlcpy_P (char *, PGM_P, size_t );

extern size_t strlen_P (PGM_P);

extern size_t strnlen_P (PGM_P, size_t);

extern int strncmp_P (const char *, PGM_P, size_t) ; extern int strncasecmp_P(const char *, PGM_P, size_t) ; extern char * strncat_P (char *, PGM_P, size_t);

extern char * strncpy_P (char *, PGM_P, size_t);

extern char * strpbrk_P (const char *s, PGM_P accept) ; extern PGM_P strrchr_P (PGM_P s, int val) ;

extern char * strsep_P (char **sp, PGM_P delim);

extern size_t strspn_P (const char *s, PGM_P accept) ; extern char * strstr_P (const char *, PGM_P) ;

S pe zi el le F un kt io ne n fü r P ro gm em

(24)

24

Zugang zu Daten aus Flash mit Assembler

.text

message2: .asciz "J.W.v. Goethe"; Daten im Flash main:

Ldi R31,hi8(message2); Adresse im Ldi r30,lo8(message2); Flash

L1: lpm r0,z+ ; [z++]-> r0

or r0,r0 ; if r0==0

Breq out ; then → out

Mov r24,r0 ;

rcall lcd_putc ; call lcd_putc(r0)

rjmp L1 ; loop

Out: ; go away

.text

message2: .asciz "J.W.v. Goethe"; Daten im Flash main:

Ldi R31,hi8(message2); Adresse im Ldi r30,lo8(message2); Flash

L1: lpm r0,z+ ; [z++]-> r0

or r0,r0 ; if r0==0

Breq out ; then → out

Mov r24,r0 ;

rcall lcd_putc ; call lcd_putc(r0)

rjmp L1 ; loop

Out: ; go away

(25)

25

EEPROM

EEMEM const char ee_str[] =

"This string from\n ** EEPROM **";

Wird abgelegt im Segment .eeprom

avr-objdump -D main.elf > main.dump liefert detaillierte Informationen

char* eeprom_s=(char*) ee_str;

while((c = eeprom_read_byte((BYTE*) eeprom_s++))){ ...}

EEMEM const char ee_str[] =

"This string from\n ** EEPROM **";

Wird abgelegt im Segment .eeprom

avr-objdump -D main.elf > main.dump liefert detaillierte Informationen

char* eeprom_s=(char*) ee_str;

while((c = eeprom_read_byte((BYTE*) eeprom_s++))){ ...}

(26)

26

uint8_t eeprom_read_byte (const uint8_t *addr);

uint16_t eeprom_read_word (const uint16_t *addr);

Void eeprom_read_block (void *pointer_ram,

const void *pointer_eeprom, size_t size);

void eeprom_write_byte (uint8_t *addr,uint8_t value);

void eeprom_write_word (uint16_t *addr,uint16_t value);

void eeprom_write_block (const void *pointer_ram, void *pointer_eeprom,

size_t size);

uint8_t eeprom_read_byte (const uint8_t *addr);

uint16_t eeprom_read_word (const uint16_t *addr);

Void eeprom_read_block (void *pointer_ram,

const void *pointer_eeprom, size_t size);

void eeprom_write_byte (uint8_t *addr,uint8_t value);

void eeprom_write_word (uint16_t *addr,uint16_t value);

void eeprom_write_block (const void *pointer_ram, void *pointer_eeprom,

size_t size);

Funktionen zur Arbeit mit dem internen EEPROM

(vereinfacht aus avr/eeprom.h)

(27)

27

EEPROM mit assembler (write)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Daten aus Flash -> eeprom

Ldi r26,lo8(message3) ; Adresse im EEPROM ldi r27,hi8(message3)

ldi R31,hi8(message4) ; Adresse im FLASH ldi r30,lo8(message4)

lwre1: lpm r0,z+ ; [Z++]-> r0

; Warten, bis vorheriges Schreiben abgeschlossen

lwre3: sbic EECR,EEWE ; skip next, if bit in PORT is clear rjmp lwre3

out EEARH, r27 ; EEPROM-Addresse (r26:r27)

out EEARL, r26; ; in EEPROM-Adressregister eintragen out EEDR,r0 ; Write data (r0) to data register

sbi EECR,EEMWE ; Write logical one to EEMWE

; nach max. 4 Takten:

sbi EECR,EEWE ; Start eeprom write by setting EEWE

adiw r26,1 ; inc EEPROM-Addresse

or r0,r0 ; 0 Byte?

breq lwre2 ; → fertig !

rjmp lwre1 ; naechstes Byte

Lwre2:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Daten aus Flash -> eeprom

Ldi r26,lo8(message3) ; Adresse im EEPROM ldi r27,hi8(message3)

ldi R31,hi8(message4) ; Adresse im FLASH ldi r30,lo8(message4)

lwre1: lpm r0,z+ ; [Z++]-> r0

; Warten, bis vorheriges Schreiben abgeschlossen

lwre3: sbic EECR,EEWE ; skip next, if bit in PORT is clear rjmp lwre3

out EEARH, r27 ; EEPROM-Addresse (r26:r27)

out EEARL, r26; ; in EEPROM-Adressregister eintragen out EEDR,r0 ; Write data (r0) to data register

sbi EECR,EEMWE ; Write logical one to EEMWE

; nach max. 4 Takten:

sbi EECR,EEWE ; Start eeprom write by setting EEWE

adiw r26,1 ; inc EEPROM-Addresse

or r0,r0 ; 0 Byte?

breq lwre2 ; → fertig !

rjmp lwre1 ; naechstes Byte

Lwre2:

. . .

EEPROM

Master Write enable

(28)

28

EEPROM mit assembler (read)

; Daten aus EEPROM-> Display

; ldi r16,6

ldi r26,lo8(message3) ;Adresse im EEPROM ldi r27,hi8(message3)

eep1: sbic EECR, EEWE ; Warten auf Bereit (EEWE=0) rjmp eep1

out EEARH, r27 ; Adresse ins EEPROM Adressreg.

out EEARL, r26

sbi EECR, EERE ; Read Enable

adiw r26, 0x01 ; EEPROM-Adresse ++

in r24, EEDR ; EEPROM Datenreg. lesen

or r24,r24 ; 0-Byte?

; subi r16,1 ; Test mit Zählschleife mit R16 breq eep2 ; 0: Ende, fertig

rcall lcd_putc ; Ausgabe auf LCD-Display

rjmp eep1 ; und von vorn

; Daten aus EEPROM-> Display

; ldi r16,6

ldi r26,lo8(message3) ;Adresse im EEPROM ldi r27,hi8(message3)

eep1: sbic EECR, EEWE ; Warten auf Bereit (EEWE=0) rjmp eep1

out EEARH, r27 ; Adresse ins EEPROM Adressreg.

out EEARL, r26

sbi EECR, EERE ; Read Enable

adiw r26, 0x01 ; EEPROM-Adresse ++

in r24, EEDR ; EEPROM Datenreg. lesen

or r24,r24 ; 0-Byte?

; subi r16,1 ; Test mit Zählschleife mit R16

breq eep2 ; 0: Ende, fertig

rcall lcd_putc ; Ausgabe auf LCD-Display

rjmp eep1 ; und von vorn

Referenzen

ÄHNLICHE DOKUMENTE

Juni 2018 gab es fünf von der Zentralbank genehmigte Teilfonds der Gesellschaft: Der Tokio Marine Japanese Equity Focus Fund ist bei der FINMA zum Vertrieb an

Idee: sch¨atze Kosten f¨ur eine Gesamtl¨osung nach oben hin ab hier z.B.:. k = Summe aller Distanzen zwischen eigenen W¨urmern und Loch ·(1 + ²) betrachte nicht solche Z¨uge, die

Von den Aufnahmegeräten werden die digitalen Bilder direkt über das Hochgeschwindig- keitsnetzwerk des Klinikums zum zen- tralen Datenspeicher transportiert und dort im PACS

Alle eingesetzten elektronischen Mengenumwerter mit integriertem Datenspeicher und alle Zusatzeinrichtungen zum Einsatz in Messanlagen für Erdgas müssen in ihrer technischen

Diese Leitfähigkeit lässt sich, wenn sie einmal erreicht ist, auch durch eine Änderung der Spannung nicht mehr rückgängig machen – einmal eingeschaltet, bleibt das

Wenn dies nicht der Fall ist, können bei der Installation der Datenspeicher auf dem Host Probleme auftreten. Um dies zu überprüfen, führen Sie SSH an einen Host aus, auf dem

Datenbanksystems Data-Dictionary eines Werkzeuges für strukturierte Analyse mit Einträgen für alle Datenflüsse und Datenspeicher.

Alle eingesetzten elektronischen Mengenumwerter mit integriertem Datenspeicher und alle Zusatzeinrichtungen zum Einsatz in Messanlagen für Erdgas müssen in ihrer technischen