w133155 发表于 2014-4-27 20:50:53

关于写LED灯驱动报错

老师们好,我自己参照别的视频写了个内存,但是在运行调试程序的时候报错:Unable to handle kernel NULL pointer dereference at virtual address 0000001e
pgd = f363c000
*pgd=5355f031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#4] PREEMPT
last sysfs file: /sys/devices/virtual/vc/vcsa2/dev
Modules linked in: mled(P) rt5370sta ds18b20 s5pv210_hdmi wm8960
CPU: 0    Tainted: P      D      (2.6.35.7-EmbedSky #1)
PC is at do_sys_open+0x80/0x11c

后面还有一大堆地址就不全部列出了,下面是我的驱动源码,麻烦老师看看:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/ioport.h>
//#include "mled.h"

#define CON 0xE0200060
#define DAT 0xE0200064

struct cdev mdev;
dev_tdevno;

unsigned int *led_config;
unsigned int *led_data;

int mem_open(struct inode *node,struct file *filp)
{ led_config = ioremap(0xe0200060,4);
if(led_config != NULL)
      {
          //writel(0x00011000,led_config);

          led_data = ioremap(0xe0200064,1);
          if(led_data == NULL)
                {printk("data fail\n");
                  //iounmap();
                  return 0;
                }

          iowrite32(0x0001<<16|0x0001<<12,led_config);
          printk("ioremap sucess\n");
      }else
                {printk("config fail\n");}
}
long mem_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{         printk("ioctl\n");
      switch (cmd)
                {
                  case 1:
                        printk("ONON\n");
                        iowrite32(0x3<<3,led_data);
                        return 0;
                  case 0:
                        iowrite32(0x0<<3,led_data);
                        //writeb(0x00,led_data);
                        return 0;
                  default:
                        return -EINVAL;
                }
}

const struct file_operations memfops =
{
      .unlocked_ioctl = mem_ioctl,
      .open = mem_open,

};

static int led_init(void)
{//50
printk("led_init\n");
cdev_init(&mdev,&memfops);
alloc_chrdev_region(&devno,0,1,"myled");
cdev_add(&mdev,devno,1);//é豸×¢2á
printk("led_init complete\n");
return 0;
}

static void led_exit(void)
{//59
cdev_del(&mdev);
unregister_chrdev_region(devno,1);
}

module_init(led_init);
module_exit(led_exit);

调试程序源码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
//#include "mled.h"


int main(int argc,char *argv[])
{ int fd;
int cmd;
if (argc < 2)
    {
      printf("please enter the second para!\n");
      return 0;
    }
cmd = atoi(argv);
fd = open("/dev/myled",O_RDWR);
if(fd < 0)
{
      printf("open fail \n");
      return 0;
}
if(cmd == 1)
{
printf("cmd= 1\n");
ioctl(fd,1);
}
else
{
printf("else\n");
ioctl(fd,0);
}
return 0;
}



加载过程是:insmod mled.ko
                  cat /proc/devies
看了myled 是250   
然后            mknod /dev/myled c 250 0
求教。

wbz073 发表于 2014-4-28 09:18:39

仔细检查你的源码空指针错误的原因,看你地址错误部分的函数调用,锁定错误位置。

w133155 发表于 2014-4-28 18:37:25

wbz073 发表于 2014-4-28 09:18
仔细检查你的源码空指针错误的原因,看你地址错误部分的函数调用,锁定错误位置。

版主,能麻烦你帮我看下我映射地址和写数据有问题没吗?我的配置寄存器和数据寄存器两个数据的修改不知道有问题不。

w133155 发表于 2014-4-28 18:38:26

#define LEDCON 0xe0200060 //0xe0200240
#define LEDDAT 0xe0200064
static void * led_config;
static void * led_data;

struct cdev cdev;
dev_t devno;

int led_open(struct inode * node, struct file * filp)
{
      led_config = ioremap(LEDCON,4);
      iowrite32((0x11<<12),LEDCON);//writel(0x11111111,led_config);
      led_data = ioremap(LEDDAT,4);
      printk("ioremap succes\n");
      return 0;
}

long led_ioctl(struct file * filp, unsigned int cmd, unsigned long arg)
{
      switch (cmd)
      {
            case LED_ON:
                printk("d:cmd=LED_ON\n");
                writel(0xff,led_data);//iowrite32((0x3<<3),led_data);
                printk("d:cmd=LED_ON\n");
                return 0;

            case LED_OFF:
                {
                printk("d:cmd = LED_off\n");
                writel(0x1f,led_data);//iowrite32((0x00<<3),led_data);
                return 0;
页: [1]
查看完整版本: 关于写LED灯驱动报错