Skip to main content
Visitor II
February 5, 2021
Question

freeModbus store data to all slave

  • February 5, 2021
  • 0 replies
  • 964 views

hello.

i was try to implement modbusTCP on STM32F7

my STM32F7 is modbus slave and my PC is modbus master for simulation.

it was work but have one question:

my modbus slave will store data to all slave(1-248), in normally, i should be store data to own slave only.

How to fix that?

0693W000007E2yTQAS.png 

i use freeRTOS to listen TCP

void StartDefaultTask(void const * argument)
{
 /* init code for LWIP */
 MX_LWIP_Init();
 /* USER CODE BEGIN StartDefaultTask */
 eMBTCPInit(0);
 eMBEnable();
 /* Infinite loop */
 for(;;)
 {
	eMBPoll();
 osDelay(1);
 __NOP();
 }
 /* USER CODE END StartDefaultTask */
}

eMBErrorCode
eMBPoll( void )
{
	/* Tx & Rx use same frame(ucMBFrame) as buffer
	 * the ucMBFrame is only PDU section, no MBAP information
	 * --------PBU--------
	 * ucMBFrame[0]: FunctionCode
	 * ucMBFrame[1]: Register address(MSB)
	 * ucMBFrame[2]: Register address(LSB)
	 * ucMBFrame[3]: Register number(MSB)
	 * ucMBFrame[4]: Register number(LSB)
	 *
	 * ex. receive frame from modbus_poll
	 * Tx:000128-E3 B5 00 00 00 06 0A 03 00 00 00 10 (hex)
	 * ucMBFrame[0]: 03 (dec)
	 * ucMBFrame[1]: 00
	 * ucMBFrame[2]: 00
	 * ucMBFrame[3]: 00
	 * ucMBFrame[4]: 16
	 */
 static UCHAR *ucMBFrame;
 static UCHAR ucRcvAddress;
 static UCHAR ucFunctionCode;
 static USHORT usLength;
 static eMBException eException;
 
 int i;
 eMBErrorCode eStatus = MB_ENOERR;
 eMBEventType eEvent;
 
 /* Check if the protocol stack is ready. */
 if( eMBState != STATE_ENABLED )
 {
 return MB_EILLSTATE;
 }
 
 /* Check if there is a event available. If not return control to caller.
 * Otherwise we will handle the event. */
 if( xMBPortEventGet( &eEvent ) == TRUE )
 {
 switch ( eEvent )
 {
 case EV_READY:
 break;
 
 case EV_FRAME_RECEIVED:
 	//receive frame at ucMBFrame
 eStatus = peMBFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength );
 if( eStatus == MB_ENOERR )
 {
 /* Check if the frame is for us. If not ignore the frame. */
 if( ( ucRcvAddress == ucMBAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST ) )
 {
 ( void )xMBPortEventPost( EV_EXECUTE );
 }
 }
 break;
 
 case EV_EXECUTE:
 ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
 eException = MB_EX_ILLEGAL_FUNCTION;
 for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
 {
 /* No more function handlers registered. Abort. */
 if( xFuncHandlers[i].ucFunctionCode == 0 )
 {
 break;
 }
 else if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode )
 {
 	//entry eMBFuncReadHoldingRegister function
 eException = xFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
 break;
 }
 }
 
 /* If the request was not sent to the broadcast address we
 * return a reply. */
 if( ucRcvAddress != MB_ADDRESS_BROADCAST )
 {
 if( eException != MB_EX_NONE )
 {
 /* An exception occured. Build an error frame. */
 usLength = 0;
 ucMBFrame[usLength++] = ( UCHAR )( ucFunctionCode | MB_FUNC_ERROR );
 ucMBFrame[usLength++] = eException;
 }
 eStatus = peMBFrameSendCur( ucMBAddress, ucMBFrame, usLength );
 }
 break;
 
 case EV_FRAME_SENT:
 break;
 }
 }
 return MB_ENOERR;
}

eMBException
eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
{
 USHORT usRegAddress;
 USHORT usRegCount;
 UCHAR *pucFrameCur;
 
 eMBException eStatus = MB_EX_NONE;
 eMBErrorCode eRegStatus;
 
 if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
 {
 usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
 usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
 usRegAddress++;
 
 //master query quantity
 usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 );
 usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
 __NOP();
 
 /* Check if the number of registers to read is valid. If not
 * return Modbus illegal data value exception. 
 */
 if( ( usRegCount >= 1 ) && ( usRegCount <= MB_PDU_FUNC_READ_REGCNT_MAX ) )
 {
 /* Set the current PDU data pointer to the beginning. */
 pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
 *usLen = MB_PDU_FUNC_OFF;
 
 /* First byte contains the function code. */
 *pucFrameCur++ = MB_FUNC_READ_HOLDING_REGISTER;
 *usLen += 1;
 
 /* Second byte in the response contain the number of bytes. */
 *pucFrameCur++ = ( UCHAR ) ( usRegCount * 2 );
 *usLen += 1;
 
 /* Make callback to fill the buffer. */
 eRegStatus = eMBRegHoldingCB( pucFrameCur, usRegAddress, usRegCount, MB_REG_READ );
 /* If an error occured convert it into a Modbus exception. */
 if( eRegStatus != MB_ENOERR )
 {
 eStatus = prveMBError2Exception( eRegStatus );
 }
 else
 {
 *usLen += usRegCount * 2;
 }
 }
 else
 {
 eStatus = MB_EX_ILLEGAL_DATA_VALUE;
 }
 }
 else
 {
 /* Can't be a valid request because the length is incorrect. */
 eStatus = MB_EX_ILLEGAL_DATA_VALUE;
 }
 return eStatus;
}

my project git: https://github.com/alien18331/ST_ModbusTCP

    This topic has been closed for replies.