KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Adding your shell commands
Todo:
Expand this tutorial

How to do it:

  1. Think of a short command name, e.g. tdc, ip, etc.. For the example we will use our StarTrek transporter. We can name our transporter command transp.
  2. Create a .c file named shell_<shortname>.c, e.g. shell/shell_transp.c, and this to the Makefile SRC. You do not need to create the corresponding header file. The Makefile is located in the build directory.
  3. In your new C-file add a short command description, this will be used when you issue the help command:
    const char cmd_transp_help[] = "Run and diagnose the transporter";
  4. Create a command skeleton like this:
    bool cmd_transp_exec(int argc, const char *args[])
    {
    // fill in
    }
  5. Add the transp command to the shell configuration in cfg/cfg_shell.h, always surrounded by X().Don't forget to escape the MACRO when using multiple lines (trailing backslashes):
    #define SHELL_COMMANDS \
    X(help) \
    X(gpio) \
    X(delay) \
    X(i2c) \
    X(transp) // <- newly added
    Note
    Its important not to have any chracters after the backslashes, not even spaces. You now have everything set up. Starting the software and issusing the help command will even bring up the transp command including the short description. However, starting the transp command directly won't do anything. The next step is to implement it.
  6. Implementing the function is simple:

    • argc is the number of argument after the transp command. i.e. transp status will result in argc being 1, and transp with no arguments will result in it being 0.
    • argv is an array [0 : argc - 1] of strings , and will contain an entry for every argument. In the above case argc[0] will contain 'status'.

    Example implementation of the StarTrek transporter:

    #include <drv/wb/transp.h> // include our transporter
    const char cmd_transp_help[] = "Run and diagnose the transporter";
    bool cmd_transp_exec(int argc, const char *args[])
    {
    if (argc == 0 || argc == 1 && strcmp(args[0], "help") == 0) {
    // make a nice help if no input is entered or, `transp help` is set.
    puts("usage: transp <command> [<options>]");
    puts("where options may be:");
    puts(" status - show the status of the transporter");
    puts(" help - shows this help");
    puts(" send <x> <y> <z> - send to coordinates X, Y, Z");
    puts(" retr <x> <y> <z> - retrieve from coordinates X, Y, Z");
    return true; // command handled correctly
    } else if (argc == 1 && strcmp(args[0], "status") == 0) {
    // Show the transporter status string
    printf("Transporter Status: %s\n", transpStatusStr());
    return true;
    } else if (argc == 4) {
    // must be a send or retrieve command
    int x = atoi(argc[1]);
    int y = atoi(argc[2]);
    int z = atoi(argc[3]);
    // was a send command
    if (strcmp(args[0], "send")) {
    // if it returns false, the error message will be filled by the driver, so we just
    // need to pass the return value.
    return transpSend(x, y, z);
    }
    // of a retrieve command
    if (strcmp(args[0], "retr")) {
    // if it returns false, the error message will be filled by the driver, so we just
    // need to pass the return value.
    return transpRetrieve(x, y, z);
    }
    }
    // if the program arrives here it must be an invalid command.
    errSet(E_SHL_INVALID_CMD);
    return false; // we did not understand your command.
    }