【无标题】

字符设备代码
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>

#define CHRDEVBASE_MAJOR 200 /* 主设备号 /
#define CHRDEVBASE_NAME “chrdevbase” /
设备名 */

static char readbuf[100]; /* 读缓冲区 /
static char writebuf[100]; /
写缓冲区 */
static char kerneldata[] = {“kernel data!”};

/*
*@description : 打开设备
*@param – inode : 传递给驱动的 inode
*@param -
filp : 设备文件,file结构体有个叫做private_data的成员变量
*一般在open的时候将private_data指向设备结构体。
*@ return : 0 成功;其他失败
*/
static int chrdevbase_open(struct inode *inode, struct file *filp)

{
printk(“chrdevbase open!\n”);
return 0;
}

/*
*@description : 从设备读取数据
*@param -filp : 要打开的设备文件(文件描述符)
*@param - buf : 返回给用户空间的数据缓冲区
*@param - cnt : 要读取的数据长度
*@param - offt : 相对于文件首地址的偏移
*@ return : 读取的字节数,如果为负值,表示读取失败
*/
static ssize_t chrdevbase_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{
int retvalue = 0;

/* 向用户空间发送数据 */
int32_t size = sizeof(kerneldata);
memcpy(readbuf, kerneldata, size);
retvalue = copy_to_user(buf, readbuf, cnt);
if (retvalue == 0)
{
	printk("kernel senddata ok!\n");
}
else
{
	printk("kernel senddata failed!\n");
}

printk("chrdevbase read!\n");
return 0;

}

/*

  • @description : 向设备写数据

  • @param - filp : 设备文件,表示打开的文件描述符

  • @param - buf : 要写给设备写入的数据

  • @param - cnt : 要写入的数据长度

  • @param - offt : 相对于文件首地址的偏移

  • @return : 写入的字节数,如果为负值,表示写入失败
    */
    static ssize_t chrdevbase_write(struct file *filp,

     						const char __user *buf,
    
     						size_t cnt, loff_t *offt)
    

{
int retvalue = 0;
/* 接收用户空间传递给内核的数据并且打印出来 */
retvalue = copy_from_user(writebuf, buf, cnt);
if (retvalue == 0)
{
printk(“kernel recevdata:%s\n”, writebuf);
}
else
{
printk(“kernel recevdata failed!\n”);
}

printk("chrdevbase write!\n");
return 0;

}

/*

  • @description : 关闭/释放设备
  • @param - filp : 要关闭的设备文件(文件描述符)
  • @return : 0 成功;其他失败
    */

static int chrdevbase_release(struct inode *inode,

						  struct file *filp)

{
printk(“chrdevbase release!\n”);
return 0;
}

/*

  • 设备操作函数结构体
    */

static struct file_operations chrdevbase_fops = {
.owner = THIS_MODULE,
.open = chrdevbase_open,
.read = chrdevbase_read,
.write = chrdevbase_write,
.release = chrdevbase_release,
};

/*

  • @description : 驱动入口函数

  • @param : 无

  • @return : 0 成功;其他失败
    */
    static int __init chrdevbase_init(void)
    {
    int retvalue = 0;

    /* 注册字符设备驱动 */
    retvalue = register_chrdev(CHRDEVBASE_MAJOR, CHRDEVBASE_NAME,
    &chrdevbase_fops);
    if (retvalue < 0)
    {
    printk(“chrdevbase driver register failed\n”);
    }
    printk(“chrdevbase_init()\n”);
    return 0;
    }

/*

  • @description : 驱动出口函数
  • @param : 无
  • @return : 无
    /
    static void __exit chrdevbase_exit(void)
    {
    /
    注销字符设备驱动 */
    unregister_chrdev(CHRDEVBASE_MAJOR, CHRDEVBASE_NAME);
    printk(“chrdevbase_exit()\n”);
    }

/*

  • 将上面两个函数指定为驱动的入口和出口函数
    */
    module_init(chrdevbase_init);
    module_exit(chrdevbase_exit);

/*

  • LICENSE和作者信息
    */
    MODULE_LICENSE(“GPL”);
    MODULE_AUTHOR(“OttoBryant”);

makefile:

To build *.ko

KERNELDIR:=/data/LinuxDrivers/linux-5.15.43
CURRENT_PATH:=$(shell pwd)
obj-m:= chrdev.o

build: kernel_modules

kernel_modules:
$(MAKE) -C ( K E R N E L D I R ) M = (KERNELDIR) M= (KERNELDIR)M=(CURRENT_PATH) modules
clean:
$(MAKE) -C ( K E R N E L D I R ) M = (KERNELDIR) M= (KERNELDIR)M=(CURRENT_PATH) clean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值