Проблема с условием If для препроцессора - PullRequest
2 голосов
/ 18 июня 2019

Я пишу загрузчик для микроконтроллера AVR XMega, и загрузчик настраивается с помощью файла конфигурации:

Config_Bootloader.h

#ifndef CONFIG_BOOTLOADER_H_ 
#define CONFIG_BOOTLOADER_H_ 

 #include <avr/io.h>

 #define BOOTLOADER_INTERFACE                   &USARTE0
 #define BOOTLOADER_BAUD                        115200
 #define BOOTLOADER_TX                          3       

#endif /* CONFIG_BOOTLOADER_H_ */

Этот файл конфигурации должен быть предварительно обработан другим включаемым файлом для получения некоторых значений регистра и т. Д.

Bootloader_Preprocessing.h

#ifndef BOOTLOADER_PREPROCESSING_H_
#define BOOTLOADER_PREPROCESSING_H_

 #include <avr/io.h>

 #ifdef USARTE0
     #if(BOOTLOADER_INTERFACE == &USARTE0)
        #define BOOTLOADER_PORT     &PORTE
     #else
        #error "Invalid bootloader interface!"
     #endif
 #endif

 #if(BOOTLOADER_BAUD == 9600)
     #define BOOTLOADER_BRREG_VALUE         12
     #define BOOTLOADER_SCALE_VALUE         0
 #elif(BOOTLOADER_BAUD == 19200)
     #define BOOTLOADER_BRREG_VALUE         11
     #define BOOTLOADER_SCALE_VALUE         -1
 #elif(BOOTLOADER_BAUD == 38400)
     #define BOOTLOADER_BRREG_VALUE         9
     #define BOOTLOADER_SCALE_VALUE         -2
 #elif(BOOTLOADER_BAUD == 57600)
     #define BOOTLOADER_BRREG_VALUE         75
     #define BOOTLOADER_SCALE_VALUE         -6
 #elif(BOOTLOADER_BAUD == 115200)
     #define BOOTLOADER_BRREG_VALUE         11
     #define BOOTLOADER_SCALE_VALUE         -7
 #else
     #error "Invalid baud rate for bootloader!"
 #endif

#endif /* BOOTLOADER_PREPROCESSING_H_ */

Я включаю оба файла в свой Bootloader.h

#ifndef BOOTLOADER_H_
#define BOOTLOADER_H_

 #include "Config_Bootloader.h"
 #include "Bootloader_Preprocessing.h"

#endif /* BOOTLOADER_H_ */

И я получаю следующие ошибки и предупреждения:

> #define BOOTLOADER_INTERFACE                  &USARTE0

operator '&' has no left operand

> #if(BOOTLOADER_INTERFACE == &USARTE0)

in expansion of macro 'BOOTLOADER_INTERFACE'
#error "Invalid bootloader interface!"

Так почему сравнение адресов не работает?

Ответы [ 2 ]

4 голосов
/ 18 июня 2019

В препроцессоре нет такого понятия, как "адрес", поэтому их нельзя сравнивать в инструкции препроцессора #if.

См. документы GCC для #IFдля деталей о том, что он может и не может сделать.Обратитесь к документации по используемому вами препроцессору, могут применяться дополнительные / другие ограничения (вы пометили это как AVR).

Похоже, ваш препроцессор пришел к выводу, что оператор & должен быть побитовым оператором &,который является двоичным оператором и поэтому требует левого операнда.

0 голосов
/ 18 июня 2019

Хорошо, у меня есть решение после борьбы с препроцессором Си. Я определяю символ BOOTLOADER_INTERFACE=E,0 в моей конфигурации и обрабатываю ввод:

 #define CATENATE(Prefix, Name)             Prefix##Name
 #define FIRST_ARG(A, B)                    A
 #define SECOND_ARG(A, B)                   B

 #define MAKE_USART_NAME(Uart)              CATENATE(USART, Uart)
 #define MAKE_PORT_NAME(Port)               CATENATE(PORT, Port)
 #define USART_NAME(Name)                   MAKE_USART_NAME(CATENATE(Name))
 #define PORT_NAME(Name)                    MAKE_PORT_NAME(FIRST_ARG(Name))

Результатом является адрес PORT- и USART-структуры, в зависимости от заданного интерфейса USART.

...