portevent_m.c 9.53 KB
/*
 * FreeModbus Libary: RT-Thread Port
 * Copyright (C) 2013 Armink <armink.ztl@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * File: $Id: portevent_m.c v 1.60 2013/08/13 15:07:05 Armink add Master Functions$
 */

/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mb_m.h"
#include "mbport.h"
#include "port.h"
#include "mbconfig.h"

#include "bsp.h"
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
/* ----------------------- Defines ------------------------------------------*/
/* ----------------------- Variables ----------------------------------------*/
//static struct rt_semaphore xMasterRunRes;
//static struct rt_event     xMasterOsEvent;
static OS_FLAG_GRP PtrEvent;
static OS_SEM Mbsem;
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBMasterPortEventInit( void )
{
	OS_ERR mberror;
	OSFlagCreate(&PtrEvent,"MBevent",0,&mberror);
	return TRUE;
//    rt_event_init(&xMasterOsEvent,"master event",RT_IPC_FLAG_PRIO);
//    return TRUE;
}

BOOL
xMBMasterPortEventPost( eMBMasterEventType eEvent )
{
	OS_ERR mberror;
	OS_FLAGS fla;
	fla = OSFlagPost(&PtrEvent,eEvent,OS_OPT_POST_FLAG_SET,&mberror);
	return TRUE;
//    rt_event_send(&xMasterOsEvent, eEvent);
//    return TRUE;
}

BOOL
xMBMasterPortEventGet( eMBMasterEventType * eEvent )
{
	OS_ERR mberror;
	*eEvent = OSFlagPend(&PtrEvent,
			EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE |
            EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS,
			0,
			OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME + OS_OPT_PEND_NON_BLOCKING,
			NULL,
			&mberror);
	return TRUE;
//    rt_uint32_t recvedEvent;
//    /* waiting forever OS event */
//    rt_event_recv(&xMasterOsEvent,
//            EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE |
//            EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS,
//            RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
//            &recvedEvent);
//    /* the enum type couldn't convert to int type */
//    switch (recvedEvent)
//    {
//    case EV_MASTER_READY:
//        *eEvent = EV_MASTER_READY;
//        break;
//    case EV_MASTER_FRAME_RECEIVED:
//        *eEvent = EV_MASTER_FRAME_RECEIVED;
//        break;
//    case EV_MASTER_EXECUTE:
//        *eEvent = EV_MASTER_EXECUTE;
//        break;
//    case EV_MASTER_FRAME_SENT:
//        *eEvent = EV_MASTER_FRAME_SENT;
//        break;
//    case EV_MASTER_ERROR_PROCESS:
//        *eEvent = EV_MASTER_ERROR_PROCESS;
//        break;
//    }
//    return TRUE;
}
/**
 * This function is initialize the OS resource for modbus master.
 * Note:The resource is define by OS.If you not use OS this function can be empty.
 *
 */
void vMBMasterOsResInit( void )
{
	OS_ERR semerror;
	OSSemCreate(&Mbsem,"MbSemm",1,&semerror);
   // rt_sem_init(&xMasterRunRes, "master res", 0x01 , RT_IPC_FLAG_PRIO);
}

/**
 * This function is take Mobus Master running resource.
 * Note:The resource is define by Operating System.If you not use OS this function can be just return TRUE.
 *
 * @param lTimeOut the waiting time.
 *
 * @return resource taked result
 */
BOOL xMBMasterRunResTake( LONG lTimeOut )
{
	OS_ERR semerror;
	OSSemPend(&Mbsem,lTimeOut,OS_OPT_PEND_NON_BLOCKING,0,&semerror);
	return semerror ? FALSE : TRUE; 

    /*If waiting time is -1 .It will wait forever */
   // return rt_sem_take(&xMasterRunRes, lTimeOut) ? FALSE : TRUE ;
}

/**
 * This function is release Mobus Master running resource.
 * Note:The resource is define by Operating System.If you not use OS this function can be empty.
 *
 */
void vMBMasterRunResRelease( void )
{
	OS_ERR semerror;
	OSSemPost(&Mbsem,OS_OPT_POST_ALL,&semerror);
    /* release resource */
  //  rt_sem_release(&xMasterRunRes);
}

/**
 * This is modbus master respond timeout error process callback function.
 * @note There functions will block modbus master poll while execute OS waiting.
 * So,for real-time of system.Do not execute too much waiting process.
 *
 * @param ucDestAddress destination salve address
 * @param pucPDUData PDU buffer data
 * @param ucPDULength PDU buffer length
 *
 */
void vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress, const UCHAR* pucPDUData,
        USHORT ucPDULength) {
	OS_ERR mberror;
	OSFlagPost(&PtrEvent,EV_MASTER_ERROR_RESPOND_TIMEOUT,OS_OPT_POST_FLAG_SET,&mberror);
    /**
     * @note This code is use OS's event mechanism for modbus master protocol stack.
     * If you don't use OS, you can change it.
     */
    //rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RESPOND_TIMEOUT);

    /* You can add your code under here. */

}

