26
26
27
27
#include "modbus.h"
28
28
29
- #if defined(HAVE_BYTESWAP_H )
30
- # include <byteswap.h>
31
- #endif
32
-
33
- #if defined(__APPLE__ )
34
- # include <libkern/OSByteOrder.h>
35
- # define bswap_16 OSSwapInt16
36
- # define bswap_32 OSSwapInt32
37
- # define bswap_64 OSSwapInt64
38
- #endif
39
-
40
- #if defined(__GNUC__ )
41
- # define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10)
42
- # if GCC_VERSION >= 430
43
- // Since GCC >= 4.30, GCC provides __builtin_bswapXX() alternatives so we switch to them
44
- # undef bswap_32
45
- # define bswap_32 __builtin_bswap32
46
- # endif
47
- # if GCC_VERSION >= 480
48
- # undef bswap_16
49
- # define bswap_16 __builtin_bswap16
50
- # endif
51
- #endif
52
-
53
- #if defined(_MSC_VER ) && (_MSC_VER >= 1400 )
54
- # define bswap_32 _byteswap_ulong
55
- # define bswap_16 _byteswap_ushort
56
- #endif
57
-
58
- #if !defined(bswap_16 )
59
- # warning "Fallback on C functions for bswap_16"
60
- static inline uint16_t bswap_16 (uint16_t x )
61
- {
62
- return (x >> 8 ) | (x << 8 );
63
- }
64
- #endif
65
-
66
- #if !defined(bswap_32 )
67
- # warning "Fallback on C functions for bswap_32"
68
- static inline uint32_t bswap_32 (uint32_t x )
69
- {
70
- return (bswap_16 (x & 0xffff ) << 16 ) | (bswap_16 (x >> 16 ));
71
- }
72
- #endif
73
29
// clang-format on
74
30
75
31
/* Sets many bits from a single byte value (all 8 bits of the byte value are
@@ -128,11 +84,14 @@ float modbus_get_float_abcd(const uint16_t *src)
128
84
uint32_t i ;
129
85
uint8_t a , b , c , d ;
130
86
131
- a = (src [0 ] >> 8 ) & 0xFF ;
132
- b = (src [0 ] >> 0 ) & 0xFF ;
133
- c = (src [1 ] >> 8 ) & 0xFF ;
134
- d = (src [1 ] >> 0 ) & 0xFF ;
87
+ // Mind: src contains 16-bit numbers in processor-endianness, hence
88
+ // we use shift operations and do not access memory directly
89
+ a = (src [0 ] >> 8 ) & 0xFF ; // high byte of first word
90
+ b = (src [0 ] >> 0 ) & 0xFF ; // low byte of first word
91
+ c = (src [1 ] >> 8 ) & 0xFF ; // high byte of second word
92
+ d = (src [1 ] >> 0 ) & 0xFF ; // low byte of second word
135
93
94
+ // we assemble 32bit integer always in abcd order via shift operations
136
95
i = (a << 24 ) | (b << 16 ) | (c << 8 ) | (d << 0 );
137
96
memcpy (& f , & i , 4 );
138
97
@@ -146,12 +105,14 @@ float modbus_get_float_dcba(const uint16_t *src)
146
105
uint32_t i ;
147
106
uint8_t a , b , c , d ;
148
107
149
- a = (src [0 ] >> 8 ) & 0xFF ;
150
- b = (src [0 ] >> 0 ) & 0xFF ;
151
- c = (src [1 ] >> 8 ) & 0xFF ;
152
- d = (src [1 ] >> 0 ) & 0xFF ;
108
+ // byte order is defined when reading from src: dcba
109
+ d = (src [0 ] >> 8 ) & 0xFF ;
110
+ c = (src [0 ] >> 0 ) & 0xFF ;
111
+ b = (src [1 ] >> 8 ) & 0xFF ;
112
+ a = (src [1 ] >> 0 ) & 0xFF ;
153
113
154
- i = (d << 24 ) | (c << 16 ) | (b << 8 ) | (a << 0 );
114
+ // we assemble 32bit integer always in abcd order via shift operations
115
+ i = (a << 24 ) | (b << 16 ) | (c << 8 ) | (d << 0 );
155
116
memcpy (& f , & i , 4 );
156
117
157
118
return f ;
@@ -164,12 +125,14 @@ float modbus_get_float_badc(const uint16_t *src)
164
125
uint32_t i ;
165
126
uint8_t a , b , c , d ;
166
127
167
- a = (src [0 ] >> 8 ) & 0xFF ;
168
- b = (src [0 ] >> 0 ) & 0xFF ;
169
- c = (src [1 ] >> 8 ) & 0xFF ;
170
- d = (src [1 ] >> 0 ) & 0xFF ;
128
+ // byte order is defined when reading from src: badc
129
+ b = (src [0 ] >> 8 ) & 0xFF ;
130
+ a = (src [0 ] >> 0 ) & 0xFF ;
131
+ d = (src [1 ] >> 8 ) & 0xFF ;
132
+ c = (src [1 ] >> 0 ) & 0xFF ;
171
133
172
- i = (b << 24 ) | (a << 16 ) | (d << 8 ) | (c << 0 );
134
+ // we assemble 32bit integer always in abcd order via shift operations
135
+ i = (a << 24 ) | (b << 16 ) | (c << 8 ) | (d << 0 );
173
136
memcpy (& f , & i , 4 );
174
137
175
138
return f ;
@@ -182,12 +145,14 @@ float modbus_get_float_cdab(const uint16_t *src)
182
145
uint32_t i ;
183
146
uint8_t a , b , c , d ;
184
147
185
- a = (src [0 ] >> 8 ) & 0xFF ;
186
- b = (src [0 ] >> 0 ) & 0xFF ;
187
- c = (src [1 ] >> 8 ) & 0xFF ;
188
- d = (src [1 ] >> 0 ) & 0xFF ;
148
+ // byte order is defined when reading from src: cdab
149
+ c = (src [0 ] >> 8 ) & 0xFF ;
150
+ d = (src [0 ] >> 0 ) & 0xFF ;
151
+ a = (src [1 ] >> 8 ) & 0xFF ;
152
+ b = (src [1 ] >> 0 ) & 0xFF ;
189
153
190
- i = (c << 24 ) | (d << 16 ) | (a << 8 ) | (b << 0 );
154
+ // we assemble 32bit integer always in abcd order via shift operations
155
+ i = (a << 24 ) | (b << 16 ) | (c << 8 ) | (d << 0 );
191
156
memcpy (& f , & i , 4 );
192
157
193
158
return f ;
@@ -196,97 +161,81 @@ float modbus_get_float_cdab(const uint16_t *src)
196
161
/* DEPRECATED - Get a float from 4 bytes in sort of Modbus format */
197
162
float modbus_get_float (const uint16_t * src )
198
163
{
199
- float f ;
200
- uint32_t i ;
201
-
202
- i = (((uint32_t ) src [1 ]) << 16 ) + src [0 ];
203
- memcpy (& f , & i , sizeof (float ));
204
-
205
- return f ;
164
+ return modbus_get_float_cdab (src );
206
165
}
207
166
208
167
/* Set a float to 4 bytes for Modbus w/o any conversion (ABCD) */
209
168
void modbus_set_float_abcd (float f , uint16_t * dest )
210
169
{
211
- uint32_t i ;
212
- uint8_t * out = (uint8_t * ) dest ;
170
+ // The straight-forward type conversion won't work because of type-punned pointer aliasing warning
171
+ // uint32_t i = *(uint32_t*)(&f);
172
+ float * fptr = & f ;
173
+ uint32_t * iptr = (uint32_t * )fptr ;
174
+ uint32_t i = * iptr ;
213
175
uint8_t a , b , c , d ;
214
176
215
- memcpy (& i , & f , sizeof (uint32_t ));
216
177
a = (i >> 24 ) & 0xFF ;
217
178
b = (i >> 16 ) & 0xFF ;
218
179
c = (i >> 8 ) & 0xFF ;
219
180
d = (i >> 0 ) & 0xFF ;
220
181
221
- out [0 ] = a ;
222
- out [1 ] = b ;
223
- out [2 ] = c ;
224
- out [3 ] = d ;
182
+ dest [0 ] = (a << 8 ) | b ;
183
+ dest [1 ] = (c << 8 ) | d ;
225
184
}
226
185
227
186
/* Set a float to 4 bytes for Modbus with byte and word swap conversion (DCBA) */
228
187
void modbus_set_float_dcba (float f , uint16_t * dest )
229
188
{
230
- uint32_t i ;
231
- uint8_t * out = (uint8_t * ) dest ;
189
+ float * fptr = & f ;
190
+ uint32_t * iptr = (uint32_t * )fptr ;
191
+ uint32_t i = * iptr ;
232
192
uint8_t a , b , c , d ;
233
193
234
- memcpy (& i , & f , sizeof (uint32_t ));
235
194
a = (i >> 24 ) & 0xFF ;
236
195
b = (i >> 16 ) & 0xFF ;
237
196
c = (i >> 8 ) & 0xFF ;
238
197
d = (i >> 0 ) & 0xFF ;
239
198
240
- out [0 ] = d ;
241
- out [1 ] = c ;
242
- out [2 ] = b ;
243
- out [3 ] = a ;
199
+ dest [0 ] = (d << 8 ) | c ;
200
+ dest [1 ] = (b << 8 ) | a ;
244
201
}
245
202
246
203
/* Set a float to 4 bytes for Modbus with byte swap conversion (BADC) */
247
204
void modbus_set_float_badc (float f , uint16_t * dest )
248
205
{
249
- uint32_t i ;
250
- uint8_t * out = (uint8_t * ) dest ;
206
+ float * fptr = & f ;
207
+ uint32_t * iptr = (uint32_t * )fptr ;
208
+ uint32_t i = * iptr ;
251
209
uint8_t a , b , c , d ;
252
210
253
- memcpy (& i , & f , sizeof (uint32_t ));
254
211
a = (i >> 24 ) & 0xFF ;
255
212
b = (i >> 16 ) & 0xFF ;
256
213
c = (i >> 8 ) & 0xFF ;
257
214
d = (i >> 0 ) & 0xFF ;
258
215
259
- out [0 ] = b ;
260
- out [1 ] = a ;
261
- out [2 ] = d ;
262
- out [3 ] = c ;
216
+ dest [0 ] = (b << 8 ) | a ;
217
+ dest [1 ] = (d << 8 ) | c ;
263
218
}
264
219
265
220
/* Set a float to 4 bytes for Modbus with word swap conversion (CDAB) */
266
221
void modbus_set_float_cdab (float f , uint16_t * dest )
267
222
{
268
- uint32_t i ;
269
- uint8_t * out = (uint8_t * ) dest ;
223
+ float * fptr = & f ;
224
+ uint32_t * iptr = (uint32_t * )fptr ;
225
+ uint32_t i = * iptr ;
270
226
uint8_t a , b , c , d ;
271
227
272
- memcpy (& i , & f , sizeof (uint32_t ));
273
228
a = (i >> 24 ) & 0xFF ;
274
229
b = (i >> 16 ) & 0xFF ;
275
230
c = (i >> 8 ) & 0xFF ;
276
231
d = (i >> 0 ) & 0xFF ;
277
232
278
- out [0 ] = c ;
279
- out [1 ] = d ;
280
- out [2 ] = a ;
281
- out [3 ] = b ;
233
+ dest [0 ] = (c << 8 ) | d ;
234
+ dest [1 ] = (a << 8 ) | b ;
282
235
}
283
236
284
237
/* DEPRECATED - Set a float to 4 bytes in a sort of Modbus format! */
285
238
void modbus_set_float (float f , uint16_t * dest )
286
239
{
287
- uint32_t i ;
288
-
289
- memcpy (& i , & f , sizeof (uint32_t ));
290
- dest [0 ] = (uint16_t ) i ;
291
- dest [1 ] = (uint16_t ) (i >> 16 );
240
+ modbus_set_float_cdab (f , dest );
292
241
}
0 commit comments