First project with PUDS, initialize question

A free API for the communication with control devices according to UDS (ISO 14229-1)
ValeV

First project with PUDS, initialize question

Post by ValeV » Fri 22. Mar 2019, 13:33

Hey all,
I am starting to learn how to use PCAN-UDS API.

Unfortunately, I get starter errors, "undefined reference to 'UDS_Initialize@20' and "undefined reference to 'UDS_Uninitialize@4'.

My code:

Code: Select all

#include <iostream>
#include <windows.h>
#include "PCANBasic.h"
#include "PCAN-ISO-TP.h"
#include "PCAN-UDS.h"

using namespace std;

int main()
{
    TPUDSCANHandle Channel;
	TPUDSStatus Status;

    // Set the PCAN-Channel to use (PCAN-USB Channel 1)
	Channel = PUDS_USBBUS1;
	// Initializing of the UDS Communication session
	Status = UDS_Initialize(Channel, PUDS_BAUD_250K, 0, 0, 0);
	printf("Initialize UDS: %i\n", (int)Status);

	UDS_Uninitialize(Channel);
}
My project folder:
Image

EDIT: Peak dongle is connected to PC, but not to controller (server).

K.Wagner
Software Development
Software Development
Posts: 1080
Joined: Wed 22. Sep 2010, 13:36

Re: First project with PUDS, initialize question

Post by K.Wagner » Fri 22. Mar 2019, 13:42

Hello,

in order to use the PCAN-UDS.dll API, you need to link it statically or dynamically to your project. To link it dynamic you need to use the Windows API functions LoadLibrary, FreeLibrary, and GetProcessAddress. If you want to link it statically, then you need to include the corresponding *.lib file to your project. These lib files are located in the same folder where the dlls are placed within the UDS package you have downloaded.
Best regards,
Keneth

ValeV

Re: First project with PUDS, initialize question

Post by ValeV » Fri 22. Mar 2019, 14:47

Thank you, it works now.

1 other question. In user guide for PCAN-UDS API I see there is class UDSApi, for which function must be called directly.

So I cannot use

Code: Select all

UDSApi mclass;
But only like:

Code: Select all

UDSApi.Initialize(...)

May I ask what is the point of such class? What are the advantages of using UDSApi.Initialize(), and not UDS_Initialize() ?


Also, if I want to do this:

Code: Select all

UDSApi mclass;
Do I have to write custom class from myself? Like

Code: Select all

define mClass.Init( UDS_Initialize(...););

K.Wagner
Software Development
Software Development
Posts: 1080
Joined: Wed 22. Sep 2010, 13:36

Re: First project with PUDS, initialize question

Post by K.Wagner » Fri 22. Mar 2019, 15:14

Hello,

