Linux测试杂项设备节点的生成,并对其测试

这里为了方便调试和移植,统一采用mod的形式注册设备和驱动

实际应用应该注意在平台中编译进内核,而非.ko文件的模块加载


首先我们要先在总线上注册一个设备

下面贴用模块注册设备的代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>


MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("HQU_Orange");

#define DEVICE_NAME	"Hello_device"

void Hello_device_release(struct device *dev);

struct platform_device Hello_device =
{
	.name	=	DEVICE_NAME	,
	.id		=	-1			,
	.dev	=	
	{
	.release=	Hello_device_release ,	
	}
};



static int  Mini_Linux_Device_Module_Init (void)
{ 
	int Device_Status;

	printk(KERN_EMERG "Mini Liunx Device Module Enter ! \r\n");
	Device_Status=platform_device_register(&Hello_device);
	printk(KERN_EMERG "Mini Linux Device Status is %d \n",Device_Status);
	return 0;
}

static void Mini_Linux_Device_Module_Exit (void)
{
	platform_device_unregister(&Hello_device);
	printk(KERN_EMERG "Mini Linux Device Module Exit ! \r\n");
}



void Hello_device_release(struct device *dev)
{
	printk(KERN_EMERG DEVICE_NAME "\tdevice release wolk!\r\n");
}

module_init(Mini_Linux_Device_Module_Init);
module_exit(Mini_Linux_Device_Module_Exit);



这个设备的名字是

将设备注册到platform上

将设备从platfrom上卸载

我现在将它划分为杂项设备,并且编写驱动代码

下面贴设备的驱动代码

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("HQU_Orange");

#define DEVICE_NAME		"Hello_device"
#define DEVICENODE_NAME	"Hello"

int Hello_driver_probe(struct platform_device* Hello_device);
int Hello_driver_remove(struct platform_device* Hello_device);
void Hello_driver_shutdown(struct platform_device* Hello_device);
int Hello_driver_suspend(struct platform_device* Hello_device,pm_message_t state);
int Hello_driver_resume(struct platform_device* Hello_device);
int Hello_driver_fops_open(struct inode* p_inode,struct file* p_file);
int Hello_driver_fops_release(struct inode* p_inode,struct file* p_file);
long Hello_driver_fops_unlocked_ioctl(struct file* p_file ,unsigned int ID ,unsigned long cmd);


struct platform_driver Hello_driver =
{
	.probe	=	Hello_driver_probe		,
	.remove	=	Hello_driver_remove		,
	.shutdown=	Hello_driver_shutdown	,
	.suspend=	Hello_driver_suspend	,
	.resume	=	Hello_driver_resume		,
	.driver	=	
	{
	.name	=	DEVICE_NAME	,
	.owner	=	THIS_MODULE	,
	}
};


struct file_operations Hello_driver_fops =
{
	.owner			=	THIS_MODULE						,
	.open			=	Hello_driver_fops_open			,
	.release		=	Hello_driver_fops_release		,
	.unlocked_ioctl	=	Hello_driver_fops_unlocked_ioctl,
};


struct miscdevice Hello_misc_device=
{
	.minor	=	MISC_DYNAMIC_MINOR	,
	.name	=	DEVICENODE_NAME		,
	.fops	=	&Hello_driver_fops	,

};


static int  Mini_Linux_Driver_Init (void)
{ 
	int Driver_Status;

	printk(KERN_EMERG "Mini Liunx Driver Enter ! \r\n");
	Driver_Status=platform_driver_register(&Hello_driver);
	printk(KERN_EMERG "Mini Linux Driver Status is %d \n",Driver_Status);
	return 0;
}

static void Mini_Linux_Driver_Exit (void)
{
	platform_driver_unregister(&Hello_driver);
	printk(KERN_EMERG "Mini Linux Driver Exit ! \r\n");
}


int Hello_driver_probe(struct platform_device* Hello_device)
{
	printk(KERN_EMERG "device-> name = %s device -> id = %d probe !\r\n",Hello_device->name,Hello_device->id);
	misc_register(&Hello_misc_device);
	return 0;
}

int Hello_driver_remove(struct platform_device* Hello_device)
{
	printk(KERN_EMERG "device-> name = %s device -> id = %d remove!\r\n",Hello_device->name,Hello_device->id);
	misc_deregister(&Hello_misc_device);
	return 0;
}

void Hello_driver_shutdown(struct platform_device* Hello_device)
{
	printk(KERN_EMERG "device-> name = %s device -> id = %d shutdown!\r\n",Hello_device->name,Hello_device->id);
}

int Hello_driver_suspend(struct platform_device* Hello_device,pm_message_t state)
{
	printk(KERN_EMERG "device-> name = %s device -> id = %d suspend!\r\n",Hello_device->name,Hello_device->id);
	return 0;
}

int Hello_driver_resume(struct platform_device* Hello_device)
{
	printk(KERN_EMERG "device-> name = %s device -> id = %d resume!\r\n",Hello_device->name,Hello_device->id);
	return 0;
}


int Hello_driver_fops_open(struct inode* p_inode,struct file* p_file)
{			
	printk(KERN_EMERG "Hello_file_open \r\n");
	return 0;
}

int Hello_driver_fops_release(struct inode* p_inode,struct file* p_file)
{
	printk(KERN_EMERG "Hello_file_release \r\n");
}

long Hello_driver_fops_unlocked_ioctl(struct file* p_file ,unsigned int ID ,unsigned long cmd)
{
	printk(KERN_EMERG "Hello_file_unlocked_ioctl \r\n");
	printk(KERN_EMERG "argv1 is %d  argv2 is %d \r\n" ,ID , cmd);
	return 0;
}


module_init(Mini_Linux_Driver_Init);
module_exit(Mini_Linux_Driver_Exit);



其中的 设备名字(DEVICE_NAME )务必保持 与上文 注册的设备名字一致

而生成的设备节点名字(DEVICENODE_NAME)可以自己任意命名

先将驱动注册到总线上,这个驱动会执行probe函数

在probe函数中对设备注册为杂项设备

接下来编写设备节点的文件操作函数

改写Makefile文件 进行编译


obj-m += Mini_linux_device_module.o    //这个修改为对应的编译文件

KDIR := /home/topeet/zImage/iTop4412_Kernel_3.0

PWD	?= $(shell pwd)

all:
		make -C	$(KDIR) M=$(PWD) modules
clean:
		rm -rf *.o *.mod.c  *.order *.symvers

make 编译 生成 .ko文件 

再make clean 删除中间文件 

将生成的.ko文件传输到板子上

可以看见模块加载成功了,返回值为0 所以设备成功注册到总线上了

再查看一下设备总线文件下生成了Hello_device

再将驱动注册到总线上,id是-1,说明只有一个设备 ,status 是0 ,说明注册成功了

查看设备节点,发现生成了Hello设备节点

接下来编写应用程序

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

int main(int argc ,char* argv[])
{
	int fd ;
	int res;
	char* file_node = argv[1];
	char id  = atoi(argv[2]);
	char cmd = atoi(argv[3]);
	
	fd=open(file_node,O_RDWR|O_NOCTTY|O_NDELAY);
	if(fd==-1)
	{
	perror(file_node);
	exit(EXIT_FAILURE);
	}

	res=ioctl(fd,id,cmd);
	if(res==-1)
	{
	perror("ioctl");
	close(fd);
	exit(EXIT_FAILURE);
	}
	
	close(fd);
	
	exit(EXIT_SUCCESS);
}


PS:ioctl这个函数传入的cmd和arg都是要做校检的,这里偷懒就没写了

编译

将其传输到板子上

确保你的驱动和设备都注册好了

调用我们刚刚写的程序

和我们的程序对比

好了,这就一整个杂项设备的驱动流程。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值