1

我正在尝试进行计时器中断,我安装了以下 risc-v_tools riscv64-unknown-elf-gcc工具链、spike simulation和pk。这是我的代码:


#define  MTIME       *((volatile uint64_t *) 0x02000000 + 0xbff8)
#define  MTIMECMP    *((volatile uint64_t *) 0x02000000 + 0x4000)

#define  MTIME_INTERRUPT_PERIOD  12000000   

void interruptHandler() __attribute__ ((interrupt, section(".interrupt_handler")));

void interruptHandler() {
    MTIME = 0;
    MTIMECMP = MTIME_INTERRUPT_PERIOD;
  
    printf("Machine Interrupt");
}

void printf_status(uint64_t mstatus, uint64_t mie, uint64_t mip, uint64_t mcause) {
    asm volatile ("csrr %[reg], mie" : [reg] "=r" (mie));
    asm volatile ("csrr %[reg], mip" : [reg] "=r" (mip));
    asm volatile ("csrr %[reg], mstatus" : [reg] "=r" (mstatus));
    asm volatile ("csrr %[reg], mcause" : [reg] "=r" (mcause));
    printf("mie=%x, mip=%x, mstatus=%x, mcause=%x\r\n", mie, mip, mstatus, mcause);
}

int main() {

    uint64_t mstatus, mie, mip, mcause, mtvec;
    printf_status(mstatus, mie, mip, mcause);
    
    // basic (non vectored) interrupt handler (to force non vectored, set 0 to lower two bits of mtvec, so force 4 byte aligned on linker script for interrupt handler)
    asm volatile ("csrw mtvec, %[reg]" : : [reg] "r" ((uint64_t) interruptHandler));
    asm volatile ("csrr %[reg], mtvec" : [reg] "=r" (mtvec));
    printf("mtvec=%x\r\n", mtvec);
    
    // machine interrupt enable
    asm volatile ("csrw mie, %[reg]" : : [reg] "r" ((uint32_t) 0x80));

    asm volatile ("csrsi mstatus, 8");

    // configure interrupt period
    MTIME = 0;
    MTIMECMP = MTIME_INTERRUPT_PERIOD;

    // sleep
    while (1){
        asm volatile ("wfi");
    }  
    
    return 0;
}

当它编译我的程序时,它没有问题,但是当我模拟它时,它向我显示以下错误:

jjrh@ubuntu-20:~/risc-v/Programs$ riscv64-unknown-elf-gcc -march=rv64g -o manejador manejador.c -static-libgcc -lm
jjrh@ubuntu-20:~/risc-v/Programs$ spike pk manejador
bbl loader
z  0000000000000000 ra 00000000000101e0 sp 0000003ffffffae0 gp 000000000001edc0
tp 0000000000000000 t0 0000000000000000 t1 000000000000000f t2 0000000000000000
s0 0000003ffffffb10 s1 0000000000000000 a0 0000000000000000 a1 0000000000000000
a2 0000000000000000 a3 0000000000000000 a4 0000000000000001 a5 0000000000000000
a6 000000000000001f a7 0000000000000000 s2 0000000000000000 s3 0000000000000000
s4 0000000000000000 s5 0000000000000000 s6 0000000000000000 s7 0000000000000000
s8 0000000000000000 s9 0000000000000000 sA 0000000000000000 sB 0000000000000000
t3 0000000000000000 t4 0000000000000000 t5 0000000000000000 t6 0000000000000000
pc 000000000001016c va/inst 00000000304027f3 sr 8000000200006020
An illegal instruction was executed!

我在调试模式下模拟它,我看到一个进入循环并且不再退出,所以它已经表明它是由于一个非法指令,但我不知道是哪一个。我模拟并编译了 github 链接https://github.com/riscv/riscv-tests/blob/master/debug/programs/interrupt.c中具有 risc-v 的程序 的中断,但它给我带来了同样的错误.

我的问题是,问题是代码还是模拟器?

任何可以指导我的人都会非常感激,因为我是这些 RISC-V 工具的新手

4

1 回答 1

0

我已经意识到这个错误的原因。

该程序运行在 pk 之上(pk 仅支持用户模式)。我必须在裸机上运行程序(裸机支持机器模式)。这样就不会产生非法指令错误。

希望这些信息对将来的某人有所帮助。

于 2021-08-03T23:17:54.323 回答