Skip to content

tests: periph_pm: add peripheral test.#8848

Merged
aabadie merged 1 commit intoRIOT-OS:masterfrom
basilfx:feature/test_periph_pm
Apr 5, 2018
Merged

tests: periph_pm: add peripheral test.#8848
aabadie merged 1 commit intoRIOT-OS:masterfrom
basilfx:feature/test_periph_pm

Conversation

@basilfx
Copy link
Copy Markdown
Member

@basilfx basilfx commented Mar 28, 2018

Contribution description

This PR adds a test application for periph_pm. Although you need a way to measure power consumption to really use this test, I think its a nice way to play with (or debug) the power modes and observe what the CPU will do.

I had this one lying around, somewhere. Initially I used this (before periph_pm) to test the power modes on the EFM32 development kits, but rearranged it for periph_pm.

Issues/PRs references

None

@basilfx basilfx added Area: tests Area: tests and testing framework Type: new feature The issue requests / The PR implemements a new feature for RIOT labels Mar 28, 2018
@jnohlgard
Copy link
Copy Markdown
Member

Cool! Useful for reference measurements to compare with what the real application uses

@aabadie
Copy link
Copy Markdown
Contributor

aabadie commented Mar 29, 2018

Sorry, but it looks like a duplicate of #7666.

@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Mar 29, 2018

@aabadie Oops, yes. I did search for periph_pm before submitting :-)

@vincent-d Maybe we can merge both PR's?

@vincent-d
Copy link
Copy Markdown
Member

I have no time to work on this at the moment, so you can go ahead with this one! I'll try to review it.

If it gets merged, we'll close mine.

@basilfx basilfx force-pushed the feature/test_periph_pm branch from 10766ec to 2a4baff Compare March 29, 2018 22:05
@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Mar 29, 2018

Merged this with the work by @vincent-d in #7666.

I chose to add an additional unblock_rtc to simplify code/ifdefs. It only works if the CPU provides pm_layered and periph_rtc.

Screenshot below show a gap of three seconds of scheduled unblocking. The other gap is a normal unblock (with UART events inbetween).

schermafbeelding 2018-03-30 om 00 09 30

@basilfx basilfx force-pushed the feature/test_periph_pm branch from 2a4baff to fa9846c Compare March 29, 2018 22:44
@vincent-d vincent-d added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Mar 30, 2018
@@ -0,0 +1,14 @@
Expected result
===============
You should be presented with the RIOT shell, providing you with three commands to test the power
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a bit more than three commands ;)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes :-)

Fixed.

Copy link
Copy Markdown
Member

@vincent-d vincent-d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quickly tested on stm32f4, pm_unblock_rtc works fine.

Except minor comment, it's looks OK.

Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I have a few comments and questions.

I'll test it on stm32l0.

@@ -0,0 +1,11 @@
APPLICATION = periph_pm
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to set this variable

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


Some power modes may require a certain event to wake up. Reset the CPU if needed.

If a RTC peripheral is available, an additional command to temporary unblock a power mode is
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/temporary/temporarily/

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

#ifdef MODULE_PERIPH_RTC
#include "periph/rtc.h"
#endif
#include "pm_layered.h"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this include should be made conditional with #ifdef MODULE_PM_LAYERED

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Fixed.


rtc_get_time(&time);
time.tm_sec += duration;
while (time.tm_sec > 60) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would make sense to use mktime/localtime functions to automatically compute the correct struct tm ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how I would use these methods to just add a certain amount of seconds.

I copied this part from #7666.

Copy link
Copy Markdown
Contributor

