驅動程式 - Linux Device Driver (LDD) - 使用範例 - C/C++ (PocketBeagle) - Tasklet



tasklet也是屬於softirq的一種,差別在於執行順序是排在softirq後面且不會有重複進入問題(reentrant),加上不是靜態編譯,因此,不需要特別修改Kernel就可以使用,因此,是一種相當適合應用在高優先級別的延遲處理機制,當然,高優先級別的機制是不適合處理太過耗時的東西,這點還是需要特別注意

使用步驟:

1. tasklet_init()
2. tasklet_schedule()
3. tasklet_kill()

main.c

#include <linux/init.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Steward Fu");
MODULE_DESCRIPTION("Linux Driver");
 
#define BUTTON 27

struct tasklet_struct mytask = {0};

void tasklet_handler(unsigned long data)
{
    printk("%s\n", __func__);
}

static irqreturn_t irq_handler(int irq, void *arg)
{
    tasklet_schedule(&mytask);
    return IRQ_HANDLED;
}

int ldd_init(void)
{
    tasklet_init(&mytask, tasklet_handler, 0);
    request_irq(gpio_to_irq(BUTTON), irq_handler, IRQF_TRIGGER_RISING, "gpio_irq", NULL);
    return 0;
}
 
void ldd_exit(void)
{
    free_irq(gpio_to_irq(BUTTON), NULL);
    tasklet_kill(&mytask);
}
 
module_init(ldd_init);
module_exit(ldd_exit);

ldd_init: 設定GPIO中斷以及tasklet延遲處理副程式
irq_handler: 安排一個tasklet延遲處理
tasklet_handler: 列印字串
ldd_exit: 釋放中斷資源以及刪除tasklet

完成

# tasklet_handler