本文介绍了ARM cortex A9 中的处理器间中断(如何在 Linux 中为软件生成的中断 (ARM) 编写处理程序?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读到 ARM 中软件生成的中断用作处理器间中断.我还可以看到其中 5 个中断已在使用中.我也知道 ARM 提供了 16 个软件生成的中断.

I read that the Software generated interrupts in ARM are used as Inter-processor interrupts. I can also see that 5 of those interrupts are already in use. I also know that ARM provides 16 Software generated interrupts.

在我的应用程序中,我在 ARM-cortex 内核和 Linux 上运行裸机应用程序.我想将一些数据从运行裸机应用程序的核心传送到运行 Linux 的核心.我计划将数据复制到片上内存(共享),我将在核心(运行 linux)上触发 SGI 以指示一些数据可供它处理.现在我可以从核心(运行裸机应用程序)生成 SGI.但是为了在 linux 端处理中断,我不确定 SGI IRQ 号是免费的,我也不确定我是否可以直接使用 IRQ 号(通常 SGI 是 0-15).有人知道如何在 Linux 中为 SGI 编写处理程序吗?

In my application i am running a bare metal application on of the ARM-cortex cores and Linux on the other. I want to communicate some data from the core running bare metal application to the core which is running Linux. I plan to copy the data to the on chip memory ( which is shared) and I will trigger a SGI on the Core ( running linux) to indicate some data is available for it to process. Now I am able to generate the SGI from the core ( running bare-metal application ). But for handling the interrupt in the linux side, I am not sure of the SGI IRQ numbers which are free and I am also not sure whether i can use the IRQ number directly ( in general SGI are from 0-15). Does any one have an idea how to write a handler for SGI in Linux?

这是对上述文本的重新措辞,因为问题已针对 关闭SSCE 原因.Cortex-A CPU 用于多 CPU 系统.ARM通用中断控制器 (GIC) 监视所有全局中断并将它们分派到特定 CPU.为了让各个 CPU 相互发送信号,软件生成的中断 (SGI) 从一个内核发送到另一个内核;这使用外设私有中断 (PPI).这个问题是,

This is a re-wording of the above text, because the question was closed for SSCE reasons. The Cortex-A CPUs are used in multi-CPU systems. An ARM generic interrupt controller (GIC) monitors all global interrupts and dispatches them to a particular CPU. In order for individual CPUs to signal each other, a software generated interrupt (SGI) is sent from one core to the other; this uses peripheral private interrupts (PPI). This question is,

如何实现可以接收 SGI 作为 PPI 的 Linux 内核驱动程序?

推荐答案

由于您没有提供 Linux 版本,我假设您使用的是最新的(或至少是最新的).ARM GIC 有 设备树绑定.通常,您需要在设备树节点中指定 SGI 中断号,

As you didn't give the Linux version, I will assume you work with the latest (or at least recent). The ARM GIC has device tree bindings. Typically, you need to specify the SGI interrupt number in a device tree node,

 ipc: ipc@address {
        compatible = "company,board-ipc"; /* Your driver */
        reg = <address range>;
        interrupts = <1 SGI 0x02>;  /* SGI is your CPU interrupt. */
        status = "enabled";
 };

interrupt 节中的第一个数字表示 PPI.SGI 可能在 0-15 之间,因为这是 SGI 中断路由的地方(至少在 Cortex-A5 上).

The first number in the interrupt stanza denotes a PPI. The SGI will probably be between 0-15 as this is where the SGI interrupts are routed (at least on a Cortex-A5).

然后你可以在你的驱动程序中使用platform_get_irq()来获取PPI(外设私有中断).我猜 address 是您希望进行通信的共享内存(物理);也许 reg 不合适,但我认为它会起作用.该区域将由 Linux MMU 重新映射,您可以使用它,

Then you can just use the platform_get_irq() in your driver to get the PPI (peripheral private interrupt). I guess that address is the shared memory (physical) where you wish to do the communications; maybe reg is not appropriate, but I think it will work. This area will be remapped by the Linux MMU and you can use it with,

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mem = devm_ioremap_resource(dev, res);

上面设备树中的地址是物理地址的十六进制值.platform_get_irq() 应该返回一个 irq 编号,您可以将其与 request_irq() 系列函数一起使用.只需将其与您的日常工作联系起来即可.

The address in the device tree above is a hex value of the physical address. The platform_get_irq() should return an irq number which you can use with the request_irq() family of functions. Just connect this to your routine.

不幸的是,Linux 禁止低于 16 的中断irq-gic.c.例如,gic_handle_irq(),将处理程序限制为 16 到 1020 之间的中断.如果启用了 SMP,则为感兴趣的中断调用 handle_IPI().gic_raise_softirq() 可用于发出中断信号.要使用当前的 Linux 处理 SGIsmp.c 需要额外的 enum ipi_msg_type 值和在 handle_IPI().看起来较新的内核(也许是 3.14+?)可能会向 smp.c 添加一个 set_ipi_handler() 以使这样的修改不再需要.

Unfortunately, interrupts below 16 are forbidden by the Linux irq-gic.c. For example, gic_handle_irq(), limits handler to interrupts between 16 and 1020. If SMP is enabled, then handle_IPI() is called for the interrupts of interest. gic_raise_softirq() can be used to signal an interrupt. To handle the SGI with the current Linux, smp.c needs additional enum ipi_msg_type values and code to handle these in handle_IPI(). It looks like newer kernels (3.14+ perhaps?) may add a set_ipi_handler() to smp.c to make such a modification unneeded.

这篇关于ARM cortex A9 中的处理器间中断(如何在 Linux 中为软件生成的中断 (ARM) 编写处理程序?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 15:18