Registering a PLIN collision event resolution schedule

The free LIN software API (Application Programming Interface) for Windows® (only for usage with the PCAN-USB Pro CAN/LIN interface)
Locked
hazime
Posts: 7
Joined: Mon 16. Aug 2021, 07:48

Registering a PLIN collision event resolution schedule

Post by hazime » Mon 16. Aug 2021, 09:06

Hello, thank you.

I'm having trouble registering a resolution schedule

Schedule 1 cannot be registered

ret2 is 0x08 error

Help me.

Code: Select all

#include <iostream>
#include "conio.h"
#include "windows.h"
#include "PLinApi.h"

#define ESC 27
#define LIN_INTERFACE_ID 0
//#define CHECKSUM_TYPE cstClassic
#define CHECKSUM_TYPE cstEnhanced


HLINHW getLINHardware()
{
	HLINHW LINHardwareBuffer[10];
	int count;
	HLINHW result = -1;

	if (errOK == LIN_GetAvailableHardware(LINHardwareBuffer, (sizeof(HLINHW) * 10), &count))
	{
		for (int cnt = 0; cnt < 10; cnt++)
		{
			char hardwareName[64];
			int idNumber;

			memset(hardwareName, 0x00, sizeof(hardwareName));
			LIN_GetHardwareParam(LINHardwareBuffer[cnt], hwpName, hardwareName, sizeof(hardwareName));
			LIN_GetHardwareParam(LINHardwareBuffer[cnt], hwpIdNumber, &idNumber, sizeof(idNumber));
			// Hardware NamerとIDが合致するPLIN-USBインターフェースを使用する
			if ((0 == strcmp(hardwareName, "PLIN-USB")) && (LIN_INTERFACE_ID == idNumber))
			{
				// 使用LINインターフェース
				result = LINHardwareBuffer[cnt];
				break;
			}
		}
	}

	return result;
}

HLINCLIENT openLINDevice(HLINHW LINHardware)
{
	HLINCLIENT result = -1;	// Client

	// LIN Clientの名称作成
	char clientName[LIN_MAX_NAME_LENGTH];
	memset(clientName, 0x00, sizeof(clientName));
	sprintf_s(clientName, "LINClient_%d", LIN_INTERFACE_ID);

	// LIN Clientの登録
	LIN_RegisterClient(clientName, NULL, &result);
	std::cout << "<Ok> LIN_RegisterClient" << std::endl;
	// LIN ClientとHardwareの接続
	LIN_ConnectClient(result, LINHardware);
	std::cout << "<Ok> LIN_ConnectClient" << std::endl;
	// LINハードウェアの初期化
	LIN_InitializeHardware(result, LINHardware, modMaster, 9600);
	std::cout << "<Ok> LIN_InitializeHardware" << std::endl;

	LIN_ResetClient(result);

	return result;
}


