使用Hifive1 RevB的PLIC中断处理
我正在为SiFive HiFive1 RevB编写一个HAL。我对中断处理有问题。 代码如下:使用Hifive1 RevB的PLIC中断处理,c,assembly,riscv,C,Assembly,Riscv,我正在为SiFive HiFive1 RevB编写一个HAL。我对中断处理有问题。 代码如下: int main (void) { int rc; unsigned int gpio = 7; set_freq_320MHz(); uint32_t mstatus, mie; __asm__ volatile("csrr %0, mstatus" : "=r"(mstatus)); mie = 0;
int main (void)
{
int rc;
unsigned int gpio = 7;
set_freq_320MHz();
uint32_t mstatus, mie;
__asm__ volatile("csrr %0, mstatus" : "=r"(mstatus));
mie = 0;
__asm__ volatile("csrw mie, %0" : : "r"(mie));
__asm__ volatile("csrw mtvec, %I" : : "r"((unsigned long)&interrupt_service_routine));
//plic_interrupt_enable:
uint32_t mie;
__asm__ volatile("csrr %0, mie" : "=r"(mie));
mie |= MIE_MEIE;
__asm__ volatile("csrw mie, %0" : : "r"(mie));
PLIC_REG(PLIC_ENABLE_OFFSET) = 0;
PLIC_REG(PLIC_ENABLE_OFFSET_2) = 0;
mstatus = MSTATUS_MIE;
__asm__ volatile("csrw mstatus, %0" : : "r"(mstatus));
//gpio_interrupt_enable:
irq_functions[IRQ_GPIO + gpio].irq_handler = isr;
irq_functions[IRQ_GPIO + gpio].active = 1;
irq_functions[IRQ_GPIO + gpio].priority = prio;
if ((IRQ_GPIO + gpio) > PLIC_ENABLE_OFFSET_MAX)
{
PLIC_REG(PLIC_ENABLE_OFFSET_2) |= (1 << (31 -IRQ_GPIO + gpio));
}
else
{
PLIC_REG(PLIC_ENABLE_OFFSET) |= (1 << (IRQ_GPIO + gpio));
}
PLIC_REG(PLIC_PRIORITY_OFFSET + 4 * (IRQ_GPIO + gpio)) = prio;
rc = gpio_init_input(gpio, GPIO_PUP_EN);
for(int i = 0; i < 100000; i++)
;
__asm__ volatile ("wfi");
while (1)
{
}
return 0;
}
void handler()
{
printf("Interrupt taken");
uint32_t in = GPIO_REG(GPIO_FALL_IP);
GPIO_REG(GPIO_FALL_IP) = in;
}
void interrupt_service_routine()
{
uint32_t mscratch;
__asm__ volatile("csrrw a0, mscratch, a0\n\t"
"sw a1, 0(a0)\n\t"
"sw a2, 4(a0)\n\t"
"sw a3, 8(a0)\n\t"
"sw a4, 12(a0)\n\t");
__asm__ volatile("csrr %0, mcause" : "=r"(mscratch));
if (mscratch & MCAUSE_INT)
{
if (mscratch & MCAUSE_MTI)
; /* Clic interrupt handling not yet coded */
else if (mscratch & MCAUSE_MSI)
; /* Clic interrupt handling not yet coded */
else if (mscratch & MCAUSE_MEI)
{
plic_interrupt_handler();
}
}
__asm__ volatile("lw a4, 12(a0)\n\t"
"lw a3, 8(a0)\n\t"
"lw a2, 4(a0)\n\t"
"lw a1, 0(a0)\n\t"
"csrrw a0, mscratch, a0\n\t"
"mret");
}
void plic_interrupt_handler()
{
uint32_t pending, claim;
unsigned int int_number;
pending = PLIC_REG(PLIC_PENDING_OFFSET);
claim = PLIC_REG(PLIC_CLAIM_OFFSET);
int_number = sqrt(claim) - 1;
if (irq_functions[int_number].active)
{
irq_functions[int_number].irq_handler();
}
}
int main(无效)
{
int rc;
无符号整数gpio=7;
设置频率为320MHz();
uint32_t mstatus,mie;
__asm_uuuuuuuuuvolatile(“csrr%0,mstatus”:“=r”(mstatus));
mie=0;
__asm_uuu挥发性(“csrw mie,%0):“r”(mie));
__asm_uuuuuvolatile(“csrw mtvec,%I”::“r”((无符号长)和中断服务例程));
//plic_中断_启用:
uint32_t mie;
__asm_uuuuuuvolatile(“csrr%0,mie”:“=r”(mie));
mie |=mie|MEIE;
__asm_uuu挥发性(“csrw mie,%0):“r”(mie));
PLIC_REG(PLIC_ENABLE_OFFSET)=0;
PLIC_REG(PLIC_ENABLE_OFFSET_2)=0;
mstatus=mstatus_MIE;
__asm_uuuu挥发性(“csrw mstatus,%0):“r”(mstatus));
//gpio_中断_启用:
irq_函数[irq_GPIO+GPIO].irq_handler=isr;
irq_函数[irq_GPIO+GPIO]。活动=1;
irq_函数[irq_GPIO+GPIO]。优先级=优先级;
如果((IRQ\U GPIO+GPIO)>PLIC\U启用\U偏移量\U最大值)
{
PLIC_REG(PLIC_ENABLE_OFFSET_2)|=(1