如何在静态嵌入式操作系统中为资源创建复杂的宏检查?

时间:2014-08-15 13:32:44

标签: c macros c-preprocessor

我有一个嵌入式操作系统,需要通过编译时间静态定义其资源。

所以,例如。

#define NUM_TASKS 200

目前,我有一个头文件,每个开发人员都需要声明他/她需要的任务,有点像这样:

#define ALL_TASKS  ( \
                     1 + \  /* need one task in module A */
                     2   \  /* need two tasks in module B */
                   )

在编译操作系统期间,有一个检查:

#if (ALL_TASKS > NUM_TASKS)
#error Please increase NUM_TASKS in CONF.H
#endif

因此,当我编译并需要更多任务时,编译停止并明确通知静态操作系统将没有足够的任务来使其工作。

到目前为止一切顺利。


输入懒惰的程序员,忘记将他在模块A中添加的任务添加到目录x / y / z / foo / bar / baz /中的全局声明文件中。

我想要的是以下构造,我尝试的任何宏观技巧似乎无法实现:

让宏声明模块中所需的资源,如下所示:

OS_RESERVE_NUMBER_OF_TASKS(2)
模块中的

将全局任务数加2。

我的第一个粗略想法是这样的:

#define OS_RESERVE_NUMBER_OF_TASKS(max_tasks)       #undef RESOURCE_CALC_TEMP_MAX_NUM_TASKS \
                                                    #define RESOURCE_CALC_TEMP_MAX_NUM_TASKS    RESOURCE_CALC_MAX_NUM_TASKS + max_tasks \
                                                    #undef RESOURCE_CALC_MAX_NUM_TASKS  \
                                                    #define RESOURCE_CALC_MAX_NUM_TASKS     RESOURCE_CALC_TEMP_MAX_NUM_TASKS    \
                                                    #undef RESOURCE_CALC_TEMP_MAX_NUM_TASKS

但这不起作用,因为#define中的#define不起作用。


所以问题基本上是:

您是否知道如何将任务数量的计算分成多个文件(即模块本身),并在编译期间将该数字编入到定义的最大任务数中?

如果使用纯C预处理器无法解决这个问题,我将不得不等到我们将make系统更改为scons ...

2 个答案:

答案 0 :(得分:3)

您是否可以要求所有任务用户必须使用某些ID或类似的任务?

<强> tasks.h

enum {
    TASK_ID_TASK_A_1,
    TASK_ID_TASK_B_1,
    TASK_ID_TASK_B_2,
    NUM_TASKS
};
void * giveResource(int taskId, int resourceId);

<强> user_module_B.c

#include "tasks.h"
...
resource = giveResource(TASK_ID_TASK_B_1, resource_id_B_needs);

答案 1 :(得分:1)

您可以使用Boost预处理器库evaluated slots functionality在翻译一个单元的过程中更新宏的值。它定义了几个&#34;插槽&#34;可以通过预处理器代码将其视为可变全局变量,这可以让您在进行时添加值,而不是使用单个表达式定义它。

(它是纯粹的标准C,但实现它的代码相当复杂)

你不能在一行中完成它,因为它依赖于对#include的调用,这意味着你无法将它包装成漂亮的单行宏,但它会看起来像这样:

#define TASK_SLOT 2    //just pick one
#define ALL_TASKS BOOST_PP_SLOT(TASK_SLOT)

#define BOOST_PP_VALUE 1 + 2
#include BOOST_PP_ASSIGN_SLOT(TASK_SLOT)    // ALL_TASKS now evals to 3

#define BOOST_PP_VALUE 3 + ALL_TASKS
#include BOOST_PP_ASSIGN_SLOT(TASK_SLOT)    // ALL_TASKS now evals to 6

由于Drew评论(我可能误解了您的要求),这仅对一个翻译单元有效。如果您有一个核心NUM_TASKS,并且每个单元都可以添加其自己的 ALL_TASKS数字,那么这很好。

如果您需要在多个.c文件中递增值(以便最终ALL_TASKS是所有模块的总和,而不是一个),您需要将它们包装成{ {3}}这种技术起作用,大多数人认为这是一个坏主意。然后,更高级的构建系统可能是合适的,因为预处理器仅设计用于单个单元。