void setTargetFrame(HLINCLIENT client, HLINHW hardware)
{
	DWORD ret;
	LIN_RegisterFrameId(client, hardware, 0, 63);

	TLINFrameEntry tLINFrame;

	memset(&tLINFrame, 0x00, sizeof(TLINFrameEntry));
	tLINFrame.FrameId = 0x10;
	tLINFrame.Length = 2;
	tLINFrame.Direction = dirSubscriber;
	tLINFrame.ChecksumType = CHECKSUM_TYPE;
//	tLINFrame.Flags = FRAME_FLAG_RESPONSE_ENABLE;
	ret = LIN_SetFrameEntry(client, hardware, &tLINFrame);
	printf("0x10=%d\n", ret);

	memset(&tLINFrame, 0x00, sizeof(TLINFrameEntry));
	tLINFrame.FrameId = 0x11;
	tLINFrame.Length = 2;
	tLINFrame.Direction = dirSubscriber;
	tLINFrame.ChecksumType = CHECKSUM_TYPE;
//	tLINFrame.Flags = FRAME_FLAG_RESPONSE_ENABLE;

	ret = LIN_SetFrameEntry(client, hardware, &tLINFrame);
	printf("0x11=%d\n", ret);

	memset(&tLINFrame, 0x00, sizeof(TLINFrameEntry));
	tLINFrame.FrameId = 0x12;
	tLINFrame.Length = 2;
	tLINFrame.Direction = dirSubscriber;
	tLINFrame.ChecksumType = CHECKSUM_TYPE;
//	tLINFrame.Flags = FRAME_FLAG_RESPONSE_ENABLE;
	ret = LIN_SetFrameEntry(client, hardware, &tLINFrame);
	printf("0x12=%d\n", ret);

	memset(&tLINFrame, 0x00, sizeof(TLINFrameEntry));
	tLINFrame.FrameId = 0x13;
	tLINFrame.Length = 2;
	tLINFrame.Direction = dirPublisher;
	tLINFrame.ChecksumType = CHECKSUM_TYPE;
	tLINFrame.Flags = FRAME_FLAG_RESPONSE_ENABLE;
	tLINFrame.InitialData[0] = 0x13;
	tLINFrame.InitialData[1] = 0x13;
	ret = LIN_SetFrameEntry(client, hardware, &tLINFrame);
	printf("0x13=%d\n", ret);
}


void setSchedule(HLINCLIENT client, HLINHW hardware)
{
	TLINScheduleSlot mainSchedule[2];

	mainSchedule[0].Type = sltUnconditional;
	mainSchedule[0].Delay = 32;
	mainSchedule[0].FrameId[0] = 0x10;
	mainSchedule[0].CountResolve = 1;
	mainSchedule[1].Type = sltUnconditional;
	mainSchedule[1].Delay = 32;
	mainSchedule[1].FrameId[0] = 0x13;
	DWORD ret1 = LIN_SetSchedule(client, hardware, 0, mainSchedule, 2);
	printf("ret1=%d\n", ret1);

	TLINScheduleSlot resolvSchedule[2];

	resolvSchedule[0].Type = sltUnconditional;
	resolvSchedule[0].Delay = 16;
	resolvSchedule[0].FrameId[0] = 0x12;
	resolvSchedule[1].Type = sltUnconditional;
	resolvSchedule[1].Delay = 16;
	resolvSchedule[1].FrameId[0] = 0x11;

	DWORD ret2 = LIN_SetSchedule(client, hardware, 1, resolvSchedule, 2);
	printf("ret2=%d\n", ret2);

	LIN_StartSchedule(client, hardware, 0);


}


void terminate(HLINCLIENT client, HLINHW hardware)
{
	LIN_ResetHardwareConfig(client, hardware);

	LIN_DisconnectClient(client, hardware);
	LIN_RemoveClient(client);
}


int main()
{
	HLINHW targetInterface = getLINHardware();
	HLINCLIENT client = openLINDevice(targetInterface);
	setTargetFrame(client, targetInterface);

	setSchedule(client, targetInterface);


	while (1) {

		if (_kbhit() && _getch() == ESC) {
			_cputs("\r\nYou Hit Esc-Key!!\r\n");
			break;
		}
	}

	terminate(client, targetInterface);
}
Last edited by K.Wagner on Mon 16. Aug 2021, 09:45, edited 1 time in total.
Reason: Code formatting for better reading

M.Heidemann
Sales & Support
Sales & Support
Posts: 1083
Joined: Fri 20. Sep 2019, 13:31

Re: Registering a PLIN collision event resolution schedule

Post by M.Heidemann » Mon 16. Aug 2021, 12:47

Hello Hazime,

Thank you for your request.

You'll need to fully initialize your arrays,
the behaviour for reading unitialized arrays is undefined.
Some languages will default to known values such as 0, but this is not the case
with C++ instead any value occupying that memory address will be the default value,
as this is unpredictable, this could either work or not depending on the situation.
(This could also lead to really bad issues later on, as this - in some instances - can
pass multiple tests and then completely fail in production)

You should do the following corrections:

