Obsługa pamięci masowych z USB za pomocą mikrokontrolerów LPC1300 firmy NXP
Rys. 2. Opcje ustawień skryptów linkera w oknie Project Properties programu LPCXpresso
Projekty w środowisku IAR zwykle wykorzystują skrypty linkera specyficzne dla układu, na który pisany jest kod. Ścieżkę do tego skryptu można znaleźć w oknie Project Options, w sekcji Linker, w zakładce Config. Żeby zaalokować część pamięci RAM na potrzeby wbudowanego sterownika USB należy kliknąć Edit w oknie Project Options (co powoduje pojawienie się okienka Linker configuration file editor i zmienić początkowy adres pamięci RAM w zakładce Memory Regions.
Rys. 3. Ustawienia skryptu linkera w oknie opcji projektu środowiska IAR Embedded Workbench
W Keil ?Vision4, aby zmienić ustawienia pamięci RAM, trzeba użyć zakładki Target w oknie Project Options. Podobnie, jak w pozostałych środowiskach, należy ustawić początkowy adres pamięci na 0x10000180, a oprócz tego, zmniejszyć rozmiar pamięci o 0x180.
Rys. 4. Ustawienia skryptu linkera w oknie opcji urządzenia docelowego w Keil ?Vision4 RealView MDK-ARM
Inicjalizacja pamięci ROM
Po zerowaniu mikrokontrolera LPC1300 zawsze jest wykonywany kod znajdujący się we wbudowanej pamięci ROM, co jest podstawowym warunkiem tego, żeby procesor znalazł się po uruchomieniu w znanym stanie. Bardzo ważne przy programowaniu układu za pomocą debuggera jest zadbanie, żeby program zapisany w ROMie mógł się wykonać przed kodem użytkownika. Zwykle rozwiązuje się ten problem za pomocą makra lub skryptu debuggera i większość narzędzi programistycznych obsługujących mikrokontrolery LPC1300 jest wyposażona w odpowiednie makra. W razie wątpliwości, trzeba poszukać stosownych informacji w dokumentacji używanego narzędzia programistycznego lub konsultować się z jego producentem.
Wywoływanie funkcji wbudowanego sterownika USB
Sterownik USB jest wyposażony w API z trzema funkcjami i obsługą przerwań. Można ich używać poprzez tablicę skoków (jump table) znajdującą się w pamięci ROM. Lokalizacja tej tablicy w ROMie może się zmieniać wraz ze zmianami i poprawkami pamięci w nowych wersjach układów, więc dostęp do niej jest realizowany za pomocą wskaźnika ustawionego na stały adres. Aby skorzystać z funkcji API, konieczne jest zadeklarowanie zawartości tablicy skoków oraz wskaźnika na wskaźnik na tę tablicę. Konfigurację wskaźników pokazano na rysunku 5.
Rys. 5. Struktura pamięci ROM dla wywołań funkcji API
Można użyć np. takiego kodu w C:
typedef struct _USBD {
void (*init_clk_pins)(void);
void (*isr)(void);
void (*init)( USB_DEV_INFO * DevInfoPtr );
void (*connect)(uint32_t con);
} USBD;
typedef struct _ROM { const USBD * pUSBD; } ROM;
ROM ** rom = (ROM **)0x1fff1ff8;
Aby wywołać jedną z funkcji można się posłużyć kodem podobnym do zamieszczonego poniżej. Kod ten pobiera adres sterownika USB z tablicy skoków (dokonuje dereferencji) za pomocą wskaźnika ustawionego na 0x1FFF1FF8, a następnie używa tablicy skoków do wywołania funkcji init_clk_pins() sterownika USB.
(*rom)->pUSBD->init_clk_pins();