Having Trouble Reading CAN Messages

A free API for the communication with control devices according to UDS (ISO 14229-1)
Post Reply
luliily
Posts: 11
Joined: Sun 22. Jan 2017, 14:13

Having Trouble Reading CAN Messages

Post by luliily » Sat 4. Feb 2017, 09:10

Hello,

When I used PCAN-UDS TP API to send a request message to the ECU and try to read the respond message,the UDS_Read returned PUDS_ERROR_NO_MESSAGE.Actully,the ECU did respond with a POSITIVE_RESPOND_MESSAGE.

Here CAN Message screenshot:
CAN Message screenshot
CAN Message screenshot
Request&Respond.png (8 KiB) Viewed 6887 times
Here's my code:

Code: Select all

void CUDSDlg::OnBnClickedButtonBoschUds()
{
	TPUDSMsg MsgUDS_READ;
	TPUDSMsg MsgUDS_WRITE;
	TPUDSStatus result;

	MsgUDS_WRITE.LEN = 2;
	MsgUDS_WRITE.DATA.RAW[0] = 0x10;
	MsgUDS_WRITE.DATA.RAW[1] = 0x81;

	MsgUDS_WRITE.MSGTYPE = PUDS_MESSAGE_TYPE_REQUEST;

	MsgUDS_WRITE.NETADDRINFO.SA = 0xFA;
	MsgUDS_WRITE.NETADDRINFO.TA = 0x00;
	MsgUDS_WRITE.NETADDRINFO.TA_TYPE = PUDS_ADDRESSING_PHYSICAL;
	MsgUDS_WRITE.NETADDRINFO.RA = 0x00;
	MsgUDS_WRITE.NETADDRINFO.PROTOCOL = PUDS_PROTOCOL_ISO_15765_2_29B;

	MsgUDS_WRITE.NO_POSITIVE_RESPONSE_MSG = PUDS_KEEP_POS_RSP_MSG_INDICATION_BIT;


	
	result = UDS_Initialize(PUDS_USBBUS1, PUDS_BAUD_250K);//Degug Point A: result == 0x00; OK
	if (result != PUDS_ERROR_OK)
	{
		MessageBox(L"Initialize Fail.");
	}

	result = UDS_Write(PUDS_USBBUS1, &MsgUDS_WRITE);//Degug Point B: result == 0x00; OK
	if (result != PUDS_ERROR_OK)
	{
		CString str;
		str.Format(L"Error Code = %d", result);
		str += L",Send Failure.";
		MessageBox(str);
		PostMessage(WM_CLOSE);
	}

	result = UDS_Read(PUDS_USBBUS1, &MsgUDS_READ);//Degug Point C: result == 0x07; Not OK.Here's the problem
	if (result != PUDS_ERROR_OK)
	{
		CString str;
		str.Format(L"Error Code = %d", result);
		str += L",Read Failure.";
		MessageBox(str);
		PostMessage(WM_CLOSE);
	}
}
I don't know what went wrong.It'll be so great if you can give me some advice.Thasnk you.

Best Wishes~

F.Vergnaud
Software Development
Software Development
Posts: 305
Joined: Mon 9. Sep 2013, 12:21

Re: Having Trouble Reading CAN Messages

Post by F.Vergnaud » Mon 6. Feb 2017, 10:08

Hello Luliily,

I see you're trying to communicate with non standard addresses, but keep in mind that the API is configured by default for standardized communication : client address is 0xF1 and ECU's ones are 0x01 to 0x08.
So after initialization, you have to configure the address of your application with function UDS_SetValue and parameter PUDS_PARAM_SERVER_ADDRESS (otherwise the API will discard any message which are not addressed to 0xF1):

Code: Select all

WORD param = 0xFA;
UDS_SetValue(Channel, PUDS_PARAM_SERVER_ADDRESS, &param, sizeof(param));
Finally be careful with how you use the UDS API: it was designed so that the users should use UDS_Services functions (UDS_SvcXXX and UDS_WaitForService) because it internally handles various UDS requirements (sessions, timeouts, delay, etc.). You can check the PCUClient sample to see how it is done.
Best regards,
Fabrice

luliily
Posts: 11
Joined: Sun 22. Jan 2017, 14:13

Re: Having Trouble Reading CAN Messages

Post by luliily » Wed 8. Feb 2017, 10:57

Hello,

First all of,thank you it's so kind of you to answer my question. :)

