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
xMBMasterPortEventInit(void)35 xMBMasterPortEventInit( void )
36 {
37 rt_event_init(&xMasterOsEvent,"master event",RT_IPC_FLAG_PRIO);
38 return TRUE;
39 }
40
41 BOOL
xMBMasterPortEventPost(eMBMasterEventType eEvent)42 xMBMasterPortEventPost( eMBMasterEventType eEvent )
43 {
44 rt_event_send(&xMasterOsEvent, eEvent);
45 return TRUE;
46 }
47
48 BOOL
xMBMasterPortEventGet(eMBMasterEventType * eEvent)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 */
vMBMasterOsResInit(void)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 */
xMBMasterRunResTake(LONG lTimeOut)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 */
vMBMasterRunResRelease(void)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 */
vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress,const UCHAR * pucPDUData,USHORT ucPDULength)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 */
vMBMasterErrorCBReceiveData(UCHAR ucDestAddress,const UCHAR * pucPDUData,USHORT ucPDULength)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 */
vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress,const UCHAR * pucPDUData,USHORT ucPDULength)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 */
vMBMasterCBRequestScuuess(void)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 */
eMBMasterWaitRequestFinish(void)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