MSPDebug embedded mode Daniel Beer 9 Oct 2012 This document describes mspdebug's embedded mode, which makes it easier to use it as a back-end to a third-party user interface. The key differences between the normal terminal interface and embedded mode are: * Command reading: in embedded mode, commands are read without displaying a prompt to the user. * Output processing: rather than directing errors to stderr, all output is sent to stdout, so that all messages remain in sync relative to one another. Output lines are prefixed with a sigil character to indicate their type (error/normal/debug). * Interrupt processing: normally, Ctrl+C or Ctrl+Break sequences can be used to interrupt a running command via the SIGINT signal, or a console event handler. In embedded mode, a terminal is not available, so another method which relies only on standard line-oriented IO is provided. * Additional output: additional data is provided which can be used by a third-party user interface to improve interaction. These differences are explained in more detail in the following sections. To enabled embedded mode, add the --embedded flag to mspdebug's command-line arguments. Output processing ================= In embedded mode, all output is directed to stdout. This ensures that the logical streams generated by mspdebug stay in order relative to one another when written to an asynchronous pipe. To distinguish the streams, each is prefixed with a single sigil character. These sigil characters are: Sigil Output type -------- ----------------- : Normal output - Debug output (suppressed in quiet mode) ! Error messages \ Shell messages Another feature of output processing in embedded mode is that when colourized output is enabled (``opt color true``), colourization is always implemented by including ANSI escape codes in the output, even on Windows. Normally, colourized output on Windows is implemented by changing console text attributes. Shell messages -------------- Shell messages are emitted only when in embedded mode. They provide additional information to the front-end and consist of a type identifier string immediately following the sigil, then optionally a space and arguments. Currently, the following shell messages may be emitted: \ready ~ The command processor is ready to receive a command. \busy ~ The command process has accepted a command and is now executing it. \power-sample-us ~ Indicates that power profiling is enabled. The period argument is a decimal number giving the sample period in microseconds. \power-samples ~ Power data captured from the running device. The data argument is a Base64-encoded string. When decoded, it consists of a sequence of 32-bit little-endian unsigned integers. Integers with bit 31 set are MAB values, and those without bit 31 set are current consumption readings, in microamps. Input processing and interruption ================================= A different input processor is used in embedded mode, to allow for interruption of running commands without the use of signals or console control handlers. When embedded mode is enabled, a prompt is never displayed. Lines of text are read from stdin in a separate thread, and any commands are posted through to the main thread. The lines of text read are also prefixed with sigils -- either ':' to indicate a command, or '\' to indicate a special reader operation. Lines of text without a sigil are assumed to be commands. Currently, the only implemented special operation is "\break", which raises a break condition to interrupt any running command. End-of-input is signalled by closing stdin. If the command processor is running a command when this occurs, it will wait until the command finishes before exiting. If a command is sent before the reader is ready to accept one, it is discarded. To avoid race conditions, a front end should: * Send a command only after the "\ready" shell message is received, and do not send further commands until it has finished executing. * To interrupt a running command by sending a "\break" operation, the front-end should first wait until the "\busy" message is received. Otherwise, the break condition may be lost. Example ======= In the following example, arrows are used to indicate text sent to mspdebug (=>) and text received from the mspdebug process (<=): $ ./mspdebug --embedded sim -q <= \ready => :prog ../fet-fw/20401004.hex <= \busy <= :Erasing... <= :Programming... <= :Done, 55472 bytes total <= \ready => :reset <= \busy <= \ready => :run <= \busy <= :Running. Press Ctrl+C to interrupt... => \break <= : <= : ( PC: 0c682) ( R4: 00000) ( R8: 00000) (R12: 00000) <= : ( SP: 024f2) ( R5: 00000) ( R9: 00000) (R13: 00000) <= : ( SR: 0000d) ( R6: 00000) (R10: 0ffff) (R14: 00002) <= : ( R3: 00000) ( R7: 00000) (R11: 00000) (R15: 00063) <= :0xc682: <= : 0c682: 0d 43 CLR R13 <= : 0c684: 3a 41 POP R10 <= : 0c686: 30 41 RET <= : 0c688: 0a 12 PUSH R10 <= : 0c68a: 0b 12 PUSH R11 <= : 0c68c: 08 12 PUSH R8 <= : 0c68e: 0b 4c MOV R12, R11 <= : 0c690: 08 4e MOV R14, R8 <= \ready