apache / nuttx

Apache NuttX is a mature, real-time embedded operating system (RTOS)
https://nuttx.apache.org/
Apache License 2.0
2.91k stars 1.19k forks source link

[BUG] hardware timers broken for ARM devices #14514

Open raiden00pl opened 1 month ago

raiden00pl commented 1 month ago

Description / Steps to reproduce the issue

Hardware timer example (apps/example/timer) is broken for some of ARM devices (probably for all ARM chips, but I can't check all of them). What I have verified and is broken: all Nordic chips and all STM32 chips.

Broken with this PR: https://github.com/apache/nuttx/pull/13606

Here crash with nrf52840-dk/jumbo:

nsh> timer
Open /dev/timer0
  flags: 00000000 timeout: 0 timeleft: 0 nsignals: 0
Set timer interval to 1000000
  flags: 00000000 timeout: 0 timeleft: 0 nsignals: 0
Attach timer handler
  flags: 00000002 timeout: 0 timeleft: 0 nsignals: 0
Start the timer
  flags: 00000003 timeout: 0 timeleft: 0 nsignals: 1
dump_assert_info: Current Version: NuttX  10.4.0 854ea78852 Oct 26 2024 09:14:06 arm
dump_assert_info: Assertion failed panic: at file: :0 task: <noname> process: <noname> 0x1284d
up_dump_register: R0: 0000000a R1: 00000000 R2: 00007fff  R3: 200034a8
up_dump_register: R4: 00000001 R5: 00000000 R6: 00000000  FP: 2000351c
up_dump_register: R8: 00000000 SB: 2000351c SL: 00000000 R11: 00000034
up_dump_register: IP: 00000001 SP: 20003468 LR: 0001347d  PC: 00000000
up_dump_register: xPSR: 60000000 PRIMASK: 00000000 CONTROL: 00000000
up_dump_register: EXC_RETURN: fffffff9
dump_stackinfo: User Stack:
dump_stackinfo:   base: 0x20002dc8
dump_stackinfo:   size: 00002016
dump_stackinfo:     sp: 0x20003468
stack_dump: 0x20003448: 0000000a 00000000 00007fff 200034a8 00000001 0001347d 00000000 60000000
stack_dump: 0x20003468: 00000000 0000459f 2000350c 00014e53 2000350c 0001333f 00000001 00000034
stack_dump: 0x20003488: 00013381 00013353 000046c9 20002b70 00014e53 00000000 0001248d 01000000
stack_dump: 0x200034a8: 000186a0 00000000 00000000 00000000 00000000 0000459f 2000350c 00014e53
stack_dump: 0x200034c8: 2000350c 0001333f 00000001 00000034 00013381 00013353 000046c9 20002b70
stack_dump: 0x200034e8: 00014e53 00000000 00000014 000130ef 00014e53 2000350c 00000003 0001283d
stack_dump: 0x20003508: 00014e53 00000003 00000000 00000000 00000001 00000000 00000000 00000003
stack_dump: 0x20003528: 00000000 00000000 00000000 00000003 00000000 000129d7 7665642f 6d69742f
stack_dump: 0x20003548: 00307265 7d4166af eb712001 00000000 200035a8 00000002 00000001 000127e5
stack_dump: 0x20003568: ffffffff fffffffe 00000002 00000000 00000000 0001284d 00000001 20002db8
stack_dump: 0x20003588: 00000000 00003fed 0001284d 00001dfd 00000000 00000000 00000000 00000000
stack_dump: 0x200035a8: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
dump_tasks:    PID GROUP PRI POLICY   TYPE    NPX STATE   EVENT      SIGMASK          STACKBASE  STACKSIZE   COMMAND
dump_task:       0     0   0 FIFO     Kthread -   Ready              0000000000000000 0x20001320      1008   <noname>
dump_task:       1     1 100 RR       Task    -   Waiting Semaphore  0000000000000000 0x20001de0      2008   <noname>
dump_task:       2     2 100 RR       Task    -   Running            0000000000000000 0x20002dc8      2016   <noname>

On which OS does this issue occur?

[OS: Linux]

What is the version of your OS?

Arch Linux

NuttX Version

nuttx-12.7.0-RC1, master

Issue Architecture

[Arch: arm]

Issue Area

[Area: Drivers]

Verification

jasonbu commented 4 weeks ago

hi @raiden00pl, looks like in #7494, we removed the

        if (lower->ops->getstatus) /* Optional */
          {
...
          }
        else
          {
            ret = -ENOSYS;
          }

caused the DEBUG_ASSERT in timer_getstatus

  DEBUGASSERT(lower->ops->tick_getstatus);

maybe we can keep compatible by return -ENOSYS, if getstatus and tick_getstatus method are both NULL, after update will be

nsh> timer
Open /dev/timer0
ERROR: Failed to get timer status: 38

when use timer cmd in nsh.

if you have more information before which commit the behavior is worked as expect, please letme know. because according to the git log, even with code before #7494, timer demo will also fail, only with no panic.

jasonbu commented 4 weeks ago

please review if the #14619 can match your requirements.

raiden00pl commented 4 weeks ago

@jasonbu hi, this doesn't fix the problem. NRF52 implements getstatus and the timer example keeps crashing. For H7 you can just comment out timer_status in timer example (it does nothing useful) and it still crashes.

In both cases https://github.com/apache/nuttx/pull/13606 is guilty (works without this change, crashes with it).

raiden00pl commented 4 weeks ago

the last working commit is f221c9ecb4 (for H7 you have to remove timer_status logic from example, for NRF52 it's not required)

jasonbu commented 4 weeks ago

the last working commit is f221c9e (for H7 you have to remove timer_status logic from example, for NRF52 it's not required)

I tried with stm32h7 and return directly in timer_status. looks like also a sig action happend in timer handler.

dump_stack in up_schedule_sigaction can get backtrace of.

up_schedule_sigaction arch/arm/src/armv7-m/arm_schedulesigaction.c:104 (discriminator 1)
nxsig_queue_action sched/signal/sig_dispatch.c:199
nxsig_tcbdispatch sched/signal/sig_dispatch.c:540
group_signal_handler sched/group/group_signal.c:155
group_foreachchild sched/group/group_foreachchild.c:78
group_signal sched/group/group_signal.c:228
nxsig_dispatch sched/signal/sig_dispatch.c:735
nxsig_notification sched/signal/sig_notification.c:147
timer_notifier drivers/timers/timer.c:127
stm32_timer_handler arch/arm/src/chip/stm32_tim_lowerhalf.c:272
irq_dispatch sched/irq/irq_dispatch.c:148
exception_direct arch/arm/src/armv7-m/arm_doirq.c:49

if it's urgent requirement, you can do

const void * const _vectors[] locate_data(".vectors")
                              aligned_data(VECTAB_ALIGN) =
{
  /* Initial stack */

  IDLE_STACK,

  /* Reset exception handler */

  start,

  /* Vectors 2 - n point directly at the generic handler */

#if 0
  [2 ... NVIC_IRQ_PENDSV] = &exception_common,
  [(NVIC_IRQ_PENDSV + 1) ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)]
                          = &exception_direct
#else
  [2 ... ARMV7M_PERIPHERAL_INTERRUPTS] = &exception_common,
#endif
};

in arch/arm/src/armv7-m/arm_vectors.c

and we shall talk about how to cover these kind of usage TCIOC_NOTIFICATION & SIGEV_SIGNAL .

CC @GUIDINGLI @xiaoxiang781216

raiden00pl commented 1 week ago

@jasonbu @GUIDINGLI @xiaoxiang781216 do you plan to fix this issue ?