一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux平臺設(shè)備框架驅(qū)動

嵌入式技術(shù) ? 來源:嵌入式技術(shù) ? 作者:嵌入式技術(shù) ? 2022-09-25 08:59 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Linux平臺設(shè)備框架驅(qū)動

? 平臺設(shè)備框架(platform)是將一個驅(qū)動分為設(shè)備層和驅(qū)動層兩個部分,通過總線模型將設(shè)備和驅(qū)動進(jìn)行綁定。在系統(tǒng)中每注冊一個設(shè)備,都會與之匹配一個驅(qū)動,同樣的,每注冊一個驅(qū)動也會與之匹配一個設(shè)備。
通常 Linux 設(shè)備和驅(qū)動通常都需要掛接在一種總線上,對于本身依附于 PCI、 USB、 I2 C、 SPI 等的設(shè)備而言,這自然不是問題,但是在嵌入式系統(tǒng)里面, SOC 系統(tǒng)中集成的獨立的外設(shè)控制器、掛接在 SOC 內(nèi)存空間的外設(shè)等卻不依附于此類總線。
基于總線框架的模型結(jié)構(gòu),Linux下就衍生了平臺設(shè)備框架模型(platform),平臺設(shè)備總線是一種虛擬總線,稱為platform總線。對應(yīng)的設(shè)備層稱為platform_device;驅(qū)動層稱為platform_driver。設(shè)備層和驅(qū)動層通過平臺設(shè)備總線進(jìn)行匹配管理。

1.平臺設(shè)備框架特性

平臺模型采用了分層結(jié)構(gòu),把一個設(shè)備驅(qū)動程序分成了兩個部分:
平臺設(shè)備( platform_device)和平臺驅(qū)動( platform_driver)。
平臺設(shè)備將設(shè)備本身的資源注冊進(jìn)內(nèi)核,可以由內(nèi)核統(tǒng)一管理。
將硬件資源和驅(qū)動接口分離,編譯代碼的維護(hù)與移植。

poYBAGMto8uAVBODAAFDIhZx3Kk481.png#pic_center

2.平臺設(shè)備總線相關(guān)接口函數(shù)

2.1 設(shè)備層接口函數(shù)

??每個設(shè)備的系統(tǒng)通過設(shè)備結(jié)構(gòu)體struct platform_device保存。結(jié)構(gòu)體原型在 include/linux/platform_devcie.h 中定義。

struct platform_device {
	const char	* name; //設(shè)備名字,驅(qū)動層和設(shè)備層匹配標(biāo)志
	int		id;//通常填-1
	struct device	dev;//設(shè)備結(jié)構(gòu)體信息
	u32		num_resources;//資源個數(shù)
	struct resource	* resource;//資源內(nèi)容
	const struct platform_device_id	*id_entry;
	/* MFD cell pointer */
	struct mfd_cell *mfd_cell;
	/* arch specific additions */
	struct pdev_archdata	archdata;
};
  • struct device dev結(jié)構(gòu)信息

struct device dev 結(jié)構(gòu)體是用來實現(xiàn)設(shè)備模型的。這個結(jié)構(gòu)體中成員比較多,結(jié)構(gòu)體原型在 include/linux/devcie.h 中定義。我們常關(guān)心的是其中的兩個成員:
平臺數(shù)據(jù)指針: void *platform_data;
資源釋放函數(shù): void (*release)(struct device *dev);
平臺數(shù)據(jù)指針platform_data是一個void *類型指針,可以向驅(qū)動層傳遞任意數(shù)據(jù),release資源釋放函數(shù)接口在設(shè)備層一定要自己實現(xiàn),否則在設(shè)備層釋放資源時會報錯。
以下列舉其中幾個成員結(jié)構(gòu):

