CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Implementing a command line interface

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

Implementing a command line interface
PostPosted: Sun Sep 10, 2006 7:28 am     Reply with quote

Hi,

I am looking for algorithms to implement a simple command line interface, like the ones from DOS and Matlab.

The two ways I can think are a state machine and comparing full commands against a "database".

Which way do you think I should try?

Thank you.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sun Sep 10, 2006 11:37 am     Reply with quote

Here is an example of what I do. It was written for the C18 compiler so you will have to work around the pointer to rom.

Code:

/*$F********************************************************************
*
* Copyright (C)pa 1997-2004 Lithonia Lighting
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Functional
* Description:  This module is designed to provide diagnostic terminal
*               support
*
* $Log: /Synergy/Input Card/Source/terminal.c $
*
* 2     8/05/04 4:58p Mark
*
* 1     7/30/04 4:17p Mark
*
*********************************************************************/
/* compiler includes */
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <i2c.h>

/* our includes */
#include "stdint.h"
#include "mystring.h"
#include "comm.h"
#include "terminal.h"
#include "eeprom.h"
#include "stptok.h"
#include "bi.h"
#include "ai.h"
#include "version.h"
#include "sprintf.h"
#include "util.h"
#include "stptok.h"
#include "sscanf.h"
#include "selftest.h"
#include "hardware.h"
#include "abus.h"

/* local typedefs */
typedef rom struct  _cmd_t
{
  const rom char  *pStr;  /* command */
  void (*pFunction) (char *pCmd, char *pArgs); /* command function */
  const rom char  *pDescription;  /* command description (for help) */
} COMMAND_DATA;

/* function prototypes */
static void         PrintStatus(char status);

static void         SelfTestCommand(char *pCmd, char *pArgs);
static void         VirginCommand(char *pCmd, char *pArgs);
static void         BootCommand(char *pCmd, char *pArgs);

       void         VersionCommand(char *pCmd, char *pArgs);
static void         ABUSCommand(char *pCmd, char *pArgs);
static void         InputCommand(char *pCmd, char *pArgs);
static void         StatusCommand(char *pCmd, char *pArgs);
static void         EEPROMDumpCommand(char *pCmd, char *pArgs);
static void         HostModeCommand(char *pCmd, char *pArgs);
static void         ReInitCommand(char *pCmd, char *pArgs);
static void         RestartCommand(char *pCmd, char *pArgs);

static void         THelpCommand(char *pCmd, char *pArgs);
static void         VHelpCommand(char *pCmd, char *pArgs);

static bool         CommandHandler(char *pArgs, COMMAND_DATA *pCommandData);
static void         VerboseHelpHandler(COMMAND_DATA *pCommandData);
static void         TerseHelpHandler(char *pArgs, COMMAND_DATA *pCommandData);
void                TerminalHandler();

#pragma idata Terminal_Table
static COMMAND_DATA CommandData[] =
{
  /* hidden commands - description is NULL */
  { { "help"      },   VHelpCommand,     { NULL                     } },
  { { "TEST"      },   SelfTestCommand,  { NULL                     } },
  { { "VIRGINIZE" },   VirginCommand,    { NULL                     } },
  { { "bootmode"  },   BootCommand,      { NULL                     } },
  { { "dump"      },   EEPROMDumpCommand,{ NULL                     } },

  /* application commands */
  { { "abus"      },   ABUSCommand,      { "sends command out abus" } },
  { { "host"      },   HostModeCommand,  { "allows this device to act as host" } },
  { { "input"     },   InputCommand,     { "input control"          } },
  { { "restart"   },   RestartCommand,   { "restart device"         } },
  { { "restore"   },   ReInitCommand,    { "restore defaults"       } },
  { { "status"    },   StatusCommand,    { "input status"           } },
  { { "ver"       },   VersionCommand,   { "sofware version"        } },
  { { "??"        },   VHelpCommand,     { "verbose help"           } },
  { { "?"         },   THelpCommand,     { "terse help"             } },
  { { NULL        },   NULL,             { NULL                     } },
};