/**
 * This is modbus master receive data error process callback function.
 * @note There functions will block modbus master poll while execute OS waiting.
 * So,for real-time of system.Do not execute too much waiting process.
 *
 * @param ucDestAddress destination salve address
 * @param pucPDUData PDU buffer data
 * @param ucPDULength PDU buffer length
 *
 */
void vMBMasterErrorCBReceiveData(UCHAR ucDestAddress, const UCHAR* pucPDUData,
        USHORT ucPDULength) {
	OS_ERR mberror;
	OSFlagPost(&PtrEvent,EV_MASTER_ERROR_RECEIVE_DATA,OS_OPT_POST_FLAG_SET,&mberror);			
    /**
     * @note This code is use OS's event mechanism for modbus master protocol stack.
     * If you don't use OS, you can change it.
     */
    //rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RECEIVE_DATA);

    /* You can add your code under here. */

}

/**
 * This is modbus master execute function error process callback function.
 * @note There functions will block modbus master poll while execute OS waiting.
 * So,for real-time of system.Do not execute too much waiting process.
 *
 * @param ucDestAddress destination salve address
 * @param pucPDUData PDU buffer data
 * @param ucPDULength PDU buffer length
 *
 */
void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUData,
        USHORT ucPDULength) {
	OS_ERR mberror;
	OSFlagPost(&PtrEvent,EV_MASTER_ERROR_EXECUTE_FUNCTION,OS_OPT_POST_FLAG_SET,&mberror);
    /**
     * @note This code is use OS's event mechanism for modbus master protocol stack.
     * If you don't use OS, you can change it.
     */
    //rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_EXECUTE_FUNCTION);

    /* You can add your code under here. */

}

/**
 * This is modbus master request process success callback function.
 * @note There functions will block modbus master poll while execute OS waiting.
 * So,for real-time of system.Do not execute too much waiting process.
 *
 */
void vMBMasterCBRequestScuuess( void ) {
	OS_ERR mberror;
	OSFlagPost(&PtrEvent,EV_MASTER_PROCESS_SUCESS,OS_OPT_POST_FLAG_SET,&mberror);
    /**
     * @note This code is use OS's event mechanism for modbus master protocol stack.
     * If you don't use OS, you can change it.
     */
    //rt_event_send(&xMasterOsEvent, EV_MASTER_PROCESS_SUCESS);

    /* You can add your code under here. */

}

/**
 * This function is wait for modbus master request finish and return result.
 * Waiting result include request process success, request respond timeout,
 * receive data error and execute function error.You can use the above callback function.
 * @note If you are use OS, you can use OS's event mechanism. Otherwise you have to run
 * much user custom delay for waiting.
 *
 * @return request error code
 */
eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
    eMBMasterReqErrCode    eErrStatus = MB_MRE_NO_ERR;
	OS_ERR mberror;
	u32 eEvent;
	eEvent = OSFlagPend(&PtrEvent,
			 EV_MASTER_PROCESS_SUCESS | EV_MASTER_ERROR_RESPOND_TIMEOUT |
             EV_MASTER_ERROR_RECEIVE_DATA |
             EV_MASTER_ERROR_EXECUTE_FUNCTION,
			0,
			OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME + OS_OPT_PEND_NON_BLOCKING,
			NULL,
			&mberror);
	switch (eEvent)
    {
		case EV_MASTER_PROCESS_SUCESS:
			break;
		case EV_MASTER_ERROR_RESPOND_TIMEOUT:
		{
			eErrStatus = MB_MRE_TIMEDOUT;
			break;
		}
		case EV_MASTER_ERROR_RECEIVE_DATA:
		{
			eErrStatus = MB_MRE_REV_DATA;
			break;
		}
		case EV_MASTER_ERROR_EXECUTE_FUNCTION:
		{
			eErrStatus = MB_MRE_EXE_FUN;
			break;
		}
    }	
	return eErrStatus;
//    rt_uint32_t recvedEvent;
//    /* waiting for OS event */
//    rt_event_recv(&xMasterOsEvent,
//            EV_MASTER_PROCESS_SUCESS | EV_MASTER_ERROR_RESPOND_TIMEOUT
//                    | EV_MASTER_ERROR_RECEIVE_DATA
//                    | EV_MASTER_ERROR_EXECUTE_FUNCTION,
//            RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
//            &recvedEvent);
//    switch (recvedEvent)
//    {
//    case EV_MASTER_PROCESS_SUCESS:
//        break;
//    case EV_MASTER_ERROR_RESPOND_TIMEOUT:
//    {
//        eErrStatus = MB_MRE_TIMEDOUT;
//        break;
//    }
//    case EV_MASTER_ERROR_RECEIVE_DATA:
//    {
//        eErrStatus = MB_MRE_REV_DATA;
//        break;
//    }
//    case EV_MASTER_ERROR_EXECUTE_FUNCTION:
//    {
//        eErrStatus = MB_MRE_EXE_FUN;
//        break;
//    }
//    }
//    return eErrStatus;
}

#endif