空指针错误oops!!!

发布于 2022-09-23 14:09:19 字数 6759 浏览 14 评论 0

原代码:(简单的ADC驱动)

  1. #include <linux/kernel.h>
  2. #include <linux/config.h>
  3. #include <linux/module.h>
  4. #include <linux/init.h>
  5. #include <linux/fs.h>
  6. #include <linux/delay.h>
  7. #include <linux/devfs_fs_kernel.h>
  8. #include <asm/io.h>
  9. #include <asm/arch/hardware.h>
  10. #include <asm/arch-s3c2410/regs-adc.h>
  11. #define   MAJOR_ID  109
  12. #define   DEV_NAME  "adc"
  13. #define   ADC_CON    (*(volatile unsigned int*)S3C2410_ADCCON)
  14. #define   ADC_DAT0   (*(volatile unsigned int*)S3C2410_ADCDAT0)
  15. static int  adc_open(struct inode * inode, struct file * file)
  16. {  int ADC_MAX_FREQ=2500000;
  17.    int PCLK=50000000;
  18.    int ADC_PRSCVL;
  19.    ADC_PRSCVL=(PCLK/ADC_MAX_FREQ)-1;
  20.    ADC_CON=(ADC_CON|(S3C2410_ADCCON_PRSCEN)|(S3C2410_ADCCON_PRSCVL(ADC_PRSCVL))|(S3C2410_ADCCON_SELMUX(0))|(S3C2410_ADCCON_STDBM));
  21.    mdelay(200);
  22.    return 0;
  23.     }
  24. static int adc_read(struct file * file, char __user * userbuf, size_t count, loff_t * off)
  25. {  int vaule;
  26.    ADC_CON=(ADC_CON|0x01);            /*开始启动转换*/
  27.    if (ADC_CON&0x01);                      /*开始使能变为低电平?同时读取转换的数据,把数据读写到ADT1与DAT0中*/
  28.    if (ADC_CON&0x8000);               /*AD转换结束?*/
  29.    *userbuf=ADC_DAT0;
  30.    return count;
  31.     }
  32. static int adc_close(struct inode * inode, struct file * file)
  33. {   ADC_CON=0x3cf4;
  34.     return 0;
  35.     }
  36. static struct file_operations adc = {
  37. .open     =   adc_open,
  38. .read     =   adc_read,
  39. .release  =   adc_close,
  40. };
  41. static int __init adc_init(void)
  42. { int result;
  43.   result=register_chrdev(MAJOR_ID,DEV_NAME,&adc);
  44.   if (result<0)
  45.           {printk ("the drives registre is fail!!\n");
  46.      return result;
  47.        }
  48.   else
  49.           {printk ("the drives registre is success!!\n");
  50.      devfs_mk_cdev(MKDEV(MAJOR_ID,0),S_IFCHR | S_IRUSR | S_IWUSR,"adc");
  51.      return result;
  52.              }
  53.     return 0;
  54.     }
  55. static void __exit adc_exit(void)
  56. { unregister_chrdev(MAJOR_ID,DEV_NAME);
  57.   devfs_remove(DEV_NAME);
  58.     }
  59. module_init(adc_init);
  60. module_exit(adc_exit);
  61. MODULE_LICENSE("GPL");
  62. MODULE_AUTHOR("kang");
  63. MODULE_DESCRIPTION("ADC");

复制代码

///////////////////////////////////////////////////////////////////////////////////////////////////////
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c2dc4000
[00000000] *pgd=3360b031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1]
Modules linked in: adc s3c2410mci clk
CPU: 0
PC is at open+0x10/0x44 [adc]
LR is at chrdev_open+0x14c/0x164
pc : [<bf005010>]    lr : [<c00888cc>]    Not tainted
sp : c3c09ed4  ip : c3c09ee8  fp : c3c09ee4
r10: 4013d180  r9 : c3c08000  r8 : c3e179e0
r7 : 00000000  r6 : 00000000  r5 : c0013c54  r4 : c3b91240
r3 : bf005000  r2 : 00000000  r1 : c3e179e0  r0 : c0013c54
Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  Segment user
Control: C000717F  Table: 32DC4000  DAC: 00000015
Process run_adc (pid: 422, stack limit = 0xc3c08194)
Stack: (0xc3c09ed4 to 0xc3c0a000)
9ec0:                                              c3b91240 c3c09f0c c3c09ee8
9ee0: c00888cc bf005010 00000000 c3e179e0 c0013c54 c03e59c0 c37a508c 00000000
9f00: c3c09f30 c3c09f10 c007e668 c0088790 00000002 00000003 00000002 c3439000
9f20: c002f004 c3c09f84 c3c09f34 c007e7e0 c007e574 c37a508c c03e59c0 00000003
9f40: c03f1ba0 c3c08000 00000101 00000001 00000000 4013d180 c3c09f84 c3c09f68
9f60: c007e83c c009aaa8 bea2cd6c 00000003 bea2cd6c bea2cd6c c3c09fa4 c3c09f88
9f80: c007e99c c007e7ac bea2cd64 4001bd80 000085b0 00000005 00000000 c3c09fa8
9fa0: c002ee80 c007e968 bea2cd64 c0035788 00008694 00000002 bea2cd6c 00000000
9fc0: bea2cd64 4001bd80 000085b0 00000001 4013f430 00008490 4013d180 bea2cd34
9fe0: 00000000 bea2cb80 00003c00 400e0c40 60000010 00008694 f737b733 7f7f1f3f
Backtrace:
[<bf005000>] (open+0x0/0x44 [adc]) from [<c00888cc>] (chrdev_open+0x14c/0x164)
r4 = C3B91240
[<c0088780>] (chrdev_open+0x0/0x164) from [<c007e668>] (dentry_open+0x104/0x238)