I use the function UDS_SetValue,but UDS_Read still return error code 0x07.

Here's my code:

Code: Select all

void CUDSDlg::OnBnClickedButtonBoschUds()
{
	TPUDSMsg MsgUDS_READ;
	TPUDSMsg MsgUDS_WRITE;
	TPUDSStatus result;

	MsgUDS_WRITE.LEN = 2;
	MsgUDS_WRITE.DATA.RAW[0] = 0x10;
	MsgUDS_WRITE.DATA.RAW[1] = 0x81;

	MsgUDS_WRITE.MSGTYPE = PUDS_MESSAGE_TYPE_REQUEST;

	MsgUDS_WRITE.NETADDRINFO.SA = 0xFA;
	MsgUDS_WRITE.NETADDRINFO.TA = 0x00;
	MsgUDS_WRITE.NETADDRINFO.TA_TYPE = PUDS_ADDRESSING_PHYSICAL;
	MsgUDS_WRITE.NETADDRINFO.RA = 0x00;
	MsgUDS_WRITE.NETADDRINFO.PROTOCOL = PUDS_PROTOCOL_ISO_15765_2_29B;

	MsgUDS_WRITE.NO_POSITIVE_RESPONSE_MSG = PUDS_KEEP_POS_RSP_MSG_INDICATION_BIT;



	result = UDS_Initialize(PUDS_USBBUS1, PUDS_BAUD_250K);//Degug Point A: result == 0x00; OK
	if (result != PUDS_ERROR_OK)
	{
		MessageBox(L"Initialize Fail.");
	}

	WORD param = 0xFA;
	result = UDS_SetValue(PUDS_USBBUS1, PUDS_PARAM_SERVER_ADDRESS, &param, sizeof(param));//New Degug Point C: result == 0x00; OK

	result = UDS_Write(PUDS_USBBUS1, &MsgUDS_WRITE);//Degug Point B: result == 0x00; OK
	if (result != PUDS_ERROR_OK)
	{
		CString str;
		str.Format(L"Error Code = %d", result);
		str += L",Send Failure.";
		MessageBox(str);
		PostMessage(WM_CLOSE);
	}

	result = UDS_Read(PUDS_USBBUS1, &MsgUDS_READ);//Degug Point C: result == 0x07; Not OK.Here's the problem
	if (result != PUDS_ERROR_OK)
	{
		CString str;
		str.Format(L"Error Code = %d", result);
		str += L",Read Failure.";
		MessageBox(str);
		PostMessage(WM_CLOSE);
	}
}
And here's screenshot of CAN messages:
UDS.png
UDS.png (59.93 KiB) Viewed 6868 times

I realize that UDS_Services functions (UDS_SvcXXX and UDS_WaitForService) are very very usefully and convenient,but ECU's diagnostic protocol is not quite standard. For example, ReadDTCInformation Service is $19 according to ISO 14229-1-2013,but ReadDTCInformation Service is $18 in my ECU... :o

F.Vergnaud
Software Development
Software Development
Posts: 305
Joined: Mon 9. Sep 2013, 12:21

Re: Having Trouble Reading CAN Messages

Post by F.Vergnaud » Wed 8. Feb 2017, 11:59

Mhh, I didn't see the first time that you're calling the UDS_Read function right after the UDS_Write function.. be careful that both functions are asynchronous: Write only adds your message to a Tx queue and Read fetches messages from the Rx queue. In your case the message may not be fully transmitted when you're trying to read the response.

You need to add a loop where you poll for new messages and exit that loop when a message is received (and/or after a timeout). This is what the UDS_WaitForService does (among other things like handling the UDS "delay" response), but the good news is that you can use this function with custom services ;).
Here is an example that you can include and test inside the PCUClient sample:

Code: Select all

