I'm making a program(C language) on RaspberryPi
My program get a data from Arduino by Serial communication
Source Code here :
#ifdef RaspberryPi
//include system librarys
#include <stdio.h> //for printf
#include <stdint.h> //uint8_t definitions
#include <stdlib.h> //for exit(int);
#include <string.h> //for errno
#include <errno.h> //error output
//wiring Pi
#include <wiringPi.h>
#include <wiringSerial.h>
char device[]= "/dev/ttyACM0";
// filedescriptor
int fd;
unsigned long baud = 9600;
unsigned long time=0;
//prototypes
void loop(void);
void setup(void);
void setup(){
printf("%s \n", "Raspberry Startup!");
fflush(stdout);
//get filedescriptor
if ((fd = serialOpen (device, baud)) < 0){
fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
exit(1); //error
}
//setup GPIO in wiringPi mode
if (wiringPiSetup () == -1){
fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
exit(1); //error
}
}
void loop(){
// Pong every 3 seconds
if(millis()-time>=3000){
serialPuts (fd, "Received\n");
time=millis();
}
// read signal
if(serialDataAvail (fd)){
char newChar = serialGetchar (fd);
printf("%c", newChar);
if((int)newChar >= 1){
system("raspistill -o image.jpg");
system("convert image.jpg -threshold 20% imagebw.jpg");
system("tesseract imagebw.jpg imageocr");
system("cat imageocr.txt");
}
fflush(stdout);
}
}
int main(void){
setup();
while(1) loop();
return 0;
}
#endif //#ifdef RaspberryPi
Before I put
system("convert image.jpg -threshold 20% imagebw.jpg");
system("tesseract imagebw.jpg imageocr");
system("cat imageocr.txt");
this code, it worked well
But, It does not work even if I delete it.
I found following error on my compiler(GCC)
/usr/lib/gcc/arm-linux-gneabihf/4.9/../../../arm-linux-gnueabihf/ort1.o:In function '_start':/build/glibc-mqlSLF/glibc-2.19/csu/../ports/sysdeps/arm/start.S:119 : undefined reference to 'main'
collect2: error: ld returned 1 exit sutatus
And I used following two command
sudo gcc test.c -o hello -lwiringPi -DRaspberryPi <br>
sudo gcc test.c -o hello -lwiringPi -DRaspberryPi -nostartfiles
Can anybody help me with this issue?
I have the following C File and I am using Mac OS X GCC Compiler.
You find the error below.
#include "support.h"
#ifdef _WIN32
#include <conio.h>
void support_init() {
// not needed
}
void support_clear() {
system("CLS");
}
int support_readkey(int timeout_ms) {
Sleep(timeout_ms);
if (!kbhit()) return 0;
return getch();
}
#else
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
void support_init() {
struct termios tio;
tcgetattr(STDIN_FILENO, &tio);
tio.c_lflag &= (~ICANON & ~ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &tio);
}
void support_clear() {
printf("\x1B[2J\x1B[0;0f");
}
int support_readkey(int timeout_ms) {
struct timeval tv = { 0L, timeout_ms * 1000L };
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
int r = select(1, &fds, NULL, NULL, &tv);
if (!r) return 0;
return getchar();
}
#endif
And this is my Makefile:
CFLAGS=-std=c11 -Wall -g
CC=clang
all: snake
.PHONY: all clean
snake: snake.o support.o
snake.o: snake.c support.h
clean:
rm -f snake
rm -f snake.o support.o
When I try to compile with the command "make all" I get the following error:
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
Please help. I am new to C :-)
check the Architecture based on that the cflags shoule be updated to set to -m32 or -m64 ,
for successful compilation in 64 bit machine this has to set to -m64.
CFLAGS+= -m64
I want to compile following c file:
#include <stdio.h>
#include <stdlib.h>
#include <../deps/linux/gpio.h>
int main(void) {
int r = gpio_is_valid(31);
if (r == -1) {
perror("GPIO address is invalid.\n");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
My Makefile looks as
build: gpio
LDFLAGS = -Llinux
gpio:
$(CC) -o gpio.o src/gpio.c $(LDFLAGS)
Unfortunately I get "gpio.h not found" as error.
gpio.h is a Linux kernel header. It can not be used for user space programs.
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.)
I'm trying to reproduce an example from Network Security with OpenSSL (by Chandra et al). The program consists of client.c server.c common.h and common.c. client.c simply creates a connection to the server on port 6012 and reads data from stdin and then send those data to the server. The server.c reads data from socket and writes it back out to stdout.
The problem is that server.c always get stuck in if(BIO_do_accept(acc) <= 0) at line 62 and never gets data sent from client.c, which runs perfectly fine. I later found the problem is that pthread_create(...) at line 66 ( which is defined as THREAD_CREATE(...) in common.h) failed and it returned 4294967295. Because THREAD_CREATE(...) failed, the program never get a chance to run do_server_loop in server_thread(...), which explains why the server never got the data from client.
How should I interpret the return values from pthread_create and how should I fix it?
PS. I later used strerror to convert 4294967295 and it returned "Unknown error".
Any help will be much appreciated!
//////////////////////////////////////////////////
Here is server.c:
#include "common.h"
void do_server_loop(BIO *conn)
{
int err, nread;
char buf[80];
do
{
fprintf(stderr, "server_loop executed.\n");
for(nread = 0; nread < sizeof(buf); nread += err)
{
err = BIO_read(conn, buf + nread, sizeof(buf) - nread);
if(err <= 0){
break;
}
}
fwrite(buf, 1, nread, stdout);
}
while (err > 0);
}
void THREAD_CC server_thread(void *arg)
{
fprintf(stderr, "server_thread(void *arg) executed.\n");
BIO *client = (BIO *)arg;
#ifndef WIN32
pthread_detach(pthread_self());
#endif
fprintf(stderr, "Connection opened.\n");
do_server_loop(client);
fprintf(stderr, "Connection closed.\n");
BIO_free(client);
ERR_remove_state(0);
#ifdef WIN32
_endthread();
#else
return 0;
#endif
}
int main(int argc, char *argv[])
{
BIO *acc, *client;
int thread_create_result;
THREAD_TYPE tid;
init_OpenSSL();
acc = BIO_new_accept(PORT);
if(!acc){
int_error("Error creating server socket");
}
if(BIO_do_accept(acc) <= 0){
int_error("Error binding server socket");
}
for(;;)
{
if(BIO_do_accept(acc) <= 0){
int_error("Error accepting connection");
}
client = BIO_pop(acc);
thread_create_result = THREAD_CREATE(tid, server_thread, client);
if(thread_create_result != 0){
fprintf(stderr, "THREAD_CREATE failed! returns: %s.\n", \
strerror(thread_create_result));
fprintf(stderr, "thread_create_result has the value: %u.\n", \
thread_create_result);
exit(-1);
}
}
BIO_free(acc);
return 0;
}
Here is common.h
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/objects.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#ifndef WIN32
#include <pthread.h>
#define THREAD_CC *
#define THREAD_TYPE pthread_t
#define THREAD_CREATE(tid, entry, arg) pthread_create(&(tid), NULL, \
(entry), (arg))
#else
#include <windows.h>
#include <process.h>
#define THREAD_CC __cdecl
#define THREAD_TYPE DWORD
#define THREAD_CREATE(tid, entry, arg) do { _beginthread((entry), 0, (arg));\
(tid) = GetCurrentThreadId();\
} while (0)
#endif
#define PORT "6012" //port
#define SERVER "10.1.251.24" //server address
#define CLIENT "10.1.21.46" //client address
#define int_error(msg) handle_error(__FILE__, __LINE__, msg)
void handle_error(const char *file, int lineno, const char *msg);
void init_OpenSSL(void);
Makefile:
CC = gcc
OPENSSLDIR = /usr/local/ssl
#CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 -D_REENTRANT -D__EXTENSIONS__
CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2
RPATH = -R${OPENSSLDIR}/lib
#LD = ${RPATH} -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -lpthread
LD = -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -pthread
OBJS = common.o
PROGS = server
all: ${PROGS}
server: server.o ${OBJS}
${CC} server.o ${OBJS} -o server ${LD}
clean:;
${RM} ${PROGS} *.ln *.BAK *.bak *.o
Change
if(thread_create_result = !0){
to
if(thread_create_result != 0){
Besides, you can use strerror function to convert error code to human-readable form.
add -D_REENTRANT on compile command lines and -lpthread on the link command line.
-D_REENTRANT will tell C/C++ libraries that your program is in multithread mode and -lpthread just load the shared library libpthread.so at runtime. I found this at William Garrison's POSIX threads tutorial and this link.
Here is the Makefile:
CC = gcc
OPENSSLDIR = /usr/local/ssl
CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 -D_REENTRANT -D__EXTENSIONS__
RPATH = -R${OPENSSLDIR}/lib
LD = ${RPATH} -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -lpthread
OBJS = common.o
PROGS = server
all: ${PROGS}
server: server.o ${OBJS}
${CC} server.o ${OBJS} -o server ${LD}
clean:;
${RM} ${PROGS} *.ln *.BAK *.bak *.o