android下調試3G之gpio控制3G上電

如果是自己開發的板子,需要用GPIO引腳控制3G模塊開機/關機時,下面的文章會對你有所幫助,是以處理器IMX6和中興MG3732模塊為例介紹。

一、引腳連接

處理器的gpio3_GPIO[9]連接3G模塊的ON/OFF(29)引腳來控制3G的開機/關機。

二、開關機條件

給ON/OFF引腳連續2500~3500毫秒低電平則開機,給再ON/OFF引腳連續2500~3500毫秒低電平則關機。

三、gpio驅動程序

gpio_3g.c

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define GPIO_IOF_MAGIC 0xd0
#define 3G_INPUT	    _IO(GPIO_IOF_MAGIC,8)
#define 3G_OUTPUT   	_IO(GPIO_IOF_MAGIC,9)
#define 3G_ON_OFF		IMX_GPIO_NR(3,9)    //控制引腳為:gpio3[9]

MODULE_LICENSE ("GPL");
int gpio_major=2555;
int gpio_minor=0;
int number_devices=1;
struct cdev gpiocdev;
struct class *my_class;

static int gpio_open(struct inode *inode,struct file *file)
{
	printk (KERN_INFO "GPIO device opened\n");
	
	if(gpio_direction_output(3G_ON_OFF,0x00)<0){
		printk("3G_ON_OFF set direction failed\n");
	}  
	return 0;
}

static long gpio_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
	int val;
	printk("GPIO:ioctl running....\n");
	
	switch(cmd){
		case 3G_INPUT:
			if(gpio_direction_input(3G_ON_OFF)0){
				gpio_set_value(3G_ON_OFF,0x01);
			}else{
				gpio_set_value(3G_ON_OFF,0x00);
			}
			val=gpio_get_value(3G_ON_OFF);
			printk("3G_ON_OFF ioctl val=%d\n",val);
		break;
		case 3G_OUTPUT:
			if(gpio_direction_output(3G_ON_OFF,0x00)0){
				gpio_set_value(3G_ON_OFF,0x01);
			}else{
				gpio_set_value(3G_ON_OFF,0x00);
			}
			val=gpio_get_value(3G_ON_OFF);
			printk("3G_ON_OFF ioctl val=%d\n",val);
		break;		
		default:
			printk("cmd is not exist\n");
			return -1;
	}
	return val;
}


static int gpio_release (struct inode *inode, struct file *file)
{
	printk (KERN_INFO "GPIO device closed\n");  
	return 0;
}

struct file_operations gpio_fops = {
	.owner=THIS_MODULE,
	.open=gpio_open,
	.release=gpio_release,
	.unlocked_ioctl=gpio_ioctl,
};

static void char_reg_setup_cdev (void)
{
	int error;
	dev_t devno;
	devno=MKDEV(gpio_major,gpio_minor);
	cdev_init(&gpiocdev,&gpio_fops);
	gpiocdev.owner=THIS_MODULE;
	error=cdev_add(&gpiocdev,devno,1);
	if (error)
		printk(KERN_NOTICE "Error %d adding char device GPIO",error);
}

static int __init gpio_init (void)
{
	int result;
	dev_t devno;

	devno=MKDEV(gpio_major,gpio_minor);

	if(gpio_major){
		result=register_chrdev_region(devno,number_devices,"gpio_3g");
	}else{
		result=alloc_chrdev_region(&devno,0,number_devices,"gpio_3g");
		gpio_major=MAJOR(devno);
	}
	if (result<0){
		printk(KERN_WARNING "GPIO:can't get major number %d\n", gpio_major);
		return result;
	}
	char_reg_setup_cdev ();	
	my_class=class_create(THIS_MODULE,"GPIOCLASS");
	device_create(my_class,NULL,MKDEV(gpio_major,gpio_minor),NULL,"gpio_3g");

	if(gpio_request(3G_ON_OFF,"UnKnow")<0){
		printk("3G_ON_OFF request failed\n");
	}
	printk (KERN_INFO "char device GPIO registered\n");

	return 0;
}

static void __exit gpio_exit(void)
{
	dev_t devno=MKDEV(gpio_major,gpio_minor);
	gpio_free(3G_ON_OFF);

	cdev_del(&gpiocdev);
	unregister_chrdev_region(devno,number_devices);
	device_destroy(my_class,devno);
	class_destroy(my_class);
	printk(KERN_INFO"char device GPIO  unregister\n");
}

module_init (gpio_init);
module_exit (gpio_exit);

四、內核添加gpio驅動步驟(android4.3源碼)

1、把gpio_3g.c放到~/myandroid/kernel_imx/drivers/char目錄下(假設源碼在~/myandroid下)。

2、~/myandroid/kernel_imx/drivers/char/Konfig中最後添加紅色框部分語句。

3、在~/myandroid/kernel_imx/drivers/char/Makefile中添加紅色框部分語句。vcD4KPHA+ICAgICAgICAgICA8aW1nIHNyYz0=”/uploadfile/Collfiles/20141101/2014110108420589.png” width=”615″ height=”125″ alt=”\”>

4、在~/myandroid/kernel_imx下 make menuconfig 來配置內核,配置完成後退出並保存。如下圖:

5、在進入~/myandroid/kernel_imx目錄執行:

cp .config arch/arm/configs/imx6_android_defconfig

到此後,行以下命令編譯:

source build/enevsetup.sh

lunch sabresb_6dq-user

make

五、編譯3G模塊開關機程序

1、程序代碼

3g_on_off.c

#include
#include
#include
#include
#include
#include

#define 3G_INPUT     _IO(GPIO_IOF_MAGIC,8)
#define 3G_OUTPUT    _IO(GPIO_IOF_MAGIC,9)

#define SET_ON           0x01
#define SET_OFF          0x00

int main(int argc, char *argv[])
{
	int fd;
	fd=open("/dev/gpio_3g",O_RDWR); //打開gpio_3g設備文件
	if(fd<0){
		perror("open:");
	}
	if(ioctl(fd,3G_OUTPUT,SET_ON)<0){ //設置該引腳為輸出高
		perror("3G_OUTPUT ioctl:");
	}
	sleep(3);
	if(ioctl(fd,3G_OUTPUT,SET_OFF)<0){ //設置該引腳為輸出低
		perror("3G_OUTPUT ioctl:");
	}
	
	if(ioctl(fd,3G_INPUT,SET_OFF)<0){ //設置該引腳為輸入,防止被意外篡改
		perror("3G_INPUT ioctl:");
	}
	close(fd);
	return 0;
}

Android.mk

LOCAL_PATH	:=$(call my-dir)
include	$(CLEAR_VARS)
LOCAL_MODULE_TAGES	:=optional
LOCAL_MODULE	:=3g_on_off
LOCAL_SRC_FILES	:=3g_on_off.c
include	$(BUILD_EXECUTABLE)

2、在~/myandroid/external下創建 3g_on_off文件夾

3、把 3g_on_off.c 和 Android.mk 文件放到新建文件夾下。

4、執行以下命令編譯:

source build/enevsetup.sh

lunch sabresb_6dq-user

mmm external/3g_on_off

5、把生成的可執行程序:

~/myandroid/out/target/product/sabresd_6dq/obj/EXECUTABLES/3g_on_off_intermediates/3g_on_off放到

~/myandroid/out/target/product/sabresd_6dq/system裡面

執行:make snod 打包

六、燒寫鏡像到開發板,執行3g_on_off程序對3G模塊進行開關機操作。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *