Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bac5867

Browse filesBrowse files
authored
Fix memory leak caused by multiple calls to addApbChangeCallback()
Every time frequency was changed, an additional cpu frequency change callback was added. Code now adds ONE callback and uses a static variable to denote active channels requiring timer reconfig on base frequency change.
1 parent e08429f commit bac5867
Copy full SHA for bac5867

File tree

Expand file treeCollapse file tree

1 file changed

+27
-20
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+27
-20
lines changed

‎cores/esp32/esp32-hal-ledc.c

Copy file name to clipboardExpand all lines: cores/esp32/esp32-hal-ledc.c
+27-20Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,32 @@ xSemaphoreHandle _ledc_sys_lock = NULL;
5555

5656
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
5757
if(ev_type == APB_AFTER_CHANGE && old_apb != new_apb){
58-
uint32_t iarg = (uint32_t)arg;
59-
uint8_t chan = iarg;
60-
uint8_t group=(chan/8), timer=((chan/2)%4);
58+
uint16_t iarg = (uint16_t*)arg;
59+
uint8_t chan = 0;
6160
old_apb /= 1000000;
6261
new_apb /= 1000000;
63-
if(LEDC_TIMER(group, timer).conf.tick_sel){
64-
LEDC_MUTEX_LOCK();
65-
uint32_t old_div = LEDC_TIMER(group, timer).conf.clock_divider;
66-
uint32_t div_num = (new_apb * old_div) / old_apb;
67-
if(div_num > LEDC_DIV_NUM_HSTIMER0_V){
68-
new_apb = REF_CLK_FREQ / 1000000;
69-
div_num = (new_apb * old_div) / old_apb;
70-
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
71-
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
62+
while(iarg){ // run though all active channels, adjusting timing configurations
63+
if(iarg & 1) {// this channel is active
64+
uint8_t group=(chan/8), timer=((chan/2)%4);
65+
if(LEDC_TIMER(group, timer).conf.tick_sel){
66+
LEDC_MUTEX_LOCK();
67+
uint32_t old_div = LEDC_TIMER(group, timer).conf.clock_divider;
68+
uint32_t div_num = (new_apb * old_div) / old_apb;
69+
if(div_num > LEDC_DIV_NUM_HSTIMER0_V){
70+
div_num = ((REF_CLK_FREQ /1000000) * old_div) / old_apb;
71+
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
72+
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
73+
}
74+
LEDC_TIMER(group, timer).conf.tick_sel = 0;
75+
} else if(div_num < 256) {
76+
div_num = 256;//highest clock possible
77+
}
78+
LEDC_TIMER(group, timer).conf.clock_divider = div_num;
79+
LEDC_MUTEX_UNLOCK();
7280
}
73-
LEDC_TIMER(group, timer).conf.tick_sel = 0;
74-
} else if(div_num < 256) {
75-
div_num = 256;//highest clock possible
7681
}
77-
LEDC_TIMER(group, timer).conf.clock_divider = div_num;
78-
LEDC_MUTEX_UNLOCK();
82+
iarg = iarg >> 1;
83+
chan++;
7984
}
8085
}
8186
}
@@ -85,13 +90,16 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
8590
{
8691
uint8_t group=(chan/8), timer=((chan/2)%4);
8792
static bool tHasStarted = false;
93+
static uint16_t _activeChannels = 0;
8894
if(!tHasStarted) {
8995
tHasStarted = true;
9096
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_LEDC_CLK_EN);
9197
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_LEDC_RST);
9298
LEDC.conf.apb_clk_sel = 1;//LS use apb clock
99+
addApbChangeCallback((void*)&_activeChannels, _on_apb_change);
100+
93101
#if !CONFIG_DISABLE_HAL_LOCKS
94-
if( _ledc_sys_lock == NULL) _ledc_sys_lock = xSemaphoreCreateMutex();
102+
_ledc_sys_lock = xSemaphoreCreateMutex();
95103
#endif
96104
}
97105
LEDC_MUTEX_LOCK();
@@ -105,8 +113,7 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
105113
LEDC_TIMER(group, timer).conf.rst = 1;//This bit is used to reset timer the counter will be 0 after reset.
106114
LEDC_TIMER(group, timer).conf.rst = 0;
107115
LEDC_MUTEX_UNLOCK();
108-
uint32_t iarg = chan;
109-
addApbChangeCallback((void*)iarg, _on_apb_change);
116+
_activeChannels |= (1 << chan); // mark as active for APB callback
110117
}
111118

112119
//max div_num 0x3FFFF (262143)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.