Skip to content

Commit

Permalink
sys/shell/commands: pm: add set mode block mode unblock mode
Browse files Browse the repository at this point in the history
  • Loading branch information
benemorius authored and aabadie committed Apr 28, 2020
1 parent aa97e7b commit 9659300
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 156 deletions.
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
2 changes: 1 addition & 1 deletion sys/shell/commands/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ endif
ifneq (,$(filter mci,$(USEMODULE)))
SRC += sc_disk.c
endif
ifneq (,$(filter pm_layered,$(USEMODULE)))
ifneq (,$(filter periph_pm,$(USEMODULE)))
SRC += sc_pm.c
endif
ifneq (,$(filter ps,$(USEMODULE)))
Expand Down
161 changes: 146 additions & 15 deletions sys/shell/commands/sc_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,49 +13,180 @@
* @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 "pm_layered.h"
#include "periph/pm.h"

/* TODO deduplicate this definition with the one in sys/pm_layered/pm.c */
typedef union {
uint32_t val_u32;
uint8_t val_u8[PM_NUM_MODES];
} pm_blocker_t;
#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) {
printf("usage: pm show: display current blockers for each power mode\n");
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;
}

int _pm(int argc, char **argv)
static int cmd_set(char *arg)
{
if (argc != 2) {
_print_usage();
int mode = parse_mode(arg);
if (mode < 0) {
return 1;
}

if (strcmp(argv[1], "show")) {
_print_usage();
return 2;
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] == 1) {
if (pm_blocker.val_u8[i]) {
lowest_allowed_mode = i + 1;
}
}

printf("lowest allowed mode: %u\n", lowest_allowed_mode);
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]);
}
#endif /* MODULE_PM_LAYERED */

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

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

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

#ifdef MODULE_PS
Expand Down Expand Up @@ -185,7 +185,7 @@ const shell_command_t _shell_command_list[] = {
{"heap", "Prints heap statistics.", _heap_handler},
#endif
#ifdef MODULE_PM_LAYERED
{ "pm", "interact with layered PM subsystem", _pm },
{ "pm", "interact with layered PM subsystem", _pm_handler },
#endif
#ifdef MODULE_PS
{"ps", "Prints information about running threads.", _ps_handler},
Expand Down
Loading

0 comments on commit 9659300

Please sign in to comment.