gpt4 book ai didi

embedded - 如何在 C 或内联汇编中设置 ARM 中断向量表分支?

转载 作者:行者123 更新时间:2023-12-04 15:58:15 26 4
gpt4 key购买 nike

有人可以向我展示如何在没有 RTOS 或 Linux 操作系统的裸机环境中使用 C 或内联汇编设置 ARM9 中断向量表的示例吗?

具体来说,如何使用内联汇编或 C 将分支设置为以 C 编码的 IRQ 中断处理程序 ISR?

/// timer1 64-bit mode interrupt handler connected to TINT2 interrupt=#34
/// \todo I think I need to ACK it once I get working
interrupt void interruptHandlerTimer1(void) {
printf("\n [* ISR *] \n");
// ACK TINT2 interrupt #34
AINTC ->IRQ1 = 1 << (34 - 32);
}
void main(void) {

TIMER1 ->TCR = 0x00000000;
// TGCR: TIMMODE=0 64-bit GP, TIM34RS=TIM12RS=1
TIM0ER1 ->TGCR = 0x00000003;
TIMER1 ->TIM34 = 0x00000000;
TIMER1 ->TIM12 = 0x00000000;
TIMER1 ->PRD34 = 0x00000000;
TIMER1 ->PRD12 = 0x0000ffff;
// TCR: inc until period match, then reset
TIMER1 ->TCR = (2 << 6);

// This is wrong.
// I think I need to insert opcode or assembly to branch to interruptHandlerTimer1 ?
// AINTC ->EABASE located @ 0x00000000
uint32_t** ptrEabase = (uint32_t**) (AINTC ->EABASE);
ptrEabase[34] = (uint32_t*) (interruptHandlerTimer1);

// Set INT34 TINT2 to IRQ priority 2
AINTC ->INTPRI4 = 0x00000200;
// Enable INT34
AINTC ->EINT1 = (1 << (34 - 32));

// Enable IRQ in CPSR
// "TMS32DM644x ARM Subsystem", 3.3 Processor Status registers
asm(" ;Enable IRQ in CPSR");
asm(" mrs r0, cpsr");
asm(" bic r0, r0, #0x80");
asm(" msr cpsr_c, r0");

// I expected to see " [* ISR *] " print
// when TIMER1->TIM12 reaches 0x0000ffff
while (1) {
printf("%08x %08x\r\n", TIMER1 ->TIM34, TIMER1 ->TIM12);
}
}

Interrupt Entry Table

预先感谢您提供任何提示或方向。

很难找到 ARM9 的裸机开发示例。

埃德
  • TI TMS320DM6466
  • Code Composer Studio v5.5
  • 最佳答案

    请注意,此答案仅适用于 Cortex 系列 ARM 处理器

    我看到您不久前为此找到了解决方案,希望这对将来遇到类似问题的任何人都有用。

    设置中断向量的方法有很多种,它们因硬件而异,某些平台可能需要额外的步骤。下面的解决方案在 ARM Cortex 微 Controller 上通常是可行的,并且与编译器无关。

    #include <string.h>

    //Size of vector table, note yours is probably 16 entries
    #define VECTOR_TABLE_ENTRIES 4
    //Base address in MCU memory of vector table (by default 0x0 for ARM9)
    #define HARDWARE_VECTOR_TABLE_ADDRESS 0x00000000

    typedef void(*isr_vector)(void);

    void myIsr1();
    void myIsr2();
    void myIsr3();
    void myIsr4();

    static isr_vector s_vector_table[VECTOR_TABLE_ENTRIES] =
    {
    myIsr1,
    myIsr2,
    myIsr3,
    myIsr4
    };

    /**
    * Load interrupt vector to correct area in system memory, call on startup
    */
    void load_vector_table()
    {
    memcpy(HARDWARE_VECTOR_TABLE_ADDRESS, s_vector_table, sizeof(isr_vector));
    }

    void myIsr1()
    {

    }

    ...

    如果您只需要向表中添加一个条目,您可以使用以下内容:
    void set_vector_table_entry(int index, isr_vector vector)
    {
    *(HARDWARE_VECTOR_TABLE_ADDRESS + (sizeof(isr_vector) * index)) = vector;
    }

    在一天结束时设置表是简单的部分,您所做的就是加载一个指向特定位置的函数指针表,困难的部分是在正确的寄存器中设置正确的位以启用中断并清除在他们之后。

    进一步注意,中断函数通常需要使用编译器特定的关键字或编译指示来声明,以确保编译器生成正确的代码。这是因为调用中断向量时的函数调用和返回处理通常与调用普通函数时不同。

    请注意,ARMv7 体系结构支持重新映射向量表,这非常有用,这种方法为表的对齐添加了约束,尽管这反过来需要编译器/链接器特定的指令。

    关于embedded - 如何在 C 或内联汇编中设置 ARM 中断向量表分支?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21435141/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com