以前樓主在論壇中已經分享了簡單驅動的編寫,如今樓主再來教剛接觸板子的新手們如何引用調用GPIO,不過這裏樓主並無將GPIO口的函數封裝成庫,而後在eclipse上調用,樓主這邊的例子,只是簡單的用adb工具進入板中,而後用一個測試程序使用端口,有興趣想要在安卓界面調用端口的,能夠參考樓主以前寫的那編jni調用的帖子。node
首先咱們依舊來簡單地說下步驟,linux
1.在/kernel/drivers下建個文件夾,本身建立並添加Kconfig和makefile,內容以下,app
2.在該目錄下寫個gpio驅動,內容在最後eclipse
3.返回drivers目錄,在目錄下修改Kconfig和makefile,修改內容以下函數
4.進入內核,打開已寫好的驅動。工具
驅動內容以下,測試
/***********************************************************************************ui
* driver for GPIO接口
* ip
**********************************************************************************/
#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