OK6410 linux设备驱动:Button驱动-中断的形式

如果不能成功注册按键驱动,请参考 OK6410 linux设备驱动:Button驱动-轮询的形式

使用的是查询的方式来获取按键值,此方法简单,但是是非常消耗cpu资源,不建议使用。以下代码是使用中断的方式进行按键值获取。采用了poll和信号量同步的方式实现。


#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>  
#include <linux/init.h> 
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <asm/ioctls.h>     /* TIOCOUTQ, TIOCINQ */
#include <asm/uaccess.h>
#include <asm/io.h>
#include <mach/gpio-bank-m.h>
#include <asm/irq.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/delay.h>  
#include <asm/irq.h>  
#include <asm/io.h>  
#include <linux/sched.h>



MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("LEO");
MODULE_DESCRIPTION("This is a Button Device Test by leo");

//S3C64XX_GPMD
volatile unsigned long *gpmcon = NULL;
volatile unsigned long *gpmdat = NULL;
volatile unsigned long *gpncon = NULL;
volatile unsigned long *gpndat = NULL;


static int Button_write(struct file *file,const char __user *buf,size_t count,loff_t * ppos);
static int Button_open(struct inode *inode,struct file *file);
static int Button_ioctl(struct file *file, unsigned int cmd,unsigned long arg );
static int Button_read(struct file *file,const char __user *buf,size_t count,loff_t * ppos);
static int Button_close(struct inode *inode,struct file *file);
static irqreturn_t Buttons_irq(int irq,void *dev_id);
static unsigned Button_poll(struct file *file, poll_table *wait);
static int Button_fasync (int fd, struct file *filp, int on);


/* 中断事件标志, 中断服务程序将它置1,read将它清0 */

static volatile unsigned int ev_press = 0;
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
static unsigned char key_val;
static struct class *Button_leo_class;
static struct class_device *Button_leo_class_dev;

static struct file_operations Button_fops={
        .owner = THIS_MODULE,
        .open = Button_open,
        .write = Button_write,
        .read = Button_read,
    //.ioctl = Button_ioctl,
        .unlocked_ioctl =  Button_ioctl,
        .release = Button_close,
        .poll = Button_poll,
        .fasync = Button_fasync,
    };
int major;
static struct irqaction Button0_IRQ={
    .name = "button0-3_byleo",
    .flags = IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING | IRQF_SHARED,
    .handler = Buttons_irq,
    };
typedef struct {
        int irqNum;
        int ButtonNum;
        char *name;  
    }_Button_irq_t;
 _Button_irq_t Button_irq_t[4]={
    {IRQ_EINT(0), 0, "Button1_leo"},  
    {IRQ_EINT(1), 1, "Button2_leo"},  
    {IRQ_EINT(2), 2, "Button3_leo"},  
    {IRQ_EINT(3), 3, "Button4_leo"},  
 };


static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = "Button_leo",
    .fops = &Button_fops,
 };

static struct fasync_struct *button_async;

static int Button_init(void)
{
    printk( "\n Button module by Button init\n");
    int minor;
    int val;
    #if 0
    major=register_chrdev(0, "Button_leo", &Button_fops);
    if(major<0)
    {
        printk("Button_leo Can't register major number \n");
        return major;
    }
    Button_leo_class = class_create (THIS_MODULE, "Button_leo_class");
    if(IS_ERR(Button_leo_class))
    {
        return PTR_ERR (Button_leo_class);
    }
    Button_leo_class_dev = device_create(Button_leo_class,NULL,MKDEV (major, 0),NULL,"Button_Interrupt_leo");//自动创建设备节点
    if(unlikely (IS_ERR(Button_leo_class_dev)))
    {
        return PTR_ERR (Button_leo_class_dev);
    }
    #else
    val = misc_register (&misc);

    #endif

    //LED 地址映射
    gpmcon = (volatile unsigned long *)ioremap (0x7F008820l, 16);
    gpmdat = gpmcon + 1 ;
    //Button 地址映射
    gpncon = (volatile unsigned long *)ioremap (0x7F008830l, 16);
    gpndat = gpncon + 1 ;
    return 0;
}
static void Button_exit(void)
{
    printk( "Button module by leo exit\n");
    int minor;
    int i ;

    iounmap(gpmcon);
    iounmap(gpncon);
    for (i = 0; i <4; i++)  
    {  
           if (Button_irq_t[i].irqNum < 0)
           {
                 continue;
           }
        free_irq(Button_irq_t[i].irqNum,(void*)&Button_irq_t[i]);     
    } 
    #if 0
    device_unregister (Button_leo_class_dev);
    class_destroy (Button_leo_class);
    unregister_chrdev(major,&Button_fops);
    #else
    misc_deregister (&misc);
    #endif
}

static int Button_open(struct inode *inode,struct file *file)
{
    printk( "Button module by leo Open\n");
    int i;
    int err=0;
    /*配置为输出引脚 M0,M1 M2 M3*/
    *gpmcon &=~ ((0x0f<<(0*4)) | (0x0f<<(1*4)) | (0x0f<<(2*4)) | (0x0f<<(3*4)));//*gpmcon = (volatile unsigned long *)ioremap (0x7F008820l, 16);
    *gpmcon |= ((0x01<<(0*4)) | (0x01<<(1*4)) | (0x01<<(2*4)) | (0x01<<(3*4)));
    for(i=0;i<4;++i)
    {   
        if(Button_irq_t[i].irqNum<0)
        {
            continue;
        }
        err = request_irq (Button_irq_t[i].irqNum, Buttons_irq , IRQF_TRIGGER_FALLING, Button_irq_t[i].name, (void *)&Button_irq_t[i]);

        if(err)
        {

            printk("request_irq %d return value is %d \n",Button_irq_t[i].irqNum,err);
            disable_irq(Button_irq_t[i].irqNum);
            free_irq(Button_irq_t[i].irqNum, (void *)&Button_irq_t[i]);
            break;
        }
    }


    return 0;

}
static int Button_write(struct file *file,const char __user *buf,size_t count,loff_t * ppos)
{
    printk( "Button module by leo Write\n");
    return 0;

}
static int Button_read(struct file *file,const char __user *buf,size_t count,loff_t * ppos)
{
    if (count != 1)
        return -EINVAL;

    wait_event_interruptible (button_waitq, ev_press);
    copy_to_user(buf,&key_val,1);
    ev_press = 0;

    return 0;
}

static int Button_ioctl(struct file *file, unsigned int cmd,unsigned long arg )
{
    //printk("cmd = %x,arg = %x \n",cmd,arg);

    switch (cmd)
    {
        case 0:
            *gpmdat |= arg; 

            break;
        case 1:
            *gpmdat &= ~arg;
            break;
        default:
                break;
    }
}
static int Button_close(struct inode *inode,struct file *file)
{
    int i;
    for (i = 0; i <4; i++)  
    {  
           if (Button_irq_t[i].irqNum < 0)
           {
                 continue;
           }
        free_irq(Button_irq_t[i].irqNum,(void*)&Button_irq_t[i]);     
    } 
}
static irqreturn_t Buttons_irq(int irq,void *dev_id)
{
    _Button_irq_t *Button_irq_buff=(_Button_irq_t *)dev_id;

    key_val=Button_irq_buff->ButtonNum;
    printk("enter the button interrupt key_val = %d \n",key_val);

    ev_press = 1;
    wake_up_interruptible (&button_waitq);
    kill_fasync (&button_async, SIGIO, POLL_IN);

    return IRQ_RETVAL(IRQ_HANDLED);
}

static unsigned Button_poll(struct file *file, poll_table *wait)
{
    unsigned int mask = 0;
    poll_wait (file, &button_waitq, wait );
    if(ev_press)
    {
        mask |= POLLIN | POLLRDBAND;
    }
    return mask;
}
static int Button_fasync (int fd, struct file *filp, int on)
{
    printk("driver: Button_fasync\n");

    return fasync_helper (fd, filp, on, &button_async);
}
module_init(Button_init);
module_exit(Button_exit);

测试代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>


int fd;
void signal_fun(int signum)
{
    unsigned char key_val;
    read(fd,&key_val,1);
        printf("key_val Value is %x\n",key_val);
}

int main(int argc,int **argv)
{
    unsigned char key_val;
    int ret;
    int i;

    int Oflags;
    fd = open ("/dev/Button_leo", O_RDWR);
    if(fd < 0)
    {
        printf ("the device can't open !\n");
        return 0;
    }
    signal(SIGIO, signal_fun);
    fcntl(fd,F_SETOWN,getpid());
    Oflags = fcntl(fd,F_GETFL);
    fcntl(fd,F_SETFL,Oflags|FASYNC);
    while(1)
    {
            for( i=0;i<4;++i)
                {
                    ioctl(fd,1,1<<i);
                    ioctl(fd,0,~(1<<i));
                    //sleep(1);
                    sleep(1);
                }
    }
    return 0;

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Q: '-webkit-scrollbar-button' 是什么? A: '-webkit-scrollbar-button' 是一种 CSS 属性,用于设置 webkit 浏览器中滚动条按钮的样式。 ### 回答2: ::-webkit-scrollbar-button是一个CSS伪元素,用于设置网页中滚动条按钮的样式。在Webkit浏览器中,应用该伪元素可以改变滚动条的外观,实现更加美观、个性化的滚动条。 在CSS中,可以通过对滚动条的四个方向(上、下、左、右)分别设置样式,来调整滚动条的大小、形状、颜色等属性。而使用::-webkit-scrollbar-button则可以单独改变滚动条按钮的样式。 具体来说,-webkit-scrollbar-button伪元素可用于设置滚动条上下、左右两种按钮的样式,可以设置其背景、边框、阴影等属性,从而改变滚动条按钮的颜色、大小和形状。 当指针悬停在滚动条上时,::-webkit-scrollbar-button可以控制按钮的鼠标移入和移出效果。这些效果如:悬停时按钮变色,按下按钮时的样式,松开按钮时的样式等。 当然,在使用::-webkit-scrollbar-button时,我们也需要考虑浏览器的兼容性问题。该伪元素只适用于Webkit内核的浏览器,对于其他浏览器可能不支持或支持方式不同,因此需要针对不同浏览器做出相应的处理。 总的来说,::-webkit-scrollbar-button是一个常见的CSS伪元素,使用它可以改变滚动条按钮的外观,以增强用户体验和提升网页的整体美观度。 ### 回答3: ::-webkit-scrollbar-button是一个Webkit浏览器CSS扩展,用于定义滚动条按钮的样式。Webkit是一个用于开发苹果Safari和Google Chrome等网络浏览器的开源渲染引擎,其语法格式为"::-webkit-"。 滚动条是网站中常见的组件,用于帮助用户浏览长页面或列表。滚动条通常包括滑块、轨道和两个按钮。滚动条按钮用于向上和向下滚动页面或列表。CSS样式可以用来定制滚动条的外观和行为。 在Webkit浏览器中,使用::-webkit-scrollbar-button样式可以修改滚动条按钮的样式。该样式可以定义按钮的宽度、高度、背景颜色、边框和不同状态下的样式。 举个例子,下面是一个使用::-webkit-scrollbar-button样式定制滚动条按钮的CSS代码: ``` ::-webkit-scrollbar-button { width: 16px; height: 16px; background-color: #ccc; border: 1px solid #aaa; } ::-webkit-scrollbar-button:hover { background-color: #aaa; } ::-webkit-scrollbar-button:active { background-color: #888; } ``` 在上面的代码中,定义了滚动条按钮的宽度、高度、背景颜色和边框。同时还定义了按钮在不同状态下的样式,比如鼠标悬停和鼠标按下时的样式。 当然,除了::-webkit-scrollbar-button,Webkit浏览器还提供了其他的滚动条扩展样式,比如::-webkit-scrollbar、::-webkit-scrollbar-thumb和::-webkit-scrollbar-track等。这些样式可以一起使用来创建更独特的滚动条样式,以满足你的网站美化需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值