色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > Linux下字符設備驅動

Linux下字符設備驅動 時間:2018-09-27      來源:未知

【linux操作系統(tǒng)驅動分類】

字符設備: 串口,led,按鍵,一次只讀取一個字節(jié)數(shù)據(jù)

塊設備: 一次讀取多個字節(jié)(512字節(jié)), 硬盤,內(nèi)存

網(wǎng)絡設備: 一次讀取多字節(jié)數(shù)據(jù)

本文引用地址://www.einuk.cn/emb/Column/7464.html

ls -l /dev 查看文件屬性

c開頭的叫字符設備文件(char), 串口,Led,I2C

b開頭的叫塊設備文件 (block)

sudo mknod /dev/led c 500 0 //生成一個設備,跟char-read.ko關聯(lián)

制作一個字符設備

【設備號】

設備和驅動是怎么關聯(lián)到一起的?

是通過500 0 關聯(lián)到一起的

500 主設備號(linux系統(tǒng)將一些常用的硬件設備進行了編號,比如串口主設備號4 ...)

0 次設備號(第一個串口 次設備號0, 1 2.....)

設備號能唯一表示一個設備,所以不可以重復

fs4412_led_drv.c 驅動文件

【如何實現(xiàn)一個字符設備驅動】

1 因為字符設備驅動屬于一個內(nèi)核模塊,所以也使用內(nèi)核模塊模板

2 字符設備驅動使用cdev架構

【cdev中重要的宏】

設備編號:

MKDEV(major, minor);

//功能:構造設備編號

major 主設備號, minor 此設備號

執(zhí)行完此函數(shù),返回一個32位的設備號,其中前12位是主設備號,后20位是次設備號

500 1

00011111 0100 000000000000000000001

#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))

MAJOR(dev_t);

//功能:取主設備號

從32位的設備號中取出主設備號

#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))

MINOR(dev_t); //取次設備號

從32位的設備號中取出次設備號

申請設備編號:

int register_chrdev_region(dev_t from, unsigned count, const char *name)

功能:將模塊與主次設備號關聯(lián)

參數(shù):

from,起始設備編號

count,次設備號個數(shù)

name,設備名

返回值:

成功返回0,失敗返回錯誤碼。

釋放設備編號:

void unregister_chrdev_region(dev_t from, unsigned count)

功能:取消模塊與主次設備號關聯(lián)

參數(shù):

from,起始設備編號

count,次設備號個數(shù)

驅動模塊和250 0 設備關聯(lián)

int hello_major = 250;

int hello_minor = 0;

int number_of_devices = 1;

static int __init hello_2_init (void)

{

int result;

dev_t dev = 0;

dev = MKDEV (hello_major, hello_minor);

result = register_chrdev_region (dev, number_of_devices, "hello");

if (result<0) {

printk (KERN_WARNING "hello: can't get major number %d\n", hello_major);

return result;

}

printk (KERN_INFO "Registered character driver\n");

return 0;

}

static void __exit hello_2_exit (void)

{

dev_t devno = MKDEV (hello_major, hello_minor);

unregister_chrdev_region (devno, number_of_devices);

printk (KERN_INFO "Char driver cleaned up\n");

}

module_init (hello_2_init);

module_exit (hello_2_exit);

sudo insmod hello.ko

cat /proc/devices | grep hello //linux會將注冊好的設備添加進/proc/devices文件中

sudo rmmod hello

struct cdev{

const struct file_operations *ops; //字符設備驅動結構體

dev_t dev; //主次設備號

unsigned int count; //設備數(shù)量

};

初始化字符設備:

void cdev_init(struct cdev *cdev, const struct file_operations *fops);

添加設備:

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

刪除設備:

void cdev_del(struct cdev *p)

下面的代碼是完成一個簡單的字符設備驅動程序,此程序沒有實際功能,知識完成了open, close函數(shù)

//定義主設備號,次設備號

#include

#include

#include

#include

#include

#include

int hello_major = 250; //主設備號

int hello_minor = 0; //次設備號

struct cdev cdev; //c -> char dev->device 字符設備的主要結構體

static int hello_open (struct inode *inode, struct file *file) //應用成執(zhí)行open函數(shù)會調(diào)用到它

{

printk ("11111111111111111111111111 device opened\n");

return 0;

}

struct file_operations hello_fops = { //將hello_open hello_close 與 open , close 關聯(lián)

.owner = THIS_MODULE,

.open = hello_open,

};

static void char_reg_setup_cdev (void) //完成cdev結構體的初始化

{

dev_t devno;

devno = MKDEV (hello_major, hello_minor); //MKDEV宏能將主次設備號放在一個32位的變量中,變成一個編號

cdev_init (&cdev, &hello_fops); //將hello_fops 放到cdev結構體中

cdev.owner = THIS_MODULE;

cdev_add (&cdev, devno , 1); //將設備號再放到cdev結構體中, 1代表 子設備數(shù)量1個

}

static int __init hello_init (void) //注冊模塊時要執(zhí)行此函數(shù)

{

int result;

dev_t devno;

devno = MKDEV (hello_major, hello_minor);

result = register_chrdev_region (devno, 1, "hello");

char_reg_setup_cdev ();

printk ("char device registered\n");

return 0;

}

static void __exit hello_exit (void)

{

dev_t devno = MKDEV (hello_major, hello_minor);

cdev_del (&cdev); //刪除cdev

unregister_chrdev_region (devno, 1); //刪除250, 0號設備

}

module_init (hello_init);

module_exit (hello_exit);

完成一個應用程序,測試驅動

#include

#include

#include

#include

#include

#include

#include

int main()

{

int fd;

fd = open("/dev/hello", O_RDWR);

if(fd > 0)

{

printf("file open success\n");

}

else

{

printf("file open failed\n");

}

}

制作字符設備的過程

1 制作驅動模塊

1)將驅動代碼 寫到hello.c中

2)make (會生成hello.ko文件)

2 sudo insmod hello.ko

3 sudo mknod /dev/hello c 250 0 //生成一個設備,跟char-read.ko關聯(lián)

4 gcc -o test test.c //將應用層的test.c 編譯生成test可執(zhí)行文件

5 sudo ./test

6 dmesg

上一篇:Java對象構造和初始化過程

下一篇:樹的存儲結構

熱點文章推薦
華清學員就業(yè)榜單
高薪學員經(jīng)驗分享
熱點新聞推薦
前臺專線:010-82525158 企業(yè)培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網(wǎng)安備11010802025203號

回到頂部

主站蜘蛛池模板: 国产欧美日韩在线观看视频 | 亚洲av无码成人精品国产 | 中文字幕日产A片在线看 | 粗长挺进新婚人妻小怡 | 黄在线观看 | 野花社区www官网在线观看 | 久久久久亚洲AV无码麻豆 | 无码一区二区三区免费 | 精品无码久久久久久久久 | 亚洲国产日韩欧美高清片 | 日本熟妇牲交视频 | 三上悠亚av影院在线看 | 久久综合给久久狠狠97色 | 国产成年人视频网站 | 爱爱免费视频 | 久久久久久人妻精品一区二区三区 | 日日夜夜精彩视频 | 日本一道综合一本88在线 | 国内揄拍国内精品人妻浪潮AV | 摸丰满大乳奶水www免费 | 精品无码国产污污污免费网站国产 | 巨胸喷奶水视频WWW网站 | 水蜜桃无码视频在线观看 | 国产又黄又爽又色的免费视频 | 男人把女人桶到爽免费应用 | 亚洲AV成人一二三区观看 | 亚洲AV无码传区国产乱码O | 人妻中文字幕乱人伦在线 | 国语精品一区二区三区 | 欧美高潮喷水高潮集合 | 亚洲国产精品日韩AV专区 | 国产原创三级 | 亚洲精品亚洲人成在线观看麻豆 | 欧美亚洲日产综合新一区 | 337P日本大胆欧洲亚洲色噜噜 | 大片免免费观看视频播放器在线观看 | 熟女俱乐部五十路二区AV | 法国精品熟妇多毛bhd | 婷婷亚洲精品久久无码一区二区三区 | 亚洲AV 日韩 国产 有码 | 国产成人a在线观看视频 |