⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remote.cc

📁 avrrice软件用于AVR单片机的JTAG调试.
💻 CC
📖 第 1 页 / 共 2 页
字号:
		mem2hex(&checksum, buf, 4);		gdbOut("Bad checksum: my count = %s, ", buf);		mem2hex(&xmitcsum, buf, 4);		gdbOut("sent count = %s\n", buf);		gdbOut(" -- Bad buffer: \"%s\"\n", buffer);		putDebugChar('-');	// failed checksum	    }	    else	    {		putDebugChar('+');	// successful transfer		// if a sequence char is present, reply the sequence ID		if(buffer[2] == ':')		{		    putDebugChar(buffer[0]);		    putDebugChar(buffer[1]);		    return &buffer[3];		}		return &buffer[0];	    }	}    }}/** Send packet 'buffer' to gdb. Adds $, # and checksum wrappers. **/static void putpacket(char *buffer){    unsigned char checksum;    int count;    char ch;    //  $<packet info>#<checksum>.    do    {	putDebugChar('$');	checksum = 0;	count = 0;	while((ch = buffer[count]))	{	    putDebugChar(ch);	    checksum += ch;	    count += 1;	}	putDebugChar('#');	putDebugChar(hexchars[checksum >> 4]);	putDebugChar(hexchars[checksum % 16]);    } while(getDebugChar() != '+'); // wait for the ACK}/** Set remcomOutBuffer to "ok" response */static void ok(){    strcpy(remcomOutBuffer, "OK");}/** Set remcomOutBuffer to error 'n' response */static void error(int n){    char *ptr = remcomOutBuffer;    *ptr++ = 'E';    ptr = byteToHex(n, ptr);    *ptr = '\0';}static void repStatus(bool breaktime){    if (breaktime)	reportStatusExtended(SIGTRAP);    else    {	// A breakpoint did not occur. Assume that GDB sent a break.	// Halt the target.	interruptProgram();	// Report this as a user interrupt	reportStatusExtended(SIGINT);    }}void talkToGdb(void){    int addr, start, end;    int length;    int i;    unsigned int newPC;    int regno;    char *ptr;    bool adding = false;    bool dontSendReply = false;    char cmd;    static char last_cmd = 0;    ptr = getpacket();    debugOut("GDB: <%s>\n", ptr);    // default empty response    remcomOutBuffer[0] = 0;    cmd = *ptr++;    switch (cmd)    {    default:	// Unknown code.  Return an empty reply message.	break;    case 'k':	// kill the program	dontSendReply = true;	break;    case 'R':	if (!resetProgram())	    gdbOut("reset failed\n");        dontSendReply = true;	break;    case '!':	ok();	break;    case 'M':    {	uchar *jtagBuffer;        int lead = 0;        static bool last_orphan_pending = false;        static uchar last_orphan = 0xff;	// MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK	// TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0	error(1); // default is error	if((hexToInt(&ptr, &addr)) &&	   (*(ptr++) == ',') &&	   (hexToInt(&ptr, &length)) &&	   (*(ptr++) == ':') &&	   (length > 0))	{	    debugOut("\nGDB: Write %d bytes to 0x%X\n",		      length, addr);            // There is no gaurantee that gdb will send a word aligned stream            // of bytes, so we need to try and catch that here. This ugly, but            // it would more difficult to change in gdb and probably affect            // more than avarice users. This hack will make the gdb 'load'            // command less prone to failure.            if (addr & 1)            {                // odd addr means there may be a byte from last 'M' to write                if ((last_cmd == 'M') && (last_orphan_pending))                {                    length++;                    addr--;                    lead = 1;                }            }            last_orphan_pending = false;	    jtagBuffer = new uchar[length];	    hex2mem(ptr, jtagBuffer+lead, length);            if (lead)                jtagBuffer[0] = last_orphan;            if ((addr < DATA_SPACE_ADDR_OFFSET) && (length & 1))            {                // An odd length means we will have an orphan this round but                // only if we are writing to PROG space.                last_orphan_pending = true;                last_orphan = jtagBuffer[length];                length--;            }	    if (jtagWrite(addr, length, jtagBuffer))		ok();	    delete [] jtagBuffer;	}	break;    }    case 'm':	// mAA..AA,LLLL  Read LLLL bytes at address AA..AA    {	uchar *jtagBuffer;	error(1); // default is error	if((hexToInt(&ptr, &addr)) &&	   (*(ptr++) == ',') &&	   (hexToInt(&ptr, &length)))	{	    debugOut("\nGDB: Read %d bytes from 0x%X\n", length, addr);	    jtagBuffer = jtagRead(addr, length);	    if (jtagBuffer)	    {		mem2hex(jtagBuffer, remcomOutBuffer, length);		delete [] jtagBuffer;	    }	}	break;    }    case '?':        // Report status. We don't actually know, so always report breakpoint	reportStatus(SIGTRAP);	break;    case 'g':   // return the value of the CPU registers    {	uchar *jtagBuffer;        uchar regBuffer[40];        memset(regBuffer, 0, sizeof(regBuffer));	// Read the registers directly from memory	// R0..R31 are at locations 0..31	// SP is at 0x5D & 0x5E	// SREG is at 0x5F	debugOut("\nGDB: (Registers)Read %d bytes from 0x%X\n",		  0x20, 0x00 + DATA_SPACE_ADDR_OFFSET);	jtagBuffer = jtagRead(0x00 + DATA_SPACE_ADDR_OFFSET, 0x20);	if (jtagBuffer)	{            // Put GPRs into the first 32 locations            memcpy(regBuffer, jtagBuffer, 0x20);            delete [] jtagBuffer;            jtagBuffer = 0;        }        else        {            error (1);            break;        }        // Read in SPL SPH SREG        jtagBuffer = jtagRead(0x5D + DATA_SPACE_ADDR_OFFSET, 0x03);             if (jtagBuffer)        {            // We have SPL SPH SREG and need SREG SPL SPH            // SREG            regBuffer[0x20] = jtagBuffer[0x02];            // NOTE: Little endian, so SPL comes first.            // SPL            regBuffer[0x21] = jtagBuffer[0x00];            // SPH            regBuffer[0x22] = jtagBuffer[0x01];            delete [] jtagBuffer;            jtagBuffer = 0;        }        else        {            error (1);            break;        }        // PC        newPC = getProgramCounter();        regBuffer[35] = (unsigned char)(newPC & 0xff);        regBuffer[36] = (unsigned char)((newPC & 0xff00) >> 8);        regBuffer[37] = (unsigned char)((newPC & 0xff0000) >> 16);        regBuffer[38] = (unsigned char)((newPC & 0xff000000) >> 24);        debugOut("PC = %x\n", newPC);        if (newPC == PC_INVALID)            error(1);        else            mem2hex(regBuffer, remcomOutBuffer, 32 + 1 + 2 + 4);	break;    }    case 'q':   // general query    {        uchar* jtagBuffer;        length = strlen("Ravr.io_reg");        if ( strncmp(ptr, "Ravr.io_reg", length) == 0 )        {            int i, j, regcount;            gdb_io_reg_def_type *io_reg_defs;            debugOut("\nGDB: (io registers) Read %d bytes from 0x%X\n",                     0x40, 0x20);            /* If there is an io_reg_defs for this device then respond */            io_reg_defs = global_p_device_def->io_reg_defs;            if (io_reg_defs)            {                // count the number of defined registers                regcount = 0;                while (io_reg_defs[regcount].name)                {                    regcount++;                }                ptr += length;                if (*ptr == '\0')                {                    sprintf(remcomOutBuffer, "%02x", regcount);                }                else if (*ptr == ':')                {                    // Request for a sequence of io registers                    int offset;                    i = 0;                     j = 0;                    unsigned int count;                    unsigned int addr;                    // Find the first register                    ptr++;                    hexToInt(&ptr,&i);                    // Confirm presence of ','                    if (*ptr++ == ',')                    {                        hexToInt(&ptr,&j);                    }                    // i is the first register to read                    // j is the number of registers to read                    while ((j > 0) && (i < regcount))                    {                        count = 0;                        if ((io_reg_defs[i].name != 0x00)                            && (io_reg_defs[i].flags != 0x00))                        {                            // Register with special flags set                            offset = strlen(remcomOutBuffer);                            sprintf(&remcomOutBuffer[offset],                                    "[-- %s --],00;", io_reg_defs[i].name);                            i++;                            j--;                        }                        else                        {                            // Get the address of the first io_register to be                            // read                            addr = io_reg_defs[i].reg_addr;                            // Count the number of consecutive address,                            // no-side effects, valid registers                            for (count = 0; count < j; count++)                            {                                if ((io_reg_defs[i+count].name == 0x00)                                     || (io_reg_defs[i+count].flags != 0x00)                                    || (io_reg_defs[i+count].reg_addr != addr))                                {                                    break;                                }                                addr++;                            }								                            if (count)                            {                                // Read consecutive address io_registers                                jtagBuffer = jtagRead(DATA_SPACE_ADDR_OFFSET +                                                      io_reg_defs[i].reg_addr,                                                      count);								                                if (jtagBuffer)                                {                                    int k = 0;                                    // successfully read                                    while(count--)                                    {                                        offset = strlen(remcomOutBuffer);                                        sprintf(&remcomOutBuffer[offset],                                                "%s,%02x;",                                                io_reg_defs[i].name,                                                jtagBuffer[k++]);                                        i++;                                        j--;                                    }                                    delete [] jtagBuffer;                                    jtagBuffer = 0;                                }                            }                        }                    }                }            }        }        break;    }    case 'P':   // set the value of a single CPU register - return OK	error(1); // error by default	if (hexToInt(&ptr, &regno) && *ptr++ == '=')        {            uchar reg[4];            if (regno >= 0 && regno < NUMREGS)            {		hex2mem(ptr, reg, 1);                if (jtagWrite(regno+DATA_SPACE_ADDR_OFFSET, 1, reg))		    ok();                break;            }            else if (regno == SREG)            {		hex2mem(ptr, reg, 1);                if (jtagWrite(0x5f+DATA_SPACE_ADDR_OFFSET, 1, reg))		    ok();            }	    else if (regno == SP)	    {		hex2mem(ptr, reg, 2);		if (jtagWrite(0x5d+DATA_SPACE_ADDR_OFFSET, 2, reg))		    ok();	    }	    else if (regno == PC)	    {		hex2mem(ptr, reg, 4);		if (setProgramCounter(reg[0] | reg[1] << 8 |				      reg[2] << 16 | reg[3] << 24))		    ok();	    }        }	break;    case 'G':	// set the value of the CPU registers	// It would appear that we don't need to support this as	// we have 'P'. Report an error (rather than fail silently,	// this will make errors in this comment more apparent...)	error(1);	break;    case 's':  // sAA..AA    Step one instruction from AA..AA(optional)	// try to read optional parameter, pc unchanged if no parm	if (hexToInt(&ptr, &addr))	{	    if (!setProgramCounter(addr))		gdbOut("Failed to set PC");	}	repStatus(singleStep());	break;    case 'e': //eAA..AA,BB..BB continue until pc leaves [A..B[ range      if (hexToInt(&ptr, &start) &&	  *ptr++ == ',' &&	  hexToInt(&ptr, &end))      {	  debugOut("single step from %x to %x\n", start, end);	  putpacket("OK");	  repStatus(start == end ? singleStep() : stepThrough(start, end));      }      break;    case 'C':    {        /* Continue with signal command format:           "C<sig>;<addr>" or "S<sig>;<addr>"           "<sig>" should always be 2 hex digits, possibly zero padded.           ";<addr>" part is optional.           If addr is given, resume at that address, otherwise, resume at           current address. */        int sig;        if (hexToInt(&ptr, &sig))        {            if (sig == SIGHUP)            {                if (resetProgram())                {                    reportStatusExtended(SIGTRAP);                }            }        }        break;    }    case 'c':  // cAA..AA    Continue from address AA..AA(optional)	// try to read optional parameter, pc unchanged if no parm	if (hexToInt(&ptr, &addr))	{	    if (!setProgramCounter(addr))		gdbOut("Failed to set PC");	}	repStatus(jtagContinue(true));	break;    case 'D':        // Detach, resumes target. Can get control back with step	// or continue      if (resumeProgram())	    ok();	else	    error(1);	break;    case 'Z':	adding = true;    case 'z':	error(1); // assume the worst.	// Add a Breakpoint. note: length specifier is ignored for now.	if (hexToInt(&ptr, &i) && *ptr++ == ',' &&	    hexToInt(&ptr, &addr) && *ptr++ == ',' &&	    hexToInt(&ptr, &length))	{	    bpType mode = NONE;	    switch(i)	    {	    case 0:	    case 1:		mode = CODE;		break;	    case 2:		mode = WRITE_DATA;		break;	    case 3:		mode = READ_DATA;		break;	    case 4:		mode = ACCESS_DATA;		break;	    default:		debugOut("Unknown breakpoint type from GDB.\n");		exit(1);	    }	    if (adding)	    {		if (addBreakpoint(addr, mode, length))		    ok();	    }	    else	    {		if (deleteBreakpoint(addr, mode, length))		    ok();	    }	}	break;    }	// switch    last_cmd = cmd;    // reply to the request    if (!dontSendReply)    {        debugOut("->GDB: %s\n", remcomOutBuffer);	putpacket(remcomOutBuffer);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -