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
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
相关文章推荐
- Linux内核---55.动态创建设备结点
- Linux系统重启python程序
- Linux内核---54.一个非常简单的字符设备
- Linux内核---53.安装kernel API的man手册
- Linux内核---52.ioremap过程
- Linux内核---51.驱动程序的hello world
- Linux内核---50.各个平台下内核模块的编译
- Linux下mysql基本操作
- linux开发---2.汇编语言arm-linux下的打印
- Linux系统中查看日志的常用命令
- Redhat使用CentOS的yum
- Linux内核---49.i2s驱动分析1测试
- Linux内核---48.spi驱动修改
- Linux内核---47.关于clk_get与clk_enable
- Linux内核---46.关于mem_map
- Linux内核---45.关于initcall
- Linux内核---44.关于中断号与中断引脚
- Linux内核---43.文件系统的挂载
- Linux内核---42.arm 内存初始化2
- [CentOS7]安装mysql遇到的问题