我正在使用EFM32 PG12入门套件和Simple Studio开发显微镜的微控制器项目。在这个项目中,我在.h文件global_definitions.h
中做了一些全局的针脚和端口定义这样做是因为复杂。不同文件中的许多功能可以直接通过思想计时器或通过PRS访问引脚。
这里是一些global_definitions.h:
#pragma once //not working
#define startUpMessage "I:000:Initialization finished"
#define prsChannel 6
//pin definitions for the lasers
unsigned int laserPinNumbers[]={2,3,12,13,14,15};
unsigned int laserPorts[]={gpioPortA,gpioPortA,gpioPortD,gpioPortD,gpioPortD,gpioPortD};
unsigned int laserTimers[]={0,0,1,1,1,1};
#define timer0 WTIMER0
#define timer1 WTIMER1
依此类推...
如果我尝试编译我的项目,则会出现错误:
arm-none-eabi-gcc -g3 -gdwarf-2 -mcpu=cortex-m4 -mthumb -T "SLM_PG12_3.ld" -Xlinker --gc-sections -Xlinker -Map="SLM_PG12_3.map" -mfpu=fpv4-sp-d16 -mfloat-abi=softfp --specs=nano.specs -o SLM_PG12_3.axf "./CMSIS/EFM32PG12B/startup_efm32pg12b.o" "./CMSIS/EFM32PG12B/system_efm32pg12b.o" "./emlib/em_cmu.o" "./emlib/em_core.o" "./emlib/em_gpio.o" "./emlib/em_prs.o" "./emlib/em_rtc.o" "./emlib/em_rtcc.o" "./emlib/em_system.o" "./emlib/em_timer.o" "./emlib/em_usart.o" "./emlib/udelay.o" "./src/i2c.o" "./src/izi_usart.o" "./src/laserSequences.o" "./src/leds.o" "./src/main.o" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
./src/leds.o:/home/grafmakula/SimplicityStudio/v4_workspace/SLM_PG12_3/GNU ARM v7.2.1 - Debug/../src/global_definitions.h:12: multiple definition of `laserPinNumbers'
./src/laserSequences.o:/home/grafmakula/SimplicityStudio/v4_workspace/SLM_PG12_3/GNU ARM v7.2.1 - Debug/../src/global_definitions.h:12: first defined here
./src/leds.o:/home/grafmakula/SimplicityStudio/v4_workspace/SLM_PG12_3/GNU ARM v7.2.1 - Debug/../src/global_definitions.h:13: multiple definition of `laserPorts'
./src/laserSequences.o:/home/grafmakula/SimplicityStudio/v4_workspace/SLM_PG12_3/GNU ARM v7.2.1 - Debug/../src/global_definitions.h:13: first defined here
...
collect2: error: ld returned 1 exit status
make: *** [SLM_PG12_3.axf] Error 1
包括卫兵
#ifndef GLOBAL_DEFINITIONS
#define GLOBAL_DEFINITIONS
...
#endif
也无法正常工作。
Waht是在c中进行全局定义的正确方法吗?
谢谢。
#pragma once
在编译single源文件时会保护头文件免受多个包含。因此,如果您编译leds.c
并尝试多次包含此文件,可能是从其他包含级别不同的包含文件中提取的,则编译指示可确保该文件在此编译期间仅被解析一次。编译laserSequences.c
时也会发生同样的情况。
现在您已经以.o
格式编译了至少2个源文件。每个人都包含一次头文件,每个人都从该头文件中声明全局变量。链接器抱怨是因为它不知道要使用哪个。
解决方法是从不在头文件中声明变量。您仅提供其外部链接的定义。声明必须在一个且仅一个源文件中进行,例如:
global_definitions.h:
#pragma once
#define startUpMessage "I:000:Initialization finished"
#define prsChannel 6
extern unsigned int laserPinNumbers[];
extern unsigned int laserPorts[];
extern unsigned int laserTimers[];
...
现在在.c
文件的one中,可以是一个文件,也可以是其他一些文件,例如global_definitions.c
,您可以声明vars:
unsigned int laserPinNumbers[]={2,3,12,13,14,15};
unsigned int laserPorts[]={gpioPortA,gpioPortA,gpioPortD,gpioPortD,gpioPortD,gpioPortD};
unsigned int laserTimers[]={0,0,1,1,1,1};
此外,#pragma once
是对替换保护宏的标准的最新添加(在编译器的较早版本中可能不起作用)。它们以相同的方式工作。