ich you check the help you will see why those classes are there:
UDS wrapper classes
UDS wrapper classes
API.PNG (20.17 KiB) Viewed 6026 times
As you can see, there are wrappers to use the APIs from other programming environments like .NET (C#, VB.NET; C++/CLR), and Delphi. Principally is the same, but since you cannot use *.lib files for .NET or delphi, one need to load the API dynamically in order to be able to use it.
ValeV wrote:So I cannot use

CODE: SELECT ALL
UDSApi mclass;


But only like:

CODE: SELECT ALL
UDSApi.Initialize(...)



May I ask what is the point of such class? What are the advantages of using UDSApi.Initialize(), and not UDS_Initialize() ?
If you see the declaration of that class you will see why:

Code: Select all

public static class UDSApi
In .NET, static classes cannot be instantiated. This class only mimport the functions of the API in .NET, so that you can use them.
ValeV wrote:Also, if I want to do this:

CODE: SELECT ALL
UDSApi mclass;


Do I have to write custom class from myself? Like
CODE: SELECT ALL
define mClass.Init( UDS_Initialize(...););
If you are using C++ and you want to have a class defined that load the API funcitons and allows you to call them, than yes.
Best regards,
Keneth

ValeV

Re: First project with PUDS, initialize question

Post by ValeV » Fri 22. Mar 2019, 15:37

Got it, thank you a lot, sir.

ValeV

Re: First project with PUDS, initialize question

Post by ValeV » Wed 27. Mar 2019, 12:49

K.Wagner wrote:Hello,

in order to use the PCAN-UDS.dll API, you need to link it statically or dynamically to your project. To link it dynamic you need to use the Windows API functions LoadLibrary, FreeLibrary, and GetProcessAddress. If you want to link it statically, then you need to include the corresponding *.lib file to your project. These lib files are located in the same folder where the dlls are placed within the UDS package you have downloaded.
I did it with dynamic linking, and it works, but there is one "problem" I don't know why happens.

FreeLibrary() function takes a lot of time, if there was an error initializing PCAN.

Pseudocode:

Code: Select all

PCANUDS* pcan = new PCANUDS()
pcan->loadAPI() // loads functions from dll, with LoadLibrary() and GetProcessAddress() for all functions
pcan->UDS_Initialize()  //returns error (lets say if is dongle not connected to PC)
pcan->unloadAPI() // calls FreeLibrary(). Takes like 5 seconds
pcan->UDS_Uninitialize()
delete pcan
If there was no error (initialize succeded), FreeLibrary() finishes quickly.

Can you help me why this happens or is this more of a question for Microsoft? (how FreeLibrary() works and all that, not connected to peak uds libraries)

K.Wagner
Software Development
Software Development
Posts: 1080
Joined: Wed 22. Sep 2010, 13:36

Re: First project with PUDS, initialize question

Post by K.Wagner » Wed 27. Mar 2019, 16:51

Hello,

When calling UDS_Initialize there are some threads that are created for communicate with the underlayer APIs (ISO-TP and PCAN-Basic). These threads are terminated when receiving some signals from the devices. Since no devices are initialized, then those threads terminates only when a timeout is reached (5 seconds). That is why you are seeing this delay.

Nevertheless, we will investigate if we can avoid waiting this time when no connection is found. Thanks for bringing this to our attention!
Best regards,
Keneth

ValeV

Re: First project with PUDS, initialize question

Post by ValeV » Thu 28. Mar 2019, 08:16

Thank you, it seems I can't "fix" this as just yet. Nevertheless, thank you for explanation.

K.Wagner
Software Development
Software Development
Posts: 1080
Joined: Wed 22. Sep 2010, 13:36

Re: First project with PUDS, initialize question

Post by K.Wagner » Thu 28. Mar 2019, 09:19

Hello,

you can just ask for channel availability before calling Initialize. The code could looks like:

Code: Select all

	TPUDSCANHandle CanChannel = PUDS_USBBUS1;
	WORD Baudrate = PUDS_BAUD_250K;
	TPUDSStatus result;
	unsigned int iBuffer = 0;

	// Check the availability of a channel before calling UDS_Initialize
	//
	result = UDS_GetValue(CanChannel, PUDS_PARAM_CHANNEL_CONDITION, &iBuffer,
	sizeof(unsigned int));
	
	if (result != PUDS_ERROR_OK)
		MessageBox(NULL, "Failed to get value", "Error", MB_OK);
	else
	{
		// The condition value is a flag
		//
		if((iBuffer & PUDS_CHANNEL_AVAILABLE) == PUDS_CHANNEL_AVAILABLE)
			// Channel is available for connection --> UDS_Initialize can be called
			//
			MessageBox(NULL, "Channel Available - Safe to call UDS_Initialize", "Channel found!", MB_OK);
		else
			// Channel not available --> UDS_Initialize will not be called
			//
			MessageBox(NULL, "Channel not Available - please check your device and try again", "Channel not found", MB_OK);
	}
In this way, you will never call UDS_Initialize on an inexistent channel, so the problem will not occur.
Best regards,
Keneth

ValeV

Re: First project with PUDS, initialize question

Post by ValeV » Thu 28. Mar 2019, 11:59

Oh great, works perfectly. Thank you!

Locked