第三方工程、库为release版本
开放给我们的是dll源码,并且是release版本
直接将dll工程改为debug,编译肯定是过不去的
曲线救国,debug信息经由一个文本文件输出
实现dll的调试
#include "SerialAnalyzer.h"
#include "SerialAnalyzerSettings.h"
#include <AnalyzerChannelData.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
SerialAnalyzer::SerialAnalyzer()
: Analyzer2(),
mSettings( new SerialAnalyzerSettings() ),
mSimulationInitilized( false )
{
SetAnalyzerSettings( mSettings.get() );
}
SerialAnalyzer::~SerialAnalyzer()
{
KillThread();
}
void SerialAnalyzer::ComputeSampleOffsets()
{
ClockGenerator clock_generator;
clock_generator.Init( mSettings->mBitRate, mSampleRateHz );
mSampleOffsets.clear();
U32 num_bits = mSettings->mBitsPerTransfer;
if( mSettings->mSerialMode != SerialAnalyzerEnums::Normal )
num_bits++;
mSampleOffsets.push_back( clock_generator.AdvanceByHalfPeriod( 1.5 ) ); //point to the center of the 1st bit (past the start bit)
num_bits--; //we just added the first bit.
for( U32 i=0; i<num_bits; i++ )
{
mSampleOffsets.push_back( clock_generator.AdvanceByHalfPeriod() );
}
if( mSettings->mParity != AnalyzerEnums::None )
mParityBitOffset = clock_generator.AdvanceByHalfPeriod();
//to check for framing errors, we also want to check
//1/2 bit after the beginning of the stop bit
mStartOfStopBitOffset = clock_generator.AdvanceByHalfPeriod( 1.0 ); //i.e. moving from the center of the last data bit (where we left off) to 1/2 period into the stop bit
//and 1/2 bit before end of the stop bit period
mEndOfStopBitOffset = clock_generator.AdvanceByHalfPeriod( mSettings->mStopBits - 1.0 ); //if stopbits == 1.0, this will be 0
}
void SerialAnalyzer::SetupResults()
{
//Unlike the worker thread, this function is called from the GUI thread
//we need to reset the Results object here because it is exposed for direct access by the GUI, and it can't be deleted from the WorkerThread
mResults.reset( new SerialAnalyzerResults( this, mSettings.get() ) );
SetAnalyzerResults( mResults.get() );
mResults->AddChannelBubblesWillAppearOn( mSettings->mInputChannel );
}
FILE *pFile;
void debug_out_to_file_init()
{
pFile = fopen("runlog.txt","w+");
//参数1文件路径,只写文件则在本工程中,参数2:打开模式
}
void debug_out_to_file(const char *str)
{
fwrite(str,1,strlen(str),pFile);
//写文件
fflush(pFile);
}
void debug_out_to_file_exit()
{
fclose(pFile);
//关闭文件
}
static int Ser_WrStr(const char* buff)
{
int retval = 0;
debug_out_to_file(buff);
return retval;
}
int g_printf_switch = 0x01;
int Ser_Printf (const char *format, ...)
{
unsigned char buffer[80 + 1];
va_list vArgs;
if( g_printf_switch == 0x00 ){
return 1;
}
va_start(vArgs, format);
vsnprintf((char *)buffer, sizeof(buffer), (char const *)format, vArgs);
va_end(vArgs);
Ser_WrStr(( const char *) buffer);
return 0;
}
#define Ser_Printf Ser_Printf
#define macdbg_prser Ser_Printf
int macdbg_dmphex(const char* buff, int len)
{
int retval = 0;
int x, y, tot, lineoff;
const char* curr;
//Ser_Printf("buff %x.\r\n", buff );
Ser_Printf("\r\n" );
lineoff = 0;
curr = buff;
tot = 0;
for( x = 0; x+16 < len; ){
Ser_Printf("%x\t", lineoff);
for( y = 0; y < 16; y++ ){
macdbg_prser("%02x ", (unsigned char)*(curr + y));
}
macdbg_prser(" ");
for( y = 0; y < 16; y++ ){
char c;
c = *(curr + y);
if( c > 31 && c < 127 ){
macdbg_prser("%c", c);
}else{
macdbg_prser("%c", '.');
}
tot++;
}
curr += 16;
x += 16;
lineoff+=16;
macdbg_prser("\r\n");
}
//do last line
//Ser_Printf("tot %d.\r\n", tot );
//Ser_Printf("len %d.\r\n", len );
if( tot < len ){
curr = (buff + tot);
macdbg_prser("%x\t", lineoff);
for( y = 0; y < (len - tot); y++ ){
macdbg_prser("%02x ", (unsigned char)*(curr + y));
}
//padding with spaces
//Ser_Printf("(len - tot) %d.\r\n", (len - tot) );
if( (len - tot) < 16 ){
for( y = 0; y < (32 - ((len - tot)*2)); y++ ){
macdbg_prser(" ");
}
}
for( y = 0; y < 16-(len - tot); y++ ){
macdbg_prser(" ");
}
macdbg_prser(" ");
//Ser_Printf("(len - tot) %d.\r\n", (len - tot) );
for( y = 0; y < (len - tot); y++ ){
char c;
c = *(curr + y);
if( c >31 && c < 127 ){
macdbg_prser("%c", c);
}else{
macdbg_prser("%c", '.');
//macdbg_prser("%c", c);
}
}
}
macdbg_prser("\r\n");
return retval;
}
void SerialAnalyzer::WorkerThread()
{
debug_out_to_file_init();
Ser_Printf("stamp.0\n");
mSampleRateHz = GetSampleRate();
//得到采样率
Ser_Printf("mSampleRateHz = %d.\n", mSampleRateHz);
ComputeSampleOffsets();
U32 num_bits = mSettings->mBitsPerTransfer;
Ser_Printf("num_bits = %d.\n", num_bits);
Ser_Printf("stamp.1\n");
if( mSettings->mSerialMode != SerialAnalyzerEnums::Normal ){
num_bits++;
}
if( mSettings->mInverted == false )
{
mBitHigh = BIT_HIGH;
mBitLow = BIT_LOW;
}else
{
mBitHigh = BIT_LOW;
mBitLow = BIT_HIGH;
}
U64 bit_mask = 0;
U64 mask = 0x1ULL;
for( U32 i=0; i<num_bits; i++ )
{
bit_mask |= mask;
mask <<= 1;
}
Ser_Printf("bit_mask = %x.\n", bit_mask);
Ser_Printf("mask = %x.\n", mask);
mSerial = GetAnalyzerChannelData( mSettings->mInputChannel );
mSerial->TrackMinimumPulseWidth();
if( mSerial->GetBitState() == mBitLow )
mSerial->AdvanceToNextEdge();
for( ; ; )
{
//we're starting high. (we'll assume that we're not in the middle of a byte.
mSerial->AdvanceToNextEdge();
//we're now at the beginning of the start bit. We can start collecting the data.
U64 frame_starting_sample = mSerial->GetSampleNumber();
//Ser_Printf("frame_starting_sample = %d.\n", frame_starting_sample);
U64 data = 0;
bool parity_error = false;
bool framing_error = false;
bool mp_is_address = false;
DataBuilder data_builder;
data_builder.Reset( &data, mSettings->mShiftOrder, num_bits );
U64 marker_location = frame_starting_sample;
for( U32 i=0; i<num_bits; i++ ){
mSerial->Advance( mSampleOffsets[i] );
data_builder.AddBit( mSerial->GetBitState() );
marker_location += mSampleOffsets[i];
mResults->AddMarker( marker_location, AnalyzerResults::Dot, mSettings->mInputChannel );
}
if( mSettings->mInverted == true ){
data = (~data) & bit_mask;
}
//数据在此已经解析出来了,保存在data变量中
Ser_Printf("parse data = 0x%x.\n", data);
if( mSettings->mSerialMode != SerialAnalyzerEnums::Normal )
{
//extract the MSB
U64 msb = data >> (num_bits - 1);
msb &= 0x1;
if( mSettings->mSerialMode == SerialAnalyzerEnums::MpModeMsbOneMeansAddress )
{
if( msb == 0x0 )
mp_is_address = false;
else
mp_is_address = true;
}
if( mSettings->mSerialMode == SerialAnalyzerEnums::MpModeMsbZeroMeansAddress )
{
if( msb == 0x0 )
mp_is_address = true;
else
mp_is_address = false;
}
//now remove the msb.
data &= ( bit_mask >> 1 );
}
parity_error = false;
if( mSettings->mParity != AnalyzerEnums::None )
{
mSerial->Advance( mParityBitOffset );
bool is_even = AnalyzerHelpers::IsEven( AnalyzerHelpers::GetOnesCount( data ) );
if( mSettings->mParity == AnalyzerEnums::Even )
{
if( is_even == true )
{
if( mSerial->GetBitState() != mBitLow ) //we expect a low bit, to keep the parity even.
parity_error = true;
}else
{
if( mSerial->GetBitState() != mBitHigh ) //we expect a high bit, to force parity even.
parity_error = true;
}
}else //if( mSettings->mParity == AnalyzerEnums::Odd )
{
if( is_even == false )
{
if( mSerial->GetBitState() != mBitLow ) //we expect a low bit, to keep the parity odd.
parity_error = true;
}else
{
if( mSerial->GetBitState() != mBitHigh ) //we expect a high bit, to force parity odd.
parity_error = true;
}
}
marker_location += mParityBitOffset;
mResults->AddMarker( marker_location, AnalyzerResults::Square, mSettings->mInputChannel );
}
//now we must dermine if there is a framing error.
framing_error = false;
mSerial->Advance( mStartOfStopBitOffset );
if( mSerial->GetBitState() != mBitHigh )
{
framing_error = true;
}else
{
U32 num_edges = mSerial->Advance( mEndOfStopBitOffset );
if( num_edges != 0 )
framing_error = true;
}
if( framing_error == true )
{
marker_location += mStartOfStopBitOffset;
mResults->AddMarker( marker_location, AnalyzerResults::ErrorX, mSettings->mInputChannel );
if( mEndOfStopBitOffset != 0 )
{
marker_location += mEndOfStopBitOffset;
mResults->AddMarker( marker_location, AnalyzerResults::ErrorX, mSettings->mInputChannel );
}
}
//ok now record the value!
//note that we're not using the mData2 or mType fields for anything, so we won't bother to set them.
Frame frame;
frame.mStartingSampleInclusive = frame_starting_sample;
frame.mEndingSampleInclusive = mSerial->GetSampleNumber();
frame.mData1 = data;
frame.mFlags = 0;
if( parity_error == true )
frame.mFlags |= PARITY_ERROR_FLAG | DISPLAY_AS_ERROR_FLAG;
if( framing_error == true )
frame.mFlags |= FRAMING_ERROR_FLAG | DISPLAY_AS_ERROR_FLAG;
if( mp_is_address == true )
frame.mFlags |= MP_MODE_ADDRESS_FLAG;
if( mp_is_address == true )
mResults->CommitPacketAndStartNewPacket();
mResults->AddFrame( frame );
mResults->CommitResults();
ReportProgress( frame.mEndingSampleInclusive );
CheckIfThreadShouldExit();
if( framing_error == true ) //if we're still low, let's fix that for the next round.
{
if( mSerial->GetBitState() == mBitLow )
mSerial->AdvanceToNextEdge();
}
}
debug_out_to_file_exit();
}
bool SerialAnalyzer::NeedsRerun()
{
AnalyzerHelpers::Assert( "Alg problem debug, shortest_pulse was 0" );
if( mSettings->mUseAutobaud == false )
return false;
//ok, lets see if we should change the bit rate, base on mShortestActivePulse
U64 shortest_pulse = mSerial->GetMinimumPulseWidthSoFar();
if( shortest_pulse == 0 )
AnalyzerHelpers::Assert( "Alg problem, shortest_pulse was 0" );
U32 computed_bit_rate = U32( double( mSampleRateHz ) / double( shortest_pulse ) );
if( computed_bit_rate > mSampleRateHz )
AnalyzerHelpers::Assert( "Alg problem, computed_bit_rate is higer than sample rate" ); //just checking the obvious...
if( computed_bit_rate > (mSampleRateHz / 4) )
return false; //the baud rate is too fast.
if( computed_bit_rate == 0 )
{
//bad result, this is not good data, don't bother to re-run.
return false;
}
U32 specified_bit_rate = mSettings->mBitRate;
double error = double( AnalyzerHelpers::Diff32( computed_bit_rate, specified_bit_rate ) ) / double( specified_bit_rate );
if( error > 0.1 )
{
mSettings->mBitRate = computed_bit_rate;
mSettings->UpdateInterfacesFromSettings();
return true;
}else
{
return false;
}
}
U32 SerialAnalyzer::GenerateSimulationData( U64 minimum_sample_index, U32 device_sample_rate, SimulationChannelDescriptor** simulation_channels )
{
if( mSimulationInitilized == false )
{
mSimulationDataGenerator.Initialize( GetSimulationSampleRate(), mSettings.get() );
mSimulationInitilized = true;
}
return mSimulationDataGenerator.GenerateSimulationData( minimum_sample_index, device_sample_rate, simulation_channels );
}
U32 SerialAnalyzer::GetMinimumSampleRateHz()
{
return mSettings->mBitRate * 4;
}
const char* SerialAnalyzer::GetAnalyzerName() const
{
//return "UART/RS232/485";
return "test1";
}
const char* GetAnalyzerName()
{
//return "UART/RS232/485";
AnalyzerHelpers::Assert( "Alg problem debug123, shortest_pulse was 0" );
return "test1";
}
Analyzer* CreateAnalyzer()
{
return new SerialAnalyzer();
}
void DestroyAnalyzer( Analyzer* analyzer )
{
delete analyzer;
}