How to develop an executable module

This doc presents how to develop an executable module (a program).

An executable module doesn't implement any interface and it also doesn't provides functions to other modules. In fact, it's an executable module that should use library and system modules to do something useful.

The development of an executable module is like the development of a C program in other operating systems, but with two details.

The first one is related to the tool that converts .o files (ELF), generated by the GCC compiler, to executable modules. The function that starts the program (main function in C programs) must have a special attribute. For instance:

void main(int argc, char *argv[], char *envp[]) __attribute__ ((section (".init")));

void main(int argc, char *argv[], char *envp[]) {
...
my code
...
}

This attribute says to put the main function in the example into ELF file's .init section.

The second detail is related to the use of library modules. Every library module used by the executable module must be started before it can be used and terminated before the executable module exit.

Here's an example of an executable module that uses two user interfaces:

#include "intermanager.h"
#include "usermodmanager.h"
#include "textvideo.h"
#include "lib/memmanager.h"
#include "lib/stringman.h"

int (*TV_Write)(const char*);

void main(void) __attribute__ ((section (".init")));

void StartLibs(void) {
    unsigned int i;
    int (*start)(void);

    i = 0;
    while ((start = UserModManager_UGetStartFunctionI(i++))) {
        if ((unsigned int)start != 0xffffffff && start()) {
            TV_Write("Error starting lib.\n");
            UserModManager_UExit(2);
        }
    }
}

void ShutdownLibs(void) {
    unsigned int i;
    int (*shutdown)(void);

    i = 0;
    while ((shutdown = UserModManager_UGetShutdownFunctionI(i++))) {
        if ((unsigned int)shutdown != 0xffffffff && shutdown()) {
            TV_Write("Error stoping lib.\n");
        }
    }
}

int GetTVFunction(void) {
    int ret;
    char outBuf[256];
    InterManager_OutputInfo *outInfo;

    /* get TextVideo functions */
    outInfo = (InterManager_OutputInfo*)outBuf;
    ret = InterManager_UGetOutputInfo(outInfo, sizeof(outBuf));
    if (ret) {
        return ret;
    }
    return UserModManager_UGetFunction(outInfo->names, outInfo->names+outInfo->interSize, TextVideo__UWRITE, UserModManager_SYS_FUNCTION, (void**)&TV_Write);
}

void main(void) {
    if (GetTVFunction()) {
        UserModManager_UExit(1);
    }
    StartLibs();
...
my code
...
    ShutdownLibs();
    UserModManager_UExit(0);
}

As one can see, the libraries are started and at the end they are shutdown.