How to create an interrupt handler that gets called when a flag is set in a certain address without polling?

I am emulating with QEMU this project.
It does not contain a UART interrupt row inside the vector table:

MPS2 is a Cortex-M3 based SoC and has 15 fixed exceptions and 45 IRQs.

A Cortex-M3/4-based board uses vectored exceptions. This means each exception calls a handler directly from the vector table.

Handlers are provided for exceptions 1-6, 11-12, and 14-15. The table here identifies the handlers used for each exception.

/* Vector table. */
const uint32_t* isr_vector[] __attribute__((section(".isr_vector"))) =
    ( uint32_t * ) &_estack,
    ( uint32_t * ) &Reset_Handler,     // Reset                -15
    ( uint32_t * ) &Default_Handler,   // NMI_Handler          -14
    ( uint32_t * ) &HardFault_Handler, // HardFault_Handler    -13
    ( uint32_t * ) &Default_Handler,   // MemManage_Handler    -12
    ( uint32_t * ) &Default_Handler,   // BusFault_Handler     -11
    ( uint32_t * ) &Default_Handler,   // UsageFault_Handler   -10
    0, // reserved
    0, // reserved
    0, // reserved
    0, // reserved   -6
    ( uint32_t * ) &vPortSVCHandler,    // SVC_Handler              -5
    ( uint32_t * ) &Default_Handler,    // DebugMon_Handler         -4
    0, // reserved
    ( uint32_t * ) &xPortPendSVHandler, // PendSV handler    -2
    ( uint32_t * ) &xPortSysTickHandler,// SysTick_Handler   -1
    ( uint32_t * ) TIMER0_Handler,     // Timer 0
	( uint32_t * ) TIMER1_Handler,     // Timer 1
    0, // Ethernet   13

so I guess that CANNOT invoke an ISR when uart receives something(unless there is other way to register an interrupt handler even if uart is not in vector table?)…
so I guess I have to do something else. UART peripheral sets a INTSTATUS flag when it receives something. How can I invoke the interrupt handler when that bit is set WITHOUT DO POLLING? Is there a way?

The U(S)ART can be configured to operate either in interrupt driven or polled mode. In the latter case, there is no need for an ISR as the interrupt never fires.

If this project is set up for polling mode (which it apparently is) and you want to emulate it “as is,” just stick with the code base. If you want interrupt driven USART I/O, you need to rewrite the code, implying among other things to add an ISR into the IVT. That is a good exercise with a good learning and functionality improvement (normally, interrupt driven I/O is preferrable over polling).

can you suggest me some material or something to search? it’s a good exercise for me but I don’t know where to begin. I just know that the vector table has the code to execute for the specific row (which in my case uart is not there so there is no row and no isr code to execute)… so what to do, how can I do?

The way I would approach it is this:

  • Look for other existing projects for compatible platforms that support interrupt driven I/O for such a device, possibly without an RTOS.
  • Copy-and-paste the isr code from that project into yours, amend the ivt, attempt to build.
  • Study how your donor project initializes the MCU to enable interrupt driven I/O, port that code into your code base.
  • spend a few hours scratching your head over why things blow left and right. Pop a bottle of good champagne once your isr is invoked. First hurdle taken!
  • Do not be surprised if things blow right and left again within the ISR, in particular if your donor code is not rtos aware. In that case, study more existing drivers to find out how I/O control flow works.
  • Be aware that emulated I/O may not be perfect, so some problems you encounter may actually be bugs or imperfections in the emulation layer. That means that even if your donor project targets the same platform as your work project, the identical code may not work as expected.

I don’t know your processor in particular, but it is almost certain that the UART has an interrupt vector defined for it, and its vector should go into one of the spots marked with a 0.

Note, this does not look like a normal M3 vector table, as you really shouldn’t put "0"s in the table, as if that interrupt does occur, your system will fault. Instead you tend to put a “dummy” vector that just loops, so you can at least see what went wrong (like those Default Handlers at the beginning of the table).

So, it looks like what really needs to be done, is replace that vector table with a table with the ISRs you want to use defined.

I know nothing abut QEMU which I understand is implemented in an FPGA. So the suggestions in other replies may be better than this one. However, if it supports the debug watchpoint functionality of the Arm Cortex M3 processor, then you could set a debug watchpoint on the address of the flag. In the DebugMon handler you could check what address has been written and what value was written, and if appropriate then call the UART interrupt handler.

If helpful, section 5 of the MPS2 AN385 document contains the interrupt assignments, which I think are also in the SMM_MPS2.h header file in the project you reference. As I recall, when using the networking on QEMU, I started with an interrupt driven driver - but I could be wrong and can’t recall now where it came from.