examples/foc: improve perf monitor

improve FOC perf monitor:

- add options to choose when perf result should be printed
- measure the controller thread call period
This commit is contained in:
raiden00pl 2024-09-20 18:46:43 +02:00 committed by Xiang Xiao
parent 5c166edf63
commit beeec27afd
6 changed files with 173 additions and 30 deletions

View file

@ -47,6 +47,24 @@ config EXAMPLES_FOC_PERF
bool "Enable performance meassurements"
default n
if EXAMPLES_FOC_PERF
config EXAMPLES_FOC_PERF_LIVE
bool "Print FOC perf results on each max value change"
default n
---help---
With this option perf results are printed every time the maximum value
changes. The disadvantage of this method is that printing can directly
affect the pref result but it gives results in real time.
config EXAMPLES_FOC_PERF_EXIT
bool "Print FOC perf results on thread exit"
default y
---help---
With this option perf results are printed on control thread exit.
endif # EXAMPLES_FOC_PERF
choice
prompt "FOC modulation selection"
default EXAMPLES_FOC_MODULATION_SVM3

View file

@ -209,6 +209,12 @@ int foc_dev_params_set(FAR struct foc_device_s *dev)
foc_perf_end(&dev->perf);
#endif
#ifdef CONFIG_EXAMPLES_FOC_PERF_LIVE
/* Print perf live stats */
foc_perf_live(&dev->perf);
#endif
errout:
return ret;
}

View file

@ -503,13 +503,6 @@ int foc_fixed16_thr(FAR struct foc_ctrl_env_s *envp)
/* Increase counter */
motor.time += 1;
#ifdef CONFIG_EXAMPLES_FOC_PERF
if (dev.perf.max_changed)
{
PRINTF_PERF("max=%" PRId32 "\n", dev.perf.max);
}
#endif
}
errout:
@ -532,6 +525,12 @@ errout:
PRINTF("ERROR: foc_device_deinit %d failed %d\n", envp->id, ret);
}
#ifdef CONFIG_EXAMPLES_FOC_PERF_EXIT
/* Print final perf stats */
foc_perf_exit(&dev.perf);
#endif
PRINTF("foc_fixed16_thr %d exit\n", envp->id);
return ret;

View file

@ -516,13 +516,6 @@ int foc_float_thr(FAR struct foc_ctrl_env_s *envp)
/* Increase counter */
motor.time += 1;
#ifdef CONFIG_EXAMPLES_FOC_PERF
if (dev.perf.max_changed)
{
PRINTF_PERF("max=%" PRId32 "\n", dev.perf.max);
}
#endif
}
errout:
@ -545,6 +538,12 @@ errout:
PRINTF("ERROR: foc_device_deinit %d failed %d\n", envp->id, ret);
}
#ifdef CONFIG_EXAMPLES_FOC_PERF_EXIT
/* Print final perf stats */
foc_perf_exit(&dev.perf);
#endif
PRINTF("foc_float_thr %d exit\n", envp->id);
return ret;

View file

@ -27,11 +27,50 @@
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <nuttx/clock.h>
#include "foc_perf.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define PRINTF_PERF(format, ...) printf(format, ##__VA_ARGS__)
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: foc_perf_exec
****************************************************************************/
static bool foc_perf_exec(struct foc_perf_s *p, FAR uint32_t *exec)
{
bool tmp = p->exec_max_changed;
*exec = p->exec_max;
p->exec_max_changed = false;
return tmp;
}
/****************************************************************************
* Name: foc_perf_per
****************************************************************************/
static bool foc_perf_per(struct foc_perf_s *p, FAR uint32_t *per)
{
bool tmp = p->per_max_changed;
*per = p->per_max;
p->per_max_changed = false;
return tmp;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -53,7 +92,7 @@ int foc_perf_init(struct foc_perf_s *p)
void foc_perf_start(struct foc_perf_s *p)
{
p->now = perf_gettime();
p->exec = perf_gettime();
}
/****************************************************************************
@ -62,13 +101,72 @@ void foc_perf_start(struct foc_perf_s *p)
void foc_perf_end(struct foc_perf_s *p)
{
p->now = perf_gettime() - p->now;
uint32_t now = perf_gettime();
uint32_t tmp = 0;
p->max_changed = false;
if (p->now > p->max)
if (p->per > 0)
{
p->max = p->now;
p->max_changed = true;
tmp = now - p->per;
}
p->per = now;
p->exec = now - p->exec;
p->exec_max_changed = false;
p->per_max_changed = false;
if (p->exec > p->exec_max)
{
p->exec_max = p->exec;
p->exec_max_changed = true;
}
if (tmp > p->per_max)
{
p->per_max = tmp;
p->per_max_changed = true;
}
}
/****************************************************************************
* Name: foc_perf_live
****************************************************************************/
void foc_perf_live(struct foc_perf_s *p)
{
uint32_t perf = 0;
if (foc_perf_exec(p, &perf))
{
PRINTF_PERF("exec ticks=%" PRId32 "\n", perf);
}
if (foc_perf_per(p, &perf))
{
PRINTF_PERF("per ticks=%" PRId32 "\n", perf);
}
}
/****************************************************************************
* Name: foc_perf_exit
****************************************************************************/
void foc_perf_exit(struct foc_perf_s *p)
{
struct timespec ts;
uint32_t max = 0;
PRINTF_PERF("===============================\n");
foc_perf_exec(p, &max);
perf_convert(max, &ts);
PRINTF_PERF("exec ticks=%" PRId32 "\n", max);
PRINTF_PERF(" nsec=%" PRId32 "\n", ts.tv_nsec);
foc_perf_per(p, &max);
perf_convert(max, &ts);
PRINTF_PERF("per ticks=%" PRId32 "\n", max);
PRINTF_PERF(" nsec=%" PRId32 "\n", ts.tv_nsec);
PRINTF_PERF("===============================\n");
}

View file

@ -27,21 +27,42 @@
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define PRINTF_PERF(format, ...) printf(format, ##__VA_ARGS__)
/****************************************************************************
* Public Type Definition
****************************************************************************/
/* The diagram below illustrates the operation of a simple FOC ocntroller
* performance measurement tool:
*
* | notify | notify | notify
* v v v
* ctrl ctrl
* |------| |------| |---
* | BUSY | wait | BUSY | wait |
* ____| |------| |------|
*
* ^ ^ ^
* | exec | |
* |<---->| |
* | |
* | per |
* |<----------->|
*
*
* exec - FOC control loop execution time
* per - FOC control loop period
* notify - notification event from FOC device,
* called with CONFIG_EXAMPLES_FOC_NOTIFIER_FREQ frequency
*/
struct foc_perf_s
{
bool max_changed;
uint32_t max;
uint32_t now;
bool exec_max_changed; /* Max execution time changed */
bool per_max_changed; /* Max period changed */
uint32_t exec_max; /* Control loop execution max */
uint32_t per_max; /* Control loop period max */
uint32_t exec; /* Temporary storage */
uint32_t per; /* Temporary storage */
};
/****************************************************************************
@ -51,5 +72,7 @@ struct foc_perf_s
int foc_perf_init(struct foc_perf_s *p);
void foc_perf_start(struct foc_perf_s *p);
void foc_perf_end(struct foc_perf_s *p);
void foc_perf_live(struct foc_perf_s *p);
void foc_perf_exit(struct foc_perf_s *p);
#endif /* __APPS_EXAMPLES_FOC_FOC_PERF_H */