// Sample to request non standard UDS Service
void testCustomService(TPUDSCANHandle Channel, TPUDSNetAddrInfo N_AI)
{
	TPUDSStatus Status;
	TPUDSMsg Message = {};
	TPUDSMsg MessageResponse = {};
	// initialization
	Message.NETADDRINFO = N_AI;

	CLEAR_CONSOLE
		printf("\n\n*** UDS Service: Custom ***\n");

	// Sends a Physical Custom Message
	printf("\n\nSends a Physical Custom Message: \n");

	// Initialize message's DATA
	memset(Message.DATA.RAW, 0, sizeof(Message.DATA));
	Message.LEN = 4;
	Message.DATA.REQUEST.SI = 0x18;	
	Message.DATA.REQUEST.PARAM[0] = 0xFF;
	Message.DATA.REQUEST.PARAM[1] = 0xAA;
	Message.DATA.REQUEST.PARAM[2] = 0xBB;
	// Transmit message
	Status = UDS_Write(Channel, &Message);
	if (Status == PUDS_ERROR_OK)
		Status = UDS_WaitForService(Channel, &MessageResponse, &Message);
	printf("  UDS_Write: %i\n", (int)Status);
	if (Status == PUDS_ERROR_OK)
		displayMessage(&Message, &MessageResponse);
	else
		displayMessage(&Message, NULL);
	waitGetch();
}
Best regards,
Fabrice

luliily
Posts: 11
Joined: Sun 22. Jan 2017, 14:13

Re: Having Trouble Reading CAN Messages

Post by luliily » Wed 1. Mar 2017, 09:08

I think you just solve my problem perfectly! :lol: ;) Thank you!

Here is my code:

Code: Select all

void CUDSDlg::OnBnClickedButtonBoschUds()
{
	TPUDSMsg MsgUDS_READ = {};
	TPUDSMsg MsgUDS_WRITE = {};
	TPUDSStatus result;

	MsgUDS_WRITE.LEN = 2;
	MsgUDS_WRITE.DATA.RAW[0] = 0x10;
	MsgUDS_WRITE.DATA.RAW[1] = 0x81;

	MsgUDS_WRITE.MSGTYPE = PUDS_MESSAGE_TYPE_REQUEST;

	MsgUDS_WRITE.NETADDRINFO.SA = 0xFA;
	MsgUDS_WRITE.NETADDRINFO.TA = 0x00;
	MsgUDS_WRITE.NETADDRINFO.TA_TYPE = PUDS_ADDRESSING_PHYSICAL;
	MsgUDS_WRITE.NETADDRINFO.RA = 0x00;
	MsgUDS_WRITE.NETADDRINFO.PROTOCOL = PUDS_PROTOCOL_ISO_15765_2_29B_NORMAL;


	result = UDS_Initialize(PUDS_USBBUS1, PUDS_BAUD_250K);
	if (result != PUDS_ERROR_OK)
	{
		MessageBox(L"Initialize Fail.");
	}

	WORD param = 0xFA;
	result = UDS_SetValue(PUDS_USBBUS1, PUDS_PARAM_SERVER_ADDRESS, &param, sizeof(param));

	DWORD ulBuffer = 2000;
	result = UDS_SetValue(PUDS_USBBUS1, PUDS_PARAM_TIMEOUT_REQUEST, &ulBuffer, sizeof(ulBuffer));
	result = UDS_SetValue(PUDS_USBBUS1, PUDS_PARAM_TIMEOUT_RESPONSE, &ulBuffer, sizeof(ulBuffer));

	result = CANTP_AddMapping(PCANTP_USBBUS1,
		0x18DA00FA,
		0x18DAFA00,
		PCANTP_ID_CAN_29BIT,
		PCANTP_FORMAT_NORMAL,
		PCANTP_MESSAGE_DIAGNOSTIC,
		0xFA,
		0x00,
		PCANTP_ADDRESSING_PHYSICAL,
		0x00);

	result = UDS_Write(PUDS_USBBUS1, &MsgUDS_WRITE);
	if (result != PUDS_ERROR_OK)
	{
		CString str;
		str.Format(L"Error Code = %d", result);
		str += L",Send Failure.";
		MessageBox(str);
		PostMessage(WM_CLOSE);
	}

//	Sleep(100);

//	result = UDS_Read(PUDS_USBBUS1, &MsgUDS_READ);//result == 0x07; Not OK
	if (result == PUDS_ERROR_OK)
	{
		result = UDS_WaitForService(PUDS_USBBUS1, &MsgUDS_READ, &MsgUDS_WRITE);
		if (result == PUDS_ERROR_OK)
		{
			MessageBox(L"Success");
		}
	}

	Sleep(100);
	result = UDS_Uninitialize(PUDS_USBBUS1);
}
Some changes below:
MsgUDS_WRITE.NETADDRINFO.PROTOCOL = PUDS_PROTOCOL_ISO_15765_2_29B_NORMAL;
CANTP_AddMapping();

Thank you very much,Fabrice. ;)

Best wishes,
luliily

Post Reply