Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

c rmi implementation for embedded system

atmosphereatmosphere Member Posts: 3
Hi,

I posted this message in another part of the forum but I figure it is more relevant being here.

I'm current developing an automated embedded testing application, which is in 2 parts. On the host (PC) a C# application is to run and contain a list of invokable test functions. These same test functions are implemented on the target (HCS08) and they are connected via serial link.

Now the test functions need to have any kind of signature (return type doesn't really matter but i've decided to make it an int) which I've implemented as follows:

Each specific test function is wrapped in a fixture,

struct fixture {
char* name;
fixtureType type;
pFunc fPointer;
}

where pFunc is a typedef of a void (*)(void) which I cast based on the fixtureType. However, right now I have to write a seperate handling function to perform each specific cast. So for an fPointer which actually points to, for example an int (*)(int, byte, word) (which I typedef to lets say p_i_ibw) I have to write a specific handler function which does

((p_i_ibw)(fixtureImpl->fPointer))((int*)pArgs[0], (byte*)pArgs[1], (word*)pArgs[2])

pArgs (defined as byte** pArgs) is a pointer to pointers which contains the raw bytes for each var which was sent from host to target. Now I've defined macros to do most of this stuff for me, however I still have to write seperate handlers for each combination of arguments which bloats the code and will just get in the way during test development.

Has anyone here implemented or seen something similar to this? How did you get around this problem? Is there a better solution (probably =p)? Any comments or suggestions is very welcome.

Thanks

EDIT: Oops, forgot to mention the implementation has to be in C (no C++)

Comments

  • stoberstober Member Posts: 9,765 ✭✭✭
    I'm not great on templates but it sounds like c++ templates would be a good approach to your problem.
    =============================================
    never lie -- the government doesn't like the competition. (Author unknown)
  • LundinLundin Member Posts: 3,711
    : I'm not great on templates but it sounds like c++ templates would be
    : a good approach to your problem.
    : =============================================
    : never lie -- the government doesn't like the competition. (Author
    : unknown)


    I would not advise to use templates, or even C++, on a HCS08, because of the huge overhead. Also there is no HCS08 compiler which supports the C++ RTTI which would have been handy here.

    What you could do is to implement a smart function pointer type. Something like this:

    [code]
    typedef union
    {
    void(*void_void)(void);
    int(*int_void)(void);
    void(*void_int)(int);

    }GenericFuncPtr;


    typedef enum
    {
    NULL_PTR,
    VOID_VOID,
    INT_VOID,
    VOID_INT,

    }FuncPtrType;


    typedef struct fixture
    {
    /* ... */
    GenericFuncPtr fPointer;
    FuncPtrType fpType;

    } Fixture;
    [/code]
  • atmosphereatmosphere Member Posts: 3
    I pretty much had that except for the union (I think). The way I had done it is to write (for example w/ 1 function type)

    typedef void (*pFunc)(void);
    typedef void (*pvs)(short);

    typedef enum {
    p_void_short = 0,
    } fixtureType;

    typedef struct {
    fixtureType type;
    pFunc fPointer;
    } fixture;

    typedef void (*pHandler)(fixture*, byte**);

    // Then for my handler, I made a quick create macro //

    #define CASTVAL(type, location)
    (*((type*)location))

    #define MAKE_1ARG_HANDLER(name, fptype, type1)
    void name(fixture* pFix, byte** pArgs) {
    ((fptype)(pFix->fPointer))(CASTVAL(type1, pArgs[0]));
    }

    // So that I could do something like this (as a shorthand) //

    MAKE_1ARG_HANDLER(handler_v_s, pvs, short)

    pHandler handlerArr[] = { handler_v_s };

    void execute(fixture* pFixture, byte** pArgs) {
    handlerArr[pFixture->type](pFixture, pArgs);
    }

    void mytestfunction(short arg1) {
    printf("%d", arg1);
    }

    // Then in my main all I have to do is //
    void main() {
    fixture pvs = { "pvs", p_v_s, (pFunc)testfunc1 };
    // ....
    execute(&pvs, pArgs); // where pArgs[0] is a byte* to a short
    }

    As you can see I just use the enum in the fixture as an index into the handler array. What bugs me is that I have to do the stupid MAKE_1ARG_HANDLER (or create more to take 2 or 3 parameters) thing for every combination of arguments I need. I tried to get clever by writing something like

    #define typeFind(t, enumtype, type)
    (t == enumtype) ? type :

    #define DOCAST(t)
    typeFind(t, type_short, short)
    void*

    So I could do DOCAST(fixture->storedTypeEnum) and just add more typeFind's for each type and just make a long ass chain of ternaries but the compiler started complaining. Is there any other way to do this (with C) or am I missing something completely?

    Thanks
  • LundinLundin Member Posts: 3,711
    With my method you would call a function with that structure as parameter, then use a switch() on the enum to select function, then call this function with whatever parameters it needs.

    I'd avoid macros entirely.
Sign In or Register to comment.