天天看点

全志A33-gpio驱动程序

开发环境

Ubuntu:14.04

开发板:A33-Vstar

开发板系统:android 4.4 、linux-3.4.39

交叉编译器:arm-linux-gnueabi-gcc 4.7.3

-----------------------------------------------------

1. 驱动程序

1)采用Linux gpio api,具有很好的移植性

2)采用misc设备,自动创建设备节点 /dev/leds

3)驱动代码:A33-gpio.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <linux/gpio.h>
#include <linux/miscdevice.h>




static int led_gpios[] = {
	GPIOH(7),
};

#define LED_NUM		ARRAY_SIZE(led_gpios)


int leds_open(struct inode *inode,struct file *filp)
{
	printk("leds device opened success!\n");
	return nonseekable_open(inode,filp);	//通知内核你的设备不支持llseek
}

int leds_release(struct inode *inode,struct file *filp)
{
	printk("leds device closed success!\n");
	return 0;
}


long leds_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
	printk("debug: leds_ioctl cmd is %d\n" , cmd);

	switch(cmd)
	{
		case 0:	//不加break,执行case1
		case 1:
			if (arg > LED_NUM) {
				return -EINVAL;
			}
			gpio_set_value(led_gpios[arg], cmd);
			break;

		default:
			return -EINVAL;
	}

	return 0;
}

static struct file_operations leds_ops = {
	.owner 			= THIS_MODULE,
	.open 			= leds_open,
	.release		= leds_release,
	.unlocked_ioctl = leds_ioctl,
};

static struct miscdevice leds_dev = {
	.minor	= MISC_DYNAMIC_MINOR,
	.fops	= &leds_ops,
	.name	= "leds",	//此名称将显示在/dev目录下面
};


static int __init leds_init(void)
{
	int ret, i;
	char *banner = "leds Initialize\n";

	printk(banner);

	for(i=0; i<LED_NUM; i++)
	{
		//申请gpio,设置为输出,高电平
		ret = gpio_request_one(led_gpios[i], GPIOF_OUT_INIT_HIGH,"LED");
		if (ret) {
			printk("leds: request GPIO %d for LED failed, ret = %d\n", led_gpios[i], ret);
			return ret;
		}

	}

	ret = misc_register(&leds_dev);
	if(ret<0)
	{
		printk("leds: register device failed!\n");
		goto exit;
	}

	return 0;

exit:
	misc_deregister(&leds_dev);
	return ret;
}

static void __exit leds_exit(void)
{
	misc_deregister(&leds_dev);	

}

module_init(leds_init);
module_exit(leds_exit);

MODULE_LICENSE("Dual BSD/GPL");
           

2. Linux应用程序

gpio-test.c

//gpio控制,循环输出高低电平
//android compile: arm-linux-gnueabi-gcc -o gpio-test gpio-test.c -static
//linux compile: arm-linux-gnueabi-gcc -o gpio-test gpio-test.c

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



#define GPIO_HIGH 1
#define GPIO_LOW  0

#define GPIO_H7	  0	//led_gpios[0]=PH7


int main()
{
    int fd = 0;
    int cmd;
    int arg = GPIO_H7;
    
    
    /*打开设备文件*/
    fd = open("/dev/leds", O_RDWR);
    if (fd < 0)
    {
        printf("open Dev /dev/leds Error!\n");
        return -1;
    }
    

    printf("running\n");
	while(1){
		cmd = GPIO_HIGH;
		if (ioctl(fd, cmd, arg) < 0)
			{
				printf("ioctl fail\n");
				return -1;
		}
		printf("GPIO_H7 value is 1\n");
		sleep(2);
		
		cmd = GPIO_LOW;
		if (ioctl(fd, cmd, arg) < 0)
			{
				printf("ioctl fail\n");
				return -1;
		}
		printf("GPIO_H7 value is 0\n");
		sleep(2);
		 
	}
    
    
    close(fd);
    return 0;    
}
           

3. 验证

3.1 开发板运行Android

1)mount -o rw,remount / 重新挂载根文件系统,否者可能提示:Read-only file system

1)adb push gpio-test /

2)adb push A33-GPIO.ko /

3)insmod A33-GPIO.ko

4)chmod 777 gpio-test

5)./gpio-test

全志A33-gpio驱动程序

6)用万用表测量PH1脚变化。

3.2 开发板运行linux

1)Ubuntu执行:sudo minicom 连接开发板

2)按 ctrl+A,选择Z,再选S,发送A33-GPIO.ko和gpio-test到开发板

3)开发板执行: insmod A33-GPIO.ko

4)开发板执行:./gpio-test

5)用万用表测量PH7脚变化。

注:当开发板运行linux时,需将引脚PH1改为PH7,因为PH1在linux下被占用。

继续阅读