⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myprotocol.c

📁 THIS CODE IS FOR EXAMPLE PURPOSES ONLY, USE AT YOUR OWN RISK, NO WARRANTY IS ASSUMED OR IMPLIED
💻 C
📖 第 1 页 / 共 3 页
字号:
		case  MODBUS_Read_Holding_Registers:
			address=ntohs(pHdr->address);
			size=ntohs(pHdr->u.size);
			bytes = size*2;
			
		    	if (myProtocolDebug)
				logMsg ("Modbus Request MODBUS_Read_Holding_Registers address=%hu size=%hu bytes=%hu\n", address, size, (int)bytes, 4, 5, 6);
                        if (((address+size) > NUMBER_OF_HOLDING_REGISTERS)
                                 || (pProtoCtrl->bufferSize < 6) 
                                 || (bytes > 256) ) 
				{
			        modbusSendError(pProtoCtrl,0x02);
				break;
				}
   			pProtoCtrl->pBuffer[2] = (uchar_t)bytes;

#if _WHY_BYTE_ORDER==_BIG_ENDIAN
			bcopy((char*)&holdingRegisters[address],&(pProtoCtrl->pBuffer[3]),bytes);
#else
			data = (ushort_t *)&pProtoCtrl->pBuffer[3]; 
			/* align if necessary */
			for (count=0;count<size;count++)
				{ 
                                data[count]= htons(holdingRegisters[address+count]);
				}
#endif
			/* transmit reply */
			pProtoCtrl->bufferSize = 3+ bytes;
			break;

		case  MODBUS_Read_Input_Registers:
		    	if (myProtocolDebug)
				logMsg ("Modbus Request MODBUS_Read_Input_Registers\n", 1, 2, 3, 4, 5, 6);
			address=ntohs(pHdr->address);
			size=ntohs(pHdr->u.size);
			bytes = size*2;
			
                        if ( ((address+size) > NUMBER_OF_INPUT_REGISTERS)
                                 || (pProtoCtrl->bufferSize < 6) 
                                 || (bytes > 256) ) 
				{
			        modbusSendError(pProtoCtrl,0x02);
				break;
				}
   			pProtoCtrl->pBuffer[2] = (uchar_t)bytes;

#if	_WHY_BYTE_ORDER==_BIG_ENDIAN
			bcopy((char*)&inputRegisters[address],&(pProtoCtrl->pBuffer[3]),bytes);
#else
			/* align if necessary */
			data = (ushort_t *)&pProtoCtrl->pBuffer[3]; 
			/* align if necessary */
			for (count=0;count<size;count++)
				{ 
                                data[count]= htons(holdingRegisters[address+count]);
				}
#endif
			/* transmit reply */
			pProtoCtrl->bufferSize = 3+ bytes;
			break;

		case  MODBUS_Write_Single_Coil:
		    	if (myProtocolDebug)
				logMsg ("Modbus Request MODBUS_Write_Single_Coil\n", 1, 2, 3, 4, 5, 6);
			address=ntohs(pHdr->address);
                        if ((address > NUMBER_OF_COILS ) 
                                 || (pProtoCtrl->bufferSize < 6) 
				 || (pProtoCtrl->pBuffer[4] != 0x00))
				{
			        modbusSendError(pProtoCtrl,0x02);
				break;
				}
			shift=address%8;

			switch( pProtoCtrl->pBuffer[3] )
				{
				case 0xFF:
					mask = (0x0001<<shift); 
					coils[address/8]|= mask;
					break;
				case 0x00:
					mask = ~(0x0001<<shift); 
					coils[address/8]&= mask;
					break;
				default:
			        	modbusSendError(pProtoCtrl,0x03);
					goto sendIt;
				}
			/* transmit reply */
			pProtoCtrl->bufferSize = 6;
			break;

		case  MODBUS_Write_Single_Register:
		    	if (myProtocolDebug)
				logMsg ("Modbus Request MODBUS_Write_Single_Register\n", 1, 2, 3, 4, 5, 6);
			address=ntohs(pHdr->address);
                        if ((address > NUMBER_OF_HOLDING_REGISTERS ) 
                                 || (pProtoCtrl->bufferSize < 6)) 
				{
			        modbusSendError(pProtoCtrl,0x02);
				break;
				}
			holdingRegisters[address] = ntohs(pHdr->u.data);

			/* transmit reply */
			pProtoCtrl->bufferSize = 6;
			break;

		case  MODBUS_Write_Multiple_registers:
			address=ntohs(pHdr->address);
			size=ntohs(pHdr->u.size);
			bytes = pHdr->bytes;
		    	if (myProtocolDebug)
				logMsg ("Modbus Request MODBUS_Write_Multiple_registers address=%d size=%d bytes=%d\n", address, size, bytes, 4, 5, 6);
                        if (((address+size) > NUMBER_OF_HOLDING_REGISTERS)
                                 || (pProtoCtrl->bufferSize < 7+bytes) 
                                 || (size*2 != bytes ) ) 
				{
			        modbusSendError(pProtoCtrl,0x02);
				break;
				}
		
#if	_WHY_BYTE_ORDER==_BIG_ENDIAN
			bcopy(&(pProtoCtrl->pBuffer[7]),(char*)&holdingRegisters[address],bytes);
#else
			/* align if necessary */
			data = (ushort_t *)&pProtoCtrl->pBuffer[7]; 
			/* align if necessary */
			for (count=0;count<size;count++)
				{ 
                                holdingRegisters[address+count]=ntohs(data[count]);
				}
#endif
			/* transmit reply */
			pProtoCtrl->bufferSize = 6;
			break;

		case  MODBUS_Read_Device_Identification:
		case  MODBUS_Mask_Write_Register:
		case  MODBUS_Read_Write_Multiple_registers:
		case  MODBUS_Read_File_Record:
		case  MODBUS_Write_Multiple_Coils:
		default:
			/* send not supported error */
		        modbusSendError(pProtoCtrl,0x01);
			break;
		}
sendIt:
    myProtocolTx(
	pProtoCtrl->pCookie,
	pProtoCtrl->pBuffer,
	pProtoCtrl->bufferSize,
	pProtoCtrl->returnAddress
	);

     /* make sure the buffer is free */
    pProtoCtrl->busy = FALSE;
    return (TRUE);
}

void modbusSendError
	(
	MODBUS_PROTO_CTRL * pProtoCtrl,
	uchar_t errornum
	)
	{
    	if (myProtocolDebug)
		logMsg ("Modbus Request Sent an ERROR\n", 1, 2, 3, 4, 5, 6);
	pProtoCtrl->pBuffer[1] |= MODBUS_ERROR;
	pProtoCtrl->pBuffer[2] = errornum;
	pProtoCtrl->bufferSize = 3;
	}