@aabadie aabadie Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there can be side effects if adding the duration (in seconds) also increases hour. I think those functions handles that better (not tested though)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. Found something here, and it seems to work (ok, I didn't test whole hours, but minutes is OK).

char line_buf[SHELL_DEFAULT_BUFSIZE];

/* print some information about the modes */
printf("This application allows you to test the power management\n"
Copy link
Copy Markdown
Contributor

@aabadie aabadie Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if power management is a peripheral. I would just say to test the CPU power management

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

/**
* @brief List of shell commands for this example.
*/
static const shell_command_t shell_commands[] = {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general this array is created just before the main function

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this. Can you explain?

Do you mean that I should move this just before the main method?

Copy link
Copy Markdown
Contributor

@aabadie aabadie Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and then you don't need to declare the command functions.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

#ifdef MODULE_PM_LAYERED
{ "block", "block power mode", cmd_block },
#endif
{ "lowest", "enter lowest mode", cmd_lowest },
Copy link
Copy Markdown
Contributor

@aabadie aabadie Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this command needed ? if one unblocks a power mode with unblock command, then the main thread (only thread running) will be blocked (waiting for incoming commands), so the system should switch to idle thread that automatically calls pm_set_lowest.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed cmd_lowest.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out-of-curiosity, do you confirm that it works as expected (in terms of power consumption) ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I observe a difference when I change the power modes.

schermafbeelding_2018-03-30_om_10_45_48

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really nice!

@basilfx basilfx force-pushed the feature/test_periph_pm branch from fa9846c to ba346ae Compare March 30, 2018 08:48
@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Mar 30, 2018

Fixed the comments and rebased.

#include "periph/rtc.h"
#endif
#endif
#include "pm_layered.h"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include is still out of the conditional #ifdef

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, sorry. Fixed that one.


return 0;
}
#endif
Copy link
Copy Markdown
Contributor

@aabadie aabadie Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment mentioning which block is closed here (MODULE_PM_LAYERED)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

#ifdef MODULE_PM_LAYERED
static int cmd_set(int argc, char **argv)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe these functions could be grouped in the same #ifdef MODULE_PM_LAYERED above block.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

*/
static const shell_command_t shell_commands[] = {
#ifdef MODULE_PM_LAYERED
{ "block", "block power mode", cmd_block },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, this line can be moved before the unblock line.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wanted to keep it sorted alphabetically. Will move it to first one in the other MODULE_PM_LAYERED block.

BOARD ?= slstk3401a
include ../Makefile.tests_common

FEATURES_REQUIRED += periph_pm
Copy link
Copy Markdown
Contributor

@aabadie aabadie Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is needed, this feature is already optional by default (see Makefile.dep). And that's probably why the CI is failing.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@basilfx basilfx force-pushed the feature/test_periph_pm branch from 76411af to 3bf1f8a Compare March 30, 2018 09:30
@basilfx basilfx added the CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable label Mar 30, 2018
#endif /* MODULE_PERIPH_RTC */
#endif /* MODULE_PM_LAYERED */

static int cmd_off(int argc, char **argv)
Copy link
Copy Markdown
Contributor

@aabadie aabadie Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmd_off and cmd_reboot should be moved to the top and then all functions that requires MODULE_PM_LAYERED could be grouped in the same conditional #ifdef.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep it this way: I now have the commands grouped together, and utility functions on top.

"The available power modes are 0 - %d. Lower-numbered power modes\n"
"save more power, but may require an event/interrupt to wake up\n"
"the CPU. Reset the CPU if needed.\n",
PM_NUM_MODES - 1);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of PM_NUM_MODE should be excluded for boards not providing the pm_layered module.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@basilfx basilfx force-pushed the feature/test_periph_pm branch from 47fd045 to 095d8a8 Compare April 2, 2018 17:08
@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Apr 2, 2018

Few MSP430-based board don't compile due to missing fflush. Any ideas?

@jnohlgard
Copy link
Copy Markdown
Member

If we can get #6445 finished all such problems would go away.

@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Apr 3, 2018

Thanks @gebart for pointing that out.

Since #6445 is not active, I propose to either blacklist the boards, or to put #ifndef MODULE_MSP430_COMMON around fflush.

I prefer the latter, since the test itself is still valuable.

@aabadie
Copy link
Copy Markdown
Contributor

aabadie commented Apr 3, 2018

I propose to either blacklist the boards

+1 for that solution (already used in other places)

@basilfx basilfx force-pushed the feature/test_periph_pm branch from 095d8a8 to 78cb81e Compare April 3, 2018 11:42
@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Apr 3, 2018

@aabadie Can I squash? Murdock is almost happy now :-)

Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few remaining comments, mainly regarding the parse_mode function.

return -1;
}

int mode = atoi(argv[1]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mode could be an uint8_t

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


int mode = atoi(argv[1]);

if (mode < 0 || mode >= (int) PM_NUM_MODES) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then here there's no need to check that mode is negative

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

#ifdef MODULE_PM_LAYERED
static int cmd_block(int argc, char **argv)
{
int mode = parse_mode(argc, argv);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mode could be uint8_t

{
int mode = parse_mode(argc, argv);

if (mode < 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse_mode function is already testing this

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would indicate a error code, so I need to check this here.

{
int mode = parse_mode(argc, argv);

if (mode < 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment about parse_mode

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would indicate a error code, so I need to check this here.


static int cmd_unblock(int argc, char **argv)
{
int mode = parse_mode(argc, argv);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse_mode

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arf, sorry, re-read the parse_mode function and testing the negative returned value is perfectly fine. The comment about uint8_t (in parse_mode) still stands.

int mode = parse_mode(argc, argv);
int duration = parse_duration(argc, argv);

if (mode < 0 || duration < 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again parse_mode

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would indicate a error code, so I need to check this here.

@basilfx basilfx force-pushed the feature/test_periph_pm branch from 78cb81e to ea04b6f Compare April 4, 2018 10:53
@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Apr 4, 2018

Processed feedback and rebased.

@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Apr 4, 2018

@aabadie Good enough to squash?

Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Played a bit with the test application and I have other comments.
I think it works but the commands messages (in case of usage errors) could be improved. I'm proposing a refactoring of parse_mode and parse_duration function.

#ifdef MODULE_PM_LAYERED
static int parse_mode(int argc, char **argv)
{
if (argc < 2) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved to each command function handler and if a wrong number of arguments is given, the command prints a usage message Usage: unblock <power mode> or Usage: unblock_rtc <power mode> <duration>.
Otherwise the error message doesn't give any hint on how to correctly use the command. Maybe introduce a _check_usage(int argc, int expected_argc) function for this ?

Then the parse_mode and parse_duration could be simplified with this signature:

static int _parse_mode(const char * mode)
static int _parse_duration(const char * duration)

@basilfx basilfx force-pushed the feature/test_periph_pm branch from ea04b6f to ad6b12d Compare April 5, 2018 08:25
@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Apr 5, 2018

@aabadie Have improved argument parsing + usage message. Is this better?

Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no more comment, ACK

Please squash.

For the record, I tested a bit the application with an stm32l0 based board and had some problems: low power modes doesn't switch automatically the first time, I have to insist a bit with the unblock command (several calls in a row). This is unrelated to this PR but at least the application is useful to exhibit the problem.

@basilfx basilfx force-pushed the feature/test_periph_pm branch from ad6b12d to 74d496f Compare April 5, 2018 08:58
@basilfx basilfx added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Apr 5, 2018
@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Apr 5, 2018

Squashed. Murdock is green.

@aabadie
Copy link
Copy Markdown
Contributor

aabadie commented Apr 5, 2018

Then go!

@aabadie aabadie merged commit 1eaec49 into RIOT-OS:master Apr 5, 2018
@aabadie aabadie mentioned this pull request Apr 5, 2018
@basilfx basilfx deleted the feature/test_periph_pm branch January 14, 2020 22:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants