在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于S3C2440的linux驅(qū)動(dòng)

            基于S3C2440的linux驅(qū)動(dòng)

            作者: 時(shí)間:2016-11-20 來源:網(wǎng)絡(luò) 收藏

            MINI2440_BUTTON.C

            #include

            本文引用地址:http://www.biyoush.com/article/201611/318871.htm

            #include

            #include

            #include

            #include

            #include

            #include

            #include interrupt.h>

            #include

            #include

            #include

            #define DEVICE_NAME "buttons"

            #define BUTTON_MAJOR 232

            struct button_irq_desc {

            int irq;

            int pin;

            int pin_setting;

            int number;

            char *name;

            };

            static struct button_irq_desc button_irqs [] = {

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

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

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

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

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

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

            };

            static volatile int key_values [] = {0, 0, 0, 0, 0, 0};

            static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

            static volatile int ev_press = 0;

            static irqreturn_t buttons_interrupt(int irq, void *dev_id)

            {

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

            int up = s3c2410_gpio_getpin(button_irqs->pin);

            if (up)

            key_values[button_irqs->number] = (button_irqs->number + 1) + 0x80;

            else

            key_values[button_irqs->number] = (button_irqs->number + 1);

            ev_press = 1;

            wake_up_interruptible(&button_waitq);

            return IRQ_RETVAL(IRQ_HANDLED);

            }

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

            {

            int i;

            int err;

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

            // 注冊(cè)中斷處理函數(shù)

            s3c2410_gpio_cfgpin(button_irqs[i].pin,button_irqs[i].pin_setting);

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

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

            set_irq_type(button_irqs[i].irq, IRQT_BOTHEDGE);

            if (err)

            break;

            }

            if (err) {

            // 釋放已經(jīng)注冊(cè)的中斷

            i--;

            for (; i >= 0; i--) {

            disable_irq(button_irqs[i].irq);

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

            }

            return -EBUSY;

            }

            return 0;

            }

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

            {

            int i;

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

            // 釋放已經(jīng)注冊(cè)的中斷

            disable_irq(button_irqs[i].irq);

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

            }

            return 0;

            }

            static int mini2440_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 = 0;

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

            memset((void *)key_values, 0, sizeof(key_values));

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

            }

            static unsigned int mini2440_buttons_poll(

            struct file *file,

            struct poll_table_struct *wait)

            {

            unsigned int mask = 0;

            poll_wait(file, &button_waitq, wait);

            if (ev_press)

            mask |= POLLIN | POLLRDNORM;

            return mask;

            }

            static struct file_operations mini2440_buttons_fops = {

            .owner = THIS_MODULE,

            .open = mini2440_buttons_open,

            .release = mini2440_buttons_close,

            .read = mini2440_buttons_read,

            .poll = mini2440_buttons_poll,

            };

            static int __init mini2440_buttons_init(void)

            {

            int ret;

            ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &mini2440_buttons_fops);

            if (ret < 0) {

            printk(DEVICE_NAME " cant register major numbern");

            return ret;

            }

            devfs_mk_cdev(MKDEV(BUTTON_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME);

            printk(DEVICE_NAME " initializedn");

            return 0;

            }

            static void __exit mini2440_buttons_exit(void)

            {

            devfs_remove(DEVICE_NAME);

            unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);

            }

            module_init(mini2440_buttons_init);

            module_exit(mini2440_buttons_exit);

            MODULE_AUTHOR("http://www.arm9.net"); // 驅(qū)動(dòng)程序的作者

            MODULE_DESCRIPTION("S3C2410/S3C2440 BUTTON Driver"); // 一些描述信息

            MODULE_LICENSE("GPL"); // 遵循的協(xié)議

            總結(jié)一下,程序框架。

            按鍵的驅(qū)動(dòng)主要是多了中斷的處理,關(guān)于中斷主要的處理函數(shù)是

            request_irq(button_irqs[i].irq, buttons_interrupt, NULL,

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

            第二個(gè)參數(shù)是主要的中斷處理函數(shù)。

            static irqreturn_t buttons_interrupt(int irq, void *dev_id)

            {

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

            int up = s3c2410_gpio_getpin(button_irqs->pin);

            if (up)

            key_values[button_irqs->number] = (button_irqs->number + 1) + 0x80;

            else

            key_values[button_irqs->number] = (button_irqs->number + 1);

            ev_press = 1;

            wake_up_interruptible(&button_waitq);

            return IRQ_RETVAL(IRQ_HANDLED);

            }

            另外還用到了兩個(gè)重要的結(jié)構(gòu)體:

            static struct button_irq_desc button_irqs [] = {

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

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

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

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

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

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

            };

            struct button_irq_desc {

            int irq;

            int pin;

            int pin_setting;

            int number;

            char *name;

            };

            而驅(qū)動(dòng)程序中的最重要的部分,file_operations為

            static struct file_operations mini2440_buttons_fops = {

            .owner = THIS_MODULE,

            .open = mini2440_buttons_open,

            .release = mini2440_buttons_close,

            .read = mini2440_buttons_read,

            .poll = mini2440_buttons_poll,

            };

            程序中其他的任務(wù)就是豐滿這個(gè)機(jī)構(gòu)體,使得應(yīng)用程序在調(diào)用open,close等的時(shí)候可以在

            驅(qū)動(dòng)中找到對(duì)應(yīng)的項(xiàng)。

            這里的request_irq在open函數(shù)里調(diào)用的。

            至于注冊(cè)的部分跟LEDS那些是一樣的,就不多說啦。

            再附個(gè)應(yīng)用程序供參考:

            #include

            #include

            #include

            #include

            #include

            #include

            #include

            #include

            #include

            #include

            int main(void)

            {

            int i;

            int buttons_fd;

            int key_value[4];

            buttons_fd = open("/dev/buttons", 0);

            if (buttons_fd < 0) {

            perror("open device buttons");

            exit(1);

            }

            for (;;) {

            fd_set rds;

            int ret;

            FD_ZERO(&rds);

            FD_SET(buttons_fd, &rds);

            ret = select(buttons_fd + 1, &rds, NULL, NULL, NULL);

            if (ret < 0) {

            perror("select");

            exit(1);

            }

            if (ret == 0) {

            printf("Timeout.n");

            }

            else if (FD_ISSET(buttons_fd, &rds)) {

            int ret = read(buttons_fd, key_value, sizeof key_value);

            if (ret != sizeof key_value) {

            if (errno != EAGAIN)

            perror("read buttonsn");

            continue;

            } else {

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

            printf("K%d %s, key value = 0x%02xn", i+1, (key_value[i] & 0x80) ? "released" :

            key_value[i] ? "pressed down" : "",

            key_value[i]);

            }

            }

            }

            close(buttons_fd);

            return 0;

            }



            關(guān)鍵詞: S3C2440linux驅(qū)

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