Linux驱动入门实验班—项目1—01_hello_drv

一、专栏介绍

本专栏内容是记录博主在学习深圳百问网科技有限公司韦东山老师开设的《驱动入门实验班》课程过程中,博主编写、调试、运行在开发板上的课程中涉及的所有驱动试验项目,连载。

课程链接(免费):【Linux驱动入门实验班-B站】 https://www.bilibili.com/video/BV1XK411D7wK/?p=14&share_source=copy_web&vd_source=1bef10f645d499b8efc7d90d0814f719

官方代码仓库(开源):https://e.coding.net/weidongshan/linux_course/linux_basic_develop.git

硬件:100ASK_IMX6ULL_PRO开发板,芯片:NXP IMX6ULL,架构:Cortex-A7 单核。有兴趣可搜索百问网官方网站获取详情。

版权:本篇中代码版权属于韦东山老师。

二、 项目介绍

简单字符设备char_device驱动程序:

  • 构造file_operations结构体

    • 在里面填充open/read/write/ioctl成员

  • 注册file_operations结构体

    • int major = register_chrdev(0, "name", &fops);

  • 入口函数:调用register_chrdev

  • 出口函数:调用unregister_chrdev

  • 辅助信息:

    • mknod命令创建设备文件,后续用代码实现

三、代码

3.1 驱动代码(内核态)

/*
*Copyright (c)2024, CSDN
*All Rights Reserved.
*文件名称: hello_drv.c
*作者:孙家明
*完成日期: 2024.3.3日
*版本号:V1.0
*项目描述:创建一个简单字符设备文件,内核态下实现对该设备的典型访问操作:open/close/read/write,用户态下编写测试代码实现前述操作。
*项目输出: open/close/read/write每个函数被调用时都会有printk打印。
*/
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/uio.h>

#include <linux/uaccess.h>
#include <linux/module.h>
/*主设备号*/
static unsigned int g_hello_major = 0;

static ssize_t hello_read (struct file *filp, char __user *buf, size_t size, loff_t *offset)
{
	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
	return size;
}

static ssize_t hello_write (struct file *filp, const char __user *buf, size_t size, loff_t *offset)
{
	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
	return size;
}

static int hello_open (struct inode *node, struct file *filp)
{
	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
	return 0;
}
static int hello_release (struct inode *node, struct file *flip)
{
	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
	return 0;
}

/* 1. create file operations */
static const struct file_operations hello_drv = {
	.owner		= THIS_MODULE,
	.read		= hello_read,
	.write		= hello_write,
	.open		= hello_open,
	.release    = hello_release
};

/* 2. register chrdey */
/* 3. entry function */
static int __init hello_init(void)
{
	g_hello_major = register_chrdev(0, "100ask_hello", &hello_drv);
	return 0;
}

/* 4. exit function */
static void __exit hello_exit(void)
{
	unregister_chrdev(g_hello_major , "100ask_hello");
	return;
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL v2");

3.2 驱动测试代码(用户态)

/*
*Copyright (c)2024, CSDN
*All Rights Reserved.
*文件名称: hello_drv_test.c
*作者:孙家明
*完成日期: 2024.3.3日
*版本号:V1.0
*项目描述:创建一个简单字符设备文件,内核态下实现对该设备的典型访问操作:open/close/read/write,用户态下编写测试代码实现前述操作。
*项目输出: open/close/read/write每个函数被调用时都会有printk打印。
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
/*
*写 ./hello_test /dev/xxx hello_world
*读 ./hello_test /dev/xxx
*/
#define BUF_LEN 100

int main(int argc, char *argv[])
{
	int fd = -1;
	int ret = 0;
	char buf[BUF_LEN] = {0};

	if(argc < 2)
	{
		printf("Usage: ");
		printf("%s <dev> [string]\n", argv[0]);
		return -1;
	}
	/*open*/
	fd = open(argv[1], O_RDWR);
	if(0 > fd)
	{
		printf("cannot open file: %s, err!\n", argv[1]);
		return -1;
	}

	if(argc == 3)
	{
		/*write*/
		ret = write(fd, argv[2], strlen(argv[2])+1);
		if(0 > ret)
		{
			printf("cannot write file: %s, err!\n", argv[1]);
			return -1;
		}
	}
	else
	{
		/*read*/
		ret = read(fd, buf, BUF_LEN);
		if(0 > ret)
		{
			printf("cannot read file: %s, err!\n", argv[1]);
			return -1;
		}
		buf[BUF_LEN-1] = '0';
	}

	/*close*/
	close(fd);

	return 0;
}

四、试验步骤及结果

/*加载模块*/
[root@100ask:/mnt/dri_labclass/01_hello_drv]# insmod hello_drv.ko
[  830.574370] hello_drv: loading out-of-tree module taints kernel.

/*显示模块*/
[root@100ask:/mnt/dri_labclass/01_hello_drv]# lsmod
Module                  Size  Used by
hello_drv               2152  0

/*创建设备文件*/
[root@100ask:/mnt/dri_labclass/01_hello_drv]# mknod /dev/hellodev c 240 0
[root@100ask:/mnt/dri_labclass/01_hello_drv]# ll /dev/hellodev
crw-r--r-- 1 root root 240, 0 Jan  1 00:40 /dev/hellodev

/*写操作*/
[root@100ask:/mnt/dri_labclass/01_hello_drv]# ./hello_drv_test /dev/hellodev sjmsjm
[ 2862.371308] /home/book/nfs_rootfs/dri_labclass/01_hello_drv/hello_drv.c hello_open 41
[ 2862.379990] /home/book/nfs_rootfs/dri_labclass/01_hello_drv/hello_drv.c hello_write 35
[ 2862.390021] /home/book/nfs_rootfs/dri_labclass/01_hello_drv/hello_drv.c hello_release 46

/*读操作*/
[root@100ask:/mnt/dri_labclass/01_hello_drv]#
[root@100ask:/mnt/dri_labclass/01_hello_drv]# ./hello_drv_test /dev/hellodev
[ 2870.867199] /home/book/nfs_rootfs/dri_labclass/01_hello_drv/hello_drv.c hello_open 41
[ 2870.875827] /home/book/nfs_rootfs/dri_labclass/01_hello_drv/hello_drv.c hello_read 29
[ 2870.884006] /home/book/nfs_rootfs/dri_labclass/01_hello_drv/hello_drv.c hello_release 46

/*卸载模块*/
[root@100ask:/mnt/dri_labclass/01_hello_drv]# rmmod hello_drv.ko

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值