This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

cli

Hi,

I am using cli and made my own command like bellow, as you see i have a command with 3 sub commands. But i think my idea is primitive because if i have 1000 sub command so i have to write many functions!!!!

Another problem of using this method is that in putty first i have to write N1 as a sub command and in the next line SEND as a command and then i can see my results. For example :

uart_cli:~$   Do A

uart_cli:~$   DO

But i want  to type like  "SEND N1'' which is contain command and sub command and then get my results. Kindly let me how to do that and let me know if it is possible, how many sub command i can type with that? is there any limitation? For example can i have something like bellow?

uart_cli:~$  DO A L g H Z K

which A, L,H,Z,K are sub commands of DO.

//sub commands
static void cmd_DO_A(nrf_cli_t const * p_cli, size_t argc, char **argv)
      { 
           A = 1;    
      }

static void cmd_DO_B(nrf_cli_t const * p_cli, size_t argc, char **argv)
      { 
          A = 2;
      }

static void cmd_DO_C(nrf_cli_t const * p_cli, size_t argc, char **argv)
      { 
            A = 3;
      }
// Command
static void cmd_DO(nrf_cli_t const * p_cli, size_t argc, char **argv)
{ 
      ASSERT(p_cli);
      //
      //
      //
      //

      switch(A)
      {
        case 1:
                
                break;
         case 2:
             
                break;
         case 3:
                
                break;

Parents
  • What you can do is to implement handler for DO command only which will be checking what subcommands were passed to it using argc and argv.

    To achieve that you need to use dynamic commands concept. It can look more less like that:

    static char m_dynamic_cmd_buffer[10][20] = {"A", "B", "c", "z", "d"};
    
    static void cmd_DO(nrf_cli_t const * p_cli, size_t argc, char **argv)
    {
        for (size_t i = 1; i < argc; i++)
        {
        	if (!strcmp(argv[i], m_dynamic_cmd_buffer[i])
        		{
        		 // do something
        		}
        }
    }
    
    
    static void dynamic_cmd_get(size_t idx, nrf_cli_static_entry_t * p_static)
    {
        ASSERT(p_static);
    
        if (idx < m_dynamic_cmd_cnt)
        {
            /* m_dynamic_cmd_buffer must be sorted alphabetically to ensure correct CLI completion */
            p_static->p_syntax = m_dynamic_cmd_buffer[idx];
            p_static->handler  = NULL;
            p_static->p_subcmd = NULL;
            p_static->p_help = NULl;
        }
        else
        {
            /* if there are no more dynamic commands available p_syntax must be set to NULL */
            p_static->p_syntax = NULL;
        }
    }
    
    NRF_CLI_CREATE_DYNAMIC_CMD(m_sub_dynamic_set, dynamic_cmd_get);
    NRF_CLI_CMD_REGISTER(DO,
                         &m_sub_dynamic_set,
                         "Demonstrate dynamic command usage.",
                         cmd_DO);
    

    I did not compile it, it's only a concept.

    Using this approach you will be able to autocomplete all subcommands.

    CLI is not capable to execute more than 1 handler at a time so you do not have much choice here.

  • Thank you for helpful advises. Could you please let me know about A,B,c,z,d?

    I mean this line:

    static char m_dynamic_cmd_buffer[10][20] = {"A", "B", "c", "z", "d"};

  • This is syntax of your subcommands :). It only means that you can autocomplete commands A, B, c, z, d

    This table could look like that

    static char m_dynamic_cmd_buffer[][20] = {"A_subcommand", "B_subcommand", "c_subcommand"};

    Next you can type in the CLI:

    DO A <TAB> and CLI will autocompleate it to:

    DO A_subcommand

    Next you can tab other (or the same) command.

    DO A_subcommand c <tab> will result in:

    DO A_subcommand c_subcommand

  • Hi

    Thank you for answering and explanation:). But putting char inside of array by this way is impossible and i will face issue with the conflicting types for 'm_dynamic_cmd_buffer'. Any other way?

    Kind regards

Reply Children
  • Hi,

    I do not understand why it is impossible and you will have a conflict types? Please let me know what problems you are facing.

  • Hi,

    Please see the bellow code. this is what i mean. Because i think the problem is in Sub commands definitions.I will appreciate if you give me more guidance.

    Kind regards 

    uint8_t     A= 0;
    
    //sub commands
    static void DO_A (nrf_cli_t const * p_cli, size_t argc, char **argv)
          { 
              A = 1;    
          }
    
    static void DO_B (nrf_cli_t const * p_cli, size_t argc, char **argv)
          { 
              A = 2;
          }
    
    static void DO_C (nrf_cli_t const * p_cli, size_t argc, char **argv)
          { 
              A = 3;
          }
    static char m_dynamic_cmd_buffer[][20] = {"Do_A", "Do_B", "Do_C"};
    
    // Command
    static void cmd_send(nrf_cli_t const * p_cli, size_t argc, char **argv)
    {
        for (size_t i = 1; i < argc; i++)
        {
        	if (!strcmp(argv[i], m_dynamic_cmd_buffer[i]))
        		{
        		//
        		//
        		//
                  switch(A)
                   {
                    case 1:
                        data[0] = 0x19;
                            
                            break;
                     case 2:
                            data[0] = 0x20;
                            
                            break;
                    }
                }    
        }                    
    }
    
    static void dynamic_cmd_get(size_t idx, nrf_cli_static_entry_t * p_static)
    {
        ASSERT(p_static);
    
        if (idx < m_dynamic_cmd_cnt)
        {
            /* m_dynamic_cmd_buffer must be sorted alphabetically to ensure correct CLI completion */
            p_static->p_syntax = m_dynamic_cmd_buffer[idx];
            p_static->handler  = NULL;
            p_static->p_subcmd = NULL;
            p_static->p_help = NULL;
        }
        else
        {
            /* if there are no more dynamic commands available p_syntax must be set to NULL */
            p_static->p_syntax = NULL;
        }
    }
    
    
    NRF_CLI_CREATE_DYNAMIC_CMD(m_sub_dynamic_set, dynamic_cmd_get);
    NRF_CLI_CMD_REGISTER(Do,
                         &m_sub_dynamic_set,
                         "Demonstrate dynamic command usage.",
                         cmd_Do);      

  • This code is not complete. What is data?

    May you please let me know what is exact error message and what compiler you are using? May you share complete project?

    btw.

    Are you aware that functions: DO_A, DO_B, DO_C will not be called so variable A will not be updated?

  • When I think a bit more about your use case I wonder why you need subcommands at all?

    You can have only 1 command and implement it like that:

    static void cmd_Do(nrf_cli_t const * p_cli, size_t argc, char **argv)
    {
        data[0] = atoi(argv[i]);
    }
    

    and you can simply call it like that:

    Do 10

  • Dear Jakub

    Thank you for answering. The code which i sent u to visit was just an example because of my better understanding of using commands and subcommands. in fact in the command i am using pipe (i prefer to use only one pipe not more!) and by the help of the payload data, i am sending data to another two boards. This is the reason that i want to use subcommands because without that i cant choose which board im going to send data. Moreover, i am using SEEGER Embedded Studio. The ''data'' in the code which i sent u is payload.data[0] also. Im eagerly waiting for ur answer. 

    Kind regatds

Related