首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 开发>Linux 嵌入式>文章内容
Linux串口上网的简单实现 (图解)
来源:www.unix5.com 作者:riechelr_hl(收集) 发布时间:2007-06-20  
int register_chdev(unsigned int major, const char *, struct fle_operations *fops)

字符设备被注册成功后,内核把这两个字符设备加入到内核字符设备驱动表中。内核字符设备驱动表保留指向struct file_operations的一个数据指针。用户进程调用设备读写操作时,通过这个指针访问设备的操作函数, struct file_operations中的域大部分是指向函数的函数指针,指向用户自己编写的设备操作函数。


struct file_operations ed_ops ={
#ifdef LINUX_24
    NULL,
#endif
    NULL,
    device_read,
    device_write,
    NULL,
    NULL,
    device_ioctl,
    NULL,
    device_open,
    NULL,
    device_release,    	
};

注意到Linux2.4.x和 Linux2.2.x内核中定义的struct file_operations是不一样的。device_read()、device_write()、device_ioctl()、 device_open()、device_release()就是需要用户自己定义的函数操作了,这几个函数是最基本的操作,如果需要设备驱动程序完成更复杂的任务,还必须编写其他struct file_operations中定义的操作。eddev_module_init()除了注册设备及其操作外,它还有初始化字符设备结构struct ed_device,分配内核缓存区所需要的空间的作用。在内核空间,分配内存空间的API函数是kmalloc()。

下面介绍一下字符设备的主要操作例程device_open()、device_release()、device_read()、devie_write()。字符设备文件操作结构ed_ops中定义的指向以上函数的函数指针的原形:


	 device_open:  int(*open)(struct inode *,struct file *)     
     device_release: int (*release) (struct inode *, struct file *);
     device_read:  ssize_t (*read) (struct file *, char *, size_t, loff_t *);
     device_write: ssize_t (*write) (struct file *, const char *, size_t, loff_t *);


操作int device_open(struct inode *inode,struct file *file)是设备节点上的第一个操作,如果多个设备共享这一个操作函数,必须区分设备的设备号。我们使用inode->i_rdev >> 8 语句获得设备的主设备号,本文中的接收设备主设备号是200,发送设备号是201。每个字符设备的file>private_data指向打开设备时候使用的file结构,private_data实际上可以指向用户定义的任何结构,这里只指向我们自己定义的struct ed_device,用来保存字符设备的一些基本信息,比如设备名、内核缓存区等。

操作ssize_t device_read(struct file *file,char *buffer,size_t length, loff_t *offset)是读取设备数据的操作。device_read()结构如图4所示。


图4

从设备中读取数据(用户空间调用read()系统调用)的时候,需要从内核空间把数据拷贝到用户空间,copy_to_user()可完成此功能,它和 memcpy()此类函数有本质的区别,memcpy()不能完成不同用户空间数据的交换。如果需要数据临界区的保护,使用spin_lock()内核 API负责加锁,spin_unlock()负责解锁,防止数据污染。由于串口守候进程server需要不断轮询设备,以查询是否有数据可读,如果用户进程不处于休眠状态,在用户空间查看进程使用资源情况,发现server占用了很多CPU资源。所以我们改进device_read(),使之在内核中轮询,当发现当前设备没有数据可读取,那么就阻塞用户进程,使用内核API add_wait_queue()可完成此功能,这时候用户进程并没有占用很多CPU资源,而是处于休眠状态。当内核发现有数据可读的时候,调用 remove_wait_queue()即可唤醒等待进程,这段

代码如下:


    DECLARE_WAITQUEUE(wait,current);
    add_wait_queue(&edp->rwait,&wait);
    for(;;){        
        set_current_state(TASK_INTERRUPTIBLE);
        if ( file->f_flags & O_NONBLOCK)
            break;
        /*其他代码 */
        if ( signal_pending(current))
            break;
        schedule();
    }
    set_current_state(TASK_RUNNING);
remove_wait_queue(&edp->rwait,&wait);

操作ssize_t device_write(struct file *file,const char *buffer, size_t length,loff_t *offset)向设备写入数据。拷贝数据的copy_from_user()和copy_to_user()的功能恰恰相反,它是从用户空间拷贝数据到内核空间,如图5所示。


图 5
 

编写伪网络设备驱动程序

伪网络驱动程序和字符设备驱动程序一样,也必须初始化和注册。网络驱动需记录其发送和接收数据量的统计信息,所以我们定义一个记录这些信息的数据结构。


共7页: 上一页 [1] [2] 3 [4] [5] [6] [7] 下一页
 

如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·嵌入式Linux系统下图形库讲解及
·Qt/Embedded在嵌入式Linux中的应
·嵌入式Linux:uClinux操作系统移
·嵌入式系统 Boot Loader 技术内
·嵌入式 用户图形接口uC/GUI的简
·基于GTK+和X的GUI在嵌入式Linux
·嵌入式Linux系统下的MiniGUI研究
·在Ubuntu上建立Arm Linux的开发
·嵌入式Linux操作系统启动信息完
·Linux 2.6 内核的嵌入式系统应用
·嵌入式Linux在Blackfin处理器上
·嵌入式uClinux的内核结构和开发
  相关文章
·嵌入式 用户图形接口uC/GUI的简
·学习嵌入式Linux系统的笔记和体
·嵌入式Linux 中的应用中的GTK+
·Linux高手进阶 嵌入式系统设计开
·基于GTK+和X的GUI在嵌入式Linux
·嵌入式Linux系统的动态电源管理
·在嵌入式Linux增加自己的设备驱
·RTOS设备驱动向嵌人式Linux的移
·嵌入式Linux操作系统的网络存储
·嵌入式操作系统的两种远程调试方
·嵌入式Linux操作系统启动信息完
·嵌入式系统中的模块动态加载技术

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!