簡體   English   中英

ARM A7 Linux原始中斷處理可能嗎?

[英]ARM A7 Linux raw interrupt handling possible?

我想編寫一個開源的核心驅動程序來控制Linux中的步進電機。 在這種情況下,尤其是3D打印機。

基本思想是驅動程序在一個IO端口上保留引腳,然后立即操作這些引腳。 它接收一個充滿“切換此,切換”值的緩沖區,然后使用硬件計時器將這些值發送到端口。

現在的問題是:有沒有辦法盡快處理特定的硬件中斷?

有問題的芯片是Allwinner H3,我正在使用所述芯片的TMR1資源(IRQ 51)。 我可以很好地使用它,它也可以用作中斷:

static irqreturn_t stepCore_timer_interrupt(int irq, void *dev_id)
{
        writel(TMR1_IRQ_PEND, TMR_IRQ_ST_VREG);
        icnt++;

        porta_state = readl(PA_VDAT);
        porta_state &= porta_mask;

        if(icnt & 0x00000001)
        {
            porta_state |= 0x00000001;
        }

        writel(porta_state, PA_VDAT);

        return IRQ_HANDLED;
}

static struct irqaction stepCore_timer_irq = {
        .name = "stepCore_timer",
        .flags = IRQF_DISABLED | IRQF_NOBALANCING , IRQF_PERCPU,
        .handler = stepCore_timer_interrupt,
        .dev_id = NULL,
};

static void stepCore_timer_interrupt_setup(void)
{
    int ret;
    u32 val;

    writel( 24000000, TMR1_INTV_VALUE_VREG );
    writel( ( TMR1_MODE_CONTINUOUS | TMR1_CLK_PRES_1 | TMR1_CLK_SRC_OSC24M ), TMR1_CTRL_VREG );

    ret = setup_irq(SUNXI_IRQ_TIMER1, &stepCore_timer_irq);
    if (ret)
            printk("%s: ERROR: failed to install irq %d\n", __func__, SUNXI_IRQ_TIMER1);
    else
            printk("%s: irq %d installed\n", __func__, SUNXI_IRQ_TIMER1);

    ret = irq_set_affinity_hint(SUNXI_IRQ_TIMER1, cpumask_of(3));
    if (ret)
            printk("%s: ERROR: failed to set irq affinity for irq %d\n", __func__, SUNXI_IRQ_TIMER1);
    else
            printk("%s: set irq affinity for irq %d\n", __func__, SUNXI_IRQ_TIMER1);
    /* Enable timer0 interrupt */
    val = readl(TMR_IRQ_EN_VREG);
    writel(val | TMR1_IRQ_EN, TMR_IRQ_EN_VREG);

}

TMR1否則未使用(事實上,我必須自己添加),到目前為止工作。 但是,在處理相當簡單的IRQ例程時存在相當長的延遲。 由於我想生成一些可用於3D打印機的代碼,我非常喜歡更“穩定”的定時器中斷。

所以,我的問題是:有沒有辦法在Linux中擁有一個具有最高優先級的非常短的IRQ例程? 甚至根本不關心Linux調度程序,只是“做它的事情”? 基本上是一個原始的IRQ處理程序,忽略Linux認為它應該是什么?

無論如何,它運行的核心專門用於完成該任務。 處理程序將盡可能短:從數組中獲取u32,將其寫入端口,完成。

我希望有一些東西可以忽略Linux的其余部分。 是的,我知道這不是辦法。 但這是針對一個相當特殊的情況,所以我對調整常規內核源代碼以滿足這些需求沒有任何疑慮。

哦,這提醒我,內核是3.4.112,帶有合適的preempt-rt補丁。

任何幫助是極大的贊賞。

問候,

克里斯

以下是此問題的一般解決方案。 您可以編寫一個內核模塊,它將覆蓋現有的中斷處理例程,並將被您自己的例程替換,您可以在其中處理您感興趣的irq並將所有irq重定向到現有的內核中斷處理例程。 對於x86 arch,您可以獲得低級CPU指令,以獲取中斷描述例程( lidt )的現有地址。 我相信它也應該可以用於ARM。 現在,Linux具有CPU隔離技術isolcpus通過利用這種技術,您可以將CPU從調度程序域中取出,即在該特定CPU上不會安排任務,直到您指定要在該特定CPU上運行的任務(使用任務集)。 將CPU從調度程序域中取出后,您可以獲得對該隔離CPU的仿射中斷技術的幫助,您可以通過/proc/irq/IRQ_NUMBER/smp_affinity 現在,所有的中斷都將由這個隔離的CPU處理,並且100%專用於該中斷。 使用您自己的IRQ例程,您可以完全控制中斷處理。

希望這會有所幫助!

您是否考慮過使用FIQ? 我們有一篇關於它的博客文章: http//free-electrons.com/blog/fiq-handlers-in-the-arm-linux-kernel/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM