免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3151 | 回复: 2
打印 上一主题 下一主题

lradc0通道采集电池电压驱动问题咨询 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-04-11 14:22 |只看该作者 |倒序浏览
大家好,
开发环境:linux2.6.35+imx287处理器
本人参照网上的adc驱动模板,写了个LRADC0单通道的电池电压采集代码,编译成lradc0.ko后,insmod可以加载成功,在/dev下可以看见设备节点,但是一执行测试代码,系统就抱死,卡主不动了,通过调试串口输入任何按键都没反应,包括ctrl+z,也没有反应。

附上驱动代码和测试代码,请各位帮忙分析下,给点思路,本人是新手:
驱动代码:
#include <linux/module.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/jiffies.h>
#include <linux/io.h>
#include <linux/sched.h>
#include <linux/clk.h>
#include <mach/ddi_bc.h>
//#include "ddi_bc_internal.h"
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <mach/regulator.h>
#include <mach/regs-power.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/clock.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <asm/fiq.h>
#include <mach/mx28.h>
#include <mach/regs-lradc.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>


#define DEVICE_NAME  "lradc0"
static struct clk *adc_clock;
static void __iomem *base_addr;
static wait_queue_head_t adc_waitqueue;
struct resource *lradc_ch0_irq;

DECLARE_MUTEX(adc_lock);
EXPORT_SYMBOL(adc_lock);

static volatile int is_read_ok = 0;
static volatile int adc_data;

static int lradc0_open(struct inode *inode, struct file *file);
static ssize_t lradc0_read(struct file *filp, char *buffer, size_t count, loff_t *ppos);
static int lradc0_close(struct inode *inode, struct file *filp);

static struct file_operations lradc0_fops =  
{  
    .owner   = THIS_MODULE,  
    .open    = lradc0_open,  
    .read    = lradc0_read,     
    .release = lradc0_close,  
};  

static struct miscdevice adc_miscdev =  
{  
    .minor  = MISC_DYNAMIC_MINOR,
    .name   = DEVICE_NAME,  
    .fops   = &lradc0_fops,
};


static irqreturn_t lradc0_irq(int irq, void *dev_id)  
{  

    if(!is_read_ok)  
    {      
        adc_data = readl(base_addr +HW_LRADC_CHn(0)) & 0x3ffff;  
   
         is_read_ok = 1;  
       wake_up_interruptible(&adc_waitqueue);  
    }  
   
    return IRQ_RETVAL(IRQ_HANDLED);  
}  



static int lradc0_open(struct inode *inode, struct file *file)  
{  
    int ret;
   
    ret = request_irq(IRQ_LRADC_CH0, lradc0_irq, IRQF_SHARED, DEVICE_NAME, (void *)1);  
    if (ret)  
    {  
        printk(KERN_ERR "Could notallocate ts IRQ_ADC !\n";  
        return -EBUSY;  
    }  
    return 0;  
}  


static void adc_run(void)  
{  
    volatile unsigned int lradccon;  
   
//ctrl0
    lradccon = readl(base_addr);
//31 30
    lradccon &= ~(3 << 30);//3
//0
    lradccon |= (1 << 0);
    writel(lradccon, base_addr);

//ctrl1 16
    lradccon = (1 << 16);
    writel(lradccon, base_addr + HW_LRADC_CTRL1);

//ctrl3 25 24
    lradccon = (0x01 << 24);
    writel(lradccon, base_addr + HW_LRADC_CTRL3);

//ctrl4 0 1 2 3
    lradccon = (0x7 << 0);
    writel(lradccon, base_addr + HW_LRADC_CTRL4);
      
}  



static ssize_t lradc0_read(struct file *filp, char *buff, size_t count, loff_t *offp)  
{  
    int err;  
  
    down_interruptible(&adc_lock);  
     adc_run();   
     wait_event_interruptible(adc_waitqueue,is_read_ok);  
     is_read_ok = 0;  
      err = copy_to_user(buff, (char*)&adc_data, min(sizeof(adc_data),count));  
    up(&adc_lock);  
   
    return err ? -EFAULT : sizeof(adc_data);  
}  


  
static int lradc0_close(struct inode *inode, struct file *filp)  
{  
    free_irq(IRQ_LRADC_CH0, (void *)1);     
    return 0;  
}  
   
static int __init lradc0_init(void)
{  
    int ret;  
     
    adc_clock = clk_get(NULL, "lradc";  
    if (!adc_clock)  
    {  
        printk(KERN_ERR "failed to get lradcclock source\n";  
        return -ENOENT;  
    }  
   
    clk_enable(adc_clock);  
   

    base_addr = ioremap(LRADC_PHYS_ADDR, 0x2A;  
    if (base_addr == NULL)  
    {  
        printk(KERN_ERR "Failed to remapregister block\n";  
        return -ENOMEM;  
        goto fail1;  
    }  
     

    init_waitqueue_head(&adc_waitqueue);  
   
     
    ret = misc_register(&adc_miscdev);  
    if (ret)  
    {  
        printk(KERN_ERR "Failed toregister miscdev\n";  
        goto fail2;  
    }  
   
    printk(DEVICE_NAME "initialized!\n";  
   
    return 0;  
     
fail2:  
    iounmap(base_addr);  
fail1:  
    clk_disable(adc_clock);  
    clk_put(adc_clock);  
   
    return ret;  
}  
   
static void __exit lradc0_exit(void)
{  

    iounmap(base_addr);  
   

    if (adc_clock)              
    {  
        clk_disable(adc_clock);  
        clk_put(adc_clock);  
        adc_clock = NULL;  
    }  
   

    misc_deregister(&adc_miscdev);  
}  
   
module_init(lradc0_init);  
module_exit(lradc0_exit);  
   
MODULE_AUTHOR("";  
MODULE_DESCRIPTION("IMX287 LRADC0 Misc Device Driver";  
MODULE_VERSION("IMX287 LRADC0 1.0";  
MODULE_LICENSE("GPL";


测试代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>


#define DEVICE_NAME "/dev/lradc0"

int main(void)  
{  
    int fd;  
    char buf[4];  
    int i,res,adc_data;  
  
    if ((fd = open(DEVICE_NAME, O_RDONLY)) < 0)
        {  
        printf("open adc_dev failed\n");  
        return -1;  
    }  
    printf("adc_test result:\n");

    if ((res =read(fd, buf, 4)) != 4)
        {  
        printf("read adc_dev failed \n");
        return -1;  
    }
        printf("adc value = %d", res);
    close(fd);  
  
    return 0;
}


现象如下:
root@freescale /$ insmod fs_lradc.ko
lradc0initialized!
root@freescale /$ ./lradc0_test
adc_test result:


之后系统就没有任何反应了,只能按复位键,请各位帮忙解答,谢谢

论坛徽章:
0
2 [报告]
发表于 2013-04-11 15:17 |只看该作者
在线等,着急

论坛徽章:
1
拜羊年徽章
日期:2015-03-03 16:15:43
3 [报告]
发表于 2013-08-03 10:02 |只看该作者
你的驱动现在工作了吗? 我也在写lradc驱动,希望有个参考程序,谢谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP