当前位置: 首页 > news >正文

正点原子RK3568学习日志11-申请字符设备号

1.申请字符设备号

驱动编译成驱动模块ko  运行驱动编译成模块insmod

字符设备是指在I/O传输过程中以字符为单位进行传输的设备,可以使用与普通文件相同的文件操作命令(打开、关闭、读、写等)对字符设备进行操作,是Linux驱动中最基本的一类设备驱动,例如最常见的LED、按键、IIC、SPI,LCD等都属于字符设备的范畴。

要想对字符设备进行操作,需要通过设备号来对相应的设备进行查找

主设备号用来表示一个特定的驱动,次设备号用来管理下面的设备

/include/linux/fs.h”文件

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

alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name)动态

/include/linux/types.h” 文件——申请的设备号类型为dev_t

#define MINORBITS   20   /*次设备号位数*/  
#define MINORMASK   ((1U << MINORBITS) - 1)  /*次设备号掩码*/  #define MAJOR(dev)  ((unsigned int) ((dev) >> MINORBITS))/*dev右移20位得到主设备号*/  
#define MINOR(dev)  ((unsigned int) ((dev) & MINORMASK))  /*与次设备掩码与,得到次设备号*/ 
#define MKDEV(ma,mi)    (((ma) << MINORBITS) | (mi))/*MKDEV宏将主设备号(ma)左移20位,然后与次设备号(mi)相与,得到设备号*/

dev_t是一个无符号的32位整形类型。其中高12位表示主设备号,低20位表示次设备号

静态申请设备号时需要将指定的主设备号和从设备号通过MKDEV(ma,mi)宏进行设备号的转换

动态申请设备号时可以用MAJOR(dev) 和MINOR(dev)宏将动态申请的设备号转化为主设备号和从设备号

内核源码/include/uapi/asm-generic/int-ll64.h”文件——u32类型

静态申请设备号:

extern int register_chrdev_region(dev_t, unsigned, const char *);   

 自定义的dev_t类型设备号,申请设备的数量,申请的设备名称

 申请成功返回0,申请失败返回负数

动态申请设备号

extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);

会将申请完成的设备号保存在dev变量中, 次设备号可申请的最小值, 申请设备的数量, 

申请的设备名称

申请成功返回0,申请失败返回负数

static int major = 0;  //静态主设备号major
static int minor = 0;  //静态次设备号minormodule_param(major, int, S_IRUGO);  //驱动模块传参,主设备号major   全部只读
module_param(minor, int, S_IRUGO);  //驱动模块传参,次设备号minor   全部只读
static dev_t dev_num;   //定义32位的变量dev_num,用于存放设备号
dev_num = MKDEV(major, minor);  //组成生成设备号
major = MAJOR(dev_num);  //获取主设备号
minor = MINOR(dev_num);  //获取次设备号
unregister_chrdev_region(dev_num, 1); //释放设备号

2.实验:04_dev_t 申请字符设备号

dev_t.c     Makefile

