Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8964f86

Browse files
committedMar 19, 2025
irq: use nested and atomic control in critical section
Make sure all peripherals that share the same critical section have some nesting and atomic access control. Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
1 parent 5ec5052 commit 8964f86

26 files changed

+126
-81
lines changed
 

‎components/driver/deprecated/adc_legacy.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "esp_private/periph_ctrl.h"
2828
#include "driver/adc_types_legacy.h"
2929
#include "esp_clk_tree.h"
30+
#include "rtc_lock.h"
3031

3132
#if SOC_DAC_SUPPORTED
3233
#include "hal/dac_types.h"
@@ -45,11 +46,6 @@ static const char *ADC_TAG = "ADC";
4546
//////////////////////// Locks ///////////////////////////////////////////
4647
LOG_MODULE_REGISTER(adc_legacy, CONFIG_ADC_LOG_LEVEL);
4748

48-
extern int rtc_spinlock;
49-
50-
#define RTC_ENTER_CRITICAL() do { rtc_spinlock = irq_lock(); } while(0)
51-
#define RTC_EXIT_CRITICAL() irq_unlock(rtc_spinlock);
52-
5349
#define DIGI_ENTER_CRITICAL()
5450
#define DIGI_EXIT_CRITICAL()
5551

‎components/driver/deprecated/dac_common_legacy.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@
1515
#include "hal/gpio_types.h"
1616
#include "hal/dac_ll.h"
1717
#include "clk_ctrl_os.h"
18-
19-
extern int rtc_spinlock;
20-
21-
#define RTC_ENTER_CRITICAL() do { rtc_spinlock = irq_lock(); } while(0)
22-
#define RTC_EXIT_CRITICAL() irq_unlock(rtc_spinlock);
18+
#include "rtc_lock.h"
2319

2420
static __attribute__((unused)) const char *TAG = "DAC";
2521

‎components/driver/gpio/rtc_io.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@
1313
#include "driver/rtc_io.h"
1414
#include "hal/rtc_io_hal.h"
1515
#include "soc/soc_caps.h"
16+
#include "rtc_lock.h"
1617

1718
static const char __attribute__((__unused__)) *RTCIO_TAG = "RTCIO";
1819

19-
extern int rtc_spinlock;
20-
21-
#define RTCIO_ENTER_CRITICAL() do { rtc_spinlock = irq_lock(); } while(0)
22-
#define RTCIO_EXIT_CRITICAL() irq_unlock(rtc_spinlock);
20+
#define RTCIO_ENTER_CRITICAL() RTC_ENTER_CRITICAL()
21+
#define RTCIO_EXIT_CRITICAL() RTC_EXIT_CRITICAL()
2322

2423
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
2524

‎components/driver/touch_sensor/touch_sensor_common.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "driver/gpio.h"
2121
#include "hal/touch_sensor_types.h"
2222
#include "hal/touch_sensor_hal.h"
23+
#include "rtc_lock.h"
2324

2425
static const char *TOUCH_TAG = "TOUCH_SENSOR";
2526
#define TOUCH_CHECK(a, str, ret_val) ({ \
@@ -43,10 +44,8 @@ static const char *TOUCH_TAG = "TOUCH_SENSOR";
4344

4445
_Static_assert(TOUCH_PAD_MAX == SOC_TOUCH_SENSOR_NUM, "Touch sensor channel number not equal to chip capabilities");
4546

46-
extern int rtc_spinlock;
47-
48-
#define TOUCH_ENTER_CRITICAL() do { rtc_spinlock = irq_lock(); } while(0)
49-
#define TOUCH_EXIT_CRITICAL() irq_unlock(rtc_spinlock)
47+
#define TOUCH_ENTER_CRITICAL() RTC_ENTER_CRITICAL()
48+
#define TOUCH_EXIT_CRITICAL() RTC_EXIT_CRITICAL()
5049

