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 <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
And This is the code
/*
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);
}
Related
I'm trying to send data (IP address) from the kernel space to the user space, by running the following BPF prorgam:
struct bpf_map_def EVENTS = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(__u32),
.value_size = sizeof(__u32),
.max_entries = 1,
};
SEC("xdp")
int _xdp_ip_filter(struct xdp_md *ctx) {
bpf_printk("got a packet\n");
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
// check packet size
if (eth + 1 > data_end) {
return XDP_PASS;
}
// get the source address of the packet
struct iphdr *iph = data + sizeof(struct ethhdr);
if (iph + 1 > data_end) {
return XDP_PASS;
}
__u32 ip_src = iph->saddr;
bpf_printk("source ip address is %u\n", ip_src);
// key of the maps
__u32 key = 0;
bpf_printk("starting xdp ip filter\n");
// send the ip to the userspace program.
bpf_map_update_elem(&EVENTS, &key, &ip_src, BPF_ANY);
return XDP_PASS;
}
Makefile:
CLANG ?= clang
LLC ?= llc
OPT ?= opt
DIS ?= llvm-dis
ARCH ?= $(shell uname -m | sed -e 's/aarch64/arm64/' -e 's/x86_64/x86/')
KERNEL ?= /usr/src/linux
CFLAGS += \
-O2 -g -emit-llvm \
-D__KERNEL__ \
-D__BPF_TRACING__ \
-Wno-unused-value \
-Wno-pointer-sign \
-Wno-compare-distinct-pointer-types \
-Wno-address-of-packed-member \
-Wno-tautological-compare \
-Wno-unknown-warning-option \
-Wno-gnu-variable-sized-type-not-at-end \
-fno-asynchronous-unwind-tables
bytecode.$(ARCH).o: bytecode.c
$(CLANG) $(CFLAGS) -c $< -o - | \
$(OPT) -O2 -mtriple=bpf-pc-linux | \
$(DIS) | \
$(LLC) -march=bpf $(LLC_FLAGS) -filetype=obj -o $#
However I keep getting the following err:
58: (85) call bpf_map_update_elem#2
R1 type=map_value expected=map_ptr
verification time 272 usec
Can anyone help me understand this error? In addition where can I see the bpf_printk messages?
I suspect the file generated by make does not include the EVENTS map.. But am not sure how to fix it - if I add a SEC("maps") above the map the kernel verifier does fails to locate the section at all..
You are missing:
SEC("maps") in the map declaration (as you had guessed).
The license declaration.
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <bpf/bpf_helpers.h>
struct bpf_map_def SEC("maps") EVENTS = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(__u32),
.value_size = sizeof(__u32),
.max_entries = 1,
};
SEC("xdp")
int _xdp_ip_filter(struct xdp_md *ctx) {
bpf_printk("got a packet\n");
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
// check packet size
if (eth + 1 > data_end) {
return XDP_PASS;
}
// get the source address of the packet
struct iphdr *iph = data + sizeof(struct ethhdr);
if (iph + 1 > data_end) {
return XDP_PASS;
}
__u32 ip_src = iph->saddr;
bpf_printk("source ip address is %u\n", ip_src);
// key of the maps
__u32 key = 0;
bpf_printk("starting xdp ip filter\n");
// send the ip to the userspace program.
bpf_map_update_elem(&EVENTS, &key, &ip_src, BPF_ANY);
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
I was able to load and attach with:
make
sudo ip link set dev wlp59s0 xdp obj ./bytecode.o sec xdp
I am using Yocto project cross-compiler to compile my C code.
But for some reasons I have compilation errors.
This is my C code :
#include <stdio.h>
#include <stdlib.h>
#include "/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa.hpp"
/* MRAA does not yet understand GPIO-A - GPIO-L */
/* Linaro will add this */
/* What Mraa does understand is pin out numbers so, */
/* pin 23 is GPIO-A and pin 25 is GPIO-C */
#define LED 10
#define BUTTON 29
bool running = true;
bool led_state = false;
int last_touch;
void sig_handler(int signo)
{
if (signo == SIGINT)
running = false;
}
int main(int argc, char* argv[])
{
mraa::Result ret;
int touch;
mraa::Gpio* touch_gpio = new mraa::Gpio(BUTTON);
if (touch_gpio == NULL){
return mraa::ERROR_UNSPECIFIED;
}
mraa::Gpio* led_gpio = new mraa::Gpio(LED);
if (led_gpio == NULL){
return mraa::ERROR_UNSPECIFIED;
}
signal(SIGINT, sig_handler);
if ((ret = touch_gpio->dir(mraa::DIR_IN))!= mraa::SUCCESS){
return ret;
}
if ((ret = led_gpio->dir(mraa::DIR_OUT))!= mraa::SUCCESS){
return ret;
}
led_gpio->write(led_state);
while (running) {
touch = touch_gpio->read();
if (touch == 1 && last_touch == 0) {
led_state = !led_state;
ret = led_gpio->write(led_state);
usleep(100000);
}
last_touch = touch;
usleep(1);
}
delete led_gpio;
delete touch_gpio;
return ret;
}
This is the Makefile :
#CC=arm-poky-linux-gnueabi-gcc -march=armv7-a -marm -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a5 --sysroot=/opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi
#CC="gcc"
all: last1.o
${CC} last1.o -o target_bin -lmraa
last1.o: last1.c
${CC} -I . -c last1.c
clean:
rm -rf *.o
rm target_bin
And this is what I get when i run make all :
In file included from
/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa/common.hpp:28:0,
from /home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa.hpp:27,
from last1.c:4:
/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa/types.hpp:32:1:
error: unknown type name ‘namespace’ namespace mraa ^~~~~~~~~
/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa/types.hpp:33:1:
error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘{’
token { ^
In file included from
/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa.hpp:27:0,
from last1.c:4: /home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa/common.hpp:29:10:
fatal error: string: No such file or directory #include
^~~~~~~~
compilation terminated. Makefile:8: recipe for target 'last1.o' failed
make: *** [last1.o] Error 1
You are compiling your code written in C with a C++ compiler.
Just change your .c files to .cpp files, and compile using g++ rather than gcc if you are on Unix systems.
I'm developing a custom file system with fuse. What I want to do is to read contents of a directory from remote server and list them in mount point. My rpc program run solely well. but when I try to combine it with rpc it got some build error. I'm using rpcgen to create my rpc program but I don't know how exactly I should build them together.
this is my cfs_client.c :
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos#szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
gcc -Wall cfs.c `pkg-config fuse --cflags --libs` -o cfs
*/
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "cfs.h"
static const char *cfs_str = "Hello World!\n";
static const char *cfs_path = "/cfs";
static int cfs_getattr(const char *path, struct stat *stbuf) {
int res = 0;
memset(stbuf, 0, sizeof (struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path, cfs_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(cfs_str);
} else
res = -ENOENT;
return res;
}
static int cfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi) {
(void) offset;
(void) fi;
char *host = "localhost";
char *dirname = "/home/hamed/test";
CLIENT *clnt;
readdir_res *result_1;
if (strcmp(path, "/") != 0)
return -ENOENT;
#ifndef DEBUG
clnt = clnt_create(host, CFSPROG, CFSVERS, "udp");
if (clnt == NULL) {
clnt_pcreateerror(host);
exit(1);
}
#endif /* DEBUG */
result_1 = readdir_1(&dirname, clnt);
if (result_1 == (readdir_res *) NULL) {
clnt_perror(clnt, "call failed");
}
namelist nl;
nl = result_1->readdir_res_u.list;
while (nl) {
printf("dirname = %s\n", nl->name);
filler(buf, nl->name, NULL, 0);
nl = nl->next;
}
#ifndef DEBUG
clnt_destroy(clnt);
#endif /* DEBUG */
return 0;
}
static int cfs_open(const char *path, struct fuse_file_info *fi) {
if (strcmp(path, cfs_path) != 0)
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
return -EACCES;
return 0;
}
static int cfs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi) {
size_t len;
(void) fi;
if (strcmp(path, cfs_path) != 0)
return -ENOENT;
len = strlen(cfs_str);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, cfs_str + offset, size);
} else
size = 0;
return size;
}
static struct fuse_operations cfs_oper = {
.getattr = cfs_getattr,
.readdir = cfs_readdir,
.open = cfs_open,
.read = cfs_read,
};
int main(int argc, char *argv[]) {
return fuse_main(argc, argv, &cfs_oper, NULL);
}
here is my cfs_server.c :
/*
* This is sample code generated by rpcgen.
* These are only templates and you can use them
* as a guideline for developing your own functions.
*/
#include "cfs.h"
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <rpc/pmap_clnt.h>
readdir_res * readdir_1_svc(nametype *dirname, struct svc_req *rqstp) {
DIR *dp;
struct dirent *directory;
static readdir_res result;
int inode;
namelist nl;
namelist *nlp;
dp = opendir(*dirname);
if (dp != NULL) {
nlp = &result.readdir_res_u.list;
while (directory = readdir(dp)) {
nl = *nlp = (namenode *) malloc(sizeof (namenode));
nl->name = directory->d_name;
nlp = &nl->next;
}
}
*nlp = NULL;
result.errnum = 0;
closedir(dp);
return &result;
}
and this is make file that I useed :
# This is a template Makefile generated by rpcgen
# Parameters
CLIENT = cfs_client
SERVER = cfs_server
SOURCES_CLNT.c =
SOURCES_CLNT.h =
SOURCES_SVC.c =
SOURCES_SVC.h =
SOURCES.x = cfs.x
TARGETS_SVC.c = cfs_svc.c cfs_server.c cfs_xdr.c
TARGETS_CLNT.c = cfs_clnt.c cfs_client.c cfs_xdr.c
TARGETS = cfs.h cfs_xdr.c cfs_clnt.c cfs_svc.c cfs_client.c cfs_server.c
OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)
OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)
# Compiler flags
CFLAGS += -g -Wall -DRPC_SVC_FG $(shell pkg-config fuse --cflags --libs)
LDLIBS += -lnsl
RPCGENFLAGS = -g
# Targets
all : $(CLIENT) $(SERVER)
$(TARGETS) : $(SOURCES.x)
rpcgen $(RPCGENFLAGS) $(SOURCES.x)
$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c)
$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c)
$(CLIENT) : $(OBJECTS_CLNT)
$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)
$(SERVER) : $(OBJECTS_SVC)
$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)
clean:
$(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER)
edit :
error is :
root#debian:/programs/c/rpc/custom file system# make -f Makefile.cfs
rpcgen -g cfs.x
usage: rpcgen infile
rpcgen [-abkCLNTM][-Dname[=value]] [-i size] [-I [-K seconds]] [-Y path] infile
rpcgen [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] [-o outfile] [infile]
rpcgen [-s nettype]* [-o outfile] [infile]
rpcgen [-n netid]* [-o outfile] [infile]
options:
-a generate all files, including samples
-b backward compatibility mode (generates code for SunOS 4.1)
-c generate XDR routines
-C ANSI C mode
-Dname[=value] define a symbol (same as #define)
-h generate header file
-i size size at which to start generating inline code
-I generate code for inetd support in server (for SunOS 4.1)
-K seconds server exits after K seconds of inactivity
-l generate client side stubs
-L server errors will be printed to syslog
-m generate server side stubs
-M generate MT-safe code
-n netid generate server code that supports named netid
-N supports multiple arguments and call-by-value
-o outfile name of the output file
-s nettype generate server code that supports named nettype
-Sc generate sample client code that uses remote procedures
-Ss generate sample server code that defines remote procedures
-Sm generate makefile template
-t generate RPC dispatch table
-T generate code to support RPC dispatch tables
-Y path directory name to find C preprocessor (cpp)
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
make: *** [cfs_clnt.c] Error 1
I've solved my problem by using a bash file. This is my script for those who may have same problem as mine :
cc -g -c -o cfs_clnt.o cfs_clnt.c
cc -g -D_FILE_OFFSET_BITS=64 -c -o cfs_client.o cfs_client.c
cc -g -c -o cfs_xdr.o cfs_xdr.c
cc -g -o cfs_client cfs_clnt.o cfs_client.o cfs_xdr.o -lnsl -Wall `pkg-config fuse --cflags --libs`
cc -g -c -o cfs_svc.o cfs_svc.c
cc -g -c -o cfs_server.o cfs_server.c
cc -g -o cfs_server cfs_svc.o cfs_server.o cfs_xdr.o -lnsl
I have to compile two independent processes-sendfdsock.c and recvfdsock.c using make file. Both the files have there own main function. This means they are independent and I have to compile them as two different binaries. This is my make file:
compileAll:sendfdsock recvfdsock
sendfdsock:sendfdsock.o
gcc -o sendfdsock sendfdsock.o
sendfdsock.o:sendfdsock.c accessories.h
gcc -c sendfdsock.c
recvfdsock.o:recvfdsock.c accessories.h
gcc -c recvfdsock.c
recvfdsock:recvfdsock.o
gcc -o recvfdsock recvfdsock.o
Here I have made a compileAll target which compiles both the files.
Both files need to use accessories.h. As mention in GNU Make Doc - A simple Make file. I wrote this make file.
accessories.h :
#include <malloc.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <error.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <stropts.h>
#define PORT "4444" //port we are listening on
int sendall(int fd, char *buf, int *len);
int recvall(int fd, char *buf, int *len);
void logp(int typ, char* msg);
void errorp(char *where, int boolean, int errn,char *what);
accessories.c :
#include "accessories.h"
void logp(int typ, char* msg) // typ --> type(category) of message [1-Normal Log, 2-Warning(any unexpected thing happened), 3-Error, 4-Debugging Log ]
{
int fd;
time_t now;
ssize_t wlength=0;
char * dat;
char * str;
int size = 45+strlen(msg);//14+24+5+sizeof msg+1
str= (char *) malloc(size);
time(&now);//system time in seconds
dat = ctime(&now); // converting seconds to date-time format
dat = strtok(dat,"\n");
//Appending type of log
switch(typ)
{
case 1:
strcpy(str,"__LOG__ | ");
strcat(str,dat);
break;
case 2:
strcpy(str,"__WARN__ | ");
strcat(str,dat);
break;
case 3:
strcpy(str,"__ERR__ | ");
strcat(str,dat);
break;
case 4:
strcpy(str,"__DEBUG__ | ");
strcat(str,dat);
break;
default:
strcpy(str,"__UNDEF__ | ");
strcat(str,dat);
break;
}
strcat(str," | ");
strcat(str,msg);//appending message
strcat(str,"\n");
fd = open("log", O_WRONLY | O_CREAT | O_APPEND, 0644); // should be opened somewhere else
if (fd == -1)
printf("Could not open log - %s\n",strerror(errno));
else
{//need to add lock to the file and printing error message
while ( wlength < strlen(str) )
{
wlength = write(fd, str,strlen(str));
if (wlength == -1)
{
printf("Error : writing log\n");
break;
}
}
}
}
int sendall(int fd, char *buf, int *len)
{
int total = 0; // how many bytes we've sent
int bytesleft = *len; // how many we have left to send
int n;
while(total < *len) {
n = send(fd, buf+total, bytesleft, 0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}
*len = total; // return number actually sent here
return n==-1?-1:0; // return -1 on failure, 0 on success
}
int recvall(int fd, char *buf, int *len)
{
int total = 0; // how many bytes we've sent
int bytesleft = *len; // how many we have left to send
int n;
while(total < *len) {
n = recv(fd, buf+total, bytesleft, 0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}
*len = total; // return number actually sent here
return n==-1?-1:0; // return -1 on failure, 0 on success
}
void errorp(char *where, int boolean, int errn,char *what)
{
char errmsg[21+strlen(where)];
strcpy(errmsg,"Where - ");
strcat(errmsg,where);
strcat(errmsg," | Error - ");
if(boolean == 1)//we got error number
{
strcat(errmsg,strerror(errn));
//fprintf(stderr,"ERROR - In %s and error is %s\n",where ,strerror(errn));
logp(3,errmsg);
}
else if(boolean == 0)//we got a message
{
strcat(errmsg,what);
//fprintf(stderr,"ERROR - In %s and error is %s\n",where ,what);
logp(3,errmsg);
}
else//we got nothing
{
strcat(errmsg,"No Message");
//fprintf(stderr,"ERROR - In %s\n",where);
logp(3,errmsg);
}
}
Initially everything work fine but when I trid to use any function which is defined in accessories.c compilation give me error.
For example I use the log function in sendfdsock.c :
#include "accessories.h"
#define CONTROLLEN CMSG_LEN(sizeof(int))
static struct cmsghdr *cmptr = NULL; /* malloc'ed first time */
int send_err(int fd, int errcode, const char *msg);
int send_fd(int fd, int fd_to_send);
int main(int argc, char const *argv[])
{
logp(1,"started"); //This function is defined in accessories.c
int fd_to_send;
if((fd_to_send = open("vi",O_RDONLY)) < 0)
printf("vi open failed");
struct sockaddr_un address;
int socket_fd, nbytes;
char buffer[256];
........
Output of the compilation is:
abhi#abhi-me:~/bridge/server$ make compileAll
gcc -c sendfdsock.c
sendfdsock.c: In function ‘send_fd’:
sendfdsock.c:111:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘ssize_t’ [-Wformat]
sendfdsock.c:114:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘ssize_t’ [-Wformat]
gcc -o sendfdsock sendfdsock.o
sendfdsock.o: In function `main':
sendfdsock.c:(.text+0x32): undefined reference to `logp'
collect2: ld returned 1 exit status
make: *** [sendfdsock] Error 1
abhi#abhi-me:~/bridge/server$
Why undefined reference to logp error?
Why I don't write accessories.o in final linking:
But as this example is given in GNU Make Doc:
In this example, all the C files include ‘defs.h’, but
only those defining editing comminclude ‘command.h’, and only
low level files that change the editor buffer include 'buffer.h':
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
Here while linking all the files in edit they don't write defs.o or buffer.o. Means while linking they are not including object files of header files. Also they have not written any target like: defs.o or buffer.o
Why?
You just missed accessories.o in both linking targets. Something like this:
accessories.o: accessories.c
sendfdsock: sendfdsock.o accessories.o
$(CC) -o $# $(CFLAGS) $(LDFLAGS) $+
Also, consider using the built-in rules, just modify their parameters, if needed. See make -p for the full list (and makes infopage)
You misunderstand the relationship between source files, header files and object files.
Suppose I have the following four files:
//foo.h
#define PI 3.1
//bar.h
void func();
//bar.c
#include "foo.h"
#include "bar.h"
void func()
{
...
}
//baz.c
#include "foo.h"
#include "bar.h"
int main()
{
func();
}
(I left out the header guards, I presume you know about those.) I must use the compiler to produce an object file from each source file: bar.c -> bar.o and baz.c -> baz.o. I don't have to make object files from the headers foo.h and bar.h, those will simply be #included by any source file that needs them. Then I link the object files together to form an executable:
baz: bar.o baz.o
gcc -o baz bar.o baz.o
bar.o: bar.c foo.h bar.h
gcc -c bar.c
baz.o: baz.c foo.h bar.h
gcc -c baz.c
If I neglect to link bar.o into the executable, I'll get a linker error when the linker gets to the place where baz calls func() and the linker doesn't know what to put there (because it lacks the definition of func() in bar.o):
baz.o: In function `main':
baz.c:(.text+0x32): undefined reference to `func()'
So the GNU Make doc is correct, and as Alex said, your rule should have:
sendfdsock:sendfdsock.o accessories.o
...
accessories.o: accessories.c accessories.h
...
(Incidentally, once you get this makefile working, we can show you how to make it more concise.)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
sem_open() error: “undefined reference to sem_open()” on linux (Ubuntu 10.10)
Having issues with compilation of posix semaphores. My goal is to create a shared memory segment and protect it by semaphores. shared memory works fine but semaphores code gives me compilation errors even though I included semaphore.h and added -lrt to compilation flags
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <time.h>
int main (int argc, char** argv) {
FILE *configFile;
int i,j;
int CashDesksNo=0;
int maxCashDesksNo;
int n,m;
int TmaxServe;
int custPerc; //customer ratio policy
int maxCapacity;
char * nlptr=NULL;
char * pch=NULL;
char line[125];
char termInput[30];
char tmpString[40];
int flg1,flg2;
int flag;
int execResult=0;
int fd;
int rc;
int randNum;
int status;
pid_t ch_pid;
int a,b,c;
int shmid=0;
int *shm_ptr;
int * err;
int retval;
sem_t *sp;
char semName[10];
strcpy(semName,"mutex");
//---------- Davasma kai elegxos in line parameters-----------------
// read inline params and config file
.
.
.
//------------ Print Configuration Data ----------------------------
if(CashDesksNo>maxCashDesksNo || CashDesksNo<1)
{
printf("\n# of Cash Desks should be between 1 and %d",maxCashDesksNo);
printf("\nsupermarket will now exit...\n");
exit(1);
}
printf("\n//-----------------------------------------------");
printf("\nSupermarket initialization");
printf("\n# of Cash Desks: %d",CashDesksNo);
printf("\n# of max products: %d",n);
printf("\nMax price: %d",m);
printf("\nMaximum serving time(secs): %d",TmaxServe);
printf("\n%% Customer/Cashier Percentage: %d/%d",custPerc,100-custPerc);
printf("\nMax Supermarket capacity: %d",maxCapacity);
printf("\n//-----------------------------------------------\n");
printf("\nAbout to create customer and cashier processes");
// ----------- Shared Memory Attachment --------------------------------
shmid=shmget(IPC_PRIVATE,sizeof(int*),0666);
if (shmid < 0)
{
perror("shmget");
exit(1);
}
shm_ptr=(int*)shmat(shmid,(void *)0,0);
if (shm_ptr == (int *)(-1))
{
perror("shmat");
exit(1);
}
a=0; //shm
shm_ptr=(int*)a;
printf("shmPtr:%d",(int)shm_ptr);
// ----- create & initialize semaphore ---------------------------------
sp = sem_open(semName,O_CREAT,0644,1);
if(sp == SEM_FAILED)
{
perror("unable to create semaphore");
exit(-1);
}
while(1)
{
printf("\nPress enter to start a new day at the supermarket(type exit to quit)\n");
fgets(termInput,sizeof(termInput),stdin);
nlptr = strchr(termInput, '\n');// termatismos string
if (nlptr) *nlptr = '\0';
if(strcmp(termInput,"exit")==0)//exit apo tin efarmogi
{
printf("\nExiting Supermarket..\n");
exit(0);
}
i=0;
while(i<maxCapacity)
{
//-Fork new process for the simulation --------------------
ch_pid = fork();
if (ch_pid == -1) {
perror("\nFailed to fork initial spliter/merger process \n");
exit(1);
}
if ( ch_pid == 0 ) //this is the child process
{
srand (getpid());//pid based seed
// "itoa" - Metatropi ari8mou se string
sprintf( tmpString, "%d", shmid );
randNum=rand() % 100 + 1;
if(randNum<custPerc)// customer : cashier ratio
{
execResult=execl("customer","customer","0",tmpString,NULL);
//printf("\nCreated a customer,randNum %d",randNum);
}else
{
execResult=execl("cashier","cashier","0",tmpString,NULL);
//printf("\nCreated a cashier,randNum %d",randNum);
}
if(execResult==-1)
{
perror("Could not perform exec to create cashier/customer process");
}
}
i++;
}
//Root process
//wait for childs to terminate
for (i = 0; i < maxCapacity; ++i)
{
waitpid(-1,&status,0);
}
printf("supermarket shared memory content: %d",(int)shm_ptr);
sem_close(sp);
sem_unlink(semName);
err = (int*)shmctl(shmid, IPC_RMID, 0);
if (err == -1)
perror ("Shared Memory Removal.");
else
printf("Shared Memory Removed. %d\n", (int)(err));
}
}
this is the makefile:
OBJS = supermarket.o cashier.o customer.o
SOURCE = supermarket.c cashier.c customer.c
HEADER = struct.h
OUT = supermarket cashier customer
CC = gcc
FLAGS = -lrt -g -c
LIBS = -lm
# -g option enables debugging mode
# -c flag generates object code for separate files
# -lm math library
all: supermarket cashier customer
supermarket: supermarket.c
$(CC) supermarket.c -o supermarket
cashier: cashier.c
$(CC) cashier.c -o cashier
customer: customer.c
$(CC) customer.c -o customer
# clean house
clean:
rm -f $(OBJS) $(OUT)
# do a bit of accounting
count:
wc $(SOURCE) $(HEADER)
I keep getting this error:
george#george-System-Product-Name:~/Desktop/prj3$ make
gcc supermarket.c -o supermarket
supermarket.c: In function ‘main’:
supermarket.c:310:11: warning: comparison between pointer and integer [enabled by default]
/tmp/ccYxA2Wi.o: In function `main':
supermarket.c:(.text+0x75c): undefined reference to `sem_open'
supermarket.c:(.text+0x9b0): undefined reference to `sem_close'
supermarket.c:(.text+0x9bf): undefined reference to `sem_unlink'
collect2: ld returned 1 exit status
make: *** [supermarket] Error 1
what can i do?
this is a project for operating systems class, my system is linux Ubuntu
I think you should link against pthread as well:
-lpthread
Example makefile from an old project of mine (see comments):
CC=gcc
CFLAGS=-c -Wall -O3 -g
LDFLAGS=-pthread
SOURCES=chatzor.c clientlist.c messagequeue.c
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=chatzor_server
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
clean:
rm -rf *.o ${EXECUTABLE}
You're going to have sore shins once you're done with this.
The compilation trace says:
$ make
gcc supermarket.c -o supermarket
supermarket.c: In function ‘main’:
...
Your makefile says:
supermarket: supermarket.c
$(CC) supermarket.c -o supermarket
It should say (at minimum):
supermarket: supermarket.c
$(CC) supermarket.c -o supermarket $(LIBS)
Indeed, it should probably be saying:
supermarket: supermarket.c
$(CC) $(CFLAGS) supermarket.c -o supermarket $(LDFLAGS) $(LIBS)