• 第七章 LED 将为我闪烁: 控帘 j发光二级管


    一 、LED驱动的实现原理

      尽管Linux驱动直接与硬件打交道,但并不是Linux驱动直接向硬件中的内存写数据,而是与本机的I/O内存进行交互。每一个连接Linux的硬件在I/O内存中都会有映射首地址,开发板上的LED也有其映射首地址。

    二 、编写LED驱动 

      第一步:使用cdev_init函数初始化cdev , 描述设备文件

      struct cdev{

        struct kobject kobj;    //封装设备文件的对象

        struct module *owner;   //指向内核模块的指针

        const struct file_operations *ops;  //指向file_operations结构体的指针

        struct list_head list;   //指向上一个和下一个cdev结构体的指针

        dev_t dev;  // 表示设备号,int类型,前12位主设备号,后20位次设备号

        unsigned int count;  //请求的连接设备编号范围(最大值),在建立多个设备文件时使用

      }

      void cdev_init(struct cdev *cdev,const struct file_operations *fops)

      {

        memset(cdev,0,sizeof *cdev);

        INIT_LIST_HEAD(&cdev->list);

        kobject_init(&cdev->kobj,&ktype_cdev_default);

        cdev->ops = fops;

      }

      第二步:指定设备号    用1个int类型表示,前12位表示主设备号,后20位表示次设备号

        int dev_number=MKDEV(major,minor); //major表示主设备号,minor表示次设备号

        int major=MAJOR(dev_number);

        int minor=MAJOR(dev_number);

      第三步:使用cdev_add函数将字符设备添加到内核中的字符设备数组中

        int cdev_add(struct cdev *p,dev_t dev,unsigned count)

      {

        p->dec=dev;

        p->count-count;

        return kobj_map(cdev_map,dev,count,NULL,exact_match,exact_lock,p);

      }

      第四步:使用class_create 宏创建struct class

        struct class *leds_class = NULL;

        leds_class=class_create(THIS_MODULE,"dev_name");

      第五步:使用device_create函数创建设备文件

        device_create函数的原型如下:struct device *device_create(struct class *class,struct device *parent,dev_t devt,void *drvdata,const chahr*fmt,...)

        leds_init函数是LED驱动的初始化函数:

        static in leds_init(void)

        {

          int ret;

          ret=leds_create_device();// 创建设备文件

          printk(DEVICE_NAME" inintialized ");

        }

        module_init(leds_init);

      第六步:卸载设备文件

        static void leds_destroy_device(void)

        {

          device_destroy(leds_class,dev_number);//移除通过device_create函数建立的字符设备

          if(leds_calss)//销毁struct class

            class_destroy(leds_class);

           unregister_chrdev_region(dec_number,DEVICE_NUMBER);//注销字符设备区域

          return;

        }

        static void leds_exit(void)

        {

          leds_destroy_device();//卸载LED驱动的设备文件

          printk(DEVICE_NAME" exit! ");

        }

        module_exit(leds_exit);

      第七步:分配寄存器

        leds_init_gpm函数初始化寄存器

        在leds_init函数中调用leds_init_gpm函数完成寄存器的初始化

        static int leds_init(void)

        {

          int ret;

          ret=leds_create_device();

          leds_init_gpm(0xE);//初始化寄存器

          printk(DEVICE_NAME"tinitialized ");

          return ret;

        }

      第八步:控制LED

        两种方式:通过字符串控制(使用file_operations.write函数)

             AND 通过I/O命令控制LED(使用file_operations.ioctl函数)

    三、测试LED驱动

      最后进行测试led驱动,方法有一下几种

      (一)编写测试 f/0 控制命令的通用程序

      (二)使用 NDK 测试 LED 驱动

      (三)使用 Java 测试 LED 驱动

    四、LED驱动的移植

      LED 驱动最简单的移植就是将其 在不同 Lim肌肉核版本下进行编译。

      比如这本书上的LED 驱动是在 Linux 2.6.36 下编译的,如果需 要将 LED 驱动安装到 Linux 3.x 内核的系统上( Android 4.x及以上版本的系统〉,首先要获取 Linux 3. x 内核的源代码〈至少是 Linux 内核的头文件〉,然后在新内核下重新编译即可。

    http://www.cnblogs.com/JOKERLAU/

  • 相关阅读:
    maven打包时出现 Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.4:install (default-install) on project……
    maven+springmvc出现:java.sql.SQLException: Unknown system variable 'query_cache_size'
    IDEA复制某个类的包名路径
    IDEA中更改Tomcat服务器的URL
    IDEA去除自动检测bean是否存在
    ASM ClassReader failed to parse class file
    The content of element type "web-app" must match "(icon?,display-name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,servlet- mapping*,session-config?,mime-map
    Could not open ServletContext resource [/WEB-INF/xxx-servlet.xml]
    Eclipse+maven 构建第一个简单的springmvc项目
    Eclispe中编辑xml配置文件时不会提示也不能自动调整格式
  • 原文地址:https://www.cnblogs.com/JOKERLAU/p/5560312.html
Copyright © 2020-2023  润新知