Макрос, указывающий на используемые контакты ввода/вывода

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

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

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

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


person detly    schedule 26.10.2009    source источник
comment
нет ответа, но хороший вопрос. (Я полагаю, было бы проще, если бы ребята из Microchip подняли свои задницы и поддержали C++.)   -  person Jason S    schedule 26.10.2009
comment
Ну, у них все равно нет компилятора для Linux, так что для меня это HiTech (в любом случае я предпочитаю их макросы).   -  person detly    schedule 29.10.2009


Ответы (3)


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

#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
person DigitalRoss    schedule 26.10.2009
comment
Однако это ошибки только в том случае, если они находятся в одной единице перевода. - person bdonlan; 26.10.2009

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

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

Изменить. Судя по комментариям, так может получиться лучше:

#define CLAIM_PIN(n) void claimed_pin_#nn(void) {}
person Mark Ransom    schedule 26.10.2009
comment
Это использует один байт на вывод. Если это проблема, OP может захотеть изучить параметры компоновщика, чтобы поместить эти определения в свой собственный раздел и удалить их из окончательного изображения. - person bdonlan; 26.10.2009
comment
Прошло так много времени с тех пор, как я использовал архитектуру, в которой имел значение один байт, я даже не думал об этом. - person Mark Ransom; 26.10.2009
comment
Но это не ошибка. Это совершенно законно для C, даже в нескольких единицах компиляции. - person DigitalRoss; 26.10.2009
comment
Как насчет использования функции вместо символа? - person bdonlan; 26.10.2009

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

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

person Michael Burr    schedule 26.10.2009