免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 857 | 回复: 0
打印 上一主题 下一主题

LED驱动 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-06 02:31 |只看该作者 |倒序浏览
LED驱动
  好就没写了,虽然写的比较烂。但是一定要坚持。坚持学习,坚持记录。

  这段时间写了两个小小的驱动,很简单。还看了一下书。LED的驱动和BUTTON的驱动。

现在先说下LED的感觉

首先是设备注册函数:
  1.发现原来2.6内核和2.4内核提倡的注册设备方法是不同的。很多资料上面都说尽量使用固定的主设备号,但是在《linux设备驱动程序》书中说尽量使用动态分配的方法,我想这个也是linux发展的方向。

  2.在2.4中用来注册设备的函数是register_dhrdev(unsigned int major, const char *name, struct file_operations *fops),这个函数注册0~255次设备号给指定的主设备号,使用这个接口的驱动程序的open函数必须能处理0~255次设备号的打开,而且只能用于主设备号和次设备号都不大于255情况。
    在2.6中注册设备是有一个流程的,(1)指定主设备号使用register_chrdev_region(dev_t first,unsigned int count, char *name);这是申请设备号,frist是要分配的设备编号的起始值,count是要分配的设备号的个数,name是设备名称,它将出现在/proc/devices和sysfs中。
    自动分配使用alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name),dev是用于输出的参数,成功后保存分配到的第一个编号。
    注销使用unregister_chrdev_region(dev_t first,unsigned int count)
    使用时最好是自动分配自设备号,但是保留手动分配的方法。

    2.6的注册流程:
        a.用上面的函数分配设备号。
        b.使用cdev_init(struct cdev *dev, struct file_operations *fops)为字符设备分配结构体,
        c.使用cdev_add(struct cdev *dev,dev_t num, struct file_operations *fops)来告诉内核该结构体的信息。应该是往内核设备结构链表中添加这个结构体。
   
  3.设置IO口模式是使用的函数:
    set_gpio_ctrl(LED(i)|GPIO_PULLUP_EN|GPIO_MODE_OUT);//这是一个宏函数。包含在Regs-gpio.h (kernel-2.6.13\include\asm-arm\arch-s3c2410)中。
    write_gpio_bit(LED(i),0);//同样是个宏,写IO口数据
    虽然这两个函数实现要求的功能,但是应该在内核里有更通用的方法,不过现在还没看到,暂时用着先。

   4.使用了关于内存的两个函数kmalloc(sizeof(struct LED_cdev),GFP_KERNEL); kfree(led_devices);但是理解不够,要好好了解.

   5.write和ioctl函数。
      这里两个函数都写了,网上有的说用write好,有点说是用ioctl比较好,不明白什么原因,就都写上去了。
     在write中:用到了一个copy_from_user(&ledctl,buf ,sizeof(int));函数,这是从内核空间传递数据到用户空间的函数。第一个是数据来源地址(内核空间中),第二个是用户空间指针,第三是大小
     这里是用来传一个数据来表示gpio的状态,最低四位是LED亮灭状态的表示。
     
     在led_ioctl中使用unsigned int cmd,做控制码,unsigned long arg作为LED序号表示,在用户空间ioctl的原型是int ioctl(int fd, unsigned long cmd, ...);后面...是可选参数,一般在驱动程序里面就是ioctl函数的最后一个参数int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);中的unsigned long arg。在驱动程序中一般是用switch(cmd)语句来实现控制。

   6.在read函数中使用了一个copy_to_user(buf,&readtest,sizeof(int));来传递一个参数到用户空间,只是顺便实验一下。也是第一次用。第一个参数是目标首地址,第二个是原数据首地址,第三个是大小

   7.这个驱动用的测试程序有两个,一个是自己写的,用来测试读写的,还有一个是改了一点友善之臂的测试LED的程序的。都能正常运行


文件:
led.rar
大小:
26KB
下载:
下载

   这个LED的驱动到这里也就基本上写完了,下一个是Button的。 已经写出来的,但是还没有总结。
   那个涉及到中断,现在不算是非常理解。关键是中断注册的位置,中断函数的参数传递的问题。里面还有时间回调函数。
   
    最近感觉自己的程序真的不怎么行。一定要花时间在次巩固程序。主要是程序的整体把握不是很好。程序灵感不是很好。需要提高,抽空学下数据结构不知道怎么样?还是用C写一个相对大些的项目效果会比较好一点呢?



















本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/85783/showart_1682046.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP