|
在英贝德的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 |
|