Code: Select all

	TLINScheduleSlot mainSchedule[2] = {0};

Code: Select all

	TLINScheduleSlot resolvSchedule[2] = {0};
Please report back to us, if this resolved your problem.

For further questions feel free to contact me again.

Best Regards

Marvin
---
Marvin Heidemann
PEAK-Support Team

hazime
Posts: 7
Joined: Mon 16. Aug 2021, 07:48

Re: Registering a PLIN collision event resolution schedule

Post by hazime » Tue 17. Aug 2021, 11:15

Thank you Marvin.
Schedule 1 has been registered.
However, it was not switched to the "resolving schedule" at the time of the collision.

Are there any settings that are missing when registering the "resolving schedule"?

--------------------------------------------------------------------------------------------------------

Code: Select all

PLIN-USB x 3
Master, slave 1, slave 2

Master is the modified source

slave1

#include <iostream>
#include "conio.h"
#include "windows.h"
#include "PLinApi.h"

#define ESC 27
#define LIN_INTERFACE_ID 1
//#define CHECKSUM_TYPE cstClassic
#define CHECKSUM_TYPE cstEnhanced

HLINHW getLINHardware()
{
	HLINHW LINHardwareBuffer[10];
	int count;
	HLINHW result = -1;

	if (errOK == LIN_GetAvailableHardware(LINHardwareBuffer, (sizeof(HLINHW) * 10), &count))
	{
		for (int cnt = 0; cnt < 10; cnt++)
		{
			char hardwareName[64];
			int idNumber;

			memset(hardwareName, 0x00, sizeof(hardwareName));
			LIN_GetHardwareParam(LINHardwareBuffer[cnt], hwpName, hardwareName, sizeof(hardwareName));
			LIN_GetHardwareParam(LINHardwareBuffer[cnt], hwpIdNumber, &idNumber, sizeof(idNumber));
			// Hardware NamerとIDが合致するPLIN-USBインターフェースを使用する
			if ((0 == strcmp(hardwareName, "PLIN-USB")) && (LIN_INTERFACE_ID == idNumber))
			{
				// 使用LINインターフェース
				result = LINHardwareBuffer[cnt];
				break;
			}
		}
	}

	return result;
}

HLINCLIENT openLINDevice(HLINHW LINHardware)
{
	HLINCLIENT result = -1;	// Client

	// LIN Clientの名称作成
	char clientName[LIN_MAX_NAME_LENGTH];
	memset(clientName, 0x00, sizeof(clientName));
	sprintf_s(clientName, "LINClient_%d", LIN_INTERFACE_ID);

	// LIN Clientの登録
	LIN_RegisterClient(clientName, NULL, &result);
	std::cout << "<Ok> LIN_RegisterClient" << std::endl;
	// LIN ClientとHardwareの接続
	LIN_ConnectClient(result, LINHardware);
	std::cout << "<Ok> LIN_ConnectClient" << std::endl;
	// LINハードウェアの初期化
	LIN_InitializeHardware(result, LINHardware, modSlave, 9600);
	std::cout << "<Ok> LIN_InitializeHardware" << std::endl;

	LIN_ResetClient(result);

	return result;
}


void setTargetFrame(HLINCLIENT client, HLINHW hardware)
{
	LIN_RegisterFrameId(client, hardware, 0, 63);

	TLINFrameEntry tLINFrame;

	memset(&tLINFrame, 0x00, sizeof(TLINFrameEntry));
	tLINFrame.FrameId = 0x10;
	tLINFrame.Length = 2;
	tLINFrame.Direction = dirPublisher;
	tLINFrame.ChecksumType = CHECKSUM_TYPE;
	tLINFrame.Flags = FRAME_FLAG_RESPONSE_ENABLE;
	tLINFrame.InitialData[0] = 0x01;
	tLINFrame.InitialData[1] = 0x10;
	LIN_SetFrameEntry(client, hardware, &tLINFrame);

	memset(&tLINFrame, 0x00, sizeof(TLINFrameEntry));
	tLINFrame.FrameId = 0x11;
	tLINFrame.Length = 2;
	tLINFrame.Direction = dirPublisher;
	tLINFrame.ChecksumType = CHECKSUM_TYPE;
	tLINFrame.Flags = FRAME_FLAG_RESPONSE_ENABLE;
	tLINFrame.InitialData[0] = 0x11;
	tLINFrame.InitialData[1] = 0x11;
	LIN_SetFrameEntry(client, hardware, &tLINFrame);

	BYTE RemapTable[64];
	for (int cnt = 0; cnt <= LIN_MAX_FRAME_ID; cnt++)
	{
		RemapTable[cnt] = cnt;
	}
	RemapTable[0x11] = 0x10;
	LIN_SetResponseRemap(client, hardware, RemapTable);

}


void terminate(HLINCLIENT client, HLINHW hardware)
{
	LIN_ResetHardwareConfig(client, hardware);

	LIN_DisconnectClient(client, hardware);
	LIN_RemoveClient(client);
}


int main()
{
	HLINHW targetInterface = getLINHardware();
	HLINCLIENT client = openLINDevice(targetInterface);
	setTargetFrame(client, targetInterface);

	while (1) {

		if (_kbhit() && _getch() == ESC) {
			_cputs("\r\nYou Hit Esc-Key!!\r\n");
			break;
		}
	}

	terminate(client, targetInterface);
}
[/list]

slave2
[list]
#include <iostream>
#include "conio.h"
#include "windows.h"
#include "PLinApi.h"

#define ESC 27
#define LIN_INTERFACE_ID 2
//#define CHECKSUM_TYPE cstClassic
#define CHECKSUM_TYPE cstEnhanced

HLINHW getLINHardware()
{
	HLINHW LINHardwareBuffer[10];
	int count;
	HLINHW result = -1;

	if (errOK == LIN_GetAvailableHardware(LINHardwareBuffer, (sizeof(HLINHW) * 10), &count))
	{
		for (int cnt = 0; cnt < 10; cnt++)
		{
			char hardwareName[64];
			int idNumber;

			memset(hardwareName, 0x00, sizeof(hardwareName));
			LIN_GetHardwareParam(LINHardwareBuffer[cnt], hwpName, hardwareName, sizeof(hardwareName));
			LIN_GetHardwareParam(LINHardwareBuffer[cnt], hwpIdNumber, &idNumber, sizeof(idNumber));
			// Hardware NamerとIDが合致するPLIN-USBインターフェースを使用する
			if ((0 == strcmp(hardwareName, "PLIN-USB")) && (LIN_INTERFACE_ID == idNumber))
			{
				// 使用LINインターフェース
				result = LINHardwareBuffer[cnt];
				break;
			}
		}
	}

	return result;
}

HLINCLIENT openLINDevice(HLINHW LINHardware)
{
	HLINCLIENT result = -1;	// Client

	// LIN Clientの名称作成
	char clientName[LIN_MAX_NAME_LENGTH];
	memset(clientName, 0x00, sizeof(clientName));
	sprintf_s(clientName, "LINClient_%d", LIN_INTERFACE_ID);

	// LIN Clientの登録
	LIN_RegisterClient(clientName, NULL, &result);
	std::cout << "<Ok> LIN_RegisterClient" << std::endl;
	// LIN ClientとHardwareの接続
	LIN_ConnectClient(result, LINHardware);
	std::cout << "<Ok> LIN_ConnectClient" << std::endl;
	// LINハードウェアの初期化
	LIN_InitializeHardware(result, LINHardware, modSlave, 9600);
	std::cout << "<Ok> LIN_InitializeHardware" << std::endl;

	LIN_ResetClient(result);

	return result;
}


