add documention for writing built-in commands
This documentation update provides an introduction to the command handling facilities provided by command.[ch]. A primer walks the user through the elements of a pointedly pedantic module: src/hello.c. A summary of the API is provided in the OpenOCD Architecture section.__archive__
parent
89870c86e7
commit
ebbc762182
|
@ -31,7 +31,63 @@ This section needs to be expanded to describe OpenOCD's Jim API.
|
||||||
|
|
||||||
/** @page helpercommand OpenOCD Command API
|
/** @page helpercommand OpenOCD Command API
|
||||||
|
|
||||||
This section needs to be expanded to describe OpenOCD's Command API.
|
OpenOCD's command API allows modules to register callbacks that are then
|
||||||
|
available to the scripting services. It provides the mechanism for
|
||||||
|
these commands to be dispatched to the modlue using a standard
|
||||||
|
interfaces. It provides macros for defining functions that use and
|
||||||
|
extend this interface.
|
||||||
|
|
||||||
|
@section helpercmdhandler Command Handlers
|
||||||
|
|
||||||
|
Command handlers are functions with a particular signature, which can
|
||||||
|
be extended by modules for passing additional parameters to helpers or
|
||||||
|
another layer of handlers.
|
||||||
|
|
||||||
|
@subsection helpercmdhandlerdef Defining and Calling Command Handlers
|
||||||
|
|
||||||
|
These functions should be defined using the COMMAND_HANDLER macro.
|
||||||
|
These methods must be defined as static, as their principle entry point
|
||||||
|
should be the run_command dispatch mechanism.
|
||||||
|
|
||||||
|
Command helper functions that require access to the full set of
|
||||||
|
parameters should be defined using the COMMAND_HELPER. These must be
|
||||||
|
declared static by you, as sometimes you might want to share a helper
|
||||||
|
among several files (e.g. s3c24xx_nand.h).
|
||||||
|
|
||||||
|
Both types of routines must be called using the CALL_COMMAND_HANDLER macro.
|
||||||
|
Calls using this macro to normal handlers require the name of the command
|
||||||
|
handler (which can a name or function pointer). Calls to helpers and
|
||||||
|
derived handlers must pass those extra parameters specified by their
|
||||||
|
definitions; however, lexical capture is used for the core parameters.
|
||||||
|
This dirty trick is being used as a stop-gap measure while the API is
|
||||||
|
migrated to one that passes a pointer to a structure containing the
|
||||||
|
same ingredients. At that point, this macro will be removed and callers
|
||||||
|
will be able to use direct invocations.
|
||||||
|
|
||||||
|
Thus, the following macros can be used to define and call command
|
||||||
|
handlers or helpers:
|
||||||
|
|
||||||
|
- COMMAND_HANDLER - declare or define a command handler.
|
||||||
|
- COMMAND_HELPER - declare or define a derived command handler or helper.
|
||||||
|
- CALL_COMMAND_COMMAND - call a command handler/helper.
|
||||||
|
|
||||||
|
@subsection helpercmdhandlerparam Command Handler Parameters
|
||||||
|
|
||||||
|
The following parameters are defined in the scope of all command
|
||||||
|
handlers and helpers:
|
||||||
|
- <code>struct command_context_s *cmd_ctx</code> - the command's context
|
||||||
|
- <code>unsigned argc</code> - the number of command arguments
|
||||||
|
- <code>const char *args[]</code> - contains the command arguments
|
||||||
|
|
||||||
|
@subsection helpercmdhandlermacros Command Handler Macros
|
||||||
|
|
||||||
|
In addition, the following macro may be used:
|
||||||
|
- <code>COMMAND_NAME</code> - contains the command name
|
||||||
|
|
||||||
|
@section helpercmdprimer Command Development Primer
|
||||||
|
|
||||||
|
This @ref primercommand provides details about the @c hello module,
|
||||||
|
showing how the pieces desrcribed on this page fit together.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,17 @@ associated with the fundamental technologies used by OpenOCD.
|
||||||
- @subpage primertcl
|
- @subpage primertcl
|
||||||
- @subpage primerjtag
|
- @subpage primerjtag
|
||||||
|
|
||||||
These documents should bridge any "ancillary" gaps in contributor
|
The above documents should bridge any "ancillary" gaps in contributor
|
||||||
knowledge, without having to learn the complete languages or technology.
|
knowledge, without having to learn the complete languages or technology.
|
||||||
They should provide enough information for experienced developers to
|
They should provide enough information for experienced developers to
|
||||||
learn how to make "correct" changes when creating patches.
|
learn how to make "correct" changes when creating patches.
|
||||||
|
|
||||||
|
Beyond the fundamentals, the following primers provide introductory
|
||||||
|
tutorials for OpenOCD's sub-systems. These complement the @ref oocd
|
||||||
|
pages that provide more high-level perspective on related topics.
|
||||||
|
|
||||||
|
- @subpage primercommand
|
||||||
|
|
||||||
In all cases, these Primers should use idiomatic conventions that the
|
In all cases, these Primers should use idiomatic conventions that the
|
||||||
community has agreed are the "right way of doing things". In this
|
community has agreed are the "right way of doing things". In this
|
||||||
respect, these documents typically assume some familiarity with the
|
respect, these documents typically assume some familiarity with the
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/** @page primercommand Command Development Primer
|
||||||
|
|
||||||
|
This page provides a primer for writing commands by introducing @c hello
|
||||||
|
module. The full source code used in this example can be found in
|
||||||
|
hello.c, and the @ref primercmdcode section shows how to use it.
|
||||||
|
|
||||||
|
A summary of this information can be found in @ref helpercommand .
|
||||||
|
|
||||||
|
@section primercmdhandler Command Handlers
|
||||||
|
|
||||||
|
Defining new commands and their helpers is easy. The following code
|
||||||
|
defines a simple command handler that delegates its argument parsing:
|
||||||
|
@code
|
||||||
|
COMMAND_HANDLER(handle_hello_command)
|
||||||
|
{
|
||||||
|
const char *sep, *name;
|
||||||
|
int retval = CALL_COMMAND_HANDLER(handle_hello_args);
|
||||||
|
if (ERROR_OK == retval)
|
||||||
|
command_print(cmd_ctx, "Greetings%s%s!", sep, name);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Here, the @c COMMAND_HANDLER macro establishes the function signature,
|
||||||
|
see in command.h by the @c __COMMAND_HANDLER macro.
|
||||||
|
|
||||||
|
The COMMAND_HELPER macro function allows defining functions with an
|
||||||
|
extended version of the base signature. These helper functions can be
|
||||||
|
called (with the appropriate parameters), the @c CALL_COMMAND_HANDLER
|
||||||
|
macro to pass any e as parameters to the following helper function:
|
||||||
|
|
||||||
|
The subsequent blocks of code are a normal C function that can do
|
||||||
|
anything, so only complex commands deserve should use comamnd helper
|
||||||
|
functions. In this respect, this example uses one to demonstrate how --
|
||||||
|
not when -- they should be used.
|
||||||
|
|
||||||
|
@code
|
||||||
|
static COMMAND_HELPER(handle_hello_args, const char **sep, const char **name)
|
||||||
|
{
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
LOG_ERROR("%s: too many arguments", COMMAND_NAME);
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
|
}
|
||||||
|
if (1 == argc)
|
||||||
|
{
|
||||||
|
*sep = ", ";
|
||||||
|
*name = args[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*sep = *name = "";
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Of course, you may also call other macros or functions, but that extends
|
||||||
|
beyond the scope of this tutorial on writing commands.
|
||||||
|
|
||||||
|
@section primercmdreg Command Registration
|
||||||
|
|
||||||
|
Before this new function can be used, it must be registered somehow.
|
||||||
|
For a new module, registering should be done in a new function for
|
||||||
|
the purpose, which must be called from @c openocd.c:
|
||||||
|
@code
|
||||||
|
int hello_register_commands(struct command_context_s *cmd_ctx)
|
||||||
|
{
|
||||||
|
struct command_s *cmd = register_command(cmd_ctx, NULL, "hello",
|
||||||
|
NULL, COMMAND_ANY, "print greetings");
|
||||||
|
return cmd ? ERROR_OK : -ENOMEM;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
That's it! The command should now be registered and avaiable to scripts.
|
||||||
|
|
||||||
|
@section primercmdcode Trying These Example Commands
|
||||||
|
|
||||||
|
The commands may be enabled by editing src/openocd.c and uncommenting
|
||||||
|
the call to @c hello_register_commands and rebuilding the source tree.
|
||||||
|
|
||||||
|
Once OpenOCD has been built with this example code, the following script
|
||||||
|
demonstrate the abilities that the @c hello module provides:
|
||||||
|
@code
|
||||||
|
hello
|
||||||
|
hello World
|
||||||
|
hello {John Doe}
|
||||||
|
hello John Doe # error: too many arguments
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
If saved in @c hello.cfg, then running <code>openocd -f hello.cfg</code>
|
||||||
|
should produce the following output before exiting:
|
||||||
|
@code
|
||||||
|
Greetings!
|
||||||
|
Greetings, World!
|
||||||
|
Greetings, John Doe!
|
||||||
|
Error: ocd_hello: too many arguments
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
Loading…
Reference in New Issue