We need a simple way to trace our application since note driver task trace depends on cannot work well in NEO3. Related tickets:
Jira Legacy |
---|
server | System JIRA |
---|
serverId | 5c72af4b-e2b8-3562-b028-6bcef8f5fab0 |
---|
key | NEO3-6077 |
---|
|
(Refer to the ticket comment to enable task trace on nuttx) Jira Legacy |
---|
server | System JIRA |
---|
serverId | 5c72af4b-e2b8-3562-b028-6bcef8f5fab0 |
---|
key | NEO3-3764 |
---|
|
...
Code Block |
---|
ifeq ($(CONFIG_DEBUG_TRACE),y)
EXCLUDEFILENAME = trace_exclude_files.txt
EXCLUDEFUNCNAME = trace_exclude_functions.txt
EXCLUDEFILES := $(shell for file in `cat $(EXCLUDEFILENAME)`; do echo -n $$file, ; done)
EXCLUDEFUNCS := $(shell for func in `cat $(EXCLUDEFUNCNAME)`; do echo -n $$func, ; done)
CFLAGS += -finstrument-functions
ifneq ($(EXCLUDEFILES), )
CFLAGS += -finstrument-functions-exclude-file-list='$(EXCLUDEFILES)'
endif
ifneq ($(EXCLUDEFUNCS), )
CFLAGS += -finstrument-functions-exclude-function-list='$(EXCLUDEFUNCS)'
endif
endif |
The functions defined in the files this Makefile will compile will be instrumented.
You can add the file names list that are excluded from trace instrumentation to trace_exclude_files.txt like below.
tal/src/tal_buffer.c
tal_semaphore.c
And function names list that are excluded from tracing to trace_exclude_functions.txt like below.
IFD_
TAL_get_instance
The functions begin TAL_get_instance() and the functions beginning with “IFD_“ will not be tracedinstrumented.
3. Add syslog to profiling functions in your APP.
Because syslog mask is 2 in config, the priority of syslog shoule be LOG_CRIT
here. The priority value should <= logmask. Add below code in your application. For example, we add once below code is added in k81start.c, above gcc option in is added to idtapps/neo3/idt_apps/k81_reader/Makefile and idtapps/neo3/idt_apps/k81_system/Makefile, trace log will be output with all user functions defined in the path idtapps/neo3/idt_apps/k81_reader and k81_system if trace_exclude_files.txt or trace_exclude_functions.txt is not created or empty.
Code Block |
---|
#ifdef CONFIG_DEBUG_TRACE
void __attribute__((__no_instrument_function__))
__cyg_profile_func_enter(void *this_func, void *call_site)
{
syslog(LOG_CRIT, "[Start].%p\n", this_func);
}
void __attribute__((__no_instrument_function__))
__cyg_profile_func_exit(void *this_func, void *call_site)
{
syslog(LOG_CRIT, "[End].%p\n", this_func);
}
#endif |
Info |
---|
Because the maximum syslog cache size is only 15K, the The files and functions do not need to be traced should be listed as many as possible in trace_exclude_files.txt or/and trace_exclude_functions.txt because of limited cache. The maximum syslog cache size in K5 is only 15K. |
4. Use trace.py to change address to function name.
...
Output trace file tracelog_20230512-091652.txt finished.
<nuttx> is the nuttx ELF file, <syslog> is the log output on console or the syslog file saved in /var/log/sys. If you just use python trace.py
without parameter, the “nuttx” and “syslog” in current directory will be the default ELF file and log file.
Below are the tool and files output from my Linux PC. Makefile and trace_exclude_xxx.txt are in k81_reader/
View file |
---|
name | trace_exclude_functions.txt |
---|
|
View file |
---|
name | trace_exclude_files.txt |
---|
|
View file |
---|
name | tracelog_20230512-091652.txt |
---|
|
\uD83D\uDCCB GCC Instrumentation-Options description
-finstrument-functions
Generate instrumentation calls for entry and exit to functions. Just after function entry and just before function exit, the following profiling functions are called with the address of the current function and its call site. (On some platforms, __builtin_return_address
does not work beyond the current function, so the call site information may not be available to the profiling functions otherwise.)
Code Block |
---|
|
void __cyg_profile_func_enter (void *this_fn,
void *call_site);
void __cyg_profile_func_exit (void *this_fn,
void *call_site);
|
The first argument is the address of the start of the current function, which may be looked up exactly in the symbol table.
This instrumentation is also done for functions expanded inline in other functions. The profiling calls indicate where, conceptually, the inline function is entered and exited. This means that addressable versions of such functions must be available. If all your uses of a function are expanded inline, this may mean an additional expansion of code size. If you use extern inline
in your C code, an addressable version of such functions must be provided. (This is normally the case anyway, but if you get lucky and the optimizer always expands the functions inline, you might have gotten away without providing static copies.)A function may be given the attribute no_instrument_function
, in which case this instrumentation is not done. This can be used, for example, for the profiling functions listed above, high-priority interrupt routines, and any functions from which the profiling functions cannot safely be called (perhaps signal handlers, if the profiling routines generate output or allocate memory).