历史上的今天
今天是:2024年12月31日(星期二)
2021年12月31日 | 4412 字符类设备的设备号
2021-12-31 来源:eefocus
一、静态申请字符类设备号
字符类设备函数在文件"include/linux/fs.h"中
内核提供了三个函数来注册一组字符设备编号,这三个函数分别是
register_chrdev_region()
alloc_chrdev_region()
register_chrdev()
register_chrdev_region()是提前知道设备的主次设备号,再去申请设备号
alloc_chrdev_region()是动态分配主次设备号
register_chrdev() 是老版本的设备号注册方式,只分配主设备号。从设备号在mknod的时候指定。
宏定义MKDEV的头文件"include/linux/kdev.h"
在kdev_t.h头文件中有一个系列设备号处理的宏命令,用于处理各种设备号相关的数据。本期视频只介绍MKDEV,后面使用了其他宏定义再介绍
include/linux/cdev.h
cdev类型是字符设备描述的结构
其次的设备号必须用"dev_t"类型来描述,高12位为主设备号,低20位为此设备号
编写编译运行
将视频"16_驱动模块传参数"中的文件"module_param.c"改成为"request_cdev_num.c",静态生成设备号
编写,编译
加载运行
使用命令"cat /proc/devices"查看已经被注册的主设备,设备号9没有被注册
insmod /mnt/udisk/request_cdev_num.ko numdev_major=9 numdev_minor=0
使用命令"cat /proc/devices"查看,设备号9被注册为scdev
rmmod request_cdev_num numdev_major=9 numdev_minor=0
register_chrdev_region
#include #include /* define module_param module_param_array header file */ #include /* define perm's head file*/ #include /* char device register head file */ #include /* MKDEV change device ID type */ #include /* define char device struct */ #include #define DEVICE_NAME "scdev" #define DEVICE_MINOR_NUM 2 #define DEV_MAJOR 0 #define DEV_MINOR 0 MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("TOPEET"); int numdev_major = DEV_MAJOR; int numdev_minor = DEV_MINOR; /* input major device ID */ module_param(numdev_major, int, S_IRUSR); /* input minor device ID */ module_param(numdev_minor, int, S_IRUSR); static int hello_init(void) { int ret; dev_t num_dev; printk(KERN_EMERG "numdev_major is %d!n", numdev_major); printk(KERN_EMERG "numdev_minor is %d!n", numdev_minor); if(numdev_major) { num_dev = MKDEV(numdev_major, numdev_minor); ret = register_chrdev_region(num_dev, DEVICE_MINOR_NUM, DEVICE_NAME); } else { printk(KERN_EMERG "numdev_major %d is failedn", numdev_major); } if(ret < 0) { printk(KERN_EMERG "register_chrdev_region req %d is failedn", numdev_major); unregister_chrdev_region(num_dev, DEVICE_MINOR_NUM); return ret; } printk(KERN_EMERG "Hello World enter!n"); return 0; } static void hello_exit(void) { dev_t num_dev = MKDEV(numdev_major, numdev_minor); unregister_chrdev_region(num_dev, DEVICE_MINOR_NUM); printk(KERN_EMERG "Hello World exit!n"); } module_init(hello_init); module_exit(hello_exit); 测试结果: [root@iTOP-4412]# insmod request_cdev_num.ko numdev_major=9 numdev_minor=0 [ 135.652085] numdev_major is 9! [ 135.653710] numdev_minor is 0! [ 135.656810] Hello World enter! [root@iTOP-4412]# cat /proc/devices Character devices: 1 mem 4 ttyS 5 /dev/tty 5 /dev/console 5 /dev/ptmx 9 scdev 10 misc 13 input 21 sg 29 fb 81 video4linux 89 i2c 108 ppp 116 alsa 128 ptm 136 pts 153 rc522_test 166 ttyACM 180 usb 188 ttyUSB 189 usb_device 204 ttySAC 216 rfcomm 243 ump 244 mali 249 mt3326-gps 250 roccat 251 BaseRemoteCtl 252 media 253 ttyGS 254 rtc Block devices: 1 ramdisk 259 blkext 7 loop 8 sd 65 sd 66 sd 67 sd 68 sd 69 sd 70 sd 71 sd 128 sd 129 sd 130 sd 131 sd 132 sd 133 sd 134 sd 135 sd 179 mmc 254 device-mapper [root@iTOP-4412]# rmmod request_cdev_num numdev_major=9 numdev_minor=0 [ 152.245805] Hello World exit! [root@iTOP-4412]# cat /proc/devices Character devices: 1 mem 4 ttyS 5 /dev/tty 5 /dev/console 5 /dev/ptmx 10 misc 13 input 21 sg 29 fb 81 video4linux 89 i2c 108 ppp 116 alsa 128 ptm 136 pts 153 rc522_test 166 ttyACM 180 usb 188 ttyUSB 189 usb_device 204 ttySAC 216 rfcomm 243 ump 244 mali 249 mt3326-gps 250 roccat 251 BaseRemoteCtl 252 media 253 ttyGS 254 rtc Block devices: 1 ramdisk 259 blkext 7 loop 8 sd 65 sd 66 sd 67 sd 68 sd 69 sd 70 sd 71 sd 128 sd 129 sd 130 sd 131 sd 132 sd 133 sd 134 sd 135 sd 179 mmc 254 device-mapper [root@iTOP-4412] 字符设备函数在文件"include/linux/fs.h"中 alloc_chrdev_region()是动态分配主次设备号 宏定义MAJOR提取dev_t数据中的主设备号 将视频"17"中的文件"request_cdev_num.c改写为"request_ascdev_num.c"动态生成字符设备号 编写,编译 加载运行 使用命令"cat /proc/device"查看 动态加载模块之后再查看设备号 修改后的代码: alloc_chrdev_region代码 #include #include /* define module_param module_param_array header file */ #include /* define perm's head file*/ #include /* char device register head file */ #include /* MKDEV change device ID type */ #include /* define char device struct */ #include #define DEVICE_NAME "scdev" #define DEVICE_MINOR_NUM 2 #define DEV_MAJOR 0 #define DEV_MINOR 0 MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("TOPEET"); int numdev_major = DEV_MAJOR; int numdev_minor = DEV_MINOR; /* input major device ID */ module_param(numdev_major, int, S_IRUSR); /* input minor device ID */ module_param(numdev_minor, int, S_IRUSR); static int hello_init(void) { int ret; dev_t num_dev; printk(KERN_EMERG "numdev_major is %d!n", numdev_major); printk(KERN_EMERG "numdev_minor is %d!n", numdev_minor); if(numdev_major) { num_dev = MKDEV(numdev_major, numdev_minor); ret = alloc_chrdev_region(&num_dev, numdev_minor, DEVICE_MINOR_NUM, DEVICE_NAME); } else { ret = alloc_chrdev_region(&num_dev, numdev_minor, DEVICE_MINOR_NUM, DEVICE_NAME); numdev_major = MAJOR(num_dev); printk(KERN_EMERG "register req major number is %dn", numdev_major); } if(ret < 0) { printk(KERN_EMERG "register_chrdev_region req %d is failedn", numdev_major); unregister_chrdev_region(num_dev, DEVICE_MINOR_NUM); return ret; } printk(KERN_EMERG "Hello World enter!n"); return 0; } static void hello_exit(void) { dev_t num_dev = MKDEV(numdev_major, numdev_minor); unregister_chrdev_region(num_dev, DEVICE_MINOR_NUM); printk(KERN_EMERG "Hello World exit!n"); } module_init(hello_init); module_exit(hello_exit); 测试运行后: [root@iTOP-4412]# insmod request_ascdev_num.ko [ 1335.710205] numdev_major is 0! [ 1335.711817] numdev_minor is 0! [ 1335.714861] register req major number is 248 [ 1335.727258] Hello World enter! [root@iTOP-4412]# cat /proc/ 1/ 670/ bus/ mfc/ 11907/ 714/ cgroups misc 12924/ 726/ cmdline modules 12925/ 731/ consoles mounts 12926/ 734/ cpu/ net/ 16/ 744/ cpuinfo pagetypeinfo 二、动态申请字符类设备号
编写编译运行
史海拾趣
|
请各位高手指教,下面的电路能不能成立,不能成立的原因是什么? 电路是我自己画的,个人分析如下,有不对的地方希望大家指正:谢谢~ 1》通电,12V经R1到Q1的C极,经R2加至Q1的B极,Q1饱和导通,C极等于0 此时Q2,Q3,Q4的B极全部为0 Q2为PNP管,此时是导通状态,但对电路没影响 2》按S1, ...… 查看全部问答> |
|
因为资料较多,先整理这一部分,后续还会完善并相继推出ARM11 6410专区,以便大家学习交流。 如果这个帖子对您有帮助,烦请各位顶贴,小弟先谢谢了O(∩_∩)O (一)2440专区: 优秀论坛专区: 第一:http://bbs.2@1ic.com/ ...… 查看全部问答> |
|
#include\"reg52.h\" void send_bit(unsigned char i) { if(i) TXD=1; else TXD=0; TR0=1; while(!TF0); &nb ...… 查看全部问答> |
|
请教各位高手: WINCE启动内核的方式有:bootloader(vivi)和eboot(bsp自带) 现在我想从WINCE42升级到wince50 可是boot这还不了解 请问: 1、bootloader(vivi方式)的跟BSP中自带的eboot有关系吗?也就是说我如果拿开发板的 ...… 查看全部问答> |
|
在移植uCOS-ii的时候,目标板是SAM6300i,MCU是AT91sam9263,现在想写一个测试程序,但是不知道怎么选择时钟频率,哪位高手用过可以指点一下!有时钟设置源码就更好了,谢谢!我的QQ邮箱:759343175@qq.com,谢谢了!急用!… 查看全部问答> |
|
pic16f877a芯片用两个74hc595和一个74hc154芯片设计16*16点阵。请问怎样显示汉字啊。 我用74hc154行扫描,显示的汉字乱作一团,不该亮的点都亮了,请问我应该怎样做啊?! 程序如下:#include<pic.h>#define uint unsigned int#define uchar ...… 查看全部问答> |




