jz2440的字符设备驱动

来源:互联网 发布:centos zip 压缩 编辑:程序博客网 时间:2024/05/16 10:23
VFS根据设备类型、设备号来找到fops
实现方法:在一个数组里面,以major为索引,找到fops后填充到数组中去。


APP:    open("/dev/xxx")     read,write
        属性 : c ,111
————————————————————————
              C 库
————————————————————————
         VFS
————————————————————————
         ___ ___ ________ _____
   数组 |_1_|_2_|.........|_111_|....VFS找到file_operation






—————————————————————————
驱动程序  (1) led_open , led_read,  led_write
          (2) 定义一个fileoperation
           (3)  register_chrdev(major,name,fops)
          
register_chrdev(0,name,fops)   // 0设置会自动选择空闲的主设备号
在open("/dev/xxx", ,)后必须建立起设备节点:
mknod  /dev/xxx  252 0


在根文件系统构造时,也有新建console、null的设备节点:
mknod  c 2 2 console
mknod  c 1 4 null






(1)驱动程序中可以自动分配主设备号
(2)应用程序   open("/dev/xxx",)    
                    ||
  ||
    —》怎么来的?
  a.mknod  /dev/xxx c 252 0   创建
  b.自动创建    
    udev(对于busybox是mdev):
                    (1).根据系统信息 
                    (2).创建设备节点 /sys/
static struct class  *firstdrv_class;              //定义类
static struct class_device *firstdrv_class_devs[4];//定义类设备
在入口函数中:
  major = register_chrdev(0,"first_drv",&first_drv_fops)  //注册fops结构
  ************************************
  产生系统信息,通过下述代码来产生
  ************************************
  firstdrv_class = class_create(THIS_MODULE,"firstdrv");  //创建类
  firstdrv_devs[0] = class_device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"leds")//创建类设备
 


查看系统中的类class:
cd sys/class 
ls  
firstdrv   //类
ls 
xyz        //设备
cd xyz 
dev  ..    //dev中就是252 0
为什么udev可以自动生成次设备号?
原因在于创建根文件系统,启动文件/etc/init.d/rcS中就已经有相应的启动语句,启动mdev:
echo /sbin/mdev  > /proc/sys/kernel/hotplug
mdev -s


写一个点LED的驱动:
1、  框架
2、完善 硬件的操作  a. 看原理图
   b. 看2440手册
   c. 写代码   单片机操作物理地址
                                驱动程序操作虚拟地址,用ioremap来映射
配置引脚:GPFCON  open函数中做
设置:    GPFDAT  write函数中做
volatile unsigned long *gpfcon = NULL;
volatile unsigned long *gpfdat = NULL;
1.在firstdrv_init函数中先将上述地址映射:
      gpfcon = (volatile unsigned long *)ioremap(0x56000050,16);
      gpfdat = gpfcon + 1;  //加1不是一般的数字加1
2.在first_drv_open中设置输出引脚的输入还是输出:
      gpfcon &= ~((0x3<<(4*2))| () |());
      gpfcon |=  (.....);
3.在first_drv_write中设置引脚值:
  copy_from_user(&val,buf,count);
  if(val = 1)
   {
  //点灯
        gpfdat |= (1<<4)| (1<<5)| (1<<6);
   }
   else  
   {
//灭灯
   }
0 0
原创粉丝点击