原创 linux 工作队列

2010-4-1 23:08 3094 4 5 分类: MCU/ 嵌入式
/*
     基于s3c2440;      2.6.30内核。
     用到EINT0, 工作队列, 等待队列。
     参考pheonix

read ready                                                                     
count is 1                                                                     
                                                                               
read ready                                                                     
count is 4                                                                     
                                                                               
read ready                                                                     
work has been in game                                                          
count is 5                                                                     
work has been in game                                                          
work has been in game                                                          
                                                                               
read ready                                                                     
count is 7                                                                     
                                                                               
read ready                                                                     
count is 8                                                                     
                                                                               
read ready                                                                     
work has been in game                                                          
count is 9                                                                     
                                                                               
read ready                                                                     
count is 11                                                                    
                                                                               
read ready                                                                     
count is 12                                                                    
                                                                               
read ready                                                                     
count is 13                                                                    
                                                                               
read ready                                                                     
work has been in game                                                          
count is 14                                                                    
q        

*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/workqueue.h>
#include <linux/miscdevice.h>

#define DEV_NAME "mydriver"
#define DEV_MAJOR 222
#define INT_NUM     IRQ_EINT0
 
void work_fun(void*data);
int count;
DECLARE_DELAYED_WORK(work, work_fun);
DECLARE_WAIT_QUEUE_HEAD(queue_read);
 
void work_fun(void* data)
{
    unsigned long temp = s3c2410_gpio_getpin(S3C2410_GPF0);
   
    if (0x1 & temp)
    {
        wake_up_interruptible(&queue_read);
        count++;   
    }
}

static int phoenix_interrupt(int irq,void *dev_id,struct pt_regs *regs)
{
    int temp;
    temp = schedule_delayed_work(&work, 200);
   
    if (0 == temp)
    {
        printk("<0>""work has been in game\n");
    }
    return 0;
}

 

int phoenix_open(struct inode *inode,struct file *filp)
{
        int temp;   

       //register interrupt
       s3c2410_gpio_cfgpin(S3C2410_GPF0,0x10);
       temp=request_irq(INT_NUM,phoenix_interrupt,IRQ_TYPE_EDGE_RISING,DEV_NAME,NULL);

       if(temp)
       {
              printk("<0>""request_irq error1:<%d> !\n",temp);
       }

      
       count=0;
       return 0;
}

int phoenix_read(struct file *filp,char *buffer,size_t length,loff_t *offset)
{   
     interruptible_sleep_on(&queue_read);
           copy_to_user(buffer,(char*)&count,2);//copy to user  

            return 4;
}

int phoenix_release(struct inode *inode,struct file *filp)

{

       free_irq(INT_NUM,NULL);

       return 0;

}

struct eint{
    struct cdev cdev;
}eint_dev;

struct file_operations eint_fops=

{

       .owner=THIS_MODULE,

       .open=phoenix_open,

       .read=phoenix_read,

       .release=phoenix_release,

};

void eint_setup_cdev(void)
{
    int err, devno=MKDEV(DEV_MAJOR, 0);
    cdev_init(&eint_dev.cdev, &eint_fops);
    eint_dev.cdev.owner = THIS_MODULE;
    eint_dev.cdev.ops   = &eint_fops;

    err = cdev_add(&eint_dev.cdev, devno, 1);
    if (err)
    {
        printk("add err");
    }
    else
    {
        printk("add ok");
    }
}

 

int phoenix_init(void)

{

     int tmp;       
    dev_t devno=MKDEV(DEV_MAJOR, 0);   

        tmp=register_chrdev_region(devno, 1, DEV_NAME);
       
       if(tmp<0)
       {
              printk("<0>""module_init error !\n");
              return tmp;
       }

      eint_setup_cdev();
       return 0;

}

void phoenix_exit(void)
{
    cdev_del(&eint_dev.cdev);
    unregister_chrdev_region(MKDEV(DEV_MAJOR, 0), 1);
}

module_init(phoenix_init);
module_exit(phoenix_exit);

MODULE_LICENSE("Dual BSD/GPL");


 ------------------------------------------
测试程序

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

int main(void)
{
    int fd;
    int ret;
    int temp;
    char buf[2];
    char c;

    fd = open("/dev/int_work", O_RDWR);
   
    if (fd<0)
    {
        printf("open int_work err\n");
        return -1;
    }

    while(1)
    {
        scanf("%c", &c);
        if ('q' == c)
        {
            close(fd);
            return 0;
        }   
        printf("read ready\n");
        ret = read(fd, buf, 2);
        if (ret != 0)
        {
            temp = buf[0] | (buf[1]<<8);
            printf("count is %d\n", temp);
        }
    }

    return 0;
}
PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1451188 2010-4-11 13:08

呵呵 难得在edn上看到linux的东东

朱玉龙 2009-12-29 09:03

我觉得国内的企业很喜欢在自己家圈一块地,然后就闷头发展,对外宣称取得怎么样的成果,还不让别人看。是骡子是马,我们都不知道,信息上绝对是不平衡的。国内的媒体没有焦点也要找焦点乱哄一气,以汉芯的暴露,龙芯的徘徊。关键,多少时间出来晃晃,而不是在自己家的研究所里。 现在这年头,从小到大发展有多难,面对国内的环境,坦诚的来说比亚迪已经不容易了,不好过多评论,期待后事发展。

tengjingshu_112148725 2009-12-28 00:42

说说比亚迪吧,比亚迪算不算整合了上游半导体?

用户52478 2009-12-27 19:36

也许当市场的参与者跟通信设备市场一样的时候,那么这个行业就会出现中国的中兴华为。当然对于从业者来说并不一定是个好事情。
相关推荐阅读
用户401536 2012-06-11 00:18
tty(2)
static int tiny_tiocmget(struct tty_struct *tty, struct file *file) {  struct tiny_serial *tiny ...
用户401536 2012-06-11 00:15
tty(1)
/*  * Tiny TTY driver  *  * Copyright (C) 2002-2004 Greg Kroah-Hartman (greg@kroah.com)  *  *...
用户401536 2012-06-05 21:14
ldd3的tty驱动-makefile
# Comment/uncomment the following line to disable/enable debugging #DEBUG = y # Add your debu...
用户401536 2012-05-31 14:20
test
kft和graphviz工具可以得到函数调用关系图。...
用户401536 2010-03-07 19:30
linux下LED驱动(使用register_chrdev_region)
本来使用register_chrdev()注册,看编译之下2.6.30已经对它不支持拉。转而用register_chrdev_region().驱动文件(module)/***************...
我要评论
1
4
关闭 站长推荐上一条 /3 下一条