📄 ecostestdownloadfilter.cpp
字号:
//####COPYRIGHTBEGIN####
//
// ----------------------------------------------------------------------------
// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
//
// This program is part of the eCos host tools.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// ----------------------------------------------------------------------------
//
//####COPYRIGHTEND####
//=================================================================
//
// eCosTestDownloadFilter.cpp
//
// Socket/serial download filter class
//
//=================================================================
//=================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 1999-09-20
// Description: This filter sits between the (farm) host's socket and
// the serial connection to the target board. The
// filter listens for special download packets from the
// client using the board. The download packet allows
// the relative slow GDB download protocol to be restricted
// to the connection between the farm host and the board.
// This prevents slow downloads due to long round-trip times
// and TCP packets with only a few bytes in them.
// To Do:
// o Move parts shared between eCosTestDownloadFilter and eCosTestSerialFilter
// into a shared class.
//####DESCRIPTIONEND####
#include "eCosStd.h"
#include "eCosTrace.h"
#include "eCosTestDownloadFilter.h"
CeCosTestDownloadFilter::CeCosTestDownloadFilter():
m_bNullFilter(false), m_bOptSerDebug(false), m_bOptFilterTrace(false),
m_nCmdIndex(0), m_bCmdFlag(false), m_bContinueSession(false)
{
}
CeCosTestDownloadFilter::~CeCosTestDownloadFilter()
{
}
//------------------------
// Output helpers.
void
CeCosTestDownloadFilter::ConsoleWrite(const char* pszStr)
{
fputs(pszStr, stderr);
fflush(stderr);
}
void
CeCosTestDownloadFilter::Trace(const char* pszFormat, ...)
{
va_list marker;
va_start (marker, pszFormat);
for(int nLength=100;nLength;) {
char *buf=new char[1+nLength];
int n=vsnprintf(buf+4, nLength-4, pszFormat, marker );
if(-1==n){
nLength*=2; // NT behavior
} else if (n<nLength){
memcpy(buf,"[d] ",4);
ConsoleWrite(buf);
nLength=0; // trigger exit from loop
} else {
nLength=n+1; // UNIX behavior generally, or NT behavior when buffer size exactly matches required length
}
delete [] buf;
}
va_end (marker);
}
void
CeCosTestDownloadFilter::PrintHex(const unsigned char* d1, int len, data_origin_t origin/*=SF_TARGET*/)
{
int offset = 0;
int i;
char buf[128];
int width = 8;
while (len) {
int count = MIN(width, len);
char* p = buf;
switch (origin) {
case SF_TARGET:
p += sprintf(p, "T");
break;
case SF_FILTER:
p += sprintf(p, "F");
break;
}
p += sprintf(p, ":%04x ", offset);
// Print hex values.
for (i = 0; i < count; i++)
p += sprintf(p, "%02x ", d1[i]);
for ( ; i < width ; i++)
p += sprintf(p, ".. ");
// Print ASCII string
p += sprintf(p, "'");
for (i = 0; i < count; i++) {
int c = d1[i];
if (' ' >= c || 'z' <= c)
c = '.';
p += sprintf(p, "%c", c);
}
sprintf(p, "'\n");
Trace("%s", buf);
len -= count;
offset += count;
d1 += count;
}
}
void
CeCosTestDownloadFilter::TargetWrite(CeCosSerial &pSer,
const unsigned char* buffer, int len)
{
unsigned int __written;
if (m_bOptSerDebug)
PrintHex(buffer, len, SF_FILTER);
do {
if (!(pSer.Write((void*) buffer, len, __written))) {
fprintf(stderr, "Writing %d bytes to serial failed\n", len);
fprintf(stderr, "%s", (LPCTSTR)pSer.ErrString());
throw _T("serial write failed");
}
buffer += __written;
len -= __written;
} while (len);
}
// Snuffed from gdb/remote.c
int
CeCosTestDownloadFilter::tohex (int nib)
{
if (nib < 10)
return '0'+nib;
else
return 'a'+nib-10;
}
int
CeCosTestDownloadFilter::hexnumstr (unsigned char* buf, unsigned long num)
{
int i;
unsigned long num2 = num;
for (i = 0; num2 != 0; i++)
num2 >>= 4;
int len = MAX (i, 1);
buf[len] = '\0';
for (i = len - 1; i >= 0; i--)
{
buf[i] = "0123456789abcdef" [(num & 0xf)];
num >>= 4;
}
return len;
}
int
CeCosTestDownloadFilter::hexnumlen (unsigned long num)
{
int i;
unsigned long num2 = num;
for (i = 0; num2 != 0; i++)
num2 >>= 4;
return MAX (i, 1);
}
// Based on routines in gdb/remote.c
int
CeCosTestDownloadFilter::put_binary (unsigned char* buf, int len,
unsigned long dl_address,
int packet_size,
CeCosSerial& serial)
{
int i;
unsigned char csum;
Buffer buf2(packet_size);
unsigned char ch;
int tcount = 0;
unsigned char *p, *p2, *plen;
while (len > 0) {
/* Subtract header overhead from MAX payload size:
$M<memaddr>,<len>:#nn */
int max_buf_size =
buf2.Size()
- ( 2 + hexnumlen(dl_address) + 1 + hexnumlen(buf2.Size()) + 4);
/* Copy the packet into buffer BUF2, encapsulating it
and giving it a checksum. */
int todo = MIN (len, max_buf_size);
p = (unsigned char*) buf2.Data();
*p++ = '$';
// Add X header.
*p++ = 'X';
p += hexnumstr(p, dl_address);
*p++ = ',';
plen = p; /* remember where len field goes */
p += hexnumstr(p, todo);
*p++ = ':';
int escaped = 0;
for (i = 0;
(i < todo) && (i + escaped) < (max_buf_size - 2);
i++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -