基于UDS编写CANoe BootLoader刷写上位机的测试脚本(2)

针对诊断刷写的脚本,之前我讲到$27服务,27服务主要是种子的请求和密钥的计算,当仿真ECU经过逻辑判断,秘钥正确给出正响应,不正确给出负响应。以下是我之前文章的内容链接:

基于UDS编写的CANoe BootLoader刷写上位机测测试脚本

1、诊断的请求与响应实现

由于之前只给出了Tester和SimECU的节点代码,并没有对传输层代码进行介绍,本次对TP层代码进行介绍。在之前的测试用例当中,我应用了几个诊断服务,包括$10、$85、$28、$3E以及$27服务,分别对应的诊断函数为:DiagnosticSessionControl()、ControlDTCSetting()、CommunicationControl()、SecurityAccess()、TesterPresent()。下面是这几个函数的诊断代码:

variables
{
	
	
	/* Create a Service DiagnosticSessionControl       */
                                                                
	diagRequest  DiagnosticSessionControl_Process DiagnosticSessionControlReq;
	diagResponse DiagnosticSessionControl_Process DiagnosticSessionControlResp;
	
	/*  create a service for Security Access    */
                                                                     
	diagRequest  SecurityAccess_Process SecurityAccessReq;
	diagResponse SecurityAccess_Process SecurityAccessResp;

	/* create a service for communication control */
                                                                     
	diagRequest  CommunicationControl_Process CommunicationControlReq;
	diagResponse CommunicationControl_Process CommunicationControlResp;

	
	/* create a service for tester present     */                                                                        
	diagRequest  TesterPresent_Process TesterPresentReq;
	diagResponse TesterPresent_Process TesterPresentResp;

/* Create a service for control DTC Settings      */                                                                
	diagRequest  ControlDTCSetting_Process ControlDTCSettingReq;
	diagResponse ControlDTCSetting_Process ControlDTCSettingResp;

}

/*  FUNCTIONAL DIAGNOSTOCS CONTROL     */                                                                                                                                                                           
long DiagnosticSessionControl(long diagnosticSessionType, char isFunctional, char isPRSuppress, char isNoResponse)
{
	long LocalResponse;

	if(isPRSuppress)
	{
		diagnosticSessionType = diagnosticSessionType + PResponseSuppressed;//正响应抑制,在响应类型基础上加0x80
	}
	DiagSetParameter(DiagnosticSessionControlReq, "diagnosticSessionType", diagnosticSessionType);
	if (isFunctional)
	{
		diagSendFunctional(DiagnosticSessionControlReq);
	}
	else
	{
		DiagSendRequest(DiagnosticSessionControlReq); /* sending request                                                */
	}
	/* write the request object in the test report                                                                     */
	testReportWriteDiagObject(DiagnosticSessionControlReq);
	/* wait for the request is sent completely                                                                         */
	TestWaitForDiagRequestSent(DiagnosticSessionControlReq, TransferTime);
	/* Wait for the response to be arrived                                                                             */
	LocalResponse = testWaitForDiagResponse(DiagnosticSessionControlReq,1000);
	/* Case a response arrived (PR or NR)                                                                              */
	if (LocalResponse == ResponseArrived)
	{
		DiagnosticSessionControlReq.GetLastResponse(DiagnosticSessionControlResp);
		LocalResponse = diagIsPositiveResponse(DiagnosticSessionControlResp);
		/* write the response object in the test report                                                                 */
		testReportWriteDiagObject(DiagnosticSessionControlResp);
	}
	/* Case response not arrived and it was PR_Suppress                                                                */
	else if (isPRSuppress)
	{
		LocalResponse = PRSuppress;
		testCaseComment("Positive Response Suppressed as per Request");
	}
	/* Case expecting no response                                                                                      */
	else if (isNoResponse)
	{
		LocalResponse = NoResponse;
		testCaseComment("No Response arrived as expected per Request");
	}
	/* Case response not arrived (not expected)                                                                        */
	else
	{
		/*  Time out occurred or faulty error                                                                           */
		LocalResponse = ResponseError;
	}
	return LocalResponse;
}

/*  FUNCTIONAL CONTROL DTC SETTING      */                                                                              

long ControlDTCSetting (long dtcSettingType, char isFunctional, char isPRSuppress, char isNoResponse)
{
	long LocalResponse;
	byte LocalByte[1];

	if (isPRSuppress)
	{
		dtcSettingType = dtcSettingType + PResponseSuppressed;
	}
	DiagSetParameter(ControlDTCSettingReq, "dtcSettingType", dtcSettingType);
	diagSetParameterRaw(ControlDTCSettingReq, "dtcSettingControlOptionRecord", LocalByte, 0);
	if (isFunctional)
	{
		diagSendFunctional(ControlDTCSettingReq);
	}
	else
	{
		DiagSendRequest(ControlDTCSettingReq);
	}
	/* write the request object in the test report                                                                     */
	testReportWriteDiagObject(ControlDTCSettingReq);
	TestWaitForDiagRequestSent(ControlDTCSettingReq, TransferTime);
	LocalResponse = testWaitForDiagResponse(ControlDTCSettingReq,1000);
	if (LocalResponse == ResponseArrived)
	{
		ControlDTCSettingReq.GetLastResponse(ControlDTCSettingResp);
		LocalResponse = diagIsPositiveResponse(ControlDTCSettingResp);
		/* write the response object in the test report                                                                 */
		testReportWriteDiagObject(ControlDTCSettingResp);
	}
	else if (isPRSuppress)
	{
		LocalResponse = PRSuppress;
		testCaseComment("Positive Response Suppressed as per Request");
	}
	/* Case expecting no response                                                                                      */
	else if (isNoResponse)
	{
		LocalResponse = NoResponse;
		testCaseComment("No Response arrived as expected per Request");
	}
	else
	{
		/*  Time out occurred or faulty error                                                                           */
		LocalResponse = ResponseError;
	}

	return LocalResponse;
}

/*  FUNCTIONAL COMMUNICATION CONTROL         */                                                                         

long CommunicationControl (
    long controlType, long communicationType, char isFunctional, char isPRSuppress, char isNoResponse)
{
	long LocalResponse;

	if (isPRSuppress)
	{
		controlType = controlType + PResponseSuppressed;
	}
	diagSetParameter(CommunicationControlReq, "controlType", controlType);
	diagSetParameter(CommunicationControlReq, "communicationType", communicationType);
	if (isFunctional)
	{
		diagSendFunctional(CommunicationControlReq);
	}
	else
	{
		diagSendRequest(CommunicationControlReq);
	}
	testReportWriteDiagObject(CommunicationControlReq);
	TestWaitForDiagRequestSent(CommunicationControlReq, TransferTime);
	LocalResponse = testWaitForDiagResponse(CommunicationControlReq,1000);
	if (LocalResponse == ResponseArrived)
	{
		CommunicationControlReq.GetLastResponse(CommunicationControlResp);
		LocalResponse = diagIsPositiveResponse(CommunicationControlResp);
		testReportWriteDiagObject(CommunicationControlResp);
	}
	else if(isPRSuppress)
	{
		LocalResponse = PRSuppress;
		testCaseComment("Response Suppressed as per Request");
	}
	/* Case expecting no response                                                                                      */
	else if (isNoResponse)
	{
		LocalResponse = NoResponse;
		testCaseComment("No Response arrived as expected per Request");
	}
	else
	{
		/*  Time out occurred or faulty error                                                                           */
		LocalResponse = ResponseError;
	}

	return LocalResponse;
}	

/*  FUNCTIONAL SECURITY ACCESS   */                                                                                     
long SecurityAccess (long securityAccessType, char isFunctional, char isNoResponse)
{
	long LocalResponse;
	byte LocalSeed[4];
	byte LocalKey[4];
	char Stub[2] = "1";
	char stub2[1]="" ;
	int SeedSize = 4;
	int KeySize  = 4;
	dword KeyActualSize;
	int RepeatSeedRequest;
	int iteration;


	RepeatSeedRequest = 1;


	/*  Request Seed                                                                                                   */
	DiagSetParameter(SecurityAccessReq, "securityAccessType", securityAccessType);
	DiagSetParameterRaw(SecurityAccessReq, "data", LocalSeed, 0);

	/*Handling the delay mechanism "the NRC requiredTimeDelayNotExpired" with maximum blockage time 10 seconds         */
	for (iteration = 1; ( (iteration <= 6) && (RepeatSeedRequest == 1) ) ; iteration++)
	{
		RepeatSeedRequest = 0;
		if (isFunctional)
		{
			diagSendFunctional(SecurityAccessReq);
		}
		else
		{
			DiagSendRequest(SecurityAccessReq); /* sending request                                                          */
		}

		testReportWriteDiagObject(SecurityAccessReq);
		TestWaitForDiagRequestSent(SecurityAccessReq, TransferTime);
		LocalResponse = testWaitForDiagResponse(SecurityAccessReq,1000);
    write("LocalResponse is %d",LocalResponse);
		if (LocalResponse == ResponseArrived)
		{
			/*A response was received*/
			SecurityAccessReq.GetLastResponse(SecurityAccessResp);
			if(diagIsNegativeResponse(SecurityAccessResp) != 0)
			{
				/*Negative response was received*/
				NRC_Value  =  diagGetResponseCode(SecurityAccessResp);
				if  (NRC_Value  ==  requiredTimeDelayNotExpired)
				{
					testWaitForTimeout(TransferTime);
					RepeatSeedRequest = 1;
				}
				else
				{
					LocalResponse = ResponseError;
				}
			}
		}
		/* Case expecting no response                                                                                      */
		else if (isNoResponse)
		{
			LocalResponse = NoResponse;
			testCaseComment("No Response arrived as expected per Request");
		}
		else
		{
			/*  Time out occurred or faulty error                                                                           */
			LocalResponse = ResponseError;
		}
	}
	testReportWriteDiagObject(SecurityAccessResp);
	if (LocalResponse !=0)
	{
		/*  get the seed from response                                                                                  */
		diagGetParameterRaw(SecurityAccessResp, "securitySeed", LocalSeed,4);  //获取种子
    //write("the seed is 0x%2X,0x%2X,0x%2X,0x%2X",LocalSeed[0],LocalSeed[1],LocalSeed[2],LocalSeed[3]);
		/*  Calculate the key from Seed                                                                                 */
		diagGenerateKeyFromSeed(LocalSeed,SeedSize,securityAccessType,Stub,stub2,LocalKey,KeySize,KeyActualSize);//生成秘钥
    //write("the key is 0x%2X,0x%2X,0x%2X,0x%2X",LocalKey[0],LocalKey[1],LocalKey[2],LocalKey[3]);
		DiagSetParameter(SecurityAccessReq, "securityAccessType", (securityAccessType+1));
		diagSetParameterRaw(SecurityAccessReq, "data", LocalKey, KeySize);
		if (isFunctional)
		{
			diagSendFunctional(SecurityAccessReq);
		}
		else
		{
			DiagSendRequest(SecurityAccessReq); /* sending request                                                       */
		}
		testReportWriteDiagObject(SecurityAccessReq);
		TestWaitForDiagRequestSent(SecurityAccessReq, TransferTime);
		LocalResponse = testWaitForDiagResponse(SecurityAccessReq,1000);
		if (LocalResponse == ResponseArrived)
		{
			SecurityAccessReq.GetLastResponse(SecurityAccessResp);
			LocalResponse = diagIsPositiveResponse(SecurityAccessResp);
		}
		/* Case expecting no response                                                                                   */
		else if (isNoResponse)
		{
			LocalResponse = NoResponse;
			testCaseComment("No Response arrived as expected per Request");
		}
		else
		{
			/*  Time out occurred or faulty error                                                                        */
			LocalResponse = ResponseError;
		}
                                                         
	}
	return LocalResponse;
}

/*  FUNCTIONAL TESTER PRESENT    */                                                                                     

long TesterPresent (long zeroSubFunction, char isFunctional, char isPRSuppress, char isNoResponse)
{
	long LocalResponse;

	if (isPRSuppress)
	{
		zeroSubFunction = zeroSubFunction + PResponseSuppressed;
	}
	DiagSetParameter(TesterPresentReq, "zeroSubFunction", zeroSubFunction);
	if(isFunctional)
	{
		diagSendFunctional(TesterPresentReq);
	}
	else
	{
		DiagSendRequest(TesterPresentReq);
	}
	/* write the request object in the test report  */                                                                   
	testReportWriteDiagObject(TesterPresentReq);
	TestWaitForDiagRequestSent(TesterPresentReq, TransferTime);
	LocalResponse = testWaitForDiagResponse(TesterPresentReq,1000);
	if (LocalResponse == ResponseArrived)
	{
		TesterPresentReq.GetLastResponse(TesterPresentResp);
		LocalResponse = diagIsPositiveResponse(TesterPresentResp);
		/* write the response object in the test report      */                                                           
		testReportWriteDiagObject(TesterPresentResp);
	}
	else if (isPRSuppress)
	{
		LocalResponse = PRSuppress;
		testCaseComment("Response Suppressed as per Request");
	}
	/* Case expecting no response                                                                                      */
	else if (isNoResponse)
	{
		LocalResponse = NoResponse;
		testCaseComment("No Response arrived as expected per Request");
	}
	else
	{
		/*  Time out occurred or faulty error                                                                           */
		LocalResponse = ResponseError;
	}

	return LocalResponse;
}

2、TP层节点代码重塑

诊断功能函数写完以后,需要对TP层节点代码进行重写,以便在Write Window中能够看到相关数据及参数。代码如下:

_Diag_SendFunctional( BYTE data[])
{
  CanTpSetPadding (gHandleFunctional, gOverwritePaddingMode);
  // Send data on the functional TP connection created earlier
  CanTpSendData( gHandleFunctional, data, elcount( data));
  //write("_Diag_SendFunctional data[0]=%d", data[0]);
}
_Diag_DataRequest( BYTE data[], DWORD count, long furtherSegments)
{
  char someBytes[24];
  WORD pos, i, max;
  BYTE val;
  pos = 0;
  max = elcount( someBytes)/3;
  if( max < count)
    --max;
  else if( max > count)
    max = count;
  for( i = 0; i < max; ++i)
  {
    val = data[i] >> 4;
    someBytes[pos++] = val + (val > 9 ? 'A' - 10 : '0');
    val = data[i] & 0xF;
    someBytes[pos++] = val + (val > 9 ? 'A' - 10 : '0');
    someBytes[pos++] = ' ';
  }
  --pos; // points to the last space
  if( i < count)
  {
    someBytes[pos++] = '.';
    someBytes[pos++] = '.';
    someBytes[pos++] = '.';
  }
  someBytes[pos] = 0;

  gSentResponse = 1;
  
  if( gSendNextRequestFunctionally)
  {
    if( !gHandleFunctional)
      return; // Not configured, so make sure an error is reported!

    writeDbgLevel(1, "(CanTP) %s: Functional DataRequest %d byte: %s",
                  gECU, count, someBytes);
    CanTpSendData(gHandleFunctional, data, count);
    gSendNextRequestFunctionally = 0;
    return;
  }

  // Send physically
  writeDbgLevel(1, "(CanTP) %s: DataRequest %d byte: %s",
                gECU, count, someBytes);
  CanTpSendData( gCANFDConnectionUsed ? gHandleFD : gHandle, data, count);
  gCANFDConnectionUsed = 0;
}
_Diag_SetupChannelReq()
{
  // This callback function is only necessary in tester nodes!
  Diag_SetupChannelCon();
}

CanTp_SendCon( long handle, DWORD txCount)
{
  writeDbgLevel(1,"(CanTP) %s: CanTp_SendCon", gECU);
  Diag_DataCon( txCount);
}

CanTp_ErrorInd( long handle, long error) 
{
  char cErrorText[12][30] = {
    "(no error)"
  , "Timeout while waiting for CF" // 1
  , "Timeout while waiting for FC" // 2
  , "Wrong Sequence Number"        // 3
  , "TP_DLL busy"                  // 4
  , "Unexpected PDU"               // 5
  , "Timeout waiting for Tx-Ack"   // 6
  , "WFT Overrun"                  // 7
  , "Buffer overflow"              // 8
  , "Wrong parameter"              // 9
  , "Invalid FlowStatus received"  // 10
  , "Transfer abort requested"     // 11
  };

  if( error < elcount(cErrorText))
    writeDbgLevel( 1, "(CanTP) %s: CanTp_ErrorInd(%d): %s", gECU, error, cErrorText[error]);
  else
    writeDbgLevel( 1, "(CanTP) %s: CanTp_ErrorInd(%d): unknown error!", gECU, error);

  Diag_ErrorInd( error);
}

CanTp_ReceptionInd( long handle, BYTE data[])
{
  writeDbgLevel(1,"(CanTP) %s: CanTp_ReceptionInd", gECU);
  gLastRequestWasReceivedFunctionally = (handle == gHandleFunctional ? 1 : 0);
  gCANFDConnectionUsed = (handle == gHandleFD ? 1 : 0);
  gSentResponse = 0;
  /* callback function for the OBC_ECU.can file to handle Raw Frames */
  RecieveRawData(data, elcount( data), CanTpGetSenderAddress());
  Diag_DataInd( data, elcount( data), CanTpGetSenderAddress());
  if( !cIsTester && !gSentResponse)
  {
    SendNegResFormat( data[0]);
  }
}

CCI_SendNextRequestFunctionally()
{
  gSendNextRequestFunctionally = 1;
}

CCI_CloseConnections()
{
  CanTpCloseConnection( gHandle);
  gHandle = 0;
  CanTpCloseConnection( gHandleFD);
  gHandleFD = 0;
  CanTpCloseConnection( gHandleFunctional);  
  gHandleFunctional = 0;
}

CanTp_FirstFrameInd( long handle, DWORD length)
{
  writeDbgLevel(1,"(CanTP) %s: CanTp_FirstFrameInd", gECU);
  diag_FirstFrameInd( 0, 1, length);
}

SendNegResFormat( BYTE serviceId)
{
  BYTE negResponse[3] = { 0x7f, 0, 0x12 };
  writeDbgLevel(0,"(CanTP) %s: Sending TP level NR(%02x)", gECU, serviceId);
  negResponse[1] = serviceId;

  gSentResponse = 1;
  CanTpSendData( gCANFDConnectionUsed ? gHandleFD : gHandle, negResponse, 3);
}

以上是部分内容,后面对$34-$36-$37服务进行介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值