5150
esp_err_t touch_pad_isr_deregister(intr_handler_t fn, void *arg)
5251
{

‎components/esp_hw_support/adc_share_hw_ctrl.c

+2-6
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,17 @@
3232
#include "esp_private/sar_periph_ctrl.h"
3333
#include "esp_private/periph_ctrl.h"
3434
#include "soc/periph_defs.h"
35+
#include "rtc_lock.h"
36+
3537
//For calibration
3638
#if CONFIG_IDF_TARGET_ESP32S2
3739
#include "esp_efuse_rtc_table.h"
3840
#elif SOC_ADC_CALIBRATION_V1_SUPPORTED
3941
#include "esp_efuse_rtc_calib.h"
4042
#endif
4143

42-
4344
static const char *TAG = "adc_share_hw_ctrl";
4445

45-
extern int rtc_spinlock;
46-
47-
#define RTC_ENTER_CRITICAL() do { rtc_spinlock = irq_lock(); } while(0)
48-
#define RTC_EXIT_CRITICAL() irq_unlock(rtc_spinlock);
49-
5046
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
5147
/*---------------------------------------------------------------
5248
ADC Hardware Calibration

‎components/esp_hw_support/clk_ctrl_os.c

+18-4
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,31 @@
55
*/
66

77
#include <zephyr/kernel.h>
8+
#include <zephyr/sys/atomic.h>
9+
#include <zephyr/sys/__assert.h>
810

911
#include "clk_ctrl_os.h"
1012
#include "soc/rtc.h"
1113
#include "esp_private/esp_clk_tree_common.h"
1214
#include "esp_check.h"
1315

14-
static int periph_spinlock;
16+
static int lock;
17+
static atomic_t lock_counter;
1518

16-
#define ENTER_CRITICAL_SECTION() do { periph_spinlock = irq_lock(); } while(0)
17-
#define LEAVE_CRITICAL_SECTION() irq_unlock(periph_spinlock);
19+
#define ENTER_CRITICAL_SECTION() \
20+
do { \
21+
if (atomic_inc(&lock_counter) == 0) { \
22+
lock = irq_lock(); \
23+
} \
24+
} while (0)
25+
26+
#define LEAVE_CRITICAL_SECTION() \
27+
do { \
28+
__ASSERT_NO_MSG(atomic_get(&lock_counter) > 0); \
29+
if (atomic_dec(&lock_counter) == 1) { \
30+
irq_unlock(lock); \
31+
} \
32+
} while (0)
1833

1934
static uint8_t s_periph_ref_counts = 0;
2035
static uint32_t s_rc_fast_freq = 0; // Frequency of the RC_FAST clock in Hz
@@ -25,7 +40,6 @@ static uint32_t s_cur_apll_freq = 0;
2540
static int s_apll_ref_cnt = 0;
2641
#endif
2742

28-
2943
bool periph_rtc_dig_clk8m_enable(void)
3044
{
3145
ENTER_CRITICAL_SECTION();

‎components/esp_hw_support/periph_ctrl.c

+18-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
#include <zephyr/kernel.h>
7+
#include <zephyr/sys/atomic.h>
8+
#include <zephyr/sys/__assert.h>
79

810
#include "hal/clk_gate_ll.h"
911
#include "esp_attr.h"
@@ -14,10 +16,23 @@
1416
#include "esp_private/esp_modem_clock.h"
1517
#endif
1618

17-
static int periph_spinlock;
19+
static atomic_t lock_counter;
20+
static int lock;
1821

19-
#define ENTER_CRITICAL_SECTION() do { periph_spinlock = irq_lock(); } while(0)
20-
#define LEAVE_CRITICAL_SECTION() irq_unlock(periph_spinlock);
22+
#define ENTER_CRITICAL_SECTION() \
23+
do { \
24+
if (atomic_inc(&lock_counter) == 0) { \
25+
lock = irq_lock(); \
26+
} \
27+
} while (0)
28+
29+
#define LEAVE_CRITICAL_SECTION() \
30+
do { \
31+
__ASSERT_NO_MSG(atomic_get(&lock_counter) > 0); \
32+
if (atomic_dec(&lock_counter) == 1) { \
33+
irq_unlock(lock); \
34+
} \
35+
} while (0)
2136

2237
static uint8_t ref_counts[PERIPH_MODULE_MAX] = {0};
2338

‎components/esp_hw_support/port/esp32/sar_periph_ctrl.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@
2020
#include "esp_log.h"
2121
#include "esp_private/sar_periph_ctrl.h"
2222
#include "hal/sar_ctrl_ll.h"
23+
#include "rtc_lock.h"
2324

2425
static const char *TAG = "sar_periph_ctrl";
2526

26-
static int rtc_spinlock;
27-
28-
#define ENTER_CRITICAL_SECTION() do { rtc_spinlock = irq_lock(); } while(0)
29-
#define LEAVE_CRITICAL_SECTION() irq_unlock(rtc_spinlock);
30-
#define LEAVE_CRITICAL() irq_unlock(rtc_spinlock);
27+
#define ENTER_CRITICAL_SECTION() RTC_ENTER_CRITICAL()
28+
#define LEAVE_CRITICAL_SECTION() RTC_EXIT_CRITICAL()
29+
#define LEAVE_CRITICAL() RTC_EXIT_CRITICAL()
3130

3231
void sar_periph_ctrl_init(void)
3332
{

‎components/esp_hw_support/port/esp32c2/sar_periph_ctrl.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@
2222
#include "esp_private/sar_periph_ctrl.h"
2323
#include "hal/sar_ctrl_ll.h"
2424
#include "hal/adc_ll.h"
25+
#include "rtc_lock.h"
2526

2627
static const char *TAG = "sar_periph_ctrl";
2728

28-
int rtc_spinlock;
29-
30-
#define ENTER_CRITICAL_SECTION() do { rtc_spinlock = irq_lock(); } while(0)
31-
#define LEAVE_CRITICAL_SECTION() irq_unlock(rtc_spinlock);
32-
#define LEAVE_CRITICAL() irq_unlock(rtc_spinlock);
29+
#define ENTER_CRITICAL_SECTION() RTC_ENTER_CRITICAL()
30+
#define LEAVE_CRITICAL_SECTION() RTC_EXIT_CRITICAL()
31+
#define LEAVE_CRITICAL() RTC_EXIT_CRITICAL()
3332

3433
void sar_periph_ctrl_init(void)
3534
{

‎components/esp_hw_support/port/esp32c3/adc2_init_cal.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ Don't put any other code into this file. */
1313
#include "hal/adc_types.h"
1414
#include "hal/adc_hal_common.h"
1515
#include "esp_private/adc_share_hw_ctrl.h"
16+
#include "rtc_lock.h"
1617

17-
extern int rtc_spinlock;
18-
19-
#define ENTER_CRITICAL_SECTION() do { rtc_spinlock = irq_lock(); } while(0)
20-
#define LEAVE_CRITICAL_SECTION() irq_unlock(rtc_spinlock);
18+
#define ENTER_CRITICAL_SECTION() RTC_ENTER_CRITICAL()
19+
#define LEAVE_CRITICAL_SECTION() RTC_EXIT_CRITICAL()
2120

2221
/**
2322
* @brief Set initial code to ADC2 after calibration. ADC2 RTC and ADC2 PWDET controller share the initial code.

‎components/esp_hw_support/port/esp32c3/sar_periph_ctrl.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@
2222
#include "esp_private/sar_periph_ctrl.h"
2323
#include "hal/sar_ctrl_ll.h"
2424
#include "hal/adc_ll.h"
25+
#include "rtc_lock.h"
2526

2627
static const char *TAG = "sar_periph_ctrl";
2728

28-
int rtc_spinlock;
29-
30-
#define ENTER_CRITICAL_SECTION() do { rtc_spinlock = irq_lock(); } while(0)
31-
#define LEAVE_CRITICAL_SECTION() irq_unlock(rtc_spinlock);
32-
#define LEAVE_CRITICAL() irq_unlock(rtc_spinlock);
29+
#define ENTER_CRITICAL_SECTION() RTC_ENTER_CRITICAL()
30+
#define LEAVE_CRITICAL_SECTION() RTC_EXIT_CRITICAL()
31+
#define LEAVE_CRITICAL() RTC_EXIT_CRITICAL()
3332

3433
void sar_periph_ctrl_init(void)
3534
{

‎components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@
2121
#include "esp_private/sar_periph_ctrl.h"
2222
#include "esp_private/esp_modem_clock.h"
2323
#include "hal/sar_ctrl_ll.h"
24+
#include "rtc_lock.h"
2425

2526
static const char *TAG = "sar_periph_ctrl";
2627

27-
int rtc_spinlock;
28-
29-
#define ENTER_CRITICAL_SECTION() do { rtc_spinlock = irq_lock(); } while(0)
30-
#define LEAVE_CRITICAL_SECTION() irq_unlock(rtc_spinlock);
31-
#define LEAVE_CRITICAL() irq_unlock(rtc_spinlock);
28+
#define ENTER_CRITICAL_SECTION() RTC_ENTER_CRITICAL()
29+
#define LEAVE_CRITICAL_SECTION() RTC_EXIT_CRITICAL()
30+
#define LEAVE_CRITICAL() RTC_EXIT_CRITICAL()
3231

3332
void sar_periph_ctrl_init(void)
3433
{

‎components/esp_hw_support/port/esp32h2/sar_periph_ctrl.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@
2020
#include "esp_private/sar_periph_ctrl.h"
2121
#include "esp_private/esp_modem_clock.h"
2222
#include "hal/sar_ctrl_ll.h"
23+
#include "rtc_lock.h"
2324

2425
static const char *TAG = "sar_periph_ctrl";
2526

26-
static int rtc_spinlock;
27-
28-
#define ENTER_CRITICAL_SECTION() do { rtc_spinlock = irq_lock(); } while(0)
29-
#define LEAVE_CRITICAL_SECTION() irq_unlock(rtc_spinlock);
30-
#define LEAVE_CRITICAL() irq_unlock(rtc_spinlock);
27+
#define ENTER_CRITICAL_SECTION() RTC_ENTER_CRITICAL()
28+
#define LEAVE_CRITICAL_SECTION() RTC_EXIT_CRITICAL()
29+
#define LEAVE_CRITICAL() RTC_EXIT_CRITICAL()
3130

3231
void sar_periph_ctrl_init(void)
3332
{

‎components/esp_hw_support/port/esp32s2/adc2_init_cal.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ Don't put any other code into this file. */
1313
#include "hal/adc_types.h"
1414
#include "hal/adc_hal_common.h"
1515
#include "esp_private/adc_share_hw_ctrl.h"
16+
#include "rtc_lock.h"
1617

17-
extern int rtc_spinlock;
18-
19-
#define ENTER_CRITICAL_SECTION() do { rtc_spinlock = irq_lock(); } while(0)
20-
#define LEAVE_CRITICAL_SECTION() irq_unlock(rtc_spinlock);
18+
#define ENTER_CRITICAL_SECTION() RTC_ENTER_CRITICAL()
19+
#define LEAVE_CRITICAL_SECTION() RTC_EXIT_CRITICAL()
2120

2221
/**
2322
* @brief Set initial code to ADC2 after calibration. ADC2 RTC and ADC2 PWDET controller share the initial code.

‎components/esp_hw_support/port/esp32s2/sar_periph_ctrl.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@
2222
#include "esp_private/sar_periph_ctrl.h"
2323
#include "hal/sar_ctrl_ll.h"
2424
#include "hal/adc_ll.h"
25+
#include "rtc_lock.h"
2526

2627
static const char *TAG = "sar_periph_ctrl";
2728

28-
static int rtc_spinlock;
29-
30-
#define ENTER_CRITICAL_SECTION() do { rtc_spinlock = irq_lock(); } while(0)
31-
#define LEAVE_CRITICAL_SECTION() irq_unlock(rtc_spinlock);
32-
#define LEAVE_CRITICAL() irq_unlock(rtc_spinlock);
29+
#define ENTER_CRITICAL_SECTION() RTC_ENTER_CRITICAL()
30+
#define LEAVE_CRITICAL_SECTION() RTC_EXIT_CRITICAL()
31+
#define LEAVE_CRITICAL() RTC_EXIT_CRITICAL()
3332

3433
void sar_periph_ctrl_init(void)
3534
{

‎components/esp_hw_support/port/esp32s3/sar_periph_ctrl.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@
2222
#include "esp_private/sar_periph_ctrl.h"
2323
#include "hal/sar_ctrl_ll.h"
2424
#include "hal/adc_ll.h"
25+
#include "rtc_lock.h"
2526

2627
static const char *TAG = "sar_periph_ctrl";
2728

28-
static int rtc_spinlock;
29-
30-
#define ENTER_CRITICAL_SECTION() do { rtc_spinlock = irq_lock(); } while(0)
31-
#define LEAVE_CRITICAL_SECTION() irq_unlock(rtc_spinlock);
32-
#define LEAVE_CRITICAL() irq_unlock(rtc_spinlock);
29+
#define ENTER_CRITICAL_SECTION() RTC_ENTER_CRITICAL()
30+
#define LEAVE_CRITICAL_SECTION() RTC_EXIT_CRITICAL()
31+
#define LEAVE_CRITICAL() RTC_EXIT_CRITICAL()
3332

3433
void sar_periph_ctrl_init(void)
3534
{

‎components/esp_hw_support/rtc_module.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "esp_types.h"
1414
#include "esp_log.h"
1515
#include "soc/rtc_periph.h"
16+
#include "rtc_lock.h"
1617
#include "soc/syscon_periph.h"
1718
#include "soc/rtc.h"
1819
#include "soc/periph_defs.h"
@@ -35,7 +36,6 @@ static const char *TAG = "rtc_module";
3536

3637
#define NOT_REGISTERED (-1)
3738

38-
int rtc_spinlock;
3939
static DRAM_ATTR int s_rtc_isr_handler_list_lock;
4040
#define RTC_ISR_HANDLER_ENTER_CRITICAL() do { s_rtc_isr_handler_list_lock = irq_lock(); } while(0)
4141
#define RTC_ISR_HANDLER_EXIT_CRITICAL() irq_unlock(s_rtc_isr_handler_list_lock);

‎components/esp_hw_support/sar_periph_ctrl_common.c

+1-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "soc/soc_caps.h"
1111
#include "esp_private/sar_periph_ctrl.h"
1212
#include "esp_log.h"
13+
#include "rtc_lock.h"
1314

1415
#if SOC_TEMP_SENSOR_SUPPORTED
1516
#include "hal/temperature_sensor_ll.h"
@@ -18,12 +19,6 @@
1819
#include "esp_private/periph_ctrl.h"
1920
#include "esp_private/adc_share_hw_ctrl.h"
2021

21-
extern int rtc_spinlock;
22-
23-
#define RTC_ENTER_CRITICAL() do { rtc_spinlock = irq_lock(); } while(0)
24-
#define RTC_EXIT_CRITICAL() irq_unlock(rtc_spinlock);
25-
26-
2722
/*------------------------------------------------------------------------------------------------------------
2823
-----------------------------------------Temperature Sensor---------------------------------------------------
2924
------------------------------------------------------------------------------------------------------------*/

0 commit comments

Comments
 (0)
Please sign in to comment.