免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2076 | 回复: 5
打印 上一主题 下一主题

一个简单的驱动程序出错,请高手们指点迷津 [复制链接]

论坛徽章:
1
水瓶座
日期:2014-10-18 20:17:41
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-04-28 16:46 |只看该作者 |倒序浏览
小第是个新手,今天用开发板写了个简单的驱动程序,可是出错了。这让我很纠结啊,现在是不知如何去解决它了,请高手们指教!
我把我现在的问题说一下,请高人指点下。

我用#insmod uart.ko 装载程序;
用#cat /proc/devices 看一下驱动程序的主设备号为:
252 uart

创建设备节点#mknod /dev/uart c 252 0

之后运行应用程序,得到输出结果是:
open start!  
open error: -1

可是我很迷惑是哪里出了差错;请高手指点迷津。

下面是我的驱动源程序:

#define rMPLLCON (*(volatile unsigned *)0x7E00F010)
#define rCLKDIVN (*(volatile unsigned *)0X7E00F020)  

#define rGPFCON (*(volatile unsigned *)(0x7F0080A0))
#define rGPFDAT (*(volatile unsigned *)(0x7F0080A4))
#define rGPFPUD (*(volatile unsigned *)(0x7F0080A)


#include<linux/module.h>
#include<linux/version.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/kernel.h>
#include<linux/stat.h>
#include<linux/errno.h>
#include<linux/kdev_t.h>
#include<linux/types.h>

#define NAME "uart"
MODULE_LICENSE("Dual BSD/GPL";
static dev_t uart_minor=0;
static dev_t uart_major=0;
void delay(void);

struct cdev *my_cdev;
static int uart_release(struct inode *inode, struct file *filp);
static int uart_ioctl(struct file * filp, unsigned int cmd, unsigned long arg);
static int uart_open(struct inode * inode, struct file *filp);

struct file_operations uart_fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = uart_ioctl,
.open = uart_open,
.release = uart_release,

};
static int uart_ioctl(struct file * filp, unsigned int cmd, unsigned long arg)
{
//int data = arg;
switch(cmd)
{

case 0:
rGPFDAT = (rGPFDAT & ~(0xfU<<14)) | (0x3<<14);
delay();break;
case 1:
rGPFDAT = (rGPFDAT & ~(0xfu<<14));
delay();
break;
}
return 0;
}

static int uart_release(struct inode *inode, struct file *filp)
{
return 0;
}

static int uart_open(struct inode * inode, struct file *filp)
{
rGPFCON = (rGPFCON & ~(0x0fU<<2)|(0x5U<<2;
rGPFPUD = (rGPFPUD & ~(0x0fU<<2)|(0xaU<<2;

return 0;
}

static int __init uart_init()
{
int result = 0, i;
dev_t dev = MKDEV(uart_major,0);
i =register_chrdev_region(dev,1,NAME);
if(i<0)
{
printk(KERN_ALERT "alloc char dev region!";
result = alloc_chrdev_region(&dev,0,1,NAME);
uart_major = MAJOR(dev);
uart_minor = MINOR(dev);
if(result<0)
return result;
}
my_cdev = cdev_alloc();
int err,devno = MKDEV(uart_major, uart_minor);

cdev_init(my_cdev,&uart_fops);
my_cdev->owner = THIS_MODULE;
my_cdev->ops = &uart_fops;

err = cdev_add(my_cdev,devno,1);
if(err)
printk(KERN_NOTICE "Error %d adding uart\n",err);
printk(KERN_ALERT "init OK!\n";
return 0;
}

static int __exit uart_exit()
{
cdev_del(my_cdev);
unregister_chrdev_region(MKDEV(uart_major,0),1);
printk(KERN_ALERT "UART removed!\n";
return 0;
}
void delay(void)
{
unsigned int k;
  for(k = 0; k < 2000000; k++);
}
module_exit(uart_exit);
module_init(uart_init);

我的makefile如下:
obj-m := uart.o
KERNELDIR := /home/linux-2.6.38
PWD := $(shell pwd)

modules :
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install :
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
.PHONY:clean
clean:
rm -f *.o *.ko *.mod.c *symvers *order


下面是我写的应用程序:
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
int main()
{
int fd;
int loop,num;
printf("open start!\n";
fd = open("/dev/uart",O_RDWR);
if(fd < 0) {
printf("open error: %d\n",fd);
return 0;
}
printf("open OK!\n";
loop = 0;
while(loop < 10) {
ioctl(fd,1,1);
sleep(1);
ioctl(fd,1,2);
loop++;
}
close(fd);
exit(0);
}

论坛徽章:
0
2 [报告]
发表于 2012-05-02 09:47 |只看该作者
返回出错码 -1  也就是ENOENT  没有这个设备节点
LZ自己查查原因吧

论坛徽章:
0
3 [报告]
发表于 2012-05-05 09:05 |只看该作者
#define rGPFCON (*(volatile unsigned *)(0x7F0080A0))         类似于这样的句子,在裸奔的时候没问题,但是在linux内核下运行就会有问题,这里涉及到虚拟地址和物理地址的差别问题,建议使用linux系统下的函数试试

譬如:
在头文件   #include <mach/regs-gpio.h>   中对各寄存器的定义
就有
#define S3C2410_GPFCON           S3C2410_GPIOREG(0x50)
#define S3C2410_GPFDAT           S3C2410_GPIOREG(0x54)
#define S3C2410_GPFUP           S3C2410_GPIOREG(0x5
   

论坛徽章:
1
水瓶座
日期:2014-10-18 20:17:41
4 [报告]
发表于 2012-05-05 19:40 |只看该作者
回复 2# xxw19840406


    可是我用mknod 在/dev/下创建了设备节点的啊,

论坛徽章:
1
水瓶座
日期:2014-10-18 20:17:41
5 [报告]
发表于 2012-05-05 19:41 |只看该作者
回复 3# henuzs


    恩,学习了,谢谢!

论坛徽章:
0
6 [报告]
发表于 2012-05-06 08:36 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP