UDS协议栈的开发和测试对于刚刚接触UDS协议的开发人员来说,不但需要阅读大量的标准文档,短时间内很难理解透彻,标准协议栈代码的编写更加困难,刚入门又没有快捷简单的测试工具帮助加快理解和验证,使得UDS诊断开发对于一般的初创公司或者小型企业来说,是一个比较难跨越的门槛。一般的企业通过购买专业的软件工具和专业的培训服务来获取UDS诊断开发和测试的技术。本文的目的是通过简单快捷的UDS上位机软件测试界面,有助于帮助开发者加快UDS协议栈的理解和开发测试,能够帮助开发者快速的掌握UDS开发和测试的一般过程和方法。
首先贴出网络层协议源码:
namespace Uds
{
public class uds_trans
{
public enum AddressingModes
{
Physical_Addressing,
Functional_Addressing,
}
private int id;
/// <summary>
/// UDS默认填充字节
/// </summary>
public byte fill_byte = 0x55;
public int tx_id;
public int rx_id;
public int test_id;
/*
** Frame types arranged in numericalorder for efficient switch statement
** jump tables.
*/
private enum FrameType
{
TX_SF = 0, /* Single Frame */
TX_FF = 1, /* First Frame */
TX_CF = 2, /* Consecutive Frame */
TX_FC = 3 /* Flow Control Frame */
};
/*
** Masks for the PCI(Protcol ControlInformation) byte.
** The MS bit contains the frame type.
** The LS bit is mapped differently,depending on frame type, as follows:
** SF: DL (number of diagnostic bytes NOT including the PCI byte; only the
** 3 LS bits are used).
** FF: XDL (extended data length; always be 0.)
** CF: Sequence number,4 bits, max value:15.
** FC: Flow Status. The value of FS shall be set to zero that means that
** the tester is ready to receive a maximum number of CF.
*/
private enum PCI /* Don't change thesevalues, these must be */
{
/* MS bits - Frame Type */
FRAME_TYPE_MASK = 0xF0,
SF_TPDU = 0x00, /* Single frame */
FF_TPDU = 0x10, /* First frame */
CF_TPDU = 0x20, /* Consecutive frame */
FC_TPDU = 0x30, /* Flow control frame */
FC_OVFL_PDU = 0x32, /* Flow control frame */
/* LS bits - SF_DL */
SF_DL_MAX_BYTES = 0x07, /* SF Max Data Length */
SF_DL_MASK = 0x07, /* number diagnostic data bytes */
SF_DL_MASK_LONG = 0x0F, /* change to check the 4 bits for testing,number diagnostic data bytes */
/* LS bits - FF_DL */
FF_EX_DL_MASK = 0x0F, /*Extended data length */
/* LS bits - CF_SN */
CF_SN_MASK = 0x0F, /* Sequence number mask */
CF_SN_MAX_VALUE = 0x0F, /* Max value of sequence number */
/* LS bits - FC Saatus */
FC_STATUS_CONTINUE = 0x00, /* Flow control frame, CONTINUE */
FC_STATUS_WAIT = 0x01, /* Flow control frame, WAIT */
FC_STATUS_OVERFLOW = 0x02, /* Flow control frame, OVERFLOW */
FC_STATUS_MASK = 0x0F,
};
private int N_As = 25;
private int N_Ar = 25;
private int N_Bs = 75;
private int N_Br;
private int N_Cr = 150;
private int N_Cs;
private int FC_BS_MAX_VALUE = 0;
private int FC_ST_MIN_VALUE = 5;
private int CF_SN_MAX_VALUE = 15;
private int SF_DL_MAX_BYTES = 7;
/*
** Time to wait for the tester to senda FC frame in response
** to a FF(wait for flow control frametime out).
** N_As + N_Bs = 25 +75 = 100ms
*/
private int FC_WAIT_TIMEOUT;//N_As +N_Bs + 50;
/*
** wait for Consecutive frame time out
** N_Cr < 150ms
*/
private int CF_WAIT_TIMEOUT;//N_Cr; //(N_Cr- 10))
private int RX_MAX_TP_BYTES = 0xFFF;
public uds_trans()
{
can_rx_info.frame = new byte[8];
can_tx_info.frame = new byte[8];
FC_WAIT_TIMEOUT = N_As + N_Bs + 50;/* N_As + N_Bs + 50 */
CF_WAIT_TIMEOUT = N_Cr; /* (N_Cr - 10)) */
}
private readonly intbeginning_seq_number = 1;
private readonly int TPCI_Byte = 0;
private readonly int DL_Byte = 1;
private readonly int BS_Byte = 1;
private readonly int STminByte = 2;
private class tx_info
{
public bool tx_rx_idle = false;
public bool tx_fc_tpdu = false;
public bool tx_last_frame_error = false;
public bool tx_wait_fc = false;
public bool tx_in_progress = false;
public int tx_block_size = 0; /* BS(Block Size) in a flow ControlFrame */
public int tx_stmin_time = 20;
public int tx_cf_stmin_wait_time =20; /* STmin Time in Flow Control Frame*/
public int tx_fc_wait_time =0; /* Wait for FC when has sentFF */
public int lenght;
public int offset;
public int next_seq_num;
public byte[] buffer;
public byte[] frame;
}
private class rx_info
{
public bool rx_in_progress = false;
public bool rx_msg_rcvd =false; /* if the message has neverbeen received to be used by application level software */
public bool tx_aborted = false;
public int rx_cf_wait_time = 0;
public boolrx_fc_wait_timeout_disable = false;
public bool rx_overflow = false;
public int lenght;
public int offset;
public int next_seq_num;
public byte[] buffer;
public byte[] frame;
}
private tx_info can_tx_info = newtx_info();
private rx_info can_rx_info = newrx_info();
#region Event
public class FarmsEventArgs : EventArgs
{
public int id = 0;
public int dlc = 0;
public byte[] dat = new byte[8];
public long time = 0;
public override string ToString()
{
time %= 1000000;
returnid.ToString("X3") + " "
+dlc.ToString("X1") + " "
+ dat.HexToStrings("") + " "
+ (time /1000).ToString() + "." + (time % 1000).ToString("d3");
}
}
public class RxMsgEventArgs : EventArgs
{
public int id = 0;
public byte[] dat;
public long time = 0;
public RxMsgEventArgs(int lenght)
{
dat = new byte[lenght];
}