update command handler documentation
Adds sections on command registration and chaining, giving an overview to developers that want to use these features.__archive__
parent
9d4c89f37f
commit
ed90b6659f
|
@ -80,6 +80,42 @@ command handlers and helpers:
|
||||||
- @c CMD_ARGC - the number of command arguments
|
- @c CMD_ARGC - the number of command arguments
|
||||||
- @c CMD_ARGV - array of command argument strings
|
- @c CMD_ARGV - array of command argument strings
|
||||||
|
|
||||||
|
@section helpercmdregister Command Registration
|
||||||
|
|
||||||
|
In order to use a command handler, it must be registered with the
|
||||||
|
command subsystem. All commands are registered with command_registration
|
||||||
|
structures, specifying the name of the command, its handler, its allowed
|
||||||
|
mode(s) of execution, and strings that provide usage and help text.
|
||||||
|
A single handler may be registered using multiple names, but any name
|
||||||
|
may have only one handler associated with it.
|
||||||
|
|
||||||
|
The @c register_commands() and @c register_commands() functions provide
|
||||||
|
registration, while the @c unregister_command() and
|
||||||
|
@c unregister_all_commands() functions will remove existing commands.
|
||||||
|
These may be called at any time, allowing the command set to change in
|
||||||
|
response to system actions.
|
||||||
|
|
||||||
|
@subsection helpercmdjim Jim Command Registration
|
||||||
|
|
||||||
|
The command_registration structure provides support for registering
|
||||||
|
native Jim command handlers (@c jim_handler) too. For these handlers,
|
||||||
|
the module can provide help and usage support; however, this mechanism
|
||||||
|
allows Jim handlers to be called as sub-commands of other commands.
|
||||||
|
These commands may be registered with a private data value (@c
|
||||||
|
jim_handler_data) that will be available when called, as with low-level
|
||||||
|
Jim command registration.
|
||||||
|
|
||||||
|
A command may have a normal @c handler or a @c jim_handler, but not both.
|
||||||
|
|
||||||
|
@subsection helpercmdregisterchains Command Chaining
|
||||||
|
|
||||||
|
When using register_commands(), the array of commands may reference
|
||||||
|
other arrays. When the @c chain field is filled in a
|
||||||
|
command_registration record, the commands on in the chained list will
|
||||||
|
added in one of two places. If the record defines a new command, then
|
||||||
|
the chained commands are added under it; otherwise, the commands are
|
||||||
|
added in the same context as the other commands in the array.
|
||||||
|
|
||||||
@section helpercmdprimer Command Development Primer
|
@section helpercmdprimer Command Development Primer
|
||||||
|
|
||||||
This @ref primercommand provides details about the @c hello module,
|
This @ref primercommand provides details about the @c hello module,
|
||||||
|
|
|
@ -63,42 +63,71 @@ 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
|
For a new module, registering should be done in a new function for
|
||||||
the purpose, which must be called from @c openocd.c:
|
the purpose, which must be called from @c openocd.c:
|
||||||
@code
|
@code
|
||||||
|
|
||||||
|
static const struct command_registration hello_command_handlers[] = {
|
||||||
|
{
|
||||||
|
.name = "hello",
|
||||||
|
.mode = COMMAND_ANY,
|
||||||
|
.handler = &handle_hello_command,
|
||||||
|
.help = "print a warm greetings",
|
||||||
|
.usage = "[<name>]",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.chain = foo_command_handlers,
|
||||||
|
}
|
||||||
|
COMMAND_REGISTRATION_DONE
|
||||||
|
};
|
||||||
|
|
||||||
int hello_register_commands(struct command_context_s *cmd_ctx)
|
int hello_register_commands(struct command_context_s *cmd_ctx)
|
||||||
{
|
{
|
||||||
struct command_s *cmd = register_command(cmd_ctx, NULL, "hello",
|
return register_commands(cmd_ctx, NULL, handle_command_handlers);
|
||||||
NULL, COMMAND_ANY, "print greetings");
|
|
||||||
return cmd ? ERROR_OK : -ENOMEM;
|
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
That's it! The command should now be registered and avaiable to scripts.
|
That's it! The command should now be registered and avaiable to scripts.
|
||||||
|
|
||||||
|
@section primercmdchain Command Chaining
|
||||||
|
|
||||||
|
This example also shows how to chain command handler registration, so
|
||||||
|
your modules can "inherit" commands provided by other (sub)modules.
|
||||||
|
Here, the hello module includes the foo commands in the same context
|
||||||
|
that the 'hello' command will be registered.
|
||||||
|
|
||||||
|
If the @c chain field had been put in the 'hello' command, then the
|
||||||
|
@c foo module commands would be registered under it. Indeed, that
|
||||||
|
technique is used to define the 'foo bar' and 'foo baz' commands,
|
||||||
|
as well as for the example drivers that use these modules.
|
||||||
|
|
||||||
|
The code for the 'foo' command handlers can be found in @c hello.c.
|
||||||
|
|
||||||
@section primercmdcode Trying These Example Commands
|
@section primercmdcode Trying These Example Commands
|
||||||
|
|
||||||
The commands may be enabled by editing src/openocd.c and uncommenting
|
These commands have been inherited by the dummy interface, faux flash,
|
||||||
the call to @c hello_register_commands and rebuilding the source tree.
|
and testee target drivers. The easiest way to test these is by using the
|
||||||
|
dummy interface.
|
||||||
|
|
||||||
Once OpenOCD has been built with this example code, the following script
|
Once OpenOCD has been built with this example code, the following command
|
||||||
demonstrate the abilities that the @c hello module provides:
|
demonstrates the abilities that the @c hello module provides:
|
||||||
@code
|
@code
|
||||||
hello
|
openocd -c 'interface dummy' \
|
||||||
hello World
|
-c 'dummy hello' \
|
||||||
hello {John Doe}
|
-c 'dummy hello World' \
|
||||||
hello John Doe # error: too many arguments
|
-c 'dummy hello {John Doe}' \
|
||||||
|
-c 'dummy hello John Doe' # error: too many arguments
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If saved in @c hello.cfg, then running <code>openocd -f hello.cfg</code>
|
If saved in @c hello.cfg, then running <code>openocd -f hello.cfg</code>
|
||||||
should produce the following output before exiting:
|
should produce the following output before displaying the help text and
|
||||||
|
exiting:
|
||||||
@code
|
@code
|
||||||
Greetings!
|
Greetings!
|
||||||
Greetings, World!
|
Greetings, World!
|
||||||
Greetings, John Doe!
|
Greetings, John Doe!
|
||||||
Error: ocd_hello: too many arguments
|
Error: hello: too many arguments
|
||||||
|
Runtime error, file "openocd.cfg", line 14:
|
||||||
|
hello: too many arguments
|
||||||
|
dummy hello [<name>]
|
||||||
|
prints a warm welcome
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
This difference between the registered and displayed command name comes from
|
|
||||||
the fact that the TCL scripts are provided with a stub that calls the munged
|
|
||||||
name. This stub wraps the internal <code>ocd_</code>-prefixed routine,
|
|
||||||
providing a measure of high-level error handling.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue