static inline void vector_to_irq(int irq_nbr, int *may_swap) { /* * As in this architecture an irq (code) executes in 0 time, * it is a bit senseless to call z_int_latency_start/stop() */ /* z_int_latency_start(); */ sys_trace_isr_enter(); if (irq_vector_table[irq_nbr].func == NULL) { /* LCOV_EXCL_BR_LINE */ /* LCOV_EXCL_START */ posix_print_error_and_exit("Received irq %i without a " "registered handler\n", irq_nbr); /* LCOV_EXCL_STOP */ } else { if (irq_vector_table[irq_nbr].flags & ISR_FLAG_DIRECT) { *may_swap |= ((direct_irq_f_ptr) irq_vector_table[irq_nbr].func)(); } else { #ifdef CONFIG_SYS_POWER_MANAGEMENT posix_irq_check_idle_exit(); #endif ((normal_irq_f_ptr)irq_vector_table[irq_nbr].func) (irq_vector_table[irq_nbr].param); *may_swap = 1; } } sys_trace_isr_exit(); /* z_int_latency_stop(); */ }
static inline void vector_to_irq(int irq_nbr, int *may_swap) { /** * Call the test IRQ sniffer, and if it returns * true ignore the interrupt */ bool ret; ret = bst_irq_sniffer(irq_nbr); if (ret) { return; } bs_trace_raw_time(6, "Vectoring to irq %i (%s)\n", irq_nbr, irqnames[irq_nbr]); sys_trace_isr_enter(); if (irq_vector_table[irq_nbr].func == NULL) { /* LCOV_EXCL_BR_LINE */ /* LCOV_EXCL_START */ posix_print_error_and_exit("Received irq %i without a " "registered handler\n", irq_nbr); /* LCOV_EXCL_STOP */ } else { if (irq_vector_table[irq_nbr].flags & ISR_FLAG_DIRECT) { *may_swap |= ((direct_irq_f_ptr) irq_vector_table[irq_nbr].func)(); } else { #ifdef CONFIG_SYS_POWER_MANAGEMENT posix_irq_check_idle_exit(); #endif ((normal_irq_f_ptr)irq_vector_table[irq_nbr].func) (irq_vector_table[irq_nbr].param); *may_swap = 1; } } sys_trace_isr_exit(); bs_trace_raw_time(7, "Irq %i (%s) ended\n", irq_nbr, irqnames[irq_nbr]); }
/* * @brief Announces the number of sys ticks that have passed since the last * announcement, if any, and programs the RTC to trigger the interrupt on the * next sys tick. * * The ISR is set pending due to a regular sys tick and after exiting idle mode * as scheduled. * * Since this ISR can be preempted, we need to take some provisions to announce * all expected sys ticks that have passed. * * Consider the following example: * * sys tick timeline: (1) (2) (3) (4) (5) (6) * rtc tick timeline : 0----100----200----300----400----500----600 * !********** * 450 * * The last sys tick was anounced at 200, i.e, rtc_past = 200. The ISR is * executed at the next sys tick, i.e. 300. The following sys tick is due at * 400. However, the ISR is preempted for a number of sys ticks, until 450 in * this example. The ISR will then announce the number of sys ticks it was * delayed (2), and schedule the next sys tick (5) at 500. */ void rtc1_nrf5_isr(void *arg) { ARG_UNUSED(arg); RTC_CC_EVENT = 0; #ifdef CONFIG_EXECUTION_BENCHMARKING extern void read_timer_start_of_tick_handler(void); read_timer_start_of_tick_handler(); #endif sys_trace_isr_enter(); #ifdef CONFIG_TICKLESS_KERNEL if (!expected_sys_ticks) { if (_sys_clock_always_on) { program_max_cycles(); } return; } _sys_idle_elapsed_ticks = expected_sys_ticks; /* Initialize expected sys tick, * It will be later updated based on next timeout. */ expected_sys_ticks = 0; /* Anounce elapsed of _sys_idle_elapsed_ticks systicks*/ _sys_clock_tick_announce(); /* _sys_clock_tick_announce() could cause new programming */ if (!expected_sys_ticks && _sys_clock_always_on) { program_max_cycles(); } #else rtc_announce_set_next(); #endif #ifdef CONFIG_EXECUTION_BENCHMARKING extern void read_timer_end_of_tick_handler(void); read_timer_end_of_tick_handler(); #endif sys_trace_isr_exit(); }