how to use libmodbus, using a makefile?

413 views Asked by At

Im working in a new project, and i need use modbus tcp/ip... the current project has already a makefile, the main problem is that i don't know how to edit the makefile to link the library.

Anyone can help me? please!

Hi! Im working in a new project, and i need use modbus tcp/ip... the current project has already a makefile, the main problem is that i don't know how to edit the makefile to link the library.

Anyone can help me? please! Hi! Im working in a new project, and i need use modbus tcp/ip... the current project has already a makefile, the main problem is that i don't know how to edit the makefile to link the library.

Anyone can help me? please!

this is the make file

#   Copyright © 2003 NOAO
#
#   Behzad Abareshi <[email protected]>
#   National Optical Astronomy Observatories
#   950 N Cherry Ave, Tucson AZ 85719, USA
#-------------------------------------------------------------------------------


#   Makefile
#   1 Jan 2002


#
#-------------------------------------------------------------------------------
CC = gcc

CFLAGS = -Wall -Winline -pedantic -std=gnu99
#CFLAGS += -Wshadow -Wbad-function-cast -Wcast-qual -Wwrite-strings -Wconversion
#CFLAGS += -Wsign-compare -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
#CFLAGS += -Wredundant-decls -Wnested-externs -Wunreachable-code
CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS += -Wredundant-decls -Wnested-externs
#CFLAGS += -Wunreachable-code

DEFS += -DHYDRA_TWO_NAMESPACE
DEFS += -DHYDRA_II_SPEEDY
DEFS += -DHYDRA_II_SPEEDY_LEVEL_2
DEFS += -DHYDRA_II_PROTOCOL

# special builds:
#
#DEFS += -DHYDRA_II_TEST_MODE
#DEFS += -DHYDRA_II_SLOW_MODE
# engineering:
#DEFS += -DHYDRA_II_TUNE_MODELS
#DEFS += -DHYDRA_II_TUNE_Z
#DEFS += -DHYDRA_II_TUNE_Z_NO_SANITY
#DEFS += -DHYDRA_II_TUNE_Z_PAUSE
#DEFS += -DHYDRA_II_TRACE_SKIP_Z_MOUNT_PROBLEM
#
# debug 8051 response time
#DEFS += -DDEBUG_8051_RESPONSE_TIME

ifeq ($(MODE),sim)
DEFS += -DHYDRA_II_SIMULATOR
DEFS += -DHYDRA_II_SIMULATOR_UNREAL_TIME
DEFS += -DHYDRA_II_SIMULATOR_FAKE_IT
endif

LIBROOT = libhydra2
STATIC_LIB = $(LIBROOT).a

CFLAGS += -fPIC
LIBVER = 1
LIBMV = 0
LIBRN = 1
SONAME = $(LIBROOT).so.$(LIBVER)
DYNAMIC_LIB = $(SONAME).$(LIBMV).$(LIBRN)
LIBFLAGS = -shared -Wl,-soname,$(SONAME) -o $(DYNAMIC_LIB) -lc

ifeq ($(STATIC),YES)
LIBS += -static
endif

LIBS += -L ./ -lhydra2 -lreadline -lncurses -lc -lm -ltermcap

ifeq ($(OPTIMIZED),YES)
CFLAGS += -O3
else
CFLAGS += -O0 -ggdb
endif

HDRS =  hydra_cli.h \
    hydra_cli_private.h \
    hydra_com.h \
    hydra_common.h \
    hydra_com_private.h \
    hydra_config.h \
    hydra_log.h \
    hydra_log_private.h \
    hydra_mc.h \
    hydra_mc_protected.h \
    hydra_mc_private.h \
    hydra_sim.h \
    hydra_sim_private.h \
    hydra_models.h \
    hydra_models_private.h \
    hydra_Tsensor.h \
    hydra_Tsensor_private.h \
    hydra_sleep.h \
    hydra_sleep_private.h \
    hydra_sm.h \
    hydra_sm_private.h \
    hydra_sm_protected.h \
    hydra_system.h \
    hydra_system_private.h \
    hydra_tools.h \
    hydra_tools_private.h \
    instruction_set.h \
    smart_motor.h \
    smart_motor_private.h \
    smart_motor_protected.h

SRCS =  hydra_sleep.c \
    hydra_log.c \
    hydra_com.c \
    smart_motor.c \
    hydra_tools.c \
    hydra_models.c \
    hydra_sm.c \
    hydra_Tsensor.c \
    hydra_mc.c \
    hydra_sim.c \
    hydra_cli.c \
    hydra_system.c

OBJS = $(SRCS:.c=.o) 


#
#-------------------------------------------------------------------------------
.c.o:
    $(CC) -c $(CFLAGS) $(DEFS) $(INCS) $<
.SUFFIXES: .c .o


#
#-------------------------------------------------------------------------------
TARGETS = hc hcli mc_test model_test system_test sensor_test
LIB_INST = $(HYDRA)/lib

ifeq ($(TYPE),package)
APP_INST = $(PACKAGE)/bin.base 
else
APP_INST = $(HYDRA)/bin.base 
endif

#
#-------------------------------------------------------------------------------
all: .build $(STATIC_LIB) $(TARGETS)

.build: $(SRCS) $(HDRS) Makefile
    @-rm -f *.o *.a
    perl -p -i -w -e 's/(BUILD_NUMBER\s\()(\d+)(\)\s)/$$1 . ($$2 + 1) . $$3/eg;' hydra_common.h
    touch .build

$(OBJS): .build

$(STATIC_LIB): $(OBJS)
    ar rcs $(STATIC_LIB) $(OBJS)

$(DYNAMIC_LIB): $(OBJS)
    $(CC) $(LIBFLAGS) $(OBJS)
    rm -f $(SONAME) $(LIBROOT).so
    ln -s $(DYNAMIC_LIB) $(SONAME)
    ln -s $(DYNAMIC_LIB) $(LIBROOT).so

hc: hc.o $(STATIC_LIB)
    $(CC) -o $@ $< $(LIBS)

hcli: hcli.o $(STATIC_LIB)
    $(CC) -o $@ $< $(LIBS)

mc_test: hydra_mc_test.o $(STATIC_LIB)
    $(CC) -o $@ $< $(LIBS)

system_test: hydra_system_test.o $(STATIC_LIB)
    $(CC) -o $@ $< $(LIBS)

model_test: hydra_models_test.o $(STATIC_LIB)
    $(CC) -o $@ $< $(LIBS)

sensor_test: hydra_Tsensor_test.o $(STATIC_LIB)
    $(CC) -o $@ $< $(LIBS)

clean:
    @-rm -f *.o *.a $(TARGETS) *.so* *log core* *~

install:
    install $(STATIC_LIB) $(LIB_INST)
ifeq ($(MODE),sim)
else
    install mc_test $(APP_INST)
    install hcli $(APP_INST)
endif

rml:
    @-rm -f *.log /tmp/*.LCK

BUILD := $(shell date +%H.%M.%S_%y.%h.%d)
TREE := $(shell basename `pwd`)

tar: clean
    @echo
    @echo "making tarball ..."
    @cd ..; tar czf $(BUILD)_$(TREE).tgz $(TREE)
    @echo "done!"

.PHONY: all install clean tar rml

And This is the code

/*
Copyright © 2004 NOAO

Behzad Abareshi <[email protected]>
National Optical Astronomy Observatories
950 N Cherry Ave, Tucson AZ 85719, USA
------------------------------------------------------------------------------*/


/*
**  hydra_com.c
**  13 Jan 2004 : Hydra II communication module.
**
*/


/*  headers
------------------------------------------------------------------------------*/
#include "hydra_com_private.h"
#include "/usr/local/include/modbus/modbus.h"
#include "/home/hydra/Downloads/libmodbus-3.1.6/tests/unit-test.h"
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

const int EXCEPTION_RC = 2;

enum {
    TCP,
    TCP_PI,
    RTU
};



int modbus(int argc, char *argv[])
{
const int NB_REPORT_SLAVE_ID = 10;
uint8_t *tab_rp_bits = NULL;
uint16_t *tab_rp_registers = NULL;
uint16_t *tab_rp_registers_bad = NULL;
modbus_t *ctx = NULL;
int i;
uint8_t value;
int nb_points;
int rc;
float real;
uint32_t old_response_to_sec;
uint32_t old_response_to_usec;
uint32_t new_response_to_sec;
uint32_t new_response_to_usec;
uint32_t old_byte_to_sec;
uint32_t old_byte_to_usec;
int use_backend;
int success = FALSE;
int old_slave;
ctx = modbus_new_tcp("192.168.1.40", 502);
modbus_set_debug(ctx, TRUE);
modbus_set_error_recovery(ctx,
                      MODBUS_ERROR_RECOVERY_LINK |
                      MODBUS_ERROR_RECOVERY_PROTOCOL);

if (use_backend == RTU) {
modbus_set_slave(ctx, SERVER_ID);
}

modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec);
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
modbus_get_response_timeout(ctx, &new_response_to_sec, &new_response_to_usec);

/* Allocate and initialize the memory to store the bits */
nb_points = (UT_BITS_NB > UT_INPUT_BITS_NB) ? UT_BITS_NB : UT_INPUT_BITS_NB;
tab_rp_bits = (uint8_t *) malloc(nb_points * sizeof(uint8_t));
memset(tab_rp_bits, 0, nb_points * sizeof(uint8_t));

/* Allocate and initialize the memory to store the registers */
nb_points = (UT_REGISTERS_NB > UT_INPUT_REGISTERS_NB) ?
UT_REGISTERS_NB : UT_INPUT_REGISTERS_NB;
tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t));
memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));

/** Read REGISTERS **/

rc = modbus_read_registers(ctx, 2000,1, tab_rp_registers);

/** Write REGISTERS **/
rc = modbus_write_register(ctx, 50, 110);

modbus_close(ctx);
modbus_free(ctx);
}
/*  globals 
------------------------------------------------------------------------------*/
char CL [HC_BUF_SIZE];
bool VERBOSE = false;

static Device device [HC_DEVICES_MAX];
static unsigned short device_count;
static unsigned char MODE;
static char msg [HC_BUF_SIZE];
static Log_Unit log_unit;


/*==============================================================================
**  broadcast
**
*/
int broadcast (char *cl, char *reply[])
{
    int rt_val = OK;
    unsigned short i;

    for (i = 0; i < device_count; ++i)
    {
        if (device[i].global_member && device[i].original)
        {
            char cmd [HC_BUF_SIZE];
            strcpy (cmd, cl);

            sprintf (msg, "[%s] broadcast on %s\n", cl, device[i].port);
            hc_log (VERBOSE ? 2 : 0, msg);

            if (MODE & REAL_COMMUNICATION)
            {
                if (talk (&device[i], cmd, reply) == ERR)
                {
                    sprintf (msg, "ERROR: broadcast to device %hu\n", device[i].id);
                    hc_log (2, msg);
                    rt_val = ERR;
                }
            }
            else
            {
                simulator (cmd, reply);
            }
        }
    }

    return rt_val;
}


/*==============================================================================
**  com_end
**
*/
int com_end (void)
{
    if (MODE & REAL_COMMUNICATION)
    {
        return ports_close();
    }

    return OK;
}


/*==============================================================================
**  com_init
**
*/
int com_init (const char *cfg_file, const char *end_char, unsigned short ms_timeout, unsigned char mode)
{
    unsigned short i;

    strcpy (log_unit.tag, "Hydra_com");

    if (log_init (&log_unit) == ERR)
    {
        fprintf (stderr, "%s\n", "hydra_com: FATAL: could not initiate logging");
        exit (ERR);
    }

    hc_log (VERBOSE ? 2 : 0, version());
    sprintf (msg, "PID: %d", getpid());
    hc_log (0, msg);

    MODE = mode; 
#ifdef HYDRA_II_SIMULATOR
    MODE = 0x00;
#endif

    rd_cfg (cfg_file);

    if (MODE & REAL_COMMUNICATION)
    {
        ports_open();
    }
    else
    {
        sim_init();
    }

    for (i = 0; i < device_count; ++i)
    {
        strcpy (device[i].end_char, end_char);
        device[i].ms_timeout = ms_timeout;

            sprintf (msg, "\n[%4hu] [%25s]  fd[%2d]  sa[%10lu]  original[%s]  global[%s]  strip[%s]\n",
                    device[i].id, device[i].port, device[i].fd, device[i].s_addr,
                    device[i].original ? "Y" : "N",
                    device[i].global_member ? "Y" : "N",
                    device[i].strip_id ? "Y" : "N");
            hc_log (VERBOSE ? 2 : 0, msg);
    }

    return OK;
}


