zoukankan      html  css  js  c++  java
  • 控制发光二极管

    一 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驱动的移植

    若将LED驱动安装到另一个版本的Linux内核的系统上,首先要获取新的Linux内核的源代码,然后在新内核下重新编译即可

  • 相关阅读:
    50.EasyGank妹纸App
    项目开发规范,数据库设计规范
    用外部物理路由器时与外部dhcp服务时怎样使用metadata服务(by quqi99)
    [报错处理]Python Requests
    [译]为什么在__new __()后总是调用__init __()?
    '>/dev/null 2>&1' 是什么意思?
    “努力就会成功”
    [译]如何在红帽系统(RHEL)上源码安装python3?
    [译]在你的GitHub主页固定仓库
    [译]拉取仓库远程分支
  • 原文地址:https://www.cnblogs.com/xiansheng/p/5532251.html
Copyright © 2011-2022 走看看