Button驱动学习

本文详细阐述了如何在一个设备驱动中实现按键中断,包括按键与中断的连接、中断请求函数的注册以及中断服务函数的设计。文章还介绍了如何在中断服务函数中判断按键的按下或释放,并通过等待队列实现事件同步机制。

是一个char字符类型的驱动

按键与一个中断相连,所以在open的时候要申请一个中断,其中会包含

static int s3c24xx_buttons_open(struct inode *inode, struct file *file)

{

int i;

int err = 0;

for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {

if (button_irqs[i].irq < 0) {

continue;

}

err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,

button_irqs[i].name, (void *)&button_irqs[i]);

if (err)

break;

}

if (err) {释放资源

}

return -EBUSY;

}

ev_press = 1;

return 0;

}

为每一个button都申请一个中断号,dev_id就是该button的数组button_irqs的一维的地址,中断发生后,dev_id就会传到中断服务函数中,中断服务函数根据dev_id判断是那个button按下了。

request_irq(IRQ_EINT8, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,

"KEY0", (void *)&button_irqs[i]);

buttons_interrupt是与该中断号对应的中断服务程序,dev_id定义为button_irqs一维的地址?

int request_irq(unsigned int irq,

irq_handler_t handler,

unsigned long flags, const char *devname, void *dev_id)

参数说明

在发生对应于第 1个参数 irq 的中断时,则调用第 2 个参数 handler 指定的中断服务函数(也就是把 handler() 中断服务函数注册到内核中 )。

第 3 个参数 flags 指定了快速中断或中断共享等中断处理属性。在 2.6 教新的内核里(我的是 2.6.27 ~ 2.6.31 ),在 linux/interrupt.h 中定义操作这个参数的宏如下:

第 4 个参数 name 通常是设备驱动程序的名称。改值用在 /proc/interrupt 系统 (虚拟) 文件上,或内核发生中断错误时使用。

第 5 个参数 dev_id 可作为共享中断时的中断区别参数,也可以用来指定中断服务函数需要参考的数据地址。

返回值

函数运行正常时返回 0 ,否则返回对应错误的负值。

static struct button_irq_desc button_irqs [] = {

{IRQ_EINT8 , S3C2410_GPG0 , S3C2410_GPG0_EINT8 , 0, "KEY0"},

{IRQ_EINT11, S3C2410_GPG3 , S3C2410_GPG3_EINT11 , 1, "KEY1"},

{IRQ_EINT13, S3C2410_GPG5 , S3C2410_GPG5_EINT13 , 2, "KEY2"},

{IRQ_EINT14, S3C2410_GPG6 , S3C2410_GPG6_EINT14 , 3, "KEY3"},

{IRQ_EINT15, S3C2410_GPG7 , S3C2410_GPG7_EINT15 , 4, "KEY4"},

{IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG11_EINT19, 5, "KEY5"},

};

static struct miscdevice misc = {

.minor = MISC_DYNAMIC_MINOR,

.name = DEVICE_NAME,

.fops = &dev_fops,

};

在初始化代码中就是注册一下驱动。

static int __init dev_init(void)

{

int ret;

ret = misc_register(&misc);

printk (DEVICE_NAME"\tinitialized\n");

return ret;

}

中断服务函数

static irqreturn_t buttons_interrupt(int irq, void *dev_id)

{

struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;

int down;

// udelay(0);

down = !s3c2410_gpio_getpin(button_irqs->pin);

//按下down = 1 = !0 //松开down = 0 = !1

if (down != (key_values[button_irqs->number] & 1)) { // Changed

//1 != 0&1 //0 != 1&1 &优先级比!=低

key_values[button_irqs->number] = '0' + down;

// = ‘0’+1 = ‘1’ // = ‘0’+0 = ‘0’

ev_press = 1;

wake_up_interruptible(&button_waitq);

}

return IRQ_RETVAL(IRQ_HANDLED);

}

更新key_values将其传给read

执行机制:

通过一个等待队列实现wince中的事件同步机制

什么是等待队列?

在软件开发中任务经常由于某种条件没有得到满足而不得不进入睡眠状态,然后等待条件得到满足的时候再继续运行,进入运行状态。这种需求需要等待队列机制的支持。Linux中提供了等待队列的机制,该机制在内核中应用很广泛。

在Linux内核中使用等待队列的过程很简单,首先定义一个wait_queue_head,然后如果一个task想等待某种事件,那么调用wait_event(等待队列,事件)就可以了。

clip_image002

首先创建一个等待队列头button_waitq

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

App中调用read函数,驱动中调用s3c24xx_buttons_read函数,

static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

{

unsigned long err;

if (!ev_press) {

if (filp->f_flags & O_NONBLOCK)

return -EAGAIN;

else

wait_event_interruptible(button_waitq, ev_press); // ev_press是等待条件

}

ev_press = 0;

err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));

return err ? -EFAULT : min(sizeof(key_values), count);

}

s3c24xx_buttons_read中添加一个事件到等待队列button_waitq中,其中ev_press是等待条件,那么App中的read函数调用驱动中的s3c24xx_buttons_read函数,此函数会阻塞在wait_event_interruptible处等待中断。

然后,如果产生了中断,中断服务函数中的:

key_values[button_irqs->number] = '0' + down;

ev_press = 1;

wake_up_interruptible(&button_waitq);

会唤醒等待队列button_waitq中的可以被中断的任务,同时设置ev_press为1

这样,s3c24xx_buttons_read中的阻塞函数将得以执行下去,对等待条件复位,复制键值。

转载于:https://www.cnblogs.com/yanhc/archive/2011/09/13/2175221.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值