硬件_LED

LED


平台:全志A64

源码:Android 7.1  Linux 3.1

 

led.c

  1 //没有使用平台总线
  2 
  3 #include <linux/init.h>
  4 #include <linux/module.h>
  5 #include <linux/fs.h>
  6 #include <linux/device.h>
  7 #include <linux/slab.h>
  8 #include <linux/gpio.h>
  9 #include <linux/cdev.h>
 10 
 11 #include <asm/io.h>
 12 #include <asm/uaccess.h>
 13 #include <asm-generic/ioctl.h>
 14 
 15 
 16 //面向对象封装led信息
 17 struct a64_led{
 18     //unsigned int major;
 19     dev_t  devno;
 20     struct class * cls;
 21     struct device * dev;
 22     struct cdev  *cdev;
 23     int data;
 24 };
 25 struct a64_led *led_dev;
 26 
 27 
 28 volatile unsigned int *gpco_conf = NULL;
 29 volatile unsigned int *gpco_data = NULL;
 30 
 31 
 32 
 33 
 34 int led_open(struct inode *inode, struct file *filp)
 35 {
 36 
 37     //将对应的管脚设置为输出——PL10
 38     *gpco_conf &= ~(0x07<<8);  //清零    
 39     *gpco_conf |=   0x01<<8;   //置位
 40    
 41     return 0;
 42 }
 43 
 44 
 45 ssize_t led_write(struct file *filp, const char __user *buf, size_t size, loff_t *flags)
 46 {
 47     int ret;
 48 
 49     //应用空间数据转换为内核空间数据
 50     ret = copy_from_user(&led_dev->data,buf,size);
 51     if(ret != 0){
 52         printk("copy_from_user error!\n");
 53         return -EFAULT;
 54     }
 55 
 56     if(led_dev->data){
 57         *gpco_data |= 0x1<<10; //点灯
 58     }else{
 59         *gpco_data &= ~(0x1<<10);//灭灯    
 60     }
 61 
 62     return size;
 63 }
 64 
 65 
 66 int led_close(struct inode *inode, struct file *filp)
 67 {
 68     
 69     *gpco_data &= ~(0x1<<10);  //灭灯
 70     
 71     return 0;
 72 }
 73 
 74 
 75 static struct file_operations fops = {
 76     .open = led_open,   // 打开对gpio初始化config
 77     .write = led_write,
 78     .release = led_close,
 79 };
 80 
 81 
 82 static int __init led_init(void)   
 83 {
 84 
 85 // 1_实例化设备对象
 86     //参数1 -- 要申请的空间的大小
 87     //参数2 -- 申请的空间的标识    
 88     led_dev = kzalloc(sizeof(struct a64_led),GFP_KERNEL);
 89     if(IS_ERR(led_dev)){
 90         printk("kzalloc error!\n");
 91         ret = PTR_ERR(led_dev);
 92         return -ENOMEM;
 93     }
 94 
 95 
 96 // 2_申请设备编号
 97 
 98     //动态申请设备号
 99     ret = alloc_chrdev_region(&led_dev->devno,10,1,"led_drv");
100     if(ret < 0){
101         printk("register_chrdev_region error!\n");
102         ret =  -EINVAL;
103         goto err_kfree;
104     }
105 
106     //申请cdev的空间
107     led_dev->cdev = cdev_alloc();
108     if(IS_ERR(led_dev->cdev)){        
109         printk("led_dev->cdev error!\n");
110         ret = PTR_ERR(led_dev->cdev);
111         goto err_unregister;
112     }
113 
114     //初始化cdev的成员
115     cdev_init(led_dev->cdev,&fops);
116     
117     //将cdev加入到内核中----链表
118     ret = cdev_add(led_dev->cdev,led_dev->devno,1);
119     
120     
121 // 3_创建设备文件    
122     led_dev->cls = class_create(THIS_MODULE,"led_cls");
123     if(IS_ERR(led_dev->cls)){
124         printk("class_create error!\n");
125         ret = PTR_ERR(led_dev->cls);
126         goto err_cdev_del;
127     }    
128     led_dev->dev = device_create(led_dev->cls,NULL,led_dev->devno,NULL,"led");
129     if(IS_ERR(led_dev->dev)){
130         printk("device_create error!\n");
131         ret = PTR_ERR(led_dev->dev);
132         goto err_class;
133     }    
134 
135 // 4_硬件初始化----地址映射
136 
137     gpco_conf = ioremap(0x1F02C04,8);
138     gpco_data = ioremap(0x1F02C10,8);    
139 
140     return 0;
141 
142 err_class:
143     class_destroy(led_dev->cls);
144     
145 err_cdev_del:
146     cdev_del(led_dev->cdev);
147     
148 err_unregister:
149     unregister_chrdev_region(led_dev->devno,1);
150     
151 err_kfree:
152     kfree(led_dev);
153     return ret;
154 
155 }
156 
157 
158 static void __exit led_exit(void)   
159 {
160     printk("--------^_^ %s------------\n",__FUNCTION__);
161     device_destroy(led_dev->cls,led_dev->devno);
162     class_destroy(led_dev->cls);
163     cdev_del(led_dev->cdev);
164     unregister_chrdev_region(led_dev->devno,1);
165     kfree(led_dev);
166 }
167 
168 module_init(led_init);
169 module_exit(led_exit);
170 MODULE_LICENSE("GPL");

 

 

app.c

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <sys/types.h>
 5 #include <sys/stat.h>
 6 #include <fcntl.h>
 7 #include <sys/ioctl.h>
 8 
 9 
10 int main(void)
11 {
12     char led [1] = {1};
13     
14     int fd = open("/dev/led",O_RDWR);
15     if(fd < 0){
16     perror("open");
17     exit(1);
18     }
19 
20     //闪灯
21     int ret = write(fd, led, 1);
22     if(ret <0)
23     {
24         printf("write failed !\n");
25         exit(0);
26     }
27     sleep(1);
28     
29     close(fd);
30     return 0;
31 }

 

 

笔记


  配置寄存器和数据寄存器自行查询用户手册(基地址+偏移地址)

  A64:如下

  

 

 

   

 

posted @ 2019-08-07 10:09  panda_w  阅读(198)  评论(0编辑  收藏  举报