By liran bh | 5/16/2016 | Linux Kernel & Internals

Workqueue Example

#include <linux/kernel.h>    /* We're doing kernel work */
#include <linux/module.h>    /* Specifically, a module */
#include <linux/sched.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>    /* We want an interrupt */
#include <asm/io.h>
 
#define MY_WORK_QUEUE_NAME "WQsched.c"
 
static struct workqueue_struct *my_workqueue;
 
/* 
 * This will get called by the kernel as soon as it's safe
 * to do everything normally allowed by kernel modules.
 */
static void got_char(void *scancode)
{
    printk(KERN_INFO "Scan Code %x %s.\n",
           (int)*((char *)scancode) & 0x7F,
           *((char *)scancode) & 0x80 ? "Released" : "Pressed");
}
 
/* 
 * This function services keyboard interrupts. It reads the relevant
 * information from the keyboard and then puts the non time critical
 * part into the work queue. This will be run when the kernel considers it safe.
 */
 
irqreturn_t irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
    /* 
     * This variables are static because they need to be
     * accessible (through pointers) to the bottom half routine.
     */
    static unsigned char scancode;
    unsigned char status;
    static struct work_struct task;
    INIT_WORK(&task, got_char);
 
    /* 
     * Read keyboard status
     */
    status = inb(0x64);
    scancode = inb(0x60);
 
    queue_work(my_workqueue, &task);
 
    return IRQ_HANDLED;
}
 
/* 
 * Initialize the module - register the IRQ handler 
 */
int init_module()
{
    my_workqueue = create_workqueue(MY_WORK_QUEUE_NAME);
 
    /* 
     * Since the keyboard handler won't co-exist with another handler,
     * such as us, we have to disable it (free its IRQ) before we do
     * anything.  Since we don't know where it is, there's no way to
     * reinstate it later - so the computer will have to be rebooted
     * when we're done.
     */
    free_irq(1, NULL);
 
    /* 
     * Request IRQ 1, the keyboard IRQ, to go to our irq_handler.
     * SA_SHIRQ means we're willing to have othe handlers on this IRQ.
     * SA_INTERRUPT can be used to make the handler into a fast interrupt.
     */
    return request_irq(1,    /* The number of the keyboard IRQ on PCs */
               irq_handler,    /* our handler */
               SA_SHIRQ, "test_keyboard_irq_handler",
               (void *)(irq_handler));
}
 
/* 
 * Cleanup 
 */
void cleanup_module()
{
    /* 
     * This is only here for completeness. It's totally irrelevant, since
     * we don't have a way to restore the normal keyboard interrupt so the
     * computer is completely useless and has to be rebooted.
     */
    free_irq(1, NULL);
}
 
/* 
 * some work_queue related functions are just available to GPL licensed Modules
 */
MODULE_LICENSE("GPL");

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now