From 7c82ac6838fd762c1a124b1a37653f6974da2532 Mon Sep 17 00:00:00 2001 From: Thomas Stilwell Date: Wed, 3 Jul 2019 08:44:03 -0700 Subject: [PATCH 1/6] sys/shell/commands: add `pm show` command to view current blockers --- sys/shell/commands/Makefile | 3 ++ sys/shell/commands/sc_pm.c | 61 +++++++++++++++++++++++++++++ sys/shell/commands/shell_commands.c | 7 ++++ 3 files changed, 71 insertions(+) create mode 100644 sys/shell/commands/sc_pm.c diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index f2ad26f1aa02..d8279517f2f0 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -8,6 +8,9 @@ endif ifneq (,$(filter mci,$(USEMODULE))) SRC += sc_disk.c endif +ifneq (,$(filter pm_layered,$(USEMODULE))) + SRC += sc_pm.c +endif ifneq (,$(filter ps,$(USEMODULE))) SRC += sc_ps.c endif diff --git a/sys/shell/commands/sc_pm.c b/sys/shell/commands/sc_pm.c new file mode 100644 index 000000000000..073d99bf76a3 --- /dev/null +++ b/sys/shell/commands/sc_pm.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019 Thomas Stilwell + * + * 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 Thomas Stilwell + * + * @} + */ + +#include +#include +#include "pm_layered.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; + +extern volatile pm_blocker_t pm_blocker; /* sys/pm_layered/pm.c */ + +static void _print_usage(void) { + printf("usage: pm show: display current blockers for each power mode\n"); +} + +int _pm(int argc, char **argv) +{ + if (argc != 2) { + _print_usage(); + return 1; + } + + if (strcmp(argv[1], "show")) { + _print_usage(); + return 2; + } + + 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) { + lowest_allowed_mode = i + 1; + } + } + + printf("lowest allowed mode: %u\n", lowest_allowed_mode); + + return 0; +} diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index 620c4d1feaeb..663d44ee278c 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -34,6 +34,10 @@ extern int _id_handler(int argc, char **argv); extern int _heap_handler(int argc, char **argv); #endif +#ifdef MODULE_PM_LAYERED +extern int _pm(int argc, char **argv); +#endif + #ifdef MODULE_PS extern int _ps_handler(int argc, char **argv); #endif @@ -180,6 +184,9 @@ const shell_command_t _shell_command_list[] = { #ifdef MODULE_HEAP_CMD {"heap", "Prints heap statistics.", _heap_handler}, #endif +#ifdef MODULE_PM_LAYERED + { "pm", "interact with layered PM subsystem", _pm }, +#endif #ifdef MODULE_PS {"ps", "Prints information about running threads.", _ps_handler}, #endif From 100390cdca7e361d2a791f9611165421c2aedc72 Mon Sep 17 00:00:00 2001 From: Thomas Stilwell Date: Fri, 21 Jun 2019 18:32:24 -0700 Subject: [PATCH 2/6] tests/periph_pm: print block/unblock error instead of assertion failure --- tests/periph_pm/main.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/periph_pm/main.c b/tests/periph_pm/main.c index 63d16f97ef15..ac6675c01c4a 100644 --- a/tests/periph_pm/main.c +++ b/tests/periph_pm/main.c @@ -40,6 +40,15 @@ #endif #ifdef MODULE_PM_LAYERED + +/* 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; + +extern volatile pm_blocker_t pm_blocker; /* sys/pm_layered/pm.c */ + static int check_mode(int argc, char **argv) { if (argc < 2) { @@ -173,6 +182,11 @@ static int cmd_unblock(int argc, char **argv) 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); @@ -195,6 +209,11 @@ static int cmd_unblock_rtc(int argc, char **argv) return 1; } + if (pm_blocker.val_u8[mode] == 0) { + printf("Mode %d is already unblocked.\n", mode); + return 1; + } + printf("Unblocking power mode %d for %d seconds.\n", mode, duration); fflush(stdout); From 90579e81c914c82d2c5462ad9c325acbf25ce0e2 Mon Sep 17 00:00:00 2001 From: Thomas Stilwell Date: Sat, 22 Jun 2019 17:30:22 -0700 Subject: [PATCH 3/6] tests/periph_pm: print current PM blockers on startup --- tests/periph_pm/Makefile | 1 + tests/periph_pm/main.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/tests/periph_pm/Makefile b/tests/periph_pm/Makefile index 16bb20073bed..f8ca0371e745 100644 --- a/tests/periph_pm/Makefile +++ b/tests/periph_pm/Makefile @@ -8,5 +8,6 @@ FEATURES_OPTIONAL += periph_rtc FEATURES_OPTIONAL += periph_gpio_irq USEMODULE += shell +USEMODULE += shell_commands include $(RIOTBASE)/Makefile.include diff --git a/tests/periph_pm/main.c b/tests/periph_pm/main.c index ac6675c01c4a..949d8814d53a 100644 --- a/tests/periph_pm/main.c +++ b/tests/periph_pm/main.c @@ -32,6 +32,7 @@ #include "periph/rtc.h" #endif #include "pm_layered.h" +extern int _pm(int argc, char **argv); #endif #include "shell.h" @@ -270,6 +271,13 @@ int main(void) "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); + + /* In case the system boots into an unresponsive shell, at least display + * the state of PM blockers so that the user will know which power mode has + * been entered and is presumably responsible for the unresponsive shell. + */ + _pm(2, (char *[]){"pm", "show"}); + #else puts("This application allows you to test the CPU power management.\n" "Layered support is not unavailable for this CPU. Reset the CPU if\n" From aa97e7b49a2e65797fefb56a6f25591bfa06a9d5 Mon Sep 17 00:00:00 2001 From: Thomas Stilwell Date: Sat, 22 Jun 2019 17:33:41 -0700 Subject: [PATCH 4/6] tests/periph_pm: be more verbose about what pm_set() is doing --- tests/periph_pm/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/periph_pm/main.c b/tests/periph_pm/main.c index 949d8814d53a..de256e64a2c4 100644 --- a/tests/periph_pm/main.c +++ b/tests/periph_pm/main.c @@ -163,10 +163,14 @@ static int cmd_set(int argc, char **argv) return 1; } - printf("CPU will enter power mode %d.\n", mode); + printf("CPU is entering power mode %d.\n", mode); + printf("Now waiting for a wakeup event...\n"); 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; } From 325ab426d4252607438647f57802e8b177a2996d Mon Sep 17 00:00:00 2001 From: Thomas Stilwell Date: Tue, 9 Jul 2019 18:38:37 -0700 Subject: [PATCH 5/6] sys/shell/commands: pm: add `set mode` `block mode` `unblock mode` --- sys/include/pm_layered.h | 8 ++ sys/pm_layered/pm.c | 8 -- sys/shell/commands/Makefile | 2 +- sys/shell/commands/sc_pm.c | 163 +++++++++++++++++++++++++--- sys/shell/commands/shell_commands.c | 8 +- tests/periph_pm/main.c | 140 ++---------------------- 6 files changed, 171 insertions(+), 158 deletions(-) diff --git a/sys/include/pm_layered.h b/sys/include/pm_layered.h index d7fa07e16987..7814b5e32494 100644 --- a/sys/include/pm_layered.h +++ b/sys/include/pm_layered.h @@ -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 * diff --git a/sys/pm_layered/pm.c b/sys/pm_layered/pm.c index 3f63bfa7b9b7..c14217d60ea3 100644 --- a/sys/pm_layered/pm.c +++ b/sys/pm_layered/pm.c @@ -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 */ diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index d8279517f2f0..a8403d4aa27c 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -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))) diff --git a/sys/shell/commands/sc_pm.c b/sys/shell/commands/sc_pm.c index 073d99bf76a3..6834ee8b7e86 100644 --- a/sys/shell/commands/sc_pm.c +++ b/sys/shell/commands/sc_pm.c @@ -13,49 +13,182 @@ * @file * @brief Shell command to interact with the PM subsystem * + * @author Bas Stottelaar + * @author Vincent Dupont * @author Thomas Stilwell * * @} */ #include +#include #include -#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 : manually set power mode (lasts until WFI returns)"); + puts("\tpm block : manually block power mode"); + puts("\tpm unblock : 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 \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]); + } +#else + (void)argc; +#endif /* MODULE_PM_LAYERED */ + + if (!strcmp(argv[1], "off")) { + return cmd_off(NULL); + } + + _print_usage(); + return 1; +} diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index 663d44ee278c..084ab13d6d6d 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -34,8 +34,8 @@ extern int _id_handler(int argc, char **argv); extern int _heap_handler(int argc, char **argv); #endif -#ifdef MODULE_PM_LAYERED -extern int _pm(int argc, char **argv); +#ifdef MODULE_PERIPH_PM +extern int _pm_handler(int argc, char **argv); #endif #ifdef MODULE_PS @@ -184,8 +184,8 @@ const shell_command_t _shell_command_list[] = { #ifdef MODULE_HEAP_CMD {"heap", "Prints heap statistics.", _heap_handler}, #endif -#ifdef MODULE_PM_LAYERED - { "pm", "interact with layered PM subsystem", _pm }, +#ifdef MODULE_PERIPH_PM + { "pm", "interact with layered PM subsystem", _pm_handler }, #endif #ifdef MODULE_PS {"ps", "Prints information about running threads.", _ps_handler}, diff --git a/tests/periph_pm/main.c b/tests/periph_pm/main.c index de256e64a2c4..caaccf070e0b 100644 --- a/tests/periph_pm/main.c +++ b/tests/periph_pm/main.c @@ -32,8 +32,10 @@ #include "periph/rtc.h" #endif #include "pm_layered.h" -extern int _pm(int argc, char **argv); #endif + +extern int _pm_handler(int argc, char **argv); + #include "shell.h" #ifndef BTN0_INT_FLANK @@ -42,18 +44,13 @@ extern int _pm(int argc, char **argv); #ifdef MODULE_PM_LAYERED -/* 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; - extern volatile pm_blocker_t pm_blocker; /* sys/pm_layered/pm.c */ -static int check_mode(int argc, char **argv) +#ifdef MODULE_PERIPH_RTC +static int check_mode_duration(int argc, char **argv) { - if (argc < 2) { - printf("Usage: %s \n", argv[0]); + if (argc != 3) { + printf("Usage: %s \n", argv[0]); return -1; } @@ -72,17 +69,6 @@ static int parse_mode(char *argv) return mode; } -#ifdef MODULE_PERIPH_RTC -static int check_mode_duration(int argc, char **argv) -{ - if (argc != 3) { - printf("Usage: %s \n", argv[0]); - return -1; - } - - return 0; -} - static int parse_duration(char *argv) { int duration = atoi(argv); @@ -101,106 +87,7 @@ static void cb_rtc(void *arg) pm_block(level); } -#endif /* MODULE_PERIPH_RTC */ -#endif /* MODULE_PM_LAYERED */ - -static int cmd_off(int argc, char **argv) -{ - (void) argc; - (void) argv; - - puts("CPU will turn off."); - fflush(stdout); - pm_off(); - - return 0; -} - -static int cmd_reboot(int argc, char **argv) -{ - (void) argc; - (void) argv; - - puts("CPU will reboot."); - fflush(stdout); - - pm_reboot(); - - return 0; -} - -#ifdef MODULE_PM_LAYERED -static int cmd_block(int argc, char **argv) -{ - if (check_mode(argc, argv) != 0) { - return 1; - } - - int mode = parse_mode(argv[1]); - - if (mode < 0) { - return 1; - } - - printf("Blocking power mode %d.\n", mode); - fflush(stdout); - - pm_block(mode); - - return 0; -} - -static int cmd_set(int argc, char **argv) -{ - if (check_mode(argc, argv) != 0) { - return 1; - } - - int mode = parse_mode(argv[1]); - - if (mode < 0) { - return 1; - } - - printf("CPU is entering power mode %d.\n", mode); - printf("Now waiting for a wakeup event...\n"); - 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(int argc, char **argv) -{ - if (check_mode(argc, argv) != 0) { - return 1; - } - - int mode = parse_mode(argv[1]); - - 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; -} - -#ifdef MODULE_PERIPH_RTC static int cmd_unblock_rtc(int argc, char **argv) { if (check_mode_duration(argc, argv) != 0) { @@ -248,15 +135,8 @@ static void btn_cb(void *ctx) * @brief List of shell commands for this example. */ static const shell_command_t shell_commands[] = { - { "off", "turn off", cmd_off }, - { "reboot", "reboot", cmd_reboot }, -#ifdef MODULE_PM_LAYERED - { "block", "block power mode", cmd_block }, - { "set", "set power mode", cmd_set }, - { "unblock", "unblock power mode", cmd_unblock }, -#ifdef MODULE_PERIPH_RTC - { "unblock_rtc", "temporary unblock power mode", cmd_unblock_rtc }, -#endif +#if defined MODULE_PM_LAYERED && defined MODULE_PERIPH_RTC + { "unblock_rtc", "temporarily unblock power mode", cmd_unblock_rtc }, #endif { NULL, NULL, NULL } }; @@ -280,7 +160,7 @@ int main(void) * the state of PM blockers so that the user will know which power mode has * been entered and is presumably responsible for the unresponsive shell. */ - _pm(2, (char *[]){"pm", "show"}); + _pm_handler(2, (char *[]){"pm", "show"}); #else puts("This application allows you to test the CPU power management.\n" From 804cc8cbd7186d56bec20167e524572e685f8569 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Tue, 28 Apr 2020 18:35:17 +0200 Subject: [PATCH 6/6] tests: add new boards in low memory blacklists --- tests/driver_sx127x/Makefile.ci | 2 ++ tests/gnrc_udp/Makefile.ci | 2 ++ tests/lwip/Makefile.ci | 2 ++ 3 files changed, 6 insertions(+) diff --git a/tests/driver_sx127x/Makefile.ci b/tests/driver_sx127x/Makefile.ci index 3585ad2b49c9..5bb8cf0dcdea 100644 --- a/tests/driver_sx127x/Makefile.ci +++ b/tests/driver_sx127x/Makefile.ci @@ -5,5 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega328p \ nucleo-f031k6 \ + nucleo-f042k6 \ + nucleo-l031k6 \ stm32f030f4-demo \ # diff --git a/tests/gnrc_udp/Makefile.ci b/tests/gnrc_udp/Makefile.ci index 6fa52d6a3373..69ee200e1ee7 100644 --- a/tests/gnrc_udp/Makefile.ci +++ b/tests/gnrc_udp/Makefile.ci @@ -7,6 +7,8 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + blackpill \ + bluepill \ calliope-mini \ chronos \ derfmega128 \ diff --git a/tests/lwip/Makefile.ci b/tests/lwip/Makefile.ci index a8f189bb5501..620aeed99a58 100644 --- a/tests/lwip/Makefile.ci +++ b/tests/lwip/Makefile.ci @@ -11,6 +11,8 @@ BOARD_INSUFFICIENT_MEMORY := \ nucleo-f334r8 \ nucleo-l031k6 \ nucleo-l053r8 \ + saml10-xpro \ + saml11-xpro \ stm32f030f4-demo \ stm32f0discovery \ stm32l0538-disco \