|  | 
 
| 在英贝德的EBD9315开发板上,驱动EP9315的EGPIO8~15口的实验。采用模块驱动,能够正常加载设备节点,但执行测试程序时出错如下:请高手指点: Unable to handle kernel paging request at virtual address 7e840014
 pgd = c0ac0000
 [7e840014] *pgd=00000000, *pmd = 00000000
 Internal error: Oops: 805
 CPU: 0
 pc : [<c88c4188>]    lr : [<c004621c>]    Tainted: PF
 sp : c0ac7f54  ip : c0ac7f84  fp : c0ac7f80
 r10: bffffe03  r9 : c0ac6000  r8 : 00000001
 r7 : 00000000  r6 : ffffffea  r5 : c0aed7e0  r4 : c0aed800
 r3 : 000000ff  r2 : 7e840014  r1 : bffffe03  r0 : c0aed7e0
 Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  Segment user
 Control: C000717F  Table: 00AC0000  DAC: 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
 | 
 |