[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!
", (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
");
148         return -ENODEV;
149     }
150     printk(KERN_INFO "led_gpio major#: %d, minor#: %d
", 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
",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!
");
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
");
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
");
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!
");
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!
");
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!
 ")  
38     }
39 
40     api_led_close(fd_led);
41     
42     return 0;
43 }
原文地址:https://www.cnblogs.com/imapla/p/4127118.html