Problem with If-Condition for Preprocessor

Viewed 76

I write a bootloader for an AVR XMega Microcontroller and the bootloader got configured by a configuration file:

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_ */

This configuration file is should be preprocessed by another include file to get some register values etc.

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_ */

I include both files into my Bootloader.h

#ifndef BOOTLOADER_H_
#define BOOTLOADER_H_

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

#endif /* BOOTLOADER_H_ */

And I get this errors and warnings:

> #define BOOTLOADER_INTERFACE                  &USARTE0

operator '&' has no left operand

> #if(BOOTLOADER_INTERFACE == &USARTE0)

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

So why does the compare of the address doesn´t work?

2 Answers

There is no such thing as an "address" in the preprocessor, therefore they cannot be compared in an #if preprocessor instruction.

See the GCC docs for #IF for details on what it can and can't do. Consult the documentation for the preprocessor you are using, additional/different restrictions may apply (you tagged this as AVR).

It seems that your preprocessor concluded that the operator & has to be the bitwise operator &, which is a binary operator and therefore requires a left operand.

Okay, I have a solution after struggeling with the C preprocessor. I define the symbol BOOTLOADER_INTERFACE=E,0 in my config and process the input:

 #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))

The result is the address of the PORT- and USART-Structure, depending on the given USART interface.

Related