【发布时间】:2015-05-05 13:18:50
【问题描述】:
我正在 EFM32 Cortex M3 处理器上开发嵌入式 C 代码,几个月后代码开始变得疯狂......我的意思是我们改变了硬件,所以我们得到了不同的版本,我们改变了一些组件,移动了一些 IO,在启动时有不同的论文状态...
所以我想稍微清理一下:
我有一些像这样组织的非常大的文件:
/*============================================================================*/
/* File : BSP_gpio.h */
/* Processor : EFM32GG980F1024 */
/*----------------------------------------------------------------------------*/
/* Description : gpio driver */
/*----------------------------------------------------------------------------*/
#ifndef BSP_GPIO_H
#define BSP_GPIO_H
#ifdef EXTERN
#undef EXTERN
#endif
#ifdef BSP_GPIO_C
#define EXTERN
#else
#define EXTERN extern
#endif
typedef enum
{
GPIO_INIT = 0,
GPIO_WAKEUP = 1,
GPIO_SLEEP = 2,
} GPIO_MODE;
/* Definition / conts */
#define PIO_PIN_HIGH 1
#define PIO_PIN_LOW 0
#ifdef HW_v1
... hundreds of lines...
#elif defined HW_v2
... hundreds of lines...
#endif
#endif
我尝试在单独的文件中分离不同的版本并尝试这样的事情:
#ifdef HW_v1
#include "BSP_gpio_HW1.h"
#elif defined HW_v2
#include "BSP_gpio_HW2.h"
#endif
每个“子文件”使用相同类型的标题(直到枚举)。目的是在每个其他“.c”文件中都包含“BSP_gpio.h”,它会自动包含与所用硬件相对应的文件。
第一个问题是编译取决于我包含子文件的位置。例如,我有一个函数“void BSP_GPIO_set(GPIO_MODE mode)”,它使用枚举“GPIO_MODE”并且在两个硬件版本中有所不同(因为IO的状态在两个硬件)。如果我在声明之前包含子文件,它不知道类型“GPIO_MODE”并产生编译错误,即使我在子文件中#include“BSP_gpio.h”。 所以我只是把它放在文件的末尾,它可以工作,即使我不是很喜欢它......
第二个问题出现在我有一个声明为 extern 的变量时,我想在子文件和其他 C 文件中使用它。假设我将这一行放在“#ifdef HW_v1”之前:
EXTERN int numberOfToggles;
“EXTERN”这个词在我的“BSP_gpio.c”文件中什么都没有,因为我在它的开头定义了 BSP_GPIO_C,并且是在我包含“BSP_gpio.c”的所有其他文件中的关键字extern。 H”。当我构建我的项目时,它会编译,但我有一个链接器错误:“BSP_gpio.o 和 BSP_gpio_HW2.o 中 numberOfToggles 的定义重复”,我找不到解决方案。
如果有人对此有适当的解决方案,我已准备好更改我的项目的架构!
【问题讨论】:
-
听起来你应该考虑为不同版本的板子构建一些 BSL(板子支持库)。
-
看看How do I use
externto share variables between source files in C?。很明显,您知道其中的大部分内容,但它可能会向您提出一些新的建议,尤其是讨论“extern与没有extern”和初始化变量等的结尾部分。
标签: c architecture c-preprocessor