Skip to content

Commit 0193d06

Browse files
committed
Merge branch 'feature/refactor_ccompare_timer' into 'master'
esp8266: refactor CCOMPARE timer and system time by microseconds See merge request sdk/ESP8266_RTOS_SDK!1060
2 parents 805feee + b061230 commit 0193d06

File tree

7 files changed

+85
-61
lines changed

7 files changed

+85
-61
lines changed

components/esp8266/include/driver/soc.h

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,6 @@ extern "C" {
2626
typedef uint32_t esp_tick_t;
2727
typedef uint32_t esp_irqflag_t;
2828

29-
static inline esp_tick_t soc_get_ticks(void)
30-
{
31-
esp_tick_t ticks;
32-
33-
__asm__ __volatile__(
34-
"rsr %0, ccount\n"
35-
: "=a"(ticks)
36-
:
37-
: "memory"
38-
);
39-
40-
return ticks;
41-
}
42-
4329
static inline esp_irqflag_t soc_save_local_irq(void)
4430
{
4531
esp_irqflag_t flag;
@@ -102,6 +88,16 @@ static inline uint32_t soc_get_ccount(void)
10288
return ticks;
10389
}
10490

91+
static inline void soc_set_ccount(uint32_t ticks)
92+
{
93+
__asm__ __volatile__(
94+
"wsr %0, ccount\n"
95+
:
96+
: "a"(ticks)
97+
: "memory"
98+
);
99+
}
100+
105101
static inline void soc_clear_int_mask(uint32_t mask)
106102
{
107103
__asm__ __volatile__(

components/esp8266/include/esp8266/eagle_soc.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@
9494
#define APB_CLK_FREQ CPU_CLK_FREQ
9595
#define UART_CLK_FREQ APB_CLK_FREQ
9696
#define TIMER_CLK_FREQ (APB_CLK_FREQ >> 8) // divided by 256
97+
98+
#define FREQ_1MHZ (1000 * 1000)
99+
#define FREQ_1KHZ (1000)
100+
101+
#define CPU_FREQ_160MHZ (160 * 1000 * 1000)
102+
#define CPU_FREQ_80MHz (80 * 1000 * 1000)
103+
104+
#define CPU_160M_TICKS_PRT_MS (CPU_FREQ_160MHZ / FREQ_1MHZ)
105+
#define CPU_80M_TICKS_PRT_MS (CPU_FREQ_80MHz / FREQ_1KHZ)
106+
107+
#define CPU_160M_TICKS_PRT_US (CPU_FREQ_160MHZ / FREQ_1MHZ)
108+
#define CPU_80M_TICKS_PRT_US (CPU_FREQ_80MHz / FREQ_1MHZ)
97109
//}}
98110

99111
//Peripheral device base address define{{

components/esp8266/source/esp_timer.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -202,26 +202,7 @@ esp_err_t esp_timer_delete(esp_timer_handle_t timer)
202202

203203
int64_t esp_timer_get_time()
204204
{
205-
extern esp_tick_t g_cpu_ticks;
206-
extern uint64_t g_os_ticks;
205+
extern uint64_t g_esp_os_us;
207206

208-
esp_irqflag_t flag;
209-
esp_tick_t diff_ticks, ticks;
210-
uint64_t time;
211-
212-
flag = soc_save_local_irq();
213-
214-
time = g_os_ticks * portTICK_PERIOD_MS * 1000;
215-
ticks = soc_get_ticks();
216-
if (ticks >= g_cpu_ticks) {
217-
diff_ticks = ticks - g_cpu_ticks;
218-
} else {
219-
diff_ticks = ESP_TICKS_MAX - g_cpu_ticks + ticks;
220-
}
221-
222-
time += diff_ticks / (_xt_tick_divisor * configTICK_RATE_HZ / (1000 * 1000));
223-
224-
soc_restore_local_irq(flag);
225-
226-
return (int64_t)time;
207+
return (int64_t)g_esp_os_us;
227208
}

components/freertos/freertos/tasks.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2522,7 +2522,7 @@ implementations require configUSE_TICKLESS_IDLE to be set to a value other than
25222522
1. */
25232523
#if ( configUSE_TICKLESS_IDLE != 0 )
25242524

2525-
void vTaskStepTick( const TickType_t xTicksToJump )
2525+
void IRAM_ATTR vTaskStepTick( const TickType_t xTicksToJump )
25262526
{
25272527
/* Correct the tick count value after a period during which the tick
25282528
was suppressed. Note this does *not* call the tick hook function for

components/freertos/port/esp8266/include/freertos/FreeRTOSConfig.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,11 @@ NVIC value of 255. */
158158
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
159159

160160
#ifdef CONFIG_FREERTOS_RUN_TIME_STATS_USING_CPU_CLK
161+
#ifndef __ASSEMBLER__
162+
extern uint64_t g_esp_os_cpu_clk;
163+
#define portGET_RUN_TIME_COUNTER_VALUE() g_esp_os_cpu_clk
164+
#endif
161165
/* Fine resolution time */
162-
#define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount()
163166
#elif defined(CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER)
164167
/* Coarse resolution time (us) */
165168
#ifndef __ASSEMBLER__

components/freertos/port/esp8266/port.c

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ int __g_is_task_overflow;
6363
variable. */
6464
static uint32_t uxCriticalNesting = 0;
6565

66-
esp_tick_t g_cpu_ticks = 0;
67-
uint64_t g_os_ticks = 0;
66+
uint32_t g_esp_boot_ccount;
67+
uint64_t g_esp_os_ticks;
68+
uint64_t g_esp_os_us;
69+
uint64_t g_esp_os_cpu_clk;
6870

6971
void vPortEnterCritical(void);
7072
void vPortExitCritical(void);
@@ -134,20 +136,46 @@ void esp_increase_tick_cnt(const TickType_t ticks)
134136

135137
flag = soc_save_local_irq();
136138

137-
g_cpu_ticks = soc_get_ticks();
138-
g_os_ticks += ticks;
139+
g_esp_os_ticks += ticks;
139140

140141
soc_restore_local_irq(flag);
141142
}
142143

143-
void TASK_SW_ATTR xPortSysTickHandle(void *p)
144+
void IRAM_ATTR xPortSysTickHandle(void *p)
144145
{
145-
const uint32_t cpu_clk_cnt = soc_get_ccount() + _xt_tick_divisor;
146+
uint32_t us;
147+
uint32_t ticks;
148+
uint32_t ccount;
149+
150+
/**
151+
* System or application may close interrupt too long, such as the operation of read/write/erase flash.
152+
* And then the "ccount" value may be overflow.
153+
*
154+
* So add code here to calibrate system time.
155+
*/
156+
if (_xt_tick_divisor == (CPU_FREQ_80MHz / XT_TICK_PER_SEC)) {
157+
ccount = soc_get_ccount();
158+
us = ccount / CPU_80M_TICKS_PRT_US;
159+
} else {
160+
ccount = soc_get_ccount();
161+
us = ccount / CPU_160M_TICKS_PRT_US;
162+
}
163+
g_esp_os_us += us;
164+
g_esp_os_cpu_clk += ccount;
165+
166+
soc_set_ccount(0);
167+
soc_set_ccompare(_xt_tick_divisor);
146168

147-
soc_set_ccompare(cpu_clk_cnt);
169+
ticks = us / 1000 / portTICK_PERIOD_MS;
170+
if (!ticks) {
171+
ets_printf("\r\nERROR: CCOMPARE timer period");
172+
ticks = 1;
173+
}
148174

149-
g_cpu_ticks = soc_get_ticks();
150-
g_os_ticks++;
175+
g_esp_os_ticks += ticks;
176+
if (ticks > 1) {
177+
vTaskStepTick(ticks - 1);
178+
}
151179

152180
if (xTaskIncrementTick() != pdFALSE) {
153181
vTaskSwitchContext();
@@ -186,13 +214,12 @@ portBASE_TYPE xPortStartScheduler(void)
186214
/* Initialize system tick timer interrupt and schedule the first tick. */
187215
_xt_tick_divisor = xtbsp_clock_freq_hz() / XT_TICK_PER_SEC;
188216

217+
g_esp_boot_ccount = soc_get_ccount();
218+
soc_set_ccount(0);
189219
_xt_tick_timer_init();
190220

191221
vTaskSwitchContext();
192222

193-
/* Get ticks before RTOS starts */
194-
g_cpu_ticks = soc_get_ticks();
195-
196223
/* Restore the context of the first task that is going to run. */
197224
_xt_enter_first_task();
198225

components/log/log.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include "esp_log.h"
3030
#include "esp_system.h"
3131

32+
#ifndef BOOTLOADER_BUILD
33+
#include "FreeRTOS.h"
34+
#endif
35+
3236
#ifdef CONFIG_LOG_COLORS
3337
#define LOG_COLOR_HEAD "\033[0;%dm"
3438
#define LOG_BOLD_HEAD "\033[1;%dm"
@@ -55,7 +59,18 @@ static const char s_log_prefix[ESP_LOG_MAX] = {
5559

5660
uint32_t IRAM_ATTR esp_log_early_timestamp()
5761
{
58-
return xthal_get_ccount() / ((CRYSTAL_USED * 2) * 1000);
62+
#ifndef BOOTLOADER_BUILD
63+
extern uint64_t g_esp_os_us;
64+
extern uint64_t g_esp_boot_ccount;
65+
66+
const uint32_t ticks_per_ms = _xt_tick_divisor * configTICK_RATE_HZ / 1000;
67+
const uint32_t ms = g_esp_os_us / 1000 + g_esp_boot_ccount / ((CRYSTAL_USED * 2) * 1000);
68+
#else
69+
const uint32_t ticks_per_ms = ((CRYSTAL_USED * 2) * 1000);
70+
const uint32_t ms = 0;
71+
#endif
72+
73+
return soc_get_ccount() / ticks_per_ms + ms;
5974
}
6075

6176
#ifndef BOOTLOADER_BUILD
@@ -190,16 +205,6 @@ static int esp_log_write_str(const char *s)
190205
return ret;
191206
}
192207

193-
uint32_t esp_log_timestamp()
194-
{
195-
static uint32_t base = 0;
196-
197-
if (base == 0) {
198-
base = esp_log_early_timestamp();
199-
}
200-
201-
return base + clock() * (1000 / CLOCKS_PER_SEC);
202-
}
203208
#endif
204209

205210
/**
@@ -262,7 +267,7 @@ void esp_log_write(esp_log_level_t level, const char *tag, const char *fmt, ...
262267
}
263268
#endif
264269
prefix = level >= ESP_LOG_MAX ? 'N' : s_log_prefix[level];
265-
ret = asprintf(&pbuf, "%c (%d) %s: ", prefix, esp_log_timestamp(), tag);
270+
ret = asprintf(&pbuf, "%c (%d) %s: ", prefix, esp_log_early_timestamp(), tag);
266271
if (ret < 0)
267272
goto out;
268273
ret = esp_log_write_str(pbuf);

0 commit comments

Comments
 (0)