[CanTp] Vehicle Diagnostic Communication Part 29 [Simulation 17]

[CanTp] Vehicle Diagnostic Communication Part 29 [Simulation 17] 車両診断通信
[CanTp] Vehicle Diagnostic Communication Part 29 [Simulation 17]

Click here for back issues.
https://www.simulationroom999.com/blog/diagnostic-communication-en-back-issue/

Introduction.

Let’s simulate ISO-TP. series.
In this article, I will explain how to reproduce the receive interrupt and the transmission completion interrupt of the XL driver library.

Source code for interrupt emulation in XL driver library

Continuing from the previous article, we will realize interrupt-like things with the XL driver library.

First, let’s check the source code I created.
Since it would be too much to list all the source code, I will only include the part related to threads.

DWORD WINAPI CCANFunctions::RxThread(LPVOID par) 
{
	XLstatus		xlStatus;
	XLcanRxEvent	xlEvent;
	CCANFunctions *pThis;
	TStruct *pth;
	
	bThreadRun = TRUE;
	pth = (TStruct*) par;  
	pThis = (CCANFunctions *)pth->pThis;

	while (bThreadRun) { 

		WaitForSingleObject(pth->hMsgEvent,100);
	    
		xlStatus = XL_SUCCESS;
		unsigned short	flags;

		while (!xlStatus) {
			xlStatus = xlCanReceive(pth->xlPortHandle,  &xlEvent);	
			
			if ( xlStatus != XL_ERR_QUEUE_IS_EMPTY ) {
				flags = xlEvent.tag;
				
				switch( flags ){
				case XL_CAN_EV_TAG_RX_ERROR:
					// receive error
					if( pThis->err_callback ){
						// error interrupt
						pThis->err_callback( pThis, &xlEvent );
					}
					break;
				case XL_CAN_EV_TAG_TX_ERROR:
					// transmission error
					if( pThis->err_callback ){
						// error interrupt
						pThis->err_callback( pThis, &xlEvent );
					}
					break;
				case XL_CAN_EV_TAG_TX_OK:
					// transmission complete
					if( pThis->tx_callback ){
						// Transmission completion interrupt
						pThis->tx_callback( pThis, &xlEvent );
					}
					break;
				case XL_CAN_EV_TAG_RX_OK:
					// reception 
					if( pThis->rx_callback ){
						// receive interrupt
						pThis->rx_callback( pThis, &xlEvent );
					}
					break;
				case XL_CAN_EV_TAG_CHIP_STATE:
					// BusOFF forced return
					pThis->CANGoOffBus();
					pThis->CANGoOnBus();
					break;
				default:
					break;
				}
			}
		}
	}
	return NO_ERROR; 
}

Explanation of interrupt emulation in XL driver library

Just looking at it will not give you an idea of how it works.

The points are as follows.

(1) WaitForSingleObject function
(2) xlCanReceive function
(3) Switch statement and various callbacks

WaitForSingleObject function

The WaitForSingleObject function is a Win32 API function.
This function returns when an event object enters a signal state or a specified timeout expires.
In other words, it basically stops here more often than not.

Who doesn’t know what a “signal state” is?

In the case of an event object, calling the corresponding event object with the SetEvent function in a separate thread will put it in the signal state.
When it returns from WaitForSingleObject, it is in a non-signal state, and the processing in the thread is executed for the number of times the SetEvent function is called.

Therefore, the SetEvent function is called in the XL driver library for each CAN reception or CAN transmission, and the thread runs once at that timing.

xlCanReceive function

The xlCanReceive function is one of the APIs of the XL driver library and is a function for CAN reception.
In this function, the receive information is stored in the xlEvent variable.
If it is empty, the return value is XL_ERR_QUEUE_IS_EMPTY.
In the state that exits WaitForSingleObject, XL_ERR_QUEUE_IS_EMPTY should not be the return value, but we check that it is not XL_ERR_QUEUE_IS_EMPTY and proceed to the next judgment.

switch statement and various callbacks

The part that realizes interrupt emulation is the various case statements and callback functions.
You can assume that xlEvent.tag contains the meaning of the data obtained from xlCanReceive.

Although xlCanReceive is a receive function, it can actually retrieve transmitted frames and error information in the sense of a single frame.

Therefore, based on the information in xlEvent.tag, it branches with a switch and calls the corresponding method.

Although not shown in the code presented here, if there is a process that calls a callback function passed from a higher-level function, it will behave like an interrupt.
In other words, interrupts are realized by threads.

Although interrupts and threads are two different concepts, it seems that only the characteristic of switching to another process is used.
In this way, it looks like an interrupt has been received from the higher-level AUTOSAR-CanTp.

Also, in the case of XL_CAN_EV_TAG_CHIP_STATE, there is some kind of processing that turns BusOff and then BusOn.
I think it should not be a concern for virtual CAN Bus.
However, in the case of a real physical CAN, there are times when the CAN goes BusOff and doesn’t come back on when the harness is unplugged.
I’m including this as a spell to force it to return.

We really need to be aware of the error active, error passive, and BusOFF states of CAN, but I’m going to omit that here.

Conclusion.

  • The code for interrupt emulation is presented.
  • Wait for signal with WaitForSingleObject.
  • xlCanReceive to get various information on receive, send, and error.
  • xlEvent.tag allocates to various processes.

Click here for back issues.

コメント

タイトルとURLをコピーしました