|
| 1 | +/* |
| 2 | + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: BSD-3-Clause |
| 5 | + */ |
| 6 | + |
| 7 | +#ifndef _HARDWARE_EXCEPTION_H_ |
| 8 | +#define _HARDWARE_EXCEPTION_H_ |
| 9 | + |
| 10 | +#include "pico.h" |
| 11 | +#include "hardware/address_mapped.h" |
| 12 | +#include "hardware/regs/m0plus.h" |
| 13 | + |
| 14 | +/** \file exception.h |
| 15 | + * \defgroup hardware_exception hardware_exception |
| 16 | + * |
| 17 | + * Methods for setting processor exception handlers |
| 18 | + * |
| 19 | + * Exceptions are identified by a \ref exception_num which is a number from -15 to -1; these are the numbers relative to |
| 20 | + * the index of the first IRQ vector in the vector table. (i.e. vector table index is exception_num plus 16) |
| 21 | + * |
| 22 | + * There is one set of exception handlers per core, so the exception handlers for each core as set by these methods are independent. |
| 23 | + * |
| 24 | + * \note That all exception APIs affect the executing core only (i.e. the core calling the function). |
| 25 | + */ |
| 26 | + |
| 27 | +// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_EXCEPTION, Enable/disable assertions in the exception module, type=bool, default=0, group=hardware_exception |
| 28 | +#ifndef PARAM_ASSERTIONS_ENABLED_EXCEPTION |
| 29 | +#define PARAM_ASSERTIONS_ENABLED_EXCEPTION 0 |
| 30 | +#endif |
| 31 | + |
| 32 | +#ifdef __cplusplus |
| 33 | +extern "C" { |
| 34 | +#endif |
| 35 | + |
| 36 | +/*! \brief Exception number definitions |
| 37 | + * |
| 38 | + * Note for consistency with irq numbers, these numbers are defined to be negative. The VTABLE index is |
| 39 | + * the number here plus 16. |
| 40 | + * |
| 41 | + * Name | Value | Exception |
| 42 | + * ---------------------|-------|---------- |
| 43 | + * NMI_EXCEPTION | -14 | Non Maskable Interrupt |
| 44 | + * HARDFAULT_EXCEPTION | -13 | HardFault |
| 45 | + * SVCALL_EXCEPTION | -5 | SV Call |
| 46 | + * PENDSV_EXCEPTION | -2 | Pend SV |
| 47 | + * SYSTICK_EXCEPTION | -1 | System Tick |
| 48 | + * |
| 49 | + * \ingroup hardware_exception |
| 50 | + */ |
| 51 | +enum exception_number { |
| 52 | + NMI_EXCEPTION = -14, /* Non Maskable Interrupt */ |
| 53 | + HARDFAULT_EXCEPTION = -13, /* HardFault Interrupt */ |
| 54 | + SVCALL_EXCEPTION = -5, /* SV Call Interrupt */ |
| 55 | + PENDSV_EXCEPTION = -2, /* Pend SV Interrupt */ |
| 56 | + SYSTICK_EXCEPTION = -1, /* System Tick Interrupt */ |
| 57 | +}; |
| 58 | + |
| 59 | +/*! \brief Exception handler function type |
| 60 | + * \ingroup hardware_exception |
| 61 | + * |
| 62 | + * All exceptions handlers should be of this type, and follow normal ARM EABI register saving conventions |
| 63 | + */ |
| 64 | +typedef void (*exception_handler_t)(void); |
| 65 | + |
| 66 | +/*! \brief Set the exception handler for an exception on the executing core. |
| 67 | + * \ingroup hardware_exception |
| 68 | + * |
| 69 | + * This method will assert if an exception handler has been set for this exception number on this core via |
| 70 | + * this method, without an intervening restore via exception_restore_handler. |
| 71 | + * |
| 72 | + * \note this method may not be used to override an exception handler that was specified at link time by |
| 73 | + * providing a strong replacement for the weakly defined stub exception handlers. It will assert in this case too. |
| 74 | + * |
| 75 | + * \param num Exception number |
| 76 | + * \param handler The handler to set |
| 77 | + * \see exception_number |
| 78 | + */ |
| 79 | +exception_handler_t exception_set_exclusive_handler(enum exception_number num, exception_handler_t handler); |
| 80 | + |
| 81 | +/*! \brief Restore the original exception handler for an exception on this core |
| 82 | + * \ingroup hardware_exception |
| 83 | + * |
| 84 | + * This method may be used to restore the exception handler for an exception on this core to the state |
| 85 | + * prior to the call to exception_set_exclusive_handler(), so that exception_set_exclusive_handler() |
| 86 | + * may be called again in the future. |
| 87 | + * |
| 88 | + * \param num Exception number \ref exception_nums |
| 89 | + * \param original_handler The original handler returned from \ref exception_set_exclusive_handler |
| 90 | + * \see exception_set_exclusive_handler() |
| 91 | + */ |
| 92 | +void exception_restore_handler(enum exception_number, exception_handler_t original_handler); |
| 93 | + |
| 94 | +/*! \brief Get the current exception handler for the specified exception from the currently installed vector table |
| 95 | + * of the execution core |
| 96 | + * \ingroup hardware_exception |
| 97 | + * |
| 98 | + * \param num Exception number |
| 99 | + * \return the address stored in the VTABLE for the given exception number |
| 100 | + */ |
| 101 | +exception_handler_t exception_get_vtable_handler(enum exception_number num); |
| 102 | +#ifdef __cplusplus |
| 103 | +} |
| 104 | +#endif |
| 105 | + |
| 106 | +#endif |
0 commit comments