Rumah > Tutorial sistem > LINUX > teks badan

Model pemacu peranti Linux

WBOY
Lepaskan: 2024-07-22 18:54:35
asal
412 人浏览过

Model pemacu peranti Linux

Daftar Kandungan

Satu pembolehubah persekitaran Linux, model pemacu peranti 1. Asal usul model pemacu peranti Linux

Semak dahulu proses biasa kompilasi pemacu peranti

【1】Laksanakan fungsi kemasukan module_init() dan fungsi pemunggahan modul module_exit();

【2】Mohon nombor peranti, daftar_chrdev();----->

【3】Gunakan mekanisme udev/mdev untuk mencipta nod fail peranti class_create(), device_create();------>(berkaitan dengan kernel)

【4】Pengamatan perkakasan: 1.io pemetaan sumber ioremap(), kernel menyediakan fungsi perpustakaan gpio 2. Daftar gangguan. ------->(berkaitan perkakasan)

【5】Bina struktur operasi_fail-------->

[6] Laksanakan kaedah pengendalian perkakasan xxx_open(), xxx_write()...

linux驱动编程_编程驱动聚水潭_编程驱动光谱仪Inferens: Bukan sahaja bahagian keempat daripada keseluruhan proses berkaitan dengan perkakasan, tetapi selebihnya adalah operasi yang serupa Untuk menyusun pemacu peranti dengan mudah (tanpa mencipta semula roda) dan menjimatkan tenaga manusia, model pemacu peranti dicadangkan untuk memudahkan peranti. proses penyusunan pemandu.

2. Rangka kerja model pemacu peranti

Anda boleh melihat objek bas melalui sistem fail maya sysfs (mengambil USB sebagai contoh)

在这里插入图片描述

Pengaturcaraan pemandu Linux

, pengaturcaraan model bas BUS Peta konsep

1.Objek bas

【1】structbus_type: Institusi latihan linux objek bas, menerangkan bas, mengurus peranti dan pemandu

pengaturcaraan pemandu linux

, dipadankan dengan sempurna.

 struct bus_type {//只列举重要成员
	const char		*name; //总线名字
	int (*match)(struct device *dev, struct device_driver *drv);//匹配方法
};
Salin selepas log masuk

【2】Daftar dan log keluar bas

int bus_register(struct bus_type *bus);
void bus_unregister(struct bus_type *bus);
Salin selepas log masuk

【3】Bina bas

 #include 
#include 
#include 
//实例化一个bus对象
struct bus_type mybus = {
	.name = "mybus",
	.match = mybus_match,
};
EXPORT_SYMBOL(mybus); //导出总线对象,让device对象和driver对象使用
	
static int __init mybus_init(void)
{
	printk("------%s---------n",__FUNCTION__);
	int ret;
	
	//构建一个总线结果:/sys/bus/mybus
	ret = bus_register(&mybus);
	if(ret != 0)
	{
		printk("bus_register errorn");
		return ret;
	}
	return 0;
}
static void __exit mybus_exit(void)
{
	printk("------%s---------n",__FUNCTION__);
	bus_unregister(&mybus);
}
module_init(mybus_init);
module_exit(mybus_exit);
MODULE_LICENSE("GPL");
Salin selepas log masuk

2.objek peranti

【1】objek peranti: objek peranti, menerangkan maklumat peranti, termasuk alamat, gangguan dan data lain

struct device {//只列举重要成员
	struct kobject kobj; //所有对象的父类
	const char *init_name;//在/sys/bus/mybus/device的名字,用于在总线中匹配
	struct bus_type	*bus;		 //指向该device对象依附的总线对象
	void *platform_data;	 //自定义的数据,指向任何类型的数据
};
Salin selepas log masuk

【2】Daftar dan log keluar bas

int device_register(struct device *dev);
void device_unregister(struct device *dev);
Salin selepas log masuk

【3】Tulis objek peranti

linux驱动编程_编程驱动聚水潭_编程驱动光谱仪

定义一个描述设备的信息的结构体,匹配成功以后让driver对象在总线中领到device对象的信息,实现分离。

