Skip to content
Shahbaz Youssefi edited this page Jun 3, 2015 · 2 revisions

The Skeleton of Skinware Applications

The drivers, user applications and services all require to start up and cleanup URT, the real-time abstraction layer used by Skinware, and Skinware itself. Therefore, the skeleton for all these applications look the same. This page describes this skeleton. You may want to read how to write applications with URT first, to understand why things look the way they do.

This would be the skeleton of a program that uses URT:

#include <skin.h>

URT_MODULE_LICENSE("GPL");
URT_MODULE_AUTHOR("Shahbaz Youssefi");
URT_MODULE_DESCRIPTION("Sample emulation driver\n");

URT_MODULE_PARAM_START()
URT_MODULE_PARAM_END()

struct data
{
    int currently_unused;
};

static int start(struct data *d);
static void body(struct data *d);
static void stop(struct data *d);

URT_GLUE(start, body, stop, struct data, interrupted, done)

static void cleanup(void)
{
    /* clean up URT */
    urt_exit();
}

static int start(struct data *d)
{
    *d = (struct data){0};

    /* start up URT */
    if (urt_init())
        return EXIT_FAILURE;

    return 0;
}

static void body(struct data *d)
{
    done = 1;
}

static void stop(struct data *d)
{
    /* wait until a signal arrives */
    while (!interrupted)
        urt_sleep(10000000);

    cleanup();
}

In the above example, we simply startup the real-time abstraction layer, URT, and clean it up. Let's compile and run it:

$ gcc -std=gnu11 -c $(urt-config --user-cflags) main.c
$ gcc -std=gnu11 -o test_driver main.o -lskin -lurt $(urt-config --user-ldflags)
$ ./test_driver

Nothing happens in particular, but the program doesn't terminate either. Let's send a signal by pressing CTRL+C. The program now terminates. If you were using a back-end of URT that supports Linux kernel modules, you could try to build the same program as a kernel module, insmod and then rmmod it to see a similar behavior where nothing happens:

# Write a Kbuild file for the kernel to be able to build the code
$ cat Kbuild
obj-m += skin_test.o
skin_test-y = main.o

# Call the kernel Makefile
$ kp=/lib/modules/$(uname -r)/build
$ make -C $kp/build M=$PWD EXTRA_CFLAGS="$(urt-config --kernel-cflags)" \
       KBUILD_EXTRA_SYMBOLS="$kp/skin/Module.symvers $kp/urt/Module.symvers $(urt-config --kernel-symbols)" \
       modules

# Insert urt and skin modules
$ sudo modprobe urt
$ sudo modprobe skin

# Run your driver
$ sudo insmod ./skin_test.ko
$ sudo rmmod skin_test

Now, let's initialize and free Skinware as well.

#include <skin.h>

URT_MODULE_LICENSE("GPL");
URT_MODULE_AUTHOR("Shahbaz Youssefi");
URT_MODULE_DESCRIPTION("Sample emulation driver\n");

URT_MODULE_PARAM_START()
URT_MODULE_PARAM_END()

struct data
{
    struct skin *skin;
};

static int start(struct data *d);
static void body(struct data *d);
static void stop(struct data *d);

URT_GLUE(start, body, stop, struct data, interrupted, done)

static void cleanup(struct data *d)
{
    /* clean up Skinware if initialized */
    skin_free(d->skin);
    /* clean up URT */
    urt_exit();
}

static int start(struct data *d)
{
    *d = (struct data){0};

    /* start up URT */
    if (urt_init())
        return EXIT_FAILURE;

    /* start up Skinware */
    d->skin = skin_init();
    if (d->skin == NULL)
        goto exit_fail;

    return 0;
exit_fail:
    cleanup(d);
    return EXIT_FAILURE;
}

static void body(struct data *d)
{
    done = 1;
}

static void stop(struct data *d)
{
    /* wait until a signal arrives */
    while (!interrupted)
        urt_sleep(10000000);

    cleanup(d);
}

If you compile and run this, again you would see the same behavior as before.

Clone this wiki locally