I should write a linux device driver code that periodically print an information. This information should be printed until the module will be unloaded. I should write something like this
int boolean = 1;
static int hello_init(void)
{
while(boolean){
printk(KERN_ALERT "An information\n");
msleep(1000);
}
return 0;
}
static void hello_exit(void)
{
boolean=0;
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Obviously, this code doesn't work (I suppose because __init and __exit can't work concurrently, so the boolean value cannot change). Can anyone help me to solve this problem?
If the task you are performing periodically needs to go to sleep, you may not be able to use timer functions. Delayed workqueues can be used in that situation -- they are not as precise as the hrtimer but if the timing requirements aren't too strict, they work just fine.
I recently posted a question about doing things periodically here:
Calling spi_write periodically in a linux driver
I posted a workqueue example in it that you may find useful.
I also found this documentation to be helpful:
http://www.makelinux.net/ldd3/chp-7-sect-6
However, some changes have been made to the API since it was published. This article outlines these changes:
http://lwn.net/Articles/211279/
You should set up a timer with hrtimer_start() at the hello_init().
The struct hrtimer *timer contains a function pointer what will be called at the time you set. That callback function should contains the printk(). You have to renew the timer each time the callback called.
Don't forget to call the hrtimer_cancel() at the hello_exit().
You can use the ktime_set() function to calculate the expire time you want. Have a look here, there are some related and useful functions: High-resolution timers
Related
I am doing some embedded system work and have a couple of question. I have a timer function which fires every 100ms. I now need to get the actual time once the system has started .
Currently my code is something like this:
struct timer
{
uint8_t millis_100;
uint8_t minute_455;
}
void tick()
{
//fires evry 100ms
timer_task.millis_100++;
}
However I am confused if this is the right approach since I will need to check if millis_100 overflowed to 0 and then increment it inside the ISR routine. If I need more than 455*2^8-1 then I would need to put another if statement in the ISR. IS this how system ticks are used to make software timers? Or is there a more elegant solution?
If you are worried about the timer overflowing, why not use an unsigned long variable ??
Check the timer implementation in linux kernel timer.c, timer.h
For more details, read the section The Timer API in LDD3/ch07
I have been trying to intercept the system call at the kernel level. I got the basic idea from this question . The system call I was trying to intercept was the fork(). So I found out the address of the sys_fork() from System.map and it turned out to be 0xc1010e0c.Now I wrote the module as below.
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/unistd.h>
#include<linux/semaphore.h>
#include<asm/cacheflush.h>
MODULE_LICENSE("GPL");
void **sys_call_table;
asmlinkage int (*original_call)(struct pt_regs);
asmlinkage int our_call(struct pt_regs regs)
{
printk("Intercepted sys_fork");
return original_call(regs);
}
static int __init p_entry(void)
{
printk(KERN_ALERT "Module Intercept inserted");
sys_call_table=(void *)0xc1010e0c;
original_call=sys_call_table[__NR_open];
set_memory_rw((long unsigned int)sys_call_table,1);
sys_call_table[__NR_open]=our_call;
return 0;
}
static void __exit p_exit(void)
{
sys_call_table[__NR_open]=original_call;
set_memory_ro((long unsigned int)sys_call_table,1);
printk(KERN_ALERT "Module Intercept removed");
}
module_init(p_entry);
module_exit(p_exit);
However , after compiling the module and when I tried to insert it to the kernel, I got the following from the dmesg output.
Of course its not intercepting the system call.Can you help me figure out the problem? I am using 3.2.0-4-686 version of Linux kernel.
http://lxr.linux.no/linux+*/arch/x86/mm/pageattr.c#L874 says
if (*addr & ~PAGE_MASK) {
*addr &= PAGE_MASK;
/*
* People should not be passing in unaligned addresses:
*/
WARN_ON_ONCE(1);
}
So the warning is because your sys_call_table variable is not page-aligned.
It should be said that patching the system call table is officially discouraged by the kernel maintainers, and they've put some deliberate roadblocks in your way -- you've probably already noticed that you can't access the real sys_call_table symbol, and the write protection is also deliberate. If you can possibly find another way to do what you want, then you should. Depending on your larger goal, you might be able to accomplish it using ptrace and no kernel module at all. The trace_sched_process_fork hook may also be useful.
original_call=sys_call_table[__NR_open];
....
sys_call_table[__NR_open]=our_call;
If you're intercepting fork, the entry for open is not what you want to change.
And instead of the address of the sys_fork() from System.map, you should have used the address of sys_call_table.
It is not clear if you solved your problem, but depending on how you test your module glib don't use sys_fork anymore, but use sys_clone instead.
I am trying to implement my own new schedule(). I want to debug my code.
Can I use printk function in sched.c?
I used printk but it doesn't work. What did I miss?
Do you know how often schedule() is called? It's probably called faster than your computer can flush the print buffer to the log. I would suggest using another method of debugging. For instance running your kernel in QEMU and using remote GDB by loading the kernel.syms file as a symbol table and setting a breakpoint. Other virtualization software offers similar features. Or do it the manual way and walk through your code. Using printk in interrupt handlers is typically a bad idea (unless you're about to panic or stall).
If the error you are seeing doesn't happen often think of using BUG() or BUG_ON(cond) instead. These do conditional error messages and shouldn't happen as often as a non-conditional printk
Editing the schedule() function itself is typically a bad idea (unless you want to support multiple run queue's etc...). It's much better and easier to instead modify a scheduler class. Look at the code of the CFS scheduler to do this. If you want to accomplish something else I can give better advice.
It's not safe to call printk while holding the runqueue lock. A special function printk_sched was introduced in order to have a mechanism to use printk when holding the runqueue lock (https://lkml.org/lkml/2012/3/13/13). Unfortunatly it can just print one message within a tick (and there cannot be more than one tick when holding the run queue lock because interrupts are disabled). This is because an internal buffer is used to save the message.
You can either use lttng2 for logging to user space or patch the implementation of printk_sched to use a statically allocated pool of buffers that can be used within a tick.
Try trace_printk().
printk() has too much of an overhead and schedule() gets called again before previous printk() calls finish. This creates a live lock.
Here is a good article about it: https://lwn.net/Articles/365835/
It depends, basically it should be work fine.
try to use dmesg in shell to trace your printk if it is not there you apparently didn't invoked it.
2396 if (p->mm && printk_ratelimit()) {
2397 printk(KERN_INFO "process %d (%s) no longer affine to cpu%d\n",
2398 task_pid_nr(p), p->comm, cpu);
2399 }
2400
2401 return dest_cpu;
2402 }
there is a sections in sched.c that printk doesn't work e.g.
1660 static int double_lock_balance(struct rq *this_rq, struct rq *busiest)
1661 {
1662 if (unlikely(!irqs_disabled())) {
1663 /* printk() doesn't work good under rq->lock */
1664 raw_spin_unlock(&this_rq->lock);
1665 BUG_ON(1);
1666 }
1667
1668 return _double_lock_balance(this_rq, busiest);
1669 }
EDIT
you may try to printk once in 1000 times instead of each time.
How does one create a timer in C?
I want a piece of code to continuously fetch data from a gps parsers output.
Are there good libraries for this or should it be self written?
Simplest method available:
#include <pthread.h>
void *do_smth_periodically(void *data)
{
int interval = *(int *)data;
for (;;) {
do_smth();
usleep(interval);
}
}
int main()
{
pthread_t thread;
int interval = 5000;
pthread_create(&thread, NULL, do_smth_periodically, &interval)
...
}
On POSIX systems you can create (and catch) an alarm. Alarm is simple but set in seconds. If you need finer resolution than seconds then use setitimer.
struct itimerval tv;
tv.it_interval.tv_sec = 0;
tv.it_interval.tv_usec = 100000; // when timer expires, reset to 100ms
tv.it_value.tv_sec = 0;
tv.it_value.tv_usec = 100000; // 100 ms == 100000 us
setitimer(ITIMER_REAL, &tv, NULL);
And catch the timer on a regular interval by setting sigaction.
One doesn't "create a timer in C". There is nothing about timing or scheduling in the C standard, so how that is accomplished is left up to the Operating System.
This is probably a reasonable question for a C noob, as many languages do support things like this. Ada does, and I believe the next version of C++ will probably do so (Boost has support for it now). I'm pretty sure Java can do it too.
On linux, probably the best way would be to use pthreads. In particular, you need to call pthread_create() and pass it the address of your routine, which presumably contains a loop with a sleep() (or usleep()) call at the bottom.
Note that if you want to do something that approximates real-time scheduling, just doing a dumb usleep() isn't good enough because it won't account for the execution time of the loop itself. For those applications you will need to set up a periodic timer and wait on that.
SDL provides a cross platform timer in C.
http://www.libsdl.org/cgi/docwiki.cgi/SDL_AddTimer
If your using Windows, you can use SetTimer,else you can build a timer out of timeGetTime and _beginthreadex along with a queue of timers with callbacks
The question about a timer is quite unspecific, though there are two functions that come to my mind that will help you:
sleep() This function will cause execution to stop for a specified number of seconds. You can also use usleep and nanosleep if you want to specify the sleeptime more exactly
gettimeofday() Using this function you are able to stop between to timesteps.
See manpages for further explanation :)
If the gps data is coming from some hardware device, like over a serial port, then one thing that you may consider is changing the architecture around so that the parser kicks off the code that you are trying to run when more data is available.
It could do this through a callback function or it could send an event - the actual implementation would depend on what you have available.
gcc 4.4.3
vc++ 2008
I would like to make a timer application would be portable on windows and linux. However, would be suffice to start with.
My idea is to start a timer and set it for a specified number of seconds. When the time expires call a callback function.
Is that the best way to do this?
Many thanks,
There are many ways to do a timer. It is not hard but you need to think exactly what you want. If you want to call a callback, you usually use a thread that sleep until your delay is elapsed, before calling your callback. If you don't want to use a thread, you can call periodically a checker function that compute the time delta.
You api will be a function taking the delay and a function pointer plus the callback parameters. It will launch a thread that will sleep for the delay, then call the callback with the given parameters.
Check general purpose libraries, they usually have timers implemented (gtk+ glib, boost::timer I think).
my2c
Edit:
For the portability part, you have of course to write two versions of your timer function. If you use thread that means it is better to use a lib. As libs give you timers ... Use a lib :)
Windows and linux do timers differently. I suggest that you encapsulate the timing functionality into a class. You'll have to write the class twice (once for each platform) but then the rest of the program can be the same.
Alternatively you can use a toolkit where somebody else gas already done it for you. e.g. QT or Boost.
I have worked with several such timers in both C and C++. For C GTK example on the following url may be helpful http://zetcode.com/tutorials/gtktutorial/gtkevents/. In C++ I used glib timer https://developer.gnome.org/glibmm/2.34/classGlib_1_1SignalTimeout.html (although it is not precise). I also work with libev (which uses epoll() on Linux and select() on Windows) for better precision timer. For C, I present an example below
//This program is demo for using pthreads with libev.
//Try using Timeout values as large as 1.0 and as small as 0.000001
//and notice the difference in the output
//(c) 2013 enthusiasticgeek for stack overflow
//Free to distribute and improve the code. Leave credits intact
//On Ubuntu (assuming libev is installed) compile with the command - gcc -g test.c -o test -lev
#include <ev.h>
#include <stdio.h> // for printf
#include <stdlib.h>
double timeout = 1.0; //seconds
ev_timer timeout_watcher;
int timeout_count = 0;
static void timeout_cb (EV_P_ ev_timer *w, int revents) // Timer callback function
{
++timeout_count;
printf("%d\n", timeout_count);
w->repeat = timeout;
ev_timer_again(loop, &timeout_watcher); //Start the timer again.
}
int main (int argc, char** argv)
{
struct ev_loop *loop = EV_DEFAULT; //or ev_default_loop (0);
ev_timer_init (&timeout_watcher, timeout_cb, timeout, 0.); // Non repeating timer. The timer starts repeating in the timeout callback function
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive
ev_loop(loop, 0);
return 0;
}
For more docs on libev view http://doc.dvgu.ru/devel/ev.html