
说明vectors.S不存放中断向量表向量表在startup_gcc.S的__Vectors段本文件实现异常/中断入口、上下文保存、软件分发 ISR等底层逻辑。二者通过mtvec/mtvt在启动时关联。1. 在启动链中的位置la a0, Default_Handler ori a0, a0, 3 csrw mtvec, a0 la a0, __Vectors csrw mtvt, a0CSR指向作用mtvecDefault_Handler低 2 位 3异常统一入口模式 3 表示与 CLIC/向量扩展配合mtvt__Vectors中断向量表IRQn → 处理函数地址sp初值g_top_irqstack中断专用栈顶__Vectors中 0–15 多为Default_Handler7 为Default_IRQHandler16 起外设 IRQ 多为Default_IRQHandler见startup_gcc.S。整体路径可概括为异常 mtvecIRQ mtvt 表项是否是 中断否 同步异常硬件 trap/IRQ入口Default_HandlerDefault_IRQHandlermcause低10位24?NMI_Handler → g_nmivectortrapmcause最高位1?保存寄存器 → trap_cg_irqvector 分发 ISR2. BSS栈与辅助变量第 13–39 行.section .bss ... g_base_irqstack: .space AIC_INTERRUPTSTACK_SIZE g_top_irqstack: ... g_trap_sp: .long 0 ... #ifdef KERNEL_BAREMETAL g_base_normalstack / g_top_normalstack #endif irq_nested_level: .long 0符号含义g_base_irqstack~g_top_irqstack4KBAIC_INTERRUPTSTACK_SIZE中断栈Reset_Handler把sp设为g_top_irqstackg_trap_sp异常上下文保存区指针trap里用g_trap_sp - 132作帧g_*_normalstack仅 baremetal普通任务栈irq_nested_level嵌套计数本文件未改可能供他处使用3.Default_IRQHandler统一外设中断入口第 47–163 行所有指向Default_IRQHandler的向量表项都会进入这里再按mcause软件查表调用具体 ISR。3.1 T-Head 硬件压栈ipush/ipopDefault_IRQHandler: #ifdef __riscv_xthead ipush #else .long 0x0040000b #endif有 T-Head 扩展用ipush/ipop由硬件保存/恢复部分上下文。否则嵌入自定义指令编码0x0040000b/0x0050000b与 E907 工具链约定一致。3.2 可选栈回溯帧、FPU_ENABLE_BACK_TRACE_STACK__NO_OMIT_FRAME_POINT_在栈上建小帧保存s0、mepc便于 C 侧回溯。ARCH_RISCV_FPU保存/恢复ft0–ft11、fa0–fa7共 20 个浮点寄存器调用约定中的 caller-saved 浮点部分。3.3 RT-Thread / FreeRTOS 钩子#if defined(KERNEL_RTTHREAD) la t0, rt_interrupt_enter jalr t0 #elif defined(KERNEL_FREERTOS) la t0, aicos_irq_enter进入 ISR 前通知内核“进入中断”退出时调用rt_interrupt_leave/aicos_irq_exit用于中断嵌套计数、调度器临界区等。3.4 核心软件向量分发csrr t1, mcause andi t1, t1, 0x3FF slli t1, t1, 2 la t0, g_irqvector add t0, t0, t1 lw t2, (t0) mv a0, t1 srli a0, a0, 2 /* a0 irq_num */ la t0, g_irqdata add t0, t0, t1 lw a1, (t0) /* a1 irq_data */ ... jalr t2 /* handler(irq_num, irq_data) */逻辑mcause[9:0]→ IRQ 编号与aic_soc.h中IRQn一致如CORET_IRQn7、DMA_IRQn32。g_irqvector[irq_num]→ 函数指针aic_drv_irq.c里drv_irq_register填充。g_irqdata[irq_num]→ 第二个参数。g_irqcnt[irq_num]→ 统计中断次数drv_irq_show等可用。默认初始化drv_irq_vectors_init把 0…MAX_IRQn-1设为Default_HandlerCORET_IRQn设为SysTick_Handler未注册的外设 IRQ 若仍进Default_IRQHandler会调到Default_Handler→trap→ 打印异常。与硬件向量表的关系表项地址固定为Default_IRQHandler真正驱动 ISR 在运行时通过g_irqvector切换无需改__Vectors。4.trap异常 vs 中断分流第 173–321 行trap: addi sp, sp, -4 sw t0, 0x0(sp) csrr t0, mcause blt t0, x0, .Lirq /* MSB1 → 中断 */ ... /* 同步异常保存 x1-x31、mepc、mstatus 到 132 字节帧 */ la a5, trap_c jalr a5 ... j . /* 异常后死循环 */ .Lirq: ... j Default_IRQHandlerRISC-V 约定mcause最高位为 1表示中断为 0 表示同步异常。中断恢复t0、sp后跳到Default_IRQHandler与向量表路径汇合。同步异常非法指令、访存错误、ecall 等在g_trap_sp - 132或AIC_BACKTRACE_DEBUG时用当前sp保存 GPR 帧故意不保存 x5t0最后把临时保存的t0写入帧偏移 16调用 C 函数trap_c(regs)trap_c.c打印mcause/mtval/mepc等若开启AIC_BACKTRACE_DEBUG还会print_stack/print_back_trace最后j .挂死正常异常路径不会返回。g_trap_sp在链接脚本或别处应指向一块 ≥132 字节的缓冲区异常时复用该静态区域避免在未知栈上写爆。5.Default_Handlermtvec 入口 NMI第 327–436 行Default_Handler: ... csrr t0, mcause andi t0, t0, 0x3FF li t1, 24 beq t0, t1, .NMI_Handler ... j trap先到Default_Handler的 trap多数是未向量化的异常或向量表里填的Default_Handler。mcause 0x3FF 24芯片上的NMI 异常码与aic_soc.h里枚举名NMI_EXPn -2的“逻辑编号”不同硬件编码为 24。NMI 路径保存 callee-saved 浮点可选→jalr g_nmivector默认TIM4_NMIHandler→mret返回。非 NMIj trap走同步异常/中断判断。向量表里未单独实现的外设 handler通过宏弱符号别名到Default_Handler.macro def_irq_handler handler_name .weak \handler_name .globl \handler_name .set \handler_name, Default_Handler .endm驱动可定义强符号DMA_IRQHandler等覆盖当前 d13x 主要靠drv_irq_registerg_irqvector而不是 per-IRQ 汇编符号。6. Baremetal 的PendSV_Handler第 453–461 行#ifdef KERNEL_BAREMETAL PendSV_Handler: j trap #endifstartup_gcc.S向量 3 指向PendSV_Handlerbaremetal 下直接进trap用于软件 PendSV/上下文切换类异常无 RT-Thread 时简化处理。7. 与aic_drv_irq.c/trap_c.c的配合组件职责drv_irq_vectors_init()填充g_irqvector/g_nmivectordrv_irq_register()注册void handler(uint32_t irq, void *data)Default_IRQHandler所有 CLIC 外设 IRQ 的汇编入口 分发trap_c()打印寄存器、可选回调、死循环SysTickg_irqvector[CORET_IRQn] SysTick_Handler仍经Default_IRQHandler→mcause7→SysTick_Handler。8. 设计要点小结两级模型硬件mtvt表项多为Default_IRQHandler运行时用g_irqvector[]做第二级分发便于统一统计和 GPIO 扩展 IRQMAX_IRQ_ENTRY可大于MAX_IRQn。异常与中断分离mtvec→Default_Handler中断在trap里根据mcause最高位再并入Default_IRQHandler。NMI 单独快速路径异常码 24不经过trap_c直接g_nmivectormret。栈与扩展独立中断栈 T-Headipush/ipopFPU/回溯为可编译选项。未使用宏MSTATUS_PRV1 0x3880在本文件中未引用可能为历史遗留或其它文件使用。9. 调试时可关注的点外设中断不进驱动查drv_irq_enable、g_irqvector[irq]是否仍为Default_Handler。进中断就 “CPU Exception”可能同步异常或 NMI/未注册 IRQ 落到trap/Default_Handler。mcause与aic_soc.h的IRQn应对齐低 10 位CORET_IRQn7对应 SysTick。异常后挂死trap末尾j .与trap_c里while(1)属预期需修根因后复位。