记录的资料来源于迅为视频学习教程。
本节是对上一节的补充,介绍可以复用的GPIO管脚。通过修改程序实现控制32个GPIO。
1.首先去掉占用GPIO的驱动,包括leds, buzzer, camera ov5640, WIFI, mt6620
总线类的如I2C类,虽然也可以作为普通的GPIO使用,但一般尽量不要动。
以上图中的CAM_MCLK为例,在核心板上的位置:
使用的是GPJ1_3。
使用menuconfig将上面提到的驱动从内核中去掉重新编译,烧写进系统。操作如下:
VIDEO_OV5640
– Device Drivers
– Multimedia support(MEDIA_SUPPORT [=y])
– Video capture adapters(VIDEO_CAPTURE_DRIVERS [=y])(去掉)
• MTK_COMBO_CHIP_MT6620
Device Drivers
- MediaTek Connectivity Combo Chip Config
- MediaTek Connectivity Combo Chip Support (MTK_COMBO [=y])(去掉)
- Select Chip (<choice> [=y])
Enable LEDS config
– Device Drivers
– Character devices
– Enable LEDS config
Enable BUZZER config
– Device Drivers
– Character devices
– Enable BUZZER config
修改完config之后重新编译:make zImage -j4
将生成的zImage拷贝到升级的sdupdate目录下,插入板子中在uboot模式下sd更新内核:
1 uboot模式下操作: 2 SYSTEM ENTER NORMAL BOOT MODE 3 Hit any key to stop autoboot: 0 4 iTOP-4412 # 5 iTOP-4412 # 6 iTOP-4412 # 7 iTOP-4412 # 8 iTOP-4412 # sdfuse flash kernel zImage 9 SD sclk_mmc is 400K HZ 10 SD sclk_mmc is 50000K HZ 11 SD sclk_mmc is 50000K HZ 12 [Fusing Image from SD Card.] 13 [Partition table on MoviNAND] 14 ptn 0 name='bootloader' start=0x0 len=N/A (use hard-coded info. (cmd: movi)) 15 ptn 1 name='kernel' start=N/A len=N/A (use hard-coded info. (cmd: movi)) 16 ptn 2 name='ramdisk' start=N/A len=0x300000(~3072KB) (use hard-coded info. (cmd: movi)) 17 ptn 3 name='Recovery' start=N/A len=0x600000(~6144KB) (use hard-coded info. (cmd: movi)) 18 ptn 4 name='system' start=0x15DDA00 len=0xA900FA00(~2768958KB) 19 ptn 5 name='userdata' start=0xAA5ED400 len=0x1321EC00(~313467KB) 20 ptn 6 name='cache' start=0xBD80C000 len=0x1321EC00(~313467KB) 21 ptn 7 name='fat' start=0xD0A2AC00 len=0x2DC00(~183KB) 22 Partition: kernel, File: /sdupdate/zImage 23 Partition1: Start Address(0x580000), Size(0x1827c00) 24 reading /sdupdate/zImage 25 3706068 (0x00388cd4) bytes read 26 flashing 'kernel' 27 writing kernel.. 1120, 12288 28 MMC write: dev # 0, block # 1120, count 12288. 12288 blocks write finish 29 12288 blocks written: OK 30 completed 31 partition 'kernel' flashed 32 iTOP-4412 # reset 33 ...
2. 部分GPIO介绍:
LED的两个IO,网络是KP_COL0, VDD50_EN
蜂鸣器的一个IO,网络是MOTOR_PWM
矩阵键盘的8个IO,网络是CHG_FLT, HOOK_DET, CHG_UOK, XEINT14_BAK, GM_INT1, 6260_GPIO1, CHG_COK, XEINT29/KP_ROW13/ALV_DBG25
摄像头的14个IO,网络是CAM_MCLK, CAM2M_RST, CAM2M_PWDN, CAM_D5, CAM_D7, CAM_D6, CAM_D4, CAM_D3, CAM_D2,
CAM_D1, CAM_PCLK, CAM_D0, CAM_VSYNC, CAM_HREF。
I2C_SDA7, I2C_SCL7也可以设置为GPIO,不过总线一般不要去动它。
WiFi模块的7个IO,WIFI_D3, WIFI_CMD, WIFI_D1, WIFI_CLK, WIFI_D0, WIFI_D2, GPC1_1
串口Rx和Tx等也是可以设置为GPIO,一般不要动它。
数组中有32个引出到端子或者模块的IO,还有类似sd卡等也是可以作为GPIO,其它引到连接器但是没有使用的GPIO等等。
具体的查看方法参见1中的图片。
3. 将上一步提到的所有IO定义到下列的数组中:
直接截图PPT中的内容粘贴过来,SCP中按照这个方式将所有GPIO配置在里面。
4. 编译简单程序测试:
与上一节程序相比修改的地方:
hello_probe中使用for循环依次申请和配置资源。hello_remove中取消,hello_ctl中循环设置。
编译
1 nan@nanzh:~/iTOP4412/8$ arm-none-linux-gnueabi-gcc invoke_gpios.c -o invoke_gpios -static 2 nan@nanzh:~/iTOP4412/8$ ls invoke_gpios* 3 invoke_gpios invoke_gpios.c 4 nan@nanzh:~/iTOP4412/8$ make 5 make -C /home/nan/iTOP4412/iTop4412_Kernel_3.0 M=/home/nan/iTOP4412/8 modules 6 make[1]: Entering directory '/home/nan/iTOP4412/iTop4412_Kernel_3.0' 7 CC [M] /home/nan/iTOP4412/8/gpios.o 8 /home/nan/iTOP4412/8/gpios.c: In function 'hello_ctl': 9 /home/nan/iTOP4412/8/gpios.c:41: warning: format '%d' expects type 'int', but argument 3 has type 'long unsigned int' 10 Building modules, stage 2. 11 MODPOST 1 modules 12 LD [M] /home/nan/iTOP4412/8/gpios.ko 13 make[1]: Leaving directory '/home/nan/iTOP4412/iTop4412_Kernel_3.0'
运行结果及现象:
1 # 本来led只有LED2被uboot点亮,在insmod之后LED2和LED3都亮了 2 root@iTOP4412-ubuntu-desktop:~/tests/8# insmod gpios.ko 3 [ 1222.814463] hello world enter! 4 [ 1222.825380] initialized 5 [ 1222.855242] DriverState is 0 6 root@iTOP4412-ubuntu-desktop:~/tests/8# ls /dev/hello_gpio 7 /dev/hello_gpio 8 # 其他现象,如测试CAMERA的9和10引脚,为高电平 9 # invoke_gpio参数0全部设置为低电平,1全部设置为高电平 10 root@iTOP4412-ubuntu-desktop:~/tests/8# ./invoke_gpios 0 11 argv[0] is ./invo[ 1575.083592] hello open 12 ke_gpios;argv[1] is 0;cmd is 0! 13 App open /dev/hel[ 1575.090302] cmd is 0, args is 0 14 [ 1575.093464] cmd is 0, args is 1 15 lo_gpio success 16 App ioctl /dev/hello_gpio, cmd is 0, i is 0 17 App ioctl /dev/he[ 1575.105256] cmd is 0, args is 2 18 [ 1575.108378] cmd is 0, args is 3 19 llo_gpio, cmd is 0, i is 1 20 App ioctl /dev/hello_gpio, cmd is 0, i is 2 21 App ioctl /dev/he[ 1575.120226] cmd is 0, args is 4 22 [ 1575.123352] cmd is 0, args is 5 23 llo_gpio, cmd is 0, i is 3 24 App ioctl /dev/hello_gpio, cmd is 0, i is 4 25 App ioctl /dev/he[ 1575.135226] cmd is 0, args is 6 26 [ 1575.138352] cmd is 0, args is 7 27 [ 1575.142201] cmd is 0, args is 8 28 [ 1575.144623] cmd is 0, args is 9 29 llo_gpio, cmd is 0, i is 5 30 App ioctl /dev/hello_gpio, cmd is 0, i is 6 31 App ioctl /dev/hello_gpio, cmd is 0, i is 7 32 App ioctl /dev/hello_gpio, cmd is 0, i is 8 33 App ioctl /dev/he[ 1575.165209] cmd is 0, args is 10 34 [ 1575.168420] cmd is 0, args is 11 35 llo_gpio, cmd is 0, i is 9 36 App ioctl /dev/hello_gpio, cmd is 0, i is 10 37 App ioctl /dev/he[ 1575.190200] cmd is 0, args is 12 38 [ 1575.193408] cmd is 0, args is 13 39 llo_gpio, cmd is 0, i is 11 40 App ioctl /dev/hello_gpio, cmd is 0, i is 12 41 App ioctl /dev/he[ 1575.210216] cmd is 0, args is 14 42 [ 1575.213425] cmd is 0, args is 15 43 llo_gpio, cmd is 0, i is 13 44 App ioctl /dev/hello_gpio, cmd is 0, i is 14 45 App ioctl /dev/he[ 1575.230227] cmd is 0, args is 16 46 [ 1575.233435] cmd is 0, args is 17 47 llo_gpio, cmd is 0, i is 15 48 App ioctl /dev/hello_gpio, cmd is 0, i is 16 49 App ioctl /dev/he[ 1575.250209] cmd is 0, args is 18 50 [ 1575.253413] cmd is 0, args is 19 51 llo_gpio, cmd is 0, i is 17 52 App ioctl /dev/hello_gpio, cmd is 0, i is 18 53 App ioctl /dev/he[ 1575.270238] cmd is 0, args is 20 54 [ 1575.273447] cmd is 0, args is 21 55 llo_gpio, cmd is 0, i is 19 56 App ioctl /dev/hello_gpio, cmd is 0, i is 20 57 App ioctl /dev/he[ 1575.290214] cmd is 0, args is 22 58 [ 1575.293420] cmd is 0, args is 23 59 llo_gpio, cmd is 0, i is 21 60 App ioctl /dev/hello_gpio, cmd is 0, i is 22 61 App ioctl /dev/he[ 1575.310240] cmd is 0, args is 24 62 [ 1575.313446] cmd is 0, args is 25 63 llo_gpio, cmd is 0, i is 23 64 App ioctl /dev/hello_gpio, cmd is 0, i is 24 65 App ioctl /dev/he[ 1575.330209] cmd is 0, args is 26 66 [ 1575.333417] cmd is 0, args is 27 67 llo_gpio, cmd is 0, i is 25 68 App ioctl /dev/hello_gpio, cmd is 0, i is 26 69 App ioctl /dev/he[ 1575.350226] cmd is 0, args is 28 70 [ 1575.353435] cmd is 0, args is 29 71 llo_gpio, cmd is 0, i is 27 72 App ioctl /dev/hello_gpio, cmd is 0, i is 28 73 App ioctl /dev/he[ 1575.368545] cmd is 0, args is 30 74 [ 1575.371821] cmd is 0, args is 31 75 [ 1575.374970] hello release! 76 llo_gpio, cmd is 0, i is 29 77 App ioctl /dev/hello_gpio, cmd is 0, i is 30 78 App ioctl /dev/hello_gpio, cmd is 0, i is 31 79 root@iTOP4412-ubuntu-desktop:~/tests/8# ./invoke_gpios 1 80 argv[0] is ./invo[ 1628.366283] hello open 81 [ 1628.368580] cmd is 1, args is 0 82 ke_gpios;argv[1] is 1;cmd is 1! 83 App open /dev/hello_gpio success 84 App ioctl /dev/he[ 1628.380315] cmd is 1, args is 1 85 [ 1628.383435] cmd is 1, args is 2 86 llo_gpio, cmd is 1, i is 0 87 App ioctl /dev/hello_gpio, cmd is 1, i is 1 88 App ioctl /dev/he[ 1628.400235] cmd is 1, args is 3 89 [ 1628.403356] cmd is 1, args is 4 90 [ 1628.406791] cmd is 1, args is 5 91 [ 1628.409603] cmd is 1, args is 6 92 llo_gpio, cmd is 1, i is 2 93 App ioctl /dev/hello_gpio, cmd is 1, i is 3 94 App ioctl /[ 1628.420173] cmd is 1, args is 7 95 [ 1628.423301] cmd is 1, args is 8 96 dev/hello_gpio, cmd is 1, i is 4 97 App ioctl /dev/hello_gpio, cmd is 1, i is 5 98 App ioctl /dev/hell[ 1628.435178] cmd is 1, args is 9 99 [ 1628.437900] cmd is 1, args is 10 100 o_gpio, cmd is 1, i is 6 101 App ioctl /dev/hello_gpio, cmd is 1, i is 7 102 App ioctl /dev/hello_gpio, [ 1628.450181] cmd is 1, args is 11 103 [ 1628.452832] cmd is 1, args is 12 104 [ 1628.456501] cmd is 1, args is 13 105 [ 1628.459252] cmd is 1, args is 14 106 cmd is 1, i is 8 107 App ioctl /dev/hello_gpio, cmd is 1, i is 9 108 App ioctl /dev/hello_[ 1628.470174] cmd is 1, args is 15 109 [ 1628.472971] cmd is 1, args is 16 110 gpio, cmd is 1, i is 10 111 App ioctl /dev/hello_gpio, cmd is 1, i is 11 112 App ioctl /dev/hello_gpio, [ 1628.485174] cmd is 1, args is 17 113 [ 1628.488048] cmd is 1, args is 18 114 [ 1628.491684] cmd is 1, args is 19 115 [ 1628.494343] cmd is 1, args is 20 116 cmd is 1, i is 12 117 App ioctl /dev/hello_gpio, cmd is 1, i is 13 118 App ioctl /dev/hello_gpio, cmd is 1, i is 14 119 App ioctl /dev/hello_gpio, cmd is 1, i is 15 120 App ioctl /dev/hello_gpio, cmd is 1, i [ 1628.515159] cmd is 1, args is 21 121 [ 1628.517905] cmd is 1, args is 22 122 is 16 123 App ioctl /dev/hello_gpio, cmd is 1, i is 17 124 App ioctl /dev/hello_gpio, cmd is 1, i is 18 125 App ioctl /dev/hello_gpio, cmd is 1, i is 19 126 App ioctl /dev/hello_gpio, cmd is 1, i is 20 127 App ioctl /dev/hell[ 1628.540155] cmd is 1, args is 23 128 [ 1628.542407] cmd is 1, args is 24 129 o_gpio, cmd is 1, i is 21 130 App ioctl /dev/hello_gpio, cmd is 1, i is 22 131 App ioctl /dev/hello_gpio[ 1628.555172] cmd is 1, args is 25 132 [ 1628.557339] cmd is 1, args is 26 133 , cmd is 1, i is 23 134 App ioctl /dev/hello_gpio, cmd is 1, i is 24 135 App ioctl /dev/hello_gpio, cmd [ 1628.570159] cmd is 1, args is 27 136 [ 1628.572269] cmd is 1, args is 28 137 is 1, i is 25 138 App ioctl /dev/hello_gpio, cmd is 1, i is 26 139 App ioctl /dev/hello_gpio, cmd is 1, i is 27 140 App i[ 1628.585203] cmd is 1, args is 29 141 [ 1628.588415] cmd is 1, args is 30 142 octl /dev/hello_gpio, cmd is 1, i is 28 143 App ioctl /dev/hello_gpio, cmd is 1, i is 29 144 App ioctl /dev/he[ 1628.605207] cmd is 1, args is 31 145 [ 1628.608450] hello release! 146 llo_gpio, cmd is 1, i is 30 147 App ioctl /dev/hello_gpio, cmd is 1, i is 31 148 root@iTOP4412-ubuntu-desktop:~/tests/8# rmmod gpios 149 [ 1676.228733] hello world exit! 150 [ 1676.240051] remove
源码如下:
gpios.c
1 #include <linux/init.h> 2 #include <linux/module.h> 3 4 #include <linux/platform_device.h> 5 #include <linux/miscdevice.h> 6 #include <linux/fs.h> 7 8 #include <linux/gpio.h> //通用的一般会被其他的包含 9 #include <plat/gpio-cfg.h> //三星平台 10 #include <mach/gpio.h> //EXYNOS平台 11 #include <mach/gpio-exynos4.h> //4412平台 12 13 #define DRIVER_NAME "hello_ctl" 14 #define DEVICE_NAME "hello_gpio" 15 16 //定义需要使用的所有GPIO的数组 17 static int led_gpios[] = { 18 //LED 19 EXYNOS4_GPL2(0),EXYNOS4_GPK1(1), 20 //蜂鸣器 21 EXYNOS4_GPD0(0), 22 23 //矩阵键盘 24 EXYNOS4_GPX1(0),EXYNOS4_GPX1(3),EXYNOS4_GPX1(5),EXYNOS4_GPX1(6), 25 EXYNOS4_GPX3(0),EXYNOS4_GPX2(6),EXYNOS4_GPX2(7),EXYNOS4_GPX3(5), 26 27 //摄像头 28 EXYNOS4212_GPJ1(3),EXYNOS4_GPL0(1),EXYNOS4_GPL0(3),EXYNOS4212_GPJ1(0), 29 EXYNOS4212_GPJ1(2),EXYNOS4212_GPJ1(1),EXYNOS4212_GPJ0(7),EXYNOS4212_GPJ0(6), 30 EXYNOS4212_GPJ0(5),EXYNOS4212_GPJ0(4),EXYNOS4212_GPJ0(0),EXYNOS4212_GPJ0(3), 31 EXYNOS4212_GPJ0(1),EXYNOS4212_GPJ0(2), 32 33 //WIFI模块 34 EXYNOS4_GPK3(6),EXYNOS4_GPK3(1),EXYNOS4_GPK3(4),EXYNOS4_GPK3(0), 35 EXYNOS4_GPK3(3),EXYNOS4_GPK3(5),EXYNOS4_GPC1(1), 36 }; 37 #define LED_NUM ARRAY_SIZE(led_gpios) 38 39 //参数1是GPIO的值为0或1,参数2是GPIO的个数 40 static long hello_ctl(struct file *files, unsigned int cmd, unsigned long arg){ 41 printk(KERN_EMERG "cmd is %d, args is %d ", cmd, arg); 42 43 switch(cmd){ 44 case 0: 45 case 1: 46 if(arg > LED_NUM){ 47 return -EINVAL; 48 } 49 gpio_set_value(led_gpios[arg], cmd); 50 break; 51 default: 52 return -EINVAL; 53 } 54 55 gpio_set_value(led_gpios[2], 0); 56 return 0; 57 } 58 static int hello_release(struct inode *inode, struct file *file){ 59 printk(KERN_EMERG "hello release! "); 60 return 0; 61 } 62 static int hello_open(struct inode *inode, struct file *file){ 63 printk(KERN_EMERG "hello open "); 64 return 0; 65 } 66 static struct file_operations hello_ops = { 67 .owner = THIS_MODULE, 68 .open = hello_open, 69 .release = hello_release, 70 .unlocked_ioctl = hello_ctl, 71 }; 72 73 static struct miscdevice hello_dev = { 74 .minor = MISC_DYNAMIC_MINOR, 75 .name = DEVICE_NAME, 76 .fops = &hello_ops, 77 }; 78 79 //资源申请也在probe中 80 static int hello_probe(struct platform_device *pdv){ 81 int ret, i; 82 printk(KERN_EMERG "initialized "); 83 84 for(i=0; i<LED_NUM; i++){ 85 ret = gpio_request(led_gpios[i], "LED"); //参数宏在文件中查找:arch/arm/mach-exynos/include/mach/gpio-exynos4.h 86 if(ret) 87 printk(KERN_EMERG "%s: request GPIO %d for LED failed, ret = %d ", DRIVER_NAME, i, ret); 88 else{ 89 s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT); 90 gpio_set_value(led_gpios[i], 1); 91 } 92 } 93 94 gpio_set_value(led_gpios[2], 0); //将蜂鸣器设置为0,否则一直在响 95 96 misc_register(&hello_dev); 97 98 if(ret < 0){ 99 printk(KERN_EMERG "leds: register device failed! "); 100 goto exit; 101 } 102 return 0; 103 104 exit: 105 misc_deregister(&hello_dev); 106 return ret; 107 } 108 static int hello_remove(struct platform_device *pdv){ 109 int i; 110 printk(KERN_EMERG "remove "); 111 112 for(i=0; i < LED_NUM; i++){ 113 gpio_free(led_gpios[i]); 114 } 115 116 misc_deregister(&hello_dev); 117 return 0; 118 } 119 static void hello_shutdown(struct platform_device *pdev){ 120 ; 121 } 122 static int hello_suspend(struct platform_device *pdv, pm_message_t pmt){ 123 return 0; 124 } 125 static int hello_resume(struct platform_device *pdv){ 126 return 0; 127 } 128 129 struct platform_driver hello_driver = { 130 .probe = hello_probe, 131 .remove = hello_remove, 132 .shutdown = hello_shutdown, 133 .suspend = hello_suspend, 134 .resume = hello_resume, 135 .driver = { 136 .name = DRIVER_NAME, 137 .owner = THIS_MODULE, 138 } 139 }; 140 141 static int hello_init(void){ 142 int DriverState; 143 144 printk(KERN_EMERG "hello world enter! "); 145 DriverState = platform_driver_register(&hello_driver); 146 147 printk(KERN_EMERG "DriverState is %d ", DriverState); 148 return 0; 149 } 150 151 static void hello_exit(void){ 152 printk(KERN_EMERG "hello world exit! "); 153 platform_driver_unregister(&hello_driver); 154 } 155 156 module_init(hello_init); 157 module_exit(hello_exit); 158 159 MODULE_LICENSE("Dual BSD/GPL"); 160 MODULE_AUTHOR("NANZH");
Makefile:
obj-m += gpios.o KDIR := /home/nan/iTOP4412/iTop4412_Kernel_3.0 PWD ?= $(shell pwd) all: make -C $(KDIR) M=$(PWD) modules clean: rm -rf *.o
invoke_gpios.c:
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <string.h> #define GPIOS 32 int main(int argc, char **argv) { int fd, i, cmd = 2; char *hello_node = "/dev/hello_gpio"; char *cmd0 = "0"; char *cmd1 = "1"; printf("argv[0] is %s;argv[1] is %s;",argv[0],argv[1]); if(strcmp(argv[1], cmd0) == 0){ cmd = 0; printf("cmd is 0! "); } if(strcmp(argv[1], cmd1) == 0){ cmd = 1; printf("cmd is 1! "); } if((fd = open(hello_node, O_RDWR|O_NDELAY)) < 0){ printf("App open %s failed! ", hello_node); } else{ printf("App open %s success ", hello_node); for(i=0; i<GPIOS; i++){ ioctl(fd, cmd, i); printf("App ioctl %s, cmd is %d, i is %d ",hello_node, cmd, i); } } close(fd); return 0; }
以上
脑力不够,今天好累,下次调整和完善