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

2023-12-19

有人可以向我展示如何在没有 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);
        }
    }

预先感谢您的任何提示或指导。

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

Ed

  • TI TMS320DM6466
  • 代码作曲家工作室 v5.5

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

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

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

    #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 架构支持重新映射向量表,这非常有用,这种方法增加了对表对齐的约束,但这反过来又需要编译器/链接器特定的指令。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 C 或内联汇编中设置 ARM 中断向量表分支? 的相关文章

  • 适用于arm(cortex-m3)的位置独立可执行文件(-pie)

    我正在使用codesourcery g lite 基于gcc4 7 2版本 为stm32 Cortex m3 编程 我希望动态加载可执行文件 我知道我有两个选择 1 可重定位的elf 需要一个elf解析器 2 具有全局偏移寄存器的位置无关代
  • 手臂“版本”之间的差异? (仅限 ARMv7)

    基本上我想知道ARMv7l和ARMv7之间的区别hl 我有一个带有armv7l的arm处理器 并且有很多armv7的rpmhl 我完全不知道我必须搜索什么才能获得相关信息 这个 后缀 叫什么 还有其他类型吗 他们的做法有何不同 我假设它指示
  • RAM 存储二进制数和汇编语言的冒泡排序

    我必须使用 ARM v7 执行一个例程 在 RAM 内存中存储 10 个二进制数 然后使用冒泡排序对这些数字从高到低进行排序 我应该如何开始 func bubbleSortAscendingU32 ldr r3 r0 4 mov r1 9
  • DSP 库 - RFFT - 奇怪的结果

    最近我一直在尝试在我的STM32F4 Discovery评估板上进行FFT计算 然后将其发送到PC 我已经调查了我的问题 我认为我对制造商提供的 FFT 函数做错了 我正在使用 CMSIS DSP 库 现在我一直在用代码生成样本 如果工作正
  • ARM Cortex A8 PMNC 读取在启用后也给出 0.. 有什么想法/建议吗?

    MODULE LICENSE GPL MODULE DESCRIPTION user mode access to performance registers int init arm init void unsigned int valu
  • C 嵌入式应用程序中 time() 函数的问题

    我在用time 在 ARM 微控制器上 处理器一到达此函数就会重新启动 奇怪的是 当我处于调试模式时 代码运行得很好 但一旦我想将其应用到独立模式 我就会遇到重置 我是否忽略了什么 这个功能有替代品吗 代码部分是这样的 include
  • 我可以从哪里开始使用可编程硬件?

    一段时间以来 我一直渴望至少学习一点有关硬件编程的知识 并想在这里提出要求以获得一些起点 我是一位相当有成就的程序员 具有 Delphi 和 Objective c 经验 但从未听过设备端口 中断 我什至不知道术语 更不用说对硬件进行编程了
  • Linux malloc() 在 ARM 和 x86 上的行为是否不同?

    这个网站上有很多关于内存分配的问题 但是我 找不到专门解决我的问题的人 这 问题 https stackoverflow com questions 19148296 linux memory overcommit details似乎最接近
  • C 相同结构不同尺寸

    我的问题与此相关 c 在struct中定义不同大小的数组 https stackoverflow com questions 17956697 c define arrays in struct with different sizes 但
  • M1 MacBook Pro 上的 Android Studio 无法使用 ABI armeabi-v7a 模拟系统映像

    我的 M1 Macbook Pro 上的 Android Studio 可以很好地模拟 ABI arm64 v8a 的所有系统映像 API 24 29 30 31 但是 它无法使用 ABI armeabi v7a 运行所有映像 例如 API
  • 用于嵌入式服务器的 Web 技术

    我最近开始了一个针对嵌入式设备的新 Web 开发项目 并希望征求一些有关使用技术的建议 该设备将提供 HTML 页面 其中包括用于从 JSON 服务器检索数据的 AJAX 代码 我们暂时使用 Cherokee 作为 Web 服务器 但我们并
  • C 中的可移植函数(无汇编)返回其堆栈帧的大小

    用 C 编写一个可移植函数 无需汇编 返回其堆栈帧的大小 int stackframe size 尝试如下解决 该函数在使用 VS 2010 编译时返回 228 字节 有没有办法验证其正确性 int stackframe size int
  • ARM 调用约定是否允许函数不将 LR 存储到堆栈中?

    正如标题所示 我在理解 ARM 架构的调用约定时遇到问题 特别是 我仍然很难知道当你调用子程序时 LR 寄存器会发生什么 我认为 当您进入子程序时 处理 LR 寄存器的最明显 最安全的方法是将其存储到堆栈中 但该行为没有出现在文档中 因此我
  • 如何使用 Neon SIMD 将无符号字符转换为有符号整数

    如何转换变量的数据类型uint8 t to int32 t使用霓虹灯 我找不到执行此操作的任何内在因素 假设您想要将 16 x 8 位整数的向量转换为 4 个 4 x 32 位整数的向量 您可以通过首先解压缩为 16 位 然后再次解压缩为
  • ELF 文件头

    关于 elf 文件头的一个简单问题 我似乎找不到任何关于如何在 elf 头中添加 更改字段的有用信息 我希望能够更改幻数并向标题添加构建日期 以及可能的其他一些内容 据我了解 链接器创建标头信息 但我在 LD 脚本中没有看到任何引用它的内容
  • 产生并处理软件中断

    有人可以告诉我如何在Linux下生成软件中断然后用request irq处理它吗 或者也许这是不可能的 您可以使用软中断来代替 您可以通过编辑 include linux interrupt h 来定义您的 sofirq 然后使用函数 ra
  • stm32中如何在同一个回调函数中从不同的uart获取数据

    我使用的是stm32f407控制器 我正在使用 2 个 uart 2 3 我第一次被中断 但第二次我在 uart 2 上被中断 我在 uart3 上没有被中断 下面是我的回调函数 void HAL UART RxCpltCallback U
  • qemu kvm:如何获取性能监控中断?

    我在操作系统内核中编写了一些函数 以便在指令计数器溢出时发出性能监控中断 PMI 它在我的机器 Intel core i5 上运行良好 但是当我使用 qemu 在 qemu 上运行它时 qemu system x86 64 enable k
  • Beaglebone Black 的 U-boot 无法构建 - 目标 CPU 不支持 THUMB 指令

    我正在尝试按照 Chris Simmonds 的 掌握嵌入式 Linux 编程 中的说明为 Beagle Bone Black 构建 u boot 我已经构建了交叉工具链 现在正在尝试使用该工具链构建 Das U boot 但由于不支持 T
  • ARM 系统调用的接口是什么?它在 Linux 内核中的何处定义?

    我读过有关 Linux 中的系统调用的内容 并且到处都给出了有关 x86 架构的描述 0x80中断和SYSENTER 但我无法追踪 ARM 架构中系统调用的文件和进程 任何人都可以帮忙吗 我知道的几个相关文件是 arch arm kerne

随机推荐