I'm trying to implement FreeRTOS on my Arduino ATmega2560, and during this process, I came across 2 errors that I don't understand. And don't know how to fix. hopefully someone here does. The first error is missing binary operator before token "long"
.
The error points to the following line in FreeRTOSConfig.h:
#define configCPU_CLOCK_HZ ((unsigned long) 16000000)
And here is the output of the build:
C:\Projects\src\config\FreeRTOSConfig.h(36,39): error: missing binary operator before token "long"
#define configCPU_CLOCK_HZ ((unsigned long) 16000000)
^
This define is only used in port.c
which has another error that I haven't been able to fix. This error comes from the auto-generated makefile. Not sure if these 2 errors are connected, but better add it here if someone knows how to fix it. The error is:
recipe for target 'src/Core/FreeRTOS/port.o' failed
And this is what I find in the Makefile:
src/Core/FreeRTOS/port.o: ../src/Core/FreeRTOS/port.c
@echo Building file: $<
@echo Invoking: AVR/GNU C Compiler : 5.4.0
$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -x c -DDEBUG -DBOARD=USER_BOARD -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\include" -I"../src/ASF/common/boards/user_board" -I"../src/ASF/common/boards" -I"../src/ASF/mega/utils/preprocessor" -I"../src/ASF/mega/utils" -I"../src/ASF/common/utils" -I"../src" -I"../src/config" -O1 -fdata-sections -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -g3 -Wall -mmcu=atmega2560 -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega2560" -c -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<"
@echo Finished building: $<
missing binary operator before token "long"
This error occurs when you try to use the macro in a pre-processor directive. For example, compile the following C++ code:
#define configCPU_CLOCK_HZ ((unsigned long) 16000000)
#if configCPU_CLOCK_HZ > 0x1000
#endif
avr-g++ will complain:
*.cpp:1:39: error: missing binary operator before token "long"
#define configCPU_CLOCK_HZ ((unsigned long) 16000000)
^
*.cpp:3:5: note: in expansion of macro 'configCPU_CLOCK_HZ'
#if configCPU_CLOCK_HZ > 0x1000
^
So the problem is very likely that configCPU_CLOCK_HZ
is used in a pre-processor directive like above, but configCPU_CLOCK_HZ
is not appropriate for such usage.
Yet another problem is that the environment that you are using drops a part of the diagnostics.
16000000
is already of type long
because it doesn't fit in int
, which is 16-bit type in avr-gcc. So in most cases you can just use plain 16000000
.
If you want something that can be used in preprocessor directives, you can use
16000000ul
. Moreover, C99's stdint.h
provides macros that yield constants of bit-widths that can be used in preprocessor macros like
#include <stdint.h>
#define configCPU_CLOCK_HZ UINT32_C(16000000)
which will expand to an unsigned 32-bit type. Notice however, that older versions of AVR-LibC had a bug with these macros: It just used casts which does not comply to the language standard, which states that [U]INTXX_C
must be usable in pre-processor macros.