【linux】驱动-7-平台设备驱动

内核使用 bus_type 来抽象系统中的总线。相应地,内核使用 platform_bus_type 来描述平台总线。
源码:
struct bus_type platform_bus_type = {

.name           = "platform",
.dev_groups     = platform_dev_groups,
.match          = platform_match,
.uevent         = platform_uevent,
.pm             = &platform_dev_pm_ops,

};

EXPORT_SYMBOL_GPL(platform_bus_type);
位于 内核源码/driver/base/platform.c。

该总线在Linux内核启动的时候自动进行注册。

平台总线初始化函数源码:

int __init platform_bus_init(void){
int error;

error = bus_register(&platform_bus_type);

return error;}
位于 内核源码/driver/base/platform.c。
error = bus_register(&platform_bus_type); 就是向Linux内核注册 plateform_bus_type 平台总线。
建议:以上匹配规则及源码,可以追踪函数 platform_match 源码来分析。

7.2 平台设备
7.2.1 platform_device
平台设备:

使用 platform_device 描述平台设备。
源码:
struct platform_device {
const char *name;
int id;
struct device dev;
u32 num_resources;
struct resource *resource;
const struct platform_device_id id_entry;
/
省略部分成员 */
};
位于 内核源码/include/linux/platform_device.h
name:设备名称,总线进行匹配时,会比较设备和驱动的名称是否一致;
id:指定设备的编号,Linux支持同名的设备,而同名设备之间则是通过该编号进行区分;
dev:Linux设备模型中的device结构体,platform_device 通过继承该结构体可复用它的相关代码,方便内核管理平台设备;
num_resources:记录资源的个数,当结构体成员 resource 存放的是数组时,需要记录 resource 数组的个数,内核提供了宏定义 ARRAY_SIZE 用于计算数组的个数;
resource:平台设备提供给驱动的资源,如irq,dma,内存等等;
id_entry:平台总线提供的另一种匹配方式,原理依然是通过比较字符串,这里的 id_entry 用于保存匹配的结果;
7.2.2 设备信息
平台设备的工作是为 驱动程序 提供 设备信息。包括 硬件信息 和 软件信息。

硬件信息:驱动程序需要使用到的寄存器、中断号、内存资源、IO口等等;
软件信息:以太网设备中的 MAC 地址、I2C 设备中的设备地址等等。
硬件信息:

硬件信息使用 struct resource 来保存设备所提供的资源。
源码:
/**

  • Resources are tree-like, allowing nesting etc…
    */
    struct resource {
    resource_size_t start;
    resource_size_t end;
    const char name;
    unsigned long flags;
    /
    省略部分成员 */
    };
    位于 内核源码/include/linux/ioport.h;
    name:资源名字,可为 NULL;
    start、end:指定资源的起始地址及结束地址;
    对于 IORESOURCE_IO 和 IORESOURCE_MEM 是有起始和结束地址的,若只有一个引脚或者一个通道,那么 start == end。
    flags:用于指定资源的类型,在 Linux 中,资源包括I/O、Memory、Register、IRQ、DMA、Bus等多种类型,如:
    IORESOURCE_IO:IO 地址空间,对应于 IO 端口映射方式;
    IORESOURCE_MEM:外设可直接寻址的地址空间;
    IORESOURCE_IRQ:指定该设备使用哪个中断;
    IORESOURCE_DMA:指定 DMA 通道。
    设备驱动程序主要目的还是操作设备的寄存器。
    不同架构的计算机提供不同的操作接口,主要有IO端口映射和IO内存映射两种方式。

IO端口映射方式:

只能通过专门的接口函数才能访问。
IO内存映射方式:

可以像内存一样访问,去读写寄存器。
软件信息:

软件信息需要以私有数据保存;
platform_device 结构体中继承有 device 结构体,成员为 dev,该结构体里面的 platform_data 可以用于保存设备的私有数据。
platform__data 是 void * 类型的万能指针,所以,只需要把私有数据的地址付给 platform_data 即可。
7.2.3 注册/注销平台设备
注册:platform_device_register:

注册平台设备,挂在到平台总线上。
函数原型:int platform_device_register(struct platform_device *pdev);位于 内核源码/drivers/base/platform.c。
pded:platform_device 类型结构体指针;
返回:
成功:0;
失败:负数。
注销:platform_device_unregister:

