下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

最新资讯
简化任何设备的身份验证云连接。
利用 CoAP 设计节能型云连接 IoT 解决方案。
11.0.0 版 FreeRTOS 内核简介:
FreeRTOS 路线图和代码贡献流程。
使用 FreeRTOS 实现 OPC-UA over TSN。

 

实现命令

FreeRTOS-Plus-CLI 为可扩展架构,允许应用程序编写人员定义并注册自身的命令行输入参数。本页介绍如何编写实现命令行为的函数。

 

函数输入和输出

实现用户定义命令的行为的函数必须具有以下接口(原型):

BaseType_t xFunctionName( char *pcWriteBuffer,
                             size_t xWriteBufferLen,
                             const char *pcCommandString );
		

以下描述了调用函数时将传递到函数的参数,以及必须返回的值。

参数:

pcWriteBuffer   缓冲区,任何生成的输出都应写入其中。例如,如果函数只返回固定的字符串 “Hello World”,则该字符串将写入 pcWriteBuffer。输出必须始终以空字符结尾。
xWriteBufferLen   pcWriteBuffer 参数所指向的缓冲区大小。将超过 xWriteBufferLen 个字符写入 pcWriteBuffer 后,可能会导致缓冲区溢出。
pcCommandString   指向整个命令字符串的指针。有了对整个命令字符串的访问权,函数实现就可以提取命令参数(如有)。FreeRTOS-Plus-CLI 提供了接受命令字符串并返回命令参数的辅助函数——因此不需要明确的字符串解析。本页提供了相关示例。

返回:

执行某些命令将导致产生不止一行输出。例如,文件系统"dir"(或“Is”)命令将为目录下的每个文件生成一行输出。如果目录下有三个文件,则输出可能如下所示:

file1.txt
file2.txt
file3.txt

为将 RAM 的使用率降至最低,并确定 RAM 的使用率,FreeRTOS-Plus-CLI 允许实现命令行为的函数每次输出一行。函数返回值用于指示输出行是否是输出的末尾,或者是否要生成更多行。

如果生成的输出是输出的末尾,则返回 pdFALSE,这意味着不需再生成更多行,并且命令执行已完成。

如果返回的输出不是输出的末尾,并且在命令执行完成之前仍有一行或多行要生成,则返回 pdTRUE

再来看一下“dir”命令。在该示例中,此命令输出三个文件名称:

  1. 实现 dir 命令的函数第一次调用时,可能只输出第一行 (file1.txt)。完成此操作后,该函数须返回 pdTRUE,以指示后面还有更多行。

     

  2. 实现 dir 命令的函数第二次调用时,可能只输出第二行 (file2.txt)。完成此操作后,该函数须再次返回 pdTRUE,以指示后面还有更多行。

     

  3. 实现 dir 命令的函数第三次调用时,只会输出第三行 (file3.txt)。此时,没有其他行需要输出,因此函数须返回 pdFALSE。

     

或者,如果有足够多的 RAM,并且 xWriteBufferLen 中传递的值足够大,则可以一次性返回所有三行。在这种情况下,函数须在其第一次执行命令时返回 pdFALSE。

每次执行命令时,FreeRTOS-Plus-CLI 将重复调用实现命令行为的函数,直到函数返回 pdFALSE。

 

示例

本页提供如下示例:

  1. 一种命令,该命令不带参数,并且返回单个字符串。
  2. 一种命令,该命令不带参数并且一次返回单行多个字符串。
  3. 一种命令,该命令需要固定数量的参数。
  4. 一种命令,该命令接受可变数量的参数并且一次返回单行可变数量的字符串。

示例 1:不带参数的命令

FreeRTOS vTaskList() API 函数生成一个包含每个任务状态信息的表。该表包含每个任务的单行文本。示例 1 中实现的命令可输出此表。示例 1 演示了一次输出整个表的简单实例。代码中的注释用于进一步解释说明。


/* This function implements the behaviour of a command, so must have the correct
prototype. */

static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer,
size_t xWriteBufferLen,
const char *pcCommandString )
{
/* For simplicity, this function assumes the output buffer is large enough
to hold all the text generated by executing the vTaskList() API function,
so the xWriteBufferLen parameter is not used. */

( void ) xWriteBufferLen;

/* pcWriteBuffer is used directly as the vTaskList() parameter, so the table
generated by executing vTaskList() is written directly into the output
buffer. */

vTaskList( pcWriteBuffer + strlen( pcHeader ) );

/* The entire table was written directly to the output buffer. Execution
of this command is complete, so return pdFALSE. */

return pdFALSE;
}

Example 1: Outputting multiple lines at once

 

示例 2 :一次返回多行

每个用 FreeRTOS-Plus-CLI 注册的命令都有自己的帮助字符串。帮助字符串是演示如何使用命令的一行文本。FreeRTOS-Plus-CLI包含一个“帮助”命令,该命令能返回所有帮助字符串,为用户提供可用的命令列表以及有关如何使用每个命令的说明。示例 2 演示了帮助命令的实现方式。与示例 1 (在该示例中,一次性生成所有输出)不同的是,示例 2 中,一次只生成单行输出。请注意,此函数并非可重入函数。


/* This function implements the behaviour of a command, so must have the correct
prototype. */

