Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests/periph_pm: make usage more intuitive and move shell commands to sys/ #11731

Merged
merged 6 commits into from
Apr 28, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions sys/include/pm_layered.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ extern "C" {
#define PROVIDES_PM_SET_LOWEST
#endif

/**
* @brief Power Management mode blocker typedef
*/
typedef union {
uint32_t val_u32; /**< power mode blockers u32 */
uint8_t val_u8[PM_NUM_MODES]; /**< power mode blockers u8 */
} pm_blocker_t;

/**
* @brief Block a power mode
*
Expand Down
8 changes: 0 additions & 8 deletions sys/pm_layered/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@
#define PM_BLOCKER_INITIAL 0x01010101 /* block all by default */
#endif

/**
* @brief Power Management mode typedef
*/
typedef union {
uint32_t val_u32;
uint8_t val_u8[PM_NUM_MODES];
} pm_blocker_t;

/**
* @brief Global variable for keeping track of blocked modes
*/
Expand Down
3 changes: 3 additions & 0 deletions sys/shell/commands/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ endif
ifneq (,$(filter mci,$(USEMODULE)))
SRC += sc_disk.c
endif
ifneq (,$(filter periph_pm,$(USEMODULE)))
SRC += sc_pm.c
endif
ifneq (,$(filter ps,$(USEMODULE)))
SRC += sc_ps.c
endif
Expand Down
194 changes: 194 additions & 0 deletions sys/shell/commands/sc_pm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
* Copyright (C) 2019 Thomas Stilwell <[email protected]>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup sys_shell_commands
* @{
*
* @file
* @brief Shell command to interact with the PM subsystem
*
* @author Bas Stottelaar <[email protected]>
* @author Vincent Dupont <[email protected]>
* @author Thomas Stilwell <[email protected]>
*
* @}
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "periph/pm.h"

#ifdef MODULE_PM_LAYERED
#include "pm_layered.h"

extern volatile pm_blocker_t pm_blocker; /* sys/pm_layered/pm.c */
#endif /* MODULE_PM_LAYERED */

static void _print_usage(void) {
puts("Usage:");
#ifdef MODULE_PM_LAYERED
puts("\tpm show: display current blockers for each power mode");
puts("\tpm set <mode>: manually set power mode (lasts until WFI returns)");
puts("\tpm block <mode>: manually block power mode");
puts("\tpm unblock <mode>: manually unblock power mode");
#endif /* MODULE_PM_LAYERED */
puts("\tpm off: call pm_off()");
}

#ifdef MODULE_PM_LAYERED
static int check_mode(int argc, char **argv)
{
if (argc != 3) {
printf("Usage: %s %s <power mode>\n", argv[0], argv[1]);
return -1;
}

return 0;
}

static int parse_mode(char *argv)
{
uint8_t mode = atoi(argv);

if (mode >= PM_NUM_MODES) {
printf("Error: power mode not in range 0 - %d.\n", PM_NUM_MODES - 1);
return -1;
}

return mode;
}

static int cmd_block(char *arg)
{
int mode = parse_mode(arg);
if (mode < 0) {
return 1;
}

printf("Blocking power mode %d.\n", mode);
fflush(stdout);

pm_block(mode);

return 0;
}

static int cmd_set(char *arg)
{
int mode = parse_mode(arg);
if (mode < 0) {
return 1;
}

printf("CPU is entering power mode %d.\n", mode);
puts("Now waiting for a wakeup event...");
fflush(stdout);

pm_set(mode);
/* execution stops here until anything (like shell input) wakes the CPU */

printf("CPU has returned from power mode %d.\n", mode);

return 0;
}

static int cmd_unblock(char *arg)
{
int mode = parse_mode(arg);

if (mode < 0) {
return 1;
}

if (pm_blocker.val_u8[mode] == 0) {
printf("Mode %d is already unblocked.\n", mode);
return 1;
}

printf("Unblocking power mode %d.\n", mode);
fflush(stdout);

pm_unblock(mode);

return 0;
}

static int cmd_show(char *arg)
{
(void)arg;
uint8_t lowest_allowed_mode = 0;

for (unsigned i = 0; i < PM_NUM_MODES; i++) {
printf("mode %u blockers: %u \n", i, pm_blocker.val_u8[i]);
if (pm_blocker.val_u8[i]) {
lowest_allowed_mode = i + 1;
}
}

printf("Lowest allowed mode: %u\n", lowest_allowed_mode);
return 0;
}
#endif /* MODULE_PM_LAYERED */

static int cmd_off(char *arg)
{
(void)arg;

pm_off();

return 0;
}

int _pm_handler(int argc, char **argv)
{
#ifdef MODULE_PM_LAYERED
if (!strcmp(argv[1], "show")) {
if (argc != 2) {
puts("usage: pm show: display current blockers for each power mode");
return 1;
}

return cmd_show(argv[1]);
}

if (!strcmp(argv[1], "block")) {
if (check_mode(argc, argv) != 0) {
return 1;
}

return cmd_block(argv[2]);
}

if (!strcmp(argv[1], "unblock")) {
if (check_mode(argc, argv) != 0) {
return 1;
}

return cmd_unblock(argv[2]);
}

if (!strcmp(argv[1], "set")) {
if (check_mode(argc, argv) != 0) {
return 1;
}

return cmd_set(argv[2]);
}
#else
(void)argc;
#endif /* MODULE_PM_LAYERED */

if (!strcmp(argv[1], "off")) {
return cmd_off(NULL);
}

_print_usage();
return 1;
}
7 changes: 7 additions & 0 deletions sys/shell/commands/shell_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ extern int _id_handler(int argc, char **argv);
extern int _heap_handler(int argc, char **argv);
#endif

#ifdef MODULE_PERIPH_PM
extern int _pm_handler(int argc, char **argv);
#endif

#ifdef MODULE_PS
extern int _ps_handler(int argc, char **argv);
#endif
Expand Down Expand Up @@ -180,6 +184,9 @@ const shell_command_t _shell_command_list[] = {
#ifdef MODULE_HEAP_CMD
{"heap", "Prints heap statistics.", _heap_handler},
#endif
#ifdef MODULE_PERIPH_PM
{ "pm", "interact with layered PM subsystem", _pm_handler },
#endif
#ifdef MODULE_PS
{"ps", "Prints information about running threads.", _ps_handler},
#endif
Expand Down
1 change: 1 addition & 0 deletions tests/periph_pm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ FEATURES_OPTIONAL += periph_rtc
FEATURES_OPTIONAL += periph_gpio_irq

USEMODULE += shell
USEMODULE += shell_commands

include $(RIOTBASE)/Makefile.include
Loading