文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>key44driver

key44driver

时间:2009-08-19  来源:sure_priterand

//==================key44driver.c==============================================
#ifndef __KERNEL__
    #define __KERNEL__
#endif
#ifndef MODULE
    #define MODULE
#endif
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>    /* printk() */
#include <linux/init.h>    /* __init __exit */
#include <linux/types.h>    /* size_t */
#include <linux/fs.h>    /* file_operation */
#include <linux/errno.h>    /* Error number */
#include <linux/delay.h>    /* udelay */
#include <asm/uaccess.h>    /* copy_to_user, copy_from_user */
#include <asm/hardware.h>
#include <asm/semaphore.h>
#include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/kfifo.h>
#include <asm/irq.h>
#define DRIVER_NAME    "key44Driver"
#ifdef DEBUG
#define PRINTK(fmt, arg...)        printk(KERN_NOTICE fmt, ##arg)
#else
#define PRINTK(fmt, arg...)
#endif
struct timer_list myTimer;
static int key44Driver_Major = 0;        /* Driver Major Number */
struct semaphore bufflock;
/* Vitual Driver Buffer */
static spinlock_t buffer_lock = SPIN_LOCK_UNLOCKED;
static struct kfifo *buffer;
char  key_old[2] = {'0','0'};
#define BUFFER_SIZE   256
/* Driver Operation Functions */
static int key44Driver_open(struct inode *inode, struct file *filp)
{
    MOD_INC_USE_COUNT;
    PRINTK("key44Driver open called!\n");
    
    enable_irq(IRQ_EINT0);
    enable_irq(IRQ_EINT1);
    enable_irq(IRQ_EINT2);
    enable_irq(IRQ_EINT3);
    sema_init(&bufflock, 0);
    return 0;
}
static int key44Driver_release(struct inode *inode, struct file *filp)
{
    MOD_DEC_USE_COUNT;
    disable_irq(IRQ_EINT0);
    disable_irq(IRQ_EINT1);
    disable_irq(IRQ_EINT2);
    disable_irq(IRQ_EINT3);
    PRINTK("key44Driver release called!\n");
    kfifo_free(buffer);
    
    return 0;
}
static ssize_t key44Driver_read(struct file *filp, char *buf, size_t count,loff_t *f_pos)
{
    PRINTK("key44Driver read called!\n");
    down_interruptible(&bufflock);
    kfifo_get(buffer, buf, 2);
    return 2;
}
void timerHandler(unsigned long data)
{
    int i;
    unsigned int data_buf;
    char  key[2];
    
    GPFCON = 0X0055;
    GPFDAT = 0X0F0;
    for(i = 0; i < 1000; i++ );
    data_buf = GPFDAT;
    data_buf = data_buf & 0x0f0;
    switch(data_buf)
    {
        case 0x0e0:
            key[0] = '1';
            break;
        case 0x0d0:
            key[0] = '2';
            break;
        case 0x0b0:
            key[0] = '3';
            break;
        case 0x070:
            key[0] = '4';
            break;
        default:
            key[0] = '0';
            break;
    }
    key[1] = data + '0';
    if(((key[0] != key_old[0]) || (key[1] != key_old[1])) && key[0] != '0')
    {
        kfifo_put(buffer, key, 2);
        up(&bufflock);
        key_old[0] = key[0];
        key_old[1] = key[1];
    }
    GPFCON = 0X55aa;
    GPFDAT = 0X0F;
    enable_irq(IRQ_EINT0);
    enable_irq(IRQ_EINT1);
    enable_irq(IRQ_EINT2);
    enable_irq(IRQ_EINT3);
    
}
void handler(int irq, void *dev_id, struct pt_regs *regs)
{
    disable_irq(IRQ_EINT0);
    disable_irq(IRQ_EINT1);
    disable_irq(IRQ_EINT2);
    disable_irq(IRQ_EINT3);
    myTimer.expires = jiffies + 3;
    myTimer.data = irq;
    myTimer.function = timerHandler;
    add_timer(&myTimer);
}
/* Driver Operation structure */
static struct file_operations key44Driver_fops = {
    owner:        THIS_MODULE,
    read:        key44Driver_read,
    open:        key44Driver_open,
    release:    key44Driver_release,
};
/* Module Init & Exit function */
#ifdef CONFIG_DEVFS_FS
devfs_handle_t devfs_key44Driver_dir;
devfs_handle_t devfs_key44Driver_raw;
#endif
static int __init myModule_init(void)
{
    /* Module init code */
    PRINTK("myModule_init\n");
    /* Driver register */
    key44Driver_Major = register_chrdev(0, DRIVER_NAME, &key44Driver_fops);
    if(key44Driver_Major < 0)
    {
        PRINTK("register char device fail!\n");
        return key44Driver_Major;
    }
    PRINTK("register key44Driver OK! Major = %d\n", key44Driver_Major);
#ifdef CONFIG_DEVFS_FS
    devfs_key44Driver_dir = devfs_mk_dir(NULL, "key44Driver", NULL);
    devfs_key44Driver_raw = devfs_register(devfs_key44Driver_dir, "0",DEVFS_FL_DEFAULT, key44Driver_Major, 0, \
S_IFCHR | S_IRUSR | S_IWUSR, &key44Driver_fops, NULL);
    PRINTK("add dev file to devfs OK!\n");
#endif
    GPFCON = 0X55aa;
    GPFUP = 0X00;
    GPFDAT = 0X0F;
    set_external_irq(IRQ_EINT0, EXT_FALLING_EDGE, 0);
    set_external_irq(IRQ_EINT1, EXT_FALLING_EDGE, 0);
    set_external_irq(IRQ_EINT2, EXT_FALLING_EDGE, 0);
    set_external_irq(IRQ_EINT3, EXT_FALLING_EDGE, 0);
    request_irq(IRQ_EINT0, handler, SA_INTERRUPT, "KEY0", NULL);
    request_irq(IRQ_EINT1, handler, SA_INTERRUPT, "KEY1", NULL);
    request_irq(IRQ_EINT2, handler, SA_INTERRUPT, "KEY2", NULL);
    request_irq(IRQ_EINT3, handler, SA_INTERRUPT, "KEY3", NULL);
    
    buffer = kfifo_alloc(BUFFER_SIZE, GFP_KERNEL, &buffer_lock);
    
    init_timer(&myTimer);
    return 0;
}
static void __exit myModule_exit(void)
{
    /* Module exit code */
    PRINTK("myModule_exit\n");
    /* Driver unregister */
    if(key44Driver_Major > 0)
    {
        #ifdef CONFIG_DEVFS_FS
            devfs_unregister(devfs_key44Driver_raw);
            devfs_unregister(devfs_key44Driver_dir);
        #endif
            unregister_chrdev(key44Driver_Major, DRIVER_NAME);
    }
    del_timer(&myTimer);
    free_irq(IRQ_EINT0, NULL);
    free_irq(IRQ_EINT1, NULL);
    free_irq(IRQ_EINT2, NULL);
    free_irq(IRQ_EINT3, NULL);
    return;
}
MODULE_AUTHOR("sure");
MODULE_LICENSE("Dual BSD/GPL");
module_init(myModule_init);
module_exit(myModule_exit);
//===========================Makefile========================================
OUTPUT = key44driver.o
OUTPUT_DIR = output
#s3c2410
KERNEL = /home/sure/kernel_2.4.18
CROSSPREFIX = /usr/local/arm/2.95.3/bin/arm-linux-
#pc 2.4
#KERNEL = /usr/src/linux-2.4
#CROSSPREFIX =
CFLAGS = -Wall -I$(KERNEL)/include -c -DDEBUG
#CFLAGS += -DEXPORT_SYMTAB -DMODVERSIONS -include $(KERNEL)/include/linux/modversions.h 
DEST = $(foreach fn, $(OUTPUT), $(OUTPUT_DIR)/$(fn))
all: $(OUTPUT_DIR)/install.sh
$(OUTPUT_DIR)/install.sh: $(OUTPUT_DIR) $(DEST)
    @rm $@ -f
    @echo -e " $(foreach fn, $(OUTPUT), "insmod $(fn)\\n")" >> $@
    @echo "Finished!"
$(OUTPUT_DIR):
    @mkdir $@
    @chmod 777 -R $@
$(OUTPUT_DIR)/%.o: %.c
    @echo -n "Compling $^..."
    @$(CROSSPREFIX)gcc $(CFLAGS) $^ -o $@
    @echo "OK"
clean:
    @find . \( -name '*.[oas]' -o -name install.sh \) -type f -print | xargs rm -f
    @echo "Cleaned!"
//==================test.c=============================================
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
    char buf[2] = "";
    int key = 0,i = 0;
    if((key = open("/dev/key44Driver/0", O_RDONLY)) <= 0)
    {
        printf("open error\n");
        exit(1);
    }
    while(read(key, buf, 2) > 0)
    {
        printf("%d:  %s\n\n", i++, buf);
    }
}
 
相关阅读 更多 +
排行榜 更多 +
马里奥赛车世界游戏手机版下载

马里奥赛车世界游戏手机版下载

赛车竞速 下载
无畏契约皮肤开箱器手游下载

无畏契约皮肤开箱器手游下载

休闲益智 下载
旭日之城官方正版下载

旭日之城官方正版下载

策略塔防 下载