This cpp source file is generated by pvdevelop.
It is derived from the modbus ini-file.
This is the daemon that will read modbus cyclically and write to shared memory.
Also it will wait on the mailbox for output messages.

//
// Modbus daemon template                                 (C) R. Lehrig 2003
//
//
// Attention: this program must be run as super user
//

#include <stdio.h>
#include <stdlib.h>
#include "rlmodbus.h"
#include "rlsharedmemory.h"
#include "rlmailbox.h"
#include "rlthread.h"
#include "rlcutil.h"

#define MODBUS_IDLETIME (4*1000)/96
#define SERIAL_DEVICE   "/dev/ttyS0"
rlModbus       modbus(256+1,rlModbus::MODBUS_RTU);
rlSerial       serial;
rlSharedMemory shm("/srv/automation/shm/modbus.shm",2);
rlMailbox      mbx("/srv/automation/mbx/modbus.mbx");
rlThread       thread;
rlThread       watchdog;

// watchdog
static char *av0 = "";
static int watchcnt1 = 0;
void *watchdogthread(void *arg)
{
  int cnt1 = -1;

  while(1)
  {
    rlsleep(5000);
    if(cnt1 == watchcnt1) break;
    cnt1 = watchcnt1;
  }
  serial.closeDevice();
  rlsleep(100);
#ifdef unix
  rlexec(av0);
#endif
  exit(0); // pcontrol may start me again if rlexec fails
  return arg;
}

// read mailbox and write to modbus
void *reader(void *arg)
{
  int ret,slave,function,buflen;
  unsigned char buf[256+1];

  mbx.clear(); // clear old messages
  while((buflen = mbx.read(buf,sizeof(buf))) > 0)
  {
    slave        = buf[0];
    function     = buf[1];
    thread.lock();
    rlsleep(MODBUS_IDLETIME);
    ret = modbus.write( slave, function, &buf[2], buflen-2);
    ret = modbus.response( &slave, &function, buf);
    rlsleep(MODBUS_IDLETIME);
    thread.unlock();
    printf("mbx ret=%d slave=%d function=%d buf[2]=%d\n",ret,slave,function,buf[2]);
  }
  return arg;
}

// read cycle on modbus
int modbusCycle(int offset, int slave, int function, int start_adr, int num_register)
{
  unsigned char data[256+1];
  int ret;

  watchcnt1++;
  if(watchcnt1 > 10000) watchcnt1 = 0;
  rlsleep(MODBUS_IDLETIME);
  thread.lock();
  ret = modbus.request(slave, function, start_adr, num_register);
  if(ret >= 0) ret = modbus.response( &slave, &function, data);
  thread.unlock();
  if(ret > 0) shm.write(offset,data,ret);
  printf("cycle ret=%d slave=%d function=%d data[0]=%d\n",ret,slave,function,data[0]);
  return ret;
}

int main(int ac, char **av)
{
  int offset,ret,first;
  if(ac > 0) av0 = av[0];
  first = 1;
  while(serial.openDevice(SERIAL_DEVICE,B9600,1,1,8,1,rlSerial::NONE) < 0)
  {
    if(first==1) printf("could not open serial device %s\n",SERIAL_DEVICE);
    first = 0;
    rlsleep(1000);
  }
  printf("\n%s starting\n",av0);
  modbus.registerSerial(&serial);
  thread.create(reader,NULL);
  watchdog.create(watchdogthread,NULL);

  while(1)
  {
    offset = 0;
    //    modbusCycle(offset, slave, function, start_adr, num_register);
    ret = modbusCycle(offset,1,2,0,10);
    if(ret>0) offset += ret; else continue;
  }

  // we will never come here
  serial.closeDevice();
  return 0;
}