我在一个新项目中工作,我需要使用 modbus tcp/ip ...当前项目已经有一个 makefile,主要问题是我不知道如何编辑 makefile 以链接库。
任何人都可以帮助我吗?请!
你好!我在一个新项目中工作,我需要使用 modbus tcp/ip ...当前项目已经有一个 makefile,主要问题是我不知道如何编辑 makefile 以链接库。
任何人都可以帮助我吗?请!你好!我在一个新项目中工作,我需要使用 modbus tcp/ip ...当前项目已经有一个 makefile,主要问题是我不知道如何编辑 makefile 以链接库。
任何人都可以帮助我吗?请!
这是制作文件
# Copyright © 2003 NOAO
#
# Behzad Abareshi <behzad@noao.edu>
# 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
这是代码
/*
Copyright © 2004 NOAO
Behzad Abareshi <behzad@noao.edu>
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);
}