2012-01-19 16 views
5

Mam mikrokontroler, z którym pracuję. Podczas debugowania konieczne jest wywołanie funkcji, która jest zakodowana w pamięci ROM. Technical Reference pokazuje jak to zrobić:Wskaźnik do funkcji w pamięci ROM

# define Device_cal (void(*)(void))0x3D7C80 

i wywołanie procedura wygląda następująco:

(*Device_cal)() 

nie mogę zrozumieć, co tak naprawdę dzieje się tutaj, więc moje pytanie brzmi: Jak to działa?

Odpowiedz

3

W #define przyczyny (*Device_cal)() zostać rozszerzona na ten natychmiast przed kompilacją:

(*(void(*)(void))0x3D7C80)() 

void(*)(void) jest deklaracja dla wskaźnika funkcję, która pobiera i zwraca voidvoid typów. Numer (*()) reprezentuje rzutowanie na następny token w wyrażeniu (0x3D7C80). W ten sposób prosi się o traktowanie danych w lokalizacji 0x3D7C80 jako funkcji. Ostateczny () wywołuje funkcję bez żadnych argumentów.

7

void (*) (void) to typ. Jest to wskaźnik do funkcji, która nie przyjmuje parametru i zwraca void.

(void(*)(void)) 0x3D7C80 rzuca liczbę całkowitą 0x3D7C80 do tego wskaźnika funkcji.

dzwoni do funkcji.

(Device_cal)() zrobiłby dokładnie to samo.

Wymagane są nawiasy około *Device_cal i Device_cal, ponieważ w przeciwnym razie rzutowanie na liczbę całkowitą nie miałoby wyższego pierwszeństwa.

2

cóż, "zdefiniuj" wskaźnik do funkcji i wywołaj go. void(*)(void) oznacza wskaźnik do funkcji, który nie otrzymuje żadnych argumentów i zwraca void. Jeśli odrzucisz 0x3D7C80 do tego typu i wywołasz go, to po prostu wywołasz funkcję, której adres to 0x3D7C80.

0

Symbol jest wklejony, w którym tworzy tymczasowy (nie nazwany) wskaźnik do funkcji w stałej lokalizacji pamięci, a następnie wywołuje go poprzez dereferencje.

2

To nie jest odpowiedź (to już zostało zrobione w sposób zadowalający), ale kilka rad:

Proponuję następującą metodę Zamiast:

typedef void (*tVOID_ROMFUNCTION_VOID)(void) ; 

tVOID_ROMFUNCTION_VOID Device_cal = (tVOID_ROMFUNCTION_VOID)0x3D7C80 ; 

Device_cal() ; 

ten sposób można utworzyć dowolną liczbę globalny wskaźniki funkcji podczas inicjalizacji, podczas gdy połączenia wyglądają jak zwykłe statycznie połączone funkcje. Unikasz też mylenia makr preprocesora voodoo w tym samym czasie.

Tworząc różne typy wskaźników funkcji z różnymi sygnaturami, kompilator będzie mógł wykonać dla ciebie również sprawdzanie parametrów.

+0

Jestem zaskoczony, że ta odpowiedź nie ma więcej głosów w górę. Jest o wiele czystszy niż rozwiązania makro. – tomlogic

+0

@tom: Dzięki, ale żeby być uczciwym, tak jak powiedziałem, to nie jest tak naprawdę odpowiedź na zadane pytanie, tylko lepszy sposób robienia tego, o co pytano. – Clifford

Powiązane problemy