crb8 发表于 2007-5-21 16:56:22

EP9315驱动出错

在英贝德的EBD9315开发板上,驱动EP9315的EGPIO8~15口的实验。采用模块驱动,能够正常加载设备节点,但执行测试程序时出错如下:请高手指点:
Unable to handle kernel paging request at virtual address 7e840014
pgd = c0ac0000
*pgd=00000000, *pmd = 00000000
Internal error: Oops: 805
CPU: 0
pc : [<c88c4188>]    lr : [<c004621c>]    Tainted: PF
sp : c0ac7f54ip : c0ac7f84fp : c0ac7f80
r10: bffffe03r9 : c0ac6000r8 : 00000001
r7 : 00000000r6 : ffffffear5 : c0aed7e0r4 : c0aed800
r3 : 000000ffr2 : 7e840014r1 : bffffe03r0 : c0aed7e0
Flags: NzCvIRQs onFIQs onMode SVC_32Segment user
Control: C000717FTable: 00AC0000DAC: 00000015
Process GPIOdrv_test (pid: 334, stack limit = 0xc0ac6390)
Stack: (0xc0ac7f54 to 0xc0ac8000)
7f40:                                              c0cd6840 7e840004 7e840014
7f60: 00001000 c0aed800 00000001 bffffe03 c0aed7e0 00000000 c0ac7f84 c004621c
7f80: c88c4160 00000000 40126668 4001c720 bffffe54 00008778 00000004 c001b604
7fa0: 40127c98 c001b460 4001c720 c001b3fc 00000003 bffffe03 00000001 bffffe03
7fc0: 4001c720 bffffe54 00008778 4000b040 00000001 000084dc 40127c98 bffffe20
7fe0: 400cf2f0 bffffe00 00008544 400cf2f4 60000010 00000003 7f1011d2 042f967f
Backtrace:
Function entered at [<c88c4150>] from [<c004621c>]
Code: e59f3058 e50b3028 e51b2024 e3a030ff (e5823000)
Segmentation fault

驱动程序如下:
/************************************************************************
*File Name:        GPIOdrv,c
*Description:        drive GPIO on HDB93xx system
*************************************************************************/
#ifdef MODULE
#define        __NO_VERSION__
#include <linux/module.h>
#include <linux/version.h>
#endif

#define        __KERNEL__
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/fcntl.h>
#include <asm-arm/arch-ep93xx/regmap.h>

#define IO_ADDRESS(pa) (((unsigned int)pa)-IO_BASE_PHYS + IO_BASE_VIRT)

static int GPIO_write(struct file *,const char *,int,loff_t *);

static void Delay(int);
static unsigned int major = 0;

static struct file_operations GPIO_fops = {
        write:        (void(*))GPIO_write,
};

char GPIO_name[] = "GPIOdrv";

static int __init GPIOdrv_init_module(void){
        int retv;
        retv = register_chrdev(major,GPIO_name,&GPIO_fops);
        if(retv<0){
                printk("register fail\n");
                return retv;
        }
        if(major == 0)
                major =retv;
        printk("GPIO_device ok\n");
        return 0;
}

static void __exit GPIOdrv_cleanup(void){
        int retv;
        retv = unregister_chrdev(major,GPIO_name);
        if(retv<0){
                printk("unregister fail\n");
                return;
        }
        printk("GPIODRV:Good bye!\n");
}

static int GPIO_write(struct file *GPIO_file,const char *buf,int len,loff_t *loff){
        unsigned int iopdata;
        volatile unsigned int *pbddr;
        volatile unsigned int *pbdr;
        pbddr = (volatile unsigned int *)IO_ADDRESS(GPIO_PBDDR);
        pbdr = (volatile unsigned int *)IO_ADDRESS(GPIO_PBDR);
        //printk("-\n");
        //printk("%d,%d",pbddr,pbdr);
        //return len;
        *pbddr = 0xff;
        if(copy_from_user((char *)&iopdata,buf,len))
                return -EFAULT;
        *pbdr = iopdata;
        return len;
}

static void Delay(int x)
{
        int j,i,k;
        for(i=0;i<x;i++)
                for(j=0;j<0xff;j++)
                        for(k=0;k<0xff;k++)
                                ;
}

module_init(GPIOdrv_init_module);
module_exit(GPIOdrv_cleanup);

//end of GPIOdrv.c


测试程序如下:
/****************************************************************
*File Name:        GPIOdrv_test.c
*Description:        Test GPIO driver on ep93XX board.
****************************************************************/

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>

static void Delay(int);

int main(void)
{
        int fd,count;
        int i,j;

        unsigned char iodata;

        if((fd = open("/dev/GPIOdrv",O_RDWR)) == -1){
                perror("open error");
                exit(1);
        }
        else
                printf("open GPIOdrv success");
        getchar();
        iodata = 0x0;
        if((count = write(fd,(char *)&iodata,1))!= 1){
                perror("write error");
                exit(1);
        }
        else
                printf("write all ioport to 0,success\n");
        getchar();
        for(j=0;j<5;j++){
        for(i=0;i<8;i++){
                iodata|=0x01<<i;
                if((count = write(fd,(char *)&iodata,1))!=1){
                        perror("write error2");
                        exit(1);
                }
                else
                        printf("write ioport to 1 success\n");
                Delay(25);
        }
        for(i=0;i<8;i++){
                iodata&=0x7f>>i;
                if((count = write(fd,(char *)&iodata,1))!=1){
                        perror("write error3");
                        exit(1);
                }
                else
                        printf("write ioport to 0 success\n");
                Delay(25);
        }
        }
        close(fd);
        return(0);
}

static void Delay(int x){
        int i,j,k;
        for(i=0;i<x;i++)               
                for(j=0;j<0xff;j++)
                        for(k=0;k<0xff;k++)
                                ;
}

//end of GPIOdrv_test.c

crb8 发表于 2007-5-21 16:59:04

会不会是IO已被占用?怎么查看是否被占用?
页: [1]
查看完整版本: EP9315驱动出错