PolarFire® SoC mpfs-mmuart-interrupt 串口2 中断处理过程

 一、demo: mpfs-mmuart-interrupt 

polarfire-soc-bare-metal-examples/driver-examples/mss/mss-mmuart/mpfs-mmuart-interrupt at main · polarfire-soc/polarfire-soc-bare-metal-examples

 

串口1 是本地中断 , 参考  PolarFire® SoC mpfs-mmuart-interrupt 串口1 初始化过程 - 所长 - 博客园

 

以串口2中断是 全局中断,为例子,总过程如下:

   中断触发  →  trap_vector →  trap_from_machine_mode → handle_m_ext_interrupt → PLIC_mmuart2_IRQHandler → mmuart2_plic_IRQHandler→uart_isr→rx_handler→uart2_rx_handler 

 

二、/mpfs-mmuart-interrupt/src/platform/mpfs_hal/startup_gcc/mss_entry.S

 

 中断触发  →  trap_vector →  trap_from_machine_mode 

 

3、trap_from_machine_mode 函数 在   /mpfs-mmuart-interrupt/src/platform/mpfs_hal/common/mss_mtrap.c

 

void trap_from_machine_mode(uintptr_t * regs, uintptr_t dummy, uintptr_t mepc)
{

// 读取 csr 寄存器, 该寄存器 标识 中断和异常的 原因
volatile uintptr_t mcause = read_csr(mcause); if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) >=\ IRQ_M_LOCAL_MIN)&& ((mcause & MCAUSE_CAUSE) <= IRQ_M_LOCAL_MAX)) {
// 本地中断处理 handle_local_interrupt((uint8_t)(mcause
& MCAUSE_CAUSE)); } else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)\ == IRQ_M_EXT)) {

// 外部中断处理 handle_m_ext_interrupt(); }
else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)\ == IRQ_M_SOFT)) {
// 软件中断处理 handle_m_soft_interrupt(); }
else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)\ == IRQ_M_TIMER)) {
// mtime 中断处理 handle_m_timer_interrupt(); }
else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)\ == IRQ_M_BEU )) {
// 总线错误中断 handle_local_beu_interrupt(); }
else { uint32_t i = 0U;

  // 死循环
while(1U) { /* wait for watchdog */ i++; if(i == 0x1000U) { i = (uint32_t)mcause; /* so mcause is not optimised out */ } } switch(mcause) { case CAUSE_LOAD_PAGE_FAULT: break; case CAUSE_STORE_PAGE_FAULT: break; case CAUSE_FETCH_ACCESS: break; case CAUSE_LOAD_ACCESS: break; case CAUSE_STORE_ACCESS: break; default: bad_trap(regs, dummy, mepc); break; } } }

 4、trap_from_machine_mode → handle_m_ext_interrupt → PLIC_mmuart2_IRQHandler → mmuart2_plic_IRQHandler→uart_isr→rx_handler→uart2_rx_handler

 

void handle_m_ext_interrupt(void)
{

    volatile uint32_t int_num  = PLIC_ClaimIRQ();

    if (PLIC_INVALID_INT_OFFSET == int_num)
    {
       return;
    }

    uint8_t disable = EXT_IRQ_KEEP_ENABLED;
    disable = ext_irq_handler_table[int_num]();

    PLIC_CompleteIRQ(int_num);

    if(EXT_IRQ_DISABLE == disable)
    {
        PLIC_DisableIRQ((PLIC_IRQn_Type)int_num);
    }

}

 

void uart2_rx_handler(mss_uart_instance_t *this_uart) 
{
  

uint32_t hart_id = read_csr(mhartid);
int8_t info_string2[50];


irq_cnt++;
sprintf(info_string2, "UART2 Interrupt count = 0x%x \r\n\r\n", irq_cnt);


/* This will execute when interrupt from hart 2 is raised */
g_rx_size2 = MSS_UART_get_rx(this_uart, g_rx_buff2, sizeof(g_rx_buff2));


MSS_UART_polled_tx(p_uartmap_u54_2, info_string2,
strlen(info_string2));


}

 

posted on 2025-09-10 10:46  所长  阅读(13)  评论(0)    收藏  举报

导航