/* * * MAIN process * */ int main(int argc, char* argv[]) { char serial_port[32] = SERIAL_PORT_PREFIX; int baud_rate; int num_slaves; int i, k; if ((argc < 6) || ((argc>6) && (argc<NUM_REG_PER_SLAVE+5))) { printf("Usage:\n\n"); printf(" Single slave (passthrough) mode:\n"); printf(" mbrtud <serial dev> <baudrate> <num_regs> <reg_offset> <slave addr>\n"); printf(" serial dev: name of the serial device used for connection to the Modbus converter (e.g. USB0 or S0)\n"); printf(" baudrate: baudrate used for serial connection\n"); printf(" num_regs: number of consecutive registers to read\n"); printf(" reg_offset: register address offset to add for slave request\n"); printf(" slave addr: address of Modbus slave device\n\n"); printf(" Multiple slave (register mapping) mode:\n"); printf(" mbrtud <serial dev> <baudrate> <num_regs> <reg 1> ... <reg %d> <slave addr> [<slave addr> ...]\n", NUM_REG_PER_SLAVE); printf(" serial dev: name of the serial device used for connection to the Modbus converter (e.g. USB0 or S0)\n"); printf(" baudrate: baudrate used for serial connection\n"); printf(" num_regs: number of consecutive registers to read\n"); printf(" reg x: register map to use for slave request\n"); printf(" slave addr: address of Modbus slave devices (up to %d)\n", MAX_SLAVES); return 0; } openlog("mbrtud", LOG_PID|LOG_CONS, LOG_USER); syslog(LOG_DAEMON | LOG_NOTICE, "Starting Modbus RTU daemon (version %s)\n", VERSION); /* Install signal handler for SIGTERM and SIGINT ("CTRL C") to be used to terminate */ signal(SIGTERM, doExit); signal(SIGINT, doExit); /* Get input parameters */ i=1; strcat(serial_port, argv[i++]); baud_rate = atoi(argv[i++]); num_regs = atoi(argv[i++]); if (argc == 6) { /* Single slave (passthrough) mode */ mode=MODE_SINGLESLAVE; reg_offset = atoi(argv[i++]); slave_addr_table[0] = atoi(argv[i++]); } else { /* Multiple slave (register mapping) mode */ mode=MODE_MULTISLAVE; for (k=0; (i<argc)&&(k<NUM_REG_PER_SLAVE); i++, k++) custom_reg_table[k] = atoi(argv[i]); memset(slave_addr_table, 0, sizeof(slave_addr_table)); for (k=0; (i<argc)&&(k<MAX_SLAVES); i++, k++) slave_addr_table[k] = atoi(argv[i]); num_slaves = k; } /* Init the Modbus RTU connection */ mb = modbus_new_rtu(serial_port, baud_rate, 'N', 8, 1); if (mb == NULL) { syslog(LOG_DAEMON | LOG_ERR, "Unable to create RTU485 context\n"); modbus_free(mb); return 1; } if (modbus_connect(mb) == -1) { syslog(LOG_DAEMON | LOG_ERR, "Connection failed: %s\n", modbus_strerror(errno)); return 2; } /* Set Modbus timeouts */ modbus_set_response_timeout(mb, 20, 0); modbus_set_byte_timeout(mb, 1, 0); /* Specific setting for direction control of the RS485 transceiver */ if (strstr(serial_port, "USB") == NULL) { /* Enable RS485 direction control via RTS line */ if (modbus_rtu_set_rts(mb, MODBUS_RTU_RTS_DOWN) == -1) { syslog(LOG_DAEMON | LOG_ERR, "Setting RTS mode failed: %s\n", modbus_strerror(errno)); modbus_free(mb); return 3; } /* Set RTS control delay (before and after transmission) */ if (DEFAULT_RTS_DELAY > 0) { if (modbus_rtu_set_rts_delay(mb, DEFAULT_RTS_DELAY) == -1) { syslog(LOG_DAEMON | LOG_ERR, "Setting RTS delay failed: %s\n", modbus_strerror(errno)); modbus_free(mb); return 4; } } syslog(LOG_DAEMON | LOG_NOTICE, "using direction control via RTS line"); } //modbus_set_debug(mb, TRUE); syslog(LOG_DAEMON | LOG_NOTICE, "Using Modbus connection on serial port %s at %dbaud", serial_port, baud_rate); if (mode == MODE_SINGLESLAVE) { syslog(LOG_DAEMON | LOG_NOTICE, "Single slave mode - slave address: %d", slave_addr_table[0]); } else { syslog(LOG_DAEMON | LOG_NOTICE, "Multiple slave mode - register map for each slave:"); syslog(LOG_DAEMON | LOG_NOTICE, " Reg | Id "); syslog(LOG_DAEMON | LOG_NOTICE, " ---------"); for (i=0; i<NUM_REG_PER_SLAVE; i++) syslog(LOG_DAEMON | LOG_NOTICE, " %02d | %02d", i+1, custom_reg_table[i]); syslog(LOG_DAEMON | LOG_NOTICE, "List of slaves:"); for (i=0; i<num_slaves; i++) syslog(LOG_DAEMON | LOG_NOTICE, " slave %d: %d (regs[%d...%d])\n", i+1, slave_addr_table[i], i*NUM_REG_PER_SLAVE+1, i*NUM_REG_PER_SLAVE+NUM_REG_PER_SLAVE); } /* Start Modbus TCP server loop */ modbustcp_server(MODBUS_SLAVE_ADDRESS, // Modbus slave address read_register_handler, // Read register handler write_register_handler // Write register handler ); return 0; }
int main(int argc, char *argv[]) { modbus_t *diris; int code; char errmsg[255]; FILE *f_lock; uint16_t tab_reg[64]; int i; int debug=0; if (argc==1) { fprintf(stderr,"Usage: %s <reg>\n", argv[0]); exit(1); } /* Lock file */ srandom(time(NULL)); i=0; f_lock=fopen("/var/run/modbus.lck","r"); while (i < 4 && f_lock>0) { fclose(f_lock); usleep(500000*random()%10); i++; f_lock=fopen("/var/run/modbus.lck","r"); } if (i==4) { fprintf(stderr, "Lock timeout\n"); exit(1); } if (f_lock<0) { f_lock=fopen("/var/run/modbus.lck","a"); fputs("modbus",f_lock); fclose(f_lock); } /* Open Serial Device */ diris=modbus_new_rtu("/dev/ttyUSB0", 9600, 'O', 8, 1); if (diris == NULL) { fprintf(stderr, "Unable to create the libmodbus context\n"); unlink("/var/run/modbus.lck"); return 1; } /* Prepare to connect to Slave */ code=modbus_set_slave(diris, 5); if(code <0) { perror(errmsg); fprintf(stderr,"Set slave error: %s\n",errmsg); unlink("/var/run/modbus.lck"); return 1; } if (debug) modbus_set_debug(diris, 1); if (debug) { /* Check Serial Mode */ code=modbus_rtu_get_serial_mode(diris); if (code=MODBUS_RTU_RS485) { printf("Mode: RS485\n"); } else { printf("Mode: RS232\n"); } } if (debug) { /* Check RTS Mode */ code=modbus_rtu_get_rts(diris); switch(code) { case MODBUS_RTU_RTS_NONE: printf("RTS: None\n"); break; case MODBUS_RTU_RTS_UP: printf("RTS: Up\n"); break; case MODBUS_RTU_RTS_DOWN: printf("RTS: Down\n"); break; default: printf("RTS: Unknown\n"); } printf("RTS: %d\n", code); } /* Change RTS Mode */ modbus_rtu_set_rts(diris, MODBUS_RTU_RTS_UP); if (debug) { code=modbus_rtu_get_rts(diris); switch(code) { case MODBUS_RTU_RTS_NONE: printf("RTS: None\n"); break; case MODBUS_RTU_RTS_UP: printf("RTS: Up\n"); break; case MODBUS_RTU_RTS_DOWN: printf("RTS: Down\n"); break; default: printf("RTS: Unknown\n"); } printf("RTS: %d\n", code); } /* Initiate connect (nothing to do in serial mode) */ if (modbus_connect(diris) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(diris); unlink("/var/run/modbus.lck"); return -1; } if (debug) {printf("Connect OK\n");} /* Do the read */ if (debug) { printf("Reading %s\n", argv[1]); } /* int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest); */ code = modbus_read_registers(diris, atoi(argv[1]), 2, tab_reg); if (code == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); modbus_close(diris); modbus_free(diris); unlink("/var/run/modbus.lck"); return -1; } /* Display Value returned */ /*for (i=0; i < code; i++) { printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); } */ if (code==2) { printf("%d\n", tab_reg[1]); } /*printf("Reset IMax\n"); code=modbus_write_register(diris, 1024, 1); if (code == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); modbus_close(diris); modbus_free(diris); return -1; }*/ /* Close */ modbus_close(diris); modbus_free(diris); unlink("/var/run/modbus.lck"); return 0; }