How to know if a timer has ended in C - c

I need to be able to start multiple timers simultaneously and know specifically if a timer has stopped or is still going.
#define RESEND_TIMEOUT 5
void timerCreate();
void timer_start(timer_t * timer, uint32 timeout);
bool timer_complete(timer_t * timer);
int main() {
timer_t resend_timer = timerCreate();
timer_start(&resend_timer, RESEND_TIMEOUT);
while(1) {
if (timer_complete(&resend_timer))
break;
}
}
void timer_start(timer_t * timer, uint32_t timeout)
{
printf("timer starting\n");
struct itimerspec it_val;
it_val.it_value.tv_sec = timeout;
it_val.it_value.tv_nsec = 0;
// timer expires once
it_val.it_interval.tv_sec = 0;
it_val.it_interval.tv_nsec = 0;
if (timer_settime(*timer, 0, &it_val, NULL) == -1) {
errExit("Could not set timeout");
}
}
// return true if timer ended
bool timer_complete(timer_t * timer)
{
if(timer_getoverrun(*timer) == 0)
return false;
else
return true;
}
I never break out of the loop. Why can't I get the overrun of the timer (it always returns 0, which means the timer has not passed its expiration)? Yet when I add a signal handler, I know that the timer expires.
I want to try timer_gettime(timer_t timerid, struct itimerspec *curr_value) inside of my timer_complete function to see if the remaining time is 0, but how can I pass the curr_value argument without having a global variable?
Last but not least, I have tried with the TIMER_ABSTIME flag when arming the timer with timer_settime. From the manpage of int timer_settime(timer_t timerid, int flags,
const struct itimerspec *new_value,
struct itimerspec * old_value):
By default, the initial expiration time specified in
new_value->it_value is interpreted relative to the current time on
the timer's clock at the time of the call. This can be modified by
specifying TIMER_ABSTIME in flags, in which case new_value->it_value
is interpreted as an absolute value as measured on the timer's clock;
that is, the timer will expire when the clock value reaches the value
specified by new_value->it_value. If the specified absolute time has
already passed, then the timer expires immediately, and the overrun
count (see timer_getoverrun(2)) will be set correctly.

I never break out of the loop. Why can't I get the overrun of the timer (it always returns 0, which means the timer has not passed its expiration)?
No, it means you had no overruns.
The OS is not going to queue timer signals even if you specify realtime signals. Overun tells you how many signals would have been queued if the wood chuck didn't chuck signals.
So consider you set a timer to go off once every second. But for some reason you didn't handle the signal. Say you had it blocked for 5 seconds. The overrun count is going to be 4 - the signal you will/are processing and the 4 you missed.
In your case you set a one-time timer to go off after "timeout" seconds. The signal was delivered. There will be no more signals hence overrun is always going to be 0, as it should be.

Related

Linux C ignore event for x seconds

