prepare server code for an maybe client

master
Steffen Pohle 2 years ago
parent 010eb60b21
commit f6d0ece8a6

@ -4,7 +4,7 @@ APP = testmodbus-server
-include Makefile.rules -include Makefile.rules
OBJECTS = gui.oo main.oo mbsconfig.oo modbus.oo guimodbusdata.oo guivalues.oo json.oo tcp.oo OBJECTS = gui.oo server.oo mbsconfig.oo modbus.oo guimodbusdata.oo guivalues.oo json.oo tcp.oo
DISTNAME=testmodbus-server-$(VERSION) DISTNAME=testmodbus-server-$(VERSION)
ifeq ($(TARGET),) ifeq ($(TARGET),)
@ -17,7 +17,7 @@ help:
echo "set up configuration" echo "set up configuration"
echo " make configwindows to generate the windows build" echo " make configwindows to generate the windows build"
echo " make configcross to generate the windows cross build" echo " make configcross to generate the windows cross build"
echo " make configlinux to generate the linix build" echo " make configlinux to generate the linux build"
echo " make buildwindows to generate the build for windows (uses cross compiler)" echo " make buildwindows to generate the build for windows (uses cross compiler)"
configlinux: clean configlinux: clean
@ -58,6 +58,7 @@ clean:
rm -rf Makefile.rules rm -rf Makefile.rules
rm -rf test-fc16 rm -rf test-fc16
rm -rf test-fc15 rm -rf test-fc15
rm -rf config.h
dist: clean dist: clean
rm -rf $(DISTNAME) rm -rf $(DISTNAME)

