|
1 /* |
|
2 * Copyright (c) 2002,2016 Mario de Sousa (msousa@fe.up.pt) |
|
3 * |
|
4 * This file is part of the Modbus library for Beremiz and matiec. |
|
5 * |
|
6 * This Modbus library is free software: you can redistribute it and/or modify |
|
7 * it under the terms of the GNU Lesser General Public License as published by |
|
8 * the Free Software Foundation, either version 3 of the License, or |
|
9 * (at your option) any later version. |
|
10 * |
|
11 * This program is distributed in the hope that it will be useful, but |
|
12 * WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
|
14 * General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU Lesser General Public License |
|
17 * along with this Modbus library. If not, see <http://www.gnu.org/licenses/>. |
|
18 * |
|
19 * This code is made available on the understanding that it will not be |
|
20 * used in safety-critical situations without a full and competent review. |
|
21 */ |
|
22 |
|
23 |
|
24 |
|
25 #include <fcntl.h> /* File control definitions */ |
|
26 #include <stdio.h> /* Standard input/output */ |
|
27 #include <string.h> |
|
28 #include <stdlib.h> |
|
29 #include <termio.h> /* POSIX terminal control definitions */ |
|
30 #include <sys/time.h> /* Time structures for select() */ |
|
31 #include <unistd.h> /* POSIX Symbolic Constants */ |
|
32 #include <errno.h> /* Error definitions */ |
|
33 |
|
34 #include "mb_layer1.h" |
|
35 #include "mb_slave_private.h" |
|
36 #include "mb_master_private.h" |
|
37 #include "mb_slave.h" |
|
38 #include "mb_master.h" |
|
39 |
|
40 //#define DEBUG /* uncomment to see the data sent and received */ |
|
41 |
|
42 |
|
43 #ifndef TRUE |
|
44 #define TRUE 1 |
|
45 #endif |
|
46 |
|
47 #ifndef FALSE |
|
48 #define FALSE 0 |
|
49 #endif |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 layer1_funct_ptr_t fptr_[4] = { |
|
55 { /* WARNING: TCP functions MUST be the first, as we have this hardcoded in the code! */ |
|
56 /* more specifically, in the get_ttyfd() macro in mb_slave.c */ |
|
57 /* in the mb_slave_new() function in mb_slave.c */ |
|
58 /* in the mb_master_connect() function in mb_master.c */ |
|
59 &modbus_tcp_write |
|
60 ,&modbus_tcp_read |
|
61 ,&modbus_tcp_init |
|
62 ,&modbus_tcp_done |
|
63 ,&modbus_tcp_connect |
|
64 ,&modbus_tcp_listen |
|
65 ,&modbus_tcp_close |
|
66 ,&modbus_tcp_silence_init |
|
67 ,&modbus_tcp_get_min_timeout |
|
68 },{ |
|
69 &modbus_rtu_write |
|
70 ,&modbus_rtu_read |
|
71 ,&modbus_rtu_init |
|
72 ,&modbus_rtu_done |
|
73 ,&modbus_rtu_connect |
|
74 ,&modbus_rtu_listen |
|
75 ,&modbus_rtu_close |
|
76 ,&modbus_rtu_silence_init |
|
77 ,&modbus_rtu_get_min_timeout |
|
78 },{ |
|
79 &modbus_ascii_write |
|
80 ,&modbus_ascii_read |
|
81 ,&modbus_ascii_init |
|
82 ,&modbus_ascii_done |
|
83 ,&modbus_ascii_connect |
|
84 ,&modbus_ascii_listen |
|
85 ,&modbus_ascii_close |
|
86 ,&modbus_ascii_silence_init |
|
87 ,&modbus_ascii_get_min_timeout |
|
88 },{ |
|
89 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL |
|
90 } |
|
91 }; |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 /************************************************************************ |
|
99 |
|
100 initialise / shutdown the library |
|
101 |
|
102 These functions sets up/shut down the library state |
|
103 (allocate memory for buffers, initialise data strcutures, etc) |
|
104 |
|
105 **************************************************************************/ |
|
106 #define max(a,b) (((a)>(b))?(a):(b)) |
|
107 |
|
108 int mb_slave_and_master_init(int nd_count_tcp, int nd_count_rtu, int nd_count_ascii) { |
|
109 int extra_bytes, extra_bytes_tcp, extra_bytes_rtu, extra_bytes_ascii; |
|
110 |
|
111 #ifdef DEBUG |
|
112 fprintf( stderr, "mb_slave_and_master_init()\n"); |
|
113 fprintf( stderr, "creating %d nodes\n", nd_count); |
|
114 #endif |
|
115 |
|
116 /* initialise layer 1 library */ |
|
117 if (modbus_tcp_init (nd_count_tcp, DEF_OPTIMIZATION, &extra_bytes_tcp ) < 0) |
|
118 goto error_exit_0; |
|
119 if (modbus_rtu_init (nd_count_rtu, DEF_OPTIMIZATION, &extra_bytes_rtu ) < 0) |
|
120 goto error_exit_1; |
|
121 if (modbus_ascii_init(nd_count_ascii, DEF_OPTIMIZATION, &extra_bytes_ascii) < 0) |
|
122 goto error_exit_2; |
|
123 extra_bytes= max(extra_bytes_tcp, extra_bytes_rtu); |
|
124 extra_bytes= max(extra_bytes , extra_bytes_ascii); |
|
125 |
|
126 /* initialise master and slave libraries... */ |
|
127 if (mb_slave_init__(extra_bytes) < 0) |
|
128 goto error_exit_3; |
|
129 if (mb_master_init__(extra_bytes) < 0) |
|
130 goto error_exit_4; |
|
131 return 0; |
|
132 |
|
133 /* |
|
134 error_exit_3: |
|
135 modbus_master_done(); |
|
136 */ |
|
137 error_exit_4: |
|
138 mb_slave_done__(); |
|
139 error_exit_3: |
|
140 modbus_ascii_done(); |
|
141 error_exit_2: |
|
142 modbus_rtu_done(); |
|
143 error_exit_1: |
|
144 modbus_tcp_done(); |
|
145 error_exit_0: |
|
146 return -1; |
|
147 } |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 int mb_slave_and_master_done(void) { |
|
153 int res = 0; |
|
154 res |= mb_slave_done__ (); |
|
155 res |= mb_master_done__ (); |
|
156 res |= modbus_ascii_done(); |
|
157 res |= modbus_rtu_done (); |
|
158 res |= modbus_tcp_done (); |
|
159 return res; |
|
160 } |
|
161 |