コード例 #1
0
ファイル: mbrtud.c プロジェクト: Telegea/Smartbox-software
/*
 * 
 * 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;
}
コード例 #2
0
ファイル: modbus_read.c プロジェクト: obedouet/socomec-diris
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;
}