JZ2440笔记:字符设备驱动程序之查询方式的按键驱动程序(一直在等快递,心神不灵)

在上回的代码上修改,将first_drv.c改成second_drv.c,firstdrvtest.c改成seconddrvtest.c。

注意:在vi里批量替换使用命令 :%s/first/second/gc   将first字样全部改成second。

#include <asm/mach/map.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/module.h>

volatile unsigned long *gpfcon = NULL;
volatile unsigned long *gpgcon = NULL;
volatile unsigned long *gpfdat = NULL;
volatile unsigned long *gpgdat = NULL;


static int second_drv_open(struct inode *inode,struct file *file)
{
        *gpfcon &= ~(0x3<<(0*2)|(0x3<<(2*2)));

        *gpgcon &= ~(0x3<<(3*2)|(0x3<<(11*2)));

        return 0;
}

static ssize_t second_drv_read(struct file *file,const char __user *buf,size_t len,loff_t *ppos)
{
        unsigned char key_value[4];
        int temp;

        if(len!=sizeof(key_value))
                return -EINVAL;

        temp = *gpfdat;
        key_value[0] = (temp & (1<<0)) ? 1:0;
        key_value[1] = (temp & (1<<2)) ? 1:0;
        temp = *gpgdat;
        key_value[2] = (temp & (1<<3)) ? 1:0;
        key_value[3] = (temp & (1<<11)) ? 1:0;

        copy_to_user(buf,key_value,sizeof(key_value));

        return sizeof(key_value);
}

static struct file_operations second_drv_fops = {
        .owner = THIS_MODULE,
        .open = second_drv_open,
        .read = second_drv_read,
};

int major;
static struct class *seconddrv_class;
static struct device *seconddrv_device;
static int second_drv_init(void)
{
        int i;
        major = register_chrdev(0,"second_drv",&second_drv_fops);
        seconddrv_class = class_create(THIS_MODULE,"seconddrv");
        seconddrv_device = device_create(seconddrv_class,NULL,MKDEV(major,0),NULL,"buttons");

        gpfcon = (volatile unsigned long *)ioremap(0x56000050,16);
        gpfdat = gpfcon + 1;
        gpgcon = (volatile unsigned long *)ioremap(0x56000060,16);
        gpgdat = gpgcon + 1;

        printk("second_drv_init\n");
        return 0;
}

static void second_drv_exit(void)
{
        iounmap(gpfcon);
        iounmap(gpgcon);

        unregister_chrdev(major,"second_drv");
        device_destroy(seconddrv_class,MKDEV(major,0));
        class_destroy(seconddrv_class);
        printk("second_drv_exit\n");
}

module_init(second_drv_init);
module_exit(second_drv_exit);

MODULE_LICENSE("GPL");

make出现 warning: passing argument 1 of 'copy_to_user' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers],原来是static ssize_t second_drv_read(struct file *file,const char __user *buf,size_t len,loff_t *ppos)中的buf在read函数不能用const修饰,毕竟buf是要被写入的,不能不被修改。疏忽大意。

再次make出现second_drv.c:54:6: warning: unused variable 'i' [-Wunused-variable],在vi中使用命令 :set nu显示出行号,找到第54行,使用命令dd删除此行即可。编译通过。

测试文件seconddrvtest.c:

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
        int fd;
        unsigned char key_value[4];
        int cnt = 1;

        fd = open("/dev/buttons",O_RDWR);
        if(fd<0)
        {
                printf("can't open /dev/buttons!\n");
                return 0;
        }

        while(1)
        {
                read(fd,key_value,sizeof(key_value));
                if(!key_value[0]||!key_value[1]||!key_value[2]||!key_value[3])
                        printf("%04d key_pressed: %d %d %d %d\n",cnt++,key_value[0],key_value[1],key_value[2],key_value[3]);
        }
        return 0;
}

编译通过。

注意:%04d表示输出的数据为整形,4表示输出的数据宽度为4,不足位用0填充。

测试驱动:

# insmod second_drv.ko
second_drv_init
# cat /proc/devices
Character devices:
248 second_drv
# ls /dev/buttons -l
crw-rw----    1 0        0         248,   0 Jan  4 02:58 /dev/buttons
# ./seconddrvtest
0001 key_pressed: 1 0 1 1
0002 key_pressed: 1 0 1 1
0003 key_pressed: 1 0 1 1
0004 key_pressed: 1 0 1 1
0005 key_pressed: 1 0 1 1

测试成功。

# ./seconddrvtest &
# top
Mem: 11792K used, 46204K free, 0K shrd, 0K buff, 4688K cached
CPU: 20.0% usr 80.0% sys  0.0% nic  0.0% idle  0.0% io  0.0% irq  0.0% sirq
Load average: 0.83 0.43 0.18 2/31 1090
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
 1089   873 0        R     1632  2.8   0 73.1 ./seconddrvtest
 1090   873 0        R     3624  6.2   0  6.6 top


可以看到./seconddrvtest cpu进程占比为73.1%。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值