亚洲成精品动漫久久精久,九九在线精品视频播放,黄色成人免费观看,三级成人影院,久碰久,四虎成人欧美精品在永久在线

掃一掃
關(guān)注微信公眾號(hào)

深入淺出 Linux字符設(shè)備驅(qū)動(dòng)程序解析
2007-04-30   網(wǎng)絡(luò)

llseek()函數(shù) 該函數(shù)用來修改文件的當(dāng)前讀寫位置,并將新位置作為(正的)返回值返回,原型為:

loff_t (*llseek) (struct file *, loff_t, int);

poll()函數(shù) poll 方法是poll 和select 這兩個(gè)系統(tǒng)調(diào)用的后端實(shí)現(xiàn),用來查詢?cè)O(shè)備是否可讀或可寫,或是否處于某種特殊狀態(tài),原型為:

unsigned int (*poll) (struct file *, struct poll_table_struct *);

我們將在"設(shè)備的阻塞與非阻塞操作"一節(jié)對(duì)該函數(shù)進(jìn)行更深入的介紹。

 設(shè)備"gobalvar"的驅(qū)動(dòng)程序的這些函數(shù)應(yīng)分別命名為gobalvar_open、 gobalvar_ release、gobalvar_read、gobalvar_write、gobalvar_ioctl,因此設(shè)備"gobalvar"的基本入口點(diǎn)結(jié)構(gòu)變量gobalvar_fops 賦值如下:

struct file_operations gobalvar_fops = {

 read: gobalvar_read,

 write: gobalvar_write,

};

  上述代碼中對(duì)gobalvar_fops的初始化方法并不是標(biāo)準(zhǔn)C所支持的,屬于GNU擴(kuò)展語法。

  完整的globalvar.c文件源代碼如下:

#include <linux/module.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <asm/uaccess.h> 

MODULE_LICENSE("GPL");

#define MAJOR_NUM 254 //主設(shè)備號(hào)

static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);

static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);

//初始化字符設(shè)備驅(qū)動(dòng)的file_operations結(jié)構(gòu)體

struct file_operations globalvar_fops =

{

 read: globalvar_read, write: globalvar_write,

};

static int global_var = 0; //"globalvar"設(shè)備的全局變量

static int __init globalvar_init(void)

{

 int ret;

 //注冊(cè)設(shè)備驅(qū)動(dòng)

 ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);

 if (ret)

 {

  printk("globalvar register failure");

 }

 else

 {

  printk("globalvar register success");

 }

 return ret;

}

static void __exit globalvar_exit(void)

{

 int ret;

 //注銷設(shè)備驅(qū)動(dòng)

 ret = unregister_chrdev(MAJOR_NUM, "globalvar");

 if (ret)

 {

  printk("globalvar unregister failure");

 }

 else

 {

  printk("globalvar unregister success");

 }

}

static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off)

{

 //將global_var從內(nèi)核空間復(fù)制到用戶空間

 if (copy_to_user(buf, &global_var, sizeof(int)))

 {

  return - EFAULT;

 } 

 return sizeof(int);

}

static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off)

{

 //將用戶空間的數(shù)據(jù)復(fù)制到內(nèi)核空間的global_var

 if (copy_from_user(&global_var, buf, sizeof(int)))

 {

  return - EFAULT;

 } 

 return sizeof(int);

}

module_init(globalvar_init);

module_exit(globalvar_exit); 

  運(yùn)行:

gcc -D__KERNEL__ -DMODULE -DLINUX -I /usr/local/src/linux2.4/include -c -o globalvar.o globalvar.c 

  編譯代碼,運(yùn)行:

inmod globalvar.o 

  加載globalvar模塊,再運(yùn)行:

cat /proc/devices 

  發(fā)現(xiàn)其中多出了"254 globalvar"一行,如下圖:

 

  接著我們可以運(yùn)行:

mknod /dev/globalvar c 254 0 

  創(chuàng)建設(shè)備節(jié)點(diǎn),用戶進(jìn)程通過/dev/globalvar這個(gè)路徑就可以訪問到這個(gè)全局變量虛擬設(shè)備了。

我們寫一個(gè)用戶態(tài)的程序globalvartest.c來驗(yàn)證上述設(shè)備:

#include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>

#include <fcntl.h>

main()

{

 int fd, num;

 //打開"/dev/globalvar"

 fd = open("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR);

 if (fd != -1 )

 {

  //初次讀globalvar

  read(fd, &num, sizeof(int));

  printf("The globalvar is %d\n", num);

  //寫globalvar

  printf("Please input the num written to globalvar\n");

  scanf("%d", &num);

  write(fd, &num, sizeof(int));

  //再次讀globalvar

  read(fd, &num, sizeof(int));

  printf("The globalvar is %d\n", num);

  //關(guān)閉"/dev/globalvar"

  close(fd);

 }

 else

 {

  printf("Device open failure\n");

 }

} 

  編譯上述文件:

gcc -o globalvartest.o globalvartest.c 

  運(yùn)行

./globalvartest.o 

  可以發(fā)現(xiàn)"globalvar"設(shè)備可以正確的讀寫。

熱詞搜索:

上一篇:深入淺出 Linux字符設(shè)備驅(qū)動(dòng)程序解析 一
下一篇:在Linux操作系統(tǒng)下如何開啟硬盤DMA 一

分享到: 收藏