Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
1
PRZERWANIA, DMA, UART Orkiszewski Marcin
Koło Naukowe Układów Cyfrowych DEMAIN
2
Altera NIOS II Wymagane oprogramowanie: Quartus II v. 9.0
Nios IDE v. 9.0 Do pobrania na stronie
3
Uwaga! Katalogi, w których instalujemy oprogramowanie oraz w których zakładamy projekty: ! NIE MOGĄ zawierać spacji !
4
Uwaga! Unikać powtarzania nazw: - block diagram: <..>_project
- SOPC: <..>_sopc - Nios IDE <..>_soft W razie problemów
5
Założenie projektu
6
1. Otworzenie projektu Quartus II Project Restore Archived Project…
Otworzenie archiwum projektu: Quartus II Project Restore Archived Project…
9
[CPU] – bez Data Cache
10
[Buttons] – generują przerwanie
11
[UART] – 8 bitowy
12
[SDRAM] – 16 bitowy !!
13
[PLL] 50 MHz 100 MHz (-65˚ dla SDRAM)
14
[RAM] – dwuportowa pamięć !
15
2. Kompilacja projektu Processing Start compilation
- Wykorzystanie komórek logicznych - Wykorzystanie bloków pamięci
16
3. Załadowanie obrazu do układu
Tools Programmer - Hardware Setup USB-Blaster Program/Configure Start - Czasami przydatne bywa włączenie zasilania -
17
Programowanie
18
7. Założenie projektu (1/2)
File New Project… Nios II C/C++ Application
19
7. Założenie projektu (2/2)
Wskazanie obrazu systemu (.ptf): Select project template: Blank Project Name: szkolenie2_soft SOPC Builder System PTF File: ../szkolenie2_sopc.ptf Finish
20
8. Kompilacja biblioteki
Prawy klawisz myszki na szkolenie2_soft_syslib Properties System Library Reduced device drivers Small C library itp.. Build Project
22
9. Dodanie plików źródłowych (C/C++)
Prawy klawisz myszki na szkolenie2_soft Import… General File System szkolenie2.h szkolenie2_1.c szkolenie2_2.c szkolenie2_3.c szkolenie2_4.c szkolenie2_5.c szkolenie2_6.c
23
10. Uruchomienie projektu
Run Run… Nios II Hardware Main Project: szkolenie2_soft Target Connection: USB-Blaster Run
25
Program 1 (Buttons)
26
Program 1 int main() { // init while(1) ; // ? } return 0;
27
Przerwanie Asynchroniczne sprzętowe zgłoszenie się komponentu.
Przerywa obecnie wykonywany kod (skok do funkcji przerwania zachowanie stanu procesora na stosie). Wymaga odblokowania dla każdego z komponentów (oraz potwierdzenia !). Przerwanie o wysokim priorytecie przerywa przerwanie o niskim priorytecie (możliwość zagnieżdżania przerwań).
28
vs. Pooling Przegląd urządzeń (czy nie potrzebują obsługi)
„Wyżeramy” 100% mocy procesora nic nie robiąc (tzw. aktywne oczekiwanie), nieprzerywalność operacji obsługi (np. nie możemy odbierać danych, bo akurat coś liczymy, przegapiamy wciśnięcie przycisku, itp..), nie możemy ustalić priorytetów. „Technicznie chałowe w najwyższym stopniu”. Dr inż. Jerzy Chrząszcz (Techniki Mikroprocesorowe)
29
Jak używać ? Wykonywać tylko to, co musi być zrobione natychmiast !
Resztę operacji dokończyć w pętli głównej programu (poprzez ustawienie odpowiednich znaczników – zmiennych globalnych). Pamiętać o kasowaniu znaczników przerwania ! Unikać zagnieżdżania przerwań. Unikać tworzenia zmiennych lokalnych, nie wywoływać funkcji printf. Używać rozsądnie – zbyt częste lub zbyt rozbudowane przerwania skutecznie paraliżują procesor.
30
Program 1 #include <sys/alt_irq.h>
void BUTTONS_ISR( void *context, unsigned long id ) { //… } int main() { alt_irq_register( BUTTONS_IRQ, 0, BUTTONS_ISR ); } // Zarejestrowanie funkcji przerwania
31
Komponent PIO – mapa rejestrów
IOWR_ALTERA_AVALON_PIO_IRQ_MASK( BUTTONS_BASE, 0xFF );
32
Program 1 volatile alt_u8 buttons; // zmienna globalna volatile
void BUTTONS_ISR( void *context, unsigned long id ) { buttons = IORD_ALTERA_AVALON_PIO_DATA( BUTTONS_BASE ); IOWR_ALTERA_AVALON_PIO_DATA( LED_G_BASE, buttons ); // potwierdzenie przerwania IOWR_ALTERA_AVALON_PIO_EDGE_CAP( BUTTONS_BASE, 0 ); }
33
Program 2 (Timer)
34
Program 2 volatile alt_u8 irq_flag = 0;
void TIMER_ISR( void *context, unsigned long id ) { irq_flag = 1; IOWR_ALTERA_AVALON_TIMER_STATUS( TIMER_BASE, 0 ); // potwierdzenie } int main() alt_irq_register( TIMER_IRQ, 0, TIMER_ISR );
35
Program 2 // Obsługa w pętli głównej programu int main() {
IOWR_ALTERA_AVALON_TIMER_PERIODH( TIMER_BASE, 0x05F5 ); // 100 MHz IOWR_ALTERA_AVALON_TIMER_PERIODL( TIMER_BASE, 0xE100 ); IOWR_ALTERA_AVALON_TIMER_CONTROL( TIMER_BASE, 0x01 | 0x02 | 0x04 ); while(1) if( irq_flag ) // obsługa przerwania irq_flag = 0; }
36
Program 3 (DMA)
37
alt_u16 * pointer = SDRAM_BASE;
#include ”system.h” alt_u16 * pointer = SDRAM_BASE; Odczyt i zapis do SDRAM realizowany jest przez sprzętowy kontroler pamięci. Aby operować na tej pamięci wystarczy posłużyć się zwykłym wskaźnikiem!
38
DMA (Direct Memory Access)
Idea – szybkie kopiowanie danych (o rozmiarze LENGTH) spod adresu READADDRESS pod adres WRITEADDRESS
39
DMA - inicjalizacja #include ”altera_avalon_dma_regs.h”
// alt_u16 data[10] – tablica danych IOWR_ALTERA_AVALON_DMA_RADDRESS( DMA_BASE, data ); // adres docelowy IOWR_ALTERA_AVALON_DMA_WADDRESS( DMA_BASE, SDRAM_BASE ); // 16-bit, DMA aktywne, kopiuj określoną liczbę danych IOWR_ALTERA_AVALON_DMA_CONTROL( DMA_BASE, 0x02 | 0x08 | 0x80 ); // start IOWR_ALTERA_AVALON_DMA_LENGTH( DMA_BASE, 20 ); DMA skopiuje 20 BAJTÓW !
40
DMA - koniec transferu // oczekiwanie na koniec transferu danych
while( IORD_ALTERA_AVALON_DMA_STATUS( DMA_BASE ) & 0x11 != 0x11 ) ; 0x11 = 10001
41
DMA - ustawienia główne
0x0001 0x0002 0x0004 0x włączenie DMA 0x przerwanie 0x0020 0x0040 0x warunek stopu 0x stały adres odczytu 0x stały adres zapisu 0x0400 0x0800 0x1000
42
Program 3 Kopiowanie tablicy alt_u16 data[10] do SDRAM (10 x 16 bitów = 20 bajtów) IOWR_ALTERA_AVALON_DMA_STATUS( DMA_SDRAM_BASE, 0 ); IOWR_ALTERA_AVALON_DMA_RADDRESS( DMA_SDRAM_BASE, data ); IOWR_ALTERA_AVALON_DMA_WADDRESS( DMA_SDRAM_BASE, SDRAM_BASE ); IOWR_ALTERA_AVALON_DMA_CONTROL( DMA_SDRAM_BASE, (0x02 | 0x08 | 0x80 ) ); IOWR_ALTERA_AVALON_DMA_LENGTH( DMA_SDRAM_BASE, 20 ); while ( (IORD_ALTERA_AVALON_DMA_STATUS( DMA_SDRAM_BASE ) & 0x11 ) != 0x11 ) ;
43
Program 3 Kopiowanie wartości do SDRAM
IOWR_ALTERA_AVALON_DMA_STATUS( DMA_SDRAM_BASE, 0 ); IOWR_ALTERA_AVALON_DMA_RADDRESS( DMA_SDRAM_BASE, &data[6] ); IOWR_ALTERA_AVALON_DMA_WADDRESS( DMA_SDRAM_BASE, SDRAM_BASE ); IOWR_ALTERA_AVALON_DMA_CONTROL( DMA_SDRAM_BASE, 0x02 | 0x08 | 0x80 |0x100 ); IOWR_ALTERA_AVALON_DMA_LENGTH( DMA_SDRAM_BASE, 20 ); while ( (IORD_ALTERA_AVALON_DMA_STATUS( DMA_SDRAM_BASE ) & 0x11 ) != 0x11 ) ;
44
DMA - informacje Maksymalną liczbę danych jaką może kopiować DMA określamy w SoPC Wartość w rejestrze LENGTH musi być wielokrotnością danego typu (np. dla słów 32 bitowych możemy ustawiać tylko wielokrotność 4) Przed ponownym uruchomieniem DMA musimy ponownie określić adresy docelowe, chyba że zostały one oznaczone jako niezmienne W każdej chwili można sprawdzić, ile bajtów DMA już skopiowało (poprzez odczyt rejestru LENGTH) Należy znać adresy komponentów podłączanych do DMA, które nie znajdują się w przestrzeni adresowej mikroprocesora (nie ma ich w ”system.h”).
45
DMA - konfiguracja
46
Program 4 (test DMA)
47
Program 4 - wydajność DMA
Ile danych w ciągu 1 sekundy skopiuje do SDRAM: Mikroprocesor ? DMA ? Timer po 1 sekundzie przerywa zapis danych i sprawdza ile MB udało się skopiować DMA, a ile mikroprocesorowi.
48
Program 5 (UART)
49
UART (Universal Asynchronous Receiver and Transmitter)
Idea – zarządzanie transmisją danych np. RS-232, RS lub między komponentami !
50
Program 5 - echo #include ”altera_avalon_uart_regs.h” int main() {
alt_u8 data; while(1) if( IORD_ALTERA_AVALON_UART_STATUS( UART_BASE ) & 0x80 ) data = IORD_ALTERA_AVALON_UART_RXDATA( UART_BASE ); IOWR_ALTERA_AVALON_UART_TXDATA( UART_BASE, data ); } return 0; }
51
UART - koniec transferu
// czy otrzymano dane ? if( IORD_ALTERA_AVALON_UART_STATUS( UART_BASE ) & 0x80 ) // czy dane wysłane ? while( ! (IORD_ALTERA_AVALON_UART_STATUS( DMA_BASE ) & 0x40) ) ; 0x40 0x80
52
Program 6 (UART + DMA)
53
Program 6 Podłączenie UART pod DMA – nasłuch:
volatile alt_u8 data_recv[5]; IOWR_ALTERA_AVALON_DMA_STATUS( DMA_RS_READ_BASE, 0 ); IOWR_ALTERA_AVALON_DMA_RADDRESS( DMA_RS_READ_BASE, UART_BASE ); IOWR_ALTERA_AVALON_DMA_WADDRESS( DMA_RS_READ_BASE, data_recv ); IOWR_ALTERA_AVALON_DMA_CONTROL( DMA_RS_READ_BASE, (0x01 | 0x08 | 0x10 | 0x80 | 0x100) ); // 8bit & GO & IRQ & LEEN & RCONST // nasłuch 5 bajtów IOWR_ALTERA_AVALON_DMA_LENGTH( DMA_RS_READ_BASE, 5 );
54
Program 6 Podłączenie UART pod DMA – nadawanie:
volatile alt_u8 data_recv[5]; IOWR_ALTERA_AVALON_DMA_STATUS( DMA_RS_WRITE_BASE, 0 ); IOWR_ALTERA_AVALON_DMA_RADDRESS( DMA_RS_WRITE_BASE, data_recv ); IOWR_ALTERA_AVALON_DMA_WADDRESS( DMA_RS_WRITE_BASE, (UART_BASE+1) ); IOWR_ALTERA_AVALON_DMA_CONTROL( DMA_RS_WRITE_BASE, (0x01 | 0x08 | 0x80 | 0x200) ); // 8bit & GO & LEEN & WCONST
55
Program 6 - echo DMA_READ ustawiane na odbiór 5 bajtów.
Po odebraniu 5 bajtów, DMA_READ zgłasza przerwanie. W funkcji przerwania uruchamiane jest DMA_WRITE, które odpowiada 5 bajtami odebranymi. W funkcji przerwania ustawiana jest flaga do obsłużenia w pętli głównej programu. W pętli głównej sprawdzane jest, czy DMA_WRITE zakończyło nadawanie. W pętli głównej DMA_READ jest ponownie ustawiane odbiór 5 bajtów.
56
Materiały dostępne na stronie Koła
Publikacje 24 XI 2009
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.