@ -20,6 +20,10 @@
extern GtkBuilder *_builder_; // work around for threads extern GtkBuilder *_builder_; // work around for threads
extern void addvar_displaywithvalues (gpointer data, GuiValue *v); extern void addvar_displaywithvalues (gpointer data, GuiValue *v);
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
// //
// call back functions // call back functions
@ -44,9 +48,9 @@ void cb_window_show (GtkWidget *widget, gpointer data) {
void cb_menu_new (GtkWidget *widget, gpointer data) { void cb_menu_new (GtkWidget *widget, gpointer data) {
// GtkBuilder *builder = (GtkBuilder *) data; // GtkBuilder *builder = (GtkBuilder *) data;
modbus.EnableAll(0); modbussrv.EnableAll(0);
MBData_EnableAll(0); MBData_EnableAll(0);
modbus.RequestsClear(); modbussrv.RequestsClear();
MBData_ReqReset (); MBData_ReqReset ();
Value_DelAll(); Value_DelAll();
}; };
@ -177,21 +181,21 @@ void cb_btn_start (GtkWidget *widget, gpointer data) {
int port = atoi(gtk_entry_get_text(GTK_ENTRY(portentry))); int port = atoi(gtk_entry_get_text(GTK_ENTRY(portentry)));
if (modbus.isRunning()) { if (modbussrv.isRunning()) {
printf ("Stop Server\n"); printf ("Stop Server\n");
modbus.Stop(); modbussrv.Stop();
gtk_widget_set_sensitive(portentry, TRUE); gtk_widget_set_sensitive(portentry, TRUE);
gtk_button_set_label(GTK_BUTTON(widget), _("Start")); gtk_button_set_label(GTK_BUTTON(widget), _("Start"));
} }
else { else {
printf ("Start Server (port: %d)\n", port); printf ("Start Server (port: %d)\n", port);
if (modbus.Start(port)) { if (modbussrv.Start(port)) {
gtk_button_set_label(GTK_BUTTON(widget),_("Stop")); gtk_button_set_label(GTK_BUTTON(widget),_("Stop"));
gtk_widget_set_sensitive(portentry, FALSE); gtk_widget_set_sensitive(portentry, FALSE);
} }
usleep (250000); usleep (250000);
if (modbus.isRunning() == 0) { if (modbussrv.isRunning() == 0) {
modbus.Stop(); modbussrv.Stop();
displayerror("modbus server could not been started.\nSee console output for errors."); displayerror("modbus server could not been started.\nSee console output for errors.");
gtk_widget_set_sensitive(portentry, TRUE); gtk_widget_set_sensitive(portentry, TRUE);
gtk_button_set_label(GTK_BUTTON(widget), _("Start")); gtk_button_set_label(GTK_BUTTON(widget), _("Start"));
@ -256,7 +260,7 @@ void addvar_displaywithvalues (gpointer data, GuiValue *v) {
vn.value = gtk_entry_get_text(GTK_ENTRY(value)); // load the from the entry vn.value = gtk_entry_get_text(GTK_ENTRY(value)); // load the from the entry
if (Value_SetValue(vn.value, vn.type, vn.fc, &regstowrite, regvals)) { if (Value_SetValue(vn.value, vn.type, vn.fc, &regstowrite, regvals)) {
modbus.SetRegValue(vn.fc, vn.reg, regstowrite, (uint16_t*)regvals); modbussrv.SetRegValue(vn.fc, vn.reg, regstowrite, (uint16_t*)regvals);
} }
} }
@ -575,19 +579,19 @@ void cb_about_btnclose(GtkWidget *widget, gpointer data) {
} }
void cb_btn_enableall (GtkWidget *widget, gpointer data) { void cb_btn_enableall (GtkWidget *widget, gpointer data) {
modbus.EnableAll(1); modbussrv.EnableAll(1);
MBData_EnableAll(1); MBData_EnableAll(1);
}; };
void cb_btn_disableall (GtkWidget *widget, gpointer data) { void cb_btn_disableall (GtkWidget *widget, gpointer data) {
modbus.EnableAll(0); modbussrv.EnableAll(0);
MBData_EnableAll(0); MBData_EnableAll(0);
}; };
void cb_btn_clearreq (GtkWidget *widget, gpointer data) { void cb_btn_clearreq (GtkWidget *widget, gpointer data) {
modbus.RequestsClear(); modbussrv.RequestsClear();
MBData_ReqReset (); MBData_ReqReset ();
}; };
@ -620,7 +624,7 @@ void cb_btn_enablevalues (GtkWidget *widget, gpointer data) {
break; break;
} }
modbus.Enable(atoi(v_fc), atoi(v_reg), Value_GetSize(v_type), 1); modbussrv.Enable(atoi(v_fc), atoi(v_reg), Value_GetSize(v_type), 1);
MBData_Enable(atoi(v_fc), atoi(v_reg), Value_GetSize(v_type), 1); MBData_Enable(atoi(v_fc), atoi(v_reg), Value_GetSize(v_type), 1);
if (v_name != NULL) free (v_name); if (v_name != NULL) free (v_name);
@ -721,9 +725,9 @@ void load_file(std::string fn) {
int autoadd = 0; int autoadd = 0;
modbus.EnableAll(0); modbussrv.EnableAll(0);
MBData_EnableAll(0); MBData_EnableAll(0);
modbus.RequestsClear(); modbussrv.RequestsClear();
MBData_ReqReset (); MBData_ReqReset ();
Value_DelAll(); Value_DelAll();
std::string confdata; std::string confdata;

@ -14,7 +14,7 @@
#include "guimodbusdata.h" #include "guimodbusdata.h"
#include "modbus.h" #include "modbus.h"
extern Modbus modbus; extern ModbusSrv modbussrv;
extern GtkBuilder *_builder_; // work around for threads extern GtkBuilder *_builder_; // work around for threads
void mbdata_enabletoggled_cb(GtkCellRendererToggle *cellrenderer, char *path, gpointer data); void mbdata_enabletoggled_cb(GtkCellRendererToggle *cellrenderer, char *path, gpointer data);
@ -45,7 +45,7 @@ GtkTreeModel *MBData_create_with_data() {
gtk_tree_store_set (store, &secondlevel, MBDATA_COL_FCREG, regname1.c_str(),-1); gtk_tree_store_set (store, &secondlevel, MBDATA_COL_FCREG, regname1.c_str(),-1);
} }
modbus.GetRegister(fc, regnum, &r); modbussrv.GetRegister(fc, regnum, &r);
regname2 = "FC" + std::to_string(fc) + " " + std::to_string(regnum); regname2 = "FC" + std::to_string(fc) + " " + std::to_string(regnum);
if (fc < 3) { if (fc < 3) {
if (r.value == 0) txt = "false"; if (r.value == 0) txt = "false";
@ -152,7 +152,7 @@ void mbdata_enabletoggled_cb(GtkCellRendererToggle *cellrenderer, char *path, gp
gtk_tree_store_set(GTK_TREE_STORE(model), &iter, gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
MBDATA_COL_ENABLED, enabled, MBDATA_COL_ENABLED, enabled,
-1); -1);
modbus.Enable(fc, reg, 1, enabled); modbussrv.Enable(fc, reg, 1, enabled);
g_free (fcreg); g_free (fcreg);
fcreg = NULL; fcreg = NULL;
} }

@ -19,7 +19,7 @@
#include "modbus.h" #include "modbus.h"
#include "guivalues.h" #include "guivalues.h"
void Value_ModStore(GtkTreeModel *model, GtkTreeIter *iter, GuiValue *g);
extern GtkBuilder *_builder_; // work around for threads extern GtkBuilder *_builder_; // work around for threads
GuiValue::GuiValue() { GuiValue::GuiValue() {
@ -233,7 +233,7 @@ gboolean Value_Loop(gpointer data) {
uint16_t regvals[4]; uint16_t regvals[4];
int regstowrite = 1; int regstowrite = 1;
if (Value_SetValue(v.value, v.type, v.fc, &regstowrite, regvals)) { if (Value_SetValue(v.value, v.type, v.fc, &regstowrite, regvals)) {
modbus.SetRegValue(v.fc, v.reg, regstowrite, (uint16_t*)regvals); modbussrv.SetRegValue(v.fc, v.reg, regstowrite, (uint16_t*)regvals);
} }
} }
@ -297,7 +297,7 @@ void Value_Add(GuiValue *g) {
Value_ModStore(model, &iter, g); Value_ModStore(model, &iter, g);
count = Value_GetSize(g->type); count = Value_GetSize(g->type);
modbus.Enable(g->fc, g->reg, count, 1); modbussrv.Enable(g->fc, g->reg, count, 1);
MBData_Enable(g->fc, g->reg, count, 1); MBData_Enable(g->fc, g->reg, count, 1);
} }

@ -1,107 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// main.cc is part of TestModbus-Server.
//
/////////////////////////////////////////////////////////////////////////////////
#include <sys/time.h>
#include "config.h"
#include "mbsconfig.h"
#include "gui.h"
#include "modbus.h"
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// global variables
//
Config config;
Modbus modbus;
GtkBuilder *_builder_ = NULL; // work around for the thread situation
uint16_t modbusdata[4][0x10000]; // needed for work with the gui will by synced by the modbus call back functions
gboolean modbus_callback(gpointer data);
int main (int argc, char **argv) {
GtkBuilder *builder;
GObject *window;
#ifdef BUILD_WINDOWS
char buffer[16];
setvbuf (stdout, buffer, _IONBF, 16);
#endif
printf ("TestModbus-Server - %s\n", VERSION);
printf (" https://steffen.gulpe.de/modbus-tcpip\n");
printf (" written by Steffen Pohle <steffen@gulpe.de>\n");
gtk_init (&argc, &argv);
_builder_ = builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, BUILDER_FILE, NULL);
gtk_builder_connect_signals(builder, builder);
//
// #if defined _WIN32 || defined _WIN64 || defined __CYGWIN__
// #else
// #endif
//
modbus.SetCallback(&modbus_callback);
window = gtk_builder_get_object (builder, "testmodbus-server");
gtk_widget_show_all (GTK_WIDGET(window));
if (argc == 2) {
printf ("Load File:%s\n", argv[1]);
config.SetFilename(argv[1]);
load_file(config.GetFilename());
}
else {
printf ("Load File:default.modbus\n");
config.SetFilename("default.modbus");
load_file(config.GetFilename());
}
gtk_main ();
return 0;
}
string to_hex16 (int v) {
char HEX[] = "0123456789ABCDEF";
int i = v;
int n;
string txt = "";
for (n = 0; n < 4; n++) {
txt = HEX[i%16]+ txt;
i = i / 16;
}
return txt;
}
gboolean modbus_callback(gpointer data) {
struct modbus_callback_data *mdata = (struct modbus_callback_data *) data;
MBData_ChangeRegs(mdata->fc, mdata->regstart, mdata->count, mdata->r);
Values_ChangeRegs(mdata->fc, mdata->regstart, mdata->count, mdata->r);
if (mdata->r) free (mdata->r);
free (mdata);
return FALSE;
};
float get_cycletime(struct timeval *t) {
struct timeval t1;
float f = 0.0;
t1 = *t;
gettimeofday(t, NULL);
f = (float)(t->tv_sec - t1.tv_sec) + ((t->tv_usec - t1.tv_usec) / 1000000.0);
return f;
}

@ -42,6 +42,6 @@ class Config {
// declared in main.cc // declared in main.cc
// //
extern Config config; extern Config config;
extern Modbus modbus; extern ModbusSrv modbussrv;
#endif #endif

@ -19,14 +19,14 @@
// //
// C / C++ Wrapper // C / C++ Wrapper
gpointer _ServerThread (gpointer data) { gpointer _ServerThread (gpointer data) {
modbus.ServerThread (); modbussrv.ServerThread ();
return NULL; return NULL;
}; };
// //
// //
Modbus::Modbus () { ModbusSrv::ModbusSrv () {
onchangecallback = NULL; onchangecallback = NULL;
ModbusRegister r = {0, false, 0, false}; ModbusRegister r = {0, false, 0, false};
port = 502; port = 502;
@ -44,7 +44,7 @@ Modbus::Modbus () {
} }
}; };
Modbus::~Modbus () { ModbusSrv::~ModbusSrv () {
for (int i = 0; i < MODBUS_MAXCLIENTS; i++) { for (int i = 0; i < MODBUS_MAXCLIENTS; i++) {
if (clients[i] != NULL) { if (clients[i] != NULL) {
delete clients[i]; delete clients[i];
@ -54,12 +54,12 @@ Modbus::~Modbus () {
}; };
int Modbus::isRunning() { int ModbusSrv::isRunning() {
return tcpserver.IsListen(); return tcpserver.IsListen();
}; };
int Modbus::Start(int serverport) { int ModbusSrv::Start(int serverport) {
port = serverport; port = serverport;
serverthread = g_thread_new("network thread", _ServerThread, NULL); serverthread = g_thread_new("network thread", _ServerThread, NULL);
@ -67,7 +67,7 @@ int Modbus::Start(int serverport) {
return 1; return 1;
}; };
void Modbus::Stop() { void ModbusSrv::Stop() {
g_mutex_lock(&servermutex); g_mutex_lock(&servermutex);
for (int i = 0; i < MODBUS_MAXCLIENTS; i++) { for (int i = 0; i < MODBUS_MAXCLIENTS; i++) {
if (clients[i] != NULL) { if (clients[i] != NULL) {
@ -80,7 +80,7 @@ void Modbus::Stop() {
}; };
void Modbus::CloseConnection(int slot) { void ModbusSrv::CloseConnection(int slot) {
if (slot < 0 || slot >= MODBUS_MAXCLIENTS) return; // slot out of bound if (slot < 0 || slot >= MODBUS_MAXCLIENTS) return; // slot out of bound
if (clients[slot] != NULL) if (clients[slot] != NULL)
delete clients[slot]; delete clients[slot];
@ -88,14 +88,14 @@ void Modbus::CloseConnection(int slot) {
}; };
void Modbus::SetCallback (gboolean (*callback_func)(gpointer data)) { void ModbusSrv::SetCallback (gboolean (*callback_func)(gpointer data)) {
onchangecallback = callback_func; onchangecallback = callback_func;
} }
/*************************************************************************************************** /***************************************************************************************************
* this should only be called from within the ServerThread function * this should only be called from within the ServerThread function
*/ */
void Modbus::ReadData(gpointer pdata) { void ModbusSrv::ReadData(gpointer pdata) {
int slot; int slot;
long int len; long int len;
@ -111,7 +111,7 @@ void Modbus::ReadData(gpointer pdata) {
}; };
void Modbus::ServerThread() { void ModbusSrv::ServerThread() {
int keep_running = 1; int keep_running = 1;
int ret; int ret;
struct timeval cycletimestamp = { 0 }; struct timeval cycletimestamp = { 0 };
@ -267,7 +267,7 @@ void Modbus::ServerThread() {
// return 0 on error // return 0 on error
int Modbus::WorkerAndEncodeRead(struct modbus_data *mbin, struct modbus_data *mbout) { int ModbusSrv::WorkerAndEncodeRead(struct modbus_data *mbin, struct modbus_data *mbout) {
// //
// to prevent race condition and invalid data: servermutex must be already locked // to prevent race condition and invalid data: servermutex must be already locked
// buffer on outdata must be of size 0x10000 // buffer on outdata must be of size 0x10000
@ -414,7 +414,7 @@ int Modbus::WorkerAndEncodeRead(struct modbus_data *mbin, struct modbus_data *mb
} }
int Modbus::WorkerAndEncodeWriteSingle(struct modbus_data *mbin, struct modbus_data *mbout) { int ModbusSrv::WorkerAndEncodeWriteSingle(struct modbus_data *mbin, struct modbus_data *mbout) {
uint16_t i16; uint16_t i16;
int pos = 0; int pos = 0;
int error = 0; int error = 0;
@ -510,7 +510,7 @@ int Modbus::WorkerAndEncodeWriteSingle(struct modbus_data *mbin, struct modbus_d
} }
int Modbus::WorkerAndEncodeWriteMulti(struct modbus_data *mbin, struct modbus_data *mbout) { int ModbusSrv::WorkerAndEncodeWriteMulti(struct modbus_data *mbin, struct modbus_data *mbout) {
uint16_t i16; uint16_t i16;
int pos = 0; int pos = 0;
int i; int i;
@ -628,7 +628,7 @@ int Modbus::WorkerAndEncodeWriteMulti(struct modbus_data *mbin, struct modbus_da
void Modbus::Decode(struct modbus_data *mbdata) { void ModbusSrv::Decode(struct modbus_data *mbdata) {
// //
uint16_t i16; uint16_t i16;
uint8_t i8; uint8_t i8;
@ -687,7 +687,7 @@ void Modbus::Decode(struct modbus_data *mbdata) {
mbdata->bytecnt = i8; mbdata->bytecnt = i8;
}; };
int Modbus::GetRegister(int fc, int regnum, ModbusRegister *r) { int ModbusSrv::GetRegister(int fc, int regnum, ModbusRegister *r) {
r->enabled = false; r->enabled = false;
r->requested = 0; r->requested = 0;
r->updated = false; r->updated = false;
@ -708,7 +708,7 @@ int Modbus::GetRegister(int fc, int regnum, ModbusRegister *r) {
}; };
int Modbus::GetRegisters(int fc, int regnum, int count, ModbusRegister *r) { int ModbusSrv::GetRegisters(int fc, int regnum, int count, ModbusRegister *r) {
r->enabled = false; r->enabled = false;
r->requested = 0; r->requested = 0;
r->updated = false; r->updated = false;
@ -729,7 +729,7 @@ int Modbus::GetRegisters(int fc, int regnum, int count, ModbusRegister *r) {
}; };
int Modbus::SetRegister(int fc, int regnum, ModbusRegister *r) { int ModbusSrv::SetRegister(int fc, int regnum, ModbusRegister *r) {
if (regnum < 0 || regnum >= 0x10000) return -1; if (regnum < 0 || regnum >= 0x10000) return -1;
g_mutex_lock(&servermutex); g_mutex_lock(&servermutex);
@ -745,7 +745,7 @@ int Modbus::SetRegister(int fc, int regnum, ModbusRegister *r) {
} }
int Modbus::SetRegisters(int fc, int regnum, int count, ModbusRegister *r) { int ModbusSrv::SetRegisters(int fc, int regnum, int count, ModbusRegister *r) {
int reg = regnum; int reg = regnum;
int regend = regnum+count; int regend = regnum+count;
@ -768,7 +768,7 @@ int Modbus::SetRegisters(int fc, int regnum, int count, ModbusRegister *r) {
} }
void Modbus::Enable(int fc, int regstart, int count, int onoff) { void ModbusSrv::Enable(int fc, int regstart, int count, int onoff) {
int i; int i;
if (fc < 1 || fc > 4) return; if (fc < 1 || fc > 4) return;
if (regstart < 0) return; if (regstart < 0) return;
@ -782,7 +782,7 @@ void Modbus::Enable(int fc, int regstart, int count, int onoff) {
}; };
void Modbus::RequestsClear() { void ModbusSrv::RequestsClear() {
int fc, reg; int fc, reg;
g_mutex_lock(&servermutex); g_mutex_lock(&servermutex);
@ -793,7 +793,7 @@ void Modbus::RequestsClear() {
}; };
void Modbus::EnableAll(int onoff) { void ModbusSrv::EnableAll(int onoff) {
int fc, reg; int fc, reg;
g_mutex_lock(&servermutex); g_mutex_lock(&servermutex);
@ -804,7 +804,7 @@ void Modbus::EnableAll(int onoff) {
}; };
void Modbus::SetRegValue(int fc, int regstart, int count, uint16_t *values) { void ModbusSrv::SetRegValue(int fc, int regstart, int count, uint16_t *values) {
int reg; int reg;
if (fc <= 0 || fc > 4) { if (fc <= 0 || fc > 4) {

@ -63,7 +63,7 @@ struct modbus_callback_data {
}; };
class Modbus { class ModbusSrv {
private: private:
TCP tcpserver; TCP tcpserver;
int port; int port;
@ -82,8 +82,8 @@ private:
int WorkerAndEncodeWriteSingle(struct modbus_data *mbin, struct modbus_data *mbout); int WorkerAndEncodeWriteSingle(struct modbus_data *mbin, struct modbus_data *mbout);
int WorkerAndEncodeWriteMulti(struct modbus_data *mbin, struct modbus_data *mbout); int WorkerAndEncodeWriteMulti(struct modbus_data *mbin, struct modbus_data *mbout);
public: public:
Modbus(); ModbusSrv();
~Modbus(); ~ModbusSrv();
void ServerThread(); void ServerThread();
void SetCallback (gboolean (*callback_func)(gpointer data)); void SetCallback (gboolean (*callback_func)(gpointer data));

Loading…
Cancel
Save