Linux 定時器 延時工作佇列 外部中斷例程

2021-10-06 23:05:32 字數 3375 閱讀 2269

先上**:

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define gpio_max_num	256

#define timer_timeout_value 1

#define work_delay_value 1

#define use_timer 0

#define use_delay_work 1

#define dev_name "data_dect"

int irq_num = 0;

int irq_gpio = 0;

int pad_sai2_rxd = 0;

struct timer_list timer;

static struct delayed_work delay_work1;

int major;

static struct class *mod_class;

struct device *mod_dev;

dev_t devt;

struct completion data_dect_completion;

//裝置檔案寫函式

static ssize_t data_dect_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_ops)

//呼叫read返回,就說明出現了空白的現象

static ssize_t data_dect_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)

static long data_dect_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

static int data_dect_open(struct inode *node, struct file *filp)

static const struct file_operations data_dect_fops =

;static irqreturn_t irq_handler_func(int irq, void *dev)

void timer_function(unsigned long arg)

else }

//中斷裡面啟動延時工作佇列

//延時時間到時,開始執行下面的函式

static void delay_work_func(struct work_struct *work) }

static int __init mod_init(void)

irq_gpio = of_get_named_gpio(dts_of_node, "int-gpios", 0);

if(irq_gpio < 0)

pad_sai2_rxd = of_get_named_gpio(dts_of_node, "pad_sai2_rxd", 0);

if(gpio_is_valid(pad_sai2_rxd))

} else

irq_num = irq_of_parse_and_map(dts_of_node, 0); //獲取中斷號

if(irq_num < 0)

ret = request_irq(irq_num, irq_handler_func, irqf_trigger_rising, "gpio_interrupt", null); //申請中斷,上公升沿觸發

if(ret < 0)

#if use_timer

init_timer(&timer); //初始化定時器

timer.expires = jiffies+timer_timeout_value;

timer.function = timer_function;

add_timer(&timer);

#endif

#if use_delay_work

init_delayed_work(&delay_work1, delay_work_func);

schedule_delayed_work(&delay_work1, msecs_to_jiffies(work_delay_value));

#endif

init_completion(&data_dect_completion); //初始化完成量

//建立裝置節點

major = register_chrdev(0, dev_name, &data_dect_fops); //註冊字元裝置 返回主裝置號

if(major < 0)

mod_class = class_create(this_module, dev_name); //建立類

if (is_err(mod_class))

mod_dev = device_create(mod_class, null, mkdev(major, 0), null, dev_name); //建立裝置

if(is_err(mod_dev))

return 0;

error5:

class_destroy(mod_class);

error4:

unregister_chrdev(major, dev_name);

error3:

#if use_timer

del_timer(&timer);

#endif

#if use_delay_work

cancel_delayed_work_sync(&delay_work1);

#endif

error2:

gpio_free(pad_sai2_rxd);

error1:

return -1;

}module_init(mod_init);

static void __exit mod_exit(void)

module_exit(mod_exit);

module_author("lqd");

module_license("gpl");

上面的例程,通過裝置樹獲取中斷資訊。通過中斷,去觸發定時器/延時工作佇列去檢測gpio的電平

Linux 延時工作佇列的簡單使用

先上 如下 include include include include include include include include include include include include include include include include include include ...

Linux 工作佇列

工作佇列 work queue 是另外一種將工作推後執行的形式,它和tasklet有所不同。工作佇列可以把工作推後,交由乙個核心執行緒去執行,也就是說,這個下半部分可以 在程序上下文中執行。這樣,通過工作佇列執行的 能佔盡程序上下文的所有優勢。最重要的就是工作佇列允許被重新排程甚至是睡眠。那麼,什麼...

linux工作佇列

在linux核心中,對下半部 或者說推後執行的工作 的處理方式有好幾種,包括bh bottom half 軟中斷,tasklets和工作佇列等等。在2.6核心中,大名鼎鼎的bh處理被廢除,新增了更方便的工作佇列。工作佇列的方便之處在於它把工作推後,交由乙個核心執行緒去執行,這個核心執行緒總會在程序上...