any tips for parsing commands from a serial terminal?

16 Jul 2012

Hello all, I'm trying to find an efficient way to take commands from a serial terminal in a project.. Currently, I have an mBed connected via usb using putty to terminal into it... I've been experimenting and have come up with the following code based on some stuff I was able to scrounge up on the web...

char string[128];
void recvCMD(void const *argument) {
    while (true) {
        if (pc.readable()) {
            pc.scanf("%s", &string);
            const char *options[]={
                "led1",
                "led2",
                "led3",
                "led4",
                "led5",
                0
            };
            long option=-1;
            for (long a=0; options[a] && option<0; a++)
                if (!strcmp(string,options[a])) {
                    option=a;
                    switch (option) {
                        case 0:
                            pc.printf("%s\n", string);
                            led1Var = !led1Var;
                            break;
                        case 1:
                            pc.printf("%s\n", string);
                            led2Var = !led2Var;
                            break;
                        case 2:
                            pc.printf("%s\n", string);
                            led3Var = !led3Var;
                            break;
                        case 3:
                            pc.printf("%s\n", string);
                            led4Var = !led4Var;
                            break;
                        case 4:
                            pc.printf("%s\n", string);
                            break;
                        default:
                            pc.printf("No Command: %s\n", string);
                            osDelay(1000);
                            break;
                    }
                }
        }
    }
}

What I'd like to do, is something a little more structured.. Like accept a command such as "LED" and then use whatever follows it as a variable for that root command.... So later I can have something like a hierarchical list of commands...

Any help or word in a direction would be great!! Thanks!

17 Jul 2012

Hi,

One solution, as you seem to be part way there, is to create an individual function for each command or action you want to perform. Then you create an array of function pointers to these functions. You already have the array of commands so its then a case of working out what command was entered then using the index to call the function pointed to by the corresponding index entry in the function pointer array. This way you then lose the switch statement and if you add new commands its just a case of adding the function, a pointer to it in the function pointer array and an entry in the command array. The 2 arrays could even be combined into a struct or c++ class to keep everything together.

I would have added some example code but dont have any to hand. I've used this approach in previous, non mbed projects so have some examples on another system.

Hope this helps.

SRB

17 Jul 2012

Hello,

try a search for "CMDB" in the search function. There is a library available; I'm using this with effort.

Bye,

Michael

17 Jul 2012

Thank you both for the answers... Andrew, that does seem like a reasonable approach. Im my program, I do actually have it calling other functions... I tried simplifying for the example, but my question is how do I use variables in that example..? Say I want to have one command... 'device' and assign a variable or qualifier of some sort such as 'connect' or 'reboot', etc..? I've noticed with my method having a space in the command causes problems.. I like the idea of two arrays instead of the switch statement.. I'll have to do some thinking I guess about how to split off the second/third words and pass those to whatever function it calls...(?)...

Michael, thank you for pointing me at CMDB .. That looks pretty hefty! I'm going to have to take a better look when I have a few minutes.. ;) Looks like a pretty robust solution though.. I can see why you say 'with effort'...!