#pragma idata vars

/* *************************************************************************
  DESCRIPTION:  Prints status of ok or fail. PARAMETERS: port (IN) port to
                print to status (IN) TRUE if OK, FALSE if fail GLOBALS:
                none
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void PrintStatus(
  char            status) /* FIX ME: add comment */
{
  if (status)
    Comm_PutRomString("Ok\r\n");
  else
    Comm_PutRomString("Fail\r\n");

  return;
}

/* *************************************************************************
  DESCRIPTION:  List the IO Mapping for an input
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
void EEPROMDumpCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  char            buf[MAX_LINE_LEN];  /* local buffer */
  uint16_t        n  = 0;      // index to counter
  uint16_t        num;
  uint16_t        row = 0;

  (void)pCmd;
  (void)pArgs;

  Comm_PutRomString("   ");
  for (num = 0; num < 16; num++)
  {
    sprintf(buf, "%02x ", num);
    Comm_PutString(buf);
  }

//  for (n = 0; n <= SEEPROM_SIZE; n++)
  for (n = 0; n <= 64; n++)
  {
    if (!(n & 0x0F))
    {
      sprintf(buf, "\r\n%02x ", row);
      Comm_PutString(buf);
      row++;
    }
    num = EEPROM_Read(n);
    sprintf(buf, "%02x ", num);
    Comm_PutString(buf);
  }
  Comm_PutRomString("\r\n");

}

/* *************************************************************************
  DESCRIPTION:  Allows this card to act as ABUS host
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
void HostModeCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  (void)pCmd;

  if (strncmpipgm2ram(pArgs, "true", 4) == 0)
  {
    ABUS_HostMode(TRUE);
    PrintStatus(TRUE);
  }
  else if (strncmpipgm2ram(pArgs, "false", 5) == 0)
  {
    ABUS_HostMode(FALSE);
    PrintStatus(TRUE);
  }
  else
  {
    Comm_PutRomString("Examples:\r\n");
    Comm_PutString(pCmd);
    Comm_PutRomString(" TRUE - starts host mode\r\n");
    Comm_PutString(pCmd);
    Comm_PutRomString(" FALSE - exits host mode\r\n");
  }

  return;
}

/* *************************************************************************
  DESCRIPTION:  Sends command out the ABUS
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void ABUSCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  #define BUFFER_SIZE 40
  uint8_t buf[40];
  char temp[5];
  uint8_t i = 0;

  (void)pCmd;
  buf[0] = TX_READY;

  while (pArgs)
  {
    i++;
    if (i >= BUFFER_SIZE)   
    {
      PrintStatus(FALSE);
      return;
    }
    pArgs = stptok(pArgs, temp, sizeof(temp), " ");
    if (strlen(temp) > 3)
    {
      PrintStatus(FALSE);
      return;
    }
    buf[i] = atob(temp);
  }

  if ( buf[1] == ABUS_Fixed_Address )
  {
    buf[0] = PROCESS_OK;
    ABUS_Process_Message((union RX_MSG*)buf, sizeof(buf));
  }
  else
  {
    if (ABUS_Transmit(buf, sizeof(buf)))
      PrintStatus(TRUE);
    else
      PrintStatus(FALSE);
  }

  return;

}

/* *************************************************************************
  DESCRIPTION:  Restarts the event scheduler GLOBALS: none
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void RestartCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  (void)pCmd;
  (void)pArgs;
  {
    _asm clrwdt reset _endasm
  }
}

/* *************************************************************************
  DESCRIPTION:  Re-initializes all the modules data GLOBALS: none
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void ReInitCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  (void)pCmd;
  (void)pArgs;

  /* Reinit */
  Hardware_Initialize_Device();
  PrintStatus(TRUE);

  return;
}

