Making FreeRTOS CLI more CLI-ish : registering commands

 Now that we have basic functionality lets make some custom commands.

The prototype for commands can be seen here 

I am going to make a simple command called "ok" and it will display a message saying that everything is ok. 

Below is my commands.c file in its entirety as of right now:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "FreeRTOS.h"
#include "FreeRTOS_CLI.h"
#include "main.h"
#include "main_app.h"

static BaseType_t cmd_ok(int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString);

static BaseType_t cmd_ok(int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString)
{
    const char *const okMessage = "everything OK! \r\n";

    memset(pcWriteBuffer, 0x00, xWriteBufferLen);
    /* Generate a table of task stats. */
    strcpy(pcWriteBuffer, okMessage);
    /* There is no more data to return after this single string, so return
        pdFALSE. */
    return pdFALSE;
}

static const CLI_Command_Definition_t xCmdOK = {
    "ok",                               // command to type
    "ok :\r\n Shows an OK message\r\n", // help string
    cmd_ok,                             // command handler
    0                                   // num of pasrameters to expect
};

void vRegisterCLICommands(void)
{
    FreeRTOS_CLIRegisterCommand(&xCmdOK);
}


  • Line 6 : is the function prototype for my command. That has to be the function signature of all FreeRTOS CLI commands.
  • Lines 8 - 18 : Is the implementation of the function itself. 
  • Line 10 : This is simply a string with the message I want to display
  • Line 12 : Clears the buffer that FreeRTOS  CLI uses to print messages from within commands
  • Line 14 : Copies the string into the buffer
  • Line 17 : Returns false, I will sure you later on what condition you want to return true
  • Line 20 - 25 : Makes a struct that is used to register a command.
  • Line 20 : This is a FreeRTOS predefined struct type and xCmdOk is simply the name I assigned this command when registering it.
  • Line 21 : Is the string you will type in the CLI to call the command
  • Line 22 : Is the help message that will correspond to this command 
  • Line 23 : Is the function that will be called to handle the command
  • Line 24 : Is the number of parameters this command expects
  • Line 27 : Is a function I made that registers all commands .
Now we can go back to main_app.c and in out command line task we can call the register function right before the for loop like so:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
void vCommandConsoleTask(void *pvParameters)
{
    int8_t cInputIndex = 0;
    BaseType_t xMoreDataToFollow;
    /* The input and output buffers are declared static to keep them off the
     * stack. */
    static int8_t pcOutputString[MAX_OUTPUT_LENGTH], pcInputString[MAX_INPUT_LENGTH];

    vRegisterCLICommands();

    for (;;)
    {

Run the application and type "help" , also type "ok" and observe the output. 

So how can we improve this basic CLI?

  1. We can make it recognize backspace so that we can delete typos
  2. Make it recognize the left and right arrow keys so that we can move across our typed command and change a character
  3. We can implement the up and down keys to show history of previously typed commands
  4. We can add tab hints, so that when you type something and press tab t will show you all commands that match the current characters you have typed
  5. We can improve the help string printing mechanism
  6. We can have an actual command prompt like "CLI:>>" 
  7. We can add the ability to modify the prompt to display any ongoing activity. For example if you have a command that starts a background test your command prompt will change  to something like " (test active ) CLI: >>" This makes it dynamic and informative.
Read on to the next post to start implementing all of these features.





Comments

Share your comments with me

Archive

Contact Form

Send