ARM AMBA协议详解与演化

需积分: 13 2 下载量 45 浏览量 更新于2024-07-09 收藏 1.3MB PDF 举报
"【极术公开课】Jay Wu-AMBA 协议.pdf 是一份关于AMBA协议的课程资料,涵盖了AMBA协议的历史演变、主要组件以及相关扩展协议的介绍。" AMBA(Advanced Microcontroller Bus Architecture)协议是ARM公司开发的一系列开放标准,用于微处理器之间的片上通信。这份资料详细介绍了AMBA协议的发展历程和主要特点。 1. **AMBA协议历史与版本**: - AMBA协议始于1997年,最初是为了解决低带宽外设的连接问题,推出了Advanced Peripheral Bus (APB)。 - 1999年,AMBA2引入了Advanced High-performance Bus (AHB),支持更高的性能和多主控器环境。 - 2003年,AMBA3进一步升级,加入了AXI(Adv.eXtensible Interface),以支持更灵活的数据传输,如独立的地址/数据阶段、突发传输和多未完成请求。 - 随后,AMBA4引入了Advanced Coherency Extensions (ACE),提供了跨多核集群的系统范围一致性。 - AMBA5则带来了Coherent Hub Interface (CHI)等新特性,以应对更高的性能需求和可扩展性,并引入了对低功耗和电源管理的支持。 2. **AMBA协议组件**: - APB:面向低带宽外围设备,适用于简单、低速的系统组件。 - AHB:为高性能主控器设计,支持64/128位数据宽度和多主控器配置,还有针对单主控器的简化版本AHB-Lite。 - AXI:作为AXI3和AXI4的基础,支持分离的地址/数据阶段、突发传输、多个未完成的地址和乱序响应,适用于各种复杂系统。 - ACE:在AXI基础上增加了系统一致性,特别适用于多核环境。 - CHI:为实现可扩展的协调一致性协议而设计,具有分层架构。 - ATB (Adv.Trace Bus) 和DTI (Distributed Translation Interface) 用于调试和翻译接口,如与PCIe Root Complex的交互。 - LTI (Local Translation Interface) 用于I/O主控器和TBU之间的连接,而LPI (Low-power interface for clock) 则是针对低功耗场景设计的接口。 3. **AMBA协议的演进**: - 随着技术的进步,AMBA协议不断演进以满足更高的带宽需求、系统一致性、可扩展性和低功耗要求。例如,AHB5和APB3/4提升了性能,而AXI5和CHI.C则扩展了接口功能。 - DTI在AMBA5中扮演重要角色,它改善了与外部接口如PCIe的通信,支持ATS(Address Translation Services)功能。 这份资料深入探讨了AMBA协议的各个方面,对于理解嵌入式系统中的片上通信和设计有着极大的帮助,适合那些想要深入了解AMBA协议及其在现代SoC设计中应用的学习者。

static int sbsa_uart_probe(struct platform_device *pdev) { struct uart_amba_port *uap; struct resource r; int portnr, ret; int baudrate; / * Check the mandatory baud rate parameter in the DT node early * so that we can easily exit with the error. */ if (pdev->dev.of_node) { struct device_node *np = pdev->dev.of_node; ret = of_property_read_u32(np, "current-speed", &baudrate); if (ret) return ret; } else { baudrate = 115200; } portnr = pl011_find_free_port(); if (portnr < 0) return portnr; uap = devm_kzalloc(&pdev->dev, sizeof(struct uart_amba_port), GFP_KERNEL); if (!uap) return -ENOMEM; ret = platform_get_irq(pdev, 0); if (ret < 0) { if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "cannot obtain irq\n"); return ret; } uap->port.irq = ret; #ifdef CONFIG_ACPI_SPCR_TABLE if (qdf2400_e44_present) { dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n"); uap->vendor = &vendor_qdt_qdf2400_e44; } else #endif uap->vendor = &vendor_sbsa; uap->reg_offset = uap->vendor->reg_offset; uap->fifosize = 32; uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.ops = &sbsa_uart_pops; uap->fixed_baud = baudrate; snprintf(uap->type, sizeof(uap->type), "SBSA"); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ret = pl011_setup_port(&pdev->dev, uap, r, portnr); if (ret) return ret; platform_set_drvdata(pdev, uap); return pl011_register_port(uap); }linux内核uart驱动在设备注册时,使用acpi表定义的波特率来初始化串口,请根据我的要求和上述代码,在代码中添加这一功能

148 浏览量

struct ring_buffer { int head; int tail; struct msg *data; int size; unsigned int capacity; }; struct msg { u16 module_id; u16 cmd_id; u16 cmd_subid; u16 complete; u8 data[128]; };struct pokemon_uart_port { struct uart_port port; struct clk *clk; const struct vendor_data vendor; unsigned int im; / interrupt mask / unsigned int old_status; unsigned int fifosize; unsigned int old_cr; / state during shutdown */ unsigned int fixed_baud; struct ring_buffer tx_buf; struct ring_buffer rx_buf; char type[12]; };struct ring_buffer ring_buffer_init(unsigned int capacity) { struct ring_buffer rbuf=kmalloc(sizeof(struct ring_buffer),GFP_KERNEL); rbuf->capacity=capacity; rbuf->head = rbuf->size=0; rbuf->tail = capacity - 1; rbuf->data = kmalloc(rbuf->capacity * sizeof(struct msg), GFP_KERNEL); printk(KERN_DEBUG "ring_buffer create successfully!/n"); return rbuf; }static int pokemon_uart_probe(struct amba_device *dev, const struct amba_id *id) { struct pokemon_uart_port *pup; struct vendor_data *vendor = id->data; int portnr, ret; portnr = pokemon_find_free_port(); if (portnr < 0) return portnr; pup = devm_kzalloc(&dev->dev, sizeof(struct pokemon_uart_port), GFP_KERNEL); if(!pup) return -ENOMEM; pup->clk = devm_clk_get(&dev->dev, NULL); if(IS_ERR(pup->clk)) return PTR_ERR(pup->clk); pup->port.irq = dev->irq[0]; pup->port.line = portnr; pup->vendor = vendor; pup->fifosize = 32; pup->port.iotype = pup->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; pup->port.ops = &pokemon_uart_ops; snprintf(pup->type, sizeof(pup->type), "PL011 rev%u", amba_rev(dev)); pup->tx_buf = ring_buffer_init(10); pup->rx_buf = ring_buffer_init(10); ret = pokemon_setup_port(&dev->dev, pup, &dev->res, portnr); if (ret) return ret; amba_set_drvdata(dev, pup); return pokemon_register_port(pup); }检查一下这段linux内核驱动代码中,有无代码逻辑和格式错误,如果有,请给出修改之后的代码

169 浏览量