上層應用通過設備節點訪問對應的設備。
部分驅動要和上層通信,都需要生成設備節點,上層應用通過一套標準的接口函數調用設備節點就可以控制底層以及和底層通信。本文就給大家介紹最簡單易用的雜項設備節點如何生成。
在虛擬機的 Ubuntu 系統上,如下圖所示,使用命令“cat /proc/misc”,可以查看到 PC機 Ubuntu 系統的雜項設備。
Linux系統中主設備號只有 256 個,設備又非常多,所以引入了子設備號。其中雜項設備的主設備號是 10,在任何 Linux 系統中它都是固定的。
生成設備節點流程:
1、添加頭文件;
2、定義hello_open、hello_ioctl、hello_release等函數;
3、定義file_operations結構體hello_ops;
4、定義miscdevice結構體hello_dev;
5、分別在hello_probe、hello_release函數中調用函數misc_register、misc_deregister註冊雜項設備節點。
如下,是完整的生成雜項設備節點的代碼:devicenode_linux_module.c
#include <linux/init.h>
#include <linux/module.h>
/*驅動註冊的頭文件,包含驅動的結構體和註冊和卸載的函數*/
#include <linux/platform_device.h>
/*註冊雜項設備頭文件*/
#include <linux/miscdevice.h>
/*註冊設備節點的文件結構體*/
#include <linux/fs.h>
#define DRIVER_NAME "hello_ctl"
#define DEVICE_NAME "hello_ctl123"
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET");
static long hello_ioctl( struct file *files, unsigned int cmd, unsigned long arg){
printk("cmd is %d,arg is %d\n",cmd,arg);
return 0;
}
static int hello_release(struct inode *inode, struct file *file){
printk(KERN_EMERG "hello release\n");
return 0;
}
static int hello_open(struct inode *inode, struct file *file){
printk(KERN_EMERG "hello open\n");
return 0;
}
static struct file_operations hello_ops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.unlocked_ioctl = hello_ioctl,
};
static struct miscdevice hello_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &hello_ops,
};
static int hello_probe(struct platform_device *pdv){
printk(KERN_EMERG "\tinitialized\n");
misc_register(&hello_dev);
return 0;
}
static int hello_remove(struct platform_device *pdv){
printk(KERN_EMERG "\tremove\n");
misc_deregister(&hello_dev);
return 0;
}
static void hello_shutdown(struct platform_device *pdv){
;
}
static int hello_suspend(struct platform_device *pdv,pm_message_t pmt){
return 0;
}
static int hello_resume(struct platform_device *pdv){
return 0;
}
struct platform_driver hello_driver = {
.probe = hello_probe,
.remove = hello_remove,
.shutdown = hello_shutdown,
.suspend = hello_suspend,
.resume = hello_resume,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
}
};
static int hello_init(void)
{
int DriverState;
printk(KERN_EMERG "HELLO WORLD enter!\n");
DriverState = platform_driver_register(&hello_driver);
printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
return 0;
}
static void hello_exit(void)
{
printk(KERN_EMERG "HELLO WORLD exit!\n");
platform_driver_unregister(&hello_driver);
}
module_init(hello_init);
module_exit(hello_exit);
Makefile文件如下:
在 Ubuntu 中的目錄“/home/topeet”下新建“devicenode_linux_module”目錄,拷貝驅動文件“devicenode_linux_module.c”和編譯文件“Makefile”到新建目錄中,如下圖所示。
如下圖所示,使用命令“make”,編譯生成模塊“devicenode_linux_module.ko”文件。
啓動開發板,拷貝“devicenode_linux_module.ko”到 U 盤,將 U 盤插入開發板,加載驅動文件“devicenode_linux_module.ko”,如下圖所示。
如下圖所示,加載之後使用命令“ls /dev”,可以看到新生成了設備節點 hello_ctl123,也就是設備節點和驅動名以及設備名沒有一關係,不過最好設備節點的命名便於識別。
如下圖所示,使用命令“rmmod devicenode_linux_module”卸載驅動。
如下圖所示,使用命令“ls /dev”,發現設備節點 hello_ctl123 已經去掉了。
另注:相關Linux命令
查看總線: ls /sys/bus/
查看設備:cat /proc/devices/
查看設備節點:ls /dev/