简体   繁体   中英

How do I create a sophisitcated macro check for resources in a static embedded OS?

I have an embedded OS that needs its resources to be defined statically by compile time.

So eg

#define NUM_TASKS 200

At the moment, I have one header file where every developer needs to declare the tasks he/she needs, kind of like this:

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

and during compilation of the OS, there is a check:

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

So when I compile and more Tasks are needed the compilation stops and gives explicit notice that the static OS won't have enough tasks for this to work.

So far so good.


Enter the lazy programmer that forgets to add the tasks he added in module A to the global declaration file in directory x/y/z/foo/bar/baz/.

What I would like is the following construct, which I can't seem to achieve with any macro tricks I tried:

Have macros to declare the resources needed in a module like so:

OS_RESERVE_NUMBER_OF_TASKS(2)

in the modules adds 2 to the global number of Tasks.

my first rough idea was something like this:

#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

but that doesn't work because a #define in a #define does not work.


So the question basically is:

Do you have an idea how it would be possible to split the calculation of the number of tasks into multiple files (namely the modules themselves) and have that number comapred to the defined max number of tasks during compile time?

If this isn't solvable with pure C preprocessor, I'll have to wait until we change the make system to scons...

Can you require that tasks have some ID or similar which all task users must use?

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);

You can update the value of a macro in the course of translating one unit using the Boost Preprocessor library's evaluated slots functionality . It defines several "slots" that can be treated as mutable global variables by preprocessor code, which will let you add to a value as you go along rather than defining it with a single expression.

(It's pure standard C, but the code that implements it is rather complicated)

You can't do it in one line, because it relies on calls to #include , and that means you can't wrap it up into a pretty one-liner macro, but it would look something like this:

#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

As Drew comments (I may have misunderstood your req.), this is only valid for one translation unit. Which is fine if you have a central NUM_TASKS and each unit is allowed to add up its own ALL_TASKS figure.

If you need the value to increment across multiple .c files (so that the final ALL_TASKS is the total across all modules, not for one), you'd need to wrap them up into a unity build for this technique to work, which most people reckon is a bad idea. A more advanced build system would then probably be appropriate, because the preprocessor is only designed to work on single units.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM