Battery-Emulator/Software/ModbusServerRTU.h
2023-02-27 13:12:18 -08:00

92 lines
3.3 KiB
C++

// =================================================================================================
// eModbus: Copyright 2020 by Michael Harwerth, Bert Melis and the contributors to eModbus
// MIT license - see license.md for details
// =================================================================================================
#ifndef _MODBUS_SERVER_RTU_H
#define _MODBUS_SERVER_RTU_H
#include "options.h"
#if HAS_FREERTOS
#include <Arduino.h>
#include "Stream.h"
#include "ModbusServer.h"
#include "RTUutils.h"
extern "C" {
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
}
// Specal function signature for broadcast or sniffer listeners
using MSRlistener = std::function<void(ModbusMessage msg)>;
class ModbusServerRTU : public ModbusServer {
public:
// Constructors
explicit ModbusServerRTU(uint32_t timeout, int rtsPin = -1);
ModbusServerRTU(uint32_t timeout, RTScallback rts);
// Destructor
~ModbusServerRTU();
// begin: create task with RTU server to accept requests
void begin(Stream& serial, uint32_t baudRate, int coreID = -1);
void begin(HardwareSerial& serial, int coreID = -1);
// end: kill server task
void end();
// Toggle protocol to ModbusASCII
void useModbusASCII(unsigned long timeout = 1000);
// Toggle protocol to ModbusRTU
void useModbusRTU();
// Inquire protocol mode
bool isModbusASCII();
// Toggle skipping of leading 0x00 byte
void skipLeading0x00(bool onOff = true);
// Special case: worker to react on broadcast requests
void registerBroadcastWorker(MSRlistener worker);
// Even more special: register a sniffer worker
void registerSniffer(MSRlistener worker);
protected:
// Prevent copy construction and assignment
ModbusServerRTU(ModbusServerRTU& m) = delete;
ModbusServerRTU& operator=(ModbusServerRTU& m) = delete;
inline void isInstance() { } // Make class instantiable
// internal common begin function
void doBegin(uint32_t baudRate, int coreID);
static uint8_t instanceCounter; // Number of RTU servers created (for task names)
TaskHandle_t serverTask; // task of the started server
uint32_t serverTimeout; // given timeout for receive. Does not really
// matter for a server, but is needed in
// RTUutils. After timeout without any message
// the server will pause ~1ms and start
// receive again.
Stream *MSRserial; // The serial interface to use
uint32_t MSRinterval; // Bus quiet time between messages
unsigned long MSRlastMicros; // microsecond time stamp of last bus activity
int8_t MSRrtsPin; // GPIO number of the RS485 module's RE/DE line
RTScallback MRTSrts; // Callback to set the RTS line to HIGH/LOW
bool MSRuseASCII; // true=ModbusASCII, false=ModbusRTU
bool MSRskipLeadingZeroByte; // true=first byte ignored if 0x00, false=all bytes accepted
MSRlistener listener; // Broadcast listener
MSRlistener sniffer; // Sniffer listener
// serve: loop function for server task
static void serve(ModbusServerRTU *myself);
};
#endif // HAS_FREERTOS
#endif // INCLUDE GUARD