This repository has been archived by the owner on Sep 20, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 36
bench_pm: Helper application for testing pm behavior #55
Open
jnohlgard
wants to merge
6
commits into
RIOT-OS:master
Choose a base branch
from
jnohlgard:bench_pm
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
298a08f
bench_pm: Helper application for testing pm behavior
00643c7
fixup! bench_pm: Helper application for testing pm behavior
9f088b0
squash bench_pm Update configuration macros
668e89f
bench_pm: conditionally define test pins
26a439d
bench_pm: implement coma mode
ddcc6ab
squash bench_pm: Clean up defines
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
APPLICATION = bench_pm | ||
BOARD ?= frdm-kw41z | ||
|
||
RIOTBASE ?= $(CURDIR)/../../RIOT | ||
QUIET ?= 1 | ||
DEVELHELP ?= 1 | ||
|
||
FEATURES_OPTIONAL = periph_rtt periph_gpio_irq | ||
|
||
# Disable auto_init to avoid starting any extra services | ||
DISABLE_MODULE += auto_init | ||
|
||
include $(RIOTBASE)/Makefile.include |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
Purpose | ||
======= | ||
|
||
This project is used to provide a baseline for the power consumption of the | ||
platform when no software is interfering with the low power modes. The | ||
application is designed to be used as a test subject for measuring power | ||
consumption and timing of low power modes. | ||
|
||
Hardware requirements | ||
===================== | ||
|
||
The data collection relies on external measurement equipment. An oscilloscope, | ||
or logic analyzer and a multimeter is required for any meaningful measurements. | ||
|
||
Test outputs | ||
============ | ||
|
||
The test uses the board's LED0, LED1 pins as feedback from the application to | ||
the logic analyzer to signal when a low power mode is exited. | ||
The wake up request is triggered by UART RX activity, or a configurable GPIO pin. | ||
|
||
Set up | ||
====== | ||
|
||
Connect the logic analyzer to trigger on the chosen GPIO wake pin (or UART RX | ||
pin, if not using the GPIO), connect the LED0 pin to the logic analyzer as well. | ||
|
||
The LED0 pin will be asserted immediately when control returns to the main thread. | ||
The LED1 pin is asserted by the ISR. | ||
|
||
Tested hardware | ||
=============== | ||
|
||
The application is designed to run on the FRDM-KW41Z (or a custom R41Z board), | ||
but some care has been taken to allow building for different platforms without | ||
any major changes. | ||
|
||
Future work | ||
=========== | ||
|
||
The logic analyzer requirement could be eliminated by creating a measurement | ||
application which can run on a different board for driving the test and taking | ||
measurements. |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
/* | ||
* Copyright (C) 2017-2018 SKF AB | ||
* Copyright (C) 2014 Freie Universität Berlin | ||
* | ||
* 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 tests | ||
* @{ | ||
* | ||
* @file | ||
* @brief Test for low power modes and wake up timings | ||
* | ||
* This test will switch to different low power modes and wait for wake events. | ||
* | ||
* @author Joakim Nohlgård <[email protected]> | ||
* | ||
* @} | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdint.h> | ||
|
||
#include "cpu.h" | ||
#include "board.h" | ||
#include "periph_conf.h" | ||
#include "periph/rtt.h" | ||
#ifdef MODULE_PM_LAYERED | ||
#include "pm_layered.h" | ||
#endif | ||
#ifdef MODULE_PERIPH_GPIO_IRQ | ||
#include "periph/gpio.h" | ||
#endif | ||
#ifdef MODULE_PERIPH_LLWU | ||
/* Kinetis specific low leakage mode handling */ | ||
#include "llwu.h" | ||
#endif | ||
|
||
#ifndef ENABLE_DEBUG | ||
/* Enabling debug prints will affect timing measurements */ | ||
#define ENABLE_DEBUG (0) | ||
#endif | ||
#include "debug.h" | ||
|
||
#if COMA_MODE | ||
/* For testing deepest low power modes without any interference */ | ||
#undef MODULE_PERIPH_GPIO_IRQ | ||
#undef MODULE_PERIPH_RTT | ||
#undef MODULE_PERIPH_LLWU | ||
#undef LED0_ON | ||
#undef LED1_ON | ||
#endif | ||
|
||
#ifdef MODULE_PERIPH_RTT | ||
#define PRINT_RTT() (printf("RTT: %" PRIu32 "\n", rtt_get_counter())) | ||
#else | ||
#define PRINT_RTT() | ||
#endif | ||
|
||
#ifdef MODULE_PERIPH_GPIO_IRQ | ||
#ifndef GPIO_WAKE_PIN | ||
#ifdef BTN0_PIN | ||
#define GPIO_WAKE_PIN BTN0_PIN | ||
#else | ||
#error Missing GPIO_WAKE_PIN configuration | ||
#endif /* BTN0_PIN */ | ||
#endif /* GPIO_WAKE_PIN */ | ||
#endif /* MODULE_PERIPH_GPIO_IRQ */ | ||
|
||
#ifdef MODULE_PERIPH_LLWU | ||
/* Platform specific configuration for testing Kinetis low leakage wake up module (LLWU) */ | ||
#ifndef LLWU_WAKE_PIN | ||
/* This macro should correspond to the pin used in the GPIO_WAKE_PIN macro */ | ||
#if defined(BOARD_FRDM_KW41Z) | ||
#define LLWU_WAKE_PIN LLWU_WAKEUP_PIN_PTC4 | ||
#elif defined(BOARD_FRDM_K22F) | ||
#define LLWU_WAKE_PIN LLWU_WAKEUP_PIN_PTC1 | ||
#elif defined(BOARD_FRDM_K64F) | ||
#define LLWU_WAKE_PIN LLWU_WAKEUP_PIN_PTC6 | ||
#endif | ||
#endif /* LLWU_WAKE_PIN */ | ||
#endif /* MODULE_PERIPH_LLWU */ | ||
|
||
#ifndef TEST_PIN_ON | ||
#ifdef LED0_ON | ||
#define TEST_PIN_ON LED0_ON | ||
#define TEST_PIN_OFF LED0_OFF | ||
#else | ||
#define TEST_PIN_ON | ||
#define TEST_PIN_OFF | ||
#endif /* LED0_ON */ | ||
#endif /* TEST_PIN_ON */ | ||
|
||
#ifndef TEST_ISR_PIN_ON | ||
#ifdef LED1_ON | ||
#define TEST_ISR_PIN_ON LED1_ON | ||
#define TEST_ISR_PIN_OFF LED1_OFF | ||
#else | ||
#define TEST_ISR_PIN_ON | ||
#define TEST_ISR_PIN_OFF | ||
#endif /* LED1_ON */ | ||
#endif /* TEST_ISR_PIN_ON */ | ||
|
||
#ifdef MODULE_PERIPH_RTT | ||
#define TICKS_TO_WAIT (10 * RTT_FREQUENCY) | ||
#endif /* MODULE_PERIPH_RTT */ | ||
|
||
static volatile unsigned busy = 0; | ||
|
||
#ifdef MODULE_PERIPH_RTT | ||
static void cb_rtt(void *arg) | ||
{ | ||
(void)arg; | ||
TEST_ISR_PIN_ON; | ||
DEBUG("RTT IRQ\n"); | ||
|
||
busy = 0; | ||
} | ||
#endif /* MODULE_PERIPH_RTT */ | ||
|
||
#ifdef MODULE_PERIPH_LLWU | ||
static void cb_llwu(void *arg) | ||
{ | ||
(void)arg; | ||
TEST_ISR_PIN_ON; | ||
DEBUG("llwu pin\n"); | ||
|
||
busy = 0; | ||
} | ||
#endif /* MODULE_PERIPH_LLWU */ | ||
|
||
#ifdef MODULE_PERIPH_GPIO_IRQ | ||
static void cb_gpio(void *arg) | ||
{ | ||
(void)arg; | ||
TEST_ISR_PIN_ON; | ||
DEBUG("gpio pin\n"); | ||
|
||
busy = 0; | ||
} | ||
#endif /* MODULE_PERIPH_GPIO_IRQ */ | ||
|
||
int main(void) | ||
{ | ||
TEST_PIN_ON; | ||
puts("\nRIOT power consumption and wake timing test application"); | ||
|
||
#ifdef MODULE_PERIPH_LLWU | ||
/* Kinetis specific */ | ||
puts("Enable LLWU wake up from RTC"); | ||
llwu_wakeup_module_enable(LLWU_WAKEUP_MODULE_RTC_ALARM); | ||
puts("Enable LLWU IRQ on PTC4 (SW4) falling"); | ||
gpio_init(GPIO_WAKE_PIN, GPIO_IN); | ||
llwu_wakeup_pin_set(LLWU_WAKE_PIN, LLWU_WAKEUP_EDGE_FALLING, cb_llwu, NULL); | ||
#endif /* MODULE_PERIPH_LLWU */ | ||
|
||
#ifdef MODULE_PERIPH_GPIO_IRQ | ||
puts("Enable GPIO IRQ on PTC4 (SW4) falling"); | ||
int res = gpio_init_int(GPIO_WAKE_PIN, GPIO_IN_PU, GPIO_FALLING, cb_gpio, NULL); | ||
if (res != 0) { | ||
printf("!! gpio_init_int: %d\n", res); | ||
} | ||
#endif /* MODULE_PERIPH_GPIO_IRQ */ | ||
|
||
#ifdef MODULE_PERIPH_RTT | ||
puts("Initializing the RTT driver"); | ||
rtt_init(); | ||
#endif /* MODULE_PERIPH_RTT */ | ||
|
||
#if ENABLE_CLKOUT | ||
/* Kinetis specific, clock monitor via CLKOUT on pin PTB3 */ | ||
puts("Enable CLKOUT on PTB3"); | ||
PORTB->PCR[3] = PORT_PCR_MUX(4); | ||
/* Select which clock to output */ | ||
SIM->SOPT2 = (SIM->SOPT2 & ~SIM_SOPT2_CLKOUTSEL_MASK) | SIM_SOPT2_CLKOUTSEL(2); | ||
/* Use a logic analyzer or oscilloscope to look at the signal */ | ||
#endif | ||
|
||
#if COMA_MODE | ||
puts("Coma mode, going to pm_set(0), not coming back"); | ||
while (1) { | ||
pm_set(0); | ||
puts("woke up unexpectedly, going to pm_set(0)"); | ||
} | ||
#endif | ||
|
||
while (1) { | ||
PRINT_RTT(); | ||
puts("Busy spin"); | ||
{ | ||
#ifdef MODULE_PERIPH_RTT | ||
uint32_t rtt_target = rtt_get_counter() + TICKS_TO_WAIT; | ||
rtt_target &= RTT_MAX_VALUE; | ||
rtt_set_alarm(rtt_target, cb_rtt, 0); | ||
#endif /* MODULE_PERIPH_RTT */ | ||
busy = 1; | ||
TEST_PIN_OFF; | ||
TEST_ISR_PIN_OFF; | ||
while (busy) { | ||
__asm__ volatile ("" ::: "memory"); | ||
} | ||
TEST_PIN_ON; | ||
PRINT_RTT(); | ||
} | ||
#ifdef MODULE_PM_LAYERED | ||
for (int k = PM_NUM_MODES; 0 <= k; --k) { | ||
#ifdef MODULE_PERIPH_RTT | ||
uint32_t rtt_target = rtt_get_counter() + TICKS_TO_WAIT; | ||
rtt_target &= RTT_MAX_VALUE; | ||
rtt_set_alarm(rtt_target, cb_rtt, 0); | ||
#endif /* MODULE_PERIPH_RTT */ | ||
PRINT_RTT(); | ||
printf("pm_set(%d)\n", k); | ||
TEST_PIN_OFF; | ||
TEST_ISR_PIN_OFF; | ||
pm_set((unsigned)k); | ||
TEST_PIN_ON; | ||
printf("wake from %d\n", k); | ||
} | ||
#endif | ||
} | ||
return 0; | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've had some boards that made it really difficult to re-attach a debugger when going to deep sleep too fast.
Could we maybe guard this, either by a second delay or using something like
while (gpio_read(BUTTON1)) {}
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like, the only way was to do "while true; do make -C examples/hello-world flash; done" and hammering the reset button, hoping to hop into the short time from reset to CPU stop...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And reset_config connect_assert_srst and a recent openocd did not help?
(including the important improvement bb976e3c387bc82e20ab7304f0cfac3e5eede3a1 in https://repo.or.cz/openocd.git/commit/bb976e3c387bc82e20ab7304f0cfac3e5eede3a1 if you are using a CMSIS-DAP debugger)