/*==============================================================================
**  device_lock
**
*/
static int device_lock (Device *device)
{
    if (0 == device->s_addr)
    {
        char *base = strrchr (device->port, '/');
        sprintf (device->lock, "/tmp/%s.LCK", base ? base + 1 : device->port);
    }
    else
    {
        sprintf (device->lock, "/tmp/%lu.LCK", device->s_addr);
    }

    sprintf (msg, "creating lock [%s]\n", device->lock);
    hc_log (VERBOSE ? 2 : 0, msg);

    if (open (device->lock, O_RDWR | O_CREAT | O_EXCL , 0444) == ERR)
    {
        perror (device->lock);
        exit (ERR);
    }

    return OK;
} 


/*==============================================================================
**  device_unlock
**
*/
static int device_unlock (Device *device)
{
    sprintf (msg, "removing lock [%s]\n", device->lock);
    hc_log (VERBOSE ? 2 : 0, msg);

    if (access (device->lock, F_OK) == OK)
    {
        if (unlink (device->lock) == ERR) 
        {
            perror (device->lock);
            return ERR;
        }
    }
    else
    {
        perror (device->lock);
        return ERR;
    }

  return OK;
}


/*==============================================================================
**  get_cl
**
*/
int get_cl (const char *prompt)
{
    char *cl = (NULL == prompt) ?  readline ("> ") : readline (prompt);

    if (cl == NULL) return ERR;

    // account for null and optional end char
    if (strlen (cl) >= sizeof (CL) - 2)
    {
        hc_log (2, "ERROR: command too big: ignored\n");
        return ERR;
    }

    bzero (CL, sizeof (CL));
    strcpy (CL, cl);
    free (cl);

    // get rid of precdeing blanks
    cl = CL;
    while (isspace (*cl)) cl++;
    strcpy (CL, cl);

    if (*CL) add_history (CL);
    
    return OK;
}


/*==============================================================================
**  hc_log
**
*/
int hc_log (int pipe, char *msg)
{
    return log_it (&log_unit, pipe, msg);
}


/*==============================================================================
**  open_serial
**
*/
static int open_serial (Device *device)
{
    struct termios s_t;

    if ((device->fd = open (device->port, O_RDWR | O_NOCTTY)) == ERR)
    {
        perror (device->port);
        exit (ERR);
    }

    memset( &s_t, 0, sizeof( s_t ) );

    if (cfsetispeed (&s_t, B38400) == ERR)
    {
        perror (device->port);
        exit (ERR);
    }

    if (cfsetospeed (&s_t, B38400) == ERR)
    {
        perror (device->port);
        exit (ERR);
    }

    s_t.c_cflag |= (CS8 | CLOCAL | HUPCL | CREAD);

    // Critical for canonical communication.
    s_t.c_iflag &= ~(IGNCR);
    s_t.c_iflag |= ICRNL;

#ifdef NON_CANONICAL
    // Essential to make sure we capture all the characters
    // when reading responses.
    // NOTE: we could use 0 for both to make communication faster
    // and more efiicient, but then we have to carefully make the read
    // in talk() work in a loop and read until a newline is detected.
    // Note how we intentionally DO NOT ignore CR and convert it to NL.
    s_t.c_cc [VMIN]  = 16;
    s_t.c_cc [VTIME] = 1;
#else
    s_t.c_lflag |= ICANON;
#endif
// NON_CANONICAL

    if (tcsetattr (device->fd, TCSANOW, &s_t) == ERR)
    {
        perror (device->port);
        exit (ERR);
    }

    if (tcflush (device->fd, TCIOFLUSH) == ERR)
    {
        perror (device->port);
        exit (ERR);
    }

    return OK;
}


/*==============================================================================
**  open_socket 
**
*/
static int open_socket (Device *device)
{
    size_t adr_len;
    int fd = socket (AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in adr;

    adr.sin_addr.s_addr = device->s_addr;
    adr.sin_family = AF_INET;
    adr.sin_port = htons (HC_ISERVER_PORT);
    adr_len = sizeof(adr);

}
0

There are 0 answers