void setTargetFrame(HLINCLIENT client, HLINHW hardware)
{
	LIN_RegisterFrameId(client, hardware, 0, 63);

	TLINFrameEntry tLINFrame;

	memset(&tLINFrame, 0x00, sizeof(TLINFrameEntry));
	tLINFrame.FrameId = 0x10;
	tLINFrame.Length = 2;
	tLINFrame.Direction = dirPublisher;
	tLINFrame.ChecksumType = CHECKSUM_TYPE;
	tLINFrame.Flags = FRAME_FLAG_RESPONSE_ENABLE;
	tLINFrame.InitialData[0] = 0x02;
	tLINFrame.InitialData[1] = 0x10;
	LIN_SetFrameEntry(client, hardware, &tLINFrame);

	memset(&tLINFrame, 0x00, sizeof(TLINFrameEntry));
	tLINFrame.FrameId = 0x12;
	tLINFrame.Length = 2;
	tLINFrame.Direction = dirPublisher;
	tLINFrame.ChecksumType = CHECKSUM_TYPE;
	tLINFrame.Flags = FRAME_FLAG_RESPONSE_ENABLE;
	tLINFrame.InitialData[0] = 0x12;
	tLINFrame.InitialData[1] = 0x12;
	LIN_SetFrameEntry(client, hardware, &tLINFrame);

	BYTE RemapTable[64];
	for (int cnt = 0; cnt <= LIN_MAX_FRAME_ID; cnt++)
	{
		RemapTable[cnt] = cnt;
	}
	RemapTable[0x12] = 0x10;
	LIN_SetResponseRemap(client, hardware, RemapTable);

}


void terminate(HLINCLIENT client, HLINHW hardware)
{
	LIN_ResetHardwareConfig(client, hardware);

	LIN_DisconnectClient(client, hardware);
	LIN_RemoveClient(client);
}


int main()
{
	HLINHW targetInterface = getLINHardware();
	HLINCLIENT client = openLINDevice(targetInterface);
	setTargetFrame(client, targetInterface);




	while (1) {

		if (_kbhit() && _getch() == ESC) {
			_cputs("\r\nYou Hit Esc-Key!!\r\n");
			break;
		}
	}

	terminate(client, targetInterface);
}
Last edited by M.Heidemann on Tue 17. Aug 2021, 11:18, edited 1 time in total.
Reason: Please use "Code"-tags when posting code

M.Heidemann
Sales & Support
Sales & Support
Posts: 1083
Joined: Fri 20. Sep 2019, 13:31

Re: Registering a PLIN collision event resolution schedule

Post by M.Heidemann » Tue 17. Aug 2021, 13:05

Dear Hazime,

You defined the schedule-slot responsible for triggering the Resolve-Scheduler
as unconditional, however a collison will be given by an event frame, so in order
to have the resolve schedule triggered you will need to change the Schedule-Slot type,
this is also mentioned in the docuemntation of PLIN-API:
ResolveSchedule.png
ResolveSchedule.png (14.9 KiB) Viewed 5377 times
In the last code you have shared with us, the slot responsible for triggering
the ResolveScheduler was still set as unconditional:

Code: Select all


	mainSchedule[0].Type = sltUnconditional;
	mainSchedule[0].Delay = 32;
	mainSchedule[0].FrameId[0] = 0x10;
	mainSchedule[0].CountResolve = 1;
	
Change the slot type to sltEvent and try again.

Best Regards

Marvin
---
Marvin Heidemann
PEAK-Support Team

hazime
Posts: 7
Joined: Mon 16. Aug 2021, 07:48

Re: Registering a PLIN collision event resolution schedule

Post by hazime » Wed 18. Aug 2021, 03:20

Thank you Marvin.

As you said, setting it to "sltEvent" switched to a resolution schedule.

Thank you so much to help me.

M.Heidemann
Sales & Support
Sales & Support
Posts: 1083
Joined: Fri 20. Sep 2019, 13:31

Re: Registering a PLIN collision event resolution schedule

Post by M.Heidemann » Wed 18. Aug 2021, 08:27

Hello Hazime,

Thank you for your feedback!

-closed-
---
Marvin Heidemann
PEAK-Support Team

Locked