来自:http://blog.csdn.net/hanbo622/article/details/40656011
如果是自己开发的板子,需要用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<linux/module.h>
- #include<linux/kernel.h>
- #include<linux/init.h>
- #include<linux/fs.h>
- #include<linux/cdev.h>
- #include<linux/device.h>
- #include<asm/io.h>
- #include<linux/mm.h>
- #include<asm/uaccess.h>
- #include<linux/gpio.h>
-
- #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){
- printk("3G_ON_OFF set input failed\n");
- }
- if(arg>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){
- printk("3G_ON_OFF set direction failed\n");
- }
- if(arg>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中添加红色框部分语句。
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<stdio.h>
- #include<unistd.h>
- #include<fcntl.h>
- #include<errno.h>
- #include<sys/ioctl.h>
- #include<sys/types.h>
-
- #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);
- 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模块进行开关机操作。
3G上电后,连接板子的调试串口终端会输出以下红色框的信息,此时表明已识别USB串口设备