· 6 years ago · Aug 31, 2019, 07:34 AM
1From 56036a278ba819bdabf3b32f580d9ecd51123db7 Mon Sep 17 00:00:00 2001
2From: Peter Bigot <peter.bigot@nordicsemi.no>
3Date: Mon, 19 Aug 2019 11:00:00 -0500
4Subject: [PATCH] drivers/timer/nrf_rtc_timer: clarify intent of ZLI
5 compensation
6
7The variable enabling entry to the zero latency interrupt compensation
8loop was named generically, and its logic inverted, making the code
9difficult to understand. Change the name and initial value to more
10clearly indicate its role.
11
12Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
13---
14 drivers/timer/nrf_rtc_timer.c | 16 +++++++++
15 kernel/idle.c | 2 ++
16 kernel/sched.c | 61 +++++++++++++++++++++++++++++++--
17 kernel/timeout.c | 10 ++++++
18 tests/kernel/sleep/src/main.c | 2 +-
19 tests/kernel/sleep/src/usleep.c | 6 ++--
20 6 files changed, 91 insertions(+), 6 deletions(-)
21
22diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c
23index a83aa13ddb..6955d40cab 100644
24--- a/drivers/timer/nrf_rtc_timer.c
25+++ b/drivers/timer/nrf_rtc_timer.c
26@@ -52,6 +52,7 @@ void rtc1_nrf_isr(void *arg)
27 ARG_UNUSED(arg);
28 RTC->EVENTS_COMPARE[0] = 0;
29
30+ NRF_P1->OUTSET = (1U << 4);
31 k_spinlock_key_t key = k_spin_lock(&lock);
32 u32_t t = counter();
33 u32_t dticks = counter_sub(t, last_count) / CYC_PER_TICK;
34@@ -71,6 +72,7 @@ void rtc1_nrf_isr(void *arg)
35 }
36
37 k_spin_unlock(&lock, key);
38+ NRF_P1->OUTCLR = (1U << 4);
39 z_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
40 }
41
42@@ -114,6 +116,7 @@ void z_clock_set_timeout(s32_t ticks, bool idle)
43 ARG_UNUSED(idle);
44
45 #ifdef CONFIG_TICKLESS_KERNEL
46+ NRF_P1->OUTSET = (1U << 3);
47 ticks = (ticks == K_FOREVER) ? MAX_TICKS : ticks;
48 ticks = MAX(MIN(ticks - 1, (s32_t)MAX_TICKS), 0);
49
50@@ -121,6 +124,8 @@ void z_clock_set_timeout(s32_t ticks, bool idle)
51 u32_t cyc, dt, t = counter();
52 bool flagged = false;
53
54+ counter_sub(t, last_count);
55+
56 /* Round up to next tick boundary */
57 cyc = ticks * CYC_PER_TICK + 1 + counter_sub(t, last_count);
58 cyc += (CYC_PER_TICK - 1);
59@@ -154,19 +159,29 @@ void z_clock_set_timeout(s32_t ticks, bool idle)
60 * interrupt. The docs say two cycles, they mean two cycles.
61 */
62 if (counter_sub(cyc, t) > 2) {
63+ NRF_P1->OUTSET = (1U << 2);
64 set_comparator(cyc);
65+ NRF_P1->OUTCLR = (1U << 2);
66 } else {
67 set_comparator(cyc);
68 dt = counter_sub(cyc, counter());
69 if (dt == 0 || dt > 0x7fffff) {
70 /* Missed it! */
71+ NRF_P1->OUTSET = (1U << 2) | (1U << 8);
72 NVIC_SetPendingIRQ(RTC1_IRQn);
73 if (IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS)) {
74 flagged = true;
75 }
76+ NRF_P1->OUTCLR = (1U << 2) | (1U << 8);
77 } else if (dt == 1) {
78 /* Too soon, interrupt won't arrive. */
79+ NRF_P1->OUTSET = (1U << 2);
80 set_comparator(cyc + 2);
81+ NRF_P1->OUTCLR = (1U << 2);
82+ NRF_P1->OUTSET = (1U << 2);
83+ NRF_P1->OUTCLR = (1U << 2);
84+ NRF_P1->OUTSET = (1U << 2);
85+ NRF_P1->OUTCLR = (1U << 2);
86 }
87 /* Otherwise it was two cycles out, we're fine */
88 }
89@@ -191,6 +206,7 @@ void z_clock_set_timeout(s32_t ticks, bool idle)
90 #endif
91
92 k_spin_unlock(&lock, key);
93+ NRF_P1->OUTCLR = (1U << 3);
94 #endif /* CONFIG_TICKLESS_KERNEL */
95 }
96
97diff --git a/kernel/idle.c b/kernel/idle.c
98index 2172c077c2..1466b9b254 100644
99--- a/kernel/idle.c
100+++ b/kernel/idle.c
101@@ -75,7 +75,9 @@ static void sys_power_save_idle(void)
102 * API we need to honor...
103 */
104 #ifdef CONFIG_SYS_CLOCK_EXISTS
105+ //NRF_P1->OUTSET = (1U << 8);
106 z_set_timeout_expiry((ticks < IDLE_THRESH) ? 1 : ticks, true);
107+ //NRF_P1->OUTCLR = (1U << 8);
108 #endif
109
110 set_kernel_idle_time_in_ticks(ticks);
111diff --git a/kernel/sched.c b/kernel/sched.c
112index 026804d057..7a892a4ec3 100644
113--- a/kernel/sched.c
114+++ b/kernel/sched.c
115@@ -800,8 +800,46 @@ int z_unpend_all(_wait_q_t *wait_q)
116 return need_sched;
117 }
118
119+#define LOGIC 1
120+
121 void z_sched_init(void)
122 {
123+#if (LOGIC - 0)
124+ NRF_P1->OUTCLR = (0xFFU << 1);
125+ NRF_P1->PIN_CNF[1] = ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
126+ | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
127+ | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
128+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos));
129+ NRF_P1->PIN_CNF[2] = ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
130+ | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
131+ | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
132+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos));
133+ NRF_P1->PIN_CNF[3] = ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
134+ | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
135+ | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
136+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos));
137+ NRF_P1->PIN_CNF[4] = ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
138+ | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
139+ | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
140+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos));
141+ NRF_P1->PIN_CNF[5] = ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
142+ | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
143+ | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
144+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos));
145+ NRF_P1->PIN_CNF[6] = ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
146+ | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
147+ | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
148+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos));
149+ NRF_P1->PIN_CNF[7] = ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
150+ | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
151+ | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
152+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos));
153+ NRF_P1->PIN_CNF[8] = ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
154+ | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
155+ | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
156+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos));
157+#endif
158+
159 #ifdef CONFIG_SCHED_DUMB
160 sys_dlist_init(&_kernel.ready_q.runq);
161 #endif
162@@ -981,13 +1019,30 @@ Z_SYSCALL_HANDLER(k_sleep, ms)
163 }
164 #endif
165
166+#define MEASURE 0
167+extern s32_t xxx_nto;
168+
169 s32_t z_impl_k_usleep(int us)
170 {
171 s32_t ticks;
172
173- ticks = z_us_to_ticks(us);
174- ticks = z_tick_sleep(ticks);
175- return __ticks_to_us(ticks);
176+#if (MEASURE - 0)
177+ u32_t now = NRF_RTC1->COUNTER; // k_cycle_get_32();
178+#endif /* MEASURE */
179+ ticks = z_us_to_ticks(us); /* 1 */
180+#if (LOGIC - 0)
181+ NRF_P1->OUTSET = (1U << 1);
182+#endif /* LOGIC */
183+ z_tick_sleep(ticks); /* 0 */
184+ ticks = xxx_nto;
185+#if (LOGIC - 0)
186+ NRF_P1->OUTCLR = (1U << 1);
187+#endif /* LOGIC */
188+#if (MEASURE - 0)
189+ ticks = (NRF_RTC1->COUNTER - now) & ((1U << 24) - 1);
190+ return ticks; // __ticks_to_us(ticks);
191+#endif /* MEASURE */
192+ return ticks; // __ticks_to_us(ticks);
193 }
194
195 #ifdef CONFIG_USERSPACE
196diff --git a/kernel/timeout.c b/kernel/timeout.c
197index 99f3d24c85..a4457bd50a 100644
198--- a/kernel/timeout.c
199+++ b/kernel/timeout.c
200@@ -16,6 +16,7 @@
201 k_spin_unlock(lck, __key), __i.key = 1)
202
203 static u64_t curr_tick;
204+s32_t xxx_nto;
205
206 static sys_dlist_t timeout_list = SYS_DLIST_STATIC_INIT(&timeout_list);
207
208@@ -106,7 +107,9 @@ void z_add_timeout(struct _timeout *to, _timeout_func_t fn, s32_t ticks)
209 }
210
211 if (to == first()) {
212+ NRF_P1->OUTSET = (1U << 5); /* first */
213 z_clock_set_timeout(next_timeout(), false);
214+ NRF_P1->OUTCLR = (1U << 5);
215 }
216 }
217 }
218@@ -159,6 +162,7 @@ void z_set_timeout_expiry(s32_t ticks, bool idle)
219 {
220 LOCKED(&timeout_lock) {
221 int next = next_timeout();
222+ xxx_nto = next;
223 bool sooner = (next == K_FOREVER) || (ticks < next);
224 bool imminent = next <= 1;
225
226@@ -168,9 +172,13 @@ void z_set_timeout_expiry(s32_t ticks, bool idle)
227 * that will bump the timeout to the "next" tick if
228 * it's not considered to be settable as directed.
229 */
230+ NRF_P1->OUTSET = (1U << 6); /* expiry */
231 if (sooner && !imminent) {
232+ NRF_P1->OUTCLR = (1U << 6);
233 z_clock_set_timeout(ticks, idle);
234+ NRF_P1->OUTSET = (1U << 6);
235 }
236+ NRF_P1->OUTCLR = (1U << 6);
237 }
238 }
239
240@@ -181,6 +189,7 @@ void z_clock_announce(s32_t ticks)
241 #endif
242
243 k_spinlock_key_t key = k_spin_lock(&timeout_lock);
244+ NRF_P1->OUTSET = (1U << 7); /* announce */
245
246 announce_remaining = ticks;
247
248@@ -207,6 +216,7 @@ void z_clock_announce(s32_t ticks)
249
250 z_clock_set_timeout(next_timeout(), false);
251
252+ NRF_P1->OUTCLR = (1U << 7);
253 k_spin_unlock(&timeout_lock, key);
254 }
255
256diff --git a/tests/kernel/sleep/src/main.c b/tests/kernel/sleep/src/main.c
257index 0675b5a1f1..843033cf59 100644
258--- a/tests/kernel/sleep/src/main.c
259+++ b/tests/kernel/sleep/src/main.c
260@@ -239,7 +239,7 @@ extern void test_usleep(void);
261 void test_main(void)
262 {
263 ztest_test_suite(sleep,
264- ztest_unit_test(test_sleep),
265+ //ztest_unit_test(test_sleep),
266 ztest_user_unit_test(test_usleep));
267 ztest_run_test_suite(sleep);
268 }
269diff --git a/tests/kernel/sleep/src/usleep.c b/tests/kernel/sleep/src/usleep.c
270index 29cd6ec236..df53e169d4 100644
271--- a/tests/kernel/sleep/src/usleep.c
272+++ b/tests/kernel/sleep/src/usleep.c
273@@ -52,6 +52,7 @@ void test_usleep(void)
274 {
275 int retries = 0;
276 s64_t elapsed_ms;
277+ s32_t delay = 0;
278
279 while (retries < RETRIES) {
280 s64_t start_ms;
281@@ -62,7 +63,7 @@ void test_usleep(void)
282 start_ms = k_uptime_get();
283
284 for (i = 0; i < LOOPS; ++i) {
285- k_usleep(1);
286+ delay = k_usleep(1);
287 }
288
289 end_ms = k_uptime_get();
290@@ -70,13 +71,14 @@ void test_usleep(void)
291
292 /* if at first you don't succeed, keep sucking. */
293
294+ printk("elapsed_ms = %lld delay %d ticks\n", elapsed_ms, delay);
295+
296 if ((elapsed_ms >= LOWER_BOUND_MS) &&
297 (elapsed_ms <= UPPER_BOUND_MS)) {
298 break;
299 }
300 }
301
302- printk("elapsed_ms = %lld\n", elapsed_ms);
303 zassert_true(elapsed_ms >= LOWER_BOUND_MS, "short sleep");
304 zassert_true(elapsed_ms <= UPPER_BOUND_MS, "overslept");
305 }
306--
3072.17.1