2009-10-26 21 views
10

Piszę oprogramowanie układowe dla PIC32MX, używając HiTech PICC32. Jednym z problemów, których chcę uniknąć, jest to, że ponieważ większość pinezek ma wiele nazw (np. AN0 = RB0 ​​= CN2 = PGED1), ja lub ktoś inny może przypadkowo użyć RB0, nie zdając sobie sprawy, że AN0 jest już używany. (W rzeczywistości może to być katastrofalne, ponieważ niepoprawne skonfigurowanie pinów analogowo-cyfrowych może prowadzić do nadmiernego poboru prądu i uwolnienia podstawowego dymu.)Makro wskazujące szpilki I/O używane

Oprócz kompleksowego dokumentowania każdego używanego styku, zastanawiałem się, czy istnieje szybka metoda wyłączyć tę kwestię na poziomie kodowania. Chcę makro, którego mogą używać ludzie (głównie ja), na przykład CLAIM_PIN(58), które spowoduje ostrzeżenie lub błąd, jeśli zostanie uruchomione dwukrotnie.

(Nie chcę tego za wszelką cenę, jeśli jedyne możliwe rozwiązanie jest zbyt przerażające lub niemożliwe do zapamiętania, to zapomnę o tym i po prostu rozwiną się reputacje za wybuchające łzami lub podpalenie czy coś takiego. także zobaczyłem to pytanie o macro producing macros, które wyklucza to.)

Powinienem wyjaśnić: kod IS jest zapisany w wielu jednostkach kompilacji (przynajmniej, myślę, że to właśnie oznacza to wyrażenie). Mam plik .h/.c dla mojego kodu A2D, podobnie jak dla SPI, i podobnie dla różnych urządzeń peryferyjnych, które używają tylko niektórych portów I/O. Przestrzeń nie jest naprawdę problem, mój kod pozostawia dużo miejsca na PIC32MX; również mogę użyć innej flagi __DEBUG, aby usunąć kod sprawdzania pinów do ostatecznego użycia.

+0

brak odpowiedzi, ale dobre pytanie. (Przypuszczam, że byłoby łatwiej, gdyby ludzie z Microchip dostali swoje tyłki i wspierają C++.) –

+0

Tak czy inaczej, nie mają kompilatora Linuksa, więc to dla mnie HiTech (i tak wolę ich makra). – detly

Odpowiedz

6

OK, tutaj. Bez kosztów runtime.

#define CLAIM(n) struct busy##n {} 

CLAIM(58); 
CLAIM(58); 

Jeśli uruchomić dwa razy będzie error out:

z.c:4: error: redefinition of ‘struct busy58’ 

Aby rozszerzyć zaznaczenie do wielu jednostek kompilacji będzie chciał zawinąć makro w #if DEBUG bo będziemy za pomocą łącznika, aby wykryć zderzenie i dlatego miałby ślad czasu działania.

#define CLAIM(n) char busy##n = 1; 
#define CLAIM(n) void busy##n() {} // bdonlan 
+4

Jednak to tylko błędy, jeśli znajdują się w tej samej jednostce tłumaczeniowej. – bdonlan

8
#define CLAIM_PIN(n) char claimed_pin_##n; 

Teraz, gdy dwa kawałki kodu próbować ubiegać się o kołek, symbol zostanie zdefiniowany podwójnie i albo kompilator lub linker wygeneruje błąd.

Edit: W oparciu o komentarze, to może okazać się lepsze:

#define CLAIM_PIN(n) void claimed_pin_#nn(void) {} 
+2

Wykorzystuje to jeden bajt na pinezkę. Jeśli jest to problem, OP może chcieć zajrzeć do opcji linkera, aby umieścić te definicje w swojej własnej sekcji i usunąć je z ostatecznego obrazu. – bdonlan

+0

Od dawna używałem architektury, w której liczył się jeden bajt, nawet o tym nie myślałem. –

+2

Ale to nie błąd. Jest to całkowicie legalne C, nawet w wielu kompilatorach. – DigitalRoss

2

Jeśli możesz sobie pozwolić napowietrznej wykonania lub, jeśli jest to tylko do debugowania, to bym po prostu stworzyć coś w rodzaju funkcji IOPinOpen() które śledzą szpilki w użyciu zamiast zajmować się makrami.

Z drugiej strony, Mark Ransom's updated answer było warte +1.