diff --git a/Documentation/guides/tasktraceuser.rst b/Documentation/guides/tasktraceuser.rst index f80cfc192e9..b04db80ab8b 100644 --- a/Documentation/guides/tasktraceuser.rst +++ b/Documentation/guides/tasktraceuser.rst @@ -53,6 +53,10 @@ The following configurations are configurable parameters for trace. - If enabled, stop overwriting old notes in the circular buffer when the buffer is full by default. This is useful to keep instrumentation data of the beginning of a system boot. +- ``CONFIG_SCHED_INSTRUMENTATION_HIRES`` + + - If enabled, use higher resolution system timer for instrumentation. + After the configuration, rebuild the NuttX kernel and application. If the trace function is enabled, "``trace``" :doc:`../components/nsh/builtin` will be available. diff --git a/include/nuttx/sched_note.h b/include/nuttx/sched_note.h index 90baedfa2a3..40fff58d104 100644 --- a/include/nuttx/sched_note.h +++ b/include/nuttx/sched_note.h @@ -160,7 +160,13 @@ struct note_common_s uint8_t nc_cpu; /* CPU thread/task running on */ #endif uint8_t nc_pid[2]; /* ID of the thread/task */ + +#ifdef CONFIG_SCHED_INSTRUMENTATION_HIRES + uint8_t nc_systime_sec[4]; /* Time when note was buffered (sec) */ + uint8_t nc_systime_nsec[4]; /* Time when note was buffered (nsec) */ +#else uint8_t nc_systime[4]; /* Time when note was buffered */ +#endif }; /* This is the specific form of the NOTE_START note */ diff --git a/sched/Kconfig b/sched/Kconfig index 6ebfcf9eb7b..850e4f1db33 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -990,6 +990,12 @@ config SCHED_INSTRUMENTATION_IRQHANDLER void sched_note_irqhandler(int irq, FAR void *handler, bool enter); +config SCHED_INSTRUMENTATION_HIRES + bool "Use Hi-Res RTC for instrumentation" + default n + ---help--- + Use higher resolution system timer for instrumentation. + config SCHED_INSTRUMENTATION_FILTER bool "Instrumenation filter" default n diff --git a/sched/sched/sched_note.c b/sched/sched/sched_note.c index 02f5b244eb2..7da2866543c 100644 --- a/sched/sched/sched_note.c +++ b/sched/sched/sched_note.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -117,7 +118,13 @@ static void note_common(FAR struct tcb_s *tcb, FAR struct note_common_s *note, uint8_t length, uint8_t type) { +#ifdef CONFIG_SCHED_INSTRUMENTATION_HIRES + struct timespec ts; + + clock_systime_timespec(&ts); +#else uint32_t systime = (uint32_t)clock_systime_ticks(); +#endif /* Save all of the common fields */ @@ -130,12 +137,23 @@ static void note_common(FAR struct tcb_s *tcb, note->nc_pid[0] = (uint8_t)(tcb->pid & 0xff); note->nc_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff); +#ifdef CONFIG_SCHED_INSTRUMENTATION_HIRES + note->nc_systime_nsec[0] = (uint8_t)(ts.tv_nsec & 0xff); + note->nc_systime_nsec[1] = (uint8_t)((ts.tv_nsec >> 8) & 0xff); + note->nc_systime_nsec[2] = (uint8_t)((ts.tv_nsec >> 16) & 0xff); + note->nc_systime_nsec[3] = (uint8_t)((ts.tv_nsec >> 24) & 0xff); + note->nc_systime_sec[0] = (uint8_t)(ts.tv_sec & 0xff); + note->nc_systime_sec[1] = (uint8_t)((ts.tv_sec >> 8) & 0xff); + note->nc_systime_sec[2] = (uint8_t)((ts.tv_sec >> 16) & 0xff); + note->nc_systime_sec[3] = (uint8_t)((ts.tv_sec >> 24) & 0xff); +#else /* Save the LS 32-bits of the system timer in little endian order */ note->nc_systime[0] = (uint8_t)(systime & 0xff); note->nc_systime[1] = (uint8_t)((systime >> 8) & 0xff); note->nc_systime[2] = (uint8_t)((systime >> 16) & 0xff); note->nc_systime[3] = (uint8_t)((systime >> 24) & 0xff); +#endif } /****************************************************************************