主题 : 帮浏览下这个AD驱动及test,运行后:Segmentation fault 复制链接 | 浏览器收藏 | 打印
级别: 侠客
UID: 3241
精华: 0
发帖: 57
金钱: 435 两
威望: 327 点
综合积分: 114 分
注册时间: 2009-01-01
最后登录: 2017-05-18
楼主  发表于: 2009-04-22 21:10

 帮浏览下这个AD驱动及test,运行后:Segmentation fault

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
    
#include <plat/regs-adc.h>
#include <mach/regs-gpio.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>

#define ADC_MAJOR 201 // 主设备号
#define DEVICE_NAME "adc_dev" // 设备名
#define SUCCESS 0
#define adc_con (unsigned long)ioremap(0x58000000,4)  //
#define adc_dat0 (volatile unsigned long)ioremap(0x5800000c,4)

static int Device_Open = 0;
int adc_init(void);
//void devfs_mk_cdev(int,int,char*);
void adc_cleanup(void);
static int device_open(struct inode *,struct file *);
static int device_release(struct inode *,struct file *);
static ssize_t device_read();
static ssize_t device_ioctl(struct inode *,struct file *,unsigned int,unsigned long);
int init_module(void);
void cleanup_module(void);

struct file_operations adc_ops =                       //  < linux/fs.h >
{    
    .owner = THIS_MODULE,
    .read = device_read,
    .ioctl = device_ioctl,
    .open = device_open,
    .release = device_release,
};

static int Major;

int __init adc_init(void) // 初始化
{
    Major = register_chrdev(ADC_MAJOR,DEVICE_NAME,&adc_ops); // 设备注册
    if(Major <0)
    {
        printk("ADC init_module:failed with %d\n",Major);

        return Major;
    }
    //devfs_mk_cdev(MKDEV(ADC_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR |
//S_IRGRP,DEVICE_NAME);
    printk(DEVICE_NAME " initialized\n");
    return 0;
}

static int device_open(struct inode * inode,struct file *file)

{
    if(Device_Open)
    {
        return -EBUSY;
    }
    Device_Open++;        //
    return SUCCESS;
}

static int device_release(struct inode * inode,struct file *file)
{
    Device_Open --;
    return 0;
}
static int adc_setadccon(void)
    {
    __raw_writel((1<<14)|(0x5<<6), adc_con); // 设置 ADCCON
    return 0;
    }
static ssize_t device_read(void)
{
    unsigned long buf;
    __raw_writel(__raw_readl(adc_con)|0x1, adc_con); // 启动AD转换
    while(__raw_readl(adc_con) &0x1); // 启动转换后等待启动位清零
    while(!(__raw_readl(adc_con) & 0x8000)); // 等待转换是否完毕
    buf=__raw_readl(adc_dat0) & 0x3ff; // 读取数据
    //*buffer=(unsigned char)buf;
    //buffer++;
    //*buffer=(unsigned char)(buf>>8);
    return buf;
}
static ssize_t device_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
    {
    unsigned long val;
    switch(cmd){
          case(0):
          adc_setadccon();
          return 0;
          case(1):
          val=device_read();
          return val;
         }
    }


void adc_cleanup() // 卸载
{
    //int ret;
    unregister_chrdev(Major,DEVICE_NAME);
    //if(ret < 0)
        //{
    //    printk("unregister_chrdev:error %d\n",ret);
    //}
}
module_init(adc_init);
module_exit(adc_cleanup);
MODULE_LICENSE("GPL");
[ 此帖被qinqin04在2009-04-22 21:15重新编辑 ]
级别: 侠客
UID: 3241
精华: 0
发帖: 57
金钱: 435 两
威望: 327 点
综合积分: 114 分
注册时间: 2009-01-01
最后登录: 2017-05-18
1楼  发表于: 2009-04-22 21:18
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

#define device_name "/dev/adc_dev"

int main()
    {
    int i,fd,ret;
    float voltage;
    //char *buffer;
    if((fd=open(device_name,0))<0)
          {
          perror("open device error!");
          exit(1);
          }
    while(1)
        {
        ioctl(fd,0,0);
        for(i=0;i<50;i++)
            {
            ret=ioctl(fd,1,0);
            //val=*buffer;
            voltage=(float)ret;
            voltage=(voltage-1023)*(-1)*3.3/1023;
            printf("val-ain0=%dv\n",voltage);
            }
        ret=close(fd);
        printf("close adc driver test\n");
        }
    return 0;
    }
级别: 侠客
UID: 3241
精华: 0
发帖: 57
金钱: 435 两
威望: 327 点
综合积分: 114 分
注册时间: 2009-01-01
最后登录: 2017-05-18
2楼  发表于: 2009-04-22 21:34
贴上来了才发现篇幅占的有点长....行距太大了
上面是我改的别人的程序 编译生成可执行文件后 ./test 提示:Segmentation fault
没有具体的提示错误,整了半天没法了,大家有时间浏览下 给指点指点
有点耗时间,真不好意思!
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
3楼  发表于: 2009-04-22 22:32
如果你不会用gdb这样的工具,printf()是最简单的debug方法
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 47498
精华: 0
发帖: 19
金钱: 95 两
威望: 19 点
综合积分: 38 分
注册时间: 2011-05-23
最后登录: 2011-09-04
4楼  发表于: 2011-08-30 19:20
   voltage=(voltage-1023)*(-1)*3.3/1023;
double类型,一般不支持,是不是?