Linux内核与驱动学习记录-字符设备驱动程序框架实验

By: Ailson Jack
Date: 2021.08.28
个人博客:http://www.only2fire.com/
本文在我博客的地址是:http://www.only2fire.com/archives/138.html,排版更好,便于学习,也可以去我博客逛逛,兴许有你想要的内容呢。

根据上一章《Linux内核与驱动学习记录-字符设备驱动程序框架》的内容,这一章编写了一个例程,作为实验进行说明,加深对字符设备驱动程序开发步骤的理解。
实验代码如下:

/**
 * @file chrdev_frame.c
 * @author Ailson Jack (jackailson@foxmail.com)
 * @brief
 * @version 1.0
 * @date 2021-07-31
 *
 * @copyright Copyright (c) 2021
 *
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/fs.h>

#define CHRDEV_COUNT        1

struct chrdev_mine
{
    struct class    *class; // 指向这个设备应该注册到的 struct 类的指针
    struct cdev     chrdev; // 字符设备的定义
    dev_t           dev;    // 设备号
};

static struct chrdev_mine chrdev_mine;

static const struct file_operations chrdev_mine_fops;

/* 内核模块加载函数 */
static int __init chrdev_frame_init(void)
{
    printk(KERN_EMERG "[KERN_EMERG] char device Module init!\r\n");
    printk("[default] char device Module init!\r\n");

    // 设备号的动态申请
    alloc_chrdev_region(&chrdev_mine.dev, 0, 1, "chrdev_frame");

    // 字符设备的初始化
    cdev_init(&chrdev_mine.chrdev, &chrdev_mine_fops);

    // 字符设备的注册
    cdev_add(&chrdev_mine.chrdev, chrdev_mine.dev, CHRDEV_COUNT);

    // 设备节点的创建
    chrdev_mine.class = class_create(THIS_MODULE, "led_chrdev");
    device_create(chrdev_mine.class, NULL, chrdev_mine.dev, NULL, "chrdev_frame%d", 0);

    return 0;
}

/* 内核模块卸载函数 */
static void __exit chrdev_frame_exit(void)
{
    printk(KERN_EMERG "[KERN_EMERG] char device Module exit!\r\n");
    printk("[default] char device Module exit!\r\n");

    // 设备节点的销毁
    device_destroy(chrdev_mine.class, chrdev_mine.dev);
    class_destroy(chrdev_mine.class);

    // 字符设备的移除
    cdev_del(&chrdev_mine.chrdev);

    // 设备号的归还
    unregister_chrdev_region(chrdev_mine.dev, CHRDEV_COUNT);
}

module_init(chrdev_frame_init);
module_exit(chrdev_frame_exit);

MODULE_LICENSE("GPL v2"); //表示模块代码接受的软件许可协议
MODULE_AUTHOR("Ailson Jack"); //描述模块的作者信息
MODULE_DESCRIPTION("chrdev frame"); //对模块的简单介绍
MODULE_ALIAS("chrdev_frame"); //给模块设置一个别名

Makefile内容如下:

# 指向编译出来的 linux 内核具体路径
KERNEL_DIR = ../../kernel/ebf-buster-linux/build_image/build

# 定义变量,并且导出变量给子 Makefile 使用
ARCH = arm
CROSS_COMPILE = arm-linux-gnueabihf-
export ARCH CROSS_COMPILE

# obj-m := <模块名>.o: 定义要生成的模块
obj-m := chrdev_frame.o

# 选项 "-C":让 make 工具跳转到 linux 内核目录下读取顶层 Makefile
# "M=" 表示内核模块源码目录
# $(CURDIR): Makefile 默认变量,值为当前目录所在路径
# make modules: 执行 Linux 顶层 Makefile 的伪目标,它实现内核模块的源码读取并编译为.ko文件
all:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules

.PHONY:clean copy

clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean

copy:
	cp *.ko /home/ailsonjack/share/nfs/temp

将实验代码编译之后的chrdev_frame.ko,下载到板子。
加载内核模块,执行命令:

sudo insmod chrdev_frame.ko

在这里插入图片描述
卸载内核模块,执行命令:

sudo rmmod chrdev_frame

在这里插入图片描述
欢迎关注博主的公众号呀:

在这里插入图片描述
如果文中有什么问题欢迎指正,毕竟博主的水平有限。

如果这篇文章对你有帮助,记得点赞和关注博主就行了^_^。

排版更好的内容见我博客的地址:http://www.only2fire.com/archives/138.html

注:转载请注明出处,谢谢!^_^

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackailson

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值