gprof_stub.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include "nuclei_sdk_soc.h"
  2. #include "gprof_api.h"
  3. // TODO uncomment below if you are using RTOS, and you need to implement check the TODO in this file
  4. //#define USING_RTOS
  5. // TODO comment below if you dont want to use systimer interrupt as period sample interrupt
  6. // or this systimer interrupt is already used by other tasks such as RTOS or some other program
  7. // or you can add gprof_sample(pc) in your own period timer interrupt function
  8. #define SAMPLE_USING_SYSTIMER
  9. extern void gprof_sample(unsigned long pc);
  10. #ifdef USING_RTOS
  11. // TODO: If you are using RTOS, please take care that the system timer interrupt is already used by tick interrupt
  12. // so you need to call gprof_sample() function by yourself
  13. #error "You must implement a period timer interrupt run in PROF_HZ and call gprof_sample when USING_RTOS"
  14. #else
  15. // Sample in period interrupt, defined in PROF_HZ
  16. #define SAMPLE_TIMER_TICKS (SOC_TIMER_FREQ / PROF_HZ)
  17. #ifdef SAMPLE_USING_SYSTIMER
  18. // timer interrupt handler
  19. // vector mode interrupt
  20. __INTERRUPT void eclic_mtip_handler(void)
  21. {
  22. /* get current pc which is interrupted by interrupt via mepc */
  23. unsigned long pc = (unsigned long) (__RV_CSR_READ(CSR_MEPC));
  24. // Reload Timer Interrupt
  25. SysTick_Reload(SAMPLE_TIMER_TICKS);
  26. gprof_sample(pc);
  27. }
  28. #endif
  29. // setup timer
  30. static void setup_gprof_timer(void)
  31. {
  32. #ifdef SAMPLE_USING_SYSTIMER
  33. SysTick_Config(SAMPLE_TIMER_TICKS);
  34. // initialize timer interrupt as vector interrupt
  35. ECLIC_Register_IRQ(SysTimer_IRQn, ECLIC_VECTOR_INTERRUPT,
  36. ECLIC_LEVEL_TRIGGER, 1, 0, eclic_mtip_handler);
  37. // Enable IRQ
  38. __enable_irq();
  39. #else
  40. // TODO if you don't use rtos or SAMPLE_USING_SYSTIMER
  41. // you should setup your own gprof period timer interrupt here
  42. #endif
  43. }
  44. static void stop_gprof_timer(void)
  45. {
  46. #ifdef SAMPLE_USING_SYSTIMER
  47. ECLIC_DisableIRQ(SysTimer_IRQn);
  48. // Disable IRQ
  49. __disable_irq();
  50. #else
  51. // TODO if you don't use rtos or SAMPLE_USING_SYSTIMER
  52. // you should disable your sample interrupt here if it is not used by other case
  53. #endif
  54. }
  55. #endif
  56. /* Stop profiling */
  57. void gprof_off(void)
  58. {
  59. #ifndef USING_RTOS
  60. stop_gprof_timer();
  61. #endif
  62. }
  63. /* Start profiling */
  64. void gprof_on(void)
  65. {
  66. #ifndef USING_RTOS
  67. setup_gprof_timer();
  68. #endif
  69. }