mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Fix example code, add chapter to docs about interrupts and multicore issues
This commit is contained in:
parent
cb9ef19d3b
commit
baa6a477c5
@ -568,15 +568,14 @@ esp_err_t rmt_config(rmt_config_t* rmt_param);
|
||||
* @brief register RMT interrupt handler, the handler is an ISR.
|
||||
*
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @note
|
||||
* If you already called rmt_driver_install to use system RMT driver,
|
||||
* @note If you already called rmt_driver_install to use system RMT driver,
|
||||
* please do not register ISR handler again.
|
||||
*
|
||||
* @param fn Interrupt handler function.
|
||||
* @param arg Parameter for handler function
|
||||
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
|
||||
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
|
||||
* @param If non-zero, a handle to later clean up the ISR gets stored here.
|
||||
* @param handle If non-zero, a handle to later clean up the ISR gets stored here.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
|
@ -381,7 +381,8 @@ esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg,
|
||||
|
||||
|
||||
/**
|
||||
* @brief Free UART interrupt handler registered by uart_isr_register.
|
||||
* @brief Free UART interrupt handler registered by uart_isr_register. Must be called on the same core as
|
||||
* uart_isr_register was called.
|
||||
*
|
||||
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
|
||||
*
|
||||
|
@ -29,7 +29,33 @@ interrupt for DevA is still pending, but because the int line never went low (De
|
||||
even when the int for DevB was cleared) the interrupt is never serviced.)
|
||||
|
||||
|
||||
Multicore issues
|
||||
----------------
|
||||
|
||||
Peripherals that can generate interrupts can be divided in two types: external peripherals, outside the Xtensa
|
||||
cores in the ESP32, and internal peripherals, inside the ESP32. Interrupt handling differs slightly between
|
||||
these two types of peripherals.
|
||||
|
||||
Each Xtensa core has its own set of internal peripherals: three timer comparators, a performance monitor and two
|
||||
software interrupts. These peripherals can only be configured from the core they are associated with. When
|
||||
generating an interrupt, the interrupt they generate is hard-wired to their associated core; it's not possible
|
||||
to have e.g. an internal timer comparator of one core generate an interrupt on another core. That is why these
|
||||
sources can only be managed using a task running on that specific core. Internal interrupt sources are still
|
||||
allocatable using esp_intr_alloc as normal, but they cannot be shared and will always have a fixed interrupt
|
||||
level (namely, the one associated in hardware with the peripheral). Internal interrupt sources are defined
|
||||
in esp_intr_alloc.h as ETS_INTERNAL_*_INTR_SOURCE.
|
||||
|
||||
The remaining interrupt slots in both cores are wired to an interrupt multiplexer, which can be used to
|
||||
route any external interrupt source to any of these interrupt slots. Allocating an external interrupt will always
|
||||
allocate it on the core that does the allocation, and freeing the interrupt should always happen on the same
|
||||
core. Disabling and enabling the interrupt from another core is allowed, however. External interrupts can
|
||||
share an interrupt slot bu passing ESP_INTR_FLAG_SHARED as a flag to esp_intr_alloc. External interrupt sources
|
||||
are defined in soc/soc.h as ETS_*_INTR_SOURCE.
|
||||
|
||||
Care should be taken when allocating an interrupt using a task not pinned to a certain core; while running
|
||||
code not in a critical secion, these tasks can migrate between cores at any moment, possibly making an
|
||||
interrupt operation fail because of the reasons mentioned above. It is advised to always use
|
||||
xTaskCreatePinnedToCore with a specific CoreID argument to create tasks that will handle interrupts.
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
@ -58,6 +84,7 @@ Macros
|
||||
.. doxygendefine:: ESP_INTR_FLAG_SHARED
|
||||
.. doxygendefine:: ESP_INTR_FLAG_EDGE
|
||||
.. doxygendefine:: ESP_INTR_FLAG_IRAM
|
||||
.. doxygendefine:: ESP_INTR_FLAG_INTRDISABLED
|
||||
|
||||
Type Definitions
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
@ -157,7 +157,7 @@ void tg0_timer0_init()
|
||||
/*Enable timer interrupt*/
|
||||
timer_enable_intr(timer_group, timer_idx);
|
||||
/*Set ISR handler*/
|
||||
timer_isr_register(timer_group, timer_idx, timer_group0_isr, (void*) timer_idx, ESP_INTR_FLAG_IRAM);
|
||||
timer_isr_register(timer_group, timer_idx, timer_group0_isr, (void*) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
|
||||
/*Start timer counter*/
|
||||
timer_start(timer_group, timer_idx);
|
||||
}
|
||||
@ -187,7 +187,7 @@ void tg0_timer1_init()
|
||||
/*Enable timer interrupt*/
|
||||
timer_enable_intr(timer_group, timer_idx);
|
||||
/*Set ISR handler*/
|
||||
timer_isr_register(timer_group, timer_idx, timer_group0_isr, (void*) timer_idx, ESP_INTR_FLAG_IRAM);
|
||||
timer_isr_register(timer_group, timer_idx, timer_group0_isr, (void*) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
|
||||
/*Start timer counter*/
|
||||
timer_start(timer_group, timer_idx);
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ static void pcnt_init(void)
|
||||
/*Reset counter value*/
|
||||
pcnt_counter_clear(PCNT_TEST_UNIT);
|
||||
/*Register ISR handler*/
|
||||
pcnt_isr_register(pcnt_intr_handler, NULL, 0);
|
||||
pcnt_isr_register(pcnt_intr_handler, NULL, 0, NULL);
|
||||
/*Enable interrupt for PCNT unit*/
|
||||
pcnt_intr_enable(PCNT_TEST_UNIT);
|
||||
/*Resume counting*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user