我正在为带有C 的Mbedded系统开发,并设置了一个环境,以至于我能够在没有目标平台的情况下在本地测试#define TESTING_ENABLED
。
这将很快扩展到包括项目的所有方面,因此在平台之间切换时,管理每个测试定义可能会变得乏味。
我能够通过makefile设置#define directive
或检测到不同编译器的使用?
使用#define
和#if
为此目的通常是一个非常糟糕的主意,原因有几个原因,代码变为: 1.不可读; 2.无法携带; 3.无法获得;
一般经验法则是,您只能在标题文件中使用#define
和#if
。一旦预处理器进入源文件,就成为维护和便携性方面的项目故障的清晰途径。
so,不惜一切代价避免使用这样的代码:
void foo()
{
...
#if TARGET_REAL_CPU
...
#endif
...
}
作为一个极端的例子,我已经看到了一个代码:
bool some_func(
int index,
#if SOME_DEFINE
bool flag,
#else
struct exception* ex,
#endif
void* buffer,
size_t size,
)
{
...
}
上面的此代码将带领任何项目到总计clasterfuck!
现在,应该如何完成。
抽象是您的朋友! 3个主要内容之间的一般分离:硬件,平台和编译器/工具链。有些人搞砸了编译器和平台。
所以,我创建了一个项目的虚拟示例,目录结构应该看起来像这样。它应该使您清楚地知道如何完成分离:
firmware/
├── bin
│ ├── arm
│ ├── windows_x64
│ └── windows_x86
├── build
│ ├── gcc
│ │ └── arm
│ ├── keil5
│ │ └── arm
│ └── vs2017
│ └── windows
├── include
│ └── firmware
│ └── frm.h
├── src
│ ├── arm
│ │ ├── frm_init_impl.c
│ │ └── frm_platform.h
│ ├── frm_idle.c
│ ├── frm_init.c
│ ├── frm_state.c
│ └── windows
│ ├── frm_init_impl.c
│ └── frm_platform.h
└── test
└── firmware_test
├── build
│ └── vs2017
│ └── windows
└── src
1。尽可能多地写平台对内部代码!在大多数情况下,它将简化开发和调试。例如,编写&在诸如Visual Studio之类的方便环境中,调试代码尽可能多,然后使用VI和GDB甚至Keil-这是我个人认为的垃圾!
2。一旦您拥有一个平台依赖性功能,就必须将其移至_impl.c
文件和所有平台的特定定义中_platform.h
文件
FrmStatus frm_init()
{
// Platform in-depended code
...
status = frm_init_impl(...);
if(FAILED(status))
{
...
}
// Platform in-depended code
...
}
在这种情况下,您将在不同的文件夹中具有不同的frm_init_impl
函数的实现,例如Windows模拟代码和真实的芯片特定代码。但是,无论如何,您的平台中依赖性frm_init
功能将始终保持不变!
3。通过在build
目录中使用不同的文件夹单独的编译器和工具链。然后,这些项目文件包括来自src
相应子文件夹的特定.c
和.h
文件;
例如,这种方法将帮助您轻松地使用Windows或仿真KEIL为固件开发测试套件。然后您可以为真实硬件创建测试项目。
如果我错过了一些东西,我将在此过程中进行编辑,我想社区的开发人员会有所帮助。