/******************************************************************************
*
* modbus - a command line interface for the modbus master (or client) 
*
* This function provides a interface to the protocol for demostration purposes.
* The format of the command is
*
* modbus read|write points type address@host  [data1] [data2] .. [dataN]  
*
* dataX, points, and address are unsigned integers 
* type is any one of the following

* 	coils             (1 bit read/write values)
*       inputs            (1 bit read only values)
*       holding           (16 bit read/write holding registers)
*       registers         (16 bit read only input registers)
*       ID                (Device identification string)    
*
* RETURNS: OK or ERROR, indicating command syntax only, 
*          communication errors and response are logged to thew consol
*
*
*/
int modbus(
   char * rwStr, 
   unsigned int points, 
   char * typeStr, 
   char * addressAtHost, 
   ...)
{

#define COIL_TYPE       0
#define INPUT_TYPE	1
#define HOLDING_TYPE	2
#define REGISTER_TYPE	3
#define ID_TYPE		4 
#define MAX_SIZE       512

    va_list vaList;	/* traverses argument list */
    char *      pHost;     
    char sendBuf[270];
    MODBUS_HEADER * pHdr = (MODBUS_HEADER * )sendBuf;
    int destInetAddr;	
    unsigned int modbusAddr;	
    int type,requestSize,count; 	
    volatile ushort_t data; /* made volatile so it doesn't get optimised out */ 
    ushort_t * pData; 
    char  mac[7];
 
    static MODBUS_PROTO_CTRL *       pProtoCtrl;
    static BOOL init = FALSE; 

    if(NULL== rwStr)  
	goto printSyntax;	
		
    if( 0 == points)
	{	
	printf("ERROR points must be > 0\n");	
	goto printSyntax;	
	}

    if( NULL ==( pHost = strchr(addressAtHost,'@')))
	{	
	printf("ERROR addess@host|IP must contain '@'\n");	
	goto printSyntax;	
	}
    pHost++;
    
    sscanf(pHost,"%2hx",&data);mac[0]=(uchar_t)data; 	
    sscanf(pHost,"%*3c%2hx",&data);mac[1]=(uchar_t)data; 	
    sscanf(pHost,"%*6c%2hx",&data);mac[2]=(uchar_t)data; 	
    sscanf(pHost,"%*9c%2hx",&data);mac[3]=(uchar_t)data; 	
    sscanf(pHost,"%*12c%2hx",&data);mac[4]=(uchar_t)data; 	
    sscanf(pHost,"%*15c%2hx",&data);mac[5]=(uchar_t)data; 	
    
 /*   printf("%02x:%02x:%02x:%02x:%02x:%02x\n",(int)mac[0],(int)mac[1],
		(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]);	*/

    if (0==strncmp( typeStr, "coil", 4))
	type = COIL_TYPE;
    else if (0==strncmp( typeStr, "input", 5)) 
	type = INPUT_TYPE;
    else if (0==strncmp( typeStr, "hold", 4)) 
	type = HOLDING_TYPE;
    else if (0==strncmp( typeStr, "reg", 3)) 
	type = REGISTER_TYPE;
    else if (0==strncmp( typeStr, "ID", 2)) 
	type = ID_TYPE;
    else goto printSyntax;	

    pHdr->type = MODBUS_REQUEST;   /* identify message as comming from Master */
    pHdr->address = htons((ushort_t)atoi(addressAtHost)); /* parse the address (the client checks for illegal values) */	   	

    if (0==strncmp( rwStr, "read", 4))
    	{
		switch(type)
			{
			case COIL_TYPE:
				pHdr->function = MODBUS_Read_Coils;
				pHdr->u.size = htons(points);
				requestSize = 6;
 				break;
			case INPUT_TYPE:
				pHdr->function = MODBUS_Read_Discrete_Inputs;
				pHdr->u.size = htons(points);
				requestSize = 6;
 				break;
			case HOLDING_TYPE:
				pHdr->function = MODBUS_Read_Holding_Registers;
				pHdr->u.size = htons(points);
				requestSize = 6;
 				break;
			case REGISTER_TYPE:
				pHdr->function = MODBUS_Read_Input_Registers;
				pHdr->u.size = htons(points);
				requestSize = 6;
 				break;
			case ID_TYPE:
				pHdr->function = MODBUS_Read_Input_Registers;
				sendBuf[2] = 0x0E;
				if (points == 1)
					sendBuf[3] = 0x04; /* individual items */
				else
					sendBuf[3] = 0x03; /* stream access, all item types */
				sendBuf[4] = (uchar_t)atoi(addressAtHost); /* first item to get */
				requestSize = 5;
				break;
			}
	}
    else if (0==strncmp( rwStr, "write", 4)) 
	{
		va_start (vaList, addressAtHost);
		switch(type)
			{
			case COIL_TYPE:
				if (points == 1)
				{
					pHdr->function = MODBUS_Write_Single_Coil;
					data = va_arg (vaList, ushort_t);
					if (data)
						sendBuf[4] = 0xFF; 
					else
						sendBuf[4] = 0x00; 
					sendBuf[5] = 0x00; 
					requestSize = 6;
				}
				else
				{
					pHdr->function = MODBUS_Write_Multiple_Coils;
				     	printf("ERROR writting multiple coils not supported.\n");	
				     	return(ERROR);
				}
 				break;
			case INPUT_TYPE:
				printf("ERROR Discrete inputs are read only.\n");	
				return(ERROR);
 				break;
			case HOLDING_TYPE:
				if (points ==1)
				{
					pHdr->function = MODBUS_Write_Single_Register;
					data = va_arg (vaList, ushort_t);
 					pHdr->u.data=htons(data);
					requestSize = 6;
				}
				else if(points > 128 )
				{
					printf("ERROR to many data points\n");	
					return(ERROR);
				}
				else
				{
					pHdr->function = MODBUS_Write_Multiple_registers;
					pHdr->u.size= htons(points);
					pHdr->bytes= points*2;
					pData=(ushort_t *)&sendBuf[7];
					for(count=0;count<points;count++)
						{
                        /*  data going into buffer to be sent on network.  needed htons().  EAN 07/26/02 */
                        volatile int temp;
                        /*  have to use a temporary, or htons() will call va_arg() twice...  
                            pain in the butt to figure this one out, thank goodness for 
                            preprocessed files.  EAN 07/26/02  */
                        temp=(ushort_t) va_arg (vaList,int );
						pData[count] =htons(temp);
						}
					requestSize = 7+pHdr->bytes;
				}
 				break;
			case REGISTER_TYPE:
				printf("ERROR Inputs registers are read only.\n");	
				return(ERROR);
			case ID_TYPE:
				printf("ERROR Device ID is read only.\n");	
				return(ERROR);
			}
		va_end (vaList);	
	}	
    else goto printSyntax;	

    if(!init)
	{  	
		if( pProtoCtrl = myProtocolInit(sysBootParams.bootDev, 0)) 	
			init = TRUE;
		else
 		   printf("ERROR can't attach protocol to specified device.\n");	
		   return(ERROR);
	} 
  
  	myProtocolTx(
		pProtoCtrl->pCookie,
		sendBuf,
		requestSize,
		mac);


    return(OK);

printSyntax:

	printf("\nmodbus read|write points type address@XX:XX:XX:XX:XX:XX [data1].. [dataN]\n\n");  
	printf("  dataX and address are positive integers\n"); 
	printf("  type is any one of the following\n");
	printf("      coils             (1 bit read/write values)\n");
	printf("      inputs            (1 bit read only values)\n");
	printf("      holding           (16 bit read/write holding registers)\n");
	printf("      registers         (16 bit read only input registers)\n");
	printf("      ID                (Device identification string)\n\n");    
	printf("  examples:\n   -> modbus \"read\", 2, \"coils\", \"123@00:50:DA:FE:7B:DD\"\n");    
	printf("   -> modbus \"write\", 2, \"holding\", \"43@00:a0:1e:09:08:07\", 234, 56\n\n");    
    return(ERROR);
}  

void dump( void)
{
	int i;
	for( i=0;i<NUMBER_OF_HOLDING_REGISTERS;i++)
	{
		if((i%10)==0)
			printf("\n %d  ",i);
		printf("%hu,   ",holdingRegisters[i]);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -