Forum Discussion
Altera_Forum
Honored Contributor
20 years agoHi,
If you are using the build in altera HAL, maybe it can be done different as expressed here, or is maybe impossible to make yourself, I let to others to answer this. For the so called 'legacy' (I hate this word) way it goes like this : The exception handler itself, you can browse in the altera provided code to see a bit how it works : This is how it goes- allocate space on the stack for saving registers (sp = sp + x where x is the amount of bytes reserved)
- save ea register minus 4 to the stack
- save registers r2 - r15 to the stack
- detect highest priority interrupt in the ipending control register (lowest bit set)
optional
- save ienable control register to the stack
- mask all lower priority interrupts in ienable
- enable interrupts (writing '1' to status control register)
- calculate offset in table for finding the function to call (typically a table of 32 times 2 DWORD's are used (one DWORD for the address, one for a context to transfer as argument to the interrupt service routine)
- call the function (store the context in r4)
optional
- restore the ienable register from the stack
- disable interrupts (write '0' to status)
- restore the registers r2 - r15 from the stack
- restore ea from the stack
- set estatus to '1', interrupts will be enabled again after 'eret'
- free the reserved space on the stack (sp = sp + x where x is the amount of bytes reserved)
- issue 'eret' instruction The optional part is if you want interrupts enabled during isr handling. This is needed if you have some high priority interrupts that need very fast and low jitter handling. The interrupt latency and jitter can be furhter reduced, but this can be a good start point. For getting it into the project, this is another thing. - write the code in a section (e.g. called exception). This means before the handler starts you use .section after the code you do .endsection like this : .section .exception "xa"
_irq_entry :
# here comes the code
eret
.endsection Next step is to change the linkerscript (*.ld file) to start with the section "exception" on the address you want. This can be done by typing the following just after the SECTIONS keyword . = nasys_exception_address;
.exception :
{
*(.exception)
}
.=nasys_program_mem;
/* here comes the rest */ The linkerscript example is easy here, because I use always the exception handler in on chip RAM, the rest of the code in off chip SRAM. If you have another situation for example interrupt handler and program memory in the same RAM, you need to delete the line (.=nasys_program_mem). A good idea is to check the object dump file to see if everything is in the correct place. Linkerscript documentation can be found at www.gnu.org. Hope you can do something with it. Stefaan