Endianness-independent code

This commit is contained in:
Valerio De Benedetto 2023-03-13 12:30:32 +01:00
parent 2feb8b639e
commit f70fbd5260
4 changed files with 10 additions and 43 deletions

View File

@ -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:

View File

@ -8,8 +8,6 @@
#include <stdio.h>
#include <windows.h>
#define NMBS_LITTLE_ENDIAN 1
#include "..\..\nanomodbus.h"
#include "comm.h"

View File

@ -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>

View File

@ -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;