Linux 字符设备驱动框架学习记录(三)

发布于:2025-09-04 ⋅ 阅读:(23) ⋅ 点赞:(0)

Linux字符设备驱动开发新框架详解

一、新旧驱动框架对比

传统字符设备驱动流程

  1. 手动分配设备号 (register_chrdev_region)
  2. 实现file_operations结构体
  3. 使用mknod手动创建设备节点

新式驱动框架优势

  • 自动设备号分配:动态申请避免冲突
  • 自动节点创建:通过class_create/device_create实现
  • 更好的设备管理:通过struct cdev规范设备操作 cdev_add 向 Linux 系统添加字符设备…

二、自动设备号申请机制

核心函数实现

/* 动态分配设备号 */
alloc_chrdev_region(&newchrled.devid, 0, 1, LED_NAME);
newchrled.major = MAJOR(newchrled.devid); // 提取主设备号
newchrled.minor = MINOR(newchrled.devid); // 提取次设备号

/* 传统静态分配示例(对比) */
// register_chrdev_region(devid, 1, "led");

设备号管理流程

  1. 调用alloc_chrdev_region申请未使用设备号
  2. 通过MAJOR/MINOR宏分解主次设备号
  3. 驱动卸载时使用unregister_chrdev_region释放

三、自动创建设备节点

现代驱动节点创建

/* 创建设备类 */
newchrled.class = class_create(THIS_MODULE, LED_NAME);

/* 创建设备节点 */
newchrled.dev = device_create(newchrled.class, NULL, 
                            newchrled.devid, NULL, LED_NAME);

工作机制说明

  1. class_create:在/sys/class下创建设备类
  2. device_create:基于udev机制自动创建/dev节点
  3. 无需手动执行mknod命令

四、完整驱动加载流程

初始化函数实现

static int __init newchrled_init(void)
{
    /* 硬件初始化 */
    ioremap(CCM_CCGR1_BASE, 4); // 寄存器地址映射
    
    /* 字符设备注册四部曲 */
    1. alloc_chrdev_region() // 设备号申请
    2. cdev_init()           // 初始化cdev结构体
    3. cdev_add()            // 添加设备到系统
    4. device_create()       // 自动创建设备节点
}

驱动卸载流程

static void __exit newchrled_exit(void)
{
    /* 逆向释放资源 */
    1. device_destroy()      // 删除设备节点
    2. class_destroy()       // 销毁设备类
    3. cdev_del()           // 移除字符设备
    4. unregister_chrdev_region() // 释放设备号
}

五、应用层交互示例

int main(int argc, char *argv[])
{
    // 打开自动创建的设备节点
    int fd = open("/dev/newchrled", O_RDWR);
    
    // 控制指令下发
    unsigned char cmd = 1; // 1:开灯 0:关灯
    write(fd, &cmd, sizeof(cmd));
    
    // 关闭设备
    close(fd);
    return 0;
}

六、测试命令集

# 加载驱动模块
insmod newchrled.ko
# 方法二
modporbe nwechrled.ko

# 查看自动生成的设备节点
ls -l /dev/newchrled

# 查看内核分配的设备号
dmesg | grep newchrled

# 测试LED控制
./ledAPP /dev/newchrled 1  # 开灯
./ledAPP /dev/newchrled 0  # 关灯

七、常见问题排查

  1. 设备节点未生成

    • 检查class_create返回值
    • 确认udev服务正常运行
    • 查看/sys/class下是否生成对应类目录
  2. 权限问题

    sudo chmod 666 /dev/newchrled
    
  3. 设备号冲突

    cat /proc/devices | grep newchrled
    

网站公告

今日签到

点亮在社区的每一天
去签到