r8 = 00000000  r7 = C37A508C  r6 = C03E59C0  r5 = C0013C54
r4 = C3E179E0
[<c007e564>] (dentry_open+0x0/0x238) from [<c007e7e0>] (filp_open+0x44/0x4c)
r8 = C002F004  r7 = C3439000  r6 = 00000002  r5 = 00000003
r4 = 00000002
[<c007e79c>] (filp_open+0x0/0x4c) from [<c007e99c>] (sys_open+0x44/0x88)
r4 = BEA2CD6C
[<c007e958>] (sys_open+0x0/0x88) from [<c002ee80>] (ret_fast_syscall+0x0/0x2c)
r7 = 00000005  r6 = 000085B0  r5 = 4001BD80  r4 = BEA2CD64
Code: e1a0c00d e92dd810 e24cb004 e3a02000 (e5923000)
Segmentation fault
空指针出现的错误地方,应该是在OPEN函数里面!是不是那个地址映射的问题?不过,之前我都是这样做的,没有引用内核里面的__raw_write( ).

[ 本帖最后由 dreamice 于 2009-1-7 16:36 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

掌心的温暖 2022-09-30 14:09:19

我顶!!!

恋竹姑娘 2022-09-30 14:09:19

各位前辈!!帮一下忙嘛!
在此谢过!!

困倦 2022-09-30 14:09:19

又是adc啊

孤芳又自赏 2022-09-30 14:09:19

原帖由 shuiyu123 于 2009-1-7 15:36 发表
原代码:(简单的ADC驱动)

#include
#define   MAJOR_ID  109
#define   DEV_NAME  "adc"
#def ...

你open函数中的这句话错了
ADC_CON=(ADC_CON|(S3C2410_ADCCON_PRSCEN)|(S3C2410_ADCCON_PRSCVL(ADC_PRSCVL))|(S3C2410_ADCCON_SELMUX(0))|(S3C2410_ADCCON_STDBM));

因为
#include <asm/arch-s3c2410/regs-adc.h>中

#define S3C2410_ADCREG(x) (x)
#define S3C2410_ADCCON           S3C2410_ADCREG(0x00)

所以你定义的#define   ADC_CON    (*(volatile unsigned int*)S3C2410_ADCCON)
实际上是一个NULL

呵呵,把ADC寄存器基地址用ioremap换成虚地址后再操作

轻拂→两袖风尘 2022-09-30 14:09:19

原帖由 shuiyu123 于 2009-1-7 15:36 发表
原代码:(简单的ADC驱动)

#define   MAJOR_ID  109
#define   DEV_NAME  "adc"
#def ...

现在觉得OOPS其实很性感

可遇━不可求 2022-09-30 14:09:19

怎么我在有的地方可以使用呢!
#define  GPFDAT    (*(volatile unsigned*)S3C2410_GPFDAT)

static int write(struct file * file, const char __user * userbuf,size_t count, loff_t * off)
{   printk ("write data to GPFDAT!!!\n");
    printk ("data=%x\n",*userbuf);
        GPFDAT =(*userbuf);
    return count;
  }

剑心龙吟 2022-09-30 14:09:19

原帖由 shuiyu123 于 2009-1-7 17:16 发表
怎么我在有的地方可以使用呢!
#define  GPFDAT    (*(volatile unsigned*)S3C2410_GPFDAT)

static int write(struct file * file, const char __user * userbuf,size_t count, loff_t * off)
{   printk  ...

你把GPFDAT打出来看看,这个宏其实已经加上0xF4000000的偏移量了

蓝礼 2022-09-30 14:09:19

原帖由 shuiyu123 于 2009-1-7 17:16 发表
怎么我在有的地方可以使用呢!
#define  GPFDAT    (*(volatile unsigned*)S3C2410_GPFDAT)

static int write(struct file * file, const char __user * userbuf,size_t count, loff_t * off)
{   printk  ...

你把GPFDAT打出来看看,这个宏其实已经加上0xF4000000的偏移量了

缪败 2022-09-30 14:09:19

你把你驱动的反汇编代码贴出来

用这个命令:
arm-linux-objdump -D adc.o > adc.objdump

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文