hlinterrupts.rst 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. High-Level Interrupts
  2. =====================
  3. .. toctree::
  4. :maxdepth: 1
  5. The Xtensa architecture has support for 32 interrupts, divided over 8 levels, plus an assortment of exceptions. On the {IDF_TARGET_NAME}, the interrupt mux allows most interrupt sources to be routed to these interrupts using the :doc:`interrupt allocator <../api-reference/system/intr_alloc>`. Normally, interrupts will be written in C, but ESP-IDF allows high-level interrupts to be written in assembly as well, allowing for very low interrupt latencies.
  6. Interrupt Levels
  7. ----------------
  8. ===== ================= ====================================================
  9. Level Symbol Remark
  10. ===== ================= ====================================================
  11. 1 N/A Exception and level 0 interrupts. Handled by ESP-IDF
  12. 2-3 N/A Medium level interrupts. Handled by ESP-IDF
  13. 4 xt_highint4 Normally used by ESP-IDF debug logic
  14. 5 xt_highint5 Free to use
  15. NMI xt_nmi Free to use
  16. dbg xt_debugexception Debug exception. Called on e.g. a BREAK instruction.
  17. ===== ================= ====================================================
  18. Using these symbols is done by creating an assembly file (suffix .S) and defining the named symbols, like this::
  19. .section .iram1,"ax"
  20. .global xt_highint5
  21. .type xt_highint5,@function
  22. .align 4
  23. xt_highint5:
  24. ... your code here
  25. rsr a0, EXCSAVE_5
  26. rfi 5
  27. For a real-life example, see the :component_file:`{IDF_TARGET_PATH_NAME}/dport_panic_highint_hdl.S` file; the panic handler interrupt is implemented there.
  28. Notes
  29. -----
  30. - Do not call C code from a high-level interrupt; because these interupts still run in critical sections, this can cause crashes.
  31. (The panic handler interrupt does call normal C code, but this is OK because there is no intention of returning to the normal code
  32. flow afterwards.)
  33. - Make sure your assembly code gets linked in. If the interrupt handler symbol is the only symbol the rest of the code uses from this
  34. file, the linker will take the default ISR instead and not link the assembly file into the final project. To get around this, in the
  35. assembly file, define a symbol, like this::
  36. .global ld_include_my_isr_file
  37. ld_include_my_isr_file:
  38. (The symbol is called ``ld_include_my_isr_file`` here but can have any arbitrary name not defined anywhere else.)
  39. Then, in the component.mk, add this file as an unresolved symbol to the ld command line arguments::
  40. COMPONENT_ADD_LDFLAGS := -u ld_include_my_isr_file
  41. This should cause the linker to always include a file defining ``ld_include_my_isr_file``, causing the ISR to always be linked in.
  42. - High-level interrupts can be routed and handled using esp_intr_alloc and associated functions. The handler and handler arguments
  43. to esp_intr_alloc must be NULL, however.
  44. - In theory, medium priority interrupts could also be handled in this way. For now, ESP-IDF does not support this.