📄 ecostestserialfilter.cpp
字号:
static int count = 0; unsigned char c = (unsigned char) (count++ & 0xff); // don't allow $s and @s in the data, nor 0x03 (GDB C-c) if ('$' == c || '@' == c || 0x03 == c) c = (unsigned char) '*'; data_out[i] = c; } // Do checksum. crc = DoCRC(data_out, size); // Send checksum to target. SendChecksum(pSer, crc); switch (mode) { case MODE_NO_ECHO: { // Simple transmit. Don't expect target to echo data back. TargetWrite(pSer, data_out, size); ReceiveDone(pSer, NULL, 0); } break; case MODE_EOP_ECHO: { int in_crc; TargetWrite(pSer, data_out, size); // Expect target to echo the data TargetRead(pSer, data_in, size); // Check echoed data, and reply OK/ER accordingly. in_crc = DoCRC(data_in, size); SendStatus(pSer, (in_crc == crc)); // Dump seen/expected on console. if (in_crc != crc) { Trace("Data seen:\n"); PrintHex(data_in, size); Trace("<end>\n"); Trace("Data expected:\n"); PrintHex(data_out, size); Trace("<end>\n"); } ReceiveDone(pSer, data_in, size); } break; case MODE_DUPLEX_ECHO: { int block_size = 64; int fail, j; // This is a simple implementation (maybe too simple). // Host sends 4 packets with the same size (64 bytes atm). // Target echoes in this way: // packet1 -> packet1 // packet2 -> packet2, packet2 // packet3 -> packet3 // packet4 -> /dev/null // // The reads/writes are interleaved in a way that should ensure // the target out buffer to be full before the target starts to read // packet3. That is, the target should be both receiving (packet3) // and sending (packet2) at the same time. // This code needs restructuring. It's not very obvious what's // happening: The same block of data is output several times, // the target echoes the data back (one of the blocks is // echoed twice). Then the echoed data is compared agains the // outgoing data block. fail = 0; while (loop_count--) { int i; for (i = 0; i < block_size*4; i++) data_in[i] = 0; // out1: block_size -> block_size TargetWrite(pSer, data_out, block_size); // out2: block_size -> 2 x block_size TargetWrite(pSer, data_out, block_size); // in1: TargetRead(pSer, data_in, block_size); // out3: block_size -> block_size TargetWrite(pSer, data_out, block_size); // in2: TargetRead(pSer, &data_in[block_size], 2*block_size); // out4: block_size -> 0 TargetWrite(pSer, data_out, block_size); // in3: TargetRead(pSer, &data_in[block_size*3], block_size); if (0 == loop_count % 10) Trace("%d loops to go\n", loop_count); // Verify data. if (!fail) { for (j = 0; j < 4 && !fail; j++) { for (i = 0; i < block_size && !fail; i++) { if (data_out[i] != data_in[j*block_size + i]) { fail = 1; Trace("Failed at byte %d\n", j*block_size + i); Trace("Data seen:\n"); PrintHex(&data_in[j*block_size], block_size); Trace("<end>\n"); Trace("Data expected:\n"); PrintHex(data_out, block_size); Trace("<end>\n"); } } } } } // Check echoed data, and reply OK/ER accordingly. SendStatus(pSer, (!fail)); ReceiveDone(pSer, data_in, block_size*4); } break; default: Trace("Unknown mode. Ignoring.\n"); } // Free buffer. free(data_in); free(data_out);}//-----------------------------------------------------------------------------// Test transformations on text transmissions//// This test transmits null-terminated C strings back and forth. Since// the translation is under test and may fail, the length of the data is// (potentially) unknown. Sending with a null-terminator allows proper// recovery even if the translations do not work as intended.//// Format in:// <flags>!<4 bytes binary checksum><C string>// Format out:// <C string>// OK/ER//// Mode:// MODE_EOP_ECHO:// Receive data, verify CRC, resend data.// Send OK/ER reply when done.// MODE_DUPLEX_ECHO:// Receive data, echo data, verify CRC.// Send OK/ER reply when done.//// To Do:// Implement.voidCeCosTestSerialFilter::CMD_TestText(CeCosTestSerial &pSer, char* args){ CYG_UNUSED_PARAM(args); SendStatus(pSer, 1);}//-----------------------------------------------------------------------------// Reply to PING packet from target.// Format in:// "!"// Format out:// OKvoidCeCosTestSerialFilter::CMD_TestPing(CeCosTestSerial &pSer, char* args){ CYG_UNUSED_PARAM(args); SendStatus(pSer, 1);}//-----------------------------------------------------------------------------// Dispatch test command. voidCeCosTestSerialFilter::DispatchCommand(CeCosTestSerial &pSer, char* cmd){ char* args; args = strchr(cmd, (int) ':'); if (!args) { Trace("Bogus command (%s) Ignoring.\n", cmd); return; } *args++ = 0; Trace("Dispatching command %s.\n", cmd); if (0 == strcmp("CONFIG", cmd)) { CMD_ChangeConfig(pSer, args); } else if (0 == strcmp("DEFCONFIG", cmd)) { // Note: Currently the arguments are ignored. 9600 8N1 is default. CMD_DefaultConfig(pSer); } else if (0 == strcmp("BINARY", cmd)) { CMD_TestBinary(pSer, args); } else if (0 == strcmp("TEXT", cmd)) { CMD_TestText(pSer, args); } else if (0 == strcmp("PING", cmd)) { CMD_TestPing(pSer, args); } else Trace("Unknown command '%s'.\n", cmd); Trace("Command %s completed.\n", cmd);}bool CALLBACKSerialFilterFunction(void*& pBuf, unsigned int& nRead, CeCosTestSerial& serial, CeCosTestSocket& socket, void* pParem){ CeCosTestSerialFilter* p = (CeCosTestSerialFilter*) pParem; return p->FilterFunctionProper(pBuf, nRead, serial, socket);}boolCeCosTestSerialFilter::FilterFunctionProper(void*& pBuf, unsigned int& nRead, CeCosTestSerial& serial, CeCosTestSocket& socket){ char* buffer = (char*) pBuf; // Don't do anything in the null filter mode. if (m_bNullFilter) return true; // Allows trace to be called without a reference to the socket... m_cGDBSocket = &socket; // Output the serial data if option enabled - but only if dumping // state to the console or after the first command has been seen // from the filter. GDB gets confused by O-packets if they appear // when it's trying to connect. if (m_bOptSerDebug && (m_bOptConsoleOutput || m_bFirstCommandSeen)) PrintHex((unsigned char*) buffer, nRead); // Command handling. // If we are not presently reading a command, look for the // start marker. unsigned int i = 0; if (!m_bCmdFlag) for (; i < nRead; i++) { if ('@' == buffer[i]) { m_bCmdFlag = true; // Send the data before the marker. if (i) socket.send(buffer, i); break; } } // If reading a command, look for the end marker. if (m_bCmdFlag) { char c = 0; while (i < nRead && m_nCmdIndex < MAX_CMD_LEN) { c = buffer[i++]; m_aCmd[m_nCmdIndex++] = c; if ('!' == c) { if (i != nRead) { m_nUnreadBufferIndex = 0; m_nUnreadBufferSize = nRead - i; m_xUnreadBuffer = (unsigned char*) malloc(m_nUnreadBufferSize); if (!m_xUnreadBuffer) { m_nUnreadBufferSize = 0; throw "Could not allocate unread buffer!"; } int ix = 0; while (i < nRead) m_xUnreadBuffer[ix++] = buffer[i++]; } break; } } if (MAX_CMD_LEN == m_nCmdIndex) { Trace("Received too long command. Ignoring it!\n"); m_nCmdIndex = 0; m_bCmdFlag = false; } else if ('!' == c) { // Was the command completed? m_aCmd[m_nCmdIndex - 1] = 0;// terminate cmd m_nCmdIndex = 0; m_bCmdFlag = false; // First command dispatched. Initialize serial to nonblocking. if (!m_bFirstCommandSeen) { m_bFirstCommandSeen = true; serial.SetBlockingReads(false); } try { // skip @ when passing ptr DispatchCommand(serial, &m_aCmd[1]); } catch (filter_abort_t* msg) { // This allows the filter to unwind, wherever in the // protocol it may be, when a $ is detected from the // target side. When this happens, we may have a // trap/exception on the target and we want the user // to access the target via GDB without intervention. // Do nothing from next call. m_bNullFilter = true; // Copy the start of the $-packet to the inbuffer. unsigned char *d = (unsigned char*) pBuf; const unsigned char *s = msg->data_ptr; unsigned int len = msg->data_len; // It should be possible to re-allocate buffer. Didn't seem // to work properly though. Probably won't be a problem // since we would normally only see 1-2 bytes of the // $-packet anyway. if (len > nRead) throw "Not enough room for $-message"; while (len--) *d++ = *s++; nRead = msg->data_len; delete msg; return true; } } nRead = 0; // Never leave anything for caller // This is a violation of the intended // filter function behavior. } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -