From: Zachary T Welch Date: Wed, 11 Nov 2009 09:31:34 +0000 (-0800) Subject: add documention for writing built-in commands X-Git-Tag: v0.4.0-rc1~795 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=ebbc762182c943d5967ea106933181a2fb726b1b 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. --- diff --git a/doc/manual/helper.txt b/doc/manual/helper.txt index 91bf2d51be..7060607cd4 100644 --- a/doc/manual/helper.txt +++ b/doc/manual/helper.txt @@ -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: +- struct command_context_s *cmd_ctx - the command's context +- unsigned argc - the number of command arguments +- const char *args[] - contains the command arguments + +@subsection helpercmdhandlermacros Command Handler Macros + +In addition, the following macro may be used: +- COMMAND_NAME - 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. */ diff --git a/doc/manual/main.txt b/doc/manual/main.txt index b9430b6df6..8e76464363 100644 --- a/doc/manual/main.txt +++ b/doc/manual/main.txt @@ -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 diff --git a/doc/manual/primer/commands.txt b/doc/manual/primer/commands.txt new file mode 100644 index 0000000000..9efcca2e84 --- /dev/null +++ b/doc/manual/primer/commands.txt @@ -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 openocd -f hello.cfg +should produce the following output before exiting: +@code +Greetings! +Greetings, World! +Greetings, John Doe! +Error: ocd_hello: too many arguments +@endcode + + */