how to do debug an interrupt handler - linux-kernel

I am doing one assignment where I have to write and interrupt handler for Keyboard. So in this assignment we have to log the key stroke so it is allowed to do File I/O and we are using Work queue for that.
I know it is not allowed to sleep in Interrupt handler and so we cannot use any file i/o or printk in interrupt handler.
So in real industry how to debug and interrupt handler OR what I can do if I want to debug something ?

Yes! this is correct we can not use printk inside an ISR. As i studied in RTOS(Real time operating System) during interrupt handling it creates message log and save required information in the log file which you can see later.
The similar thing is also available for latest Kernel. Using trace_printk you can debug time critical place. I haven't used this before so no sample for this. You can follow this link to know more about trace_printk.

Related

When save states while dealing with tasklets?

I'm reading Linux Kernel development and get confused in the tasklets chapter (https://doc.lagout.org/operating%20system%20/linux/Linux%20Kernel%20Development%2C%203rd%20Edition.pdf page143).
In the tasklet_schedule function, the interrupt state is saved while in the taslet_action it is not. The author explains that the context is not saved in taslet_action because the function knows that interrupts are always enabled. I fail to understand how does the set of interrupts interfere with saving the context? Thank you!
The author states that tasklet_schedule can be called with either interrupts disabled or enabled. Since it wants them disabled, it needs to save whether they are already disabled. Then after the work is done it knows whether to enable them (if they were enabled prior to the call it enables them, if they were disabled prior to the call it leaves them disabled). In contrast, tasklet_action is only called with interrupts enabled, so there is no point in checking their state. They always get disabled and enabled on return.
In case of tasklet_schedule :
We do not want interrupt to disturb us when we are scheduling a tasklet, so we have to disable it. But we also know that, when we are done with scheduling the tasklet, we want to go back to the state of IRQ as it was before schedule tasklet was called. To achieve this, we save the state of the IRQ register before doing anything, then disable the IRQ as per our requirement, do the scheduling, now before going back restore the state of the IRQ and then return from the function.
Now coming to the complicated part, Why dont we need to save the IRQ when executing the tasklet i.e when the handler calls the tasklet function ?
To understand that we need to look at two different paragraphs :
On page 141 :
The softirq handlers run with interrupts enabled and cannot
sleep .While a handler runs, softirqs on the current processor are
disabled.Another processor, however, can exe-cute other softirqs. If
the same softirq is raised again while it is executing, another
processor can run it simultaneously.
So this declares that interrupts are always enabled.
Now going to pg 143 :
Disable local interrupt delivery (there is no need to first save their state because the code here is always called as a softirq
handler and interrupts are always enabled) and retrieve the
tasklet_vec or tasklet_hi_vec list for this processor
So we can conclude that we dont need to save the IRQ state as we already know its state and it will remain so in all the conditions so we just disable the IRQ and enable it later.

How can I safely print something to kmsg in interrupt context

I have a requirement to print a message to kernel log in an Irq service routine, so it's in "interrupt context". I understand that printk is not recommended for this scenario, so what would be the best alternatives here?
Thanks for if any suggestions.
I heard of one option about printk_deferred, I noticed this is used in scheduler, but haven't yet found where it's used in irq isr. Can anyone explain what's the difference between printk_deferred and printk?
One common idea is from interrupt handler we can update variables or info to be printed and then from kernel thread print that value to kernel log buffer. This way handler will remain intact and our objective will also be achieved.

What is channel event system?

