mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2025-06-20 23:27:39 +08:00
Enable profiling for the linux port
This commit is contained in:

committed by
alfred gedeon

parent
784fb8c157
commit
a2029c781c
@ -1,7 +1,8 @@
|
|||||||
CC := gcc
|
CC := gcc
|
||||||
BIN := posix_demo
|
BIN := posix_demo
|
||||||
|
|
||||||
BUILD_DIR := build
|
BUILD_DIR := ./build
|
||||||
|
BUILD_DIR_ABS := $(abspath $(BUILD_DIR))
|
||||||
|
|
||||||
FREERTOS_DIR_REL := ../../../FreeRTOS
|
FREERTOS_DIR_REL := ../../../FreeRTOS
|
||||||
FREERTOS_DIR := $(abspath $(FREERTOS_DIR_REL))
|
FREERTOS_DIR := $(abspath $(FREERTOS_DIR_REL))
|
||||||
@ -9,20 +10,22 @@ FREERTOS_DIR := $(abspath $(FREERTOS_DIR_REL))
|
|||||||
FREERTOS_PLUS_DIR_REL := ../../../FreeRTOS-Plus
|
FREERTOS_PLUS_DIR_REL := ../../../FreeRTOS-Plus
|
||||||
FREERTOS_PLUS_DIR := $(abspath $(FREERTOS_PLUS_DIR_REL))
|
FREERTOS_PLUS_DIR := $(abspath $(FREERTOS_PLUS_DIR_REL))
|
||||||
|
|
||||||
|
KERNEL_DIR := ${FREERTOS_DIR}/Source
|
||||||
|
|
||||||
INCLUDE_DIRS := -I.
|
INCLUDE_DIRS := -I.
|
||||||
INCLUDE_DIRS += -I${FREERTOS_DIR}/Source/include
|
INCLUDE_DIRS += -I${KERNEL_DIR}/include
|
||||||
INCLUDE_DIRS += -I${FREERTOS_DIR}/Source/portable/ThirdParty/GCC/Posix
|
INCLUDE_DIRS += -I${KERNEL_DIR}/portable/ThirdParty/GCC/Posix
|
||||||
INCLUDE_DIRS += -I${FREERTOS_DIR}/Source/portable/ThirdParty/GCC/Posix/utils
|
INCLUDE_DIRS += -I${KERNEL_DIR}/portable/ThirdParty/GCC/Posix/utils
|
||||||
INCLUDE_DIRS += -I${FREERTOS_DIR}/Demo/Common/include
|
INCLUDE_DIRS += -I${FREERTOS_DIR}/Demo/Common/include
|
||||||
INCLUDE_DIRS += -I${FREERTOS_PLUS_DIR}/Source/FreeRTOS-Plus-Trace/Include
|
INCLUDE_DIRS += -I${FREERTOS_PLUS_DIR}/Source/FreeRTOS-Plus-Trace/Include
|
||||||
|
|
||||||
SOURCE_FILES := $(wildcard *.c)
|
SOURCE_FILES := $(wildcard *.c)
|
||||||
SOURCE_FILES += $(wildcard ${FREERTOS_DIR}/Source/*.c)
|
SOURCE_FILES += $(wildcard ${FREERTOS_DIR}/Source/*.c)
|
||||||
# Memory manager (use malloc() / free() )
|
# Memory manager (use malloc() / free() )
|
||||||
SOURCE_FILES += ${FREERTOS_DIR}/Source/portable/MemMang/heap_3.c
|
SOURCE_FILES += ${KERNEL_DIR}/portable/MemMang/heap_3.c
|
||||||
# posix port
|
# posix port
|
||||||
SOURCE_FILES += ${FREERTOS_DIR}/Source/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c
|
SOURCE_FILES += ${KERNEL_DIR}/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c
|
||||||
SOURCE_FILES += ${FREERTOS_DIR}/Source/portable/ThirdParty/GCC/Posix/port.c
|
SOURCE_FILES += ${KERNEL_DIR}/portable/ThirdParty/GCC/Posix/port.c
|
||||||
|
|
||||||
# Demo library.
|
# Demo library.
|
||||||
SOURCE_FILES += ${FREERTOS_DIR}/Demo/Common/Minimal/AbortDelay.c
|
SOURCE_FILES += ${FREERTOS_DIR}/Demo/Common/Minimal/AbortDelay.c
|
||||||
@ -58,8 +61,27 @@ SOURCE_FILES += ${FREERTOS_PLUS_DIR}/Source/FreeRTOS-Plus-Trace/trcStreamingReco
|
|||||||
SOURCE_FILES += ${FREERTOS_PLUS_DIR}/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c
|
SOURCE_FILES += ${FREERTOS_PLUS_DIR}/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c
|
||||||
|
|
||||||
|
|
||||||
CFLAGS := -ggdb3 -O0 -DprojCOVERAGE_TEST=0 -D_WINDOWS_
|
CFLAGS := -ggdb3 -DprojCOVERAGE_TEST=0 -D_WINDOWS_
|
||||||
LDFLAGS := -ggdb3 -O0 -pthread
|
LDFLAGS := -ggdb3 -pthread
|
||||||
|
CPPFLAGS := $(INCLUDE_DIRS) -DBUILD_DIR=\"$(BUILD_DIR_ABS)\"
|
||||||
|
|
||||||
|
ifdef PROFILE
|
||||||
|
CFLAGS += -pg -O0
|
||||||
|
LDFLAGS += -pg -O0
|
||||||
|
else
|
||||||
|
CFLAGS += -O3
|
||||||
|
LDFLAGS += -O3
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef SANITIZE_ADDRESS
|
||||||
|
CFLAGS += -fsanitize=address -fsanitize=alignment
|
||||||
|
LDFLAGS += -fsanitize=address -fsanitize=alignment
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef SANITIZE_LEAK
|
||||||
|
LDFLAGS += -fsanitize=leak
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
OBJ_FILES = $(SOURCE_FILES:%.c=$(BUILD_DIR)/%.o)
|
OBJ_FILES = $(SOURCE_FILES:%.c=$(BUILD_DIR)/%.o)
|
||||||
|
|
||||||
@ -69,14 +91,13 @@ ${BIN} : $(BUILD_DIR)/$(BIN)
|
|||||||
|
|
||||||
${BUILD_DIR}/${BIN} : ${OBJ_FILES}
|
${BUILD_DIR}/${BIN} : ${OBJ_FILES}
|
||||||
-mkdir -p ${@D}
|
-mkdir -p ${@D}
|
||||||
$(CC) $^ $(CFLAGS) $(INCLUDE_DIRS) ${LDFLAGS} -o $@
|
$(CC) $^ ${LDFLAGS} -o $@
|
||||||
|
|
||||||
|
|
||||||
-include ${DEP_FILE}
|
-include ${DEP_FILE}
|
||||||
|
|
||||||
${BUILD_DIR}/%.o : %.c
|
${BUILD_DIR}/%.o : %.c Makefile
|
||||||
-mkdir -p $(@D)
|
-mkdir -p $(@D)
|
||||||
$(CC) $(CFLAGS) ${INCLUDE_DIRS} -MMD -c $< -o $@
|
$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -c $< -o $@
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
@ -84,6 +105,10 @@ clean:
|
|||||||
-rm -rf $(BUILD_DIR)
|
-rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
GPROF_OPTIONS := --directory-path=$(INCLUDE_DIRS)
|
||||||
|
profile:
|
||||||
|
gprof -a -p --all-lines $(GPROF_OPTIONS) $(BUILD_DIR)/$(BIN) $(BUILD_DIR)/gmon.out > $(BUILD_DIR)/prof_flat.txt
|
||||||
|
gprof -a --graph $(GPROF_OPTIONS) $(BUILD_DIR)/$(BIN) $(BUILD_DIR)/gmon.out > $(BUILD_DIR)/prof_call_graph.txt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
64
FreeRTOS/Demo/Posix_GCC/Readme.md
Normal file
64
FreeRTOS/Demo/Posix_GCC/Readme.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# Profilig your application
|
||||||
|
|
||||||
|
## Introduction [(from the official gprof doc)](https://sourceware.org/binutils/docs/gprof/Introduction.html#Introduction)
|
||||||
|
Profiling allows you to learn where your program spent its time and which
|
||||||
|
functions called which other functions while it was executing. This information
|
||||||
|
can show you which pieces of your program are slower than you expected, and
|
||||||
|
might be candidates for rewriting to make your program execute faster. It can
|
||||||
|
also tell you which functions are being called more or less often than you
|
||||||
|
expected. This may help you spot bugs that had otherwise been unnoticed.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
### gprof
|
||||||
|
Version as tested: GNU gprof (GNU Binutils) 2.36
|
||||||
|
### make
|
||||||
|
Version as tested: GNU Make 3.82
|
||||||
|
### gcc
|
||||||
|
Version as tested: gcc (GCC) 11.0.0
|
||||||
|
|
||||||
|
## Generating Profiles
|
||||||
|
```
|
||||||
|
$ make PROFILE=1
|
||||||
|
```
|
||||||
|
Run your application
|
||||||
|
```
|
||||||
|
$ ./build/possix_demo
|
||||||
|
```
|
||||||
|
Since FreeRTOS and its application never come to an end and typically run
|
||||||
|
forever. The user has to kill the application with **Ctrl_C** when they feel
|
||||||
|
satisfied that the application achieved its indented task. Killing the
|
||||||
|
application will force the profiling file *gmon.out* to be generated
|
||||||
|
automatically.
|
||||||
|
In order to make sense of this file, the user has to convert the file with:
|
||||||
|
```
|
||||||
|
$ make profile
|
||||||
|
```
|
||||||
|
two (2) files *prof_call_graph.txt* and *prof_flat.txt* will be generated in the
|
||||||
|
build directory.
|
||||||
|
In order to understand the outputs generated, the best way is to read the
|
||||||
|
official documentation of gprof [here](https://sourceware.org/binutils/docs/gprof/Output.html#Output)
|
||||||
|
|
||||||
|
|
||||||
|
# Run your application with Sanitizers
|
||||||
|
## Introduction
|
||||||
|
* AddressSanitizer, a fast memory error detector. Memory
|
||||||
|
access instructions are instrumented to detect out-of-bounds and use-after-free
|
||||||
|
bugs
|
||||||
|
* LeakSanitizer, a memory leak detector. This option only matters for linking of
|
||||||
|
executables and the executable is linked against a library that overrides malloc
|
||||||
|
and other allocator functions
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
### gcc
|
||||||
|
Version as tested: gcc (GCC) 11.0.0
|
||||||
|
## Building and Running the Application
|
||||||
|
```
|
||||||
|
$ make SANITIZE_ADDRESS=1
|
||||||
|
or
|
||||||
|
$ make SANITIZE_LEAK=1
|
||||||
|
```
|
||||||
|
Then run your program normally.
|
||||||
|
```
|
||||||
|
$ ./build/possix_demo
|
||||||
|
```
|
||||||
|
If an error is detected by the sanitizer, a report showing the error will be printed to stdout.
|
@ -55,6 +55,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
/* FreeRTOS kernel includes. */
|
/* FreeRTOS kernel includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
@ -68,6 +70,12 @@
|
|||||||
|
|
||||||
#define mainSELECTED_APPLICATION BLINKY_DEMO
|
#define mainSELECTED_APPLICATION BLINKY_DEMO
|
||||||
|
|
||||||
|
#ifdef BUILD_DIR
|
||||||
|
#define BUILD BUILD_DIR
|
||||||
|
#else
|
||||||
|
#define BUILD "./"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This demo uses heap_3.c (the libc provided malloc() and free()). */
|
/* This demo uses heap_3.c (the libc provided malloc() and free()). */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@ -103,6 +111,12 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
|
|||||||
*/
|
*/
|
||||||
static void prvSaveTraceFile( void );
|
static void prvSaveTraceFile( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Signal handler for Ctrl_C to cause the program to exit, and generate the
|
||||||
|
* profiling info.
|
||||||
|
*/
|
||||||
|
static void handle_sigint(int signal);
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* When configSUPPORT_STATIC_ALLOCATION is set to 1 the application writer can
|
/* When configSUPPORT_STATIC_ALLOCATION is set to 1 the application writer can
|
||||||
@ -117,8 +131,13 @@ static BaseType_t xTraceRunning = pdTRUE;
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main( void )
|
int main( void )
|
||||||
{
|
{
|
||||||
|
/* SIGINT is not blocked by the posix port */
|
||||||
|
signal( SIGINT, handle_sigint );
|
||||||
|
|
||||||
/* Do not include trace code when performing a code coverage analysis. */
|
/* Do not include trace code when performing a code coverage analysis. */
|
||||||
#if ( projCOVERAGE_TEST != 1 )
|
#if ( projCOVERAGE_TEST != 1 )
|
||||||
{
|
{
|
||||||
@ -231,13 +250,13 @@ void vApplicationTickHook( void )
|
|||||||
|
|
||||||
void traceOnEnter()
|
void traceOnEnter()
|
||||||
{
|
{
|
||||||
int ret;
|
int xReturn;
|
||||||
struct timeval tv = { 0L, 0L };
|
struct timeval tv = { 0L, 0L };
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(0, &fds);
|
FD_SET(0, &fds);
|
||||||
ret = select(1, &fds, NULL, NULL, &tv);
|
xReturn = select(1, &fds, NULL, NULL, &tv);
|
||||||
if ( ret > 0 )
|
if ( xReturn > 0 )
|
||||||
{
|
{
|
||||||
if( xTraceRunning == pdTRUE )
|
if( xTraceRunning == pdTRUE )
|
||||||
{
|
{
|
||||||
@ -386,3 +405,14 @@ the stack and so not exists after this function exits. */
|
|||||||
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||||
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_sigint( int signal )
|
||||||
|
{
|
||||||
|
int xReturn;
|
||||||
|
xReturn = chdir( BUILD ); /* changing dir to place gmon.out inside build */
|
||||||
|
if( xReturn == -1 )
|
||||||
|
{
|
||||||
|
printf( "chdir into %s error is %d\n", BUILD, errno );
|
||||||
|
}
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user