我正在为具有C 的e mbedded系统进行开发,并设置了一个环境,使我能够在没有目标平台的情况下进行本地测试,由#define TESTING_ENABLED
启用。
这将很快扩展到包括项目的所有方面,因此在平台之间切换时管理每个测试定义可能会变得乏味。
我可以通过makefile设置#define directive
或检测不同编译器的使用吗?
答案 0 :(得分:1)
出于某种原因,使用#define
和#if
通常是一个非常糟糕的主意,代码变为:
不可读的
不可移植的
3.不可维护;
一般的经验法则是,您只能在头文件中包含#define
和#if
。一旦预处理器进入源文件,就可以在维护和可移植性方面成为项目失败的明确途径。
所以,不惜一切代价避免,代码如下:
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
目录中的不同文件夹分隔编译器和工具链。然后,这些项目文件包含来自.c
的相应子文件夹的特定.h
和src
个文件;
这种方法可以帮助您轻松地为您的固件开发测试套件,例如使用模拟窗口或仿真Keil。然后,您可以为真实硬件创建测试项目。
如果我错过了某些内容,我会在此过程中对其进行编辑,社区开发人员会提供帮助,我猜。