I have an embedded Linux platform (the Beagleboard, running Angstrom Linux) with two devices connected:
We have a written a Linux kernel module which is responsible for the SPI data transfer. It has an IRQ handler in which spi_async is called which in turn causes an async callback method to be called.
My C++ application consists of three threads:
I am experiencing problems which seem to be caused by how the modules described above interact.
With the USB device turned on and I run the program with SCHED_RR and
then I am loosing 40% of the messages because the IRQ is triggered again before the spi-callback method is called! (I could still maybe find a workaround, but the problem is that I need fast response times which can no longer be reached in this case). I need to use the thread scheduling and the laser device so I am looking for a way to solve this case.
Question 1:
My assumption was that IRQ handlers and the callbacks triggered by spi_async in kernel space have higher priority than any thread running in user space (no matter if SCHED_RR or SCHED_OTHER). This would mean that turning to SCHED_RR in my application shouldn't slow down SPI transfer, but this seems very wrong. Is it?
Question 2:
How can I determine what happens here? Which debugging aids exist? (Or maybe you don't need any further information?) The main question for me is: why do I experience the problems only when the laser device is turned on. Could the USB driver consume so much time?
----- EDIT:
I have made the following observation:
The spi_async's callback calls wake_up_interruptible(&mydata->readq);
(with wait_queue_head_t readq;
). From the user space (my app) I call a function which results in poll_wait(file, &mydata->readq, wait);
When the poll returns the user space calls read()
.
SCHED_OTHER
I can see that the callback method first finishes before the read()
method in my kernel module is entered. SCHED_RR
read is entered before exiting the callback.This seems to proof that the priority of the user space threads is higher than the callback method's context's priority. Is there any way to change this behaviour and still have SCHED_RR
for my application's threads?
RT-Linux adopts a priority scheduling policy by default, that is, the system scheduler determines the order of execution according to the priority of each real-time task. High priority first execution, low priority post execution, thus ensuring rapid scheduling of real-time processes.
Loadable kernel modules have several advantages over monolithic "blobs" of code in the kernel: * Device drivers don't have to be hard-coded into the kernel. For example, if a new chip-set comes out that powers many webcams, that kernel module can simply be loaded instead of recompiling the kernel with the new module.
Linux and UNIX® systems use a priority system with 40 priorities, ranging from -20 (highest priority) to 19 (lowest priority. Processes started by regular users usually have priority 0.
Not all kernel thread have an RT priority. Imagine a periodically waking up thread that needs to do some background work is waking up. You don't want this thread to preemt your RT thread. So I guess your first assumption is wrong.
Based on your other questions :
It seems your main processing thread get in the way of the spi driver thread responsible for the spi data transfer.
Here is what happens :
What you can do is going back to normal scheduling, while playing with the various CONFIG_PREEMPT_ options. Or mess with the spi master driver, to ensure that any delayed work is queued with enough priority. Or even not queued at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With