6410上的GPIO驱动及用户测试程序

最近在玩友善之臂Tiny6410开发板,但是源码中没有用户层操作GPIO的GPIO驱动,且之前的工作一直都是看和改,难免手生,故写此GPIO驱动,以作练习之用。

1. 驱动层gpio.c

编译:将此gpio.c放在driver/gpio目录下,并修改下面的Makefile文件,添加 obj-y += gpio.o

使用此驱动在命令行下操作GPIO:

cd /sys/class/s3c-gpio

echo GPK 4 0 > write   // 设置GPK4输出0

echo GPN 0 > read    //读取GPN0的状态

关闭/打开 GPIO驱动调试信息:

cd /sys/module/gpio/parameters

echo 0 > gpio_dbg    //关闭GPIO驱动调试信息

echo 1 > gpio+dbg    //打开GPIO驱动调试信息


#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>

static int gpio_dbg = 1;
module_param(gpio_dbg, int, S_IRUGO | S_IWUSR);

#define gpio_dbg(format, args...) \
 do { \
  if(gpio_dbg) \
   printk(format, ##args); \
 } while (0)


#define CLASS_NAME "s3c-gpio"

static struct class *gpio_class;

static int s3c64xx_gpio_sections[] = {
 S3C64XX_GPA(0), S3C64XX_GPB(0), S3C64XX_GPC(0), S3C64XX_GPD(0), 
 S3C64XX_GPE(0), S3C64XX_GPF(0), S3C64XX_GPG(0), S3C64XX_GPH(0),
 S3C64XX_GPI(0), S3C64XX_GPJ(0), S3C64XX_GPK(0), S3C64XX_GPL(0),
 S3C64XX_GPM(0), S3C64XX_GPN(0), S3C64XX_GPO(0), S3C64XX_GPP(0),
 S3C64XX_GPQ(0),
};

static int s3c_gpio_get_pin_nr(char* label, int nr)
{
 struct s3c_gpio_chip *chip;
 int pin;
 int ret = -EINVAL;
 int i;

 for(i=0; i<ARRAY_SIZE(s3c64xx_gpio_sections); i++)
 {
  pin = s3c64xx_gpio_sections[i];
  chip = s3c_gpiolib_getchip(pin);
  if (!chip)
   continue;
  if(strcmp(chip->chip.label, label)==0)
  {
   if(nr<(chip->chip.ngpio))
   {
    pin = pin + nr;
    ret = pin;
   }
   break;
  }
 }
 if(ret<0)
  printk("Can't find gpio: [%s%d] !\n", label, nr);
 else
  gpio_dbg("Find gpio: [%s%d], nr = %d\n", label, nr, ret);
 return ret;
}

static ssize_t gpio_read_show(struct class *dev, struct class_attribute *attr, char *buf)
{
 return sprintf(buf, "%s\n", "Usage: echo GPX nr > read");
}

static ssize_t gpio_read_store(struct class *dev, struct class_attribute *attr, const char *buf, size_t size)
{
 char label[16];
 int nr;
 int pin;
 int val;
 
 sscanf(buf, "%s %d", label, &nr);
 pin = s3c_gpio_get_pin_nr(label, nr);
 if(pin<0)
  return pin;
 gpio_request(pin, label);
 gpio_direction_input(pin);
 val = gpio_get_value(pin);
 gpio_free(pin);
 gpio_dbg("[%s%d] = %d\n", label, nr, val);

 return (val&0x1)|0x10;
}

static ssize_t gpio_write_show(struct class *dev, struct class_attribute *attr, char *buf)
{
 return sprintf(buf, "%s\n", "Usage: echo GPX nr val > write");
}

static ssize_t gpio_write_store(struct class *dev, struct class_attribute *attr, const char *buf, size_t size)
{
 char label[16];
 int nr;
 int pin;
 int val;
 
 sscanf(buf, "%s %d %d", label, &nr, &val);
 val = val ? 1 : 0;
 pin = s3c_gpio_get_pin_nr(label, nr);
 if(pin<0)
  return pin;
 gpio_request(pin, label);
 gpio_direction_output(pin, val);
 gpio_free(pin);
 gpio_dbg("Set [%s%d] = %d\n", label, nr, val);

 return pin;
}

static CLASS_ATTR(read, 0644, gpio_read_show, gpio_read_store);
static CLASS_ATTR(write, 0644, gpio_write_show, gpio_write_store);

static int gpio_init(void)
{
 int err;

 gpio_class = class_create(THIS_MODULE, CLASS_NAME);
 err = class_create_file(gpio_class, &class_attr_read);
 err = class_create_file(gpio_class, &class_attr_write);
 return 0;
}

void gpio_exit(void)
{
 class_remove_file(gpio_class, &class_attr_write);
 class_remove_file(gpio_class, &class_attr_read);
 class_destroy(gpio_class);
}

module_init(gpio_init);
module_exit(gpio_exit);

MODULE_AUTHOR("Jimmy.Jin <>");
MODULE_LICENSE("GPL");

 

2. 用户层测试程序test_gpio.c

测试程序的编译:arm-linux-gcc –static test_gpio.c –o test_gpio

将编译后的程序test_gpio拷贝到目标板上运行测试,此程序实现按下板上K1-K4对应LED1-LED4点亮,按下K8退出程序。

 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

#define RD_FILE "/sys/class/s3c-gpio/read"
#define WR_FILE "/sys/class/s3c-gpio/write"
#define DBG_SET_FILE "/sys/module/gpio/parameters/gpio_dbg"

int main(int argc,char *argv[])
{
 int fd_rd, fd_wr, fd_dbg;
 int i;
 int val;
 char cmd_buf[10];

 printf("Test gpio begin!\n");

 fd_rd = open(RD_FILE, O_RDWR, S_IRUSR | S_IWUSR);
 fd_wr = open(WR_FILE, O_RDWR, S_IRUSR | S_IWUSR);
 fd_dbg = open(DBG_SET_FILE, O_RDWR, S_IRUSR | S_IWUSR);
 write(fd_dbg, "0", 2);  // Disable gpio driver debug info

 while(1)
 {
  for(i=0; i<4; i++)
  {
   sprintf(cmd_buf, "GPN %d", i);
   val = write(fd_rd, cmd_buf, strlen(cmd_buf)); // Read K1-K4 status, val&0x1 is the gpio value
   sprintf(cmd_buf, "GPK %d %d", i+4, val&0x1);
   write(fd_wr, cmd_buf, strlen(cmd_buf));   // Set LED1-LED4 depending on K1-K4 status
  }
  usleep(10000);

  sprintf(cmd_buf, "GPL 12");
  val = 0x1 & (write(fd_rd, cmd_buf, strlen(cmd_buf))); // Detect K8 status
  if(val==0)  // If K8 pressed, exit test
  {
   write(fd_dbg, "1", 2);  // Enable gpio driver debug info
   printf("Test gpio finished successfully!\n");
   close(fd_rd);
   close(fd_wr);
   close(fd_dbg);
   return 0;
  }
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值