struct device {
	const char *init_name; /*邏輯設(shè)備的名字*/
	struct device_type *type; /* 設(shè)備類型 */
	struct bus_type *bus; /* 設(shè)備所屬的總線類型 */
	struct device_driver *driver;/* 指向開辟 struct device 結(jié)構(gòu) driver 指針*/
	void		*platform_data;	/* 平臺設(shè)備指針 */
	dev_t devt;  /* 存放設(shè)備號 dev_t,creates the sysfs"dev" */
	struct class *class;  /* 設(shè)備所屬類*/
	void	(*release)(struct device *dev);/*設(shè)備資源釋放函數(shù)*/
};
  • struct resource * resource結(jié)構(gòu)信息

    ??struct resource * resource 結(jié)構(gòu)體是用來保存設(shè)備資源內(nèi)容信息。該結(jié)構(gòu)體定義位置: include/linux/ioport.h
struct resource {
	resource_size_t start; //資源起始地址
	resource_size_t end; //資源結(jié)構(gòu)地址
	const char *name;//資源名字
	unsigned long flags;//資源類型
	struct resource *parent, *sibling, *child;
};
  • 設(shè)備層注冊函數(shù)
int platform_device_register(struct platform_device *pdev)
函數(shù)功能: 注冊平臺設(shè)備;
形參: pdev --設(shè)備結(jié)構(gòu)體;
返回值: 成功返回0,失敗返回其它值;
  • 設(shè)備層注銷函數(shù)
void platform_device_unregister(struct platform_device *pdev)
函數(shù)功能: 注冊平臺設(shè)備;
形參: pdev --設(shè)備結(jié)構(gòu)體;
  • 向內(nèi)核添加多個設(shè)備
int platform_add_devices(struct platform_device **devs, int num)
函數(shù)功能: 向內(nèi)核注冊多個設(shè)備;
形參: pdev --設(shè)備結(jié)構(gòu)體;
???num – 注冊的設(shè)備個數(shù)
返回值: 成功返回0,失敗返回其它值;

2.2 驅(qū)動層接口函數(shù)

驅(qū)動層通過struct platform_driver 結(jié)構(gòu)體保存相關(guān)信息,結(jié)構(gòu)體定義位置: include/linux/devcie.h
在該結(jié)構(gòu)體中必須要實現(xiàn)接口函數(shù):

資源匹配函數(shù):int (*probe)(struct platform_device *)
資源釋放函數(shù):int (*remove)(struct platform_device *);
驅(qū)動資源結(jié)構(gòu)體:struct device_driver driver;
一個驅(qū)動層可匹配多個設(shè)備層,若想同時匹配多個設(shè)備層,則通過id_table 指針完成匹配。

struct platform_driver {
	int (*probe)(struct platform_device *);//資源匹配函數(shù)
	int (*remove)(struct platform_device *);//資源釋放函數(shù)
	void (*shutdown)(struct platform_device *);
	int (*suspend)(struct platform_device *, pm_message_t state);
	int (*resume)(struct platform_device *);
	struct device_driver driver;//驅(qū)動資源結(jié)構(gòu)體
	const struct platform_device_id *id_table;//匹配多多設(shè)備時需要填寫
};
  • struct device_driver driver 結(jié)構(gòu)信息

??struct device_driver driver 結(jié)構(gòu)體中有個成員name必須要填寫,當(dāng)沒有實現(xiàn)id_table指針時,設(shè)備層和驅(qū)動層就是通過該成員完成資源匹配。

struct device_driver {
	const char		*name; //資源匹配參數(shù)
	struct bus_type		*bus;

	struct module		*owner;
	const char		*mod_name;	/* used for built-in modules */

	bool suppress_bind_attrs;	/* disables bind/unbind via sysfs */

	const struct of_device_id	*of_match_table;

	int (*probe) (struct device *dev);
	int (*remove) (struct device *dev);
	void (*shutdown) (struct device *dev);
	int (*suspend) (struct device *dev, pm_message_t state);
	int (*resume) (struct device *dev);
	const struct attribute_group **groups;

	const struct dev_pm_ops *pm;

	struct driver_private *p;
};
  • const struct platform_device_id *id_table 結(jié)構(gòu)信息

??該結(jié)構(gòu)也是用于匹配設(shè)備資源,一個驅(qū)動層可以同時匹配多個設(shè)備層。

struct platform_device_id {
	char name[PLATFORM_NAME_SIZE]; //資源匹配參數(shù)
	kernel_ulong_t driver_data
			__attribute__((aligned(sizeof(kernel_ulong_t)))); //匹配設(shè)備層的 void *platform_data數(shù)據(jù)
};
  • 驅(qū)動層注冊和注銷函數(shù)
//驅(qū)動注冊函數(shù)
int platform_driver_register(struct platform_driver *drv)
//驅(qū)動注銷函數(shù)
void platform_driver_unregister(struct platform_driver *drv)

3.平臺設(shè)備框架應(yīng)用示例

3.1 設(shè)備層注冊示例

設(shè)備層注冊步驟:

填充struct device結(jié)構(gòu)體,填寫設(shè)備資源信息struct resource * resource;
調(diào)用設(shè)備層注冊函數(shù)platform_device_register();
注銷時調(diào)用注銷函數(shù)platform_device_unregister;

#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 

static void platform_release(struct device *dev)
{
	printk("資源釋放完成n");
}
static struct resource	resource[]=
{
	[0]={
			.start=EXYNOS4X12_GPM4(0),
			.end=EXYNOS4X12_GPM4(0),
			.name="led1",
			.flags=IORESOURCE_MEM
		},
	[1]={
			.start=EXYNOS4X12_GPM4(1),
			.end=EXYNOS4X12_GPM4(1),
			.name="led2",
			.flags=IORESOURCE_MEM
		},		
		
};

struct platform_device pdev=
{
	.name="led_dev",
	.id=-1,
	.dev=
	{
		.release=platform_release,//資源釋放函數(shù)
	},
	.num_resources=sizeof(resource)/sizeof(resource[0]),
	.resource=resource,	
};

static int __init wbyq_platform_dev_init(void)
{
	platform_device_register(&pdev);
    return 0;
}
/*驅(qū)動釋放*/
static void __exit wbyq_platform_dev_cleanup(void)
{
	/*注銷設(shè)備層*/
	platform_device_unregister(&pdev);

}
module_init(wbyq_platform_dev_init);//驅(qū)動入口函數(shù)
module_exit(wbyq_platform_dev_cleanup);//驅(qū)動出口函數(shù)

MODULE_LICENSE("GPL");//驅(qū)動注冊協(xié)議
MODULE_AUTHOR("it_ashui");
MODULE_DESCRIPTION("Exynos4 platform_dev Driver");

3.2 驅(qū)動層注冊示例

驅(qū)動層注冊步驟:

填充 struct platform_driver結(jié)構(gòu)體,實現(xiàn)資源匹配函數(shù)和資源釋放函數(shù);
調(diào)用設(shè)備層注冊函數(shù)platform_driver_register();
注銷時調(diào)用注銷函數(shù)platform_driver_unregister;

#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 

static int platform_probe(struct platform_device *dev)
{
	printk("資源匹配成功n");
	printk("資源個數(shù):%dn",dev->num_resources);
	struct resource * resource=platform_get_resource(dev,IORESOURCE_MEM,0);
	if(resource)
	{
		printk("資源名:%ststart=%xtend=%xn",resource->name,resource->start,resource->end);
	}
	return 0;
	
}
static int platform_remove(struct platform_device *dev)
{
	printk("資源釋放成功n");
	return 0;
}
static struct platform_device_id id_table[]=
{
	[0]=
	{
		.name="led_dev"
	},
	[1]=
	{
		.name="tiny4412_dev"
	},
	
};
static struct platform_driver drv=
{
	.probe=platform_probe,
	.remove=platform_remove,
	.driver=
	{
		.name="platform_drv",
	},
	.id_table=id_table,
};
static int __init wbyq_platform_drv_init(void)
{
	platform_driver_register(&drv);
	printk("驅(qū)動層平臺設(shè)備注冊成功n");
    return 0;
}
/*驅(qū)動釋放*/
static void __exit wbyq_platform_drv_cleanup(void)
{
	/*注銷設(shè)備層*/
	platform_driver_unregister(&drv);
	printk("驅(qū)動層平臺設(shè)備注銷成功n");

}
module_init(wbyq_platform_drv_init);//驅(qū)動入口函數(shù)
module_exit(wbyq_platform_drv_cleanup);//驅(qū)動出口函數(shù)

MODULE_LICENSE("GPL");//驅(qū)動注冊協(xié)議
MODULE_AUTHOR("it_ashui");
MODULE_DESCRIPTION("Exynos4 platform_drv Driver");

3.3 Makefile文件

KER_ADD=/home/wbyq/src_pack/linux-3.5
all:
	make -C $(KER_ADD) M=`pwd` modules
	#arm-linux-gcc main.c -o app 
	cp ./*.ko  /home/wbyq/src_pack/rootfs/code 
	make -C $(KER_ADD) M=`pwd` modules clean
	rm app -f
obj-m +=platform_drv.o platform_dev.o platform_dev2.o

4 運行效效果

pYYBAGMto8uAbpCWAAB_bTHp4zA763.png#pic_center

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    8993

    瀏覽量

    153693
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11509

    瀏覽量

    213690
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4379

    瀏覽量

    64813
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    Linux字符設(shè)備驅(qū)動開發(fā)框架介紹

    字符設(shè)備Linux驅(qū)動中最基本的一類設(shè)備驅(qū)動,字符設(shè)備就是一個一個字節(jié),按照字節(jié)流進(jìn)行讀寫操作
    發(fā)表于 04-15 11:52 ?1748次閱讀
    <b class='flag-5'>Linux</b>字符<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動</b>開發(fā)<b class='flag-5'>框架</b>介紹

    linux平臺設(shè)備驅(qū)動

    linux平臺設(shè)備驅(qū)動http://bbs.edu118.com/forum.php?mod=viewthread&tid=630&fromuid=231(出處: 信盈達(dá)IT技術(shù)社
    發(fā)表于 09-01 14:40

    字符設(shè)備驅(qū)動設(shè)備驅(qū)動模型、sysfs、平臺設(shè)備驅(qū)動的關(guān)系 -----從需求的角度去理解Linux之三

    學(xué)習(xí)Linux設(shè)備驅(qū)動開發(fā)的過程中自然會遇到字符設(shè)備驅(qū)動、平臺
    發(fā)表于 12-17 16:16

    OpenHarmony系統(tǒng)平臺驅(qū)動驅(qū)動框架概述

    接口。這里的平臺設(shè)備,泛指I2C/UART等總線、以及GPIO/RTC等SOC片內(nèi)硬件資源。OpenHarmony系統(tǒng)平臺驅(qū)動框架是Open
    發(fā)表于 03-28 10:58

    嵌入式Linux的USB驅(qū)動設(shè)計

    本文主要介紹了 Linux 平臺的USB設(shè)備驅(qū)動開發(fā)的一般步驟方法和技巧,通過詳細(xì)介紹USB的相關(guān)概念和Linux中USB
    發(fā)表于 06-08 17:15 ?49次下載
    嵌入式<b class='flag-5'>Linux</b>的USB<b class='flag-5'>驅(qū)動</b>設(shè)計

    想要駕馭Linux驅(qū)動開發(fā),必須深刻理解Linux總線設(shè)備驅(qū)動框架

    想要駕馭Linux驅(qū)動開發(fā),必須深刻理解Linux總線設(shè)備驅(qū)動框架。之所以會形成這樣的
    的頭像 發(fā)表于 03-22 11:08 ?1.1w次閱讀
    想要駕馭<b class='flag-5'>Linux</b><b class='flag-5'>驅(qū)動</b>開發(fā),必須深刻理解<b class='flag-5'>Linux</b>總線<b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>框架</b>

    Linux DMA Engine框架的介紹

    此會話描述如何從設(shè)備驅(qū)動程序在Linux中使用DMA。 這包括內(nèi)存分配,緩存控制和DMA設(shè)備控制。 詳細(xì)介紹了Linux DMA Eng
    的頭像 發(fā)表于 11-23 06:29 ?6714次閱讀

    你對Linux總線設(shè)備驅(qū)動框架是否了解

    Linux設(shè)備驅(qū)動模型,或者說,Linux設(shè)備驅(qū)動框架
    發(fā)表于 05-05 15:13 ?879次閱讀

    米爾科技Linux設(shè)備驅(qū)動研究淺談

    Linux設(shè)備驅(qū)動開發(fā)詳解(第2版)》是一本介紹linux設(shè)備驅(qū)動開發(fā)理論、
    的頭像 發(fā)表于 11-25 09:32 ?2223次閱讀
    米爾科技<b class='flag-5'>Linux</b><b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動</b>研究淺談

    如何使用Linux內(nèi)核實現(xiàn)USB驅(qū)動程序框架

    Linux內(nèi)核提供了完整的USB驅(qū)動程序框架。USB總線采用樹形結(jié)構(gòu),在一條總線上只能有唯一的主機設(shè)備Linux內(nèi)核從主機和
    發(fā)表于 11-06 17:59 ?20次下載
    如何使用<b class='flag-5'>Linux</b>內(nèi)核實現(xiàn)USB<b class='flag-5'>驅(qū)動</b>程序<b class='flag-5'>框架</b>

    OpenHarmony HDF平臺驅(qū)動框架驅(qū)動適配介紹

    驅(qū)動平臺設(shè)備(PlatformDevice),為系統(tǒng)及外設(shè)驅(qū)動提供訪接口。這里的平臺設(shè)備,泛指
    的頭像 發(fā)表于 09-24 11:16 ?7510次閱讀
    OpenHarmony HDF<b class='flag-5'>平臺</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>框架</b>及<b class='flag-5'>驅(qū)動</b>適配介紹

    Linux內(nèi)核中視頻設(shè)備驅(qū)動框架V4L2X詳解

    V4L2(Video for Linux 2):Linux內(nèi)核中關(guān)于視頻設(shè)備驅(qū)動框架,對上向應(yīng)用層提供統(tǒng)一的接口,對下支持各類復(fù)雜硬件的靈
    的頭像 發(fā)表于 05-30 16:18 ?6971次閱讀

    看看Linux為相機提供的驅(qū)動框架

    ? V4L2 (Video Linux Two),是為支持Linux內(nèi)核設(shè)計的驅(qū)動框架驅(qū)動框架。
    的頭像 發(fā)表于 08-07 16:03 ?3808次閱讀
    看看<b class='flag-5'>Linux</b>為相機提供的<b class='flag-5'>驅(qū)動</b><b class='flag-5'>框架</b>

    Linux的PWM驅(qū)動框架及實現(xiàn)方法

    本文主要講述了Linux的PWM驅(qū)動框架、實現(xiàn)方法、驅(qū)動添加方法和調(diào)試方法。
    的頭像 發(fā)表于 05-14 15:24 ?1866次閱讀
    <b class='flag-5'>Linux</b>的PWM<b class='flag-5'>驅(qū)動</b><b class='flag-5'>框架</b>及實現(xiàn)方法

    Linux Regmap 驅(qū)動框架

    ,regmap 向驅(qū)動編寫人員提供的 API 接口,驅(qū)動編寫人員使用這些API 接口來操作具體的芯片設(shè)備,也是驅(qū)動編寫人員重點要掌握的。 2、regmap 結(jié)構(gòu)體
    的頭像 發(fā)表于 07-06 17:29 ?1428次閱讀
    <b class='flag-5'>Linux</b> Regmap <b class='flag-5'>驅(qū)動</b><b class='flag-5'>框架</b>