/* *************************************************************************
  DESCRIPTION:  Programs the switch data
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void InputCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  char        buf[MAX_LINE_LEN];  /* local buffer */
  uint8_t     address;
  uint8_t     count;

  // expecting: "INPUT 1 ON " "INPUT 1 OFF"
  if (pArgs)
  {
    count = sscanf(pArgs, "%b %s", &address, buf);
    // Our address is one less than the user address
    address--;
    if (address >= HARDWARE_MAX_BINARY_INPUTS)
    {
      PrintStatus(FALSE);
      return;
    }

    if (count == 2)
    {
      if (strcmpipgm2ram(buf, "ON") == 0)
      {
        BI_Event(address, ON);
        PrintStatus(TRUE);
      }
      else if (strcmpipgm2ram(buf, "OFF") == 0)
      {
        BI_Event(address, OFF);
        PrintStatus(TRUE);
      }
      else
      {
        PrintStatus(FALSE);
      }
    }
  }
  // User must need help
  else
  {
    Comm_PutRomString("Examples:\r\n");
    Comm_PutString(pCmd);
    Comm_PutRomString(" 1 ON\r\n");
    Comm_PutString(pCmd);
    Comm_PutRomString(" 1 OFF\r\n");
  }
  return;
}

/* *************************************************************************
  DESCRIPTION:  Prints the input status
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void StatusCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  char      buf[MAX_LINE_LEN];  /* local buffer */
  uint8_t    input = 0;

  (void)pCmd;
  (void)pArgs;

  while (input < HARDWARE_MAX_BINARY_INPUTS)
  {
    sprintf(buf, "INPUT %-2b ", (char)(input + 1));
 
    Comm_PutString(buf);
    if ( BI_Get_Level(input) )
      Comm_PutRomString("(1) ACTIVE");
    else
      Comm_PutRomString("(0) INACTIVE");

    Comm_PutRomString("\r\n");
    input++;
  }
  input = 0;
  while (input < HARDWARE_MAX_ANALOG_INPUTS)
  {
    sprintf(buf, "PHOTOCELL %-2b %b\r\n", (char)(input + 1), (char)AI_Get_Level(input));
    Comm_PutString(buf);
    input++;
  }
  return;
}



/* *************************************************************************
  DESCRIPTION:  Displays the version of the code.
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
void VersionCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  char  buf[MAX_LINE_LEN];  /* local buffer */
  (void)pCmd;
  (void)pArgs;

  sprintf(buf, "Module:  %S\r\nVersion: %S\r\n", PROGRAM_NAME, CODE_VERSION);
  Comm_PutString(buf);

  sprintf(buf, "Built:   %S\r\nAddress: %b\r\n", BUILD_DATE, Hardware_Get_Fixed_Address());
  Comm_PutString(buf);

  return;
}

/* *************************************************************************
  DESCRIPTION:  Puts the device into the bootloader
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void BootCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  /* To enter bootmode, write 'b' to the last location in the £
   * internal eeprom */
  if (pArgs)
  {
    /* This is an attempt to try and make it difficult to enter
     * boot mode with run away code */
    if (*pArgs == 'b')
    {
      EEPROM_Write_Internal(0xFF, *pArgs);
 
      /* restart the application */
      {
        _asm reset _endasm
      }
    }
  }
  PrintStatus(FALSE);
}

/* *************************************************************************
  DESCRIPTION:  Executes the self test mode
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void SelfTestCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  Selftest_Execute();
}

/* *************************************************************************
  DESCRIPTION:  Sets the EEPROMS to the "virgin" state
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void VirginCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  uint16_t  i;

  for (i = 0; i <= EEPROM_LAST_ADDRESS; i++)
  {
    EEPROM_Write(i, 0xFF);
    ClrWdt();
  }

  for (i = 0; i < 0xFF; i++)
  {
    EEPROM_Write_Internal(i, 0xFF);
    ClrWdt();
  }

  /* Write a 0 to the last location of the EEPROM to prevent going into £
   * bootmode */
  EEPROM_Write_Internal(i, 0x00);

  PrintStatus(TRUE);

  /* wait for a wdt timeout */
  while (1);
}

/* *************************************************************************
  This section consists of generic routines handling the commands from a
  data table
 *************************************************************************** */

