内核模块编译,无法点亮第二个led灯,ioctl()不能输入2?
摸鱼手会滑 2013-11-04 10:28:42 最近在学内核模块编译,用的是三星a8的板子,想通过ioctl()函数对led灯进行控制,但是很奇怪,第三个灯总是无法点亮。求大神!!!
内核模块代码下:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/sizes.h>
#define COUNT 3
#define GPH0CON 0xE0200C00
dev_t devid;
u8 *virt;
//在模块里实现对led灯的操作,通过应用程序来操作
int qioctl (struct inode *ind,struct file *f,unsigned int cmd,unsigned long arg)
{
int val;
val = ioread32(virt+4);
if (cmd==1 || cmd==2 || cmd==3)//只要输入的不是1,2,3灯就会全部灭
{//注意:a8板开机就有一个灯是亮着的,只能操作另外三个
val |= 1<<cmd;
iowrite32(val, virt+4);
printk("get cmd.\n");
}
else
{
val = 0;
iowrite32(val, virt+4);
printk("get off cmd\n");
}
//iounmap(virt);
printk("cmd done!\n");
return 0;
}
int qopen(struct inode *ind, struct file *f)
{
printk("in qopen\n");
return 0;
}
ssize_t qread(struct file *f,char __user *buf,loff_t *off)
{
printk("in qread!!!!!\n");
return 0;
}
struct cdev qcdev;
struct file_operations qfops={
.owner = THIS_MODULE,
.open = qopen,
.read = qread,
.ioctl = qioctl,
};
int test_init(void)
{
int ret;
devid = MKDEV(500, 250);
ret = register_chrdev_region(devid, COUNT, "deviii");
if (ret < 0)
goto err0;
printk("register success! in 02!\n");
cdev_init(&qcdev, &qfops);
qcdev.owner = THIS_MODULE;
ret = cdev_add(&qcdev, devid, COUNT);
if (ret < 0)
goto err1;
printk("init done!! in 02\n");
int val;
virt = ioremap(GPH0CON, SZ_4K);
if (virt == NULL)
return -ENOMEM;
val = ioread32(virt);
val &= ~0xffff;
val |= 0x1111;
iowrite32(val, virt);
return 0;
err1:
unregister_chrdev_region(devid, COUNT);
err0:
return ret;
}
void test_exit(void)
{
unregister_chrdev_region(devid, COUNT);
printk("unregister done 02 !\n");
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
上层应用程序:
/*
*加载模块insmod test.ko-->创建文件mknod /dev/qdiv c 500 250-->在应用程序打开文件
*--->通过ioctl对设备文件进行操作
*arm-none-linux-gnueabi-gcc ledctl.c-->a.out--->在板子上运行a.out控制led on/off
*/
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
//输入2不行?
int main(int argc, char *argv[])
{
int fd,cmd;
if (argc != 2)
{
printf("usage:[./a.out][num]\n");
return 2;
}
fd = open("/dev/qdev",O_RDONLY);
if (fd < 0)
{
printf("open error!\n");
return 3;
}
cmd=atoi(argv[1]);
if(!ioctl(fd,cmd))
printf("done!\n");
else
printf("error!\n");
close(fd);
return 0;
}
我执行程序时输入1,3和其他数字,都得到预期的结果,就是输入2不行,
输入2根本就不会调用模块函数的qioctl(),直接就返回了,
为什么会这样???
是ioctl()这个函数本身的问题吗??求解!!