cancel
Showing results for 
Search instead for 
Did you mean: 

freeModbus store data to all slave

YAlie.1
Associate

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

0 REPLIES 0