| Electronics > Beginners |
| help with a little program in linux, need to catch an event |
| (1/3) > >> |
| coldfiremc:
Hi I have to make a C program for Raspbian, which, among other stuff creates a binary file, and fills it with serial port captured stuff everyday. So, no matter the time the machine is turned on, just on midnight, i have to create a new file. I Can't find anything like (I'am a sort of MSDOS guy) INT70h alarm event, that triggers at a specific hour. If the solution is available just with the standard C library, it could be great. Is there anything with that behaviour? thanks |
| saike:
Take a look at crontab examples https://opensource.com/article/17/11/how-use-cron-linux which run tasks at specified times |
| coldfiremc:
ok, I need to specify more details: I need to catch an asynchronous event, with maximum precision available. alarm() looks great, except by one quirk: i need to specify an "explicit" amount of time. If I Can "subtract" ticks between the current time and midnight on the fly would be great. I was about to use date, but delays can occur, and also, I have to "unnecesarily" parse the output. |
| hamster_nz:
You could use an alarm to signal to the program to see if it needs to open a new file, or you could use something like this, to read the serial port and open a new file when the first input is seen on a new day. --- Code: ---#include <stdio.h> #include <time.h> #include <sys/time.h> int main(int argc, char *argv[]) { FILE *f = NULL; FILE *fin = NULL; int year = 0,month = 0,day = 0; int c; /* Select or open the input file */ if(argc == 1) { fin = stdin; } else if(argc == 2) { fin = fopen(argv[1],"rb"); if(fin == NULL) { fprintf(stderr,"Unable to open '%s'\n",argv[1]); } else { fprintf(stderr,"Opened '%s'\n",argv[1]); } } else { fprintf(stderr,"Usage : %s [input file]\n",argv[0]); } /* Process the characters */ while(fin != NULL) { time_t now_secs; struct tm *now; /* Get a character */ c = getc(fin); if(c == EOF) break; /* Get the time */ now_secs = time(NULL); now = localtime(&now_secs); /* Do we need to open a new file */ if(f == NULL || now->tm_mday != day || now->tm_mon != month || now->tm_year != year) { char buffer[16]; year = now->tm_year; month = now->tm_mon; day = now->tm_mday; /* Close any existing file */ if(f != NULL) { fclose(f); f = NULL; } /* Make a file name and open it - check the length of buffer if you change this! */ sprintf(buffer,"log.%04i-%02i-%02i",year+1900,month,day); f = fopen(buffer,"a"); if(f == NULL) { fprintf(stderr,"Unable to open '%s'\b", buffer); break; } } /* Output the character to the file, flush if a newline is seen */ if( f != NULL) { putc(c,f); if(c == '\n') fflush(f); } } /* Cleanup */ if(argc == 1 && fin != NULL) { fclose(fin); } if(f != NULL) fclose(f); return 0; } --- End code --- If this meets your requirements or not depends if you need an empty file on a day where you have no input. You could change the 'getc()' call to 'select()' with a timeout of a few seconds, which would allow you to avoid the hassles of managing signals. That would involve switching to the unbuffered open()/read()/close() to process the input file, which is just a bit awkward for a quick hack. You should either 'nohup' it, or set it up as a service (e.g. as script in /etc/init.d or add it to /etc/rc.local or maybe in /etc/inittab) so that it runs on boot, and/or restarts if it gets killed by a user. If you need to configure the serial port (e.g. set its speed, flow control and so on) either use the 'stty' utility before you open it, or have a read of the man page for 'tcgetattr' and add the required calls to the program. |
| hamster_nz:
--- Quote from: coldfiremc on May 14, 2018, 04:07:38 am ---Hi I have to make a C program for Raspbian, which, among other stuff creates a binary file, and fills it with serial port captured stuff everyday. So, no matter the time the machine is turned on, just on midnight, i have to create a new file. I Can't find anything like (I'am a sort of MSDOS guy) INT70h alarm event, that triggers at a specific hour. If the solution is available just with the standard C library, it could be great. Is there anything with that behaviour? thanks --- End quote --- If you really do want to set an alarm, this will help: http://www.gnu.org/software/libc/manual/html_node/Setting-an-Alarm.html You will need to set up an empty signal handler for SIGALRM, as the default behavior is to terminate the process. I think you will find that read() or getc() will return -1 with errno set to "EINTR" when the alarm is triggered, avoiding the need to do any real work in your interrupt handler. --- Code: ---#include <stdio.h> #include <signal.h> #include <unistd.h> #include <errno.h> void handler(int i) { /* Do nothing in the signal handler */ } int main(int argc, char *argv[]) { int carry_on = 1; struct sigaction sa; sa.sa_handler = handler; sa.sa_flags = 0; sigfillset(&sa.sa_mask); if(sigaction(SIGALRM, &sa, NULL) == -1) { perror("Error: cannot handle SIGALRM"); } while(carry_on) { int c; /* Set up an alarm in two seconds */ alarm(2); /* read a character */ c = getchar(); if(c == EOF) { /* Trap the alarm */ switch(errno) { case EINTR: printf("EINTR - alarm called\n"); break; default: carry_on = 0; break; } } else { /* Output the character */ putchar(c); } } return 0; } --- End code --- |
| Navigation |
| Message Index |
| Next page |