Linux AMBA驱动框架分析

一、AMBA 介绍 

        当我们查看一些芯片的设备树时,我们发现设备树上的很多片内外设的compatible属性为compatible = "arm,pl022", "arm,primecell",而且在内核源码中找不到compatible匹配的驱动,这是因为这些驱动使用了arm提供的amba协议。
        AMBA是由ARM Holdings开发的一种广泛使用的片上互连规范,它为系统级芯片(SoC)设计中的各种IP(知识产权)模块(如微控制器、处理器、存储控制器、直接内存访问控制器和其他外设)提供了连接和互连框架。
        AMBA由多个不同的规范组成,每个规范都有特定的用途。主要的规范包括:
        1.AMBA AHB(高级高性能总线):AHB是一种高性能总线协议,为不同IP模块之间的高效数据传输提供多主多从接口。它支持突发传输、分裂事务和流水线等功能,以优化数据传输速率。
        2.AMBA APB(高级外设总线):APB是一种低功耗、低成本的总线协议,主要用于将低带宽外设连接到系统。它被设计成简单易实现,适用于不需要高数据传输速率的外设接口。
        3.AMBA AXI(高级可扩展接口):AXI是一种高性能、高带宽的总线协议,专为连接具有高数据吞吐量需求的复杂IP模块而设计。它支持无序事务、多个未完成事务以及独立的读写数据通道,从而实现高效且并发的数据传输。
        ARM决定采用AMBA的原因有以下几点:
        1.标准化:AMBA提供了一种统一的、标准化的片上互连规范。这意味着在使用AMBA的系统中,不同的IP模块可以遵循相同的通信协议和接口规范,从而简化了系统集成的复杂性。
        2.可扩展性:AMBA规范具有良好的可扩展性,能够满足不同系统设计的需求。它提供了多种规范,如高性能的AHB、低功耗的APB和高带宽的AXI,使得设计人员可以根据系统的要求选择合适的总线协议。
        3.高性能:AMBA规范针对高性能和高带宽应用进行了优化。通过支持诸如突发传输、流水线和无序事务等功能,AMBA可以提供高效的数据传输,满足处理器和外设之间的快速通信需求。
        4.灵活性:AMBA规范允许设计人员根据具体应用需求进行定制。通过使用AMBA的IP模块,可以轻松地进行系统扩展和修改,以适应不同的设计要求和市场需求。
        5.行业广泛应用:AMBA是业界广泛采用的片上互连规范之一。许多芯片设计和系统集成都使用AMBA作为其互联标准,这为开发者提供了更多的工具和支持资源。
        综上所述,ARM选择采用AMBA的主要原因是为了提供一种标准化、可扩展且高性能的片上互连解决方案,简化系统设计、提高数据传输效率,并为设计者提供更大的灵活性和行业支持。

二、Linux AMBA驱动介绍

           AMBA Linux驱动程序是Linux内核中的软件组件,用于支持与基于AMBA的IP模块或外设进行交互。这些驱动程序实现了Linux内核与系统中特定的AMBA设备之间的通信和控制。它们屏蔽了AMBA总线协议的底层细节,并提供了标准化的接口,用于访问和利用连接的外设。
        AMBA Linux驱动程序通常包括以下关键组件:
        1.设备驱动程序(Device Driver):设备驱动程序是实现与特定AMBA设备交互的核心组件。它定义了设备的功能、特性和操作方式,并提供了与设备进行通信的接口。设备驱动程序负责与硬件进行交互,包括读取和写入寄存器、配置设备参数以及处理中断等操作。
        2.平台驱动程序(Platform Driver):平台驱动程序提供了与AMBA总线平台相关的初始化和管理功能。它负责识别和注册连接到AMBA总线的设备,并为这些设备分配资源和配置参数。平台驱动程序还可以处理总线特定的事件和操作,以确保设备在系统启动和运行过程中正常工作。
        3.总线驱动程序(Bus Driver):总线驱动程序处理AMBA总线的底层操作和管理。它负责管理总线上的设备探测、地址映射、数据传输和错误处理等功能。总线驱动程序提供了与AMBA总线的物理层交互的接口,并确保设备在总线上的正常通信和协调。通过这些组件,AMBA Linux驱动程序实现了与AMBA设备之间的有效通信和控制。它们提供了一致的编程接口和抽象层,使开发者能够方便地编写应用程序和驱动程序,以实现对AMBA外设的访问和操作。
        总的来说,AMBA驱动框架是为了让使用ARM片内外设的公司更容易使用基于片内外设的驱动程序。

三、Linux AMBA驱动框架分析

        1、amba设备添加到总线

        内核在启动开始后,会依次解析设备树的device node,并创建platform device,其流程如下:    

//根据不同的设备属性,创建不同的设备类型
of_platform_bus_create-> 
  //如果设备属于amba设备,则创建amba device
  of_amba_device_create->
    //amba设备申请
    amba_device_alloc->
    //获取amba设备的periphid(可能该参数设备树不存在)
    of_get_property(.., "arm,primecell-periphid",..)
    //向amba总线增加新的设备
    amba_device_add->
      //是否可以成功添加
      amba_device_try_add->
        //获取amba设备的寄存器资源
        tmp = ioremap(dev->res.start, size)
        //获取amba设备的periphid(该参数设备树不存在,这里也可以获取到)
        pid = readl();
      //如果可以,则加入amba总线链表
      list_add_tail

        2、amba驱动添加到总线并匹配amba device

        下面以片内spi amba控制器驱动举例,源码位置:drivers/spi/spi-pl022.c

        ①、amba 设备驱动相关的数据结构
//amba id结构
static const struct amba_id pl022_ids[] = {
  ...
    {
        /*
         * ST Micro derivative, this has 32bit wide
         * and 32 locations deep TX/RX FIFO
         */
        .id    = 0x01080022, //当前我的芯片使用的片内spi控制器amba id
        .mask    = 0xffffffff,
        .data    = &vendor_st,
    },
  ...
    { 0, 0 },
};
//amba_driver结构 
static struct amba_driver pl022_driver = {
    .drv = {
        .name    = "ssp-pl022",
        .pm    = &pl022_dev_pm_ops,
    },
    .id_table    = pl022_ids,
    .probe        = pl022_probe,
    .remove        = pl022_remove,
};
//amba总线数据结构
struct bus_type amba_bustype = {
    .name        = "amba",
    .dev_groups    = amba_dev_groups,
    .match        = amba_match,
    .uevent        = amba_uevent,
    .dma_configure    = platform_dma_configure,
    .pm        = &amba_pm,
};
         ②、amba 设备驱动注册到amba总线
//pl022_driver控制器驱动注册到amba总线
amba_driver_register(&pl022_driver)->
  drv->drv.bus = &amba_bustype
  drv->drv.probe = amba_probe
  drv->drv.remove = amba_remove
  drv->drv.shutdown = amba_shutdown
  //驱动注册,总线类型为amba
  driver_register(&drv->drv)  
        ③、amba 驱动匹配amba设备
driver_register->
  //driver添加到ambabus
  bus_add_driver->
    //drivers在总线上搜索对应的device资源
    driver_attach->
      bus_for_each_dev(drv->bus, ..., __driver_attach)->
        //在总线上循环遍历,实际就是遍历链表
        klist_iter_init_node(); 
           fn(dev, data)(这里的fn就是__driver_attach函数)->
            //match device
            amba_match(dev, data)->
              amba_lookup(pcdrv->id_table, pcdev)->
                //如果driver和device的amba id相同,那么匹配成功
                if (((dev->periphid & table->mask) == table->id)
            //匹配成功向下执行driver的probe函数    
            device_driver_attach->
              driver_probe_device->
                //最终执行drvier的probe函数
                really_probe->
                  //到这里,匹配的流程结束,进入到设备的初始化
                  pl022_probe


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值