Макрос, указывающий на используемые контакты ввода / вывода - PullRequest
10 голосов
/ 26 октября 2009

Пишу прошивку для PIC32MX, используя HiTech PICC32. Одна из проблем, которую я хочу избежать, состоит в том, что, поскольку большинство выводов имеют несколько имен (например, AN0 = RB0 ​​= CN2 = PGED1), я или кто-то другой мог бы случайно использовать RB0, не осознавая, что AN0 уже используется. (На самом деле это может привести к катастрофическим последствиям, поскольку неправильная настройка аналогового / цифрового контакта может привести к чрезмерному потреблению тока и выделению существенного дыма.)

Помимо подробного документирования каждого используемого пина, мне было интересно, есть ли быстрый способ решить эту проблему на уровне кодирования. Я хочу макрос, который могут использовать люди (в основном я), скажем CLAIM_PIN(58), который выдаст предупреждение или ошибку, если его запустить дважды.

(Я не хочу этого любой ценой, если единственно возможное решение является слишком ужасным или неприемлемым, тогда я забуду об этом и просто создаю репутацию расплакаться или поджечь себя или что-то в этом роде. Я также видел этот вопрос о макросах, производящих макросы , что исключает это.)

Я должен уточнить: код написан в нескольких единицах компиляции (по крайней мере, я думаю, что это то, что означает эта фраза). У меня есть файл .h / .c для моего кода A2D, аналогично для SPI и аналогично для различных периферийных устройств, которые просто используют определенные порты ввода-вывода. Пробел не на самом деле проблема, мой код оставляет много места на PIC32MX; также я могу использовать другой флаг __DEBUG для удаления кода проверки пин-кода для окончательного использования.

Ответы [ 3 ]

8 голосов
/ 26 октября 2009
#define CLAIM_PIN(n) char claimed_pin_##n;

Теперь, когда два куска кода пытаются получить пин-код, символ будет определен вдвойне, и компилятор или компоновщик выдаст ошибку.

Редактировать: Исходя из комментариев, это может оказаться лучше:

#define CLAIM_PIN(n) void claimed_pin_#nn(void) {}
6 голосов
/ 26 октября 2009

Хорошо, здесь. Нет времени выполнения.

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

CLAIM(58);
CLAIM(58);

При повторном запуске произойдет ошибка:

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

Чтобы распространить проверку на несколько модулей компиляции, вы захотите обернуть макрос в #if DEBUG, потому что мы будем использовать компоновщик для обнаружения конфликта и, следовательно, будем иметь след времени выполнения.

#define CLAIM(n) char busy##n = 1;
#define CLAIM(n) void busy##n() {} // bdonlan
2 голосов
/ 26 октября 2009

Если вы можете позволить себе накладные расходы времени выполнения или если это просто для отладки, я бы просто создал что-то вроде IOPinOpen() функции, которая отслеживала бы используемые контакты вместо того, чтобы иметь дело с трюком макросов.

С другой стороны, Обновленный ответ Марка Рэнсома стоил + 1.

...