]> granicus.if.org Git - esp-idf/commitdiff
Fix example code, add chapter to docs about interrupts and multicore issues
authorJeroen Domburg <git@j0h.nl>
Thu, 8 Dec 2016 06:42:00 +0000 (14:42 +0800)
committerJeroen Domburg <git@j0h.nl>
Thu, 8 Dec 2016 06:42:00 +0000 (14:42 +0800)
components/driver/include/driver/rmt.h
components/driver/include/driver/uart.h
docs/api/intr_alloc.rst
examples/13_timer_group/main/timer_group.c
examples/16_pcnt/main/pcnt_test.c

index 1c136689b704213aeefff8c5f6c9bafdd60c18c7..24df1ac8ed05735fd7faf618617318fe03cb2591 100644 (file)
@@ -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
index dd69dce275a860768d6fc8ed2f523b189ace6529..951ada929a2d1cdfe102bded363c67b7dc8fcf1b 100644 (file)
@@ -381,7 +381,8 @@ esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg,
 \r
 
 /**\r
- * @brief Free UART interrupt handler registered by uart_isr_register.\r
+ * @brief Free UART interrupt handler registered by uart_isr_register. Must be called on the same core as\r
+ * uart_isr_register was called.\r
  *\r
  * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2\r
  *\r
index e4e9bdb4ad1b453578e39274d3b8d850e95a4ac4..4d2f21abac0fc25422c320092f4c041a5158ec33 100644 (file)
@@ -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
 ^^^^^^^^^^^^^^^^
index f61f39b2c58cc97590fa99f08f41fae5a4763835..9db471054dd6b97bbb1a6421dbfd95fa57bb3f7f 100644 (file)
@@ -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);
 }
index 31d8f288705d9b80334cf9bc2a0837ed9a399192..cc844dcd81c6aa98a8632ade59a2a99d97c13a0f 100644 (file)
@@ -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*/