首页 > 控制发光二极管

控制发光二极管

一 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内核的源代码,然后在新内核下重新编译即可

转载于:https://www.cnblogs.com/xiansheng/p/5532251.html

更多相关:

  • 主要是在bluestore的实例上执行低级管理操作的使用程序,是ceph bluestore的管理工具 命令 help显示帮助信息fsck [--deep]对bluestore元数据进行一致性检查。如果指定了–deep,还要读取所有对象数据并验证校验和repair运行一致性检查 并修复我们可以发生的任何错误bluefs-ex...

  • iOS获取设备唯一标识的各种方法?IDFA、IDFV、UDID分别是什么含义?iOS获取设备ID总结IDFA解释 关于UUID的理解 : 英文名称是:Universally Unique Identifier,翻译过来就是通用唯一标识符。 UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提...

  • Running Your Application 原文演示了怎样在真机和模拟器上运行你的App。 原文链接:http://developer.android.com/training/basics/firstapp/running-app.html 译文链接:http://android.toolib.net/training/bas...

  • 转:http://blog.csdn.net/zhouzhuan2008/article/details/11053877   目录 MTD总概述MTD数据结构 MTD相关层实现 MTD,Memory Technology Device即内存技术设备 字符设备和块设备的区别在于前者只能被顺序读写,后者可以随机访问;同时,两者读写数...

  • 设备管理器架构 ----Windows Embedded CE 6.0 R3   原文:http://msdn.microsoft.com/en-us/library/ee484004(v=WinEmbedded.60).aspx   设备管理器运行在Windows Embedded CE操作系统下,跟踪加载的驱动及其接口。它从内核中...

  • C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能。 struct能包含成员函数吗? 能! struct能继承吗? 能!! struct能实现多态吗? 能!!!   既然这些它都能实现,那它和class还能有什么区别? 最本质的一个区别就是默认的访问控制,...

  • 学习apue课程已经有一个多月了,有很多知识点需要自己去总结: 下面是主要的几个函数的介绍: 1-stat()函数是获得文件的主要信息。在linux当中主要以一个结构体来保存文件的信息,其中每一个字段都代表着文件的一个信息量: struct stat {dev_t st_dev; /* ID of device co...

  • C/C++ 中struct的区别 C中的struct是没有权限设置的。 C++中struct增加了访问权限,且可以和类一样有成员函数。 C++中的struct等同于class,只是class默认成员权限是private,而struct默认成员权限是public。且class的默认继承为私有继承,struct的默认继承为公有继承。 C+...