亚洲精品一二区_国产黄色片网站_99久久久成人国产精品_蜜臀网_国产精品一区二区三区免费_成人av中文字幕_91精品国产欧美一区二区成人

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

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

【linux操作系統驅動分類】

字符設備: 串口,led,按鍵,一次只讀取一個字節數據

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

網絡設備: 一次讀取多字節數據

本文引用地址://m.gxqdgs.com/emb/Column/7464.html

ls -l /dev 查看文件屬性

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

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

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

制作一個字符設備

【設備號】

設備和驅動是怎么關聯到一起的?

是通過500 0 關聯到一起的

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

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

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

fs4412_led_drv.c 驅動文件

【如何實現一個字符設備驅動】

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

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

【cdev中重要的宏】

設備編號:

MKDEV(major, minor);

//功能:構造設備編號

major 主設備號, minor 此設備號

執行完此函數,返回一個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)

功能:將模塊與主次設備號關聯

參數:

from,起始設備編號

count,次設備號個數

name,設備名

返回值:

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

釋放設備編號:

void unregister_chrdev_region(dev_t from, unsigned count)

功能:取消模塊與主次設備號關聯

參數:

from,起始設備編號

count,次設備號個數

驅動模塊和250 0 設備關聯

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; //設備數量

};

初始化字符設備:

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函數

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

#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) //應用成執行open函數會調用到它

{

printk ("11111111111111111111111111 device opened\n");

return 0;

}

struct file_operations hello_fops = { //將hello_open hello_close 與 open , close 關聯

.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代表 子設備數量1個

}

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

{

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關聯

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

5 sudo ./test

6 dmesg

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

下一篇:樹的存儲結構

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

回到頂部

主站蜘蛛池模板: 日本黄页网站在线观看 | 两个人在线观看视频www | 一级特黄aaa大片免色 | 国产午夜人成在线视频麻豆 | 亚洲免费观看视频 | 日韩中文字幕在线免费观看 | 在线观看jizz | 妹妹天堂| 激情五月婷婷色 | 日本高清中文字幕在线观穿线视频 | 国产趴着打光屁股sp视频网站 | 无遮挡中文毛片免费观看 | 欧美高清在线不卡免费观看 | 久久桃花 | 国产调教视频 | 亚洲国产欧美在线人成aaa | 久草新在线 | 欧美无玛| 欧美jizzjizz在线播放 | 国产精品国产三级国产普通话a | 久久女人 | 欧洲女同免费视频网站 | 日本 国产 欧美 | 亚洲国产高清人在线 | 欧美影院久久 | 国产jjzz | 久久porn| 好吊色视频988gao在线观看 | 精品一区二区三区在线观看视频 | 国产极品尤物 | 黄色网址免费看 | 在线观看国产精美视频 | 99国产精品视频久久久久 | 欧洲一级黄色 | 99精品一区二区免费视频 | 99re热这里只有精品18 | 欧美网站在线观看 | 青青青草影院 | 狼人久久尹人香蕉尹人 | 欧美3区| 激情图片视频小说 |