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

【龙印】龙芯1c的gpio输出高低电平的linux驱动

2016-08-31 17:14 507 查看
本文为在用龙芯1c做3D打印机过程中的笔记。龙芯1c做的3d打印机简称“龙印”
控制GPIO输出高低电平是很简单,也经常用到。比如控制led,通过光耦或者功率三极管控制3d打印机的风扇和加热装置,还能控制3d打印机的步进电机。
以步进电机驱动模块A4988为例,A4988的使能,方向,步进这三个脚都是用GPIO控制的。
据此,还是决定写个简单的gpio作为输出的驱动和测试程序。
这里选gpio50,这个io口在智龙v2.0上已经接有一个led,点亮后是绿色的,如下



再看看原理图



gpio50就是CAMDATA0,有图可知,在gpio50输出低电平,led就会亮,输出高电平,就灭。
不多说了,上源码
驱动“ls1c_test_gpio_output.c”

/*
* drivers\misc\ls1c_test_gpio_output.c
* 把龙芯1c上的一个IO口设为输出,并输出高低电平
* 如果IO口上接有led,则led会亮灭,也可以用万用表测试io口的电压
*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <linux/ls1c_3dprinter_motor.h>
#include <linux/delay.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/kfifo.h>

//智龙v2.0上gpio50接有一个led
#define TEST_GPIO (50) // CAMDATA0/GPIO50
#define GPIO_VALUE_HIGH (1) // gpio输出高电平
#define GPIO_VALUE_LOW (0) // gpio输出低电平

static DEFINE_MUTEX(gpio_output_lock);

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

static int gpio_output_close(struct inode *inode, struct file *filp)
{
// 如果gpio接有led,那么在文件关闭的时候把led也灭掉
gpio_set_value(TEST_GPIO, GPIO_VALUE_HIGH);

return 0;
}

static ssize_t gpio_output_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
{
int ret = 0;
int gpio_value = 0;

if (mutex_lock_interruptible(&gpio_output_lock))
{
return -ERESTARTSYS;
}

ret = copy_from_user(&gpio_value, buf, sizeof(gpio_value));

mutex_unlock(&gpio_output_lock);

if (ret)
{
printk(KERN_ERR "[%s] write gpio_value fail.\n", __FUNCTION__);
return -1;
}
printk(KERN_DEBUG "[%s] gpio_value=%d\n", __FUNCTION__, gpio_value);

gpio_set_value(TEST_GPIO, gpio_value);

return sizeof(gpio_value);
}

static struct file_operations ls1c_gpio_output_ops = {
.owner = THIS_MODULE,
.open = gpio_output_open,
.release = gpio_output_close,
.write = gpio_output_write,
};

static struct miscdevice ls1c_gpio_output_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "ls1c_test_gpio_output",
.fops = &ls1c_gpio_output_ops,
};

static int __init gpio_output_init(void)
{
int ret = 0;

// 申请gpio资源
ret = gpio_request(TEST_GPIO, "ls1c_test_gpio_output");
if (0 > ret)
{
printk(KERN_ERR "[%s] request gpio %d fail\n", __FUNCTION__, TEST_GPIO);
return ret;
}

// 把gpio设为输出模式,并输出高电平
gpio_direction_output(TEST_GPIO, GPIO_VALUE_HIGH);

// 注册设备
ret=misc_register(&ls1c_gpio_output_miscdev);
if (ret)
{
printk(KERN_ERR "[%s] could not register miscdev\n", __FUNCTION__);
goto fail_free_gpio;
}

return 0;

fail_free_gpio:
gpio_free(TEST_GPIO);

return ret;
}

static void __exit gpio_output_exit(void)
{
misc_deregister(&ls1c_gpio_output_miscdev);
gpio_free(TEST_GPIO);
}

module_init(gpio_output_init);
module_exit(gpio_output_exit);

MODULE_AUTHOR("简单平安");
MODULE_DESCRIPTION("ls1c gpio output test");
MODULE_LICENSE("GPL");



在“drivers\misc\Kconfig”中增加

config LS1C_TEST_GPIO_OUTPUT
    tristate "ls1c test gpio output"
    depends on LS1C_MACH
    help
     Say Y here if you want to build a test gpio output driver for ls1c
    

在“drivers\misc\Makefile”中增加
obj-$(CONFIG_LS1C_TEST_GPIO_OUTPUT)     += ls1c_test_gpio_output.o

配置
make menuconfig
Device Drivers  --->
  [*] Misc devices  --->
    <*>   ls1c test gpio output

测试用的应用程序“main.c”
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
int fd = 0;
int ret = 0;
int gpio_value = 0;

fd = open("/dev/ls1c_test_gpio_output", O_RDWR);
if (-1 == fd)
{
printf("[%s] open device file.\n", __FUNCTION__);
return -1;
}

while (1)
{
gpio_value = 0;
ret = write(fd, &gpio_value, sizeof(gpio_value));
if (sizeof(gpio_value) != ret)
{
close(fd);
printf("[%s] write fail. ret=%d\n", __FUNCTION__, ret);
return -1;
}

sleep(3);

gpio_value = 1;
ret = write(fd, &gpio_value, sizeof(gpio_value));
if (sizeof(gpio_value) != ret)
{
close(fd);
printf("[%s] write fail. ret=%d\n", __FUNCTION__, ret);
return -1;
}

sleep(3);
}
}


运行的串口打印如下



linux源码中已经封装了gpio的接口,驱动中只需调用就行。当然也可以根据1c的芯片手册自己封装或者重新实现。感兴趣的可以看看“arch\mips\loongson\ls1x\gpio.c”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  龙芯1c 3d打印机