嵌入式开发记录-day26 读GPIO端口
1、在之前LED驱动的基础上继续做
2、在原理图上找到拨码开关,使用3和4做输入;向开发板内拨动,为低电平0,0V;向开发板外拨动为高电平1,1.8V;
1、在主板搜索AP_SLEEP(3)----》在核心板搜索----》GPC0_3----->根据GPIO命名规则EXYNOS4_GPC0(3)
2、在主板搜索XEINT6(4)----》在核心板搜索----》GPX0_6----->根据GPIO命名规则EXYNOS4_GPX0(6)
3、寄存器的设置:
1、将寄存器GPC0CON[3]设置为0x0,将此端口配置为输入;
2、当把引脚设置为输入的时候,可以读取寄存器GPC0DAT[4:0]获取端口的状态;
3、输入端口配置,不上下拉,寄存器GPC0PUD[n]配置为0;
4、寄存器GPC0PUDPDN一般配置输出的时候会用到,用于放大电路;
4、端口GPIO的初始配置
//1、申请GPIO端口 gpio_request(EXYNOS4_GPC0(3),"SWITCH3"); //2、设置GPIO端口为输入模式 s3c_gpio_cfgpin(EXYNOS4_GPC0(3),S3C_GPIO_INPUT); //3、3、设置无上下拉电阻 s3c_gpio_setpull(EXYNOS4_GPC0(3),S3C_GPIO_PULL_NONE); // 4、获取GPIO端口高点电平 gpio_get_value(EXYNOS4_GPC0(3));
5、配置平台文件
vim arch/arm/mach-exynos/mach-itop4412.c // 打开平台文件 // 搜索leds,并添加代码,需注意格式 struct platform_device s3c_device_read_gpio_ctl = { .name = "read_gpio_ctl", .id = -1, }; // 再次搜索leds,并添加 &s3c_device_read_gpio_ctl, // 在int get_lcd_type()函数返回之前添加代码 gpio_free(EXYNOS4_GPC0(3)); gpio_free(EXYNOS4_GPX0(6))
6、驱动代码readgpio.c
1 #include <linux/init.h> 2 #include <linux/module.h> 3 4 /*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/ 5 #include <linux/platform_device.h> 6 /*注册杂项设备头文件*/ 7 #include <linux/miscdevice.h> 8 /*注册设备节点的文件结构体*/ 9 #include <linux/fs.h> 10 11 /*Linux中申请GPIO的头文件*/ 12 #include <linux/gpio.h> 13 /*三星平台的GPIO配置函数头文件*/ 14 /*三星平台EXYNOS系列平台,GPIO配置参数宏定义头文件*/ 15 #include <plat/gpio-cfg.h> 16 #include <mach/gpio.h> 17 /*三星平台4412平台,GPIO宏定义头文件*/ 18 #include <mach/gpio-exynos4.h> 19 20 #define DRIVER_NAME "read_gpio_ctl" 21 #define DEVICE_NAME "read_gpio_ctl" 22 23 24 MODULE_LICENSE("Dual BSD/GPL"); 25 MODULE_AUTHOR("TOPEET"); 26 27 //应用里面通过ioctl返回值来获取管脚电平 28 static long read_gpio_ioctl( struct file *files, unsigned int cmd, unsigned long arg){ 29 printk("cmd is %d,arg is %d\n",cmd,arg); 30 31 //参数cmd可以是0或者1 32 if(cmd > 1){ 33 printk(KERN_EMERG "cmd is 0 or 1\n"); 34 } 35 if(arg > 1){ 36 printk(KERN_EMERG "arg is only 1\n"); 37 } 38 39 //如果cmd是0,则返回EXYNOS4_GPC0(3),拨码开关3对应管脚的输入电平 40 //如果cmd是1,则返回EXYNOS4_GPX0(6),拨码开关4对应管脚的输入电平 41 if(cmd == 0){ 42 // 4、获取GPIO端口高点电平 43 return gpio_get_value(EXYNOS4_GPC0(3)); 44 } 45 if(cmd == 1){ 46 return gpio_get_value(EXYNOS4_GPX0(6)); 47 } 48 return 0; 49 } 50 51 static int read_gpio_release(struct inode *inode, struct file *file){ 52 printk(KERN_EMERG "hello release\n"); 53 return 0; 54 } 55 56 static int read_gpio_open(struct inode *inode, struct file *file){ 57 printk(KERN_EMERG "hello open\n"); 58 return 0; 59 } 60 61 static struct file_operations read_gpio_ops = { 62 .owner = THIS_MODULE, 63 .open = read_gpio_open, 64 .release = read_gpio_release, 65 .unlocked_ioctl = read_gpio_ioctl, 66 }; 67 68 static struct miscdevice read_gpio_dev = { 69 .minor = MISC_DYNAMIC_MINOR, 70 .name = DEVICE_NAME, 71 .fops = &read_gpio_ops, 72 }; 73 74 static int read_gpio_probe(struct platform_device *pdv){ 75 int ret; 76 77 printk(KERN_EMERG "\tinitialized\n"); 78 // 1、申请GPIO端口 79 ret = gpio_request(EXYNOS4_GPC0(3),"SWITCH3"); 80 if(ret < 0){ 81 printk(KERN_EMERG "gpio_request EXYNOS4_GPC0(3)failed!\n"); 82 return ret; 83 } 84 else{ 85 //2、设置GPIO端口为输入模式 86 s3c_gpio_cfgpin(EXYNOS4_GPC0(3),S3C_GPIO_INPUT); 87 // 3、设置无上下拉电阻 88 s3c_gpio_setpull(EXYNOS4_GPC0(3),S3C_GPIO_PULL_NONE); 89 } 90 91 ret = gpio_request(EXYNOS4_GPX0(6),"SWITCH4"); 92 if(ret < 0){ 93 printk(KERN_EMERG "gpio_request EXYNOS4_GPX0(6) failed!\n"); 94 return ret; 95 } 96 else{ 97 s3c_gpio_cfgpin(EXYNOS4_GPX0(6),S3C_GPIO_INPUT); 98 s3c_gpio_setpull(EXYNOS4_GPX0(6),S3C_GPIO_PULL_NONE); 99 } 100 101 misc_register(&read_gpio_dev); 102 103 return 0; 104 } 105 106 static int read_gpio_remove(struct platform_device *pdv){ 107 108 printk(KERN_EMERG "\tremove\n"); 109 misc_deregister(&read_gpio_dev); 110 return 0; 111 } 112 113 static void read_gpio_shutdown(struct platform_device *pdv){ 114 115 ; 116 } 117 118 static int read_gpio_suspend(struct platform_device *pdv,pm_message_t pmt){ 119 120 return 0; 121 } 122 123 static int read_gpio_resume(struct platform_device *pdv){ 124 125 return 0; 126 } 127 128 struct platform_driver read_gpio_driver = { 129 .probe = read_gpio_probe, 130 .remove = read_gpio_remove, 131 .shutdown = read_gpio_shutdown, 132 .suspend = read_gpio_suspend, 133 .resume = read_gpio_resume, 134 .driver = { 135 .name = DRIVER_NAME, 136 .owner = THIS_MODULE, 137 } 138 }; 139 140 static int read_gpio_init(void) 141 { 142 int DriverState; 143 144 printk(KERN_EMERG "HELLO WORLD enter!\n"); 145 DriverState = platform_driver_register(&read_gpio_driver); 146 147 printk(KERN_EMERG "\tDriverState is %d\n",DriverState); 148 return 0; 149 } 150 151 static void read_gpio_exit(void) 152 { 153 printk(KERN_EMERG "HELLO WORLD exit!\n"); 154 155 platform_driver_unregister(&read_gpio_driver); 156 } 157 158 module_init(read_gpio_init); 159 module_exit(read_gpio_exit);
7、应用代码app_read_gpio.c
1 #include <stdio.h> 2 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <fcntl.h> 6 #include <unistd.h> 7 #include <sys/ioctl.h> 8 9 int main(int argc,char **argv) 10 { 11 int fd,cmd=2; 12 char *read_gpio = "/dev/read_gpioo_ctl"; 13 char *cmd0 = "0"; 14 char *cmd1 = "1"; 15 printf("argc[0] is %s;argv[1] is %s;",argv[0],argv[1]); 16 17 if(strcmp(argv[1],cmd0)==0){ 18 cmd = 0; 19 } 20 if(strcmp(argv[1],cmd1)==0){ 21 cmd = 1; 22 } 23 24 /*O_RDWR只读打开,O_NDELAY非阻塞方式*/ 25 if((fd = open(read_gpio,O_RDWR|O_NDELAY))<0){ 26 printf("APP open %s failed",read_gpio); 27 } 28 else{ 29 printf("APP open %s success!\n",read_gpio); 30 printf("%d io value is %d\n",cmd,ioctl(fd,cmd,0)); 31 } 32 close(fd); 33 }
8、编译内核并烧写镜像
9、加载测试运行