精华内容
下载资源
问答
  • 典型的字符设备包括鼠标、键盘、串行口等。 字符设备与块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般紧接着发生。块设备则不然,它利用一块系统内存作为缓冲区,若用户进程对设备的请求能...

    在Linux操作系统下有3类主要的设备文件类型:块设备、字符设备和网络设备。这种分类方法可以将控制输入/输出设备的驱动程序与其他操作系统软件分离开来。字符设备是指存取时没有缓存的设备。典型的字符设备包括鼠标、键盘、串行口等。
    字符设备与块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般紧接着发生。块设备则不然,它利用一块系统内存作为缓冲区,若用户进程对设备的请求能满足用户的要求,就返回请求的数据;否则,就调用请求函数来进行实际的I/O操作。块设备主要是针对磁盘等慢速设备设计的,以免耗费过多的CPU时间用来等待。网络设备可以通过BSD套接口访问数据。
    一.主设备号和次设备号
    主设备号标识设备对应的驱动程序;次设备号由内核使用,用于正确确定设备文件所指的设备。我们可以通过次设备号获得一个指向内核设备的直接指针,也可将次设备号当作设备本地数组的索引,不管用哪种方式,除了知道次设备号用来指向驱动程序所实现的设备之外,内核本身基本上不关心关于次设备号的任何其他消息。
    ◎设备编号的内部表达
    内核用dev_t类型(<linux/types.h>)来保存设备编号,dev_t是一个32位的数,12位表示主设备号,20位表示次设备号。
    在实际使用中,是通过<linux/kdev_t.h>中定义的宏来转换格式。
     (dev_t)-->主设备号、次设备号       MAJOR(dev_t dev)     MINOR(dev_t dev)
     主设备号、次设备号-->(dev_t)       MKDEV(int major,int minor) 
    ◎分配和释放设备编号
    建立一个字符设备之前,驱动程序首先要做的事情就是获得设备编号。其这主要函数在<linux/fs.h>中声明:
    int register_chrdev_region(dev_t first, unsigned int count,char *name);   //指定设备编号
    int alloc_chrdev_region(dev_t *dev, unsigned int firstminor,unsigned int count, char *name);  //动态生成设备编号
    void unregister_chrdev_region(dev_t first, unsigned int count);      //释放设备编号 
    分配之设备号的最佳方式是:默认采用动态分配,同时保留在加载甚至是编译时指定主设备号的余地。
    ◎动态分配主设备号

        某些主设备号已经静态地分配给了大部分公用设备。在内核源码树的Documentation/device.txt......

     

    可以讲字符设备和块设备归为一类,它们都是可以顺序/随机地进行读取和存储的单元,二者驱动主要在于块设备需要具体的burst实现,对访问也有一定的边界要求。其他的没有什么不同。
    网络设备是特殊设备的驱动,它负责接收和发送帧数据,可能是物理帧,也可能是ip数据包,这些特性都有网络驱动决定。它并不存在于/dev下面,所以与一般的设备不同。网络设备是一个net_device结构,并通过register_netdev注册到系统里,最后通过ifconfig -a的命令就能看到。
    不论是什么设备,设备级的数据传输都是基本类似的,内核里的数据表示只是一部分,更重要的是总线的访问,例如串行spi,i2c,并行dma等。

    展开全文
  • Linux设备驱动分类

    2020-03-26 23:31:18
    Linux系统的设备分为字符设备(char device),块设备(block device)和网络设备(network device)三...典型的字符设备包括鼠标,键盘,串行口等。块设备主要包括硬盘软盘设备,CD-ROM等。一个文件系统要安装进入操作系...

    Linux系统的设备分为字符设备(char device),块设备(block device)和网络设备(network device)三种。

    字符设备是指存取时没有缓存的设备。块设备的读写都有缓存来支持,并且块设备必须能够随机存取(random access),字符设备则没有这个要求。典型的字符设备包括鼠标,键盘,串行口等。块设备主要包括硬盘软盘设备,CD-ROM等。一个文件系统要安装进入操作系统必须在块设备上。

    网络设备在Linux里做专门的处理。Linux的网络系统主要是基于BSD unix的socket机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据的传递。系统里支持对发送数据和接收数据的缓存,提供流量控制机制,提供对多协议的支持。

    展开全文
  • 设备驱动程序类别

    2020-12-18 17:19:23
    在Linux操作系统中,设备驱动程序为各种设备提供了一致的访问接口,用户程序可以像 对普通文件一样对...典型的字符设备包括串口、LED灯、键盘等设备。 (2)块设备 块设备是以块的方式进行I/O操作的。块设备是利用一块

    在Linux操作系统中,设备驱动程序为各种设备提供了一致的访问接口,用户程序可以像 对普通文件一样对设备文件进行打开和读写操作。Linux包含如下三类设备驱动程序:
    (1)字符设备
    Linux下的字符设备是指设备发送和接收数据以字符的形式进行。字符设备接口支持面向字 符的1/0操作,数据不经过系统的快速缓存,由驱动本身负责管理自己的缓冲区结构。字符设备 接口只支持顺序存取的有限长度的I/O操作。典型的字符设备包括串口、LED灯、键盘等设备。
    (2)块设备
    块设备是以块的方式进行I/O操作的。块设备是利用一块系统内存作缓冲区,用来临时 存放块设备的数据。当缓存的数据请求达到一定数量,会对设备进行读写操作。块设备是主 要针对磁盘等慢速设备设计的,以免读写设备耗费过多的CPU时间。块设备支持随机存取 功能,也几乎可以支持任意位置和任意长度的I/O请求。典型的块设备包括硬盘、CF卡、 SD卡等存储设备。
    (3)网络设备
    Linux操作系统中的网络设备是一类特殊的设备。Linux的网络子系统主要是基于BSD UNIX的socket机制。在网络子系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数 据的传递。Linux操作系统支持对发送数据和接收数据的缓存,提供流量控制机制,也提供 对多种网络协议的支持。
    Linux系统为每个设备分配了一个主设备号与次设备号,主设备号唯一标识了设备类 型,次设备号标识具体设备的实例。由同一个设备驱动程序控制的所有设备具有相同的主设 备号。从设备号则用来区分具有相同主设备号的不同设备。
    每一个字符设备或块设备在文件系统中都有一个特殊设备文件与之对应,这个文件就是 设备节点。网络设备在文件系统的/dev目录中没有节点,应用层可以通过套接字访问网络设 备。字符设备和块设备的设备节点在/dev目录下面:
    [root@/dev]#ls -1 |more
    crw-rw— 1 root root 5, 1 Dec 31 19:00 console
    crw-rw— 1 root root 13, 63 Dec 31 19:00 mice
    crw-rw—— 1 root root 90, 0 Dec 31 19:00 mtdO
    crw-rw— 1 root root 90, 1 Dec 31 19:00 mtdOro
    crw-rw— 1 root root 90, 2 Dec 31 19:00 mtdl
    crw-rw-一 1 root root 90, 3 Dec 31 19:00 mtdlro
    crw-rw-一 1 root root 90, 4 Dec 31 19:00 mtd2
    crw-rw— 1 root root 90, 5 Dec 31 19:00 mtd2ro
    crw-rw—— 1 root root 90, 6 Dec 31 19:00 mtd3
    crw-rw—— 1 root root 90, 7 Dec 31 19:00 mtd3ro
    brw-rw—— 1 root root 31, 0 Dec 31 19:00 mtdblockO
    brw-rw— 1 root root 31, 1 Dec 31 19:00 mtdblockl
    brw-rw—— 1 root root 31, 2 Dec 31 19:00 mtdblock2
    brw-rw-… 1 root root 31, 3 Dec 31 19:00 mtdblock3
    brw-rw— 1 root root 43, 0 Dec 31 19:00 nbdO
    brw-rw— 1 root root 43, 1 Dec 31 19:00 nbdl
    其中每行第一个字母为c表示字符设备,为b表示块设备。上面第4列就是设备的主设 备号,第5列为设备的次设备号,最后一列为设备节点的名称。/dev下面有两个虚拟设备, 即/dev/null与/dev/zeroo /dev/null是一个空设备,写入与读取数据均没有反馈。cat afile > /dev/null将不会有输出。cat /dev/null > afile会清空afile文件的内容。访问/dev/zero会得到一 段值为0的二进制流。如下面的语句用0填充t.txt文件:

    dd if=/dev/zero of=/home/t.txt bs= 1024 count=768

    另外字符设备与块设备也可以通过/proc/devices文件查看:
    #备注:为节省篇幅,以下对原始终端输出做了重新排版, 数字为设备号, 英文为设备名
    [root@urbetter proc]# cat devices
    Character devices:
    1 mem 2 pty 3 ttyp
    4 /dev/vc/0 4 tty 4 ttyS
    5 /dev/tty 5 /dev/console 5 /dev/ptmx
    7 vcs 10 mi sc 13 input
    14 sound 21 sg 29 fb
    89 i2c 90 mtd 116 alsa
    128 ptm 136 pts 180 usb
    189 usbdevice 204 ttySAC 253 ttySDIO
    254 rtc
    Block devices:
    1 ramdisk 259 blkext 7 loop
    8 sd 31 mtdblock 43 nbd
    65 sd

    展开全文
  • 典型的字符设备包括鼠标、键盘、串行口等。字符设备与块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般紧接着发生。块设备则不然,它利用一块系统内存作为缓冲区,若用户进程对设备的请求能满足...

    在Linux操作系统下有3类主要的设备文件类型:块设备、字符设备和网络设备。这种分类方法可以将控制输入/输出设备的驱动程序与其他操作系统软件分离开来。字符设备是指存取时没有缓存的设备。典型的字符设备包括鼠标、键盘、串行口等。

    字符设备与块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般紧接着发生。块设备则不然,它利用一块系统内存作为缓冲区,若用户进程对设备的请求能满足用户的要求,就返回请求的数据;否则,就调用请求函数来进行实际的I/O操作。块设备主要是针对磁盘等慢速设备设计的,以免耗费过多的CPU时间用来等待。网络设备可以通过BSD套接口访问数据。

    一.主设备号和次设备号

    主设备号标识设备对应的驱动程序;次设备号由内核使用,用于正确确定设备文件所指的设备。我们可以通过次设备号获得一个指向内核设备的直接指针,也可将次设备号当作设备本地数组的索引,不管用哪种方式,除了知道次设备号用来指向驱动程序所实现的设备之外,内核本身基本上不关心关于次设备号的任何其他消息。

    ◎设备编号的内部表达

    内核用dev_t类型(<linux/types.h>)来保存设备编号,dev_t是一个32位的数,12位表示主设备号,20位表示次设备号。
    在实际使用中,是通过<linux/kdev_t.h>中定义的宏来转换格式。
     (dev_t)-->主设备号、次设备号       MAJOR(dev_t dev)     MINOR(dev_t dev)
     主设备号、次设备号-->(dev_t)       MKDEV(int major,int minor) 

    分配和释放设备编号

    建立一个字符设备之前,驱动程序首先要做的事情就是获得设备编号。其这主要函数在<linux/fs.h>中声明:
    int register_chrdev_region(dev_t first, unsigned int count,char *name);   //指定设备编号

    int alloc_chrdev_region(dev_t *dev, unsigned int firstminor,unsigned int count, char *name);   //动态生成设备编号

    void unregister_chrdev_region(dev_t first, unsigned int count);      //释放设备编号 

    分配之设备号的最佳方式是:默认采用动态分配,同时保留在加载甚至是编译时指定主设备号的余地。

    ◎动态分配主设备号

        某些主设备号已经静态地分配给了大部分公用设备。在内核源码树的Documentation/device.txt文件中可以找到这些设备的列表。

        一旦驱动程序被广泛使用,随机选定的主设备号可能造成冲突和麻烦。

        强烈推荐你不要随便选择一个一个当前不用的设备号做为主设备号,而使用动态分配机制获取你的主设备号。

        动态分配的缺点是,由于分配给你的主设备号不能保证总是一样的,无法事先创建设备节点。然而这不是什么问题,这是因为一旦分配了设备号,你就可以从/proc/devices读到。为了加载一个设备驱动程序,对insmod的调用被替换为一个简单的脚本,它通过/proc/devices获得新分配的主设备号,并创建节点。

        分配主设备号的最佳方式:默认采用动态分配,同时保留在加载甚至是编译时指定主设备号的余地。

    以下是在scull.c中用来获取主设备好的代码:

    if (scull_major) {
        dev = MKDEV(scull_major, scull_minor);
        result = register_chrdev_region(dev, scull_nr_devs, "scull");
    } else {
        result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,"scull");
        scull_major = MAJOR(dev);
    }
    if (result < 0) {
        printk(KERN_WARNING "scull: can't get major %d/n", scull_major);
        return result;
    }

    在这部分中,比较重要的是在用函数获取设备编号后,其中的参数name是和该编号范围关联的设备名称,它将出在/proc/devices和sysfs中。

    看到这里,就可以理解为什么mdev和udev可以动态、自动地生成当前系统需要的设备文件。udev就是通过读取sysfs下的信息来识别硬件设备的.

    二、一些重要的数据结构
    文件操作file_operations

           <linux/fs.h>中定义file_operations。

           __user表明指针是一个用户空间地址,因此不能被直接引用。

           ssize_t (*aio_write)(struct kiocb *, const char _ _user *, size_t, loff_t *); 初始化设备上的异步写入操作。

          unsigned int (*poll) (struct file *, struct poll_table_struct *);是poll、epoll和select这三个系统调用的后端实现。可用来查询某个或多个文件描述符上的读取或写入是否会被阻塞。

           int (*mmap) (struct file *, struct vm_area_struct *);用于请求将设备内存映射到进程地址空间。

           int (*fsync) (struct file *, struct dentry *, int);用户调用它来刷新待处理的数据。

           int (*fasync) (int, struct file *, int);用来通知设备其FASYNC标志发生了变化。        

    file结构

           struct file是一个内核结构,不会出现在用户程序中   

    inode结构

           内核用inode结构在内部表示文件,因此它和file结构不同,后者表示打开的文件描述符。对单个文件,可能会有许多个表示打开的文件描述符的file结构,但它们都指向单个inode结构。

           dev_t i_rdev:对表示设备文件的inode结构,该字段包含了真正的设备编号。

           struct cdev *i_cdev;struct cdev表示字符设备的内核的内部结构。当inode指向一个字符设备文件时,该字段包含了指向struct cdev结构的指针

           unsigned int iminor(struct inode *inode);

           unsigned int imajor(struct inode *inode);用来从一个inode中获得主设备号和次设备号

    三、字符设备的注册

    内核内部使用struct cdev结构来表示字符设备。在内核调用设备的操作之前,必须分配并注册一个或多个struct cdev。代码应包含<linux/cdev.h>,它定义了struct cdev以及与其相关的一些辅助函数。

    注册一个独立的cdev设备的基本过程如下:

    1、为struct cdev 分配空间(如果已经将struct cdev 嵌入到自己的设备的特定结构体中,并分配了空间,这步略过!)

    struct cdev *my_cdev = cdev_alloc();

    2、初始化struct cdev

    void cdev_init(struct cdev *cdev, const struct file_operations *fops)
    3、初始化cdev.owner

    cdev.owner = THIS_MODULE;

    4、cdev设置完成,通知内核struct cdev的信息(在执行这步之前必须确定你对struct cdev的以上设置已经完成!)

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

    从系统中移除一个字符设备:void cdev_del(struct cdev *p)

    附:

    概括的说,字符设备驱动主要要做三件事:

    1、定义一个结构体static struct file_operations变量,其内定义一些设备的打开、关闭、读、写、控制函数;

    2、在结构体外分别实现结构体中定义的这些函数;

    3、向内核中注册或删除驱动模块。

    字符设备提供给应用程序流控制接口有:open/close/read/write/ioctl,添加一个字符设备驱动程序,实际上是给上述操作添加对应的代码,Linux对这些操作统一做了抽象 struct file_operations

    file_operations结构体的例子如下

           static struct file_operations myDriver_fops = {

           owner:           THIS_MODULE,

           write:             myDriver_write,

           read:                     myDriver_read,

           ioctl:              myDriver_ioctl,

           open:              myDriver_open,

           release:           myDriver_release,

    };

    该结构体规定了驱动程序向应用程序提供的操作接口:

    实现write操作

    从应用程序接收数据送到硬件。例:

    static ssize_t myDriver_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)

    {

           size_t fill_size = count;

           PRINTK("myDriver write called!/n");

           PRINTK("/tcount=%d, pos=%d/n", count, (int)*f_pos);

           if(*f_pos >= sizeof(myDriver_Buffer))

           {

                  PRINTK("[myDriver write]Buffer Overlap/n");

                  *f_pos = sizeof(myDriver_Buffer);

                  return 0;

           }

           if((count + *f_pos) > sizeof(myDriver_Buffer))

           {

                  PRINTK("count + f_pos > sizeof buffer/n");

                  fill_size = sizeof(myDriver_Buffer) - *f_pos;

           }

           copy_from_user(&myDriver_Buffer[*f_pos], buf, fill_size);

           *f_pos += fill_size;

           return fill_size;

    }

    其中的关键函数

           u_long copy_from_user(void *to, const void *from, u_long len);

    把用户态的数据拷到内核态,实现数据的传送。

    实现read操作

    从硬件读取数据并交给应用程序。例:

    static ssize_t myDriver_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)

    {

           size_t read_size = count;

           PRINTK("myDriver read called!/n");

           PRINTK("/tcount=%d, pos=%d/n", count, (int)*f_pos);

           if(*f_pos >= sizeof(myDriver_Buffer))

           {

                  PRINTK("[myDriver read]Buffer Overlap/n");

                  *f_pos = sizeof(myDriver_Buffer);

                  return 0;

           }

           if((count + *f_pos) > sizeof(myDriver_Buffer))

           {

                  PRINTK("count + f_pos > sizeof buffer/n");

                  read_size = sizeof(myDriver_Buffer) - *f_pos;

           }

           copy_to_user(buf, &myDriver_Buffer[*f_pos], read_size);

           *f_pos += read_size;

           return read_size;

    }

           其中的关键函数

                         u_long copy_to_user(void * to, const void *from, u_long len);

                  该函数实现把内核态的数据拷到用户态下。

    实现ioctl操作

    为应用程序提供对硬件行为的控制。例:

    static int myDriver_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

    {

           PRINTK("myDriver ioctl called(%d)!/n", cmd);

        if(_IOC_TYPE(cmd) != TSTDRV_MAGIC)

        {

            return -ENOTTY;

        }

     

        if(_IOC_NR(cmd) >= TSTDRV_MAXNR)

        {

            return -ENOTTY;

        }

           switch(cmd)

           {

                  case MYDRV_IOCTL0:

                         PRINTK("IOCTRL 0 called(0x%lx)!/n", arg);

                         break;

                  case MYDRV_IOCTL1:

                         PRINTK("IOCTRL 1 called(0x%lx)!/n", arg);

                         break;

                  case MYDRV_IOCTL2:

                         PRINTK("IOCTRL 2 called(0x%lx)!/n", arg);

                         break;

                  case MYDRV_IOCTL3:

                         PRINTK("IOCTRL 3 called(0x%lx)!/n", arg);

                         break;

           }

           return 0;

    }

    实现open操作

    当应用程序打开设备时对设备进行初始化,使用MOD_INC_USE_COUNT增加驱动程序的使用次数。例:

    static int myDriver_open(struct inode *inode, struct file *filp)

    {

           MOD_INC_USE_COUNT;

           PRINTK("myDriver open called!/n");

           return 0;

    }

    实现release操作

    当应用程序关闭设备时处理设备的关闭操作。使用MOD_DEC_USE_COUNT增加驱动程序的使用次数。例:

    static int myDriver_release(struct inode *inode, struct file *filp)

    {

           MOD_DEC_USE_COUNT;

           PRINTK("myDriver release called!/n");

           return 0;

    }

    驱动程序初始化函数

    Linux在加载内核模块时会调用初始化函数,初始化驱动程序本身使用register_chrdev向内核注册驱动程序,该函数的第三个指向包含有驱动程序接口函数信息的file_operations结构体。

    例:

    /* Module Init & Exit function */

    #ifdef CONFIG_DEVFS_FS

    devfs_handle_t devfs_myDriver_dir;

    devfs_handle_t devfs_myDriver_raw;

    #endif

    static int __init myModule_init(void)

    {

           /* Module init code */

           PRINTK("myModule_init/n");

           /* Driver register */

           myDriver_Major = register_chrdev(0, DRIVER_NAME, &myDriver_fops);

           if(myDriver_Major < 0)

           {

                  PRINTK("register char device fail!/n");

                  return myDriver_Major;

           }

           PRINTK("register myDriver OK! Major = %d/n", myDriver_Major);

    #ifdef CONFIG_DEVFS_FS

           devfs_myDriver_dir = devfs_mk_dir(NULL, "myDriver", NULL);

           devfs_myDriver_raw = devfs_register(devfs_myDriver_dir, "raw0", DEVFS_FL_DEFAULT, myDriver_Major, 0, S_IFCHR | S_IRUSR | S_IWUSR, &myDriver_fops, NULL);

           PRINTK("add dev file to devfs OK!/n");

    #endif

           return 0;

    }

    其中,关键函数

    module_init()

    向内核声明当前模块的初始化函数

     

    驱动程序退出函数

    Linux在卸载内核模块时会调用退出函数释放驱动程序使用的资源,使用unregister_chrdev从内核中卸载驱动程序。将驱动程序模块注册到内核,内核需要知道模块的初始化函数和退出函数,才能将模块放入自己的管理队列中。

    例:

    static void __exit myModule_exit(void)

    {

           /* Module exit code */

           PRINTK("myModule_exit/n");

           /* Driver unregister */

           if(myDriver_Major > 0)

           {

    #ifdef CONFIG_DEVFS_FS

                  devfs_unregister(devfs_myDriver_raw);

                  devfs_unregister(devfs_myDriver_dir);

    #endif

                  unregister_chrdev(myDriver_Major, DRIVER_NAME);

           }

           return;

    }

                  其中,关键函数

    module_exit()

    向内核声明当前模块的退出函数。

    关于devfs的操作

    在devfs中建立一个目录(/dev下)

                         devfs_handle_t devfs_mk_dir (devfs_handle_t dir, const char *name, void *info);

    在devfs中注册一个设备文件节点

                         devfs_handle_t devfs_register(devfs_handle_t dir, const char *name,

    unsigned int flags,

    unsigned int major, unsigned int minor,

    umode_t mode, void *ops, void *info);

    在devfs中删除一个设备文件节点

             void devfs_unregister(devfs_handle_t de);

     加载驱动程序

    在终端下,输入以下命令可以对模块进行相关的操作。

    insmod 内核模块文件名

    rmmod 内核模块文件名

    lsmod  列举出当前全部的加载模块文件名

    建立设备文件

    mknod 文件路径 c [主设备号] [从设备号]

    应用程序接口函数

    可以使用标准C的文件操作函数来完成。

     

    应用程序接口函数:

    int open(const char *path, int oflag,…);

    打开名为path的文件或设备

    成功打开后返回文件句柄

    常用oflag:O_RDONLY, O_WRONLY, O_RDWR

    int close(int fd);

    关闭之前被打开的文件或设备

    成功关闭返回0,否则返回错误代号

    ssize_t read(int fd, void *buffer, size_t count);

    从已经打开的文件或设备中读取数据

    buffer表示应用程序缓冲区

    count表示应用程序希望读取的数据长度

    成功读取后返回读取的字节数,否则返回-1

    ssize_t write(int fd, void *buffer, size_t count);

    向已经打开的文件或设备中写入数据

    buffer表示应用程序缓冲区

    count表示应用程序希望写入的数据长度

    成功写入后返回写入的字节数,否则返回-1

    int ioctl(int fd, unsigned long int cmd,…);

    向驱动程序发送控制命令

    cmd需是唯一值

    type:又称幻数,8bit,一般表示cmd所属模块

    number:cmd序号,8bit,一般表示实际的命令

    direction:数据传输方向,2bit

    size:数据大小,位数与体系结构有关(ARM:12bit)

    sizeof(int)-(sizeof(type)+sizeof(number)+sizeof(direction))

    使用_IO宏可快速合成cmd:_IO(MAGIC, num) 

    展开全文
  • 目前大部分(70%)数据都是基于关系型数据库进行存储,关系型数据库在操作上,需要实时高速数据读取和存储,一般数据库都采用“”(Block)方式进行数据传输,这样NAS就无法进行数据应用主流:数据库...
  • 在介绍本文之前,我想先对前面的知识做一下总结,我们知道Linux系统的设备分为字符设备(char device),块设备(block device),以及网络设备...典型的字符设备包括鼠标,键盘,串行口等。块设备主要包括硬盘软...
  • Linux 字符驱动程序(一) 在linux内核中设备主要有三种: 1 字符设备:   •字符设备的读写以字节为单位,存取时没有缓存。 ... •对字符设备发出读写请求时,... •块设备读写以块为单位,典型的块大小为512或
  • 一、I/O设备(键盘) CPU和内存最核心,其他都统称为输入输出(I/O)设备,大部分都是通过USB临时接入到计算机,硬盘也是输入输出(I/O)设备,但是它存储着所有程序和...I/O设备:可以分类块设备和字符设备。
  •  设备文件有两种:字符设备文件和块设备文件  字符设备文件(以字母"c"开头):它向设备传递数据时,一次传递一个字符,典型的通过字符传递数据的设备有终端、打印机,字符设备文件有时也...
  • 磁盘存储

    2019-08-08 18:55:27
    磁盘存储 机械硬盘的原理,分区...(1)块设备:block,存取单位:block,典型的块设备:磁盘   特性①访问单位:block 512B或4K ;块设备的存/取都是以块为单位进行的,若读取一个字节数据,进行的操作是先将所要...
  • 实时操作系统一个关键性需求是高性能字符!/O 字符设备和块设备的一个重要区别:字符设备包含了字节流序列,串行传输;不同于块设备数据永久存在于介质上,此外字符...PC机上的典型硬件设备包括: serial port
  • > HDFS现在包括(在CDH 5.8.2及更高版本中提供)一种用于跨节点移动数据的综合存储容量管理...在典型的安装中,每个目录(在HDFS术语中称为卷)位于不同的设备上(例如,在单独的HDD和SSD上)。在将新写入HDFS...
  • 一款典型的通用汽车(GM)包括AM、FM、卫星广播、两台GPS接收机和蜂窝射频。在乘客座位,还可能有蓝牙;另外,以后还会增加用于车辆与车辆和车辆与基础设施间通信的DSRC(专用短程通信,5.9GHz),也可能还有防碰撞...
  • 单片微型计算机简称单片机,是典型的嵌入式微控制器(Microcontroller Unit),常用英文字母的缩写MCU表示单片机,它最早是被用在工业控制领域。单片机由芯片内仅有CPU的专用处理器发展而来。最早的设计理念是通过将...
  • 一款典型的通用汽车(GM)包括AM、FM、卫星广播、两台GPS接收机和蜂窝射频。在乘客座位,还可能有蓝牙;另外,以后还会增加用于车辆与车辆和车辆与基础设施间通信的DSRC(专用短程通信,5.9GHz),也可能还有防碰撞...
  • 单片微型计算机简称单片机,是典型的嵌入式微控制器(Microcontroller Unit),常用英文字母的缩写MCU表示单片机,它早是被用在工业控制领域。单片机由芯片内仅有CPU的专用处理器发展而来。早的设计理念是通过将大量...
  • 路由器体系结构发展 第一代路由器:集中转发,总线交换 典型产品:华为Quidway R2500系列路由器。 最初IP网络并不大,其网关所需要连接的设备及其需要处理负载也很小。这个时候网关(路由器)基本上可以用一台...
  • 主要从对项目经济上进行分析评价,一方面是支出费用,包括设备购置费、管理和维护费用、人员工资和培训费等,另一个是取得收益。这是个小型系统,从投入人力,财力与物力来讲是非常小,发布出去之需要...
  • 第八周总结

    2018-04-29 21:03:00
    本周主要学习教材第八章Linux操作系统结构包括Linux内核,一些GNU运行库和工具,命令行shell,图形化界面X窗口系统及相应桌面环境,其操作系统内核属于一种典型的宏结构。Linux内核使用了虚拟文件管理VFS机制。Linux...
  • 书中涉及内容非常广泛,包括DBMS概念、术语和体系结构,ER模型和ER图,数据抽象和语义数据建模,UML类图表示法,基本关系模型,关系代数和关系演算,SQL,规范化,磁盘上组织记录文件主要方法,文件索引技术...
  • 第八周网络攻防作业

    2016-04-24 22:07:00
    Linux操作系统结构包括Linux内核,一些GNU运行库和工具,命令行shell,图形化界面X窗口系统及相应桌面环境,其操作系统内核属于一种典型的宏结构。 Linux内核使用了虚拟文件管理VFS机制。 Linux的一个基本特点是抽象...
  • 说明: 为以下各项指定命名约定, 包括日期和星期编号, 默认日期格式, 默认小数点字符和组分隔符, 以及默认 ISO 和本地货币符号。可支持区域包括美国, 法国和日本。有关所有区域信息, 请参阅 Oracle8i ...
  • 引用类型和原始类型具有不同特征和用法,它们包括:大小和速度问题,这种类型以哪种类型数据结构存储,当引用类型和原始类型用作某个类实例数据时所指定缺省值。对象引用实例变量缺省值为 null,而原始...
  • 大连飞翔科技有限公司开发物联网实验平台定位于高校物联网专业应用和物联网实验室建设...实验例程包括STM32W108基础实验、传感器信息采集、无线信号收发实验、物联网网络构建及通讯实验等众多实验例程和典型应用。
  • 操作系统day1

    2019-08-15 13:48:02
    管理计算机所有硬件设备资源,包括处理器,内存,磁盘,打印机,键盘,显示器,网络接口以及其他输入输出设备等。在相互竞争程序之间,有序地控制对这些硬件资源分配。 比如一个磁盘同时为多个用户保存文件,...
  • 数字集成电路广泛用于计算机、控制与测量系统,以及其它电子设备中。 一般说来,数字系统中运行电信号,其大小往往并不改变,但在实践分布上 却有着严格要求,这是数字电路一个特点。 2 系统总体设计: 2.1 ...
  •  本书由多位工作在数据库维护一线工程师合著而成,包含了精心挑选数据库诊断案例与性能优化实践经验,内容涉及oracle典型错误分析和诊断,各种sql优化方法(包括调整索引,处理表碎片,优化分页查询,改善...
  • C++用例输入

    2018-08-07 11:43:23
    互联网笔试时需要自己写测试用例的输入输出,如果在这一卡住浪费了时间显然不值得,这里对于典型的测试用例输入输出框架进行说明。 c++ cin介绍 std::cin是c++ I/O库的标准输入流,接受从外部设备进行的输入。...

空空如也

空空如也

1 2 3 4
收藏数 65
精华内容 26
关键字:

典型的块设备包括