您的位置:首页 > 运维架构 > Linux

Linux内核---56.gpio控制

2016-07-09 10:42 465 查看
一.mtk平台的gpio控制
1.1 内核中的gpio配置
//设置gpio18为GPIO模式
mt_set_gpio_mode(GPIO18, GPIO_MODE_GPIO);  
//设置gpio18方向为out
mt_set_gpio_dir(GPIO18, GPIO_DIR_OUT);
//设置gpio18高
mt_set_gpio_out(GPIO18, GPIO_OUT_ONE);  //低是ZERO
1.2 上层应用控制gpio的高低

cong@msi:/work/mtk/temp/gpiotest$
cat gpiotest.c 

#include <stdio.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/time.h>

#include <dirent.h>

#include <unistd.h>

#include <string.h>

#include <sys/ioctl.h>

#include <linux/ioctl.h>

#define dbmsg(fmt, args ...) printf("%s:%s[%d]:
"fmt"\n", __FILE__,__FUNCTION__, __LINE__,##args)

#define GPIO_IOC_MAGIC 0x90

#define GPIO_IOCQMODE _IOR(GPIO_IOC_MAGIC, 0x01, uint32_t)

#define GPIO_IOCTMODE0 _IOW(GPIO_IOC_MAGIC, 0x02, uint32_t)

#define GPIO_IOCTMODE1 _IOW(GPIO_IOC_MAGIC, 0x03, uint32_t)

#define GPIO_IOCTMODE2 _IOW(GPIO_IOC_MAGIC, 0x04, uint32_t)

#define GPIO_IOCTMODE3 _IOW(GPIO_IOC_MAGIC, 0x05, uint32_t)

#define GPIO_IOCQDIR _IOR(GPIO_IOC_MAGIC, 0x06, uint32_t)

#define GPIO_IOCSDIRIN _IOW(GPIO_IOC_MAGIC, 0x07, uint32_t)

#define GPIO_IOCSDIROUT _IOW(GPIO_IOC_MAGIC, 0x08, uint32_t)

#define GPIO_IOCQPULLEN _IOR(GPIO_IOC_MAGIC, 0x09, uint32_t)

#define GPIO_IOCSPULLENABLE _IOW(GPIO_IOC_MAGIC, 0x0A, uint32_t)

#define GPIO_IOCSPULLDISABLE _IOW(GPIO_IOC_MAGIC, 0x0B, uint32_t)

#define GPIO_IOCQPULL _IOR(GPIO_IOC_MAGIC, 0x0C, uint32_t)

#define GPIO_IOCSPULLDOWN _IOW(GPIO_IOC_MAGIC, 0x0D, uint32_t)

#define GPIO_IOCSPULLUP _IOW(GPIO_IOC_MAGIC, 0x0E, uint32_t)

#define GPIO_IOCQINV _IOR(GPIO_IOC_MAGIC, 0x0F, uint32_t)

#define GPIO_IOCSINVENABLE _IOW(GPIO_IOC_MAGIC, 0x10, uint32_t)

#define GPIO_IOCSINVDISABLE _IOW(GPIO_IOC_MAGIC, 0x11, uint32_t)

#define GPIO_IOCQDATAIN _IOR(GPIO_IOC_MAGIC, 0x12, uint32_t)

#define GPIO_IOCQDATAOUT _IOR(GPIO_IOC_MAGIC, 0x13, uint32_t)

#define GPIO_IOCSDATALOW _IOW(GPIO_IOC_MAGIC, 0x14, uint32_t)

#define GPIO_IOCSDATAHIGH _IOW(GPIO_IOC_MAGIC, 0x15, uint32_t)

    

int main ( int argc, char *argv[] )

{

    int fd_gpio;

    int ret;

    

    fd_gpio = open("/dev/mtgpio",O_RDWR);

    if(fd_gpio < 0)

    {

     printf("fd_gpio open error\n");

        return -1;

    }

    while(1)

    {

        ret = ioctl(fd_gpio, GPIO_IOCSDATAHIGH, 18);

        sleep(1);

        ret = ioctl(fd_gpio, GPIO_IOCSDATAHIGH, 18);

        sleep(1);

    }

    close(fd_gpio);

    return 0;

}

1.3 应用代码
 

gpiotest.rar
 (下载后改名为gpiotest.tar.gz)
1.4 查看gpio状态

/sys/class/misc/mtgpio/pin

130|root@78P01:/ #
cat /sys/class/misc/mtgpio/pin 

PIN: [MODE] [PULL_SEL] [DIN] [DOUT] [PULL
EN] [DIR] [IES]

3: 3 0 0 0 0 0 1 MI                  -->MODE这一项就是在code.dws中配的MODE

4: 3 0 0 0 0 1 1 MO

5: 3 0 1 0 0 1 1 CS

6: 3 0 0 0 0 1 1 CLK

二.利用sys控制gpio口
2.1 代码如下

#include <linux/init.h>

#include <linux/module.h>

#include <linux/device.h>

#include <linux/ioport.h>

#include <linux/errno.h>

#include <linux/workqueue.h>

#include <linux/platform_device.h>

#include <linux/types.h>

#include <linux/io.h>

#include <mach/mt_gpio.h>

#define GPIO_POWER_EN GPIO123 //

typedef struct {

    int gpio_power;

}hello_priv;

static ssize_t hello_set_power(struct device *dev,struct device_attribute *attr,const char *buf, size_t
count)

{

    hello_priv* prv = dev_get_drvdata(dev);

    if ('0' == buf[0]) //shutdown

    { //process: pin
low-->high

     mt_set_gpio_out(prv->gpio_power, GPIO_OUT_ZERO);

      msleep(1500);

      mt_set_gpio_out(prv->gpio_power, GPIO_OUT_ONE);

      printk(KERN_NOTICE "cong: %s:%s[%d]: buf=%s", __FILE__,__FUNCTION__, __LINE__,buf); 

    }else if ('1' == buf[0]) //poweron

    { //process: power
pin high --> low

     mt_set_gpio_out(prv->gpio_power, GPIO_OUT_ONE);

      msleep(1500);

      mt_set_gpio_out(prv->gpio_power, GPIO_OUT_ZERO);

      printk(KERN_NOTICE "cong: %s:%s[%d]: buf=%s", __FILE__,__FUNCTION__, __LINE__,buf); 

    }

    return count;

}

static DEVICE_ATTR(power_on, S_IRUGO | S_IWUSR,NULL, hello_set_power);

static struct attribute *hello_attributes[] = {

    &dev_attr_power_on.attr,

    NULL

};

static const struct attribute_group hello_attr_group = {

    .attrs = hello_attributes,

};

static int __init hello_probe(struct platform_device *pdev)

{

    int rc;

    hello_priv* prv;

    prv = devm_kzalloc(&pdev->dev, sizeof(hello_priv), GFP_KERNEL);

    if (!prv) {

        dev_err(&pdev->dev, "failed
to allocate hello\n");

        return -ENOMEM;

    }

    prv->gpio_power = GPIO_POWER_EN ;

    mt_set_gpio_mode(prv->gpio_power, GPIO_MODE_GPIO);

    mt_set_gpio_dir(prv->gpio_power, GPIO_DIR_OUT);

    platform_set_drvdata(pdev,prv);

    rc = sysfs_create_group(&pdev->dev.kobj, &hello_attr_group);

    if (rc) {

        dev_err(&pdev->dev,"failed
to create hello sysfs group\n");

        goto fail;

    }

    return 0;

fail:

    return rc;

}

struct platform_driver hello_driver = {

    .driver = {

        .name = "hello",

        .owner = THIS_MODULE,

    },

    .probe = hello_probe,

};

static struct platform_device hello_device =

{

    .name = "hello",

    .id = -1,

};

static int __init hello_init(void)

{

    int ret;

    ret = platform_device_register(&hello_device);

    if (ret != 0)

      printk(KERN_NOTICE "cong: %s:%s[%d]: error", __FILE__,__FUNCTION__, __LINE__); 

    ret = platform_driver_register(&hello_driver);

    return ret;

}

static void __init hello_exit(void)

{

    platform_driver_unregister(&hello_driver);

}

module_init(hello_init);

module_exit(hello_exit);

MODULE_DESCRIPTION("GPIO Controller Driver");

MODULE_AUTHOR("cong");

MODULE_LICENSE("GPL");

2.2 则可以在
echo 1 > /sys/devices/platform/hello/power_on
2.3 测试的应用程序如下:

#include <stdio.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/time.h>

#include <unistd.h>

#include <string.h>

#include <sys/ioctl.h>

#include <linux/ioctl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#define dbmsg(fmt, args ...) printf("%s:%s[%d]:
"fmt"\n", __FILE__,__FUNCTION__, __LINE__,##args)    

#define POWER_ON "power_on"

int usage()

{

    printf("usage:\n");

    printf("./test power_on <0/1> : 0-->poweron; 1-->poweroff \n"); 

    return 0;

}

int power_on(char* arg)

{

    int fd;

    if( ('0'!=arg[0]) && ('1'!=arg[0]))

    {

        dbmsg("bad args");

        return -1;

    }

    fd = open("/sys/devices/platform/hello/power_on", O_RDWR);

    if(fd < 0)

    {

        dbmsg("open error");

        return -1;

    }

    dbmsg("arg=%s", arg);

    write(fd, arg, 1);

    return 0;

}

int main ( int argc, char *argv[] )

{

    int ret;

    int num;

    int fd_gpio;

    if(argc < 2)

    {

        usage();

        return -1;

    }

    if(strncmp(argv[1],POWER_ON, sizeof(POWER_ON)) == 0)

    {

        dbmsg("%s", POWER_ON);

        if(argc != 3)

        {

            usage();

            return -1;

        }

        power_on(argv[2]); 

    }

    return 0;

}

2.4 测试过程

root@cong:/home/cong/driver/app# ./test
power_on 0

test.c:main[57]: power_on

test.c:power_on[39]: arg=0

root@cong:/home/cong/driver/app# ./test
power_on 1

test.c:main[57]: power_on

test.c:power_on[39]: arg=1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: