📄 ser_filter.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####
//=================================================================
//
// ser_filter.cxx
//
// Serial test filter
//
//=================================================================
//=================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 1999-03-01
// Description: This program acts as a filter between GDB and the test
// running on the target, allowing testing of the serial
// driver without confusing GDB.
// Usage: Run the program with one argument, the serial port
// on with the target is connected.
// Run serial test in GDB, connecting to the target with
// 'target remote localhost:5678'.
//
// To Do:
// o Add timeout setup and handling for recovery, can rely on testing
// agent to control global timeout.
// o Saving chunks that caused transfer failure?
// - In SEND with echo, do CRC on 32-byte sub-packets
// o Additional To Do items under each sub-protocol function.
// o Option to get all serial IO written (in hex, > and < prepends
// input/output lines) to a file.
// o Clean up the mess in this file....
// o Make main() listen on two ports - use one for ser filter, the other for
// null filter connections.
// o Maybe use environment variable to find X10 reset command.
//####DESCRIPTIONEND####
#include "eCosTestSerialFilter.h"
#include "eCosTestDownloadFilter.h"
#include "eCosTestMonitorFilter.h"
#include "eCosTestUtils.h"
#include "eCosThreadUtils.h"
#include "eCosTrace.h"
bool opt_ser_debug = false;
bool opt_null_filter = false;
bool opt_console_output = false;
bool opt_X10_reset = false;
bool opt_filter_trace = false;
char opt_X10_port[2];
bool opt_monitor = false;
void
no_gdb(const char* pszPort, int nBaud,
CeCosSocket::FilterFunc *pSerialToSocketFilterFunc,
void *pParam, bool *pbStop)
{
fprintf(stderr, "no_gdb, listening on %s\n",pszPort);
CeCosSocket dummy_socket;
CeCosSerial serial;
serial.SetBlockingReads(false);
bool rc=false;
// Open serial device.
if (!serial.Open(pszPort,nBaud)){
ERROR("Couldn't open port %s\n",pszPort);
} else {
// Flush the serial buffer.
serial.Flush();
serial.ClearError();
enum {BUFSIZE=8192};
void *pBuf=malloc(BUFSIZE);
rc=true;
while(rc && (0==pbStop || !(*pbStop))){
unsigned int nRead=0;
for(;;) {
if(serial.Read(pBuf,BUFSIZE,nRead)){
if(nRead>0){
break;
}
CeCosThreadUtils::Sleep(1);
} else {
fprintf(stderr, "Serial read failed (%d)\n", errno);
}
}
if(pSerialToSocketFilterFunc){
rc=pSerialToSocketFilterFunc(pBuf,nRead,serial,dummy_socket,
pParam);
}
}
free(pBuf);
}
}
int
main(int argc, char** argv)
{
int nSock = 0;
int baud_rate, nTcpPort;
bool opt_no_gdb = false;
char* ser_port;
int i=1;
if(!CeCosTestUtils::CommandLine(argc, argv, false)){
goto Usage;
}
while(i<argc){
if(argv[i][0]=='-'){
switch(argv[i][1]){
case 't':
// redundant - -v does this
CeCosTrace ::EnableTracing(CeCosTrace::TRACE_LEVEL_TRACE);
break;
case 'f':
opt_filter_trace = true;
break;
case 'S':
opt_ser_debug = true;
break;
case 'm':
opt_monitor = true;
break;
case 'n':
opt_no_gdb = true;
// fall through! Output on console when no GDB.
case 'c':
opt_console_output = true;
break;
case '0':
opt_null_filter = true;
break;
case 'X':
// X-10 port to reset when connection drops
opt_X10_reset = true;
opt_X10_port[0] = argv[i][2];
opt_X10_port[1] = argv[i][3];
break;
default:
fprintf(stderr,"Unrecognized switch %s\n",argv[i]);
goto Usage;
break;
}
for(int j=i;j<argc;j++){
argv[j]=argv[j+1];
}
argc--;
argv[argc]=0;
} else {
i++;
}
}
if(!((3==argc && opt_no_gdb) || (4==argc && !opt_no_gdb)))
{
goto Usage;
}
if (opt_no_gdb) {
ser_port = argv[1];
baud_rate=atoi(argv[2]);
} else {
nTcpPort=atoi(argv[1]);
if(0==nTcpPort){
fprintf(stderr,"Invalid port %s\n",argv[1]);
return main(0,argv); // Provoke usage message
}
ser_port = argv[2];
baud_rate=atoi(argv[3]);
nSock = CeCosSocket::Listen(nTcpPort);
if (-1 == nSock) {
fprintf(stderr, "Couldn't access socket.\n");
throw "listen failed";
}
}
if (opt_monitor) {
fprintf(stdout, "Monitor mode - will not interact with data streams...\n");
for(;;) {
CeCosTestMonitorFilter* host_filter =
new CeCosTestMonitorFilter();
CeCosTestMonitorFilter* target_filter =
new CeCosTestMonitorFilter();
// Set filter directions
host_filter->SetOrigin(CeCosTestMonitorFilter::MF_HOST);
target_filter->SetOrigin(CeCosTestMonitorFilter::MF_TARGET);
// Enable filters
host_filter->SetVerbose(true);
target_filter->SetVerbose(true);
// Set filter functions
CeCosSocket::FilterFunc *host_filter_function =
&SerialMonitorFunction;
CeCosSocket::FilterFunc *target_filter_function =
&SerialMonitorFunction;
try {
CeCosSocket::ConnectSocketToSerial(nSock, ser_port,
baud_rate,
target_filter_function,
(void*)target_filter,
host_filter_function,
(void*)host_filter,
NULL);
}
catch (const char* p) {
fprintf(stderr, "Caught filter crash: %s\n", p);
}
delete target_filter;
delete host_filter;
}
}
for(;;) {
CeCosTestSerialFilter* serial_filter =
new CeCosTestSerialFilter();
CeCosTestDownloadFilter* download_filter =
new CeCosTestDownloadFilter();
// Set filter configuration
serial_filter->SetFilterTrace(opt_filter_trace);
serial_filter->SetSerialDebug(opt_ser_debug);
serial_filter->SetConsoleOutput(opt_console_output);
// Set download filter configuration
download_filter->SetFilterTrace(opt_filter_trace);
download_filter->SetSerialDebug(opt_ser_debug);
// Set serial side filter
CeCosSocket::FilterFunc *ser_filter_function =
&SerialFilterFunction;
if (opt_null_filter)
ser_filter_function = NULL;
// Set socket side filter
CeCosSocket::FilterFunc *sock_filter_function =
&DownloadFilterFunction;
try {
if (opt_no_gdb)
no_gdb(ser_port, baud_rate, ser_filter_function,
(void*)serial_filter, NULL);
else
CeCosSocket::ConnectSocketToSerial(nSock, ser_port,
baud_rate,
ser_filter_function,
(void*)serial_filter,
sock_filter_function,
(void*)download_filter,
NULL);
}
catch (const char* p) {
fprintf(stderr, "Caught filter crash: %s\n", p);
}
if (opt_X10_reset) {
char X10_cmd[80];
sprintf(X10_cmd, "/usr/unsupported/bin/x10cli x10 5000 %c %c",
opt_X10_port[0], opt_X10_port[1]);
system(X10_cmd);
}
delete serial_filter;
delete download_filter;
}
// return 0;
Usage:
const char *pszMe="ser_filter";
fprintf(stderr,"Usage: %s [-c -S -0 -Xab] TcpIPport SerialPort BaudRate\n"
" or: %s -n [-c -S -0 -Xab] SerialPort BaudRate\n"
" Switches:\n"
" -f: Enable filter output tracing.\n"
" -S: Output data read from serial line.\n"
" -c: Output data on console instead of via GDB.\n"
" -m: Work only as a monitor filter. Implies -c.\n"
" -n: No GDB.\n"
" -0: Use null filter.\n"
" -Xab: Reset X-10 Port 'a b' when TCP connection breaks\n",pszMe,pszMe);
CeCosTestUtils::UsageMessage();
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -