* Semihosting output on ARM7TDMI
@ 2001-08-14 4:51 Joel Brenner
2001-08-14 7:56 ` Grant Edwards
0 siblings, 1 reply; 8+ messages in thread
From: Joel Brenner @ 2001-08-14 4:51 UTC (permalink / raw)
To: gdb
Hi I'm using JEENI debug module wich supports semihosting (libc) on a
ARM7TDMI target. I'make use of function printf() from newlib wich seems
to work.
I've tried to execute "printf("abc\n\n");" and I've logged the ADP
communication:
....
R=0001000d H->T CI_HADP: ADP_Execute 00000000
rx: [T=0 L=24] 01 d1 d1 01 0d 00 01 80 00 00 00 00 ff ff ff ff ff ff ff
ff 00 00 00 00
R=8001000d H<-T CI_HADP: ADP_Execute 00000000
rx: [T=0 L=36] 05 d2 d1 01 69 00 00 80 00 00 00 00 ff ff ff ff ff ff ff
ff 00 00 00 00 04 00 00 00 04 00 00 00 61 62 63 0a
R=80000069 H<-T CI_CLIB: CL_Write 00000000 00000004 00000004 0a636261
tx: [T=0 L=28] 05 d2 d2 01 69 00 00 00 00 00 00 00 ff ff ff ff ff ff ff
ff 01 00 00 00 04 00 00 00
R=00000069 H->T CI_CLIB: CL_Write 00000001 00000004
rx: [T=0 L=33] 05 d3 d2 01 69 00 00 80 00 00 00 00 ff ff ff ff ff ff ff
ff 00 00 00 00 01 00 00 00 01 00 00 00 0a
R=80000069 H<-T CI_CLIB: CL_Write 00000000 00000001 00000001 0000000a
tx: [T=0 L=28] 05 d3 d3 01 69 00 00 00 00 00 00 00 ff ff ff ff ff ff ff
ff 01 00 00 00 01 00 00 00
R=00000069 H->T CI_CLIB: CL_Write 00000001 00000001
rx: [T=0 L=28] 02 d4 d3 01 01 00 02 80 00 00 00 00 ff ff ff ff ff ff ff
ff 20 00 02 00 00 00 00 00
R=80020001 H<-T CI_TADP: ADP_Stopped 00020020 00000000
...
but no message are printed to gdb console. Are the above messages
correct?
Whath is the command to enable semihosting? Where GDB puts the receved
strings ?
tanks Brenner Joel
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: Semihosting output on ARM7TDMI 2001-08-14 4:51 Semihosting output on ARM7TDMI Joel Brenner @ 2001-08-14 7:56 ` Grant Edwards 2001-08-14 8:33 ` Andrew Cagney 0 siblings, 1 reply; 8+ messages in thread From: Grant Edwards @ 2001-08-14 7:56 UTC (permalink / raw) To: Joel Brenner; +Cc: gdb On Tue, Aug 14, 2001 at 02:49:01PM +0200, Joel Brenner wrote: > Hi I'm using JEENI debug module wich supports semihosting (libc) on a > ARM7TDMI target. I'make use of function printf() from newlib wich seems > to work. > I've tried to execute "printf("abc\n\n");" and I've logged the ADP > communication: > .... > R=0001000d H->T CI_HADP: ADP_Execute 00000000 > rx: [T=0 L=24] 01 d1 d1 01 0d 00 01 80 00 00 00 00 ff ff ff ff ff ff ff > ff 00 00 00 00 > R=8001000d H<-T CI_HADP: ADP_Execute 00000000 > rx: [T=0 L=36] 05 d2 d1 01 69 00 00 80 00 00 00 00 ff ff ff ff ff ff ff > ff 00 00 00 00 04 00 00 00 04 00 00 00 61 62 63 0a > R=80000069 H<-T CI_CLIB: CL_Write 00000000 00000004 00000004 0a636261 > tx: [T=0 L=28] 05 d2 d2 01 69 00 00 00 00 00 00 00 ff ff ff ff ff ff ff > ff 01 00 00 00 04 00 00 00 > R=00000069 H->T CI_CLIB: CL_Write 00000001 00000004 > rx: [T=0 L=33] 05 d3 d2 01 69 00 00 80 00 00 00 00 ff ff ff ff ff ff ff > ff 00 00 00 00 01 00 00 00 01 00 00 00 0a > R=80000069 H<-T CI_CLIB: CL_Write 00000000 00000001 00000001 0000000a > tx: [T=0 L=28] 05 d3 d3 01 69 00 00 00 00 00 00 00 ff ff ff ff ff ff ff > ff 01 00 00 00 01 00 00 00 > R=00000069 H->T CI_CLIB: CL_Write 00000001 00000001 > rx: [T=0 L=28] 02 d4 d3 01 01 00 02 80 00 00 00 00 ff ff ff ff ff ff ff > ff 20 00 02 00 00 00 00 00 > R=80020001 H<-T CI_TADP: ADP_Stopped 00020020 00000000 How handy! > but no message are printed to gdb console. Are the above > messages correct? Whath is the command to enable semihosting? > Where GDB puts the receved strings ? IIRC, The RDI interface code writes semihosting output data to whatever filedescriptor is requested. I think your request are for fd 0. The CL_Write data is fd,len,len,data. I've no clue why the length is there twice. There is an internal file table that translates from "RDI" fd number to Unix FILE pointers. The table is initialized to be empty, and then filled in when the semi-hosting client opens files. It looks like it needs to be changed so that it is pre-initialized so that stdin, stdout, and stderr are "pre-opened". I think you'll need to change the code in rdi-share/hsys.c HostSysInit() so that fds 0,1,2, are initialized to map to FILE pointers stdin, stdout, stderr. If you enable debugging info in hsys.c (by adding "#define DEBUG" at the top of the file) you might be able to get a better idea about what's going on. -- Grant Edwards grante@visi.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI 2001-08-14 7:56 ` Grant Edwards @ 2001-08-14 8:33 ` Andrew Cagney 2001-08-14 8:46 ` Grant Edwards 0 siblings, 1 reply; 8+ messages in thread From: Andrew Cagney @ 2001-08-14 8:33 UTC (permalink / raw) To: Grant Edwards; +Cc: Joel Brenner, gdb > It looks like it needs to be changed so that it is > pre-initialized so that stdin, stdout, and stderr are > "pre-opened". I think you'll need to change the code in > rdi-share/hsys.c HostSysInit() so that fds 0,1,2, are > initialized to map to FILE pointers stdin, stdout, stderr. Almost. The theory is right. For output the ``struct ui_file'' objects gdb_std*, normally target output is sent to gdb_stdtarg (one day I'll remember to rename it to gdb_targout). For input, things get messy, if you look at remote.c and fixme's from me there are hopefully enough hints on how it can be done, in theory. It is made complicated by the fact that there is an event look wanting a look-in. Andrew ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI 2001-08-14 8:33 ` Andrew Cagney @ 2001-08-14 8:46 ` Grant Edwards 2001-08-14 9:11 ` Andrew Cagney 0 siblings, 1 reply; 8+ messages in thread From: Grant Edwards @ 2001-08-14 8:46 UTC (permalink / raw) To: Andrew Cagney; +Cc: Joel Brenner, gdb On Tue, Aug 14, 2001 at 11:33:02AM -0400, Andrew Cagney wrote: > > It looks like it needs to be changed so that it is > > pre-initialized so that stdin, stdout, and stderr are > > "pre-opened". I think you'll need to change the code in > > rdi-share/hsys.c HostSysInit() so that fds 0,1,2, are > > initialized to map to FILE pointers stdin, stdout, stderr. > > Almost. The theory is right. > > For output the ``struct ui_file'' objects gdb_std*, normally target > output is sent to gdb_stdtarg (one day I'll remember to rename it to > gdb_targout). Er, wha? The routines in rdi-remote/hsys.c have no idea that gdb is "up there" somewhere. The RDI file table is in a structure defined like so: typedef struct { FILE *FileTable[HSYS_FOPEN_MAX] ; char FileFlags[HSYS_FOPEN_MAX] ; char *TempNames[UNIQUETEMPS]; } OSblock; The initialization (rdi-remote/hsys.c) looks like this 77 /* Set up the state block, filetable and register the C lib callback fn */ 78 int HostSysInit(const struct Dbg_HostosInterface *hostif, char **cmdline, 79 hsys_state **stateptr) 80 { 81 ChannelCallback HandleMessageFPtr = (ChannelCallback) HandleSysMessage; 82 int i; 83 *stateptr = (hsys_state *)malloc(sizeof(hsys_state)); 84 85 if (*stateptr == NULL) return RDIError_OutOfStore; 86 87 (*stateptr)->hostif=hostif; 88 (*stateptr)->last_errno=0; 89 (*stateptr)->OSptr=(OSblock *)malloc(sizeof(OSblock)); 90 if ((*stateptr)->OSptr == NULL) return RDIError_OutOfStore; 91 for (i=0; i<UNIQUETEMPS; i++) (*stateptr)->OSptr->TempNames[i]=NULL; 92 for (i=0; i<HSYS_FOPEN_MAX; i++) { 93 (*stateptr)->OSptr->FileTable[i]=NULL; 94 (*stateptr)->OSptr->FileFlags[i]=0; 95 } 96 (*stateptr)->CommandLine=cmdline; 97 98 return Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleMessageFPtr, 99 *stateptr); 100 } I think that it might work if the lines below were added somewhere after the second for() loop: (*stateptr)->OSptr->FileTable[0] = stdin; (*stateptr)->OSptr->FileTable[1] = stdout; (*stateptr)->OSptr->FileTable[2] = stderr; I don't think that FileFlags[n] needs to be initialized to anything other than zero, but I'm not sure about that. It would be possible to make these routines "gdb aware" but they aren't at the moment -- semi-hosting requests are handled below the gdb<->RDI interface. > For input, things get messy, if you look at remote.c and fixme's from me > there are hopefully enough hints on how it can be done, in theory. It > is made complicated by the fact that there is an event look wanting a > look-in. I think you're looking at the wrong target. ;) -- Grant Edwards grante@visi.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI 2001-08-14 8:46 ` Grant Edwards @ 2001-08-14 9:11 ` Andrew Cagney 2001-08-14 9:24 ` Grant Edwards 0 siblings, 1 reply; 8+ messages in thread From: Andrew Cagney @ 2001-08-14 9:11 UTC (permalink / raw) To: Grant Edwards; +Cc: Joel Brenner, gdb > On Tue, Aug 14, 2001 at 11:33:02AM -0400, Andrew Cagney wrote: > >> > It looks like it needs to be changed so that it is >> > pre-initialized so that stdin, stdout, and stderr are >> > "pre-opened". I think you'll need to change the code in >> > rdi-share/hsys.c HostSysInit() so that fds 0,1,2, are >> > initialized to map to FILE pointers stdin, stdout, stderr. > >> >> Almost. The theory is right. >> >> For output the ``struct ui_file'' objects gdb_std*, normally target >> output is sent to gdb_stdtarg (one day I'll remember to rename it to >> gdb_targout). > > > Er, wha? > > The routines in rdi-remote/hsys.c have no idea that gdb is "up > there" somewhere. > > The RDI file table is in a structure defined like so: > > typedef struct { > FILE *FileTable[HSYS_FOPEN_MAX] ; > char FileFlags[HSYS_FOPEN_MAX] ; > char *TempNames[UNIQUETEMPS]; > } OSblock; If you don't route the output from the target through gdb_stdtarg then people, using GUI's, will complain that their output disappears or turns up in the wrong place. gdb_stdtarg captures all output and then passes it through to things like the console. How you manage to get the output routed to gdb_stdtarg, er, isn't my problem :-) > It would be possible to make these routines "gdb aware" but > they aren't at the moment -- semi-hosting requests are handled > below the gdb<->RDI interface. It isn't so much GDB aware not assume that the world is a UNIX tty. >> For input, things get messy, if you look at remote.c and fixme's from me >> there are hopefully enough hints on how it can be done, in theory. It >> is made complicated by the fact that there is an event look wanting a >> look-in. > > > I think you're looking at the wrong target. [;)] The theory is the same. remote.c contains a working example of correctly wired output. It also contains a nasty hack, from Cygnus/Cisco, to both co-ordinate target output and GDB input. How much of that you need for tty UNIX I don't know. I do know that and a lot more are needed to get GDB handling this correctly in a GUI environment. Andrew ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI 2001-08-14 9:11 ` Andrew Cagney @ 2001-08-14 9:24 ` Grant Edwards 2001-08-14 9:31 ` Keith Seitz 0 siblings, 1 reply; 8+ messages in thread From: Grant Edwards @ 2001-08-14 9:24 UTC (permalink / raw) To: Andrew Cagney; +Cc: Joel Brenner, gdb On Tue, Aug 14, 2001 at 12:11:17PM -0400, Andrew Cagney wrote: > > The routines in rdi-remote/hsys.c have no idea that gdb is "up > > there" somewhere. > > > > The RDI file table is in a structure defined like so: > > > > typedef struct { > > FILE *FileTable[HSYS_FOPEN_MAX] ; > > char FileFlags[HSYS_FOPEN_MAX] ; > > char *TempNames[UNIQUETEMPS]; > > } OSblock; > > If you don't route the output from the target through > gdb_stdtarg then people, using GUI's, will complain that their > output disappears or turns up in the wrong place. gdb_stdtarg > captures all output and then passes it through to things like > the console. I understand. But, the RDI stuff isn't aware of gdb, and it would take some work to make it aware. It would be "a good thing" but somebody would have to want it bad enough to actuallly do it. > How you manage to get the output routed to gdb_stdtarg, er, > isn't my problem :-) Nor mine, since I don't use semi-hosting. ;) > > It would be possible to make these routines "gdb aware" but > > they aren't at the moment -- semi-hosting requests are handled > > below the gdb<->RDI interface. > > It isn't so much GDB aware not assume that the world is a UNIX > tty. Right now, the RDI host-end stuff assumes the world is a Unix filesystem and that you have to open any files before you access them. The client-end stuff appears to assume that fd 0 is pre-opened. My three-line hack will (maybe) make accesses to fd 0, 1, 2 translate into accesses to stdin, stdout, and stderr. Whether the user wants to access stdin/stdout/stderr verses the the gdb console is another question. > The theory is the same. remote.c contains a working example of > correctly wired output. It also contains a nasty hack, from > Cygnus/Cisco, to both co-ordinate target output and GDB input. > > How much of that you need for tty UNIX I don't know. I do know > that and a lot more are needed to get GDB handling this > correctly in a GUI environment. It would be nice if the RDI code were made gdb-aware, but I'm aware of no plans to do it. -- Grant Edwards grante@visi.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI 2001-08-14 9:24 ` Grant Edwards @ 2001-08-14 9:31 ` Keith Seitz 2001-08-14 11:43 ` Grant Edwards 0 siblings, 1 reply; 8+ messages in thread From: Keith Seitz @ 2001-08-14 9:31 UTC (permalink / raw) To: Grant Edwards; +Cc: Andrew Cagney, gdb On Tue, 14 Aug 2001, Grant Edwards wrote: > But, the RDI stuff isn't aware of gdb, and it would take some > work to make it aware. It would be "a good thing" but somebody > would have to want it bad enough to actuallly do it. Isn't there already some machinery in place to do target I/O? You can certainly do printf and the like on an arm board using rdi and gdb. What do the the members writec, readc, write, gets in struct Dbg_HostosInterface mean? Specifically: /* Open a connection to a remote debugger. NAME is the filename used for communication. */ static void arm_rdi_open (char *name, int from_tty) { /* snip */ rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat); if (rslt != adp_ok) error ("Could not open device \"%s\"", name); gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BIG_ENDIAN ? 1 : 0); gdb_config.fpe = 1; gdb_config.rditype = 2; gdb_config.heartbeat_on = 1; gdb_config.flags = 2; gdb_hostif.dbgprint = myprint; gdb_hostif.dbgpause = mypause; gdb_hostif.dbgarg = NULL; gdb_hostif.writec = mywritec; gdb_hostif.readc = myreadc; gdb_hostif.write = mywrite; gdb_hostif.gets = mygets; gdb_hostif.hostosarg = NULL; gdb_hostif.reset = voiddummy; rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL); /* snip */ Doesn't any of this deal with "semi-hosting"? Keith ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Semihosting output on ARM7TDMI 2001-08-14 9:31 ` Keith Seitz @ 2001-08-14 11:43 ` Grant Edwards 0 siblings, 0 replies; 8+ messages in thread From: Grant Edwards @ 2001-08-14 11:43 UTC (permalink / raw) To: Keith Seitz; +Cc: Andrew Cagney, gdb On Tue, Aug 14, 2001 at 09:31:26AM -0700, Keith Seitz wrote: > On Tue, 14 Aug 2001, Grant Edwards wrote: > > > But, the RDI stuff isn't aware of gdb, and it would take some > > work to make it aware. It would be "a good thing" but somebody > > would have to want it bad enough to actuallly do it. > > Isn't there already some machinery in place to do target I/O? You can > certainly do printf and the like on an arm board using rdi and gdb. I wasn't aware that that stuff worked. What I've seen in the past is that the semi-hosting routines generates the "CL_Write" messages, and the handler for that flushes the data. > What do the the members writec, readc, write, gets in struct > Dbg_HostosInterface mean? Specifically: It appears that they're the routines that are supposed to get called for semi-hosting console I/O. > gdb_hostif.dbgprint = myprint; > gdb_hostif.dbgpause = mypause; > gdb_hostif.dbgarg = NULL; > gdb_hostif.writec = mywritec; > gdb_hostif.readc = myreadc; > gdb_hostif.write = mywrite; > gdb_hostif.gets = mygets; > gdb_hostif.hostosarg = NULL; > gdb_hostif.reset = voiddummy; >> > Doesn't any of this deal with "semi-hosting"? It's supposed to, but I don't think it all works. From what I've seen, the semi-hosting client stuff generates writes to fd 0, and since that fd has never been opened, the data is discarded in hsys.c by HandleSysMessage: 490 case CL_Write: 491 { 492 /* Write(word handle, word nbtotal, word nbytes, bytes data) 493 * return(word nbytes) 494 * WriteX(word nbytes, bytes data) 495 * return(word nbytes) 496 */ 497 unsigned char *rwdata = NULL, *rwhead = NULL; 498 unsigned char *write_source = NULL; 499 char flags; 500 FILE *fhreal; 501 unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */ 502 503 err = -1; /* err == 0 is fwrite() error indication */ 504 unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes); 505 DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n", 506 fh, nbtotal, nbytes)); 507 ** 508 fhreal = hsysGetRealFileHandle(stateptr, fh, &flags); 509 nbtogo = nbtotal; 510 511 /* deal with the file handle */ ** 512 if (fhreal == NULL) ** 513 err = 0; 514 else { 515 if (flags & READOP) 516 fseek(fhreal,0,SEEK_CUR); 517 stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP; line 508 returns a NULL, since no file has been opened, and the data is flushed. [It looks like CL_WriteC and CL_ReadC do what they should: calling hostif->writec and hostif->readc, but I've never seen anybody post ADP traces that showed those being used.] Aha! I just noticed something that I missed before... It also looks like somebody _did_ create a special case when an fd maps to stdout or stderr by calling hostif->write() instead of calling fwrite() on the file handle directly. The RDI stuff is more aware than I thought. It isn't aware specifically of gdb, but the remote-rdi.c adapts the RDI API well enough that I think semi-hosting can be made to work right. 535 do { 536 /* at least once!! */ 537 538 if (nbtogo == 0 && err != 0) { 539 /* Do the actual write! */ ** 540 if (fhreal == stdout || fhreal == stderr) { ** 541 stateptr->hostif->write(stateptr->hostif->hostosarg, 542 (char *)write_source, nbtotal); 543 } 544 else ** 545 err = fwrite(write_source, 1, nbtotal, fhreal); 546 stateptr->last_errno = errno; 547 DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno); 548 } 549 I think that if you initialize fd #0 to be stdout, then the hostif->write() routine will get called, and that in turn calls fputc_unfiltered(c,gdb_stdout). I don't know why the semi-hosting client routines are writing to fd 0 (which I would assume to be stdin) rather than 1 (stdout) or 2 (stderr). So one could try changing my three-line kludge to initialize the first fd to stdout instead of stdin. The handling for CL_Read is different and doesn't check for stdin, stdout, stderr. Instead, if the fd maps to a file handle that's a tty, then hostif->gets() is called which then does an fgets() on stdin. Otherwise fread() is called on the file handle. -- Grant Edwards grante@visi.com ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2001-08-14 11:43 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2001-08-14 4:51 Semihosting output on ARM7TDMI Joel Brenner 2001-08-14 7:56 ` Grant Edwards 2001-08-14 8:33 ` Andrew Cagney 2001-08-14 8:46 ` Grant Edwards 2001-08-14 9:11 ` Andrew Cagney 2001-08-14 9:24 ` Grant Edwards 2001-08-14 9:31 ` Keith Seitz 2001-08-14 11:43 ` Grant Edwards
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox