xiaoxiang781216 commented on code in PR #8525:
URL: https://github.com/apache/nuttx/pull/8525#discussion_r1106163907


##########
drivers/note/note_initialize.c:
##########
@@ -25,6 +25,7 @@
 #include <nuttx/note/note_driver.h>
 #include <nuttx/note/noteram_driver.h>
 #include <nuttx/note/notectl_driver.h>
+#include <nuttx/note/note_lastsched.h>

Review Comment:
   ```suggestion
   #include <nuttx/note/notelast_driver.h>
   ```
   



##########
include/nuttx/note/note_lastsched.h:
##########
@@ -0,0 +1,49 @@
+/****************************************************************************
+ * include/nuttx/note/note_lastsched.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_NOTE_LASTSCHED_DRIVER_H
+#define __INCLUDE_NUTTX_NOTE_LASTSCHED_DRIVER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_DRIVER_NOTE_LASTSCHED
+
+/****************************************************************************
+ * Name: note_lastched_register
+ ****************************************************************************/
+
+int note_lastched_register(void);
+
+/****************************************************************************
+ * Name: note_lastsched_dump
+ ****************************************************************************/
+
+void note_lastsched_dump(void);

Review Comment:
   let's call panic_notifier_call_chain and dump automatically



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s
+{
+  uint32_t freq;
+  size_t index;
+  struct timespec ts;
+  struct note_lastsched_chunk_s
+         buffer[CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct note_lastsched_s g_note_lastsched;
+
+static const struct note_driver_ops_s g_note_lastsched_ops =
+{
+  NULL,
+  note_lastsched_start,
+  note_lastsched_stop,
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+  note_lastsched_suspend,
+  note_lastsched_resume,
+#  ifdef CONFIG_SMP
+  note_lastsched_cpu_start,
+  note_lastsched_cpu_started,
+  note_lastsched_cpu_pause,
+  note_lastsched_cpu_paused,
+  note_lastsched_cpu_resume,
+  note_lastsched_cpu_resumed,
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+  note_lastsched_premption,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+  note_lastsched_csection,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+  note_spinlock,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+  note_lastsched_syscall_enter,
+  note_lastsched_syscall_leave,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+  note_lastsched_irqhandler,
+#endif
+};
+
+static const FAR char *note_type_string[] =
+{
+  "NOTE_START",
+  "NOTE_STOP",
+  "NOTE_SUSPEND",
+  "NOTE_RESUME",
+  "NOTE_CPU_START",
+  "NOTE_CPU_STARTED",
+  "NOTE_CPU_PAUSE",
+  "NOTE_CPU_PAUSED",
+  "NOTE_CPU_RESUME",
+  "NOTE_CPU_RESUMED",
+  "NOTE_PREEMPT_LOCK",
+  "NOTE_PREEMPT_UNLOCK",
+  "NOTE_CSECTION_ENTER",
+  "NOTE_CSECTION_LEAVE",
+  "NOTE_SPINLOCK_LOCK",
+  "NOTE_SPINLOCK_LOCKED",
+  "NOTE_SPINLOCK_UNLOCK",
+  "NOTE_SPINLOCK_ABORT",
+  "NOTE_SYSCALL_ENTER",
+  "NOTE_SYSCALL_LEAVE",
+  "NOTE_IRQ_ENTER",
+  "NOTE_IRQ_LEAVE",
+  "NOTE_DUMP_STRING",
+  "NOTE_DUMP_BINARY"
+};
+
+static struct note_driver_s g_note_lastsched_driver =
+{
+  &g_note_lastsched_ops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: note_lastsched_common
+ ****************************************************************************/
+
+static inline void note_lastsched_common(FAR struct tcb_s *tcb, uint8_t type,
+                                         void *args)
+{
+  size_t index = atomic_fetch_add(&g_note_lastsched.index, 1);
+  FAR struct note_lastsched_chunk_s *note = &g_note_lastsched.buffer[index];
+
+  if (g_note_lastsched.freq != 0)
+    {
+      note->systick = up_perf_gettime();
+    }
+  else
+    {
+      struct timespec ts;
+      clock_systime_timespec(&ts);
+      note->systick = (uint32_t)&ts.tv_nsec;
+    }
+
+  note->type = type;
+  if (tcb)
+    {
+      note->cpu_pid = tcb->pid;
+#ifdef CONFIG_SMP
+      note->cpu_pid |= tcb->cpu << 27;
+#endif
+    }
+
+  note->args = args;
+  if (g_note_lastsched.index == CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS)
+    {
+      clock_systime_timespec(&g_note_lastsched.ts);
+      atomic_exchange(&g_note_lastsched.index, 0);
+    }
+}
+
+/****************************************************************************
+ * Name: note_lastsched_*
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_START, NULL);
+}
+
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_STOP, NULL);
+}
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_SUSPEND, NULL);
+}
+
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#endif
+
+#ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+#  ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#  endif
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked)
+{
+  note_lastsched_common(
+    tcb, locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter)
+{
+  note_lastsched_common(
+      tcb, enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type)
+{
+  note_lastsched_common(tcb, type, (FAR void *)spinlock);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter)
+{
+  note_lastsched_common(this_task(), enter ? NOTE_IRQ_ENTER : NOTE_IRQ_LEAVE,
+                        (FAR void *)irq);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_ENTER, (void *)nr);
+}
+
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_LEAVE, (void *)nr);

Review Comment:
   add FAR for all pointer



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s
+{
+  uint32_t freq;
+  size_t index;
+  struct timespec ts;
+  struct note_lastsched_chunk_s
+         buffer[CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct note_lastsched_s g_note_lastsched;
+
+static const struct note_driver_ops_s g_note_lastsched_ops =
+{
+  NULL,
+  note_lastsched_start,
+  note_lastsched_stop,
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+  note_lastsched_suspend,
+  note_lastsched_resume,
+#  ifdef CONFIG_SMP
+  note_lastsched_cpu_start,
+  note_lastsched_cpu_started,
+  note_lastsched_cpu_pause,
+  note_lastsched_cpu_paused,
+  note_lastsched_cpu_resume,
+  note_lastsched_cpu_resumed,
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+  note_lastsched_premption,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+  note_lastsched_csection,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+  note_spinlock,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+  note_lastsched_syscall_enter,
+  note_lastsched_syscall_leave,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+  note_lastsched_irqhandler,
+#endif
+};
+
+static const FAR char *note_type_string[] =
+{
+  "NOTE_START",
+  "NOTE_STOP",
+  "NOTE_SUSPEND",
+  "NOTE_RESUME",
+  "NOTE_CPU_START",
+  "NOTE_CPU_STARTED",
+  "NOTE_CPU_PAUSE",
+  "NOTE_CPU_PAUSED",
+  "NOTE_CPU_RESUME",
+  "NOTE_CPU_RESUMED",
+  "NOTE_PREEMPT_LOCK",
+  "NOTE_PREEMPT_UNLOCK",
+  "NOTE_CSECTION_ENTER",
+  "NOTE_CSECTION_LEAVE",
+  "NOTE_SPINLOCK_LOCK",
+  "NOTE_SPINLOCK_LOCKED",
+  "NOTE_SPINLOCK_UNLOCK",
+  "NOTE_SPINLOCK_ABORT",
+  "NOTE_SYSCALL_ENTER",
+  "NOTE_SYSCALL_LEAVE",
+  "NOTE_IRQ_ENTER",
+  "NOTE_IRQ_LEAVE",
+  "NOTE_DUMP_STRING",
+  "NOTE_DUMP_BINARY"
+};
+
+static struct note_driver_s g_note_lastsched_driver =
+{
+  &g_note_lastsched_ops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: note_lastsched_common
+ ****************************************************************************/
+
+static inline void note_lastsched_common(FAR struct tcb_s *tcb, uint8_t type,
+                                         void *args)
+{
+  size_t index = atomic_fetch_add(&g_note_lastsched.index, 1);
+  FAR struct note_lastsched_chunk_s *note = &g_note_lastsched.buffer[index];
+
+  if (g_note_lastsched.freq != 0)
+    {
+      note->systick = up_perf_gettime();
+    }
+  else
+    {
+      struct timespec ts;
+      clock_systime_timespec(&ts);
+      note->systick = (uint32_t)&ts.tv_nsec;
+    }
+
+  note->type = type;
+  if (tcb)
+    {
+      note->cpu_pid = tcb->pid;
+#ifdef CONFIG_SMP
+      note->cpu_pid |= tcb->cpu << 27;
+#endif
+    }
+
+  note->args = args;
+  if (g_note_lastsched.index == CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS)
+    {
+      clock_systime_timespec(&g_note_lastsched.ts);
+      atomic_exchange(&g_note_lastsched.index, 0);
+    }
+}
+
+/****************************************************************************
+ * Name: note_lastsched_*
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_START, NULL);
+}
+
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_STOP, NULL);
+}
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_SUSPEND, NULL);
+}
+
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#endif
+
+#ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+#  ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#  endif
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked)
+{
+  note_lastsched_common(
+    tcb, locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter)
+{
+  note_lastsched_common(
+      tcb, enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type)
+{
+  note_lastsched_common(tcb, type, (FAR void *)spinlock);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter)
+{
+  note_lastsched_common(this_task(), enter ? NOTE_IRQ_ENTER : NOTE_IRQ_LEAVE,
+                        (FAR void *)irq);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_ENTER, (void *)nr);
+}
+
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_LEAVE, (void *)nr);
+}
+#endif
+
+/****************************************************************************
+ * Name: note_lastched_register
+ ****************************************************************************/
+
+int note_lastched_register(void)
+{
+  g_note_lastsched.freq = up_perf_getfreq();
+  if (g_note_lastsched.freq == 0)
+    {
+      g_note_lastsched.freq = NSEC_PER_SEC;
+    }
+
+  clock_gettime(CLOCK_REALTIME, &g_note_lastsched.ts);

Review Comment:
   why use realtime?



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s
+{
+  uint32_t freq;

Review Comment:
   remove



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s
+{
+  uint32_t freq;
+  size_t index;
+  struct timespec ts;
+  struct note_lastsched_chunk_s
+         buffer[CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct note_lastsched_s g_note_lastsched;
+
+static const struct note_driver_ops_s g_note_lastsched_ops =
+{
+  NULL,
+  note_lastsched_start,
+  note_lastsched_stop,
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+  note_lastsched_suspend,
+  note_lastsched_resume,
+#  ifdef CONFIG_SMP
+  note_lastsched_cpu_start,
+  note_lastsched_cpu_started,
+  note_lastsched_cpu_pause,
+  note_lastsched_cpu_paused,
+  note_lastsched_cpu_resume,
+  note_lastsched_cpu_resumed,
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+  note_lastsched_premption,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+  note_lastsched_csection,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+  note_spinlock,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+  note_lastsched_syscall_enter,
+  note_lastsched_syscall_leave,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+  note_lastsched_irqhandler,
+#endif
+};
+
+static const FAR char *note_type_string[] =

Review Comment:
   ```suggestion
   static const FAR char *g_note_type[] =
   ```



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;

Review Comment:
   ```
   struct notelast_chunk_s
   {
     uint8_t type;
     uint8_t cpu;
     timespec time;
     pid_t pid;
     uintptr_t args;
   };
   ```



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s
+{
+  uint32_t freq;
+  size_t index;
+  struct timespec ts;
+  struct note_lastsched_chunk_s
+         buffer[CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct note_lastsched_s g_note_lastsched;
+
+static const struct note_driver_ops_s g_note_lastsched_ops =
+{
+  NULL,
+  note_lastsched_start,
+  note_lastsched_stop,
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+  note_lastsched_suspend,
+  note_lastsched_resume,
+#  ifdef CONFIG_SMP
+  note_lastsched_cpu_start,
+  note_lastsched_cpu_started,
+  note_lastsched_cpu_pause,
+  note_lastsched_cpu_paused,
+  note_lastsched_cpu_resume,
+  note_lastsched_cpu_resumed,
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+  note_lastsched_premption,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+  note_lastsched_csection,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+  note_spinlock,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+  note_lastsched_syscall_enter,
+  note_lastsched_syscall_leave,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+  note_lastsched_irqhandler,
+#endif
+};
+
+static const FAR char *note_type_string[] =
+{
+  "NOTE_START",
+  "NOTE_STOP",
+  "NOTE_SUSPEND",
+  "NOTE_RESUME",
+  "NOTE_CPU_START",
+  "NOTE_CPU_STARTED",
+  "NOTE_CPU_PAUSE",
+  "NOTE_CPU_PAUSED",
+  "NOTE_CPU_RESUME",
+  "NOTE_CPU_RESUMED",
+  "NOTE_PREEMPT_LOCK",
+  "NOTE_PREEMPT_UNLOCK",
+  "NOTE_CSECTION_ENTER",
+  "NOTE_CSECTION_LEAVE",
+  "NOTE_SPINLOCK_LOCK",
+  "NOTE_SPINLOCK_LOCKED",
+  "NOTE_SPINLOCK_UNLOCK",
+  "NOTE_SPINLOCK_ABORT",
+  "NOTE_SYSCALL_ENTER",
+  "NOTE_SYSCALL_LEAVE",
+  "NOTE_IRQ_ENTER",
+  "NOTE_IRQ_LEAVE",
+  "NOTE_DUMP_STRING",
+  "NOTE_DUMP_BINARY"
+};
+
+static struct note_driver_s g_note_lastsched_driver =
+{
+  &g_note_lastsched_ops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: note_lastsched_common
+ ****************************************************************************/
+
+static inline void note_lastsched_common(FAR struct tcb_s *tcb, uint8_t type,
+                                         void *args)
+{
+  size_t index = atomic_fetch_add(&g_note_lastsched.index, 1);
+  FAR struct note_lastsched_chunk_s *note = &g_note_lastsched.buffer[index];
+
+  if (g_note_lastsched.freq != 0)
+    {
+      note->systick = up_perf_gettime();
+    }
+  else
+    {
+      struct timespec ts;
+      clock_systime_timespec(&ts);
+      note->systick = (uint32_t)&ts.tv_nsec;
+    }
+
+  note->type = type;
+  if (tcb)
+    {
+      note->cpu_pid = tcb->pid;
+#ifdef CONFIG_SMP
+      note->cpu_pid |= tcb->cpu << 27;
+#endif
+    }
+
+  note->args = args;
+  if (g_note_lastsched.index == CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS)
+    {
+      clock_systime_timespec(&g_note_lastsched.ts);
+      atomic_exchange(&g_note_lastsched.index, 0);
+    }
+}
+
+/****************************************************************************
+ * Name: note_lastsched_*
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_START, NULL);
+}
+
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_STOP, NULL);
+}
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_SUSPEND, NULL);
+}
+
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#endif
+
+#ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+#  ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#  endif
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked)
+{
+  note_lastsched_common(
+    tcb, locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter)
+{
+  note_lastsched_common(
+      tcb, enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type)
+{
+  note_lastsched_common(tcb, type, (FAR void *)spinlock);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter)
+{
+  note_lastsched_common(this_task(), enter ? NOTE_IRQ_ENTER : NOTE_IRQ_LEAVE,
+                        (FAR void *)irq);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_ENTER, (void *)nr);
+}
+
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_LEAVE, (void *)nr);
+}
+#endif
+
+/****************************************************************************
+ * Name: note_lastched_register
+ ****************************************************************************/
+
+int note_lastched_register(void)
+{
+  g_note_lastsched.freq = up_perf_getfreq();
+  if (g_note_lastsched.freq == 0)
+    {
+      g_note_lastsched.freq = NSEC_PER_SEC;
+    }
+
+  clock_gettime(CLOCK_REALTIME, &g_note_lastsched.ts);
+  return note_driver_register(&g_note_lastsched_driver);
+}
+
+/****************************************************************************
+ * Name: note_lastsched_dump
+ ****************************************************************************/
+
+void note_lastsched_dump(void)
+{
+  size_t i;
+  uint32_t freq;
+  irqstate_t flags;
+  struct note_filter_mode_s old;
+  size_t index = g_note_lastsched.index;
+  FAR struct note_lastsched_chunk_s *note;
+
+  sched_note_filter_mode(&old, NULL);

Review Comment:
   why need if nuttx is in the panic



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s
+{
+  uint32_t freq;
+  size_t index;
+  struct timespec ts;
+  struct note_lastsched_chunk_s
+         buffer[CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct note_lastsched_s g_note_lastsched;
+
+static const struct note_driver_ops_s g_note_lastsched_ops =
+{
+  NULL,
+  note_lastsched_start,
+  note_lastsched_stop,
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+  note_lastsched_suspend,
+  note_lastsched_resume,
+#  ifdef CONFIG_SMP
+  note_lastsched_cpu_start,
+  note_lastsched_cpu_started,
+  note_lastsched_cpu_pause,
+  note_lastsched_cpu_paused,
+  note_lastsched_cpu_resume,
+  note_lastsched_cpu_resumed,
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+  note_lastsched_premption,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+  note_lastsched_csection,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+  note_spinlock,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+  note_lastsched_syscall_enter,
+  note_lastsched_syscall_leave,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+  note_lastsched_irqhandler,
+#endif
+};
+
+static const FAR char *note_type_string[] =
+{
+  "NOTE_START",
+  "NOTE_STOP",
+  "NOTE_SUSPEND",
+  "NOTE_RESUME",
+  "NOTE_CPU_START",
+  "NOTE_CPU_STARTED",
+  "NOTE_CPU_PAUSE",
+  "NOTE_CPU_PAUSED",
+  "NOTE_CPU_RESUME",
+  "NOTE_CPU_RESUMED",
+  "NOTE_PREEMPT_LOCK",
+  "NOTE_PREEMPT_UNLOCK",
+  "NOTE_CSECTION_ENTER",
+  "NOTE_CSECTION_LEAVE",
+  "NOTE_SPINLOCK_LOCK",
+  "NOTE_SPINLOCK_LOCKED",
+  "NOTE_SPINLOCK_UNLOCK",
+  "NOTE_SPINLOCK_ABORT",
+  "NOTE_SYSCALL_ENTER",
+  "NOTE_SYSCALL_LEAVE",
+  "NOTE_IRQ_ENTER",
+  "NOTE_IRQ_LEAVE",
+  "NOTE_DUMP_STRING",
+  "NOTE_DUMP_BINARY"
+};
+
+static struct note_driver_s g_note_lastsched_driver =
+{
+  &g_note_lastsched_ops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: note_lastsched_common
+ ****************************************************************************/
+
+static inline void note_lastsched_common(FAR struct tcb_s *tcb, uint8_t type,
+                                         void *args)

Review Comment:
   ```suggestion
                                            uintptr_t args)
   ```



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s
+{
+  uint32_t freq;
+  size_t index;
+  struct timespec ts;
+  struct note_lastsched_chunk_s
+         buffer[CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct note_lastsched_s g_note_lastsched;
+
+static const struct note_driver_ops_s g_note_lastsched_ops =
+{
+  NULL,
+  note_lastsched_start,
+  note_lastsched_stop,
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+  note_lastsched_suspend,
+  note_lastsched_resume,
+#  ifdef CONFIG_SMP
+  note_lastsched_cpu_start,
+  note_lastsched_cpu_started,
+  note_lastsched_cpu_pause,
+  note_lastsched_cpu_paused,
+  note_lastsched_cpu_resume,
+  note_lastsched_cpu_resumed,
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+  note_lastsched_premption,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+  note_lastsched_csection,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+  note_spinlock,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+  note_lastsched_syscall_enter,
+  note_lastsched_syscall_leave,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+  note_lastsched_irqhandler,
+#endif
+};
+
+static const FAR char *note_type_string[] =
+{
+  "NOTE_START",
+  "NOTE_STOP",
+  "NOTE_SUSPEND",
+  "NOTE_RESUME",
+  "NOTE_CPU_START",
+  "NOTE_CPU_STARTED",
+  "NOTE_CPU_PAUSE",
+  "NOTE_CPU_PAUSED",
+  "NOTE_CPU_RESUME",
+  "NOTE_CPU_RESUMED",
+  "NOTE_PREEMPT_LOCK",
+  "NOTE_PREEMPT_UNLOCK",
+  "NOTE_CSECTION_ENTER",
+  "NOTE_CSECTION_LEAVE",
+  "NOTE_SPINLOCK_LOCK",
+  "NOTE_SPINLOCK_LOCKED",
+  "NOTE_SPINLOCK_UNLOCK",
+  "NOTE_SPINLOCK_ABORT",
+  "NOTE_SYSCALL_ENTER",
+  "NOTE_SYSCALL_LEAVE",
+  "NOTE_IRQ_ENTER",
+  "NOTE_IRQ_LEAVE",
+  "NOTE_DUMP_STRING",
+  "NOTE_DUMP_BINARY"
+};
+
+static struct note_driver_s g_note_lastsched_driver =
+{
+  &g_note_lastsched_ops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: note_lastsched_common
+ ****************************************************************************/
+
+static inline void note_lastsched_common(FAR struct tcb_s *tcb, uint8_t type,
+                                         void *args)
+{
+  size_t index = atomic_fetch_add(&g_note_lastsched.index, 1);
+  FAR struct note_lastsched_chunk_s *note = &g_note_lastsched.buffer[index];
+
+  if (g_note_lastsched.freq != 0)
+    {
+      note->systick = up_perf_gettime();
+    }
+  else
+    {
+      struct timespec ts;
+      clock_systime_timespec(&ts);
+      note->systick = (uint32_t)&ts.tv_nsec;
+    }
+
+  note->type = type;
+  if (tcb)
+    {
+      note->cpu_pid = tcb->pid;
+#ifdef CONFIG_SMP
+      note->cpu_pid |= tcb->cpu << 27;
+#endif
+    }
+
+  note->args = args;
+  if (g_note_lastsched.index == CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS)
+    {
+      clock_systime_timespec(&g_note_lastsched.ts);
+      atomic_exchange(&g_note_lastsched.index, 0);
+    }
+}
+
+/****************************************************************************
+ * Name: note_lastsched_*
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_START, NULL);
+}
+
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_STOP, NULL);
+}
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_SUSPEND, NULL);
+}
+
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#endif
+
+#ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+#  ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#  endif
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked)
+{
+  note_lastsched_common(
+    tcb, locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter)
+{
+  note_lastsched_common(
+      tcb, enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type)
+{
+  note_lastsched_common(tcb, type, (FAR void *)spinlock);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter)
+{
+  note_lastsched_common(this_task(), enter ? NOTE_IRQ_ENTER : NOTE_IRQ_LEAVE,
+                        (FAR void *)irq);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_ENTER, (void *)nr);
+}
+
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_LEAVE, (void *)nr);
+}
+#endif
+
+/****************************************************************************
+ * Name: note_lastched_register
+ ****************************************************************************/
+
+int note_lastched_register(void)
+{
+  g_note_lastsched.freq = up_perf_getfreq();
+  if (g_note_lastsched.freq == 0)
+    {
+      g_note_lastsched.freq = NSEC_PER_SEC;
+    }
+
+  clock_gettime(CLOCK_REALTIME, &g_note_lastsched.ts);
+  return note_driver_register(&g_note_lastsched_driver);
+}
+
+/****************************************************************************
+ * Name: note_lastsched_dump
+ ****************************************************************************/
+
+void note_lastsched_dump(void)
+{
+  size_t i;
+  uint32_t freq;
+  irqstate_t flags;
+  struct note_filter_mode_s old;
+  size_t index = g_note_lastsched.index;
+  FAR struct note_lastsched_chunk_s *note;
+
+  sched_note_filter_mode(&old, NULL);
+  old.flag &= ~(NOTE_FILTER_MODE_FLAG_ENABLE);
+  sched_note_filter_mode(NULL, &old);
+  flags = enter_critical_section();
+
+  syslog(LOG_INFO,
+         "last_sched: system frequency: %" PRIu32 "\n"
+         "last_sched: start time: %" PRIu32 ".%" PRIu32,
+         g_note_lastsched.freq,
+         g_note_lastsched.ts.tv_sec,
+         g_note_lastsched.ts.tv_nsec);
+
+  freq = g_note_lastsched.freq ? NSEC_PER_SEC : g_note_lastsched.freq;
+  for (i = index; i != index - 1; i++)
+    {
+      note = &g_note_lastsched.buffer[i];
+      i = (i == CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS - 1) ? 0 : i;
+      syslog(LOG_INFO,
+             "last_sched|%" PRIuPTR ": time:%" PRIu32 ", cpu: %" PRIu32 ", "

Review Comment:
   let's follow syslog output compact format.



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s
+{
+  uint32_t freq;
+  size_t index;
+  struct timespec ts;
+  struct note_lastsched_chunk_s
+         buffer[CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct note_lastsched_s g_note_lastsched;
+
+static const struct note_driver_ops_s g_note_lastsched_ops =
+{
+  NULL,
+  note_lastsched_start,
+  note_lastsched_stop,
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+  note_lastsched_suspend,
+  note_lastsched_resume,
+#  ifdef CONFIG_SMP
+  note_lastsched_cpu_start,
+  note_lastsched_cpu_started,
+  note_lastsched_cpu_pause,
+  note_lastsched_cpu_paused,
+  note_lastsched_cpu_resume,
+  note_lastsched_cpu_resumed,
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+  note_lastsched_premption,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+  note_lastsched_csection,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+  note_spinlock,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+  note_lastsched_syscall_enter,
+  note_lastsched_syscall_leave,
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+  note_lastsched_irqhandler,
+#endif
+};
+
+static const FAR char *note_type_string[] =
+{
+  "NOTE_START",
+  "NOTE_STOP",
+  "NOTE_SUSPEND",
+  "NOTE_RESUME",
+  "NOTE_CPU_START",
+  "NOTE_CPU_STARTED",
+  "NOTE_CPU_PAUSE",
+  "NOTE_CPU_PAUSED",
+  "NOTE_CPU_RESUME",
+  "NOTE_CPU_RESUMED",
+  "NOTE_PREEMPT_LOCK",
+  "NOTE_PREEMPT_UNLOCK",
+  "NOTE_CSECTION_ENTER",
+  "NOTE_CSECTION_LEAVE",
+  "NOTE_SPINLOCK_LOCK",
+  "NOTE_SPINLOCK_LOCKED",
+  "NOTE_SPINLOCK_UNLOCK",
+  "NOTE_SPINLOCK_ABORT",
+  "NOTE_SYSCALL_ENTER",
+  "NOTE_SYSCALL_LEAVE",
+  "NOTE_IRQ_ENTER",
+  "NOTE_IRQ_LEAVE",
+  "NOTE_DUMP_STRING",
+  "NOTE_DUMP_BINARY"
+};
+
+static struct note_driver_s g_note_lastsched_driver =
+{
+  &g_note_lastsched_ops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: note_lastsched_common
+ ****************************************************************************/
+
+static inline void note_lastsched_common(FAR struct tcb_s *tcb, uint8_t type,
+                                         void *args)
+{
+  size_t index = atomic_fetch_add(&g_note_lastsched.index, 1);
+  FAR struct note_lastsched_chunk_s *note = &g_note_lastsched.buffer[index];
+
+  if (g_note_lastsched.freq != 0)
+    {
+      note->systick = up_perf_gettime();
+    }
+  else
+    {
+      struct timespec ts;
+      clock_systime_timespec(&ts);
+      note->systick = (uint32_t)&ts.tv_nsec;
+    }
+
+  note->type = type;
+  if (tcb)
+    {
+      note->cpu_pid = tcb->pid;
+#ifdef CONFIG_SMP
+      note->cpu_pid |= tcb->cpu << 27;
+#endif
+    }
+
+  note->args = args;
+  if (g_note_lastsched.index == CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS)
+    {
+      clock_systime_timespec(&g_note_lastsched.ts);
+      atomic_exchange(&g_note_lastsched.index, 0);
+    }
+}
+
+/****************************************************************************
+ * Name: note_lastsched_*
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_START, NULL);
+}
+
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_STOP, NULL);
+}
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_SUSPEND, NULL);
+}
+
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#endif
+
+#ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+#  ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, (void *)cpu);
+}
+
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb)
+{
+  note_lastsched_common(tcb, NOTE_RESUME, NULL);
+}
+#  endif
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked)
+{
+  note_lastsched_common(
+    tcb, locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter)
+{
+  note_lastsched_common(
+      tcb, enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE, NULL);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type)
+{
+  note_lastsched_common(tcb, type, (FAR void *)spinlock);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter)
+{
+  note_lastsched_common(this_task(), enter ? NOTE_IRQ_ENTER : NOTE_IRQ_LEAVE,
+                        (FAR void *)irq);
+}
+#endif
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_ENTER, (void *)nr);
+}
+
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result)
+{
+  note_lastsched_common(this_task(), NOTE_SYSCALL_LEAVE, (void *)nr);
+}
+#endif
+
+/****************************************************************************
+ * Name: note_lastched_register
+ ****************************************************************************/
+
+int note_lastched_register(void)
+{
+  g_note_lastsched.freq = up_perf_getfreq();
+  if (g_note_lastsched.freq == 0)
+    {
+      g_note_lastsched.freq = NSEC_PER_SEC;
+    }
+
+  clock_gettime(CLOCK_REALTIME, &g_note_lastsched.ts);
+  return note_driver_register(&g_note_lastsched_driver);
+}
+
+/****************************************************************************
+ * Name: note_lastsched_dump
+ ****************************************************************************/
+
+void note_lastsched_dump(void)
+{
+  size_t i;
+  uint32_t freq;
+  irqstate_t flags;
+  struct note_filter_mode_s old;
+  size_t index = g_note_lastsched.index;
+  FAR struct note_lastsched_chunk_s *note;
+
+  sched_note_filter_mode(&old, NULL);
+  old.flag &= ~(NOTE_FILTER_MODE_FLAG_ENABLE);
+  sched_note_filter_mode(NULL, &old);
+  flags = enter_critical_section();
+
+  syslog(LOG_INFO,
+         "last_sched: system frequency: %" PRIu32 "\n"
+         "last_sched: start time: %" PRIu32 ".%" PRIu32,
+         g_note_lastsched.freq,
+         g_note_lastsched.ts.tv_sec,
+         g_note_lastsched.ts.tv_nsec);
+
+  freq = g_note_lastsched.freq ? NSEC_PER_SEC : g_note_lastsched.freq;
+  for (i = index; i != index - 1; i++)
+    {
+      note = &g_note_lastsched.buffer[i];
+      i = (i == CONFIG_DRIVER_NOTE_LASTSCHED_NBUFFERS - 1) ? 0 : i;
+      syslog(LOG_INFO,
+             "last_sched|%" PRIuPTR ": time:%" PRIu32 ", cpu: %" PRIu32 ", "
+             "pid:%2" PRIu32 ", type: %-16s, args: %p\n",
+             i, (uint32_t)((uint64_t)note->systick * NSEC_PER_SEC / freq),
+             note->cpu_pid >> 27, note->cpu_pid & 0x0fffffff,
+             note_type_string[note->type], note->args);
+    }
+
+  leave_critical_section(flags);

Review Comment:
   why need



##########
drivers/note/Kconfig:
##########
@@ -231,6 +231,20 @@ config DRIVER_NOTELOG
        ---help---
                The note driver output to syslog.
 
+config DRIVER_NOTE_LASTSCHED

Review Comment:
   ```suggestion
   config DRIVERS_NOTELAST
   ```



##########
drivers/note/note_initialize.c:
##########
@@ -74,5 +75,13 @@ int note_initialize(void)
     }
 #endif
 
+#ifdef CONFIG_DRIVER_NOTE_LASTSCHED
+  ret = note_lastched_register();

Review Comment:
   ```suggestion
     ret = notelast_register();
   ```



##########
include/nuttx/note/note_lastsched.h:
##########
@@ -0,0 +1,49 @@
+/****************************************************************************
+ * include/nuttx/note/note_lastsched.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_NOTE_LASTSCHED_DRIVER_H
+#define __INCLUDE_NUTTX_NOTE_LASTSCHED_DRIVER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>

Review Comment:
   ```suggestion
   #include <nuttx/config.h>
   ```



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,

Review Comment:
   ```suggestion
   static void notelast_start(FAR struct note_driver_s *drv,
   ```
   note_lastsched_ to notelast_



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s
+{
+  uint32_t freq;
+  size_t index;
+  struct timespec ts;

Review Comment:
   remove



##########
drivers/note/note_lastsched_driver.c:
##########
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * drivers/note/note_lastsched_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stdatomic.h>
+#include <syslog.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/note/note_driver.h>
+#include <nuttx/sched.h>
+#include <nuttx/sched_note.h>
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void note_lastsched_start(FAR struct note_driver_s *drv,
+                                 FAR struct tcb_s *tcb);
+static void note_lastsched_stop(FAR struct note_driver_s *drv,
+                                FAR struct tcb_s *tcb);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH
+static void note_lastsched_suspend(FAR struct note_driver_s *drv,
+                                   FAR struct tcb_s *tcb);
+static void note_lastsched_resume(FAR struct note_driver_s *drv,
+                                  FAR struct tcb_s *tcb);
+#  ifdef CONFIG_SMP
+static void note_lastsched_cpu_start(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_started(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_pause(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_paused(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb);
+static void note_lastsched_cpu_resume(FAR struct note_driver_s *drv,
+                                      FAR struct tcb_s *tcb, int cpu);
+static void note_lastsched_cpu_resumed(FAR struct note_driver_s *drv,
+                                       FAR struct tcb_s *tcb);
+#  endif
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
+static void note_lastsched_premption(FAR struct note_driver_s *drv,
+                                     FAR struct tcb_s *tcb, bool locked);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
+static void note_lastsched_csection(FAR struct note_driver_s *drv,
+                                    FAR struct tcb_s *tcb, bool enter);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+static void note_spinlock(FAR struct note_driver_s *drv,
+                          FAR struct tcb_s *tcb, FAR volatile void *spinlock,
+                          int type);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
+static void note_lastsched_syscall_enter(FAR struct note_driver_s *drv,
+                                         int nr, int argc, va_list *ap);
+static void note_lastsched_syscall_leave(FAR struct note_driver_s *drv,
+                                         int nr, uintptr_t result);
+#endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
+static void note_lastsched_irqhandler(FAR struct note_driver_s *drv, int irq,
+                                      FAR void *handler, bool enter);
+#endif
+
+struct note_lastsched_chunk_s
+{
+  uint32_t systick;
+  uint32_t cpu_pid;
+  enum note_type_e type;
+  void *args;
+};
+
+struct note_lastsched_s

Review Comment:
   ```
   struct notelasts_s
   {
     struct note_driver_s driver;
     size_t index;
     struct notelast_chunk_s buffer[CONFIG_DRIVERS_NOTELAST_NBUFFERS];
   };
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to