Linux下的gpio调试方法

         最近在fsl平台上进行移植,需要将某些gpio配置成普通的gpio功能(fsl平台的gpio支持多个功能),便写了简单的杂项设备,来调试gpio口。

使用时,只需安装gpio驱动,可实现下列三项功能

设置拉高某gpio,echo "io:w:108:1" >/dev/gpio_debug

设置拉低某gpio,echo "io:w:108:0" >/dev/gpio_debug

读取某gpio电平,echo "io:r:108" >/dev/gpio_debug

将某个gpio设置成中断功能,并检测中断,echo "io:q:108"   >/dev/gpio_debug

#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <asm-generic/uaccess.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/ctype.h>


//echo "io:w:108:1" >/dev/gpio_debug
//echo "io:r:108"   >/dev/gpio_debug
//echo "io:q:108"   >/dev/gpio_debug

#define DEVICE_NAME  "gpio_debug"
#define GPIO_DBG     "[GPIO_DBG]"
#define GPIO_INF(format, args...)    pr_info(GPIO_DBG "%s,%d" format, __FUNCTION__,__LINE__, ##args)
int irq_state=0;
unsigned int irq;
struct mutex gpio_mutex;
char *buf[20];

int get_gpio_port(char *p)
{
    int gpio_num=-1;
    int ret=-1;
    gpio_num=simple_strtol(p,0,0);
    if((gpio_num<1))
    {
        return -EINVAL;
        GPIO_INF("unknown command\n");
    }
    ret=gpio_request(gpio_num,"debug_gpio");
    if(ret<0)
    {
        GPIO_INF("request gpio %d err!err code=%d\n",gpio_num,ret);
        gpio_free(gpio_num);
        ret=gpio_request(gpio_num,"debug_gpio");
        if(ret<0)
        {
            GPIO_INF("try request gpio %d egain err!\n",gpio_num);
            return -EAGAIN;
        }
        GPIO_INF("request gpio%d again ok!\n",gpio_num);
    }
    return gpio_num;
}

irqreturn_t irq_handler(int irq, void *dev_id)
{
    GPIO_INF("%s\n",__FUNCTION__);
    irq_state=1;
    return IRQ_HANDLED;
}

int analysis_cmd(char buffer[])
{
    int i=0;
    int ret;
    int gpio_num=-1;
    int gpio_value=-1;
    char *buf[10];
    while((buf[i++] = strsep(&buffer, ":")) != NULL);
    if(strncmp((buf[0]),"io",2)==0)
    {
        if(strncmp(buf[1],"r",1)==0)
        {
            gpio_num=get_gpio_port(buf[2]);
            gpio_direction_input(gpio_num);
            gpio_value=gpio_get_value(gpio_num);
            GPIO_INF("get gpio %d value %d.\n",gpio_num,gpio_value);
            gpio_free(gpio_num);
        }
        if(strncmp(buf[1],"w",1)==0)
        {
            gpio_num=get_gpio_port(buf[2]);
            gpio_value=simple_strtol(buf[3],0,0);
            gpio_direction_output(gpio_num,gpio_value);
            GPIO_INF("set gpio %d vlue %d.\n",gpio_num,gpio_value);
            gpio_free(gpio_num);
        }
        if(strncmp(buf[1],"q",1)==0)
        {
            if(irq_state==1)
            {
            free_irq(irq,NULL);
            irq_state=0;
            }
            gpio_num=get_gpio_port(buf[2]);
            irq=gpio_to_irq(gpio_num);
            if(irq<0)
            {
                GPIO_INF("gpio %d to request err!",gpio_num);
                return -1;
            }
            GPIO_INF("gpio to irq %d ok,irq num=%d ok!\n",gpio_num,irq);
            ret=request_irq(irq,irq_handler,IRQF_TRIGGER_RISING ,"irq_test",(void *)buf);
            if(ret<0)
            {
                GPIO_INF("request_irq %d err!err code is %d!\n",gpio_num,ret);
                return -1;
            }
            GPIO_INF("request irq %d ok!",gpio_num);
        }
    }
    return 0;
}

static int gpio_open(struct inode *inode, struct file *file)
{
    return 0;
}

static ssize_t gpio_write(struct file *file,const char __user *buffer, size_t size, loff_t *offet)
{
    int ret;
    char buf[100];
    mutex_lock(&gpio_mutex);
    if(copy_from_user(buf,buffer,size)<0)
    {
        mutex_unlock(&gpio_mutex);
        return -EFAULT;
    }
    ret=analysis_cmd(buf);
    mutex_unlock(&gpio_mutex);
    return size;
}

static struct file_operations gpio_dev_fops={
    .owner          = THIS_MODULE,
    .open           = gpio_open,
    .write          = gpio_write,
};

static struct miscdevice gpio_dev = {
    .minor          = MISC_DYNAMIC_MINOR,
    .name           = DEVICE_NAME,
    .fops           = &gpio_dev_fops,
};

static int __init debug_init(void)
{
    int ret;
    mutex_init(&gpio_mutex);
    ret = misc_register(&gpio_dev);
    if(ret<0)
        GPIO_INF("misc_register err!\n");
    else
        GPIO_INF("misc_register successful!\n");
        return ret;
}

static void __exit debug_exit(void)
{
    misc_deregister(&gpio_dev);
}

module_init(debug_init);
module_exit(debug_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("WWW");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值