I have the following arduino code:
uint32_t hold_time=600000;
uint32_t curr_time;
uint32_t last_event;
bool on_hold=false;
beginning of main loop
curr_time = millis();
if (on_hold && curr_time - last_event >= hold_time) {
on_hold = false;
}
...
if (!on_hold)
{
run the function();
on_hold = true; // Ignore this function for 1 minute
}
This basically will execute the main loop many times but the run_the_function(); only when it is unlocked so in this example once in every minute. I would like to accomplish the same in standard POSIX C which works on BSDs as well.
Since you asked for POSIX, I will give you POSIX. This is a sample code that is able to run a timer without using pthreads, but only through OS provided timers. It runs a specific function every 2 seconds. You can configure it to make it run every 60 seconds, if you prefer. I have comment thoroughly the code, and I hope it is easy enough to understand:
#include <stdlib.h> // For declaration of exit
#include <stdio.h> // For printf function
#include <signal.h> // Will be used for the signal callbacks
#include <time.h> // Timer and current time stuff
#define TIMER_SECONDS 2 // To test more rapidly I will wait
// only for 2 seconds instead of a minute...
int counter = 0; // Whe want to call the timer a limited number
// of time for this example
// BEFORE READING THIS, READ THE MAIN:
// This function is your "run_the_function" callback. As for now,
// it has no arguments and returns nothing. It asks to the system the current
// time and prints it, just to check if the timer works. It uses **printf**
// and this should be avoided in signal handlers!
static void run_the_function() {
time_t rawtime; // This is the current time variable
struct tm * timeinfo; // This is a strut that contains the time
// broken down to its components
time( &rawtime ); // To get from the system the current time
timeinfo = localtime ( &rawtime ); // For splitting the time in its components
printf("Timer CALLED %d times :: %s", ++counter, asctime(timeinfo));
}
// BEFORE READING THIS, READ THE MAIN
// This is the signal handler, a function that is called when the timer
// signals that has finished to count
static void timer_callback(int sig, siginfo_t *si, void *uc) {
run_the_function();
}
int main() {
timer_t timer_id; // An unique identifier for the timer that you are creating
struct itimerspec intervals; // Specify the intervals for the timer that we are creating
struct sigevent timer_event; // The structure that handles the event generated by the timer
struct sigaction timer_action; // The action for the timer event
// First you need to implement the action to do when the timer reaches zero,
// then you need to say that you want an event for a timer that reaches zero,
// and only at the end you set the timer.
// The function "sigaction" connects your timer event to the timer signal SIGRTMIN.
// The timer_event.sigev_signo instructs to create an EVENT for the signal SIGRTMIN, and
// for that event you prepared a custom action.
// The timer sends the SIGRTMIN signal every time it reaches zero, and when you
// create it, you connect it to the timer_event.
// Now we define what is the action to perform
timer_action.sa_flags = SA_SIGINFO; // The action to perform is to run a callback
timer_action.sa_sigaction = timer_callback; // The callback is "timer_callback"
sigemptyset(&timer_action.sa_mask); // And we are initializing the event structure
if (sigaction(SIGRTMIN, &timer_action, NULL) < 0) // We are binding this action
exit(1); // to a timer event (SIGRTMIN)
timer_event.sigev_notify = SIGEV_SIGNAL; // Instruct the event that it is related to
// a signal.
timer_event.sigev_signo = SIGRTMIN; // Instruct the event that the signal to track is SIGRTMIN
// At this point we are ready to create the timer, that uses the REAL TIME CLOCK of your
// system. When it reaches zero it raise a timer_event, and it also sets the id of the
// created timer.
if (timer_create(CLOCK_REALTIME, &timer_event, &timer_id) < 0)
exit(1);
// We now need to define the times for the timer. Intervals is composed by
// two structure: it_value, that contains the current time (or the starting time
// for the first run of your timer) and it_intervals, the time at which it will be
// reset after completing one lap. If you set it_interval to zero, the timer runs only
// one time. If you set it_value to zero, the timer does not run.
intervals.it_value.tv_sec = TIMER_SECONDS;
intervals.it_value.tv_nsec = 0;
intervals.it_interval.tv_sec = TIMER_SECONDS;
intervals.it_interval.tv_nsec = 0;
// Let's setup the time and the interval of the timer, so that it starts...
if (timer_settime(timer_id, 0, &intervals, NULL) < 0)
exit(1);
// And now we have only to wait for the timer... Easy, isn't it?
printf("Let's go!\n");
while(counter < 5) { /* Do your stuff here*/ };
return 0;
}
You need to compile it with:
gcc test.c -lrt -o test
and run it with:
./test
Let's go!
Timer CALLED 1 times :: Thu May 3 15:48:29 2018
Timer CALLED 2 times :: Thu May 3 15:48:31 2018
Timer CALLED 3 times :: Thu May 3 15:48:33 2018
Timer CALLED 4 times :: Thu May 3 15:48:35 2018
Timer CALLED 5 times :: Thu May 3 15:48:37 2018

what does timer expiration value for periodic linux timer signify?

