• 硬件_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!
    ");
     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!
    ");
     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!
    ");
    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!
    ");
    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!
    ");
    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!
    ");
    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------------
    ",__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 !
    ");
    25         exit(0);
    26     }
    27     sleep(1);
    28     
    29     close(fd);
    30     return 0;
    31 }

    笔记


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

      A64:如下

      

       

    Stay hungry, stay foolish 待续。。。
  • 相关阅读:
    改造二叉树
    汽车加油行驶问题
    [SHOI2012]回家的路
    子串
    P3558 [POI2013]BAJ-Bytecomputer
    HDU
    UVALive
    ZOJ
    HDU
    牛客小白月赛2 题解
  • 原文地址:https://www.cnblogs.com/panda-w/p/11313208.html
Copyright © 2020-2023  润新知