Fix example code, add chapter to docs about interrupts and multicore issues

pull/163/head
Jeroen Domburg 2016-12-08 14:42:00 +08:00
rodzic cb9ef19d3b
commit baa6a477c5
5 zmienionych plików z 34 dodań i 7 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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
^^^^^^^^^^^^^^^^

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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*/