Upload
nguyenthu
View
219
Download
0
Embed Size (px)
Citation preview
Techniki mikroprocesorowe
Języki programowania
• Mikrokontrolery AVR ze względu na swoją popularność doczekały się implementacji kompilatorów dla znacznej części dostępnych języków programowania
• Najpopularniejsze w chwili obecnej są assembler i C
3
Techniki mikroprocesorowe
Kompilator języka C
• Najpopularniejszy zestaw narzędzi dla języka C dla platformy AVR bazuje na porcie kompilatora gcc: avr-gcc
• Zestaw ten dla środowiska Windows nasi nazwę WinAVR
http://winavr.sourceforge.net/
4
Techniki mikroprocesorowe
WinAVR
• W skład pakietu WinAVR wchodzą następujące elementy – Kompilator C/C++ (avr-gcc, avr-g++)
– Zestaw plików nagłówkowych dla wszystkich mikrokontrolerów AVR
– Program make
– Powłoka bash wraz z podstawowymi narzędziami
– Wygodny edytor Programmer’s Notepad 2 (PN2)
– Program avrdude do programowania pamięci mikrokontrolerów AVR
5
Techniki mikroprocesorowe
Programmer’s Notepad 2
• Jest to darmowy prosty edytor dla programistów, z obsługą projektów, kolorowaniem składni wielu języków oraz możliwością korzystania z kompilatora i programatora z poziomu edytora
http://www.pnotepad.org/
6
Techniki mikroprocesorowe
Atmel Studio 6
• Jest to darmowe zintegrowane środowisko programistyczne, rozwijane przez firmę Atmel, producenta mikrokontrolerów AVR
• Umożliwia pisanie programów dla architektura AVR i ARM w assemblerze oraz C/C++
• Bazuje na MS Visual Studio, zintegrowanym z avr-gcc i arm-gcc
8
Atmel Studio 6
Techniki mikroprocesorowe
• Środowisko wspiera kilka typów programatorów oraz mechanizmy ułatwiające debugowanie
http://www.atmel.com/microsite/atmel_studio6/
9
Techniki mikroprocesorowe
Etapy
• Utworzenie w PN2 nowego projektu
• Skopiowanie do katalogu projektu generycznego pliku Makefile, który można znaleźć w katalogu domowym WinAVR (podkatalog sample)
• Dodanie plik Makefile do projektu w PN2
• Konfiguracja pliku Makefile
12
Techniki mikroprocesorowe
Etapy
• Utworzenie jednego lub kilku plików z kodem źródłowym
• Dodanie informacji o plikach źródłowych do Makefile
• Kompilacja z poziomu PN2
• Programowanie mikrokontrolera AVR z poziomu PN2
13
Techniki mikroprocesorowe
Konfiguracja pliku Makefile
• W domyślnym pliku Makefile zmiany wymagają następujące elementy
– Model mikrokontrolera i częstotliwość zegara taktującego
– Lista plików z kodem źródłowym do kompilacji
– Flagi kompilatorów (opcjonalnie)
– Konfiguracja programatora (opcjonalnie)
14
Techniki mikroprocesorowe
Makefile - konfiguracja
• Zmiany w domyślnym pliku Makefile
MCU = atmega32 #model mikrokontrolera F_CPU = 11059200 #częstotliwość zegara w Hz TARGET = main #prefix plików wynikowych
SRC = $(TARGET).c #lista plików źródłowych C CPPSRC = … #lista plików źródłowych C++ ASRC = … #lista plików źródłowych assemblera
15
Techniki mikroprocesorowe
Makefile – konfiguracja
• Flagi optymalizacji
OPT = 0 #optymalizacja wyłączona
OPT = 1 #2 lub 3 – optymalizacja wydajności
OPT = s #optymalizacja rozmiaru pliku wynikowego
16
Techniki mikroprocesorowe
Makefile – flagi CFLAGS i CXXFLAGS kompilatora C/C++
-funsigned-char – używaj domyślnie „unsigned char” zamiast „char”
-funsigned-bitfields - używaj domyślnie pól bitowych bez znaku zamiast ze znakiem
-fpack-struct – umieszczaj elementy struktur bezpośrednio jeden za drugim, bez wyrównywania i powstałych w ten sposób dziur
-fshort-enums – alokuj tylko tyle miejsce dla typu enum ile mogą zająć możliwe wartości o zadeklarowanych zakresach
17
Techniki mikroprocesorowe
Makefile – flagi kompilatora C/C++
-Wstrict-prototypes – ostrzegaj, jeśli funkcja jest zadeklarowana lub zdefiniowana bez deklaracji typów argumentów
-mshort-calls – używaj funkcji rjmp/rcall (funkcje skoku o ograniczonym zakresie) dla układów z >8kB pamięci, domyślnie dla takich układów wykorzystywane są funkcje jmp/call
-fno-unit-at-a-time – opcja pozostawiona w celu zapewnienia kompatybilności
18
Techniki mikroprocesorowe
Makefile – flagi kompilatora C/C++
-Wundef – ostrzegaj, jeśli dyrektywa #if korzysta z niezadeklarowanego argumentu
-Wunreachable-code – ostrzegaj, jeśli program zawiera kod, który nigdy nie zostanie wykonany
-Wsign-compare – ostrzegaj, gdy jest porównywana zmienna ze znakiem i bez znaku
-Wall – wyświetlaj wszystkie typy ostrzeżeń podczas kompilacji
19
Techniki mikroprocesorowe
Makefile - programator
• W procesie programowania wykorzystywany jest program avrdude, obsługujący wszystkie popularne programatory dla AVR dostępne na rynku, w tym USBASP i STK500v2
• Konfiguracja polega na wybraniu modelu programatora i portu, do którego jest podłączony
20
Techniki mikroprocesorowe
Makefile - programator
#wskazanie modelu programatora
AVRDUDE_PROGRAMMER = stk500v2
#port, do którego jest podłączony programator
AVRDUDE_PORT = com1
21
Techniki mikroprocesorowe
Użyteczne komendy
• Kompilacja programu make all
• Usunięcie plików tymczasowych i wynikowych make clean
• Programowanie mikrokontrolera make program
22
Techniki mikroprocesorowe
avrdude – obsługa z konsoli
• Konfiguracja programu avrdude w pliku Makefile nie zawsze wystarcza do wykonania nietypowych operacji podczas programowania
• Niektóre przypadki, takie jak modyfikacja fusebitów jest niewygodna podczas realizacji przez Makefile i wygodniej jest wykonać niezbędne operacje z konsoli
23
Techniki mikroprocesorowe
avrdude – obsługa z konsoli
• Komenda bazowa avrdude -p atmega32 -c stk500v2 -P com1
• Odczyt pamięci EEPROM -D -U eeprom:r:"eeprom.eep":i
• Odczyt pamięci FLASH -U flash:r:"flash.hex":i
• Odczyt fusebitów -u -U lfuse:r:"fuse_lo.hex":i -U hfuse:r:"fuse_hi.hex":i
• Odczyt lockbitów -U lock:r:"fuse_lock.hex":i
24
Techniki mikroprocesorowe
avrdude – obsługa z konsoli
• Komenda bazowa avrdude -p atmega32 -c stk500v2 -P com1 -V
• Zapis pamięci EEPROM -D -U eeprom:w:"eeprom.eep":i
• Zapis pamięci FLASH -U flash:w:"flash.hex":i
• Zapis fusebitów -u -U lfuse:w:0xE1:m -U hfuse:w:0x99:m
• Zapis lockbitów -U lock:w:0x3F:m
25
Techniki mikroprocesorowe
avrdude – obsługa z konsoli
• Kasowanie pamięci mikrokontrolera avrdude -p atmega32 -c stk500v2 -P com1 -e
• Komendy z jednego slajdu mogą być ze sobą łączone
26
Techniki mikroprocesorowe
Język C dla AVR
• Konstrukcja programu w języku C dla mikrokontrolerów AVR jest bardzo podobna do programu dla PC
• W celu optymalnej i wygodnej obsługi wszystkich elementów mikrokontrolera programista ma do dyspozycji szereg makr, funkcji i typów, niespotykanych w bibliotece standardowej dla innych platform
28
Techniki mikroprocesorowe
Typy w języku C dla AVR
• Rozmiar generycznych typów zmiennych
Typ Rozmiar (bitów)
Wartość minimalna Wartość maksymalna
char 8 -128 (0) 127 (255)
signed char 8 -128 127
unsigned char 8 0 255
short int 16 -32768 32767
unsigned short int 16 0 65535
int 16 -32768 32767
unsigned int 16 0 65535
long int 32 -2^31 2^31-1
29
Techniki mikroprocesorowe
Typy w języku C dla AVR
Typ Rozmiar (bitów)
Wartość minimalna Wartość maksymalna
unsigned long int 32 0 2^32-1
long long int 64 -2^63 2^63-1
unsigned long long int
64 0 2^64-1
float 32 ±1.18·10^(-38) ±3.4·10^38
double 32 ±1.18·10^(-38) ±3.4·10^38
long double 32 ±1.18·10^(-38) ±3.4·10^38
30
Techniki mikroprocesorowe
Typy w języku C dla AVR
• Skrócone nazwy typów C dla AVR signed char int8_t
unsigned char uint8_t signed int int16_t unsigned int uint16_t signed long int int32_t unsigned long int uint32_t signed long long int int64_t unsigned long long int uint64_t
31
Techniki mikroprocesorowe
Obsługa rejestrów w języku C dla AVR
• Zastąpienie zawartości NAZWA_REJESTRU = (1 << NAZWA_BITU);
• Ustawienie bitu NAZWA_REJESTRU |= (1 << NAZWA_BITU);
• Wyczyszczenie bitu NAZWA_REJESTRU &= ~(1 << NAZWA_BITU);
• Odczyt stanu bitu wartosc_bitu = ((NAZWA_REJESTRU >>
NAZWA_BITU) & 0x1); 32
Techniki mikroprocesorowe
Obsługa rejestrów w języku C dla AVR
• Aby skonfigurować port PA0 jako wyjście: DDRA |= (1 << DDA0);
• Aby skonfigurować port PB1 jako wejście z domyślnym stanem logicznym „1”: DDRB &= ~(1 << DDB1); PORTB |= (1 << PORTB1);
• Aby ustawić na porcie PC2 logiczną „1”: PORTC |= (1 << PORTC2);
• Aby odczytać stan portu PD3: stan_pd3 = ((PIND >> PIND3) & 0x1);
33
Techniki mikroprocesorowe
Przerwania w języku C dla AVR
• Do obsługi przerwań w języku C służy makro ISR
ISR (NAZWA_WEKTORA_PRZERWANIA)
{
//obsługa przerwania
}
34
Techniki mikroprocesorowe
Przerwania w języku C dla AVR
• Alternatywnie można użyć do tego celu makra
SIGNAL (NAZWA_SYGNAŁU)
{
//obsługa przerwania
}
35
Techniki mikroprocesorowe
Przerwania – lista wektorów i sygnałów ATmega32
Opis Wektor Sygnał
External Interrupt Request 0 INT0_vect SIG_INTERRUPT0
External Interrupt Request 1 INT1_vect SIG_INTERRUPT1
External Interrupt Request 2 INT2_vect SIG_INTERRUPT2
Timer/Counter2 Compare Match TIMER2_COMP_vect SIG_OUTPUT_COMPARE2
Timer/Counter2 Overflow TIMER2_OVF_vect SIG_OVERFLOW2
Timer/Counter1 Capture Event TIMER1_CAPT_vect SIG_INPUT_CAPTURE1
Timer/Counter1 Compare Match A TIMER1_COMPA_vect SIG_OUTPUT_COMPARE1A
Timer/Counter1 Compare Match B TIMER1_COMPB_vect SIG_OUTPUT_COMPARE1B
Timer/Counter1 Overflow TIMER1_OVF_vect SIG_OVERFLOW1
Timer/Counter0 Compare Match TIMER0_COMP_vect SIG_OUTPUT_COMPARE0
Timer/Counter0 Overflow TIMER0_OVF_vect SIG_OVERFLOW0
Serial Transfer Complete SPI_STC_vect SIG_SPI 36
Techniki mikroprocesorowe
Przerwania – lista wektorów i sygnałów ATmega32
Opis Wektor Sygnał
USART, Rx Complete USART_RXC_vect SIG_USART_RECV SIG_UART_RECV
USART Data Register Empty USART_UDRE_vect SIG_USART_DATA SIG_UART_DATA
USART, Tx Complete USART_TXC_vect SIG_USART_TRANS SIG_UART_TRANS
ADC Conversion Complete ADC_vect SIG_ADC
EEPROM Ready EE_RDY_vect SIG_EEPROM_READY
Analog Comparator ANA_COMP_vect SIG_COMPARATOR
2-wire Serial Interface TWI_vect SIG_2WIRE_SERIAL
Store Program Memory Ready SPM_RDY_vect SIG_SPM_READY
37
Techniki mikroprocesorowe
Modyfikator volatile
• Zmienne globalne, które mają być wykorzystywane wewnątrz zwykłych funkcji i funkcji obsługi przerwań powinny być zaopatrzone w modyfikator volatile
volatile TYP_ZMIENNEJ NAZWA_ZMIENNEJ;
• Modyfikator volatile zapobiega optymalizacji polegającej na operowaniu przez program na tymczasowej kopii zmiennej, co może być źródłem utraty danych
38
Techniki mikroprocesorowe
PROGMEM
• Zmienne, które nie będą modyfikowane, a potrzebują dużo pamięci mogą być trzymane w pamięci programu, zamiast pamięci RAM
#include <avr/pgmspace.h>
TYP ZMIENNA PROGMEM = WARTOŚĆ;
TYP ZMIENNA_1 = pgm_read_xxx(ADRES_ZMIENNEJ);
39
Techniki mikroprocesorowe
PROGMEM
• W zależności od lokalizacji zmiennej w pamięci wyróżnia się wersje „near” i „far” funkcji pgm_read_xxx
• Adres w wersji „near” jest 16-bitowy, natomiast w wersji „far” – 32-bitowy
40
Techniki mikroprocesorowe
PROGMEM
• Funkcje w wersji „far”
– pgm_read_byte_far(address_long)
– pgm_read_word_far(address_long)
– pgm_read_dword_far(address_long)
– pgm_read_float_far(address_long)
41
Techniki mikroprocesorowe
PROGMEM
• Funkcje w wersji „near”
– pgm_read_byte(address_short)
– pgm_read_word(address_short)
– pgm_read_dword(address_short)
– pgm_read_float(address_short)
42
Techniki mikroprocesorowe
Modyfikator inline
• Modyfikator ten informuje kompilator, że jeśli nastąpi wywołanie funkcji inline, to zamiast wygenerować w tym miejscu przeniesienie sterowania (skok) do tej funkcji, bezpośrednio wstawi wygenerowany kod tej funkcji
• Funkcje inline stosuje się w sytuacji, gdy wydajność jest ważniejsza od objętości kodu wynikowego
43
Techniki mikroprocesorowe
Modyfikator inline
• Przykład inline uint8_t max(uint8_t a, uint8_t b) { return a > b ? a : b; }
44
Techniki mikroprocesorowe
cli() i sei()
• Aby zapewnić niepodzielność operacji przez przerwania , które mogłyby być w tym czasie zgłoszone, stosuje się funkcje cli() i sei(), blokującą i odblokowującą globalną obsługę przerwań na czas wykonywania takiej operacji
45
Techniki mikroprocesorowe
Obsługa portów I/O
• Makra upraszczające obsługę portów I/O #define PORT(x) XPORT(x) #define XPORT(x) (PORT##x) #define PIN(x) XPIN(x) #define XPIN(x) (PIN##x) #define DDR(x) XDDR(x) #define XDDR(x) (DDR##x) Np. #define DRIVER_PORT A #define DRIVER_PIN_0 0 PORT(DRIVER_PORT) = (1 << DRIVER_PIN);
46
Techniki mikroprocesorowe
Cele optymalizacji
• Ograniczenie rozmiaru kodu wynikowego
• Ograniczenie zużycia pamięci operacyjnej
• Ograniczenie zużycia czasu procesora
• Zapewnienie niezawodności programu
• Ograniczenie liczby potencjalnie niebezpiecznych elementów kodu
48
Techniki mikroprocesorowe
Ograniczenie rozmiaru kodu wynikowego
• Przykłady realizacji
– Unikanie funkcji inline
– Unikanie powtarzania tych samych fragmentów kodu, jeśli to możliwe zastąpić je jedną funkcją
– Niekorzystanie z rozbudowanych gotowych funkcji, jeśli ich możliwości nie będą w pełni wykorzystane
– Użycie flagi optymalizacji „s”
49
Techniki mikroprocesorowe
Ograniczenie zużycia pamięci operacyjnej
• Stosowanie zmiennych ze znakiem i/lub zmiennoprzecinkowych tylko w razie konieczności
• Stosowanie możliwie „małych” typów danych
• Dokładne szacowanie objętości potrzebnych danych w pamięci RAM
• Unikanie rekurencji
• Stosowanie dynamicznego przydziału pamięci tylko w ostateczności (ryzyko wycieku)
50
Techniki mikroprocesorowe
Ograniczenie zużycia czasu procesora
• Wykorzystywanie funkcji inline • Wstawki assemblerowe • Jeśli to możliwe zastąpienie złożonych funkcji
arytmetycznych (np. sin, cos) tablicami • Korzystanie z flag optymalizacji „1”, „2”, „3” • Unikanie typów zmiennych liczbowych, na
których operacje arytmetyczne wykonywane są w sposób programowy
• Operacje arytmetyczne wykonywać na liczbach całkowitych
51
Techniki mikroprocesorowe
Poprawienie czasu odpowiedzi programu
• Wykorzystywanie asychronicznych trybów pracy peryferiów
• Przeniesienie możliwie dużej części sterowania programem do funkcji obsługi przerwań (pamiętając o priorytetach przerwań!)
• Priorytetyzacja zadań w programie
• Uproszczenie i optymalizacja funkcji krytycznych dla responsywności systemu
52
Techniki mikroprocesorowe
Zapewnienie niezawodności programu
• Unikanie dynamicznego alokowania pamięci oraz korzystanie z narzędzi do analizy użycia pamięci
• Unikanie funkcji operujących na strumieniach, o zmiennej liczbie argumentów itp.
• Unikanie operowania na rejestrach korzystając z numerów bitów zamiast nazw bitów
• Korzystanie z układów BOD (Brown-out Detection) i watchdog
53
Techniki mikroprocesorowe
Przykład prostego programu
#include <inttypes.h> #include <avr/io.h> #include <avr/interrupt.h> volatile uint8_t led = 0; //obsluga przerwan INT0 (przycisk) ISR (INT0_vect) { led = (led + 1) % 2; }
55
Techniki mikroprocesorowe
Przykład prostego programu
int main(void) { //konfiguracja portow I/O DDRA |= (1<<DDA0); //wyjscia sterujace diodami PORTA |= (1<<PORTA0); PORTD |= (1<<PORTD2); //wejscie przycisku cli(); //blokujemy globalnie dzialanie przerwan MCUCR |= (1<<ISC01); //przerwania INT0 reagujace na zbocze opadajace
(nacisniecie przycisku) GICR |= (1<<INT0)); //wlaczamy przerwania INT0 sei(); //odblokowujemy globalnie dzialanie przerwan
56