I have already gone through the man page to create, and start the timer.
http://man7.org/linux/man-pages/man2/timerfd_create.2.html
However, i am not sure the use of the field "it_value" of struct itimerspec other than arm(start) and disarm(stop).
Question: what happens when a non-zero value is specified for this field.The man page documents that non-zero will start the timer and documents as timer expiration period? what does a timer expiration mean? what is the effect of timer expiration?
To start(arm) a timer, one can give value ranging from 1 ns to value equal to timer interval(non-zero). what would be the difference and the expected behavior in these two cases
Method1: Make the timer expiration equal to interval
int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
int milliseconds = 50;// 50 ms for example
struct itimerspec timspec;
timspec.it_interval.tv_sec = 0;
timspec.it_interval.tv_nsec = milliseconds * 1000000;
timspec.it_value.tv_sec = timspec.it_interval.tv_sec;
timspec.it_value.tv_nsec = timspec.it_interval.tv_nsec;
int res = timerfd_settime(timerfd, 0, &timspec, 0);
Method 2: Timer expiration less then timer interval
int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
int milliseconds = 50;// 50 ms for example
struct itimerspec timspec;
timspec.it_interval.tv_sec = 0;
timspec.it_interval.tv_nsec = milliseconds * 1000000;
timspec.it_value.tv_sec = 0;
timspec.it_value.tv_nsec = 1;
int res = timerfd_settime(timerfd, 0, &timspec, 0);
However, i am not sure the use of the field "it_value" of struct itimerspec other than arm(start) and disarm(stop).
Apparently your interest is in the use of this field with the second argument to timerfd_settime(), as opposed to the interpretation of values set in the struct, if any, pointed to by the third argument, or filled in by timerfd_gettime(). It's all pretty much the same, though.
You seem to have focused on the wrong thing in keying in on arming and disarming the timer. As the manpage you linked puts it,
The new_value argument specifies the initial expiration and interval for the timer.
(emphasis added). That is, the it_value of a struct itimerspec conveys the amount of time until the next timer expiration (or the absolute time of that expiration, depending on the flags), except that both fields zero indicates that the timer will never expire -- it is disarmed -- rather than that it will expire immediately. The value conveyed by this member does not have any particular correlation to the value conveyed by the it_interval member.
It follows that timerfd_settime() can be used to arm a disarmed timer or disarm an armed one, depending on the it_value passed to it, but those are special outcomes of more general behavior. The general case is that it is used to change the amount of time before a timer next expires, and the time increment between subsequent expirations.
To start(arm) a timer, one can give value ranging from 1 ns to value equal to timer interval(non-zero).
... or more. The delay before the next expiration is not limited to the length of the interval. As an extreme case, the interval can be zero, so that the timer is disarmed after expiring once.
what would be the difference and the expected behavior in these two cases
Method1: Make the timer expiration equal to [nonzero] interval
The timer will first expire after the specified amount of time (which is equal to the interval). Each time it expires, it will be reset to the time given by the interval.
Method 2: [nonzero] Timer expiration less then [nonzero] timer interval
The timer will first expire after the specified amount of time (which is less than the interval). Each time it expires, it will be reset to the time given by the interval.

Need some help in C code for optimization (Poll + delay/sleep)

Currently I'm polling the register to get the expected value and now I want reduce the CPU usage and increase the performance.
So, I think, if we do polling for particular time (Say for 10ms) and if we didn't get expected value then wait for some time (like udelay(10*1000) or usleep(10*1000) delay/sleep in ms) then continue to do polling for more more extra time (Say 100ms) and still if you didn't get the expected value then do sleep/delay for 100ms.....vice versa... need to do till it reach to maximum timeout value.
Please let me know if anything.
This is the old code:
#include <sys/time.h> /* for setitimer */
#include <unistd.h> /* for pause */
#include <signal.h> /* for signal */
#define INTERVAL 500 //timeout in ms
static int timedout = 0;
struct itimerval it_val; /* for setting itimer */
char temp_reg[2];
int main(void)
{
/* Upon SIGALRM, call DoStuff().
* Set interval timer. We want frequency in ms,
* but the setitimer call needs seconds and useconds. */
if (signal(SIGALRM, (void (*)(int)) DoStuff) == SIG_ERR)
{
perror("Unable to catch SIGALRM");
exit(1);
}
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
it_val.it_interval = it_val.it_value;
if (setitimer(ITIMER_REAL, &it_val, NULL) == -1)
{
perror("error calling setitimer()");
exit(1);
}
do
{
temp_reg[0] = read_reg();
//Read the register here and copy the value into char array (temp_reg
if (timedout == 1 )
return -1;//Timedout
} while (temp_reg[0] != 0 );//Check the value and if not try to read the register again (poll)
}
/*
* DoStuff
*/
void DoStuff(void)
{
timedout = 1;
printf("Timer went off.\n");
}
Now I want to optimize and reduce the CPU usage and want to improve the performance.
Can any one help me on this issue ?
Thanks for your help on this.
Currently I'm polling the register to get the expected value [...]
wow wow wow, hold on a moment here, there is a huge story hidden behind this sentence; what is "the register"? what is "the expected value"? What does read_reg() do? are you polling some external hardware? Well then, it all depends on how your hardware behaves.
There are two possibilities:
Your hardware buffers the values that it produces. This means that the hardware will keep each value available until you read it; it will detect when you have read the value, and then it will provide the next value.
Your hardware does not buffer values. This means that values are being made available in real time, for an unknown length of time each, and they are replaced by new values at a rate that only your hardware knows.
If your hardware is buffering, then you do not need to be afraid that some values might be lost, so there is no need to poll at all: just try reading the next value once and only once, and if it is not what you expect, sleep for a while. Each value will be there when you get around to reading it.
If your hardware is not buffering, then there is no strategy of polling and sleeping that will work for you. Your hardware must provide an interrupt, and you must write an interrupt-handling routine that will read every single new value as quickly as possible from the moment that it has been made available.
Here are some pseudo code that might help:
do
{
// Pseudo code
start_time = get_current_time();
do
{
temp_reg[0] = read_reg();
//Read the register here and copy the value into char array (temp_reg
if (timedout == 1 )
return -1;//Timedout
// Pseudo code
stop_time = get_current_time();
if (stop_time - start_time > some_limit) break;
} while (temp_reg[0] != 0 );
if (temp_reg[0] != 0)
{
usleep(some_time);
start_time = get_current_time();
}
} while (temp_reg[0] != 0 );
To turn the pseudo code into real code, see https://stackoverflow.com/a/2150334/4386427

itimer expiration

I was using a periodic timer and taking times between when two SIGALRM signals are received. what I observed was that itimer might expires a little before or little after the time I set. e.g. if I set it for 1m sec , it might expires at 0.9998msec or 1.0023msec.
Shouldn't the timer expiration would always be greater than what is set? less time taken is what I dont understand.
here's my code:
enter code here
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <stdlib.h>
#include <time.h>
#define INTERVAL 1000
struct timespec ti[100];
int s=0;
void ex(int i)
{int d=0;
struct timespec t[100],s1,s2;
for(d=0;d<99;d++)
{
s1= ti[d];
s2= ti[d+1];
printf("%u:%u\t%u:%u\t", s1.tv_sec, s1.tv_nsec, s2.tv_sec, s2.tv_nsec);
if ((s2.tv_nsec- s1.tv_nsec)<0) {
t[d].tv_sec = s2.tv_sec-s1.tv_sec-1;
t[d].tv_nsec = 1000000000 +s2.tv_nsec -s1.tv_nsec;
} else {
t[d].tv_sec = s2.tv_sec-s1.tv_sec;
t[d].tv_nsec = s2.tv_nsec-s1.tv_nsec;
}
printf("%u:%u\n",t[d].tv_sec,t[d].tv_nsec);
}
exit(0);
}
void alarm_wakeup (int i)
{
clock_gettime(CLOCK_MONOTONIC, &ti[s]);
s++;
if(s==100)
{ ex(0);
}
}
void main ()
{
struct itimerval tout_val;
tout_val.it_interval.tv_sec = 0;
tout_val.it_interval.tv_usec = INTERVAL;
tout_val.it_value.tv_sec = 0;
tout_val.it_value.tv_usec = INTERVAL;
setitimer(ITIMER_REAL, &tout_val,0);
signal(SIGALRM,alarm_wakeup); /* set the Alarm signal capture */
signal(SIGINT,ex);
while (1)
{
}
}
When the timer expires, the signal is raised and the timer is rescheduled.
However, there can be a delay between the signal being raised and the signal being handled - if the process isn't running already, it has to be rescheduled. This means that there is a potentially variable delay between the actual expiration of the timer and when the clock_gettime() call in your signal handler runs.
If this delay before the clock_gettime() call is higher one iteration than the next, then the time between the clock_gettime() calls will be slightly less than 1ms even though there was a 1ms gap between the subsequent timer expiries.
In diagrammatic form:
time: 0ms...............1ms...............2ms...............3ms
timer expiry: X X X X
signal handler runs: S S S S
You can see that the longer delay before the second signal handler ran made the third signal appear to be "early", even though the underlying timer was not.

Reading from queue delivers always wrong value

Here is my problem:
I'm using FreeRTOS with the Cortex-M3 MCU. I have an ISR called EXTI15_10, which
is trigger during a rising edge on the pins EXTI_Line10, EXTI_Line11..etc.
Within the ISR I set the variable "status" to some specified value and before leaving the ISR
I put the variable status in a queue and send it to my thread. That works fine.
The thread is periodically called and calls the function
xQueuePeek() to get the item from the queue. Note xQueuePeek()
gets the item from the queue without removing it from the queue.
This works fine too, but I only receive the correct value once.
That means, the interrupt is generated, status is set to a value and put in the
queue, threads reads the correct value. But all the next interrupts
set status correctly(I checked it before putting the item in the queue), but my
thread reads always the old value. Do I have here a problem with compiler
optimization and volatile? xQueueSendFromISR(), expects as second argument
a const void * and not volatile void *. What I'm doing wrong here?
The ISR:
void EXTI15_10_IRQHandler()
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
int status;
if (EXTI_GetITStatus(EXTI_Line10))
status = 100;
else if (EXTI_GetITStatus(EXTI_Line11))
status = 200
else if (EXTI_GetITStatus(EXTI_Line12))
status = 300;
else if (EXTI_GetITStatus(EXTI_Line13))
status = 400;
else if (EXTI_GetITStatus(EXTI_Line14))
status = 500;
else if (EXTI_GetITStatus(EXTI_Line15))
status = 600;
// Clear the pending interrupt bits
EXTI_ClearITPendingBit(EXTI_Lines15_10);
xQueueSendFromISR(queue, &status, &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
The thread:
static void thread_xy()
{
portTickType xLastExecutionTime;
xLastExecutionTime = xTaskGetTickCount();
int status_from_queue = 0;
for (;;) {
xLastExecutionTime = xTaskGetTickCount();
vTaskDelayUntil(&xLastExecutionTime, CHECK_AND_ENABLE_LEDS_DELAY);
if (queue != 0) {
if (xQueuePeek(queue, &status_from_queue, portMAX_DELAY))
// Received item from queue...
print("Status from queue = %d\n", status_from_queue);
}
}
}
If you're only ever peeking at the queue then, yes, you'll always get the same value, simply because you're leaving it there. A queue is a first-in-first-out data structure but, in order to get at the second value in the queue, you generally have to remove the first.
Consider the following sequence:
initial state queue = { }
interrupt adds 7 queue = { 7 }
application peeks (7) queue = { 7 }
interrupt adds 42 queue = { 7, 42 }
application peeks (7) queue = { 7, 42 }
interrupt adds 314159 queue = { 7, 42, 314159 }
application peeks (7) queue = { 7, 42, 314159 }
If you want to extract a value from the queue and use it, you need to get it instead of peeking at it. Without that, the queue will also eventually fill up.
I should also mention that there may be a race condition here that may well cause you problems. If your application is halfway to modifying the queue (by getting a value out of it) when an interrupt arrives, you're going to end up in all sorts of troubles since the queue will not be in a consistent state.
You need a way to stop (or, better, delay) the interrupt while the queue may be in an inconsistent state. That may be as simple as disabling interrupts while your application is modifying it (or it may require far more complex code if, for example, you're on a multi-processor system).
Of course, the xQueuePeek() (and other associated) code may already do that since you have an xQueueSendFromISR() which seems to indicate that such protection would already be part of the queueing implementation. I'm just raising that as something to watch out for.

Resources