Deklaracja zmiennej z @ w C

11

Czytam trochę kodu C i natknąłem się na tę deklarację w programie:

unsigned char serv_ctr @0x0002;

Czy ktoś może skierować mnie do dokumentacji lub wyjaśnić, po co jest „@ 0x0002” w kompilatorze Mplab XC8 v1.35 C?

be-ee
źródło
14
Domyślam się, że jest to rozszerzenie kompilatora do umieszczania zmiennej pod określonym adresem.
Eugene Sh.
2
pytanie może wtedy skorzystać z tagu #mplab, ponieważ okazuje się, że jest to specyficzne dla MPlab.
sylvainulg
Tylko po to: czy jest to temat na tej stronie? Myślę, że to należy do SO. A może w tym miejscu można poprosić o programowanie mikrosterownika. To sprawiłoby, że byłoby trochę niejasne, gdzie powinny być te pytania.
Do widzenia,
6
@KamiKaze O jakie tematy mogę tutaj zapytać? wymieniono „pisanie oprogramowania układowego dla aplikacji bez systemu operacyjnego lub RTOS” jak w temacie, a „oprogramowanie do programowania na PC” jako nie na temat. Ponieważ wydaje się, że chodzi o programowanie systemów wbudowanych, wydaje się, że na pierwszy rzut oka jest na temat. To, że może być również na temat przepełnienia stosu, samo w sobie nie wyklucza tego tematu.
CVn
@KamiKaze dziękuję za pytanie, miałem podobne pytania (nie jestem regularnym użytkownikiem tego SE)
GPPK

Odpowiedzi:

20

Ma to na celu podanie adresu bezwzględnego, na który należy umieścić zmienną.
Ze strony podręcznika kompilatora XC8 strona 27, rozdział 2.5.2 Adresowanie bezwzględne :

Zmienne i funkcje można umieszczać pod adresem bezwzględnym za pomocą __at()konstrukcji
......
2.5.2.2 RÓŻNICE
8-bitowe kompilatory wykorzystały symbol @ do określenia adresu bezwzględnego

Eugene Sh.
źródło
6

@jest powszechnym niestandardowym rozszerzeniem języka C, który pozwala zadeklarować zmienną pod określonym adresem. Może być używany do rejestrów sprzętowych odwzorowanych w pamięci itp. W takim przypadku zmienną należy również zadeklarować volatile, aby twój przykład był niepoprawny.

Inne kompilatory używają czegoś podobnego __attribute__(section...lub #pragma ...niestandardowego C.

Jedynym racjonalnym powodem (jeśli w ogóle), dlaczego łańcuchy narzędzi to robią, jest umożliwienie debugowania rejestru na kiepskich debuggerach. Niestandardowa składnia zapewni, że rejestr stanie się częścią danych wyjściowych linkera i informacji o debugowaniu. Co z kolei pozwala oglądać rejestr w gównianym debuggerze, podobnie jak dowolną inną zmienną.

Jeśli masz dobry debugger, będzie on miał wsparcie i świadomość twojego MCU. Wtedy nie potrzebujesz niestandardowych bzdur w kodzie C, ale możesz zamiast tego napisać czysty, przenośny standardowy C:

#define serv_ctr ( *(volatile uint8_t*)0x0002u )
Lundin
źródło
1
Chociaż kompilatory są zobowiązane do zaakceptowania tej drugiej formy, implementacje mogą mapować liczby na adresy w dowolny sposób, który uznają za odpowiedni. Ponadto większość kompilatorów, które widziałem, używa @platform docelowych z wieloma notacjami pamięci lub innymi problemami, aby większość rzeczy zadeklarowanych za pomocą @notacji zachowywała się inaczej niż wszystko, co można by zrobić bez rozszerzeń.
supercat
1

Krótkie rozszerzenie:

To nie działa już od wersji Xc8 2.0 i nowszych. Teraz musiałeś napisać:

unsigned char serv_ctr __at(0x0002);

umieścić zmienną ( serv_ctr) pod adresem bezwzględnym ( 0x0002).

W XC8 2.0 możliwe jest skompilowanie starego kodu przy użyciu @składni, jeśli ustawienia kompilatora zostaną ustawione na format „C90”. Ustawienie wygląda tak, znajduje się w „XC8 Global Options” i nazywa się „C standard”.

Mikrofon
źródło
@Jednak wiele innych kompilatorów systemów wbudowanych obsługuje również składnię, nie tylko Mplab.
Lundin