You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2021/06/15 10:33:13 UTC
[mynewt-core] branch master updated: pic32: Fix tick timer handling
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push:
new f2478be pic32: Fix tick timer handling
f2478be is described below
commit f2478bead7dea495fc9f0a9678a8e9ed8f757023
Author: Jerzy Kasenberg <je...@apache.org>
AuthorDate: Mon Jun 14 21:42:36 2021 +0200
pic32: Fix tick timer handling
Tick timer interrupt handler assumed it was execute before
next tick interrupt should be fired.
In case when interrupt was handled late (due to other interrupts
or just blocked interrupt for some time) next computed tick time
was already in the past and system time stopped for a very long time.
Now COMPARE register when set is compared to current COUNT register
and if it is in the past next tick time is computed until interrupt
is schedule to be ahead of COUNT register.
Also os_time_advance() takes into account what is the difference of
COUNT and COMPARE registers and in case of late interrupt, g_os_time
can advance more then one tick at a time.
---
kernel/os/src/arch/pic32/os_arch_pic32.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/kernel/os/src/arch/pic32/os_arch_pic32.c b/kernel/os/src/arch/pic32/os_arch_pic32.c
index 3f4b0ea..5f274dc 100644
--- a/kernel/os/src/arch/pic32/os_arch_pic32.c
+++ b/kernel/os/src/arch/pic32/os_arch_pic32.c
@@ -60,15 +60,23 @@ struct os_task *g_fpu_task;
struct os_task_t* g_fpu_user;
+static uint32_t last_compare;
+
static void timer_handler(void);
/* core timer interrupt */
void __attribute__((interrupt(IPL1AUTO),
vector(_CORE_TIMER_VECTOR))) isr_core_timer(void)
{
+ uint32_t compare;
+
timer_handler();
- _CP0_SET_COMPARE(_CP0_GET_COMPARE() + OS_TICK_PERIOD);
IFS0CLR = _IFS0_CTIF_MASK;
+ compare = _CP0_GET_COMPARE();
+ do {
+ compare += OS_TICK_PERIOD;
+ _CP0_SET_COMPARE(compare);
+ } while ((int32_t)(compare - _CP0_GET_COUNT()) <= 0);
}
/* context switch interrupt, in ctx.S */
@@ -79,7 +87,11 @@ isr_sw0(void);
static void
timer_handler(void)
{
- os_time_advance(1);
+ uint32_t compare = _CP0_GET_COMPARE();
+ if (last_compare != compare) {
+ os_time_advance((compare - last_compare) / OS_TICK_PERIOD);
+ last_compare = compare;
+ }
}
void