内核模块编译,无法点亮第二个led灯,ioctl()不能输入2?
最近在学内核模块编译,用的是三星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()这个函数本身的问题吗??求解!!
内核模块代码下:
#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()这个函数本身的问题吗??求解!!
...全文
相关推荐
Ubuntu 按键控制LED灯驱动程序编译.zip
该项目实现了一个Linux内核模块驱动程序,通过读取/dev/MY_KEYS设备监测六个按键状态变化,并利用ioctl系统调用控制/dev/MY_LEDS设备上的LED灯开关。支持按键事件响应与LED
基于web远程控制led灯
本文介绍了一个用于控制LED灯的HTML页面及后端处理程序。用户可通过复选框选择要点亮的LED(LED1至LED4)并通过表单提交请求。服务端使用led.cgi脚本处理指令,通过设备文件和命名管道实现
zynq的linux驱动10-ioctl架构来控制led灯
`sleep`函数用来模拟延时,让LED灯亮一段时间后再关闭。总结起来,通过Linux的ioctl机制,我们可以灵活地在用户空间控制Zynq平台上的硬件资源,如LED灯。
wince6.0 vs2005 应用程序 点亮LED灯
- 使用延时函数`Sleep()`时,要考虑系统的实时性需求。通过上述分析,我们可以清晰地了解到如何在Wince6.0环境下利用VS2005开发工具来编写控制LED灯的应用程序。
ioctl() 函数输入输出应用实例.doc
### ioctl() 函数输入输出应用实例详解#### 实验背景及意义`ioctl()` 函数在 Linux 和其他类 Unix 操作系统中被广泛用于与设备驱动程序进行交互,特别是那些不支持标准输入输出操作


驱动程序开发区
