In September, I introduced thetopic of the GNU debugger,gdb. 1 I discussed how itsremote debugging featurecould be used to debug coderunning in an embedded sys-tem connected to a PC by a serialcable, network connection, or someother means. While commercial prod-ucts with this capability are also avail-able, in my opinion the freely availablegdb is the preferred solution becauseit provides portable, sophisticateddebugging over a broad range ofembedded systems, including deviceswith communications interfaces orresource constraints too restrictive forgeneral commercial support.I also mentioned in that articlethat, to make remote debugging possi-ble, gdb requires the services of adebugging stub—a small library ofcode in the debugging target thatmanages registers and memory,responds to breakpoints, and reportsapplication status to gdb via the com-munications link. That article con-tained excerpts from a debugging stubfor the Hitachi SH-2 microcontroller,but I didn’t actually put enough of thepieces together to show how a com-plete debugging stub would work.I’ll fix that this month by present-ing in detail the GDB Remote SerialProtocol—gdb’s standard remotecommunications protocol. Once youare comfortable with how your proces-sor handles breakpoint and other108 NOVEMBER 1999 Embedded Systems ProgrammingB I L L G A T L I F Ff e a t u r eEmbeddingwith GNU: thegdb RemoteSerial ProtocolIn this installment of a series on GNU-based embedded development, theauthor wraps up his discussion of using the GNU debugger, gdb, to debugembedded applications remotely.IEmbedded Systems Programming NOVEMBER 1999 109exceptions, then knowledge of a fewbasic Remote Serial Protocol messagesis all you need to get your embeddedsystem talking to gdb.The protocol definedThe GDB Remote Serial Protocol(RSP) is a simple, ASCII message-based protocol suitable for use on ser-ial lines, local area networks, or justabout any other communicationsmedium that can support at least half-duplex data exchange.RSP packets begin with a dollarsign ($), followed by one or moreASCII bytes that make up the messagebeing sent, and end with a pound sign(#) and two ASCII hex characters rep-resenting the message’s checksum.For example, the following is a com-plete RSP packet:$m4015bc,2#5aThe receiver of the packetresponds immediately with either a “+”or a “-” to indicate that the messagewas received either intact or in error,respectively.A typical transaction involves gdbissuing a command to a debugging tar-get, which then responds with data, asimple acknowledgement, or a target-specific error code. If the latter isreturned, gdb will report the code tothe user and halt whatever activity iscurrently in progress.The console output message,which debugging targets use to printtext on the gdb console, is the loneexception to the typical command-response sequence. Except whenanother command is already inprogress, this message can be sentfrom the debugging stub to gdb at anytime.The following paragraphs describethe RSP’s essential commands. For thepurposes of this tutorial, I have divid-ed the messages into three categories:register- and memory-related com-mands, program control commands,and other commands.Register- and memory-related commandsHere are the commands to read fromand write to registers.Read registers (“g”)Example: $g#67The debugger will issue this com-mand whenever it needs to knoweverything about the debugging tar-get’s current register state. An exam-ple target response would be: + $123456789abcdef0...#xx(Register 0 is 0x12345678, register 1 is0x9abcdef0, and so on.)The response is an ordered streamof bytes representing register dataordered per the definition in the tar-get’s macro file, gdb/config/<arch>/tm-<arch>.h (for example, gdb/con-fig/sh/tm-sh.h for the Hitachi SH).Write registers (“G”)Example: $G123456789abcdef0...#xx(Set register 0 to 0x12345678, register1 to 0x9abcdef0, and so on.)This message is the complement tothe read registers command. Withthis command, gdb supplies anordered stream of bytes representingdata to be stored in the target proces-sor’s registers immediately before pro-gram execution resumes. An exampletarget response:+ $OK#9aWrite register N (“P”)Example: $P10=0040149c#b3(Set register 16 to the value 0x40149c.)When it wants to set the value ofonly one or two registers, gdb sendsthis command instead of sending acomplete register set to the debuggingtarget. The register numbering is thesame as that used in the read regis-ters and write registers commands.An example target response: + $OK#9aBelow are the commands to readfrom and write to memory.Read memory (“m”)Example: $m4015bc,2#5a(Read two bytes, starting at address0x4015bc.)A read memory command is sent bygdb to determine the values of localand global variables, the value of anopcode about to be replaced by abreakpoint instruction, and any otherkind of information the user requests.The debugger generally is aware ofany endian issues present in thedebugging target, so the target needonly return the result as a simplestream of bytes; gdb will reformatthem as appropriate.Debugging stubs on targets that aresensitive to data widths should opti-mize the implementation of the writememory and read memory commands asthe target architecture dictates. Forexample, certain peripheral configu-ration registers in the Hitachi SH-2processor family can only be properlyread and written in 16-bit or 32-bitunits, so a debugging stub for this tar-get should use 16-bit or 32-bit accesseswhenever possible. An example targetresponse: + $2f86#06Write memory (“M”)Example: M4015cc,2:c320#6dIn my opinion the freely available gdb is the preferred solutionbecause it provides portable, sophisticated debugging over a broadrange of embedded systems.C O R B I S / T O M B R A K E F I E L Dgdb rsp(Write the value 0xc320 to address0x4015cc.)This command is the complementto the read memory command. Anexample target response: + $OK#9aProgram control commandsProgram control commands are mes-sages that gdb uses to control thebehavior of the application beingdebugged. As such, these commandsare somewhat more complicated toimplement than the more basic regis-ter- and memory-related commandswe’ve already covered.Get last signal (“?”)Example: $?#3fThis command is used to find outhow the target reached its current state.The response is the same as the “Lastsignal” response documented below.Step (“s”)Example: $s#73When it wants the target to executeexactly one assembly language instruc-tion, gdb issues a step command tothe debugging target. The debuggersends this command when the usertypes stepior stepat the gdb console.An example target response followsthe continue command description. Continue (“c”)Example: $c#63A continue command is issuedwhen gdb releases the application torun at full speed, as happens when theuser enters a continue command atthe gdb console. An example targetresponse follows.Responses to the step and continue com-mands. A debugging stub does notimmediately respond to the step orcontinue commands, other than tosend the “+” that signifies properreception of the packet. Instead, thestub provides a response when thenext breakpoint is reached, therequested instruction has been exe-cuted (in the case of the step com-mand), an exception occurs, or theapplication exits.There are two ways to respond tothese commands: a brief “last signal”response, or a more useful “expeditedresponse.”“Last signal” response (“S”)Example: $S05#b8This is the minimum reply to thelast signal, step, and continue com-mands. The “05” in the response canbe any one of the signal values used inthe standard POSIX signal() func-tion call. For example, “5” is a break-point exception, “10” is a bus error,and so forth.Expedited response (“T”)Example: $T0510:1238;F:FFE0...#xxThis message combines the infor-mation in a last signalresponse (the“05” in the example message) with keyregister values that gdb may be imme-diately interested in. Designed toimprove gdb’s performance duringcode stepping, this message allows gdbto avoid a read registers request ifthe values it needs (the target’s pro-gram counter and status register, gen-erally) are included in this message.Registers are identified by the samenumbering scheme used in the readregisters and write registers com-mands; in the example provided, thevalue of register 16 (10 hex) is 0x1238,and register 15 (F hex) contains 0xffe0.Other commandsConsole output (“O”)—optionalExample:$O48656c6c6f2c20776f726c64210a#55(Prints “Hello, world!\n” on the gdbconsole)110 NOVEMBER 1999 Embedded Systems Programminggdb rspThis command allows a debuggingstub to send a text message to the gdbconsole. The text to be displayed issent in its hex byte equivalent (‘H’ ==0x48) and gdb will queue successivemessages until it sees a newline (‘\n’,0x0a) character.This message always originates inthe debugging target; gdb never sendsa console output message to thedebugging target.Empty response (“”)If a debugging stub encounters a com-mand it doesn’t support or under-stand, it should return an emptyresponse. This allows gdb to select analternate command if one is available.Example: <an unrecognized command>Target response: + $#00Error response (“E”)When a debugging stub encounters anerror during command processing, itshould send an error response back togdb. Bus errors and/or illegal address-es during memory operations areexamples of commands which maygenerate an error response from adebugging stub.Example: <a command that producesan error>Target reponse: +$E01#xxThere aren’t any predefined errorcodes in gdb; when gdb receives anerror message, it prints it on the con-sole and halts the operation inprogress.Putting it all togetherAt this point, I’ve covered individuallyall the pieces necessary to get anembedded system talking to gdb. Inthe last article, I covered traps, single-stepping, and a few gdb features; andin the previous section I covered thecommunications protocol that gdbexpects a debugging stub to use. Allwe have left to do now is to throw all ofthese pieces together, right?Actually, we must deal with onemore minor consideration beforewe’re really ready to start debuggingcode: the chicken-and-egg problem ofactually getting the debugging stubinto the embedded system for the firsttime, so that gdb has something withwhich to communicate when we turnon the power.Several methods of attacking thisproblem exist. 2 To me, the best wayalways seems to be to place a minimalstub into some kind of nonvolatilememory in the target, and use thatcode to both boot the system and helpgdb download the rest of the applica-tion into RAM. Once gdb starts theapplication, debugging control thentransfers to a second debugging stublinked with the application itself.Embedded Systems Programming NOVEMBER 1999 111gdb rspThe biggest advantage of thisapproach is that it allows you to con-tinue developing the application-linked debugging stub without need-ing to reprogram the resident stub inthe target’s nonvolatile memory,which is a real bonus if the only non-volatile memory available is one-time-programmable ROM. Furthermore,because the resident stub needs toknow only the simplest commands—read memory, write memory, writeregister N, and continue—the likeli-hood of a serious bug being present inthis code is fairly low.Another approach is to place acomplete debugging stub into the tar-get’s nonvolatile memory, and use itfor all debugging activities. This elimi-nates the need to link a debuggingstub with the target application, butmay make it more difficult to changethe stub if errors are found or new fea-tures are added.If you’re using a commercial micro-processor evaluation board, you mightnot need to provide a debugging stubat all—gdb may already support thevendor’s protocol, or you may be ableto add support to gdb after spending afew minutes reverse-engineering theprotocol with a serial-port analyzer.Check the vendor’s license agreementif you take this approach: you mayneed to sign a non-disclosure agree-ment first, and you will definitely needto seek permission before releasingyour gdb improvements to the com-munity at large.Testing a debugging stubOnce you think you have a debuggingstub ready to go, you’ll want to test itas thoroughly as possible beforeputting it to work. Remember, theonly thing worse than a buggy applica-tion is a buggy development tool.The following is a test procedure Irecommend you use whenever youmake changes to your debugging stub,to make sure things are working theway they should.First, for convenience, add the fol-lowing lines to your .gdbinit file:set remotedebug 1set remotelogfile gdb_logfileThese commands make gdb display allRSP messages exchanged between thehost and the target, as well as log themto the file gdb_logfile.Next, connect gdb to the remotetarget, and enter the target remote[port] command. As gdb makes theconnection, watch the messagesexchanged to make sure that your stubprovides the proper responses to gdb’srequests.During startup, your debuggingstub should load values into each ofthe target processor’s registers. Usegdb’s info registers command toconfirm that gdb can properly receiveand display these values.Next, use gdb’s set command tochange a few register values, and makesure that the stub both properlyresponds to gdb’s write registercommand, and returns the correctresults in subsequent read registerscommands initiated when you typeinfo registers.Next, do the same thing for a fewmemory locations—have the stub setthe locations at startup, and then veri-fy that gdb can read and write theselocations on request. For example, trythe following:print *(long*)0x1234set *(long*)0x1234=5678print *(long*)0x1234If everything works so far, you’reready to try out gdb’s load command.The console will get extremely noisy asgdb displays the multitude of writememory commands it uses to transfer atest application to the target. You’llwant to refer to the log file then, toensure that everything happened asexpected. Once this has been com-pleted, check a few memory locationsin the application’s code space to con-firm that the expected values arethere.The test application should containsome gdb console output if your stub112 NOVEMBER 1999 Embedded Systems Programminggdb rspsupports this command. Enter con-tinue at the gdb console, and see thatthe output appears as you expected.Reset the target, and reload the testapplication. Set a breakpoint immedi-ately before the line that performs theconsole output. Enter continue again,and verify both that the applicationstops where it’s supposed to and thatthe console output appears properlywhen execution resumes.Next (and this can be combinedwith the above test), reload the appli-cation, set a breakpoint, and stepthrough a few source lines with thestep and stepi commands. Make surethat local variables (viewed with thedisplay command) change as expect-ed, and that they don’t change unex-pectedly, particularly when steppingthrough opcodes that branch or jump.Also, monitor the program counter,stack pointer, and other register val-ues, to make sure they change as yourcode dictates they should.At this point, your stub is ready togo.Final thoughtsIn my opinion, gdb has no equal inthe debugging tool community, freeor otherwise. In addition to its stabilityand long list of useful features, gdbprovides the flexibility that today’sembedded developers need at a pricethat’s hard to beat. For those willing toinvest the time necessary to develop adebugging stub, the rewards are botha thorough understanding of theirembedded target’s architecture, andthe services of a powerful, extensibledebugger. espBill Gatliff is a freelance embedded develop-er and senior design engineer withKomatsu Mining Systems, Inc. in Peoria,IL, and is a semi-regular presenter at theEmbedded Systems Conferences. He can bereached at bgat@usa.net.References1. Gatliff, Bill, “Embedding with GNU:GNU Debugger,” Embedded SystemsProgramming, September 1999, p. 80.2 Actually, there are no fewer than sevendifferent ways of accomplishing this,depending on which services the targetcan provide itself vs. which services itneeds external help with. For a morethorough presentation on this subject,see the 1999 Embedded SystemsConference Proceedings for a paperentitled “gdb: An Open SourceDebugger for Embedded Development,”by Stan Shebs, PhD, of CygnusSolutions.Embedded Systems Programming NOVEMBER 1999 113
转载于:https://www.cnblogs.com/linucos/archive/2013/03/01/2939162.html
相关资源:各显卡算力对照表!