Endianness-independent code
This commit is contained in:
parent
2feb8b639e
commit
f70fbd5260
@ -1,6 +1,7 @@
|
||||
# nanoMODBUS - A compact MODBUS RTU/TCP C library for embedded/microcontrollers
|
||||
|
||||
nanoMODBUS is a small C library that implements the Modbus protocol. It is especially useful in embedded and resource-constrained
|
||||
nanoMODBUS is a small C library that implements the Modbus protocol. It is especially useful in embedded and
|
||||
resource-constrained
|
||||
systems like microcontrollers.
|
||||
Its main features are:
|
||||
|
||||
@ -124,12 +125,6 @@ is useful, for example, to pass the connection a function should operate on.
|
||||
Its initial value can be set inside the `nmbs_platform_conf` struct when creating the `nmbs_t` instance, and changed at
|
||||
any time via the `nmbs_set_platform_arg` API method.
|
||||
|
||||
## Platform endianness
|
||||
|
||||
nanoMODBUS will attempt to detect the endianness of the platform at build time. If the automatic detection fails, you
|
||||
can manually set the endianness of the platform by defining either `NMBS_BIG_ENDIAN` or `NMBS_LITTLE_ENDIAN` in your
|
||||
build flags.
|
||||
|
||||
## Tests and examples
|
||||
|
||||
Tests and examples can be built and run on Linux with CMake:
|
||||
|
||||
@ -8,8 +8,6 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define NMBS_LITTLE_ENDIAN 1
|
||||
|
||||
#include "..\..\nanomodbus.h"
|
||||
#include "comm.h"
|
||||
|
||||
|
||||
@ -82,7 +82,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NMBS_BIG_ENDIAN=1WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@ -110,7 +110,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NMBS_LITTLE_ENDIAN=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<UndefineAllPreprocessorDefinitions>false</UndefineAllPreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
|
||||
38
nanomodbus.c
38
nanomodbus.c
@ -26,7 +26,6 @@
|
||||
|
||||
#include "nanomodbus.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
@ -37,18 +36,6 @@
|
||||
#define DEBUG(...) (void) (0)
|
||||
#endif
|
||||
|
||||
#if !defined(NMBS_BIG_ENDIAN) && !defined(NMBS_LITTLE_ENDIAN)
|
||||
#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || \
|
||||
defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
|
||||
#define NMBS_BIG_ENDIAN
|
||||
#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \
|
||||
defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || \
|
||||
defined(__MIPSEL__) || defined(__AVR_ARCH__)
|
||||
#define NMBS_LITTLE_ENDIAN
|
||||
#else
|
||||
#error "Failed to automatically detect platform endianness. Please define either NMBS_BIG_ENDIAN or NMBS_LITTLE_ENDIAN."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static uint8_t get_1(nmbs_t* nmbs) {
|
||||
uint8_t result = nmbs->msg.buf[nmbs->msg.buf_idx];
|
||||
@ -56,45 +43,32 @@ static uint8_t get_1(nmbs_t* nmbs) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void put_1(nmbs_t* nmbs, uint8_t data) {
|
||||
nmbs->msg.buf[nmbs->msg.buf_idx] = data;
|
||||
nmbs->msg.buf_idx++;
|
||||
}
|
||||
|
||||
|
||||
static void discard_1(nmbs_t* nmbs) {
|
||||
nmbs->msg.buf_idx++;
|
||||
}
|
||||
|
||||
#ifdef NMBS_BIG_ENDIAN
|
||||
|
||||
static uint16_t get_2(nmbs_t* m) {
|
||||
uint16_t result = (*(uint16_t*) (m->msg.buf + m->msg.buf_idx));
|
||||
m->msg.buf_idx += 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void put_2(nmbs_t* m, uint16_t w) {
|
||||
(*(uint16_t*) (m->msg.buf + m->msg.buf_idx)) = w;
|
||||
m->msg.buf_idx += 2;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static uint16_t get_2(nmbs_t* nmbs) {
|
||||
uint16_t result =
|
||||
((uint16_t) (nmbs->msg.buf[nmbs->msg.buf_idx + 1])) | (((uint16_t) nmbs->msg.buf[nmbs->msg.buf_idx] << 8));
|
||||
((uint16_t) nmbs->msg.buf[nmbs->msg.buf_idx]) << 8 | (uint16_t) nmbs->msg.buf[nmbs->msg.buf_idx + 1];
|
||||
nmbs->msg.buf_idx += 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void put_2(nmbs_t* nmbs, uint16_t data) {
|
||||
nmbs->msg.buf[nmbs->msg.buf_idx] = ((uint8_t) ((((uint16_t) (data)) & 0xFF00) >> 8));
|
||||
nmbs->msg.buf[nmbs->msg.buf_idx + 1] = ((uint8_t) (((uint16_t) (data)) & 0x00FF));
|
||||
nmbs->msg.buf[nmbs->msg.buf_idx] = (uint8_t) ((data >> 8) & 0xFFU);
|
||||
nmbs->msg.buf[nmbs->msg.buf_idx + 1] = (uint8_t) data;
|
||||
nmbs->msg.buf_idx += 2;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void msg_buf_reset(nmbs_t* nmbs) {
|
||||
nmbs->msg.buf_idx = 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user