[DM8168]Linux下控制GPIO实现LED流水灯
首先加载驱动模块,应用程序通过调用API实现GPIO控制功能。
驱动程序:
1 /* 2 * fileName: led_gpio.c 3 * just for LED GPIO test 4 * GP1_14 -> HDD 5 * GP1_15 -> REC 6 * GP1_27 -> NC 7 * GP1_28 -> IR 8 */ 9 10 #include <linux/device.h> 11 #include <linux/fs.h> 12 #include <linux/module.h> 13 #include <linux/kernel.h> 14 #include <linux/init.h> 15 #include <linux/moduleparam.h> 16 #include <linux/list.h> 17 #include <linux/cdev.h> 18 #include <linux/proc_fs.h> 19 #include <linux/mm.h> 20 #include <linux/seq_file.h> 21 #include <linux/ioport.h> 22 #include <linux/delay.h> 23 #include <asm/io.h> 24 #include <linux/io.h> 25 #include <mach/gpio.h> 26 #include <linux/device.h> 27 #include <linux/platform_device.h> 28 #include <linux/ioctl.h> 29 30 #define DRIVERNAME "led4" 31 32 #define CTRL_MODULE_BASE_ADDR 0x48140000 33 34 // PANEL CON 35 #define conf_gpio46 (CTRL_MODULE_BASE_ADDR + 0x0B04) 36 #define conf_gpio47 (CTRL_MODULE_BASE_ADDR + 0x0B08) 37 #define conf_gpio59 (CTRL_MODULE_BASE_ADDR + 0x0AB8) 38 #define conf_gpio60 (CTRL_MODULE_BASE_ADDR + 0x0ABC) 39 40 #define WR_MEM_32(addr, data) *(unsigned int*)OMAP2_L4_IO_ADDRESS(addr) = (unsigned int)(data) 41 #define RD_MEM_32(addr) *(unsigned int*)OMAP2_L4_IO_ADDRESS(addr) 42 43 static dev_t dev; 44 static struct cdev cdev; 45 static struct class *led_gpio_class = NULL; 46 static int gpio[4]; 47 48 static int led_gpio_open(struct inode *inode, struct file *file); 49 static int led_gpio_close(struct inode *inode, struct file *file); 50 static long led_gpio_ioctl(struct file *file, unsigned int val, unsigned long pin); 51 //static int valid_check(unsigned int gpioNum); 52 53 ////////////////////////////////////////////////////////////////////////////// 54 /*- 55 static int valid_check(unsigned int gpioNum) 56 { 57 if((gpioNum==46)||(gpioNum==47)||(gpioNum==59)||(gpioNum==60)) 58 return 1; 59 return -1; 60 } 61 -*/ 62 63 static void store_gpio_pin(void) 64 { 65 // store gpio pinmux 66 gpio[0] = RD_MEM_32(conf_gpio46); 67 gpio[1] = RD_MEM_32(conf_gpio47); 68 gpio[2] = RD_MEM_32(conf_gpio59); 69 gpio[3] = RD_MEM_32(conf_gpio60); 70 } 71 72 static void recover_gpio_pin(void) 73 { 74 // recover gpio pinmux 75 WR_MEM_32(conf_gpio46, gpio[0]); 76 WR_MEM_32(conf_gpio47, gpio[1]); 77 WR_MEM_32(conf_gpio59, gpio[2]); 78 WR_MEM_32(conf_gpio60, gpio[3]); 79 gpio_free(gpio[0]); 80 gpio_free(gpio[1]); 81 gpio_free(gpio[2]); 82 gpio_free(gpio[3]); 83 } 84 85 static void config_gpio_pin(void) 86 { 87 WR_MEM_32(conf_gpio46, 2); 88 gpio_request(46, "gpio46_en"); // request gpio46 89 gpio_direction_output(46, 0); 90 91 WR_MEM_32(conf_gpio47, 2); 92 gpio_request(47, "gpio47_en"); // request gpio47 93 gpio_direction_output(47, 0); 94 95 WR_MEM_32(conf_gpio59, 1); 96 gpio_request(59, "gpio59_en"); // request gpio59 97 gpio_direction_output(59, 0); 98 99 WR_MEM_32(conf_gpio60, 1); 100 gpio_request(60, "gpio60_en"); // request gpio60 101 gpio_direction_output(60, 0); 102 } 103 104 static int led_gpio_open(struct inode *inode, struct file *file) 105 { 106 // store gpio pin value 107 store_gpio_pin(); 108 // configure all used gpio 109 config_gpio_pin(); 110 return 0; 111 } 112 113 static int led_gpio_close(struct inode *inode, struct file *file) 114 { 115 // recover gpio pin mux; 116 recover_gpio_pin(); 117 return 0; 118 } 119 120 static long led_gpio_ioctl(struct file *file, unsigned int val, unsigned long pin) 121 { 122 if(valid_check(pin) < 0){ 123 printk("GPIO:%d can't use!\n", (int)pin); 124 return -1; 125 } 126 gpio_set_value(pin, val); 127 128 return 0; 129 } 130 131 132 133 static struct file_operations led_gpio_fops = 134 { 135 .owner = THIS_MODULE, 136 .open = led_gpio_open, 137 .release = led_gpio_close, 138 .unlocked_ioctl = led_gpio_ioctl, 139 }; 140 141 static int __init LED_init(void) 142 { 143 int result; 144 145 result = alloc_chrdev_region(&dev, 0, 1, DRIVERNAME); 146 if(result < 0){ 147 printk("Error registering led_gpio character device\n"); 148 return -ENODEV; 149 } 150 printk(KERN_INFO "led_gpio major#: %d, minor#: %d\n", MAJOR(dev), MINOR(dev)); 151 152 cdev_init(&cdev, &led_gpio_fops); 153 cdev.owner = THIS_MODULE; 154 cdev.ops = &led_gpio_fops; 155 156 result = cdev_add(&cdev, dev, 1); 157 if(result){ 158 unregister_chrdev_region(dev, 1); 159 printk("Error adding led_gpio.. error no:%d\n",result); 160 return -EINVAL; 161 } 162 led_gpio_class = class_create(THIS_MODULE, DRIVERNAME); 163 device_create(led_gpio_class, NULL, dev, NULL, DRIVERNAME); 164 165 printk(DRIVERNAME "initialized"); 166 167 return 0; 168 } 169 170 static void __exit LED_exit(void) 171 { 172 printk("led chrdev exit!\n"); 173 cdev_del(&cdev); 174 unregister_chrdev_region(dev, 1); 175 device_destroy(led_gpio_class, dev); 176 class_destroy(led_gpio_class); 177 } 178 179 module_init(LED_init); 180 module_exit(LED_exit); 181 MODULE_LICENSE("GPL");
API函数:
1 #ifndef API_LED_H 2 #define API_LED_H 3 #include <stdio.h> 4 5 #ifdef __cplusplus 6 extern "C" { 7 #endif 8 9 int api_led_open(void); 10 int api_led_close(int fd_led); 11 int api_led_ioctl(int fd_led, unsigned int pin, unsigned int val); 12 13 #ifdef __cplusplus 14 } 15 #endif 16 17 #endif
1 #include "api_led.h" 2 #include <fcntl.h> 3 #include <unistd.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <sys/ioctl.h> 7 8 #define DEVICENAME "/dev/led4" 9 10 int api_led_open(void) 11 { 12 int fd_led; 13 if((fd_led=open(DEVICENAME,O_RDWR)) <= -1){ 14 printf("open device error\n"); 15 return -1; 16 } 17 return fd_led; 18 } 19 20 int api_led_close(int fd_led) 21 { 22 if(0 == close(fd_led)) 23 return 0; 24 else 25 return -1; 26 } 27 28 int api_led_ioctl(int fd_led, unsigned int pin, unsigned int val) 29 { 30 if(ioctl(fd_led, val, pin) < 0){ 31 printf("write error\n"); 32 return -1; 33 }else{ 34 return 0; 35 } 36 }
应用程序:
1 /*- test for Lcd12864 -*/ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include "api_led.h" 6 int main(void) 7 { 8 int fd_led; 9 // int num; 10 // int ret; 11 int delay = 10; 12 13 fd_led = api_led_open(); 14 15 if(fd_led < 0){ 16 printf("fd_led open failed!\n"); 17 return -1; 18 } 19 20 21 api_led_ioctl(fd_led, 47, 1); 22 api_led_ioctl(fd_led, 60, 1); 23 24 printf("Hello, Water LEDs run!\n"); 25 26 while(delay--){ 27 api_led_ioctl(fd_led, 60, 1); // LED IR off 28 api_led_ioctl(fd_led, 46, 0); // LED HDD on 29 usleep(100000); 30 api_led_ioctl(fd_led, 46, 1); // LED HDD off 31 api_led_ioctl(fd_led, 47, 0); // LED REC on 32 usleep(100000); 33 api_led_ioctl(fd_led, 47, 1); // LED REC off 34 api_led_ioctl(fd_led, 60, 0); // LED IR on 35 usleep(100000); 36 // if(count < 0) return -1; 37 // printf("light LED HDD!\n ") 38 } 39 40 api_led_close(fd_led); 41 42 return 0; 43 }