8.荔枝派 zero(全志V3S)-字符驱动

上面是我的微信和QQ群,欢迎新朋友的加入。

1.驱动程序

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/cdev.h>

#include <linux/device.h>



static int major = 232; /* 静态设备号方式的默认值 */

static int minor = 0; /* 静态设备号方式的默认值 */


module_param(major, int, S_IRUGO);

module_param(minor, int, S_IRUGO);


struct cdev *char_cdev; /* cdev 数据结构 */

static dev_t devno; /* 设备编号 */

static struct class *char_cdev_class;


#define DEVICE_NAME "char_cdev"


static int char_cdev_open(struct inode *inode, struct file *file )

{

	try_module_get(THIS_MODULE);

	printk(KERN_INFO DEVICE_NAME " opened!\n");

	return 0;

}


static int char_cdev_release(struct inode *inode, struct file *file )

{

	printk(KERN_INFO DEVICE_NAME " closed!\n");

	module_put(THIS_MODULE);

	return 0;

}



static ssize_t char_cdev_read(struct file *file, char *buf,size_t count, loff_t *f_pos)

{

	printk(KERN_INFO DEVICE_NAME " read method!\n");

	return count;

}



static ssize_t char_cdev_write(struct file *file, const char *buf, size_t count, loff_t *f_pos)

{

	printk(KERN_INFO DEVICE_NAME " write method!\n");

	return count;

}

static long  char_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	printk(KERN_INFO DEVICE_NAME " ioctl method!\n");
	return 0;
}



struct file_operations char_cdev_fops = {

	.owner = THIS_MODULE,

	.read = char_cdev_read,

	.write = char_cdev_write,

	.open = char_cdev_open,

	.release = char_cdev_release,
	.unlocked_ioctl = char_cdev_ioctl

};



static int __init char_cdev_init(void)

{

	int ret;

	if (major > 0) { /* 静态设备号 */

		devno = MKDEV(major, minor);

		ret = register_chrdev_region(devno, 1, "char_cdev");

	} else { /* 动态设备号 */

		ret = alloc_chrdev_region(&devno, minor, 1, "char_cdev"); /* 从系统获取主设备号 */

		major = MAJOR(devno);

	}

	if (ret < 0) {

		printk(KERN_ERR "cannot get major %d \n", major);

		return -1;

	}


	char_cdev = cdev_alloc(); /* 分配 char_cdev 结构 */

	if (char_cdev != NULL) {

		cdev_init(char_cdev, &char_cdev_fops); /* 初始化 char_cdev 结构 */

		char_cdev->owner = THIS_MODULE;

		if (cdev_add(char_cdev, devno, 1) != 0) { /* 增加 char_cdev 到系统中 */

			printk(KERN_ERR "add cdev error!\n");

			goto error;

		}

	} else {

		printk(KERN_ERR "cdev_alloc error!\n");

		return -1;

	}


	char_cdev_class = class_create(THIS_MODULE, "char_cdev_class");

	if (IS_ERR(char_cdev_class)) {

		printk(KERN_INFO "create class error\n");

		return -1;

	}

	device_create(char_cdev_class, NULL, devno, NULL, "char_cdev" "%d", MINOR(devno));
	printk(KERN_ERR "Init drive!\n");

	return 0;


	error:

	unregister_chrdev_region(devno, 1); /* 释放已经获得的设备号 */

	return ret;

}

static void __exit char_cdev_exit(void)

{

	cdev_del(char_cdev); /* 移除字符设备 */

	unregister_chrdev_region(devno, 1); /* 释放设备号 */

	device_destroy(char_cdev_class, devno);

	class_destroy(char_cdev_class);
	printk(KERN_ERR "Exit drive!\n");

}


module_init(char_cdev_init);

module_exit(char_cdev_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("JUN, 2839084093@qq.com");

2.驱动makefile

 

# Makefile
ifneq ($(KERNELRELEASE),)
#kbuild syntax. dependency relationshsip of files and target modules are listed here.
obj-m := char_dev.o
else
PWD:= $(shell pwd)

KDIR := /home/jun/v3s/linux-zero-4.10.y
all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
	rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
endif

3.测试程序

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>

#define DEV_NAME "/dev/char_cdev0"

int main(int argc, char *argv[])
{
	int i;
	int fd = 0;
	int dat = 0;

	system("insmod char_cdev.ko");
	system("mknod /dev/char_cdev c 200 0");  //create the file

	fd = open (DEV_NAME, O_RDWR);
	if (fd < 0) {
		perror("Open "DEV_NAME" Failed!\n");
		exit(1);
	}

	i = read(fd, &dat, 1);
	if (!i) {
		perror("read "DEV_NAME" Failed!\n");
		exit(1);
	}

	dat = 0;
	i = write(fd, &dat, 1);
	if (!i) {
		perror("write "DEV_NAME" Failed!\n");
		exit(1);
	}

	ioctl(fd, 0);

	close(fd);
	return 0;
}

4.测试makefile

EXEC	= ./bin/char_test
OBJS    = char_test.o

CROSS	= arm-linux-gnueabihf-
CC	     = $(CROSS)gcc 
STRIP	= $(CROSS)strip
CFLAGS	= -Wall -g -O2

all:  clean $(EXEC)

$(EXEC):$(OBJS)
	$(CC) $(CFLAGS) -o $@ $(OBJS)
	$(STRIP) $@

clean:
	-rm -f $(EXEC) *.o

5.测试

将驱动和测试程序编译出来

拷贝到设备

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值