I was using a hrtimer to implement a square wave output with a GPIO.
The System is AR9331 + openwrt, and it does not support PWM output.
The snippet is the following,
Initialization and Start
hrtimer_init(&(s_WS2812_control.send_timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
s_WS2812_control.send_timer.function = send_timer_handler;
hrtimer_start(&(s_WS2812_control.send_timer), ktime_set(0, 1000), HRTIMER_MODE_REL); //timeout now
My timeout handler is
send_period = ktime_set(0, 1000); //next timeout period is 1us
gpio_level = ~gpio_level;
gpio_set_value(out_pin, gpio_level);
hrtimer_forward(&send_timer,
send_timer.base->get_time(),
send_period);
My result was not logical since its timeout period(state-switching time) is not fixed. (observed in oscilloscope)
Sometimes it was something like 3.6us, sometimes it was 15us.
I think even if the execution time of handler was larger than 1us, the waveform should be a shift compared to 1us, but not like this, since timer interrupt is high-priority for system just like other hardware interrupt in my thought.
My Waveform is like this, the short/long period is like the above. I really can not understand why the GPIO output was like this.
my waveform link
Please help if anyone know some clues about this, or any suggestion for timer tutorial/learning material is welcome.
Thanks.
Related
queue_delayed_work(struct workqueue_struct *wq,struct delayed_work *dwork,unsigned long delay)
In the above function, is it possible to give delay that is less than one jiffy?
You can give a delay of zero or more jiffies. To get delay, kernel internally uses a timer. The earliest timer can expire is on the closest next tick. therefore the smallest delay possible is of 1 jiffies. In case of zero jiffies, the delayed work (dwork) will immediately start without any delay.
queue_delayed_work internally calls __queue_delayed_work where implementation for configuring timer is done. The minimum expire time is jiffies + delay. Refer links for more information.
To schedule your work less than jiffiy timer, You can make use of hrtimers(high resolution timer).
For more information related to implementing hrtimer read followinf links :
hrtimer repeating task in the Linux kernel
https://www.ibm.com/developerworks/library/l-timers-list/
The only delay which would be less than one jiffy is 0 jiffies in case of queue_delayed_work.
delay has type unsigned long and it's specified as "number of jiffies to wait before queueing".
when we call wait_event_interruptible ( wq,
condition) is it mandatory to call wake_up function when we use wait_event_interruptible ?
I'm working with a Linux embedded SMP system that does audio I/O using ALSA and an external USB Audio device, using a 3.6.6. kernel. Problem: I'm getting infrequent (once every few weeks) system hiccups that are causing the audio stream to die. Although it's tough to be sure, the hiccups look like they lock up the entire system for a few dozens of milliseconds.
I can write ALSA code to recover after one of these hiccups, but since it's ALSA some trial and error will be required. Add that to having to wait weeks for a reoccurrence, and I'll be up a creek with a crowbar. I really need a way to cause the problem on demand.
I'd like to write a C program that runs as root and blocks all other processes on the system for a given number of milliseconds. I imagine it would involve disabling interrupts, doing a delay loop (since the timers will probably fail), and then restoring interrupts. But, I have to do it in such a way that the whole system doesn't go belly up.
Any ideas on how I would write such a program?
You could try raising the priority of your process and then using one of the "realtime" scheduling algorithms (e.g. SCHED_FIFO). This will help make sure that your process gets scheduled more consistently, even if other processes are running.
Well, based on CL's tip, and on information from http://www.tldp.org/HOWTO/text/IO-Port-Programming, I wrote the following code:
#include <stdio.h>
int main(int argc, char *argv[]) {
long i, j;
printf("About to lock system!\n");
// Boost I/O privilege level
iopl(3);
// Clear interrupt flag, masking interrupts
asm("cli");
// Wait about a second (with some hijinks to keep
// the loop from being optimized into oblivion)
j = 1;
for (i = 0; i < 250000000; i++) {
j *= i;
}
// Restore interrupt flag, restoring interrupts
asm("sti");
// Restore I/O privilege level
iopl(0);
printf("Phew! Survived!\n");
return 0;
}
When run as root, it works! Although not everything is suspended (and it's not clear to me what is and what isn't), enough locks up that my ALSA stream fails quite nicely. So, now I can stimulate the problem and ensure my code can handle it.
One note: I'd assumed that between the CLI and STI, system timing routines would fail due to the lack of interrupts. However, when just for the heck of it I tried usleep(), the timing code worked! But, the code as a whole actually didn't, because the call re-enabled interrupts, making the tool useless. Hence the use of a simple delay loop.
What is the best way to do the following in Linux
while(continue)
{
render(); //this function will take a large fraction of the framerate
wait(); //Wait until the full frame period has expired.
}
On windows, waitable timers seems to work pretty well (within 1 ms). One way of proceeding is to use a separate thread that just sleeps and triggers a sychronization mechanism. However I do not know how much overhead there are in this.
Note: Accuracy is more important than high frequency: A timer with frequency 1.000 kHz is preffered over a timer with 1 MHz.
Assuming you're looking for an answer in the C language:
I don't remember the precision, but I recall I used to use the setitimer() function when I needed good precision.
Here's an example of how to use it: http://docs.oracle.com/cd/E23824_01/html/821-1602/chap7rt-89.html
//say delay_ms = 1
void Delay(const unsigned int delay_ms)
{
unsigned int x,y;
for(x=0;x<delay_ms;x++)
{
for(y=0;y<120;y++);
}
}
I am trying to use the C code above for my 8051 microcontroller. I wish to know what is the delay time generated above. I am using a 12MHz oscillator.
This is a truly lousy way to generate a time delay.
If you look at the assembler generated by the compiler then, from the data sheet for the processor variant that you are using, you can look up the clock cycles required for each instruction in the listing. Add these up and you will get the minimum delay time that this code will produce.
If you have interrupts enabled on your processor then the delay time will be extended by the execution time of any of the interrupt handlers that are triggered during the delay. These will add an essentially random amount of time to each delay function call depending upon the frequency and processing requirements of each interrupt.
The 8051 is built with hardware timer/counters that are designed to produce a signal after a user programmable delay. These are not affected by interrupt processing (it is true that the servicing of their trigger events may be delayed by another interrupt source) and so give a far more reliable duration for the delay .
I wonder if anyone of you know how to to use the function get_timer()
to measure the time for context switch
how to find the average?
when to display it?
Could someone help me out with this.
Is it any expert who knows this?
One fairly straightforward way would be to have two threads communicating through a pipe. One thread would do (pseudo-code):
for(n = 1000; n--;) {
now = clock_gettime(CLOCK_MONOTONIC_RAW);
write(pipe, now);
sleep(1msec); // to make sure that the other thread blocks again on pipe read
}
Another thread would do:
context_switch_times[1000];
while(n = 1000; n--;) {
time = read(pipe);
now = clock_gettime(CLOCK_MONOTONIC_RAW);
context_switch_times[n] = now - time;
}
That is, it would measure the time duration between when the data was written into the pipe by one thread and the time when the other thread woke up and read that data. A histogram of context_switch_times array would show the distribution of context switch times.
The times would include the overhead of pipe read and write and getting the time, however, it gives a good sense of big the context switch times are.
In the past I did a similar test using stock Fedora 13 kernel and real-time FIFO threads. The minimum context switch times I got were around 4-5 usec.
I dont think we can actually measure this time from User space, as in kernel you never know when your process is picked up after its time slice expires. So whatever you get in userspace includes scheduling delays as well. However, from user space you can get closer measurement but not exact always. Even a jiffy delay matters.
I believe LTTng can be used to capture detailed traces of context switch timings, among other things.