内核模块编译,无法点亮第二个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()这个函数本身的问题吗??求解!!
...全文
154 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
摸鱼手会滑 2013-11-10
  • 打赏
  • 举报
回复
引用 6 楼 Idle_Cloud 的回复:
0,1,3是没占用,操作系统占用2用做bitmap。
谢谢!
falloutmx 2013-11-08
  • 打赏
  • 举报
回复
引用 5 楼 MRQ1734 的回复:
[quote=引用 2 楼 falloutmx 的回复:] 我遇到过这个问题,2这个操作数被系统占用了。驱动指令的定义最好用幻数(magic number),避免与内核或其他驱动冲突。你查下相关概念就明白了
百度说,在c语言中,把直接使用的常数叫做幻数。不是最好不要用幻数吗?[/quote] 不是一个概念。我说的是驱动里的幻数,你百度“linux 驱动 幻数”就知道了
Carl_CCC 2013-11-08
  • 打赏
  • 举报
回复
0,1,3是没占用,操作系统占用2用做bitmap。
摸鱼手会滑 2013-11-07
  • 打赏
  • 举报
回复
引用 2 楼 falloutmx 的回复:
我遇到过这个问题,2这个操作数被系统占用了。驱动指令的定义最好用幻数(magic number),避免与内核或其他驱动冲突。你查下相关概念就明白了
百度说,在c语言中,把直接使用的常数叫做幻数。不是最好不要用幻数吗?
摸鱼手会滑 2013-11-07
  • 打赏
  • 举报
回复
引用 3 楼 Idle_Cloud 的回复:
2是被系统占用了,如果你不想用幻数,最好用个大的。
能具体说说是被什么占用了吗?,1和3也很小阿,也没被什么占用
falloutmx 2013-11-05
  • 打赏
  • 举报
回复
我遇到过这个问题,2这个操作数被系统占用了。驱动指令的定义最好用幻数(magic number),避免与内核或其他驱动冲突。你查下相关概念就明白了
Carl_CCC 2013-11-05
  • 打赏
  • 举报
回复
2是被系统占用了,如果你不想用幻数,最好用个大的。
摸鱼手会滑 2013-11-04
  • 打赏
  • 举报
回复
用的是红帽5.6的系统

1,319

社区成员

发帖
与我相关
我的任务
社区描述
主要是开发驱动技术
社区管理员
  • 驱动程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