Coco – How to measure code coverage on embedded systems via CAN Bus

Coco – How to measure code coverage on embedded systems via CAN Bus

Introduction

Squish Coco generates the code execution measurement using streams and by default, the output of these streams is piped to a file on the file system. For embedded devices without a file system, this leads to problems. Squish Coco allows you to redirect the measurements stream via Custom IO Functions. In this article, we create a showcase with the common CAN Bus.

The Basic Setup

The Basic Setup of a CAN bus is a transceiver which handles the voltage on the wires and also a controller which saves incoming and outgoing frames into registers.

For this showcase we will connect a micro controller to a Linux system. This is achieved by connecting the Linux system via USB adapter to the CAN bus. The USB adapter integrates the controller and the transceiver. On  the other side, we use a STM32 micro controller which has the CAN bus controller already integrated. Finally, we need a transceiver, which is achieved by connecting the micro controller to a Breakout board which contains the transceiver.

 

General flowcharts for the PC receiver and the micro controller

PC receiver

The main task of the PC receiver is to invoke  the __coveragescanner_save() function on the micro controller, receive the data and write it to files on the PC.

Micro controller

The normal process is running on the micro controller until the save message is received and the measurement data is sent.

 

Implementation of Custom IO Functions

When the micro controller receives the RECEIVESAVECOMMANDMESSAGEID over CAN bus, the save is initialized.

status = HAL_CAN_Receive(&hcan, CAN_FIFO0, 100);		
if (status != HAL_TIMEOUT)
{
    if(hcan.pRxMsg->ExtId != 0 )
    {
        if((hcan.pRxMsg->ExtId & 0xFFFF) == RECEIVESAVECOMMANDMESSAGEID ) 
		{
		    #ifdef __COVERAGESCANNER__		
				__coveragescanner_save();
			#endif
		}					
    }
}

The Custom IO Functions on the STM32 micro controller code look like this.

#ifdefined( __COVERAGESCANNER__ )
static int csfputs(const char *s, void *stream) 
{
  while(*s)
	{
		int counter = 0;
		CanTxMsgTypeDef sendMessage;
		sendMessage.ExtId = RETURNSAVEMESSAGEID;
		sendMessage.IDE = CAN_ID_EXT;
		sendMessage.RTR = CAN_RTR_DATA;
		while(*s  && (counter < 8))
		{
			sendMessage.Data[counter] = (uint8_t) *s;
			counter++;
			s++;
		}
		sendMessage.DLC = counter;
		hcan.pTxMsg = &sendMessage;
		HAL_CAN_Transmit(&hcan,TIMEOUTTIME);
	}	
  return 0;
}
static void *csfopenappend(const char *path)          { return (void*)1; }
static int csfclose(void *fp) 
{
	CanTxMsgTypeDef sendMessage;
	sendMessage.ExtId = RETURNSAVEMESSAGEID;
	sendMessage.IDE = CAN_ID_EXT;
	sendMessage.RTR = CAN_RTR_DATA; 
	sendMessage.Data[0] = 0;	
	sendMessage.DLC = 0;
	hcan.pTxMsg = &sendMessage;
	HAL_CAN_Transmit(&hcan,TIMEOUTTIME);
	return 1; 
}
#endif

For further information contact us.

 

0 Comments

Leave a reply

Your email address will not be published. Required fields are marked *

*