【Rayeager PX2】PX2上使用GPIO口的例程

之前楼主在论坛中已经分享了简单驱动的编写,现在楼主再来教刚接触板子的新手们如何引用调用GPIO,不过这里楼主并没有将GPIO口的函数封装成库,然后在eclipse上调用,楼主这边的例子,只是简单的用adb工具进入板中,然后用一个测试程序使用端口,有兴趣想要在安卓界面调用端口的,可以参考楼主之前写的那编jni调用的帖子。

首先我们依旧来简单地说下步骤,

1.在/kernel/drivers下建个文件夹,自己创建并添加Kconfig和makefile,内容如下,

2.在该目录下写个gpio驱动,内容在最后

3.返回drivers目录,在目录下修改Kconfig和makefile,修改内容如下

4.进入内核,打开已写好的驱动。

驱动内容如下,?

/***********************************************************************************

* driver for GPIO

*

**********************************************************************************/

#include <linux/miscdevice.h>

#include <linux/input.h>

#include <linux/clk.h>

#include <linux/delay.h>

#include <asm/io.h>

#include <asm/uaccess.h>

#include <linux/module.h>

#include <linux/init.h>

#include <mach/gpio.h>

#include <linux/gpio.h>

#define DEVICE_NAME "rkpx2_GPIO" //定义设备名

#define RKPX2_GPIO_MAJOR    101  //定义设备号

static struct class *dev_class//定义设备结构体

static int gpio_open(struct inode *inode, struct file *file)

{

int i

int err

i=0

err = gpio_request(RK30_PIN4_PD1, "GPIO4_D1")//申请端口gpio4_1,成功返回0,失败返回负的错误值

if(err)

{

printk(KERN_ERR "RK_PX2 failed to request GPIO4_D1 \n")

return err

}//若申请失败,则报错,然后推出,

err = gpio_request(RK30_PIN4_PD2, "GPIO4_D2")//申请端口gpio4_2,成功返回0,失败返回负的错误值

if(err)

{

printk(KERN_ERR "RK_PX2 failed to request GPIO4_D2 \n")

return err

}

err = gpio_request(RK30_PIN4_PD3, "GPIO4_D3")//申请端口gpio4_3,成功返回0,失败返回负的错误值

if(err)

{

printk(KERN_ERR "RK_PX2 failed to request GPIO4_D3 \n")

return err

}

err = gpio_request(RK30_PIN4_PD4, "GPIO4_D4")//申请端口gpio4_4,成功返回0,失败返回负的错误值

if(err)

{

printk(KERN_ERR "RK_PX2 failed to request GPIO4_D4 \n")

return err

}

printk(KERN_INFO "RK_PX2 GPIO opened 4 !\n")

gpio_direction_output(RK30_PIN4_PD1,1)//决定GPIO的方向,为输出

gpio_direction_output(RK30_PIN4_PD2,1)

gpio_direction_output(RK30_PIN4_PD3,1)

gpio_direction_output(RK30_PIN4_PD4,1)

return 0

}

static int gpio_close(struct inode *inode, struct file *file)

{

gpio_free(RK30_PIN4_PD1)

gpio_free(RK30_PIN4_PD2)

gpio_free(RK30_PIN4_PD3)

gpio_free(RK30_PIN4_PD4)    //释放端口,

printk(KERN_INFO "RK_PX2 GPIO driver successfully close\n")

return 0

}

static int gpio_read(struct file *file, char *buffer, size_t size, loff_t *pos) //从内核中读取GPIO引脚的值

{

int ret

char key_buf[4]

if (gpio_get_value(RK30_PIN4_PD1)==0){

key_buf[0]=0

}else{

key_buf[0]=1

}

if (gpio_get_value(RK30_PIN4_PD2)==0){

key_buf[1]=0

}else{

key_buf[1]=1

}

if (gpio_get_value(RK30_PIN4_PD3)==0){

key_buf[2]=0

}else{

key_buf[2]=1

}

if (gpio_get_value(RK30_PIN4_PD4)==0){

key_buf[3]=0

}else{

key_buf[3]=1

}

ret=copy_to_user(buffer,key_buf,4)//拷贝数据到用户区 ,成功为 0,失败为字节数

return ret

}

static long gpio_ioctl(struct file *file ,unsigned int cmd,unsigned long arg){

switch(cmd){//改变引脚的电平值

case 00: gpio_set_value(RK30_PIN4_PD1,0)

printk("GPIO_D1  is low!\n")

break

case 01: gpio_set_value(RK30_PIN4_PD1,1)

printk("GPIO_D1  is high!\n")

break

case 10: gpio_set_value(RK30_PIN4_PD2,0)

printk("GPIO_D2  is low!\n")

break

case 11: gpio_set_value(RK30_PIN4_PD2,1)

printk("GPIO_D2  is high!\n")

break

case 20: gpio_set_value(RK30_PIN4_PD3,0)

printk("GPIO_D3  is low!\n")

break

case 21: gpio_set_value(RK30_PIN4_PD3,1)

printk("GPIO_D3  is high!\n")

break

case 30: gpio_set_value(RK30_PIN4_PD4,0)

printk("GPIO_D4  is low!\n")

break

case 31: gpio_set_value(RK30_PIN4_PD4,1)

printk("GPIO_D4  is high!\n")

break

}

return 0

}

/*驱动接口设置*/

static struct file_operations dev_fops = {

.owner = THIS_MODULE,

//.unlocked_ioctl = tq210_gpio_ioctl,

.open = gpio_open,

.release = gpio_close,

.read = gpio_read,

.unlocked_ioctl = gpio_ioctl,

}

/*初始化设备,配置对应的IO,以及注册设备*/

static int __init dev_init(void)

{

int ret

ret=0

ret = register_chrdev(RKPX2_GPIO_MAJOR,"rkpx2_GPIO",&dev_fops)//注册

if (ret<0) {

printk("rkpx2 GPIO for test  unable to get major%d \n",ret)

return ret

}

dev_class = class_create(THIS_MODULE,"rkpx2_GPIO")//初始化

if (IS_ERR(dev_class)){

unregister_chrdev(RKPX2_GPIO_MAJOR,"rkpx2_GPIO")

return PTR_ERR(dev_class)

}

device_create(dev_class,NULL,MKDEV(RKPX2_GPIO_MAJOR,0),NULL,"rkpx2_GPIO")//创建设备

printk(KERN_INFO "RKPX2 GPIO driver successfully probed!\n")

return ret

}

/*注销设备*/

static void __exit dev_exit(void)

{

//misc_deregister(&dev_misc)

gpio_free(RK30_PIN4_PD1)

gpio_free(RK30_PIN4_PD2)

gpio_free(RK30_PIN4_PD3)

gpio_free(RK30_PIN4_PD4)

printk(KERN_INFO "RKPX2 gpio driver successfully exit\n")

}

module_init(dev_init)

module_exit(dev_exit)

MODULE_AUTHOR("Rayeager cyl")

MODULE_DESCRIPTION("rkpx2 gpio Driver")

MODULE_LICENSE("GPL")

然后测试程序内容如下:

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <string.h>

#define DEVICE_NAME     "/dev/rkpx2_GPIO"

#define LED_OFF    0

#define LED_ON    1

int main(int argc,char **argv){

int fd

int ret

int flag

int pin

int ch

printf("\n start test gpio_drivers\n")

if(strcmp(argv[1],"open")==0){

fd=open(DEVICE_NAME,O_RDWR)

if (fd==-1){

printf("open devices %s error\n",DEVICE_NAME)

}

printf("input the pin you want to operate")

scanf("%d",&pin)

printf("\n")

printf("it will be set ?(1=on or 0=off):")

scanf("%d",&ch)

switch(pin){

case 0: (ch==1?ioctl(fd,1):ioctl(fd,2))break

case 1: (ch==1?ioctl(fd,3):ioctl(fd,4))break

case 2: (ch==1?ioctl(fd,5):ioctl(fd,6))break

case 3: (ch==1?ioctl(fd,7):ioctl(fd,8))break

}

}

if(strcmp(argv[1],"close")==0){

fd=open(DEVICE_NAME,O_RDWR)

close(fd)

}

return 0

}

Android.mk的内容

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=\

test.c

LOCAL_MODULE:=gpioapp

include$(BUILD_EXECUTABLE)

编译测试程序的方法:在源码任意位置建个目录,把Android.mk和测试程序全扔进去,然后执行mm(现在根目录执行source  build/envsetup.sh)

实际操作,过程就不说了,亲测可行,正常操作的端口为GPIO4_1234

时间: 2024-10-15 04:23:35

【Rayeager PX2】PX2上使用GPIO口的例程的相关文章

RK3288开发板PopMetal上的GPIO驱动实例

楼主在这边给大家介绍下如何使用PopMetal的GPIO.先讲过程,再讲原理吧, 该驱动需要涉及到的知识点:1,DTS设备树的作用,2,platform虚拟总线驱动的编写. 第一步,添加DTS节点 在/kernel/arch/arm/boot/dts/rockchip.dts下添加如下内容. 下图rockchip-leds-gpio这部分的内容,修改保存, 第二步,在kernel/drivers下创建个LED文件夹,然后加入如下几个文件驱动文件leds.c,Makefile和Kconfig.如下

OpenWRT GPIO口控制 WLED

Linux系统下GPIO系统架构介绍 关于这个GPIO很久以前一直以为很简单,但是,当你需要给一个特定的系统,搞这些GPIO的时候,你会发现,事实并不是如此,比如,mt7620n. GPIO#72是控制WLED -> WLAN LED. GPIO#40~44是控制WAN, LANLED. GPIO#1是控制Reset 这些东西以为自己写一个GPIO driver就完成了,其实没有那么简单,光是这个小驱动你怎么编译都比较麻烦,所以还是乖乖的学习OpenWRT的系统架构吧. 这里要说道重点dts.这

树莓派上的GPIO字符驱动程序

前言 主要是在嵌入式Linux(树莓派)中如何使用已有的函数库编写应用程序操纵GPIO,如何编写字符设备驱动程序在内核程序中使用GPIO 硬件连接图 虚拟文件系统操作GPIO Linux可以通过访问sys/class/gpio下的一些文件,通过对这些文件的读写来实现对于GPIO的访问. 树莓派下面的可用的GPIO如下图所示,需要注意树莓派一代和二代的区别 首先用一个小灯来测试下操作.首先向export中写入18,表示启用18号gpio端口,执行之后,可以看到该目录下多出了一个gpio18的目录.

stm32寄存器版学习笔记01 GPIO口的配置(LED、按键)

STM32的I/O口可以由软件配置成如下8种模式:输入浮空.输入上拉.输入下拉.模拟输入.开漏输出.推挽输出.推挽式复用功能及开漏复用功能.每个I/O口由7个寄存器来控制:配置模式的端口配置寄存器CRL和CRH(模式.速度):数据寄存器IDR和ODR:置位/复位寄存器BSRR:复位寄存器BRR:锁存寄存器LCKR. I/O口模式: GPIO的8种模式 通用输出 推挽输出(Puch-Pull) 可以输出高.低电平,连接数字器件   开漏输出(Open-Drain) 开漏引脚不连接外部的上拉电阻时,

使用linux内核hrtimer高精度定时器实现GPIO口模拟PWM,【原创】

关键词:Android  linux hrtimer 蜂鸣器  等待队列 信号量 字符设备 平台信息:内核:linux3.4.39 系统:android/android5.1平台:S5P4418  作者:庄泽彬(欢迎转载,请注明作者) 邮箱:[email protected] 程序描述:本文控制的设备是无源蜂鸣器,由于无源蜂鸣器是需要产生一定的频率的PWM才能够控制蜂鸣器,不像有源蜂鸣器,只需要提供高低电平就可以控制蜂鸣器.linux内核普通的定时器,由于具有一定的局限性,不能达到纳秒级别的定时

STM32单片机GPIO口配置问题

在学习STM32F单片机时,我们常常困惑什么时候才能叫入门,采用什么样的教材入门,或者采用什么的编程软件.在学习类的教材中,以神州,原点教材布局很多,但是相信很多人看到这类教材也是一头雾水,需要你花费巨大的精力从寄存器的最底层去学习和了解,学习时间还是相对漫长.在采用的编程软件中,KEIL和IAR各有优势吧,在这里我选用的是KEIL. 在开始学习编程时,我采用的是库函数开发指南.在安装完成KEIL软件和添加项目工程时,就开始学习库函数编程. 在编写一个GPIO口控制时,首先我们要知道我们要实现的

Linux中的gpio口使用方法

Linux中的IO使用方法 应该是新版本内核才有的方法.请参考:./Documentation/gpio.txt文件 提供的API:驱动需要包含 #include <linux/gpio.h> 判断一个IO是否合法:int gpio_is_valid(int number); 设置GPIO的方向,如果是输出同时设置电平:/* set as input or output, returning 0 or negative errno */int gpio_direction_input(unsi

51单片机GPIO口模拟串口通信

51单片机GPIO口模拟串口通信 标签: bytetimer终端存储 2011-08-03 11:06 6387人阅读 评论(2) 收藏 举报 本文章已收录于: 分类: 深入C语言(20) 作者同类文章X 1 #include "reg52.h" 2 #include "intrins.h" 3 #include "math.h" 4 #include "stdio.h" 5 sbit BT_SND =P1^5; 6 sbit

树莓派GPIO口驱动编写

一.wiringpi写法 #include <wiringPi.h> #include <stdlib.h> int main(int argc,char *argv[]) { if(argc<2) return -1; if(argc==2) { wiringPiSetup(); pinMode(0, OUTPUT); if(atoi(argv[1]) == 1) digitalWrite(0, HIGH); else if(atoi(argv[1]) == 0) digi