亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区
Chinaunix
標(biāo)題:
tty設(shè)備驅(qū)動(dòng)無(wú)read函數(shù)
[打印本頁(yè)]
作者:
lanlovehua
時(shí)間:
2010-07-28 11:49
標(biāo)題:
tty設(shè)備驅(qū)動(dòng)無(wú)read函數(shù)
最近在看tty設(shè)備驅(qū)動(dòng),它的驅(qū)動(dòng)操作里沒(méi)有read函數(shù),但是可以通過(guò)tty_flip_buffer_push函數(shù)將數(shù)據(jù)存到緩沖區(qū)。而用戶要讀tty設(shè)備緩沖區(qū)的數(shù)據(jù)可以在用戶態(tài)下使用read系統(tǒng)調(diào)用,但是我使用read系統(tǒng)調(diào)用后,程序就不運(yùn)行了,也沒(méi)有結(jié)束,就是停在哪里不動(dòng)了。
請(qǐng)問(wèn)這是什么原因?
我的系統(tǒng)是ubuntu9.04. 內(nèi)核版本是2.6.28
代碼如下:
模塊:
tty_lan_ops.c:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/tty.h>
#include <linux/fs.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/ioport.h>
#include <linux/serial_reg.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("lan");
#define TTY_LAN_MINORS_NUM
5
#define TTY_LAN_MAJOR
202
static int open_count = 0;
static struct tty_driver *tty_lan_driver;
static int tty_lan_open(struct tty_struct *tty, struct file *filp);
static void tty_lan_close(struct tty_struct *tty, struct file *filp);
static int tty_lan_write(struct tty_struct *tty, const unsigned char *buffer, int count);
static int tty_lan_write_room(struct tty_struct *tty);
static void tty_lan_set_termios(struct tty_struct *tty, struct ktermios * old);
static int tty_lan_put_char(struct tty_struct *tty, unsigned char ch);
static struct tty_operations tty_lan_ops = {
.open = tty_lan_open,
.close = tty_lan_close,
.write = tty_lan_write,
.put_char = tty_lan_put_char,
.write_room = tty_lan_write_room,
.set_termios = tty_lan_set_termios,
};
static int __init tty_lan_init(void)
{
int i;
int retval;
tty_lan_driver = alloc_tty_driver(TTY_LAN_MINORS_NUM);
if(!tty_lan_driver)
return -ENOMEM;
tty_lan_driver->owner = THIS_MODULE;
tty_lan_driver->driver_name = "tty_lan";
tty_lan_driver->name = "ttty_lan";
tty_lan_driver->major = TTY_LAN_MAJOR,
tty_lan_driver->minor_start = 0;
tty_lan_driver->type = TTY_DRIVER_TYPE_SERIAL;
tty_lan_driver->subtype = SERIAL_TYPE_NORMAL;
tty_lan_driver->flags = TTY_DRIVER_REAL_RAW;
tty_lan_driver->init_termios = tty_std_termios;
tty_lan_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
tty_set_operations(tty_lan_driver, &tty_lan_ops);
retval = tty_register_driver(tty_lan_driver);
if(retval){
printk(KERN_ERR"Failed to register tty_lan_driver!\n");
put_tty_driver(tty_lan_driver);
return retval;
}
for(i = 0; i < TTY_LAN_MINORS_NUM; i++)
tty_register_device(tty_lan_driver, i, NULL);
return 0;
}
/*static struct tty_lan_serial{
struct tty_struct *tty;
int open_count;
struct semaphore sem;
struct timer_list *timer;
};*/
static int tty_lan_open(struct tty_struct *tty, struct file *filp)
{
int i;
int data_size = 1;
char ch = '1';
if(open_count == 0){
printk("Open OK!\n");
}
for (i = 0; i < data_size; ++i) {
if (tty->count >= N_TTY_BUF_SIZE)
tty_flip_buffer_push(tty);
tty_insert_flip_char(tty, ch, TTY_NORMAL);
}
tty_flip_buffer_push(tty);
return 0;
}
static void tty_lan_close(struct tty_struct *tty, struct file *filp)
{
printk("ClOSE OK!\n");
return;
}
static int tty_lan_write(struct tty_struct *tty, const unsigned char *buffer, int count)
{
int retval = 0;
printk(KERN_DEBUG "%s - \n", __FUNCTION__);
printk("count :%d\n", count);
//for(i = 0; i < count; i++){
printk("user write: %s ", buffer);
//}
printk("\n");
return retval;
}
static int tty_lan_put_char(struct tty_struct *tty, unsigned char ch)
{
printk("put_char :%c\n", ch);
return 0;
}
static int tty_lan_write_room(struct tty_struct *tty)
{
int room;
room = 255;
return room;
}
static void tty_lan_set_termios(struct tty_struct *tty, struct ktermios * old)
{
return ;
}
static void __exit tty_lan_exit(void)
{
int i;
for(i = 0; i < TTY_LAN_MINORS_NUM; i++)
tty_unregister_device(tty_lan_driver, i);
tty_unregister_driver(tty_lan_driver);
}
module_init(tty_lan_init);
module_exit(tty_lan_exit);
-----------------------------------------------------------------------------------------------------------------------------
Makefile:
UNAME = $(shell uname -r)
LINUX_PATH = /lib/modules/$(UNAME)/build
obj-m = tty_lan_ops.o
all:
$(MAKE) -C $(LINUX_PATH) M=$(PWD) modules
clean:
$(MAKE) -C $(LINUX_PATH) M=$(PWD) clean
rm Module.markers modules.order
-------------------------------------------------------------------------------------------------------------------------------
用戶測(cè)試程序:
test.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main(int args, char *argv[])
{
int testdev;
int i, rf = 0;
char buf[15];
memset(buf, '\0', 15);
testdev = open("/dev/ttty_lan0", O_RDWR);
if(testdev == -1){
perror("open\n");
exit(0);
}
if((write(testdev, "111111111\0", 10)) < 0){
perror("Write error!\n");
exit(0);
}
close(testdev);
printf("write finish!\n");
testdev = open("/dev/ttty_lan0", O_RDWR);
rf = read(testdev, buf, 3);
if(rf < 0)
perror("read error\n");
printf("Read: %s\n", buf);
close(testdev);
return 0;
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
作者:
zhy-linux
時(shí)間:
2010-07-28 20:04
用戶程序調(diào)用read肯定會(huì)對(duì)于到對(duì)應(yīng)文件的file_operation中的read函數(shù),read函數(shù)會(huì)看tty_struct中的雙緩沖區(qū)中是否有數(shù)據(jù)(如果是行緩沖就看是否有一行數(shù)據(jù))。如果沒(méi)有,就好被掛載到等待隊(duì)列而阻塞。底層的驅(qū)動(dòng)程序通過(guò)中斷(不一定,可能是輪訓(xùn))收到數(shù)據(jù)后就會(huì)調(diào)用tty_flip_buffer_push或類似的。tty_flip_buffer_push就會(huì)喚醒等待隊(duì)列的所有進(jìn)程,至于進(jìn)程是否成功返回,要看它需要的條件是否滿足
作者:
lanlovehua
時(shí)間:
2010-07-30 15:54
回復(fù)
2#
zhy-linux
謝謝了。我明白了。
作者:
0vk0
時(shí)間:
2010-07-31 22:58
非常感謝,學(xué)習(xí)了
作者:
isup
時(shí)間:
2014-06-16 05:32
道理你明白了,但你程序的問(wèn)題解決了嗎?能讀到數(shù)據(jù)了嗎? 怎么解決的?
歡迎光臨 Chinaunix (http://72891.cn/)
Powered by Discuz! X3.2