先上**:
#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處理被廢除,新增了更方便的工作佇列。工作佇列的方便之處在於它把工作推後,交由乙個核心執行緒去執行,這個核心執行緒總會在程序上...