#include 
#include 
#include 
extern struct bus_type mybus;
struct mydev_desc{
	char* name;
	int irqno;
	unsigned long addr;
};
struct mydev_desc deviofo = {
	.name = "hqs",
	.irqno = 8877,
	.addr = 0x12345678,
};
void mydev_release(struct device* dev)
{
	printk("------%s---------n",__FUNCTION__);
}
//构建一个device对象
struct device mydev = {
	.init_name = "fsdev_drv",
	.bus = &mybus,
	.release = mydev_release,
	.platform_data = &deviofo,
};
static int __init mydev_init(void)
{
	printk("------%s---------n",__FUNCTION__);
	int ret;
	//将device注册到总线中
	ret = device_register(&mydev);
	if(ret < 0)
	{
		printk("device_register errorn");
		return ret;
	}
	return 0;
}
static void __exit mydev_exit(void)
{
	printk("------%s---------n",__FUNCTION__);
	device_unregister(&mydev);
}
module_init(mydev_init);
module_exit(mydev_exit);
MODULE_LICENSE("GPL");
Salin selepas log masuk

3.driver对象

【1】driver对象:描述设备驱动发的方式

struct device_driver {//只列举重要成员
	const char		*name;//在/sys/bus/mybus/driver的名字,用于在总线中匹配
	struct bus_type		*bus;//指向该device对象依附的总线对象
	int (*probe) (struct device *dev); //device和driver匹配之后要做的事情
	int (*remove) (struct device *dev); //device和driver分离之后要做的事情
};
Salin selepas log masuk

【2】注册和注销总线

int driver_register(struct device_driver *drv);
void driver_unregister(struct device_driver *drv);
Salin selepas log masuk

【3】编写driver对象

匹配成功以后可以在总线中领到device对象的数据,具体实现在probe函数里。

#include 
#include 
#include 
#include 
extern struct bus_type mybus;
struct mydev_desc{
	char* name;
	int irqno;
	unsigned long addr;
};
struct mydev_desc* pdesc;
int mydrv_probe(struct device *dev)
{
	printk("------%s---------n",__FUNCTION__);
	pdesc = (struct mydev_desc*)dev->platform_data;
	printk("name =%sn",pdesc->name);
	printk("irqno = %dn",pdesc->irqno);
	unsigned long * paddr = ioremap(pdesc->addr, 8);
	return 0;
}
int mydrv_remove (struct device *dev)
{
	printk("------%s---------n",__FUNCTION__);
	return 0;
}
//构建一个driver对象
struct device_driver mydrv = {
	.name = "fsdev_drv",
	.bus = &mybus,
	.probe = mydrv_probe,
	.remove = mydrv_remove,
};
static int __init mydrv_init(void)
{
	printk("------%s---------n",__FUNCTION__);
	int ret;
	//将device注册到总线中
	ret = driver_register(&mydrv);
	if(ret < 0)
	{
		printk("driver_register errorn");
		return ret;
	}
	return 0;
}
static void __exit mydrv_exit(void)
{
	printk("------%s---------n",__FUNCTION__);
	driver_unregister(&mydrv);	
}
module_init(mydrv_init);
module_exit(mydrv_exit);
MODULE_LICENSE("GPL");
Salin selepas log masuk

4.device对象和driver对象匹配

【1】实现BUS对象中的match方式(按device对象的名子和driver对象中的名子相匹配)

要注意的是不能直接用device对象中的init_name,而要用device对象中继承的structkobjectkobj;上面的成员name不然会报错

int mybus_match(struct device *dev, struct device_driver *drv)
{
	//如果匹配成功,match方法一定要返回一个1,失败返回0
	if(! strncmp(drv->name,dev->kobj.name,strlen(drv->name)))
	{
		printk("match okn");
		return 1;
	}
	else
	{	
		printk("match failedn");
		return 0;	 
	}
	return 0;
}
//实例化一个bus对象
struct bus_type mybus = {
	.name = "mybus",
	.match = mybus_match,
};
Salin selepas log masuk

【2】保证device对象和driver对象的名子一样:例如这儿都使用"fsdev_drv"才能保证能匹配成功

//构建一个device对象
struct device mydev = {
	.init_name = "fsdev_drv",
	.bus = &mybus,
	.release = mydev_release,
	.platform_data = &deviofo,
};
Salin selepas log masuk

//构建一个driver对象
struct device_driver mydrv = {
	.name = "fsdev_drv",
	.bus = &mybus,
	.probe = mydrv_probe,
	.remove = mydrv_remove,
};
Salin selepas log masuk

以上是Model pemacu peranti Linux的详细内容。更多信息请关注PHP中文网其他相关文章!

sumber:itcool.net
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!