注销平台设备。
函数原型:void platform_device_unregister(struct platform_device pdev);位于 **
内核源码/drivers/base/platform.c
*。
pded:platform_device 类型结构体指针;
7.3 平台驱动
7.3.1 platform_driver
平台驱动:

使用 platform_driver 描述平台驱动。
源码:
struct platform_driver {

int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;

};
位于 内核源码/include/platform_device.h

probe:匹配成功后执行的回调函数。

remove:移除某个平台设备是的回调函数。

driver:Linux 设备模型中用于抽象驱动的 device_driver 结构体,platform_driver 继承该结构体,也就获取了设备模型驱动对象的特性。

id_table:表示该驱动能够兼容的设备类型。

platform_device_id

name:指定驱动名称。(用于和 platform_device 中的 name 比较,匹配。)
driver_data:用于保存设备的配置。
源码:
struct platform_device_id
{
char name[PLATFORM_NAME_SIZE];
kernel_ulong_t driver_data;
};
7.3.2 注册/注销平台驱动
注册:platform_driver_register:

注册平台驱动,挂在到平台总线上。
函数原型:int platform_driver_register(struct platform_driver *drv)。
drv:platform_driver 类型结构体指针;
返回:
成功:0;
失败:负数。
注销:platform_driver_unregister:

注销平台启动驱动。
函数原型:void platform_driver_unregister(struct platform_driver drv);位于 **
内核源码/drivers/base/platform.c
*。
drv:platform_driver 类型结构体指针;
7.3.3 平台驱动获取设备信息
首先要知道的是,平台设备的硬件信息保存在 resource 结构体中。而软件信息则保存在 platform_data 中。

获取硬件信息:platform_get_resource:

获取平台设备提供的资源结构体。一般用在 probe 函数中。、

函数原型:struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);

dev:指定获取哪个平台设备的资源;

type:指定获取资源的类型,如IORESOURCE_MEM、IORESOURCE_IO等;

num:指定要获取的资源编号。每个设备所需要的资源的个数是不一样的。且不同资源的编号是不一样的。

返回:

成功:struct resouce 结构体类型指针;
失败:NULL。
若要获取的资源类型为 IORESOURCE_IRQ,平台设备驱动还提供以下函数接口,来获取中断引脚。

函数原型:int platform_get_irq(struct platform_device *pdev, unsigned int num)
pedv:指定需要获取哪个平台设备的资源;
num:指定要获取的资源编号。
返回:
成功:可用中断号;
失败:负数。
获取软件信息:dev_get_platdata:

  • dev:struct device 结构体类型指针。

static inline void *dev_get_platdata(const struct device *dev)
{
return dev->platform_data;
}
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux设备驱动程序的调试技术是指在开发和调试Linux设备驱动程序时使用的技术和工具。调试技术对于解决设备驱动程序中的错误和问题非常重要,可以有效地提高驱动程序的稳定性和性能。 首先,调试驱动程序时通常使用的技术是打印调试信息。通过在驱动程序中插入打印语句,可以在运行时输出相关的调试信息,如变量的值、函数的调用等。这可以帮助开发者追踪程序的执行流程,查找和定位错误。 另外,使用断点调试也是一种常用的技术。开发者可以通过使用调试器来设置断点,使程序在指定位置停下来,以便进一步调试。这个过程可以在实际硬件上进行,也可以在模拟器或虚拟机中进行。 为了更方便地调试驱动程序,还可以使用一些特定的调试工具。例如,通过使用内核调试器kgdb,开发者可以在驱动程序崩溃时连接到目标系统,并查看相关的内核信息,从而帮助定位问题。另外还有一些跟踪工具,如strace和sysprof,可以用于跟踪系统调用和函数调用,以及分析程序的运行性能。 此外,对于一些特殊的嵌入式系统,可能还需要使用硬件调试工具来进行调试。例如,使用JTAG接口连接到目标板上,可以通过调试器软件实时监视和控制系统状态,读取和修改寄存器的值,以进一步分析和定位问题。 总之,Linux设备驱动程序的调试技术非常重要,可以通过打印调试信息、断点调试、调试工具和硬件调试工具等方式来帮助开发者定位和解决问题,提高驱动程序的质量和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值