dev_t.c 

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>static int major = 0;  //静态主设备号major
static int minor = 0;  //静态次设备号minormodule_param(major, int, S_IRUGO);  //驱动模块传参,主设备号major   全部只读
module_param(minor, int, S_IRUGO);  //驱动模块传参,次设备号minor   全部只读static dev_t dev_num;   //定义32位的变量dev_num,用于存放设备号static int __init dev_t_init(void)
{int ret; //判断函数返回值if(major)  //传递成功{dev_num = MKDEV(major, minor);  //组成生成设备号printk("major = %d\n", major);  //打印设备号printk("minor = %d\n", minor);    //静态申请设备号ret = register_chrdev_region(dev_num, 1, "chrdev_name");if(ret < 0) //申请失败{printk("register_chrdev_region is error\n");}printk("register_chrdev_region is ok\n");       }else{//动态申请设备号ret = alloc_chrdev_region(&dev_num, 0, 1, "chrdev_name");if(ret < 0) //申请失败{printk("alloc_chrdev_region is error\n");}printk("alloc_chrdev_region is ok\n");       major = MAJOR(dev_num);  //获取主设备号minor = MINOR(dev_num);  //获取次设备号printk("major = %d\n", major);  //打印设备号printk("minor = %d\n", minor); }return 0;
}
static void __exit dev_t_exit(void)
{unregister_chrdev_region(dev_num, 1); //释放设备号printk("module exit. \n");}
module_init(dev_t_init);
module_exit(dev_t_exit);
MODULE_LICENSE("GPL v2");   //声明模块许可证
MODULE_AUTHOR("AFANFAN");   //声明模块作者

Makefile

export ARCH=arm64#设置平台架构
export CROSS_COMPILE=/opt/atk-dlrk3568-5_10_sdk-toolchain/bin/aarch64-buildroot-linux-gnu-#交叉编译器前缀
obj-m += dev_t.o    #此处要和你的驱动源文件同名
KDIR :=/home/alientek/rk3568_linux5.10_sdk/kernel    #这里是你的内核目录                                                                                                                            
PWD ?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modules    #make操作
clean:make -C $(KDIR) M=$(PWD) clean    #make clean操作

驱动编译成驱动模块ko 

使用命令“make”进行驱动的编译,编译完生成dev_t.ko目标文件

运行驱动编译成模块insmod

开发板启动之后,

如果在进行驱动模块加载时传入了major主设备号,则通过静态的方式进行设备号的申请,注意冲突

#静态设备号申请
insmod dev_t.ko major=200 minor=0

如果不传入任何参数进行驱动模块加载,则通过动态的方式进行设备号申请

#动态设备号申请
insmod dev_t.ko

注册设备号的查看  cat /proc/devices

对驱动进行卸载   rmmod cdev.ko

3.问题

1.vscode :

        添加头文件 
            "includePath": [
                "${workspaceFolder}/**",
                "/home/alientek/rk3568_linux5.10_sdk/kernel/include",
                "/home/alientek/rk3568_linux5.10_sdk/kernel/arch/arm64/include",
                "/home/alientek/rk3568_linux5.10_sdk/kernel/arch/arm64/include/generated"                           
            ],

        修改键盘快捷方式
Preferences: Open KeyPreferences: Open Keyboard Shortcuts  更改vscode键盘快捷键


2.

http://www.dtcms.com/a/507190.html

相关文章:

  • k8s device plugin
  • 征二级网站建设意见 通知室内装修设计企业
  • 【Maven】Maven设置国内源
  • 软件设计师知识点总结:程序设计语言基础
  • 让Pycharm的Terminal(终端)进入创建好的虚拟环境
  • [css] 图片阴影 filter: drop-shadow
  • 第三章深度学习---核心库TensorFlow 和 PyTorch 实操指南(三)
  • BugKu Web渗透之 cookiesWEB
  • 【研究生随笔】Pytorch中的线性代数(微分)
  • 专业品牌设计网站建设网站建设实训心得
  • 从暴力到最优——力扣88.合并两个有序数组
  • C语言——回调函数的典型示例(分析详解)
  • 雷州网站建设公司网站备案半身照
  • 【AI 风向标】gpt-oss20b 模型测试与评估报告(2025-08-21)
  • Java MyBatis(二)--- 多表查询,# 和 $的区别,SQL注入,数据库连接池,动态SQL
  • 深圳小企业网站建设vs做网站怎么放视频
  • 企业 做网站云虚拟主机搭建网站
  • PHP实现企业微信 会话存档功能
  • centos 7.9 编译安装 freeswitch 1.10.12
  • FT32A103RDAT3是什么芯片?车规级32位国产MCU可替代STM32F103RD
  • uni-app从后端返回的富文本中的视频截取一帧为封面
  • 若依前后端分离版学习笔记(二十)——实现滑块验证码(vue3)
  • Linux 服务器安全巡检与加固:从命令到实操(CentOS/Ubuntu 通用)
  • 网站如何让百度收录官网seo是什么意思
  • STM32U5G9J-DK2开发板获取RAM占用
  • 从架构到运营:AIOps与O-AA™ 如何实现智能化企业运营
  • 徐州手机网站定制公司哪家好西安大型网站制作
  • 【Day 80】Linux-NAS 和 SAN 存储
  • C++可变参数模板
  • Python下载实战技巧的技术文章大纲