how to write isr function
Interrupts do not take arguments or return values.  Basically, it's just a bare subroutine that gets 'called' by the hardware.  An interrupt signal into the core generates the equivalent of a 'call' instruction wherever the processor happens to be executing code, storing the current address and then jumping directly into the ISR.  

Generally a UART interrupt will grab a byte out of the UART receive register and then store it in a global receive buffer.  You'll need to be careful with how you access the global receive buffer outside of the ISR as it is possible for the ISR to be called WHILE you are updating receive buffer metadata (pointers, counters, etc).  You need to write code that can deal with this properly, either by carefully making sure the ISR cannot trample over the read routine or by disabling interrupts briefly to prevent the ISR from running at critical moments.  There are standard concurrent programming techniques that can be used here.  

There are a couple of (somewhat complex) interrupt-driven UART drivers for both transmit and receive in this repository: https://github.com/alexforencich/templates