/* *************************************************************************
  DESCRIPTION:  Handles the terminal operation PARAMETERS: port (IN)
                communication port pCmd (IN) command arguments GLOBALS:
                none
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static bool CommandHandler(
  char            *pArgs,         /* FIX ME: add comment */
  COMMAND_DATA    *pCommandData)  /* FIX ME: add comment */
{
  static char cmd[MAX_LINE_LEN];  /* local buffer */
  bool        found = 0;          /* valid command? */

  if (pArgs)
  {
    /* parse and remove the only the first command */
    pArgs = stptok(pArgs, cmd, sizeof(cmd), " ");

    /* find and execute command function */
    while (pCommandData->pStr != NULL)
    {
      if (strcmpipgm2ram(cmd, pCommandData->pStr) == 0)
      {
        if (pCommandData->pFunction != NULL)
        {
          (void)strupr(cmd);
          (void)pCommandData->pFunction(cmd, pArgs);
        }
        found = 1;
        break;
      }
      pCommandData++;
    }
  }
  return (found);
}

/* *************************************************************************
  DESCRIPTION:  Displays the help information strings PARAMETERS: port (IN)
                communication port pCommandData (IN) data table GLOBALS:
                none
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void VerboseHelpHandler(
  COMMAND_DATA    *pCommandData)  /* FIX ME: add comment */
{
  char  buf[MAX_LINE_LEN];  /* string to print */

  /* spew the commands and their help */
  while (pCommandData->pStr != NULL)
  {
    if (pCommandData->pDescription != NULL)
    {
      sprintf(buf, "%-10S - %S\r\n", pCommandData->pStr, pCommandData->pDescription);
      Comm_PutString(buf);
    }
    pCommandData++;
  }
  Comm_PutRomString("\r\n");

  return;
}

/* *************************************************************************
  DESCRIPTION:  Handles the display of help - verbose PARAMETERS: port (IN)
                communication port pCmd (IN) command arguments pCommandData
                (IN) data table GLOBALS: none
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void TerseHelpHandler(
  char            *pArgs,         /* FIX ME: add comment */
  COMMAND_DATA    *pCommandData)  /* FIX ME: add comment */
{
  char  buf[MAX_LINE_LEN];  /* string to print */
  uint8_t count = 0;          /* to put 4 words on a line */

  /* if the user wanted help about a specific item, show that item */
  if (pArgs)
  {
    while (pCommandData->pStr != NULL)
    {
      if (strcmpram2pgm(pCommandData->pStr, pArgs) == 0)
      {
        if (pCommandData->pDescription != NULL)
        {
          sprintf(buf, "%-10S - %S\r\n", pCommandData->pStr, pCommandData->pDescription);
          Comm_PutString(buf);
        }
        break;
      }
      ++pCommandData;
    }
  }

  /* print them all */
  else
  {
    count = 0;
    while (pCommandData->pStr != NULL)
    {
      if (pCommandData->pDescription != NULL)
      {
        sprintf(buf, "%-8S", pCommandData->pStr);
        Comm_PutString(buf);
        count++;
        if (count >= 4)
        {
          Comm_PutRomString("\r\n");
          count = 0;
        }
        else
          Comm_PutRomString("\t");
      }
      ++pCommandData;
    }
    Comm_PutRomString("\r\n");
  }

  return;
}

/* *************************************************************************
  DESCRIPTION:  Displays the help information strings PARAMETERS: port (IN)
                communication port pCmd (IN) optional arguments GLOBALS:
                none
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void THelpCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  (void)pCmd;

  /* spew the program data in a terse manner */
  TerseHelpHandler(pArgs, &CommandData[0]);

  return;
}

/* *************************************************************************
  DESCRIPTION:  Displays the help information strings PARAMETERS: port (IN)
                communication port pCmd (IN) optional arguments GLOBALS:
                none
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
static void VHelpCommand(
  char            *pCmd,  /* (IN) command string */
  char            *pArgs) /* (IN) optional arguments */
{
  (void)pArgs;
  (void)pCmd;

  /* spew the program data */
  VerboseHelpHandler(&CommandData[0]);

  return;
}

/* *************************************************************************
  DESCRIPTION:  Handles the terminal operation PARAMETERS: port (IN)
                communication port GLOBALS: none
  RETURN: none
  ALGORITHM:  none
  NOTES:  none
 *************************************************************************** */
void TerminalHandler()
{
  static uint8_t  index = 0;        /* index of buffer */
  char          ch;                 /* character from buffer */
  static char   buf[MAX_LINE_LEN];  /* for the line entry */

  while (TRUE)
  {
    if ( !Comm_IsBufferReady() )
      return;
    ch = Comm_GetChar();

    switch (ch)
    {
      /* illegal characters */
      case '\a':
      case '\f':
      case '\n':
      case '\t':
      case '\v':
      /* escape */
      case 0x1B:
        break;

      /* backspace */
      case '\b':
        if (index)
        {
          --index;

          /* do a destructive backspace */
          Comm_PutChar('\b');
          Comm_PutChar(' ');
          Comm_PutChar('\b');
        }
        break;

      /* enter */
      case '\r':
        Comm_PutChar('\r');
        Comm_PutChar('\n');
        buf[index] = '\0';

        /* did we get something? */
        if (index)
        {
          if (!CommandHandler(buf, &CommandData[0]))
            Comm_PutRomString("Invalid Command. Type ? for help.\r\n");
        }

        buf[0] = '\0';
        index = 0;

        /* write the prompt */
        Comm_PutChar('>');
        break;

      /* all the rest of the characters */
      default:
        /* leave room for null at the end */
        if (index < (MAX_LINE_LEN - 1))
        {
          buf[index] = ch;
          if (!ch)
            ch = 0;
          Comm_PutChar(ch);
          index++;
        }
        break;
    }
  }
}




and

Code:

/*$F********************************************************************
*
*  stptok() -- public domain by Ray Gardner, modified by Bob Stout,
*  Steve Karg, and Mark Norton
*
* Functional
* Description:  This file contains the stptok function
*
* $Log: /Synergy/Input Card/Source/stptok.c $
*
* 1     7/30/04 4:17p Mark
*
* 6     10/08/03 5:02p Mark
*
* 5     10/07/03 4:48p Mark
*
*
*********************************************************************/
#include <stddef.h>

/* *************************************************************************
  DESCRIPTION:  You pass this function a string to parse, a buffer to
                receive the "token" that gets scanned, the length of the
                buffer, and a string of "break" characters that stop the
                scan. It will copy the string into the buffer up to any of
                the break characters, or until the buffer is full, and will
                always leave the buffer null-terminated. It will return a
                pointer to the first non-breaking character after the one
                that stopped the scan.

  RETURN: It will return a pointer to the first non-breaking character
          after the one that stopped the scan or NULL on error or end of
          string.

  ALGORITHM:  none
 *************************************************************************** */
char *stptok(
  const char      *s,     /* string to parse */
  char            *tok,   /* buffer that receives the "token" that gets scanned */
  size_t          toklen, /* length of the buffer */
  const rom char  *brk)   /* string of break characters that will stop the scan */
{
  char            *lim; /* limit of token */
  const rom char  *b;   /* current break character */

  /* check for invalid pointers */
  if (!s || !tok || !brk)
    return (NULL);

  /* check for empty string */
  if (!*s)
    return (NULL);

  lim = tok + toklen - 1;
  while (*s && tok < lim)
  {
    for (b = brk; *b; b++)
    {
      if ((*s == *b) || (*s == '\r') || (*s == '\n'))
      {
        *tok = 0;
        for (++s, b = brk; *s && *b; ++b)
        {
          if (*s == *b)
          {
            ++s;
            b = brk;
          }
        }

        if (!*s)
          return (NULL);
        return (char *)s;
      }
    }

    *tok++ = *s++;
  }

  *tok = 0;

  if (!*s)
    return (NULL);
  return (char *)s;
}


Last edited by Mark on Mon Sep 11, 2006 4:52 am; edited 2 times in total
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Sun Sep 10, 2006 2:46 pm     Reply with quote

Thank you for the code, it will be a good learning tool.

I think that the CommandHandler() function, maybe the one that calls stptok(), is not included.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sun Sep 10, 2006 9:04 pm     Reply with quote

future wrote:
Thank you for the code, it will be a good learning tool.

I think that the CommandHandler() function, maybe the one that calls stptok(), is not included.


Had to disable HTML in the post Embarassed
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Mon Sep 11, 2006 4:47 am     Reply with quote

I saw that you edited the post, did you add something?

I still can't see the function..
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Mon Sep 11, 2006 4:53 am     Reply with quote

future wrote:
I saw that you edited the post, did you add something?

I still can't see the function..
Try it now
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Sat Sep 16, 2006 5:14 pm     Reply with quote

Thank you very much!
Guest








Convert to CCC
PostPosted: Wed Apr 11, 2007 3:59 am     Reply with quote

Hi,

Is there anybody convert to CCS C this code?

Thanks.


CENAtronics
srhoar



Joined: 17 Apr 2007
Posts: 3

View user's profile Send private message

PostPosted: Sat May 05, 2007 9:10 am     Reply with quote

Here is the state machine and parser I use for most of my projects.

It is fairly simple to modify.

Code:

#include <string.h>
#include <stdlib.h>

typedef enum { FAULT = 0, STBY, ARMED, FIRE } State_Type;
const char      state_text[4][6] = { "FAULT", "STBY", "ARMED", "FIRE" };

void         state_table(void);

State_Type      curr_state = FAULT;

char         line[17];   /* variables for parser */
int            i, c;

/* LIST ALL COMMAND TO RECOGNIZE HERE */
#define NUM_COMMANDS   10
#define EOL            '\r'

const char      commands[NUM_COMMANDS + 1][10] = {
            "FIRE", "STBY", "STAT", "SHOTS",
            "ARM", "PRF", "RED", "TEST",
            "HELP","NOHV" };


/* function protoypes void */
void         safe_system(void);
void         state_stby(void);
void         state_armed(void);
void         state_fire(void);
void         state_fault(void);
void         debug_test(void);
void         get_command(void);
void         send_stat(void);
void         delay_s(int);
void         help(void);

int            delay = 0;   /* used for state delays */

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void main()
{
   /* CHIP SETUPS */
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED, 0, 1);
   output_high(PIN_B6);   /* prevent slave resets */
   port_b_pullups(TRUE);

   enable_interrupts(INT_RB);
   enable_interrupts(GLOBAL);

   safe_system();

   while(1)
   {
      /* wait for command */
      get_command();

      printf("STATE=%d\n\r", curr_state);
      state_table();
      delay_ms(delay);
      delay = 0;
   }
}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void state_table()
{
   switch(curr_state)
   {
   case FAULT: state_fault(); break;
   case STBY:   state_stby(); break;
   case ARMED: state_armed(); break;
   case FIRE:   state_fire(); break;
   }
}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void safe_system(void)
{
   printf("SAFE ");
   help();
}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void state_stby()
{
   printf("STBY ");
}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void state_armed()
{
   printf("ARMED ");
   return;

}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void state_fire()
{
      curr_state = ARMED;
      return;
   }
   


/*
 =======================================================================================================================
 =======================================================================================================================
 */
