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.tags/v0.4.0-rc1
@@ -31,7 +31,63 @@ This section needs to be expanded to describe OpenOCD's Jim 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 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. | |||
They should provide enough information for experienced developers to | |||
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 | |||
community has agreed are the "right way of doing things". In this | |||
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 | |||
*/ |