Język C dla AVR

Transkrypt

Język C dla AVR
Język C dla mikroprocesorów AVR
Wykład 6
Techniki mikroprocesorowe
Programowanie AVR
Narzędzia
2
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
Programmer’s Notepad 2
7
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
Techniki mikroprocesorowe
Atmel Studio 6
• Środowisko wspiera kilka typów
programatorów oraz mechanizmy ułatwiające
debugowanie
http://www.atmel.com/microsite/atmel_studi
o6/
9
Techniki mikroprocesorowe
Atmel Studio 6
10
Techniki mikroprocesorowe
Przygotowanie projektu
Przygotowanie projektu
WinAVR + PN2
11
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
Język C dla AVR
27
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
unsigned char
signed int
unsigned int
signed long int
unsigned long int
signed long long int
unsigned long long int
int8_t
uint8_t
int16_t
uint16_t
int32_t
uint32_t
int64_t
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
Techniki mikroprocesorowe
36
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
Optymalizacja kodu
Optymalizacja kodu
47
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
Przykład prostego programu
54
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
Techniki mikroprocesorowe
Przykład prostego programu
//nieskonczona petla glowna programu
while(1)
{
if(led == 0)
PORTA &= ~(1<<dioda);
else
PORTA |= (1<<dioda);
}
return 0;
}
57
Techniki mikroprocesorowe

Podobne dokumenty