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