Skip to content

Commit e56f04f

Browse files
committed
fix(mcpwm): fix pm_lock memory issues
1 parent 1e4ebab commit e56f04f

File tree

6 files changed

+22
-10
lines changed

6 files changed

+22
-10
lines changed

components/esp_driver_mcpwm/src/mcpwm_cap.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,11 @@ static void mcpwm_cap_timer_unregister_from_group(mcpwm_cap_timer_t *cap_timer)
6969

7070
static esp_err_t mcpwm_cap_timer_destroy(mcpwm_cap_timer_t *cap_timer)
7171
{
72+
#if !SOC_MCPWM_CAPTURE_CLK_FROM_GROUP
7273
if (cap_timer->pm_lock) {
7374
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(cap_timer->pm_lock), TAG, "delete pm_lock failed");
7475
}
76+
#endif
7577
if (cap_timer->group) {
7678
mcpwm_cap_timer_unregister_from_group(cap_timer);
7779
}
@@ -101,6 +103,7 @@ esp_err_t mcpwm_new_capture_timer(const mcpwm_capture_timer_config_t *config, mc
101103
#if SOC_MCPWM_CAPTURE_CLK_FROM_GROUP
102104
// capture timer clock source is same as the MCPWM group
103105
ESP_GOTO_ON_ERROR(mcpwm_select_periph_clock(group, (soc_module_clk_t)clk_src), err, TAG, "set group clock failed");
106+
cap_timer->pm_lock = group->pm_lock;
104107
uint32_t periph_src_clk_hz = 0;
105108
ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &periph_src_clk_hz), err, TAG, "get clock source freq failed");
106109
ESP_LOGD(TAG, "periph_src_clk_hz %"PRIu32"", periph_src_clk_hz);

components/esp_driver_mcpwm/src/mcpwm_com.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ void mcpwm_release_group_handle(mcpwm_group_t *group)
113113
MCPWM_RCC_ATOMIC() {
114114
mcpwm_ll_enable_bus_clock(group_id, false);
115115
}
116+
if (group->pm_lock) {
117+
esp_pm_lock_delete(group->pm_lock);
118+
}
116119
free(group);
117120
}
118121
_lock_release(&s_platform.mutex);

docs/en/api-reference/peripherals/mcpwm.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -978,9 +978,9 @@ Power Management
978978

979979
When power management is enabled (i.e., :ref:`CONFIG_PM_ENABLE` is on), the system will adjust the PLL and APB frequency before going into Light-sleep, thus potentially changing the period of an MCPWM timers' counting step and leading to inaccurate time-keeping.
980980

981-
However, the driver can prevent the system from changing APB frequency by acquiring a power management lock of type :cpp:enumerator:`ESP_PM_APB_FREQ_MAX`. Whenever the driver creates an MCPWM timer instance that has selected :cpp:enumerator:`MCPWM_TIMER_CLK_SRC_PLL160M` as its clock source, the driver guarantees that the power management lock is acquired when enabling the timer by :cpp:func:`mcpwm_timer_enable`. On the contrary, the driver releases the lock when :cpp:func:`mcpwm_timer_disable` is called for that timer.
981+
However, the driver can prevent the system from going into Light-sleep by acquiring a power management lock of type :cpp:enumerator:`ESP_PM_NO_LIGHT_SLEEP`. Whenever the driver creates an MCPWM timer instance that has selected PLL as its clock source, the driver guarantees that the power management lock is acquired when enabling the timer by :cpp:func:`mcpwm_timer_enable`. On the contrary, the driver releases the lock when :cpp:func:`mcpwm_timer_disable` is called for that timer.
982982

983-
Likewise, whenever the driver creates an MCPWM capture timer instance that has selected :cpp:enumerator:`MCPWM_CAPTURE_CLK_SRC_APB` as its clock source, the driver guarantees that the power management lock is acquired when enabling the timer by :cpp:func:`mcpwm_capture_timer_enable`. And releases the lock in :cpp:func:`mcpwm_capture_timer_disable`.
983+
Likewise, whenever the driver creates an MCPWM capture timer instance, the driver guarantees that the power management lock is acquired when enabling the timer by :cpp:func:`mcpwm_capture_timer_enable`. And releases the lock in :cpp:func:`mcpwm_capture_timer_disable`.
984984

985985

986986
.. _mcpwm-iram-safe:

docs/en/api-reference/system/power_management.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,18 @@ The following drivers hold the ``ESP_PM_APB_FREQ_MAX`` lock while the driver is
118118
:SOC_TWAI_SUPPORTED: - **TWAI**: between calls to :cpp:func:`twai_driver_install` and :cpp:func:`twai_driver_uninstall` (only when the clock source is set to :cpp:enumerator:`TWAI_CLK_SRC_APB`).
119119
:SOC_BT_SUPPORTED and esp32: - **Bluetooth**: between calls to :cpp:func:`esp_bt_controller_enable` and :cpp:func:`esp_bt_controller_disable`. If Bluetooth Modem-sleep is enabled, the ``ESP_PM_APB_FREQ_MAX`` lock will be released for the periods of time when radio is disabled. However the ``ESP_PM_NO_LIGHT_SLEEP`` lock will still be held, unless :ref:`CONFIG_BTDM_CTRL_LOW_POWER_CLOCK` option is set to "External 32kHz crystal".
120120
:SOC_BT_SUPPORTED and not esp32: - **Bluetooth**: between calls to :cpp:func:`esp_bt_controller_enable` and :cpp:func:`esp_bt_controller_disable`. If Bluetooth Modem-sleep is enabled, the ``ESP_PM_APB_FREQ_MAX`` lock will be released for the periods of time when radio is disabled. However the ``ESP_PM_NO_LIGHT_SLEEP`` lock will still be held.
121+
:SOC_PCNT_SUPPORTED: - **PCNT**: between calls to :cpp:func:`pcnt_unit_enable` and :cpp:func:`pcnt_unit_disable`.
122+
:SOC_SDM_SUPPORTED: - **Sigma-delta**: between calls to :cpp:func:`sdm_channel_enable` and :cpp:func:`sdm_channel_disable`.
123+
:SOC_MCPWM_SUPPORTED: - **MCPWM**: between calls to :cpp:func:`mcpwm_timer_enable` and :cpp:func:`mcpwm_timer_disable`, as well as :cpp:func:`mcpwm_capture_timer_enable` and :cpp:func:`mcpwm_capture_timer_disable`.
121124

122125
The following peripheral drivers are not aware of DFS yet. Applications need to acquire/release locks themselves, when necessary:
123126

124127
.. list::
125128

126-
- PCNT
127-
- Sigma-delta
129+
:SOC_PCNT_SUPPORTED: - The legacy PCNT driver
130+
:SOC_SDM_SUPPORTED: - The legacy Sigma-delta driver
128131
- The legacy timer group driver
129-
:SOC_MCPWM_SUPPORTED: - MCPWM
132+
:SOC_MCPWM_SUPPORTED: - The legacy MCPWM driver
130133

131134

132135
.. only:: SOC_PM_SUPPORT_TOP_PD

docs/zh_CN/api-reference/peripherals/mcpwm.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -978,9 +978,9 @@ MCPWM 捕获通道支持在信号上检测到有效边沿时发送通知。须
978978

979979
启用电源管理(即开启 :ref:`CONFIG_PM_ENABLE`)时,系统会在进入 Light-sleep 前调整 PLL 和 APB 频率。该操作有可能会改变 MCPWM 定时器的计数步长,导致计时偏差。
980980

981-
不过,驱动程序可以获取 :cpp:enumerator:`ESP_PM_APB_FREQ_MAX` 类型的电源管理锁,防止系统改变 APB 频率。每当驱动创建以 :cpp:enumerator:`MCPWM_TIMER_CLK_SRC_PLL160M` 作为时钟源的 MCPWM 定时器实例时,都会在通过 :cpp:func:`mcpwm_timer_enable` 启用定时器时获取电源管理锁。反之,调用 :cpp:func:`mcpwm_timer_disable` 时,驱动程序释放锁。
981+
不过,驱动程序可以获取 :cpp:enumerator:`ESP_PM_NO_LIGHT_SLEEP` 类型的电源管理锁,防止系统进入 Light-sleep。每当驱动创建以 PLL 作为时钟源的 MCPWM 定时器实例时,都会在通过 :cpp:func:`mcpwm_timer_enable` 启用定时器时获取电源管理锁。反之,调用 :cpp:func:`mcpwm_timer_disable` 时,驱动程序释放锁。
982982

983-
同理,每当驱动创建一个以 :cpp:enumerator:`MCPWM_CAPTURE_CLK_SRC_APB` 作为时钟源的 MCPWM 捕获定时器实例时,都会在通过 :cpp:func:`mcpwm_capture_timer_enable` 启用定时器时获取电源管理锁,并在调用 :cpp:func:`mcpwm_capture_timer_disable` 时释放锁。
983+
同理,每当驱动创建 MCPWM 捕获定时器实例时,都会在通过 :cpp:func:`mcpwm_capture_timer_enable` 启用定时器时获取电源管理锁,并在调用 :cpp:func:`mcpwm_capture_timer_disable` 时释放锁。
984984

985985

986986
.. _mcpwm-iram-safe:

docs/zh_CN/api-reference/system/power_management.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,18 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,
118118
:SOC_TWAI_SUPPORTED: - **TWAI**:从调用 :cpp:func:`twai_driver_install` 至 :cpp:func:`twai_driver_uninstall` 期间 (只有在 TWAI 时钟源选择为 :cpp:enumerator:`TWAI_CLK_SRC_APB` 的时候生效)。
119119
:SOC_BT_SUPPORTED and esp32: - **Bluetooth**:从调用 :cpp:func:`esp_bt_controller_enable` 至 :cpp:func:`esp_bt_controller_disable` 期间。如果启用了蓝牙调制解调器,广播关闭时将释放此管理锁。但依然占用 ``ESP_PM_NO_LIGHT_SLEEP`` 锁,除非将 :ref:`CONFIG_BTDM_CTRL_LOW_POWER_CLOCK` 选项设置为 “外部 32 kHz 晶振”。
120120
:SOC_BT_SUPPORTED and not esp32: - **Bluetooth**:从调用 :cpp:func:`esp_bt_controller_enable` 至 :cpp:func:`esp_bt_controller_disable` 期间。如果启用了蓝牙调制解调器,广播关闭时将释放此管理锁。但依然占用 ``ESP_PM_NO_LIGHT_SLEEP`` 锁。
121+
:SOC_PCNT_SUPPORTED: - **PCNT**:从调用 :cpp:func:`pcnt_unit_enable` 至 :cpp:func:`pcnt_unit_disable` 期间。
122+
:SOC_SDM_SUPPORTED: - **Sigma-delta**:从调用 :cpp:func:`sdm_channel_enable` 至 :cpp:func:`sdm_channel_disable` 期间。
123+
:SOC_MCPWM_SUPPORTED: - **MCPWM**: 从调用 :cpp:func:`mcpwm_timer_enable` 至 :cpp:func:`mcpwm_timer_disable` 期间,以及调用 :cpp:func:`mcpwm_capture_timer_enable` 至 :cpp:func:`mcpwm_capture_timer_disable` 期间。
121124

122125
以下外设驱动程序无法感知动态调频,应用程序需自己获取/释放管理锁:
123126

124127
.. list::
125128

126-
- PCNT
127-
- Sigma-delta
129+
:SOC_PCNT_SUPPORTED: - 旧版 PCNT 驱动
130+
:SOC_SDM_SUPPORTED: - 旧版 Sigma-delta 驱动
128131
- 旧版定时器驱动 (Timer Group)
129-
:SOC_MCPWM_SUPPORTED: - MCPWM
132+
:SOC_MCPWM_SUPPORTED: - 旧版 MCPWM 驱动
130133

131134

132135
.. only:: SOC_PM_SUPPORT_TOP_PD

0 commit comments

Comments
 (0)