static BaseType_t prvHelpCommand( char *pcWriteBuffer,
size_t xWriteBufferLen,
const char *pcCommandString )
{
/* Executing the "help" command will generate multiple lines of text, but this
function will only output a single line at a time. Therefore, this function is
called multiple times to complete the processing of a single "help" command. That
means it has to remember which help strings it has already output, and which
still remain to be output. The static pxCommand variable is used to point to the
next help string that needs outputting. */

static const xCommandLineInputListItem *pxCommand = NULL;
signed BaseType_t xReturn;

if( pxCommand == NULL )
{
/* pxCommand is NULL in between executions of the "help" command, so if
it is NULL on entry to this function it is the start of a new "help" command
and the first help string is returned. The following line points pxCommand
to the first command registered with FreeRTOS-Plus-CLI. */

pxCommand = &xRegisteredCommands
}

/* Output the help string for the command pointed to by pxCommand, taking
care not to overflow the output buffer. */

strncpy( pcWriteBuffer,
pxCommand->pxCommandLineDefinition->pcHelpString,
xWriteBufferLen );

/* Move onto the next command in the list, ready to output the help string
for that command the next time this function is called. */

pxCommand = pxCommand->pxNext;

if( pxCommand == NULL )
{
/* If the next command in the list is NULL, then there are no more
commands to process, and pdFALSE can be returned. */

xReturn = pdFALSE;
}
else
{
/* If the next command in the list is not NULL, then there are more
commands to process and therefore more lines of output to be generated.
In this case pdTRUE is returned. */

xReturn = pdTRUE;
}

return xReturn;
}

Example 2: Generating multiple lines of output, one line at a time

 

示例 3 :具有固定数量参数的命令

有些命令带参数。例如,文件系统“copy”命令需要带源文件的名称和目标文件的名称。示例 3 是复制命令的架构,用于演示如何访问和使用命令参数。

请注意,如果此命令在注册时声明带有两个参数,除非是固定就提供两个参数,否则 FreeRTOS-Plus-CLI 不会调用此命令。

 


/* This function implements the behaviour of a command, so must have the correct
prototype. */

static BaseType_t prvCopyCommand( char *pcWriteBuffer,
size_t xWriteBufferLen,
const char *pcCommandString )
{
char *pcParameter1, *pcParameter2;
BaseType_t xParameter1StringLength, xParameter2StringLength, xResult;

/* Obtain the name of the source file, and the length of its name, from
the command string. The name of the source file is the first parameter. */

pcParameter1 = FreeRTOS_CLIGetParameter
(
/* The command string itself. */
pcCommandString,
/* Return the first parameter. */
1,
/* Store the parameter string length. */
&xParameter1StringLength
);

/* Obtain the name of the destination file, and the length of its name. */
pcParameter2 = FreeRTOS_CLIGetParameter( pcCommandString,
2,
&xParameter2StringLength );

/* Terminate both file names. */
pcParameter1[ xParameter1StringLength ] = 0x00;
pcParameter2[ xParameter2StringLength ] = 0x00;

/* Perform the copy operation itself. */
xResult = prvCopyFile( pcParameter1, pcParameter2 );

if( xResult == pdPASS )
{
/* The copy was successful. There is nothing to output. */
*pcWriteBuffer = NULL;
}
else
{
/* The copy was not successful. Inform the users. */
snprintf( pcWriteBuffer, xWriteBufferLen, "Error during copyrnrn" );
}

/* There is only a single line of output produced in all cases. pdFALSE is
returned because there is no more output to be generated. */

return pdFALSE;
}

Example 3: Accessing and using the command parameters

 

示例 4 :具有可变数量参数的命令

示例 4 演示了如何创建和实现一个接受可变数量参数的命令。FreeRTOS-Plus-CLI 不会检查所提供的参数的数量,命令的执行只是简单的回传参数,一次一个。例如,如果分配的命令字符串为 "echo_parameters",则当用户输入

"echo_parameters one two three four"

则生成以下输出结果:

参数为:
1:一
2:二
3:三
4:四


static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer,
size_t xWriteBufferLen, c
onst char *pcCommandString )
{
char *pcParameter;
BaseType_t lParameterStringLength, xReturn;

/* Note that the use of the static parameter means this function is not reentrant. */
static BaseType_t lParameterNumber = 0;

if( lParameterNumber == 0 )
{
/* lParameterNumber is 0, so this is the first time the function has been
called since the command was entered. Return the string "The parameters
were:" before returning any parameter strings. */

sprintf( pcWriteBuffer, "The parameters were:rn" );

/* Next time the function is called the first parameter will be echoed
back. */

lParameterNumber = 1L;

/* There is more data to be returned as no parameters have been echoed
back yet, so set xReturn to pdPASS so the function will be called again. */

xReturn = pdPASS;
}
else
{
/* lParameter is not 0, so holds the number of the parameter that should
be returned. Obtain the complete parameter string. */

pcParameter = ( char * ) FreeRTOS_CLIGetParameter
(
/* The command string itself. */
pcCommandString,
/* Return the next parameter. */
lParameterNumber,
/* Store the parameter string length. */
&lParameterStringLength
);

if( pcParameter != NULL )
{
/* There was another parameter to return. Copy it into pcWriteBuffer.
in the format "[number]: [Parameter String". */

memset( pcWriteBuffer, 0x00, xWriteBufferLen );
sprintf( pcWriteBuffer, "%d: ", lParameterNumber );
strncat( pcWriteBuffer, pcParameter, lParameterStringLength );
strncat( pcWriteBuffer, "rn", strlen( "rn" ) );

/* There might be more parameters to return after this one, so again
set xReturn to pdTRUE. */

xReturn = pdTRUE;
lParameterNumber++;
}
else
{
/* No more parameters were found. Make sure the write buffer does
not contain a valid string to prevent junk being printed out. */

pcWriteBuffer[ 0 ] = 0x00;

/* There is no more data to return, so this time set xReturn to
pdFALSE. */

xReturn = pdFALSE;

/* Start over the next time this command is executed. */
lParameterNumber = 0;
}
}

return xReturn;
}


Example 4: Accessing a variable number of parameters
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.