1 /* 2 * FreeModbus Libary: RT-Thread Port 3 * Copyright (C) 2013 Armink <[email protected]> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 * File: $Id: portevent_m.c v 1.60 2013/08/13 15:07:05 Armink add Master Functions$ 20 */ 21 22 /* ----------------------- Modbus includes ----------------------------------*/ 23 #include "mb.h" 24 #include "mb_m.h" 25 #include "mbport.h" 26 #include "port.h" 27 28 #if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0 29 /* ----------------------- Defines ------------------------------------------*/ 30 /* ----------------------- Variables ----------------------------------------*/ 31 static struct rt_semaphore xMasterRunRes; 32 static struct rt_event xMasterOsEvent; 33 /* ----------------------- Start implementation -----------------------------*/ 34 BOOL 35 xMBMasterPortEventInit( void ) 36 { 37 rt_event_init(&xMasterOsEvent,"master event",RT_IPC_FLAG_PRIO); 38 return TRUE; 39 } 40 41 BOOL 42 xMBMasterPortEventPost( eMBMasterEventType eEvent ) 43 { 44 rt_event_send(&xMasterOsEvent, eEvent); 45 return TRUE; 46 } 47 48 BOOL 49 xMBMasterPortEventGet( eMBMasterEventType * eEvent ) 50 { 51 rt_uint32_t recvedEvent; 52 /* waiting forever OS event */ 53 rt_event_recv(&xMasterOsEvent, 54 EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE | 55 EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS, 56 RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, 57 &recvedEvent); 58 /* the enum type couldn't convert to int type */ 59 switch (recvedEvent) 60 { 61 case EV_MASTER_READY: 62 *eEvent = EV_MASTER_READY; 63 break; 64 case EV_MASTER_FRAME_RECEIVED: 65 *eEvent = EV_MASTER_FRAME_RECEIVED; 66 break; 67 case EV_MASTER_EXECUTE: 68 *eEvent = EV_MASTER_EXECUTE; 69 break; 70 case EV_MASTER_FRAME_SENT: 71 *eEvent = EV_MASTER_FRAME_SENT; 72 break; 73 case EV_MASTER_ERROR_PROCESS: 74 *eEvent = EV_MASTER_ERROR_PROCESS; 75 break; 76 } 77 return TRUE; 78 } 79 /** 80 * This function is initialize the OS resource for modbus master. 81 * Note:The resource is define by OS.If you not use OS this function can be empty. 82 * 83 */ 84 void vMBMasterOsResInit( void ) 85 { 86 rt_sem_init(&xMasterRunRes, "master res", 0x01 , RT_IPC_FLAG_PRIO); 87 } 88 89 /** 90 * This function is take Mobus Master running resource. 91 * Note:The resource is define by Operating System.If you not use OS this function can be just return TRUE. 92 * 93 * @param lTimeOut the waiting time. 94 * 95 * @return resource taked result 96 */ 97 BOOL xMBMasterRunResTake( LONG lTimeOut ) 98 { 99 /*If waiting time is -1 .It will wait forever */ 100 return rt_sem_take(&xMasterRunRes, lTimeOut) ? FALSE : TRUE ; 101 } 102 103 /** 104 * This function is release Mobus Master running resource. 105 * Note:The resource is define by Operating System.If you not use OS this function can be empty. 106 * 107 */ 108 void vMBMasterRunResRelease( void ) 109 { 110 /* release resource */ 111 rt_sem_release(&xMasterRunRes); 112 } 113 114 /** 115 * This is modbus master respond timeout error process callback function. 116 * @note There functions will block modbus master poll while execute OS waiting. 117 * So,for real-time of system.Do not execute too much waiting process. 118 * 119 * @param ucDestAddress destination salve address 120 * @param pucPDUData PDU buffer data 121 * @param ucPDULength PDU buffer length 122 * 123 */ 124 void vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress, const UCHAR* pucPDUData, 125 USHORT ucPDULength) { 126 /** 127 * @note This code is use OS's event mechanism for modbus master protocol stack. 128 * If you don't use OS, you can change it. 129 */ 130 rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RESPOND_TIMEOUT); 131 132 /* You can add your code under here. */ 133 134 } 135 136 /** 137 * This is modbus master receive data error process callback function. 138 * @note There functions will block modbus master poll while execute OS waiting. 139 * So,for real-time of system.Do not execute too much waiting process. 140 * 141 * @param ucDestAddress destination salve address 142 * @param pucPDUData PDU buffer data 143 * @param ucPDULength PDU buffer length 144 * 145 */ 146 void vMBMasterErrorCBReceiveData(UCHAR ucDestAddress, const UCHAR* pucPDUData, 147 USHORT ucPDULength) { 148 /** 149 * @note This code is use OS's event mechanism for modbus master protocol stack. 150 * If you don't use OS, you can change it. 151 */ 152 rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RECEIVE_DATA); 153 154 /* You can add your code under here. */ 155 156 } 157 158 /** 159 * This is modbus master execute function error process callback function. 160 * @note There functions will block modbus master poll while execute OS waiting. 161 * So,for real-time of system.Do not execute too much waiting process. 162 * 163 * @param ucDestAddress destination salve address 164 * @param pucPDUData PDU buffer data 165 * @param ucPDULength PDU buffer length 166 * 167 */ 168 void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUData, 169 USHORT ucPDULength) { 170 /** 171 * @note This code is use OS's event mechanism for modbus master protocol stack. 172 * If you don't use OS, you can change it. 173 */ 174 rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_EXECUTE_FUNCTION); 175 176 /* You can add your code under here. */ 177 178 } 179 180 /** 181 * This is modbus master request process success callback function. 182 * @note There functions will block modbus master poll while execute OS waiting. 183 * So,for real-time of system.Do not execute too much waiting process. 184 * 185 */ 186 void vMBMasterCBRequestScuuess( void ) { 187 /** 188 * @note This code is use OS's event mechanism for modbus master protocol stack. 189 * If you don't use OS, you can change it. 190 */ 191 rt_event_send(&xMasterOsEvent, EV_MASTER_PROCESS_SUCESS); 192 193 /* You can add your code under here. */ 194 195 } 196 197 /** 198 * This function is wait for modbus master request finish and return result. 199 * Waiting result include request process success, request respond timeout, 200 * receive data error and execute function error.You can use the above callback function. 201 * @note If you are use OS, you can use OS's event mechanism. Otherwise you have to run 202 * much user custom delay for waiting. 203 * 204 * @return request error code 205 */ 206 eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) { 207 eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR; 208 rt_uint32_t recvedEvent; 209 /* waiting for OS event */ 210 rt_event_recv(&xMasterOsEvent, 211 EV_MASTER_PROCESS_SUCESS | EV_MASTER_ERROR_RESPOND_TIMEOUT 212 | EV_MASTER_ERROR_RECEIVE_DATA 213 | EV_MASTER_ERROR_EXECUTE_FUNCTION, 214 RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, 215 &recvedEvent); 216 switch (recvedEvent) 217 { 218 case EV_MASTER_PROCESS_SUCESS: 219 break; 220 case EV_MASTER_ERROR_RESPOND_TIMEOUT: 221 { 222 eErrStatus = MB_MRE_TIMEDOUT; 223 break; 224 } 225 case EV_MASTER_ERROR_RECEIVE_DATA: 226 { 227 eErrStatus = MB_MRE_REV_DATA; 228 break; 229 } 230 case EV_MASTER_ERROR_EXECUTE_FUNCTION: 231 { 232 eErrStatus = MB_MRE_EXE_FUN; 233 break; 234 } 235 } 236 return eErrStatus; 237 } 238 239 #endif 240