mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-28 00:53:45 +08:00
22a8575199
Keep official openpilot ancestry and dependency licenses. Store resources directly in Git, remove LFS setup requirements, and leave the downloadable big model outside the source tree.
84 lines
2.4 KiB
C
84 lines
2.4 KiB
C
#pragma once
|
|
|
|
#include "board/drivers/drivers.h"
|
|
|
|
static void unused_interrupt_handler(void) {
|
|
// Something is wrong if this handler is called!
|
|
print("Unused interrupt handler called!\n");
|
|
fault_occurred(FAULT_UNUSED_INTERRUPT_HANDLED);
|
|
}
|
|
|
|
interrupt interrupts[NUM_INTERRUPTS];
|
|
|
|
static bool check_interrupt_rate = false;
|
|
|
|
static uint32_t idle_time = 0U;
|
|
static uint32_t busy_time = 0U;
|
|
float interrupt_load = 0.0f;
|
|
|
|
void handle_interrupt(IRQn_Type irq_type){
|
|
static uint8_t interrupt_depth = 0U;
|
|
static uint32_t last_time = 0U;
|
|
ENTER_CRITICAL();
|
|
if (interrupt_depth == 0U) {
|
|
uint32_t time = microsecond_timer_get();
|
|
idle_time += get_ts_elapsed(time, last_time);
|
|
last_time = time;
|
|
}
|
|
interrupt_depth += 1U;
|
|
EXIT_CRITICAL();
|
|
|
|
interrupts[irq_type].call_counter++;
|
|
interrupts[irq_type].handler();
|
|
|
|
// Check that the interrupts don't fire too often
|
|
if (check_interrupt_rate && (interrupts[irq_type].call_counter > interrupts[irq_type].max_call_rate)) {
|
|
fault_occurred(interrupts[irq_type].call_rate_fault);
|
|
}
|
|
|
|
ENTER_CRITICAL();
|
|
interrupt_depth -= 1U;
|
|
if (interrupt_depth == 0U) {
|
|
uint32_t time = microsecond_timer_get();
|
|
busy_time += get_ts_elapsed(time, last_time);
|
|
last_time = time;
|
|
}
|
|
EXIT_CRITICAL();
|
|
}
|
|
|
|
// Every second
|
|
void interrupt_timer_handler(void) {
|
|
if (INTERRUPT_TIMER->SR != 0U) {
|
|
for (uint16_t i = 0U; i < NUM_INTERRUPTS; i++) {
|
|
// Log IRQ call rate faults
|
|
if (check_interrupt_rate && (interrupts[i].call_counter > interrupts[i].max_call_rate)) {
|
|
print("Interrupt 0x"); puth(i); print(" fired too often (0x"); puth(interrupts[i].call_counter); print("/s)!\n");
|
|
}
|
|
|
|
// Reset interrupt counters
|
|
interrupts[i].call_rate = interrupts[i].call_counter;
|
|
interrupts[i].call_counter = 0U;
|
|
}
|
|
|
|
// Calculate interrupt load
|
|
// The bootstub does not have the FPU enabled, so can't do float operations.
|
|
#if !defined(BOOTSTUB)
|
|
interrupt_load = ((busy_time + idle_time) > 0U) ? ((float) (((float) busy_time) / (busy_time + idle_time))) : 0.0f;
|
|
#endif
|
|
idle_time = 0U;
|
|
busy_time = 0U;
|
|
}
|
|
INTERRUPT_TIMER->SR = 0;
|
|
}
|
|
|
|
void init_interrupts(bool check_rate_limit){
|
|
check_interrupt_rate = check_rate_limit;
|
|
|
|
for(uint16_t i=0U; i<NUM_INTERRUPTS; i++){
|
|
interrupts[i].handler = unused_interrupt_handler;
|
|
}
|
|
|
|
// Init interrupt timer for a 1s interval
|
|
interrupt_timer_init();
|
|
}
|