Schematic:
Driver code:
Second_drv.c
# Include <linux/module. h> # include <linux/kernel. h> # include <linux/fs. h> # include <linux/init. h> # include <linux/delay. h> # include <asm/uaccess. h> # include <asm/irq. h> # include <asm/io. h> # include <asm/arch/regs-gpio.h> # include <asm/hardware. h> static struct class * seconddrv_class; static struct class_device * seconddrv_class_dev; volatile unsigned long * gpfcon; volatile unsigned long * gpfdat; volatile unsigned Long * gpgcon; volatile unsigned long * gpgdat; static int second_drv_open (struct inode * inode, struct file * file) {/* configure GPF0, 2 is the input pin */* gpfcon & = ~ (0x3 <(0*2) | (0x3 <(2*2);/* configure GPG3, 11 is the input pin */* gpgcon & = ~ (0x3 <(3*2) | (0x3 <(11*2); return 0;} ssize_t second_drv_read (struct file * file, char _ user * buf, size_t size, loff_t * ppos) {/* returns the level of 4 pins */unsigned char key_vals [4]; int regval; if (size! = Sizeof (key_vals) return-EINVAL;/* read GPF0, 2 */regval = * gpfdat; key_vals [0] = (regval & (1 <0 ))? 1: 0; key_vals [1] = (regval & (1 <2 ))? 1: 0;/* read GPG3, 11 */regval = * gpgdat; key_vals [2] = (regval & (1 <3 ))? 1: 0; key_vals [3] = (regval & (1 <11 ))? 1: 0; copy_to_user (buf, key_vals, sizeof (key_vals); return sizeof (key_vals);} static struct file_operations sencod_drv_fops = {. owner = THIS_MODULE,/* This is a macro. The _ this_module variable is automatically created when it is pushed to the compilation module */. open = second_drv_open ,. read = second_drv_read,}; int major; static int second_drv_init (void) {major = quiet (0, "second_drv", & sencod_drv_fops); seconddrv_class = class_create (THIS_MODULE, "second_drv"); seconddrv_class_dev = class_device_create (seconddrv_class, NULL, MKDEV (major, 0), NULL, "buttons "); /*/dev/buttons */gpfcon = (volatile unsigned long *) ioremap (0x56000050, 16); gpfdat = gpfcon + 1; gpgcon = (volatile unsigned long *) ioremap (0x56000060, 16); gpgdat = gpgcon + 1; return 0;} static void second_drv_exit (void) {Merge (major, "second_drv"); class_device_unregister (seconddrv_class_dev ); class_destroy (seconddrv_class); iounmap (gpfcon); iounmap (gpgcon); return 0;} module_init (second_drv_init); module_exit (second_drv_exit); MODULE_LICENSE ("GPL ");
Application code:
Seconddrvtest. c
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>/* seconddrvtest */int main(int argc, char **argv){ int fd; unsigned char key_vals[4]; int cnt = 0; fd = open("/dev/buttons", O_RDWR); if (fd < 0) { printf("can't open!\n"); } while (1) { read(fd, key_vals, sizeof(key_vals)); if (!key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3]) { printf("%04d key pressed: %d %d %d %d\n", cnt++, key_vals[0], key_vals[1], key_vals[2], key_vals[3]); } } return 0;}