I am working on some project Where I have to deal with uc ATxmega128A1 , But being a beginner to a ucontrollers I want to know what is this channel event system regarding ucs.
I have referred a link http://www.atmel.com/Images/doc8071.pdf but not getting it.
The traditional way to do things the channel system can do is to use interrupts.
In the interrupt model, the CPU runs the code starting with main(), and continues usually with some loop. When an particular event occurs, such as a button being pressed, the CPU is "interrupted". The current processing is stopped, some registers are saved, and the execution jumps to some code pointed to by an interrupt vector called an interrupt handler. This code usually has instructions to save register values, and this is added automatically by the compiler.
When the interrupting code is finished, the CPU restores the values that the registers previously had and execution jumps back to the point in the main code where it was interrupted.
But this approach takes valuable CPU cycles. And some interrupt handlers don't do very much expect trigger some peripheral to take an action. Wouldn't it be great it these kinds of interrupt handlers could be avoided and have the mC have the peripherals talk directly to each other without pausing the CPU?
This is what the event channel system does. It allows peripherals to trigger each other directly without involving the CPU. The CPU continues to execute instructions while the channel system operates in parallel. This doesn't mean you can replace all interrupt handlers, though. If complicated processing is involved, you still need a handler to act. But the channel system does allow you to avoid using very simple interrupt handlers.
The paper you reference describes this in a little more detail (but assumes a lot of knowledge on the reader's part). You have to read the actual datasheet of your mC to find the exact details.

For a shared interrupt line how do I find which interrupt handler to use?

For a shared interrupt line,I can have several interrupt handlers. The kernel will sequentially invoke all the handlers for that particular shared line.
As far as I know, each handler, when invoked informs the kernel whether it was the correct handler to be invoked or not.
My questions is how is this determined,is there a way it checks a memory mapped register that tells status of a particular device or is there some other hardware mechanism ? How does the handler know that the corresponding device is indeed the one that issued the interrupt or not ?
Is this information relayed through the interrupt controller that is between the devices and the processor interrupt line ??
The kernel will sequentially invoke all the handlers for that particular shared line.
Exactly. Say Dev1 and Dev2 shares the IRQ10. When an interrupt is generated for IRQ10, all ISRs registered with this line will be invoked one by one.
In our scenario, say Dev2 was the one that generated the interrupt. If Dev1's ISR is registered first, than its ISR (i.e Dev1's ISR) only called first. In that ISR, the interrupt status register will be verified for interrupt. If no interrupt bit is set (which is the case, cause Dev2 raised the interrupt) then we can confirm that interrupt was not generated by Dev1 - so Dev1's ISR should return to the kernel IRQ_NONE - which means:"I did not handled that interrupt", so on the kernel continues to the next ISR (i.e Dev2's ISR), which in turn, will indeed verify that its corresponding device generated the interrupt, thus, this handler should handle it and eventually return IRQ_HANDLED - which means:"I handled this one".
See the return values IRQ_NONE/IRQ_HANDLED for more information.
How does the handler know that the corresponding device issued the interrupt or not ?
By reading the Interrupt status register only.
Is this information relayed through the interrupt controller that is between the devices and the processor interrupt line ??
I'm not sure about this. But the OS will take care of calling ISRs based on the return values from ISR.

Trap Dispatching on Windows

I am actually reading Windows Internals 5th edition and i am enjoying, although isn't a easy book to read and understand.
I am confused about IRQLs and IDT Table.
I read that windows implement custom priorization levels with IRQL and the Plug and Play Manager maps IRQ from devices to IRQL.
Alright, so, IRQLs are used for Software and Hardware interrupts, and for exceptions is used the Exception Dispatch handler.
When one device generates an interrupt, the interrupt controller pass this information to the CPU with the IRQ.
So Windows takes this IRQ and translates to IRQL to schedule when to execute the routine (routine that IDT[IRQ_VALUE] is pointing to?
Is that what is happening?
Yes, on a very high level.
Everything starts with a kernel trap. Kernel trap handler handles interrupts, exceptions, system service calls and virtual memory pager.
When an interrupt happens (line based - using dedicated pin or message based- writing to an address) windows uses IRQL to determine the priority of the interrupt and uses this to see if the interrupt can be served or not during that time. HAL does the job of translating the IRQ to IRQL.
It then uses IRQ to get an index of the IDT to find the appropriate ISR routing to invoke. Note there can be multiple ISR associated for a given IRQ. All of them execute in order.
Each processor has its own IDT so you could potentially have multiple ISR's running at the same time.
Exception dispatch, as I mentioned before, is also handled by the kernel trap but the procedure for it is different. It usually starts by checking for any exception handlers by stack unwinding, then checking for debugger port etc.

Resources