Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
668d1d5255 | |||
ae5ca0c45b | |||
b00099973f | |||
5bf5cb9a67 | |||
f6848f0503 |
2
.ci
2
.ci
Submodule .ci updated: 93062ba941...dead44c3cb
@ -385,35 +385,45 @@ See the <a href="protocol.html">next chapter</a> for protocol files in depth.
|
|||||||
Generation of debug and error messages is controlled with two shell variables,
|
Generation of debug and error messages is controlled with two shell variables,
|
||||||
<code>streamDebug</code> and <code>streamError</code>.
|
<code>streamDebug</code> and <code>streamError</code>.
|
||||||
Setting those variables to 1 (actually to any number but 0) enables the
|
Setting those variables to 1 (actually to any number but 0) enables the
|
||||||
messages.
|
messages. A few noisy and rarely useful debug messages are only enabled when
|
||||||
|
setting <code>streamDebug</code> to 2.
|
||||||
Per default debug messages are switched off and error messages are switched on.
|
Per default debug messages are switched off and error messages are switched on.
|
||||||
Errors occuring while loading protocol files are always shown.
|
Errors occuring while loading protocol files are always shown.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Warning: Enabling debug messages can create a lot of output!
|
Warning: Enabling debug messages this way can create a lot of output!
|
||||||
At the moment, there is no way to set filters on debug or error messages.
|
Therefore, some limited debugging can be enabled per record, independent of
|
||||||
|
the <code>streamDebug</code> variable using the <code>.TPRO</code> field of
|
||||||
|
the record. Currently, setting <code>.TPRO</code> to 1 or 2 enables some
|
||||||
|
basic information about the processing of a record and its i/o.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Debug output can be redirected to a file with the command
|
Debug output can be redirected to a file with the command
|
||||||
<code>streamSetLogfile("<var>filename</var>")</code>.
|
<code>streamSetLogfile("<var>filename</var>")</code>.
|
||||||
When called without a filename, debug output is directed back
|
If the file already exists, it will be overwritten, not appended to.
|
||||||
to the console.
|
While debug messages are only written to the defined log file, error messages
|
||||||
|
are still printed to <var>stderr</var> too.
|
||||||
|
Calling <code>streamSetLogfile</code> without a filename directs debug output
|
||||||
|
back to <var>stderr</var> and closes the log file.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
By default the debug/error output is set to be colored if the terminal allows
|
By default, error messages to the console are printed in red color if
|
||||||
it but this can be set to always colored or never colored by setting
|
<var>stderr</var> is a tty at startup time, using ANSI color codes. Some
|
||||||
<code>streamDebugColored</code> to 1 or 0 respectively.
|
terminals may not support this properly.
|
||||||
|
The variable <code>streamDebugColored</code> can be set to 0 or 1 to
|
||||||
|
disable or enable colored error messages explicitly.
|
||||||
|
Error messages written to a log file do not use colors.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Error and debug messages are prefixed with a time stamp unless the variable
|
Error and debug messages are prefixed with a time stamp unless the variable
|
||||||
<code>streamMsgTimeStamped</code> is set to 0.
|
<code>streamMsgTimeStamped</code> is set to 0.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
When a device is disconnected StreamDevice can produce many repeated timeout
|
when a device is unresponsive, StreamDevice may produce many repeated timeout
|
||||||
messages. To reduce this logging you can set <code>streamErrorDeadTime</code>
|
messages. To reduce this, you can set <code>streamErrorDeadTime</code>
|
||||||
to an integer number of seconds. When this is set repeated timeout messages
|
to an integer number of seconds. In this case, repeated timeout messages
|
||||||
will not be printed in the specified dead time after the last message. The
|
will not be printed during the specified dead time after the last printed
|
||||||
default dead time is 0, resulting in every message being printed.
|
message. The default dead time is 0, resulting in every message being printed.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>Example (vxWorks):</h3>
|
<h3>Example (vxWorks):</h3>
|
||||||
|
@ -603,6 +603,7 @@ evalOut()
|
|||||||
// flush all unread input
|
// flush all unread input
|
||||||
unparsedInput = false;
|
unparsedInput = false;
|
||||||
inputBuffer.clear();
|
inputBuffer.clear();
|
||||||
|
inputLine.clear();
|
||||||
if (!formatOutput())
|
if (!formatOutput())
|
||||||
{
|
{
|
||||||
finishProtocol(FormatError);
|
finishProtocol(FormatError);
|
||||||
@ -1011,6 +1012,7 @@ readCallback(StreamIoStatus status,
|
|||||||
finishProtocol(Fault);
|
finishProtocol(Fault);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
inputHook(input, size);
|
||||||
inputBuffer.append(input, size);
|
inputBuffer.append(input, size);
|
||||||
debug("StreamCore::readCallback(%s) inputBuffer=\"%s\", size %" Z "u\n",
|
debug("StreamCore::readCallback(%s) inputBuffer=\"%s\", size %" Z "u\n",
|
||||||
name(), inputBuffer.expand()(), inputBuffer.length());
|
name(), inputBuffer.expand()(), inputBuffer.length());
|
||||||
|
@ -219,6 +219,7 @@ protected:
|
|||||||
|
|
||||||
// virtual methods
|
// virtual methods
|
||||||
virtual void protocolStartHook() {}
|
virtual void protocolStartHook() {}
|
||||||
|
virtual void inputHook(const void* input, size_t size) {};
|
||||||
virtual void protocolFinishHook(ProtocolResult) {}
|
virtual void protocolFinishHook(ProtocolResult) {}
|
||||||
virtual void startTimer(unsigned long timeout) = 0;
|
virtual void startTimer(unsigned long timeout) = 0;
|
||||||
virtual bool formatValue(const StreamFormat&, const void* fieldaddress) = 0;
|
virtual bool formatValue(const StreamFormat&, const void* fieldaddress) = 0;
|
||||||
|
@ -137,6 +137,7 @@ class Stream : protected StreamCore
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// StreamCore methods
|
// StreamCore methods
|
||||||
|
void inputHook(const void* input, size_t size);
|
||||||
void protocolFinishHook(ProtocolResult);
|
void protocolFinishHook(ProtocolResult);
|
||||||
void startTimer(unsigned long timeout);
|
void startTimer(unsigned long timeout);
|
||||||
bool getFieldAddress(const char* fieldname,
|
bool getFieldAddress(const char* fieldname,
|
||||||
@ -934,6 +935,10 @@ process()
|
|||||||
debug("Stream::process(%s) start\n", name());
|
debug("Stream::process(%s) start\n", name());
|
||||||
status = NO_ALARM;
|
status = NO_ALARM;
|
||||||
convert = OK;
|
convert = OK;
|
||||||
|
if (record->tpro)
|
||||||
|
{
|
||||||
|
StreamDebugClass(record->name).print("start protocol '%s'\n", protocolname());
|
||||||
|
}
|
||||||
if (!startProtocol(record->proc == 2 ? StreamCore::StartInit : StreamCore::StartNormal))
|
if (!startProtocol(record->proc == 2 ? StreamCore::StartInit : StreamCore::StartNormal))
|
||||||
{
|
{
|
||||||
debug("Stream::process(%s): could not start %sprotocol, status=%s (%d)\n",
|
debug("Stream::process(%s): could not start %sprotocol, status=%s (%d)\n",
|
||||||
@ -1028,11 +1033,26 @@ expire(const epicsTime&)
|
|||||||
|
|
||||||
// StreamCore virtual methods ////////////////////////////////////////////
|
// StreamCore virtual methods ////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Stream::
|
||||||
|
inputHook(const void* input, size_t size)
|
||||||
|
{
|
||||||
|
if (record->tpro > 1)
|
||||||
|
{
|
||||||
|
StreamDebugClass(record->name).print("received \"%s\"\n",
|
||||||
|
StreamBuffer(input, size).expand()());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Stream::
|
void Stream::
|
||||||
protocolFinishHook(ProtocolResult result)
|
protocolFinishHook(ProtocolResult result)
|
||||||
{
|
{
|
||||||
debug("Stream::protocolFinishHook(%s, %s)\n",
|
debug("Stream::protocolFinishHook(%s, %s)\n",
|
||||||
name(), toStr(result));
|
name(), toStr(result));
|
||||||
|
if (record->tpro)
|
||||||
|
{
|
||||||
|
StreamDebugClass(record->name).print("%s. out=\"%s\", in=\"%s\"\n",
|
||||||
|
toStr(result), outputLine.expand()(), inputLine.expand()());
|
||||||
|
}
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case Success:
|
case Success:
|
||||||
|
@ -171,8 +171,6 @@ print(const char* fmt, ...)
|
|||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
const char* f = strrchr(file, '/');
|
|
||||||
if (f) f++; else f = file;
|
|
||||||
FILE* fp = StreamDebugFile ? StreamDebugFile : stderr;
|
FILE* fp = StreamDebugFile ? StreamDebugFile : stderr;
|
||||||
if (streamMsgTimeStamped)
|
if (streamMsgTimeStamped)
|
||||||
{
|
{
|
||||||
@ -184,7 +182,13 @@ print(const char* fmt, ...)
|
|||||||
{
|
{
|
||||||
fprintf(fp, "%s ", StreamGetThreadNameFunction());
|
fprintf(fp, "%s ", StreamGetThreadNameFunction());
|
||||||
}
|
}
|
||||||
fprintf(fp, "%s:%d: ", f, line);
|
if (file) {
|
||||||
|
const char* f = strrchr(file, '/');
|
||||||
|
if (f) f++; else f = file;
|
||||||
|
fprintf(fp, "%s:", f);
|
||||||
|
if (line) fprintf(fp, "%d:", line);
|
||||||
|
fprintf(fp, " ");
|
||||||
|
}
|
||||||
vfprintf(fp, fmt, args);
|
vfprintf(fp, fmt, args);
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
@ -56,19 +56,15 @@ class StreamDebugClass
|
|||||||
const char* file;
|
const char* file;
|
||||||
int line;
|
int line;
|
||||||
public:
|
public:
|
||||||
StreamDebugClass(const char* file, int line) :
|
StreamDebugClass(const char* file = NULL, int line = 0) :
|
||||||
file(file), line(line) {}
|
file(file), line(line) {}
|
||||||
int print(const char* fmt, ...)
|
int print(const char* fmt, ...)
|
||||||
__attribute__((__format__(__printf__,2,3)));
|
__attribute__((__format__(__printf__,2,3)));
|
||||||
};
|
};
|
||||||
|
|
||||||
inline StreamDebugClass
|
|
||||||
StreamDebugObject(const char* file, int line)
|
|
||||||
{ return StreamDebugClass(file, line); }
|
|
||||||
|
|
||||||
#define error StreamError
|
#define error StreamError
|
||||||
#define debug (!streamDebug)?0:StreamDebugObject(__FILE__,__LINE__).print
|
#define debug (!streamDebug)?0:StreamDebugClass(__FILE__,__LINE__).print
|
||||||
#define debug2 (streamDebug<2)?0:StreamDebugObject(__FILE__,__LINE__).print
|
#define debug2 (streamDebug<2)?0:StreamDebugClass(__FILE__,__LINE__).print
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ANSI escape sequences for terminal output
|
* ANSI escape sequences for terminal output
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
# along with StreamDevice. If not, see https://www.gnu.org/licenses/.
|
# along with StreamDevice. If not, see https://www.gnu.org/licenses/.
|
||||||
#########################################################################/
|
#########################################################################/
|
||||||
|
|
||||||
terminator = CR LF;
|
terminator = LF;
|
||||||
|
|
||||||
cmd {
|
cmd {
|
||||||
out "%s";
|
out "%s";
|
||||||
|
Reference in New Issue
Block a user