又好,驱动太长,只贴关键位,如下:
......
static int ccd_stepper_open(struct inode *inode, struct file *file);
static int ccd_stepper_release(struct inode *inode, struct file *file);
static ssize_t ccd_stepper_read(struct file *filp, char *buff, size_t count, loff_t *offp);
static ssize_t ccd_stepper_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp);
static int ccd_stepper_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long msg);
static irqreturn_t ccd_stepper_reading(int irq, void *dev_id);
static struct file_operations ccd_stepper_fops= {
.owner = THIS_MODULE,
.read = ccd_stepper_read,
.write = ccd_stepper_write,
.ioctl = ccd_stepper_ioctl,
.open = ccd_stepper_open,
.release = ccd_stepper_release,
};
struct ccd_stepper_dev {
struct ccd_stepper_qset *data;
int quantum;
int qset;
unsigned long size;
unsigned int access_key;
struct semaphore sem;
struct cdev cdev;
};
struct ccd_stepper_dev devs;
static void ccd_stepper_setup_dev(struct ccd_stepper_dev *dev, int minor)
{
int err, devno = MKDEV(CCD_STEPPER_MAJOR, minor);
cdev_init(&dev->cdev, &ccd_stepper_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &ccd_stepper_fops;
err = cdev_add(&dev->cdev,devno,1);
if (err) {
printk(KERN_NOTICE "Error %d adding ccd_stepper %d \n",err,minor);
printk(KERN_WARNING "Error: unable to add ccd_stepper_dev \n");
}
printk(KERN_WARNING "OK: Be able to add cdev! \n");
}
static int __init ccd_stepper_init(void)
{
int result;
struct class *ccd_stepper_class;
dev_t dev = MKDEV(CCD_STEPPER_MAJOR, CCD_STEPPER_MINOR);
if (CCD_STEPPER_MAJOR) {
result = register_chrdev_region(dev,1,DEVICE_NAME);
}
else {
result = alloc_chrdev_region(&dev,CCD_STEPPER_MINOR,1,DEVICE_NAME);
CCD_STEPPER_MAJOR=MAJOR(dev);
}
if (result < 0) {
printk(KERN_WARNING "CCD_STEPPER: unable to registe registe major %d !\n", CCD_STEPPER_MAJOR);
return result;
}
ccd_stepper_setup_dev(&devs,CCD_STEPPER_MINOR);
printk(KERN_WARNING "Successfully registed! \nThe major of ccd_stepper device is %d !\n", CCD_STEPPER_MAJOR);
ccd_stepper_class = class_create(THIS_MODULE,"ccd_stepper");
device_create(ccd_stepper_class,NULL,MKDEV(CCD_STEPPER_MAJOR, 0),NULL,"ccd_stepper");
printk(KERN_WARNING "Device ccd_stepper is automatically created!\n");
return 0;
}
static int ccd_stepper_open(struct inode *inode, struct file *file)
{
return 0;
}
.....
下面是我的测试程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>
//#include <sys/stat.h>
int main (int argc, char **argv)
{
int d;
int p;
int fd;
int i;
int j;
if (argc !=3 || sscanf(argv[1], "%d", &d)!=1 || sscanf(argv[2],"%d",&p) !=1 || d < 0 || d > 2 || d < 0 || p > 900) {
fprintf(stderr, "Usage: stpmov 0(left)|1(right)|2(down) p(distance)\n");
exit(1);
}
fd = open("/dev/ccd_stepper",O_WRONLY);
printf("fd = %d \n",fd);
if (fd < 0) {
fprintf(stderr, "Open device ccd_stepper error!\n");
exit(1);
}
else {
printf("Open device ccd_stepper success!\n");
printf("fd = %d \n",fd);
}
....
close(fd);
return 0;
}
这是今天重新修改了的代码,open返回不是-1啦,不过出现了段错误,也不是什么原因?结果如下:
[root@SmartDPY /root]# insmod ccd_stepper.ko
OK: Be able to adding cdev!
Successfully registed!
The major of ccd_stepper device is 252 !
Device ccd_stepper is automatically created!
运行测试程序如下(很多,开始部分没有复制到):
......
5ec0: c3a56300 00000014 c3a85f04 c3a85ee8
5ee0: c009507c bf000088 00000003 c3a56300 00000014 c3a56300 c3a85f7c c3a85f08
5f00: c0095330 c0095014 4001f000 00000008 c39d2100 c3a85f78 c3a84000 00000000
5f20: c3a85f54 c3a85f30 c014b1a0 c014aee0 c39d2100 4001f000 c3a85f78 00000004
5f40: c0029008 c3a84000 c3a85f74 c3a85f58 c008950c 00000003 00000014 00000001
5f60: c3a56300 c0029008 c3a84000 00000000 c3a85fa4 c3a85f80 c0095664 c00950bc
5f80: ffffffff 00000000 000086b0 00000000 00008440 00000036 00000000 c3a85fa8
5fa0: c0028e60 c0095634 000086b0 00000000 00000003 00000001 00000014 00000001
5fc0: 000086b0 00000000 00008440 00000036 00000000 00000000 40025000 be98fb84
5fe0: 00000000 be98fb60 00008630 400e4cac 60000010 00000003 00000000 00000000
Backtrace:
[<bf000078>] (ccd_stepper_ioctl+0x0/0xa8 [ccd_stepper]) from [<c009507c>] (vfs_i
octl+0x78/0x80)
r5:00000014 r4:c3a56300
[<c0095004>] (vfs_ioctl+0x0/0x80) from [<c0095330>] (do_vfs_ioctl+0x284/0x578)
r7:c3a56300 r6:00000014 r5:c3a56300 r4:00000003
[<c00950ac>] (do_vfs_ioctl+0x0/0x578) from [<c0095664>] (sys_ioctl+0x40/0x68)
[<c0095624>] (sys_ioctl+0x0/0x68) from [<c0028e60>] (ret_fast_syscall+0x0/0x2c)
r7:00000036 r6:00008440 r5:00000000 r4:000086b0
Code: e59f202c e3a03412 e3a0000d e3a01000 (e1c320b0)
---[ end trace c9a7dd5c6bfd5e9b ]---
Trying to free already-free IRQ 16
fd = 3 // 这里好像跳过了本应该有点的输出
Segmentation fault
好像是个普通问题,不过本人没经验,搞不懂...麻烦看看,是哪里有问题..谢谢!