亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 4640 | 回復: 4
打印 上一主題 下一主題

tty設備驅動無read函數(shù) [復制鏈接]

論壇徽章:
0
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2010-07-28 11:49 |只看該作者 |倒序瀏覽
最近在看tty設備驅動,它的驅動操作里沒有read函數(shù),但是可以通過tty_flip_buffer_push函數(shù)將數(shù)據(jù)存到緩沖區(qū)。而用戶要讀tty設備緩沖區(qū)的數(shù)據(jù)可以在用戶態(tài)下使用read系統(tǒng)調(diào)用,但是我使用read系統(tǒng)調(diào)用后,程序就不運行了,也沒有結束,就是停在哪里不動了。
請問這是什么原因。

我的系統(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

-------------------------------------------------------------------------------------------------------------------------------

用戶測試程序:
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;
}

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

論壇徽章:
0
2 [報告]
發(fā)表于 2010-07-28 20:04 |只看該作者
用戶程序調(diào)用read肯定會對于到對應文件的file_operation中的read函數(shù),read函數(shù)會看tty_struct中的雙緩沖區(qū)中是否有數(shù)據(jù)(如果是行緩沖就看是否有一行數(shù)據(jù))。如果沒有,就好被掛載到等待隊列而阻塞。底層的驅動程序通過中斷(不一定,可能是輪訓)收到數(shù)據(jù)后就會調(diào)用tty_flip_buffer_push或類似的。tty_flip_buffer_push就會喚醒等待隊列的所有進程,至于進程是否成功返回,要看它需要的條件是否滿足

論壇徽章:
0
3 [報告]
發(fā)表于 2010-07-30 15:54 |只看該作者
回復 2# zhy-linux


   謝謝了。我明白了。

論壇徽章:
0
4 [報告]
發(fā)表于 2010-07-31 22:58 |只看該作者
非常感謝,學習了

論壇徽章:
0
5 [報告]
發(fā)表于 2014-06-16 05:32 |只看該作者
道理你明白了,但你程序的問題解決了嗎?能讀到數(shù)據(jù)了嗎? 怎么解決的?
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP