從零開始寫linux字符設(shè)備驅(qū)動(dòng)程序(二)(基于友善之臂tiny4412開發(fā)板)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
上節(jié),我們講解了如何寫第一個(gè)Linux字符設(shè)備驅(qū)動(dòng)程序,這節(jié),我們將代碼做一下修改。
如下:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
dev_t dev_no ;
static int __init cdev_test_init(void)
{
int ret ;
printk("HELLO KERNEL FOR CDEV!\n");
//1、創(chuàng)建設(shè)備號(hào)-->第一個(gè)是主設(shè)備號(hào),第二個(gè)是次設(shè)備號(hào)
//dev_no = MKDEV(222,2);
//2、注冊(cè)設(shè)備號(hào)
//count表示要分配多少個(gè)設(shè)備號(hào)
//ret = register_chrdev_region(dev_no,1,"my_dev");
//申請(qǐng)?jiān)O(shè)備號(hào)
ret = alloc_chrdev_region(&dev_no,1,1,"my_dev");
if(ret < 0){
goto register_error ;
}
register_error:
return 0 ;
}
static int __exit cdev_test_exit(void)
{
//注銷驅(qū)動(dòng)-->后面寫1表示從dev_no開始連續(xù)一個(gè)
unregister_chrdev_region(dev_no,1);
return 0 ;
}
module_init(cdev_test_init);
module_exit(cdev_test_exit);
MODULE_LICENSE("GPL");
然后重新編譯,將內(nèi)核鏡像下載到開發(fā)板:
cat /proc/devices查看
我們看到了,my_dev對(duì)應(yīng)的主設(shè)備號(hào)是248了,上一個(gè)驅(qū)動(dòng)是222,為什么這里就是248了,而不是222了呢?
因?yàn)椋谶@里,我們調(diào)用了#include <linux/fs.h>這個(gè)頭文件下的這個(gè)函數(shù):
extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
這個(gè)函數(shù)的作用就是,由內(nèi)核給我們分配一個(gè)設(shè)備號(hào),這個(gè)設(shè)備號(hào)是內(nèi)核自動(dòng)分配的,就不需要我們?nèi)ナ褂肕KDEV這個(gè)宏來(lái)進(jìn)行手動(dòng)分配了。這也可以稱作是字符設(shè)備的動(dòng)態(tài)分配方式。
函數(shù)原型如下:
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
const char *name)
{
struct char_device_struct *cd;
//調(diào)用__register_chrdev_region來(lái)注冊(cè)字符設(shè)備
cd = __register_chrdev_region(0, baseminor, count, name);
//注冊(cè)失敗返回PTR_ERR(cd)錯(cuò)誤碼。
if (IS_ERR(cd))
return PTR_ERR(cd);
//這里一樣的是調(diào)用MKDEV分配設(shè)備號(hào)
*dev = MKDEV(cd->major, cd->baseminor);
return 0;
}
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!