void state_fault()
{
   printf("FAULT ");
}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void debug_test()
{

}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void get_command()
{
   /*~~~~~~~~~~~~~~~~~~~*/
   /* NEW PARSER */
   char   index, j;
   char   found = 0;
   char   command = 0;
   char   lookup_str[12];
   char   name[17];
   char   val[17];
   /*~~~~~~~~~~~~~~~~~~~*/

   /*
    * printf("Parser\r\n");
    */
   while(1)
   {
      state_table();
      printf(">");
      for(i = 0; i < 17; i++) line[i] = 0;   /* clear the line buffer */
      for(i = 0; i <= 16; i++)
      {                  /* get a whole line but limit it to buffer size */
         if((c = getch()) == EOL) break;
         line[i] = c;      /* add the character to the line buffer */
      }                  /* end for loop */

      if(i < 3) continue;      /* may be a blank line, just skip it, variables must be more than 3 */
      line[i] = '\0';

      for(i = 0; (line[i] != ' ') && (i < 10) && (line[i] != '\0'); i++)
      {
         name[i] = line[i];   /* extract the first word up to a space character */
      }

      name[i] = '\0';         /* terminate the string! */

      if(line[i] != '\0')
      {
         i++;            /* skip the space character */
         j = 0;
         for(; (i < 10) && (line[i] != '\0'); i++)
         {
            val[j++] = line[i]; /* now extract the rest of the line, the "value" */
         }

         val[j] = '\0';
      }

      /* LOOK UP COMMAND */
      found = 0;               /* set to not found to start */
      command = 0;
      for(index = 0; index < NUM_COMMANDS; index++)
      {
         sprintf(lookup_str, "%s", commands[index]);
         if(strcmp(name, lookup_str) == 0)
         {
            found = 1;         /* COMMAND IS IN TABLE */
            command = index;
         }
      }

      if(found == 1)            /* COMMAND IS VALID */
      {
         printf("OK\r\n");
         switch(command)
         {
         case 0:               /* FIRE */if(curr_state == ARMED) curr_state = FIRE; break;
         case 1:               /* STBY */curr_state = STBY; break;
         case 2:               /* STAT */send_stat(); break;
         case 3:               /* SHOTS X */shots = atol(val); break;
         case 4:               /* ARM */if(curr_state == STBY) curr_state = ARMED; break;
         case 5:               /* PRF */prf = atol(val); break;
         case 6:               /* RED */red(); break;
         case 7:               /* TEST */debug_test(); break;
         case 8:               /* HELP */help(); break;
         case 9:               /* NOHV */nohv=1; break;
         default:   break;
         }
      }
      else
         printf("ERROR\r\n");   /* COMMAND NOT FOUND */
      state_table();
   }
}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void send_stat()
{
   printf("\n\rSTAT\n\r");

}



/*
 =======================================================================================================================
 =======================================================================================================================
 */
void help()
{
   printf("\nBlackjack controller V1.0\n\r");
   printf("Commands:\n\r");
   printf("STAT - Status of system\n\r");
   printf("STBY - Put system in Standby\n\r");
   printf("ARM  - Arm the system and turn on the SSU\n\r");
   printf("FIRE - Fire the system\n\r");
   printf("SHOTS # - Set the number of shots to Fire\n\r");
   printf("PRF # - Set the PRF of the System\n\r");
   printf("\n\r");
   printf("Written by Robert 'Red' Hoar for LMMFC - Dallas\n\r");
   printf("\n\r");
}

_________________
===================
|Robert 'Red' Hoar
|
|Program Manager
|Directed Energy RF
===================
MikeW



Joined: 15 Sep 2003
Posts: 184
Location: Warrington UK

View user's profile Send private message

Mark, can you help ?
PostPosted: Sat May 05, 2007 10:07 am     Reply with quote

I do wish Mark would convert his code to CCS from microchip C.

I think his approach is very good, and would make the basis of a very flexible command line parser.

Unfortunately, I dont have the C skill to do it.

please Mark if V4.033 is now functional for pointer to rom etc, could you have a go

Mike
Steve H.
Guest







PostPosted: Tue May 08, 2007 3:05 pm     Reply with quote

Future - While the parser presented is very, very good you might find a simpler one suitable for your needs. I designed a very simple one several years back. You can download it from the ARRL.org website at,

arrl.org/files/

search for PIC_DAS

It was written for PCM version 2.6XX but I think it should run under 4.XXX.

At any rate - it is a simpler - albeit not as functionally nice alternative, but it does work.

HTH - Steve H.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group