wiringPiISR fires callback at every pin - c

i'm using RaspberryPI with Wiring libray in c++, and I want to use the wiringPiISR for fire an event when i click my button on PIN 5.
This is the code
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <unistd.h>
unsigned long last_interrupt_time = 0;
#define PIN 5
//gcc foo.c -o foo -lwiringPi
void myEdge (void)
{
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 500)
{
delay(200);
if( digitalRead(PIN)== 1 )
fprintf(stdout,"gpio rising\n");
else
fprintf(stdout,"gpio falling\n");
fflush(stdout);
}
last_interrupt_time = interrupt_time;
}
int main (int argc,char **argv)
{
if (wiringPiSetupGpio() < 0)
{
fprintf (stderr, "Errore: Unable to GPIO: %s\n", strerror (errno)) ;
return 1 ;
}
pinMode(PIN, INPUT) ;
pullUpDnControl(PIN, PUD_DOWN) ;
if (wiringPiISR (PIN, INT_EDGE_BOTH , &myEdge) < 0)
{
fprintf (stderr, "Errore: Unable to setup ISR: %s\n", strerror (errno)) ;
return 1 ;
}
while (1)
delay (1000) ;
return 1;
}
I compile white
gcc foo.c -o foo -lwiringPi
This code works but fires when I click EVERY PIN... the pin 5, and also the 4 and the 6 and maybe others... WHY? Anyone can help me to understand?

Related

How to make synchronism between two distinct C programs?

First of all, I don't know if I can explain well my problem or you can get it in the appropriate way. But I will try to make it clear for you.
In fact, I have two different C programs.
The first one is a simple loop print of a message on the console :
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main ()
{
while(1)
{
printf("WAITING\n");
sleep(1);
}
}
The second one is a blocking program that waits for an event ( press button ) to turn on led in my embedded board.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <linux/input.h>
#define BTN_FILE_PATH "/dev/input/event0"
#define LED_PATH "/sys/class/leds"
#define green "green"
void change_led_state(char *led_path, int led_value)
{
char lpath[64];
FILE *led_fd;
strncpy(lpath, led_path, sizeof(lpath) - 1);
lpath[sizeof(lpath) - 1] = '\0';
led_fd = fopen(lpath, "w");
if (led_fd == NULL) {
fprintf(stderr, "simplekey: unable to access led\n");
return;
}
fprintf(led_fd, "%d\n", led_value);
fclose(led_fd);
}
void reset_leds(void)
{
change_led_state(LED_PATH "/" green "/brightness", 0);
}
int configure_leds(void)
{
FILE *l_fd;
FILE *r_fd;
char *none_str = "none";
/* Configure leds for hand control */
r_fd = fopen(LED_PATH "/" green "/trigger", "w");
fprintf(r_fd, "%s\n", none_str);
fclose(r_fd);
/* Switch off leds */
reset_leds();
return 0;
}
void eval_keycode(int code)
{
static int green_state = 0;
switch (code) {
case 260:
printf("BTN left pressed\n");
/* figure out red state */
green_state = green_state ? 0 : 1;
change_led_state(LED_PATH "/" green "/brightness", green_state);
break;
}
}
int main(void)
{
int file;
/* how many bytes were read */
size_t rb;
int ret;
int yalv;
/* the events (up to 64 at once) */
struct input_event ev[64];
char *str = BTN_FILE_PATH;
printf("Starting simplekey app\n");
ret = configure_leds();
if (ret < 0)
exit(1);
printf("File Path: %s\n", str);
if((file = open(str, O_RDONLY)) < 0) {
perror("simplekey: File can not open");
exit(1);
}
for (;;) {
/* Blocking read */
rb= read(file, &ev, sizeof(ev));
if (rb < (int) sizeof(struct input_event)) {
perror("simplekey: short read");
exit(1);
}
for (yalv = 0;
yalv < (int) (rb / sizeof(struct input_event));
yalv++) {
if (ev[yalv].type == EV_KEY) {
printf("%ld.%06ld ",
ev[yalv].time.tv_sec,
ev[yalv].time.tv_usec);
printf("type %d code %d value %d\n",
ev[yalv].type,
ev[yalv].code, ev[yalv].value);
/* Change state on button pressed */
if (ev[yalv].value == 0)
eval_keycode(ev[yalv].code);
}
}
}
close(file);
reset_leds();
exit(0);
}
When I execute the second code, the program starts waiting for the event to switch on/off the led.
My question is :
How can I make interaction between the two programs ? I want to execute the firs one --> It starts printing for me " WAITING " until I press the BUTTON --> the LED turn on --> and then it goes back to the first program and re-start printing " WAITING " on the console.
I don't know if I explained well the issue but I hope that you can help me! Thank you.
You need a communication mechanism between your two programs. This is also known als inter-process communication.
Generally, you have several options to achieve this (depending on the operating system you are using, not all of them may be available):
Shared memory / shared files
Message passing (e.g. via sockets)
Pipes
Signals
A helpful introduction can be found here.

Failing to execute "make" in Ubuntu gcc

I have several files which I'm trying to compile using gcc in Ubuntu. I have vmware machine 16.04 ubuntu, which 64-bit computer. I have added the flags for 32bit compilation in the makefile. (-m32 flag).
This is the makefile:
all: clean binsem.a ut.a ph
FLAGS = -Wall -L./ -m32
ph: ph.c
gcc ${FLAGS} ph.c -lbinsem -lut -o ph
binsem.a:
gcc $(FLAGS) -c binsem.c
ar rcu libbinsem.a binsem.o
ranlib libbinsem.a
ut.a:
gcc $(FLAGS) -c ut.c
ar rcu libut.a ut.o
ranlib libut.a
clean:
rm -f *.o
rm -f a.out
rm -f *~
rm -f ph
rm -f *a
My attempts to compile the code were not successful, as I received the following error:
ph.c:126:12: warning: ‘main’ defined but not used [-Wunused-function]
/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'ph' failed
make: *** [ph] Error 1
**I tried - **
Adding -c flags to the ph.c file in the make file. However it doesn't make much sense, since it has a main function. No success.
Adding sum -m32 flags in the makefile, in addition to what's already written. No Success.
The file "ph.c", is the following file -
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdint.h>
#include <sys/time.h>
#include <inttypes.h>
#include "binsem.h"
#include "ut.h"
#define LEFT (i+N-1)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
int N;
volatile int *phil_state;
sem_t *s;
sem_t mutex;
int *tid;
uint64_t get_wall_time() {
struct timeval time;
gettimeofday(&time, NULL);
uint64_t millis = (time.tv_sec * (uint64_t)1000) + (time.tv_usec / 1000);
return millis;
}
void think(int p) {
int i, factor;
volatile int j;
printf("Philosopher (%d) - time %" PRId64 " - is thinking\n",p, get_wall_time()); fflush (stdout);
factor = 1 + random()%5;
for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}
printf("Philosopher (%d) - time %" PRId64 " - is hungry\n", p, get_wall_time()); fflush (stdout);
}
void eat(int p){
int i, factor;
volatile int j;
printf("Philosopher (%d) - time %" PRId64 " - is eating\n",p, get_wall_time()); fflush (stdout);
factor = 1 + random()%5;
for (i = 0; i < 100000000*factor; i++){
j += (int) i*i;
}
//printf("Philosopher (%d) - time %" PRId64 " - is thinking\n",p, get_wall_time()); fflush (stdout);
}
void test(int i){
if (phil_state[i] == HUNGRY &&
phil_state[LEFT] != EATING &&
phil_state[RIGHT] != EATING){
phil_state[i] = EATING;
binsem_up(&(s[i]));
}
}
void take_forks(int i){
binsem_down(&mutex);
phil_state[i] = HUNGRY;
test(i);
binsem_up(&mutex);
binsem_down(&(s[i]));
}
void put_forks(int i){
binsem_down(&mutex);
phil_state[i] = THINKING;
test(LEFT);
test(RIGHT);
binsem_up(&mutex);
}
void int_handler(int signo) {
long int duration;
int i;
for (i = 0; i < N; i++) {
duration = ut_get_vtime(tid[i]);
printf("Philosopher (%d) used the CPU %ld.%ld sec.\n",
i+1,duration/1000,duration%1000);
}
exit(0);
}
void philosopher(int i){
while (1){
think(i);
take_forks(i);
eat(i);
put_forks(i);
}
}
static int main(int argc, char *argv[])
{
int c;
if (argc != 2){
printf("Usage: %s N\n", argv[0]);
exit(1);
}
N = atoi(argv[1]);
if (N < 2){
printf("Usage: %s N (N >=2)\n", argv[0]);
exit(1);
}
ut_init(N);
s = (sem_t *)malloc (N * sizeof(sem_t));
phil_state = (int *) malloc (N * sizeof(int));
tid = (int *) malloc (N * sizeof(int));
for (c = 0; c < N ; c++){
phil_state[c] = THINKING;
binsem_init(&(s[c]), 0);
}
for (c = 0; c < N ; c++){
tid[c] = ut_spawn_thread(philosopher,c);
printf("Spawned thread #%d\n", tid[c]);
}
binsem_init(&mutex, 1);
signal(SIGINT,int_handler);
ut_start();
return 0; // avoid warnings
}
The makefile also tries to compile these files - ut.c, binsem.c
#include <stdlib.h>
#ifndef _UT_H
#define _UT_H
#include "ut.h"
#include <sys/time.h> // for itimerval
#include <unistd.h> // for alarm
#include <stdlib.h> // for malloc
#include <stdio.h> // for perror
#include <ucontext.h>
# include "ut.h"
#define MAX_TAB_SIZE 128 // the maximal threads table size.
#define MIN_TAB_SIZE 2 // the minimal threads table size.
#define SYS_ERR -1 // system-related failure code
#define TAB_FULL -2 // full threads table failure code
/*This type defines a single slot (entry) in the threads table. Each slot describes a single
thread. Note that we don't need to keep the thread state since every thread is always ready
or running. We also don't have to support adding/stopping thread dynamically, so we also don't
have to manage free slots.*/
typedef struct ut_slot {
ucontext_t uc;
unsigned long vtime; /* the CPU time (in milliseconds) consumed by this thread.*/
void (*func)(int); /* the function executed by the thread.*/
int arg; /* the function argument.*/
} ut_slot_t, *ut_slot;
static ut_slot threads; // pointer to thread table
static volatile int numThreads = 0; // number of threads in the table
static volatile int currentThread = 0; // current thread
static ucontext_t mainThread;
#define STACKSIZE 8192 // the thread stack size.
/* The TID (thread ID) type. TID of a thread is actually the index of the thread in the
threads table. */
typedef short int tid_t;
void handler(int signal){
alarm(1); //the alarm every second as demanded in the assignment
currentThread = (currentThread +1 ) % numThreads;
printf("in signal handler: switching from %d to %d\n", currentThread, currentThread - 1);
swapcontext(&threads[currentThread].uc, &threads[currentThread].uc); /*save current thread,
* load next thread*/
if (signal == SIGVTALRM){ // increment the time stats
threads[currentThread].vtime+=100;
} else if(signal==SIGALRM) {
if (swapcontext(&threads[currentThread - 1].uc, &threads[currentThread].uc) == -1) {
perror("could not do swapping");
exit(1);
}
}
}
int ut_init(int tab_size){
/// (###)
if(tab_size < MAX_TAB_SIZE) {
threads = (ut_slot) malloc(tab_size * sizeof(int(ut_slot_t)));
}
else{
threads = (ut_slot) malloc(MAX_TAB_SIZE * sizeof(int(ut_slot_t)));
}
if (!threads) {
return SYS_ERR;
}
return 0;
}
tid_t ut_spawn_thread(void (*func)(int), int arg){
/*uc[1].uc_link = &uc[0];
uc[1].uc_stack.ss_sp = st1; //stack fro thread 1
uc[1].uc_stack.ss_size = sizeof st1; //size of stack for therad
makecontext(&uc[1], (void(*)(void)) f, 1, 1); */
int thread_stack_size = STACKSIZE/8; //no need for 8K in size
if (numThreads>=TAB_FULL){ //(*)
return TAB_FULL;
}
if (getcontext(&threads[numThreads].uc)==-1){
return SYS_ERR;
}
ut_slot_t newThread;
threads[numThreads] = newThread;
threads[numThreads].uc.uc_link = &mainThread;
threads[numThreads].uc.uc_stack.ss_sp = (void* *)malloc(thread_stack_size);
if(threads[numThreads].uc.uc_stack.ss_sp==NULL){
return SYS_ERR;
}
makecontext(&threads[numThreads].uc,(void(*)(void))func,1,arg);
numThreads++;
return numThreads - 1;
}
int ut_start(void){
struct sigaction sigaction1;
int firstThread = 0; /*represents the current thread*/
struct itimerval itv;
/* set up vtimer for accounting */
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 10000;
itv.it_value = itv.it_interval;
/* Initialize the data structures for SIGALRM handling. */
sigaction1.sa_flags = SA_RESTART; //restart instead of throwing exception
sigfillset(&sigaction1.sa_mask); // don't throw exception for additional signals
sigaction1.sa_handler = handler; // specify handler for the sigaction declared
if (sigaction(SIGVTALRM, &sigaction1, NULL) < 0)
return SYS_ERR;
/*START THE TIMER */
if (setitimer(ITIMER_VIRTUAL, &itv, NULL) < 0)
return SYS_ERR;
if (sigaction(SIGINT, &sigaction1, NULL) < 0)
return SYS_ERR;
/* Start running. */
alarm(1); //alarm every second
if(swapcontext(&threads[firstThread].uc,&threads[firstThread+1].uc)==-1){ //swap first time
return SYS_ERR;
}
return -1;
}
unsigned long ut_get_vtime(tid_t tid){
return threads[tid].vtime;
}
#endif
binsem.c
#ifndef _BIN_SEM_H
#define _BIN_SEM_H
#include "binsem.h"
#include <signal.h>
#include "atomic.h"
typedef unsigned long sem_t;
void binsem_init(sem_t *s, int init_val){
if(init_val == 1){
*s = 1;
}
else{
*s = 0;
}
}
void binsem_up(sem_t *s){
xchg(s,1); /*send the pointer of s, and the new value 1*/
}
int binsem_down(sem_t *s){
int flag = 0;
while (flag == 0){
xchg(s,0); /*try changing the value - down*/
if (*s != 0){ /*no success in changing*/
if (raise(SIGALRM)!=0){ /*raise returns 0 on success*/
return -1;
}
} else{
flag = 1;
return 0;
}
}
}
#endif
Any ideas?
You declare the main function to be static. That means it will have internal linkage, and not be exported. Therefore the linker will not be able to find it.
Remove the static modifier and that should work.
However there are also many other problems in your Makefile that will most likely lead to problems:
The target ph only depends on ph.c, not the libraries you want to link with. You need to add the libraries as dependencies as well (their full file-names).
You should also make the libraries depend on the object files used to create them, and rely on the implicit rules to build object files from source files.
Also note that for a library named A then the file-name needs to be libA.a, otherwise the linker will not be able to find it with the -l (lower-case L) option.
The error message is pretty clear:
(.text+0x18): undefined reference to `main'
In ph.c you have (probably accustomed from Java?):
static int main(int argc, char *argv[])
In C:
static ([CPPReference]: C keywords: static) means internal linkage (only valid in current translation unit (ph.o in our case)), so a static symbol won't be "seen" by the linker (loader)
Code linked to an application (not a dynamic library or shared object (.so: linked with -shared)), must explicitly define main, and that should be visible by the linker
The combination of the above 2, lead to what you're experiencing.
Remove the static and you'll be fine.
Note: There might be other errors in the Makefile.

undefined reference to main issue (using arduino, RaspberryPi, GCC)

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?

System call poll() does not work on Ubuntu Kylin 16.04 32 bit version, but works on Fedora 21 64 bit

This is a short version of my code: I have a 64 bit fedora 21 on which the code works fine. However on my other 32bit machine on which I have installed ubuntu Kylin 16.04 32 bit version, poll does not return when text is entered on stdin, it just stays blocked. When I hit Ctrl-C in gdb after the text is entered, and then try executing next command it works... Is this a bug of ubuntu 32 bit version or I have to use poll differently on 32 bit version?
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
int sockfd;
int const myOPEN_MAX=100,MAXLINE=4096;
struct pollfd client[myOPEN_MAX];
int maxi,nready,n;
char buf[4096];
client[0].fd = fileno(stdin);
client[0].events = POLLRDNORM;
for (int i = 1; i < myOPEN_MAX; i++){
client[i].fd = -1; /* -1 indicates available entry */
}
maxi = 1; /* max index into client[] array */
printf("enter something\n");
for ( ; ; ) {
nready = poll(client, maxi+1, -1);
for (int i = 0; i <= maxi; i++) { /* check all clients for data */
if ( (sockfd = client[i].fd) < 0)
continue;
if (client[i].revents & (POLLRDNORM | POLLERR)) {
if ( (n = read(sockfd, buf, MAXLINE)) > 0) {
if (i == 0) { //stdin
printf("works\n");
return 0;
}
if (--nready <= 0)
break; /* no more readable descriptors */
}
}
}
}
return 0;
}

record using /pulse/simple.h

i am trying to record my voice from the microphone on my laptop using the simple.h pulseaudio header file into an array, but i cant seem to figure it out. Every time i record and i replay my recording , it is a high pitched beep i followed examples, etc but i can't seem to get this down can someone please help me .
I am basically hacking the example "parec-simple.c" given in the doxygen page. I've tried routing the output of buf to stdout, then using libre-office calc to plot a graph to see if the output looks anything like sound but it does not.
here is the code i used
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 1024
FILE *output;
/* A simple routine calling UNIX write() in a loop */
void loop_write(uint8_t *data) {
register int size = 1023;
while (size > 0)
{
fprintf(output,"%"SCNu8"\n",data[size] ) ;
size --;
}
}
int main(int argc, char*argv[]) {
output = fopen("/home/donnell/output", "w");
/* The sample type to use */
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE,
.rate = 41000,
.channels = 2
};
pa_simple *s = NULL;
int ret = 1;
int error;
/* Create the recording stream */
if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
}
for (;;) {
uint8_t buf[BUFSIZE];
/* Record some data ... */
if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error));
goto finish;
}
/* and write it to fle*/
loop_write(buf);
}
ret = 0;
finish:
if (s)
pa_simple_free(s);
return ret;
}

Resources