免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2184 | 回复: 9

[硬件及驱动] 驱动insmod时出现以下错误,求高人指点。。 [复制链接]

论坛徽章:
0
发表于 2013-01-09 10:48 |显示全部楼层
~/tmp # insmod ads8556_dev.ko
Unable to handle kernel paging request at virtual address 59000000
pgd = c3a10000
[59000000] *pgd=00000000
Internal error: Oops: 805 [#2]
last sysfs file: /sys/class/beeper/beeper/dev
Modules linked in: ads8556_dev(+) s3c2440_beeper s3c24xx_motor s3c2410kbd nls_ut
f8 nls_cp936 [last unloaded: adc2440]
CPU: 0    Tainted: G      D     (2.6.32.2 #4)
PC is at init_module+0x18/0xf4 [ads8556_dev]
LR is at 0x56000000
pc : [<bf051018>]    lr : [<56000000>]    psr: 60000013
sp : c39edf38  ip : 00000000  fp : 00000000
r10: 00000000  r9 : c39ec000  r8 : c003b008
r7 : 0000fc00  r6 : 00000001  r5 : 00000000  r4 : 59000000
r3 : c03fb620  r2 : c39ec000  r1 : 00000000  r0 : bf051000
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: c000717f  Table: 33a10000  DAC: 00000015
Process insmod (pid: 464, stack limit = 0xc39ec270)
Stack: (0xc39edf38 to 0xc39ee000)
df20:                                                       bf051000 00000000
df40: c39ec000 bf051000 00000000 00000000 00014bfb c003a354 bf051000 00000000
df60: 00000001 00000000 bf04e3a0 00000000 000e7008 00014bfb c003b008 c39ec000
df80: 00000000 c007c910 000e7018 00014bfb 000e7008 00014bfb 000e3744 000e4000
dfa0: 00000080 c003ae60 00014bfb 000e3744 000e7018 00014bfb 000e7008 bed14dc0
dfc0: 00014bfb 000e3744 000e4000 00000080 bed14ca4 00000000 0000029e 00000000
dfe0: bed14ad8 bed14ac8 000225e8 4018cb00 60000010 000e7018 00000000 00000000
[<bf051018>] (init_module+0x18/0xf4 [ads8556_dev]) from [<c003a354>] (do_one_ini
tcall+0x5c/0x1bc)
[<c003a354>] (do_one_initcall+0x5c/0x1bc) from [<c007c910>] (sys_init_module+0xb
8/0x1e0)
[<c007c910>] (sys_init_module+0xb8/0x1e0) from [<c003ae60>] (ret_fast_syscall+0x
0/0x2
Code: e3a0e456 e3a04459 e3a06001 e3a07b3f (e5c4c000)
---[ end trace b29639688d3c6bec ]---
Segmentation fault

论坛徽章:
0
发表于 2013-01-09 11:09 |显示全部楼层
似乎遇到过,给大家看看代码。
是不是用ioremap了?
可能是那东西错了,

论坛徽章:
0
发表于 2013-01-09 16:14 |显示全部楼层
回复 2# xfortune



    #include<mach/regs-gpio.h>
#include<mach/hardware.h>
#include<linux/sched.h>
#include<linux/interrupt.h>


#define ADS8556_MAJOR 251        //需修改?
#define DEVICE_NAME "ads8556_dev"
static DECLARE_WAIT_QUEUE_HEAD(wq);
//#define CLKCON 0x4C00000C

#define GPECON 0x56000040
#define GPEDAT 0x56000044
#define GPEUP  0x56000048

#define GPGCON 0x56000060
#define GPGDAT 0x56000064
#define GPGUP  0x56000068

#define SPCON0 0x59000000
#define SPSTA0 0x59000004
#define SPPIN0 0x59000008
#define SPIPRE0 0x5900000C
#define SPTDATE0 0x59000010
#define SPRDATE0 0x59000014

static int Device_Open=0;
int ADS8556_init(void);
void ADS8556_exit(void);
int spidev_init(void);
int gpio_init(void);
static int ADS8556_open(struct inode * inode,struct file * filp);
static int ADS8556_release(struct inode * inode,struct file * filp);
static ssize_t ADS8556_read(struct file * filp,char * buffer, size_t count, loff_t * ppos);
static void ADS8556_int_handler(int irq,void * dev_id);

static struct file_operations ADS8556_fops={
        .owner=THIS_MODULE,
        .read=ADS8556_read,
        .open=ADS8556_open,
        .release=ADS8556_release,
};
int spidev_init(void)
{
        __raw_writeb(0x00,SPCON0);
        __raw_writeb(0x01,SPSTA0);
        __raw_writeb(0x00,SPPIN0);
        __raw_writeb(0x00,SPIPRE0);
        __raw_writeb(0x00,SPTDATE0);
__raw_writeb(0x00,SPRDATE0);

        return 0;
}int spidev_mode(void)
{
        __raw_writeb(0x3C,SPCON0);
        return 0;
}
int gpio_init(void)
{
        __raw_writel(0x0,GPECON);
        __raw_writew(0x0000,GPEUP);
        __raw_writel(0x0,GPGCON);
        __raw_writew(0xfc00,GPGUP);
        return 0;
}
int gpio_set(void)
{
//配置相关IO引脚
        __raw_writel((1<<1)|(0x3<<2),GPGCON);
        __raw_writel((0x2<<26)|(0x2<<22)|(1<<20)|(1<<1|(1<<16)|(1<<14),GPECON);
        __raw_writew((1<<13)|(1<<11),GPEUP);
        __raw_writew(0x1,GPGUP);
//      __raw_writew(0x0000,&GPGDAT);         //清零GPGDAT
        return 0;
}


static int Major;
int __init ADS8556_init(void)
{
//      __raw_writel((1<<13)|(1<<1,CLKCON);
        spidev_init();  //spi初始化
        gpio_init();    //io初始化
        spidev_mode();  //spi工作方式设置 ,中断模式 ,主设备,低电平,格式化A
        gpio_set();     //相关IO口功能设置
int ret;
        // 注册中断
        ret=request_irq(IRQ_EINT8,ADS8556_int_handler,IRQF_SHARED,DEVICE_NAME,NULL);
        if (ret) {
                return ret;
        }
        //注册ADS8556
        Major=register_chrdev(ADS8556_MAJOR,DEVICE_NAME,&ADS8556_fops);
        if(Major<0)
        {
                //主设备号小于0,则注册失败
                printk ("ADS8556 init_module:failed with %d\n",Major);
                return Major;
        }
        //设备权限设定,用哪个函数?
        printk(DEVICE_NAME "initialized\n";
        return 0;

}
module_init(ADS8556_init);
static int ADS8556_open(struct inode * inode,struct file * filp)
{
         if (Device_Open)
         {
                 return -EBUSY;
         }
        Device_Open++;
        return 0;
}

static int ADS8556_release(struct inode * inode,struct file * filp)
{
        Device_Open--;
        return 0;
}

//驱动程序的读函数
static ssize_t ADS8556_read(struct file * filp,char * buffer, size_t count, loff_t * ppos)
{
        unsigned long data0 ,data1,data;

        //      启动AD转换
        __raw_writew((1<<,GPEDAT);
        wait_event_interruptible(wq,(GPGDAT&1==0));
        __raw_writew(0x1,GPGDAT);
        data0=SPRDATE0 & 0xff;             //从SPRDATA0读数据
//      interruptible_sleep_on(&readwait); //进入睡眠,等待中断
        wait_event_interruptible(wq,(GPGDAT&1==0));
data1=SPRDATE0 & 0xff;
        data=data1+(data0<<;
        copy_to_user(buffer,(char *)&data,sizeof(data));     //复制数据到用户空间
        return sizeof(data);
}

//中断处理函数
static void ADS8556_int_handler(int irq,void * dev_id)
{
        __raw_writew(0x0,GPGDAT);
        wake_up_interruptible(&wq);
}


//驱动卸载函数
void __exit ADS8556_exit(void)
{
        unregister_chrdev(ADS8556_MAJOR,DEVICE_NAME); //注销ADS8556
        free_irq(IRQ_EINT8,NULL);                     //释放中断
}
module_exit(ADS8556_exit);
MODULE_LICENSE("GPL";
因为刚入手写的比较乱。。大家帮忙看看吧。。

论坛徽章:
0
发表于 2013-01-09 16:15 |显示全部楼层
虚拟机里已经成功生成。ko文件,但放在板子里insmod时,出现上面的错误。。

论坛徽章:
0
发表于 2013-01-09 17:41 |显示全部楼层
你在操作寄存器的时候不能把所有的寄存器地址都定义上,
需要一个基地址,然后做相应操作。参见ioremap

例如:

static void __iomem *base_led_addr;


#define GPB_CON (*(volatile unsigned long *)(base_addr + 0x10))
#define GPB_DAT (*(volatile unsigned long *)(base_addr + 0x14))

base_addr定义
base_addr = ioremap(0x56000000,0x20);

当然还有一种方式定义         ,你可以搜相关资料

论坛徽章:
2
酉鸡
日期:2013-09-26 11:11:15摩羯座
日期:2014-01-08 13:45:19
发表于 2013-01-09 17:42 |显示全部楼层
先单步定位下哪句话挂了吧

论坛徽章:
0
发表于 2013-01-09 17:43 |显示全部楼层
回复 5# xfortune


    static void __iomem *base_addr;

论坛徽章:
0
发表于 2013-01-09 20:35 |显示全部楼层
回复 7# xfortune
额,谢谢楼上,再请问SPI寄存器的访问方法是否与GPIO寄存器的访问方法一样呢?


   

论坛徽章:
0
发表于 2013-01-10 09:47 |显示全部楼层
难道不一样吗? 不就是换个地址吗?

论坛徽章:
0
发表于 2013-01-10 13:33 |显示全部楼层
回复 9# xfortune
我用错了个空指针。。已搞定,谢谢楼上

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP