Skip to content

Update of RTC HAL API specification and tests. #5306

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

Merged
Show file tree
Hide file tree
Changes from all 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
153 changes: 140 additions & 13 deletions TESTS/mbed_hal/rtc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,96 @@
#include "mbed.h"
#include "rtc_api.h"


using namespace utest::v1;

static const uint32_t WAIT_TIME = 4;
static const uint32_t WAIT_TOLERANCE = 1;

#define US_PER_SEC 1000000
#define ACCURACY_FACTOR 10

void rtc_init_test()
static const uint32_t DELAY_4S = 4;
static const uint32_t DELAY_10S = 10;
static const uint32_t RTC_TOLERANCE = 1;
static const uint32_t TOLERANCE_ACCURACY_US = (DELAY_10S * US_PER_SEC / ACCURACY_FACTOR);

#if DEVICE_LOWPOWERTIMER
volatile bool expired;

void callback(void)
{
for (int i = 0; i < 10; i++) {
rtc_init();
}
expired = true;
}

void rtc_sleep_test()
/* Auxiliary function to test if RTC continue counting in
* sleep and deep-sleep modes. */
void rtc_sleep_test_support (bool deepsleep_mode)
{
LowPowerTimeout timeout;
const uint32_t start = 100;
expired = false;

/*
* Since deepsleep() may shut down the UART peripheral, we wait for 10ms
* to allow for hardware serial buffers to completely flush.
* This should be replaced with a better function that checks if the
* hardware buffers are empty. However, such an API does not exist now,
* so we'll use the wait_ms() function for now.
*/
wait_ms(10);

rtc_init();

if(deepsleep_mode == false) {
sleep_manager_lock_deep_sleep();
}

rtc_write(start);
wait(WAIT_TIME);

timeout.attach(callback, DELAY_4S);

TEST_ASSERT(sleep_manager_can_deep_sleep() == deepsleep_mode);

while(!expired) sleep();

const uint32_t stop = rtc_read();

TEST_ASSERT_UINT32_WITHIN(RTC_TOLERANCE, DELAY_4S, stop - start);

timeout.detach();

if(deepsleep_mode == false) {
sleep_manager_unlock_deep_sleep();
}

rtc_free();
}
#endif

TEST_ASSERT_UINT32_WITHIN(WAIT_TOLERANCE, WAIT_TIME, stop - start);
/* Test that ::rtc_init can be called multiple times. */
void rtc_init_test()
{
for (int i = 0; i < 10; i++) {
rtc_init();
Copy link
Member

Choose a reason for hiding this comment

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

I think we could check if it actually continue working.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test case only checks if init can be called multiple times. rtc_persist_test() verifies if RTC still counts after free/init.

}

rtc_free();
}

#if DEVICE_LOWPOWERTIMER
/** Test that the RTC keeps counting in the various sleep modes. */

void rtc_sleep_test()
{
/* Test sleep mode. */
rtc_sleep_test_support(false);

/* Test deep-sleep mode. */
rtc_sleep_test_support(true);
}
#endif

/* Test that the RTC keeps counting even after ::rtc_free has been called. */
void rtc_persist_test()
{
const uint32_t start = 100;
Expand All @@ -72,6 +134,7 @@ void rtc_persist_test()
TEST_ASSERT_UINT32_WITHIN(WAIT_TOLERANCE, WAIT_TIME, stop - start);
}

/* Test time does not glitch backwards due to an incorrectly implemented ripple counter driver. */
void rtc_glitch_test()
{
const uint32_t start = 0xffffe;
Expand All @@ -88,12 +151,14 @@ void rtc_glitch_test()
rtc_free();
}

/* Test that the RTC correctly handles different time values. */
void rtc_range_test()
{
static const uint32_t starts[] = {
0x00000000,
0xEFFFFFFF,
0x00001000,
0x00000000,
0xEFFFFFFF,
0x00001000,
0x00010000,
};

rtc_init();
Expand All @@ -107,21 +172,83 @@ void rtc_range_test()
rtc_free();
}

/* Test that the RTC accuracy is at least 10%. */
void rtc_accuracy_test()
{
Timer timer1;

const uint32_t start = 100;
rtc_init();
rtc_write(start);

timer1.start();
while(rtc_read() < (start + DELAY_10S)) {
/* Just wait. */
}
timer1.stop();

/* RTC accuracy is at least 10%. */
TEST_ASSERT_INT32_WITHIN(TOLERANCE_ACCURACY_US, DELAY_10S * US_PER_SEC, timer1.read_us());
}

/* Test that ::rtc_write/::rtc_read functions provides availability to set/get RTC time. */
void rtc_write_read_test()
{
static const uint32_t rtc_init_val = 100;

rtc_init();

for (int i = 0; i < 3; i++) {
const uint32_t init_val = (rtc_init_val + i * rtc_init_val);

core_util_critical_section_enter();

rtc_write(init_val);
const uint32_t read_val = rtc_read();

core_util_critical_section_exit();

/* No tolerance is provided since we should have 1 second to
* execute this case after the RTC time is set.
*/
TEST_ASSERT_EQUAL_UINT32(init_val, read_val);
}

rtc_free();
}

/* Test that ::is_enabled function returns 1 if the RTC is counting and the time has been set, 0 otherwise. */
void rtc_enabled_test()
{
rtc_init();
TEST_ASSERT_EQUAL_INT(0, rtc_isenabled());
rtc_write(0);
TEST_ASSERT_EQUAL_INT(1, rtc_isenabled());
rtc_free();
}

Case cases[] = {
Case("RTC - init", rtc_init_test),
#if DEVICE_LOWPOWERTIMER
Case("RTC - sleep", rtc_sleep_test),
#endif
Case("RTC - persist", rtc_persist_test),
Case("RTC - glitch", rtc_glitch_test),
Case("RTC - range", rtc_range_test),
Case("RTC - accuracy", rtc_accuracy_test),
Case("RTC - write/read", rtc_write_read_test),
Case("RTC - enabled", rtc_enabled_test),
};

utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(30, "default_auto");
return greentea_test_setup_handler(number_of_cases);
}

Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);

int main() {
int main()
{
Harness::run(specification);
}
68 changes: 60 additions & 8 deletions TESTS/mbed_hal/rtc/rtc_test.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/** \addtogroup hal_rtc_tests
* @{
*/
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
*
Expand All @@ -16,6 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** \addtogroup hal_rtc_tests
* @{
*/

#ifndef MBED_RTC_TEST_H
#define MBED_RTC_TEST_H

Expand All @@ -25,31 +27,81 @@
extern "C" {
#endif

/** Test that ::rtc_init can be called multiple times
/** Test that ::rtc_init can be called multiple times.
*
* Given board provides RTC.
* When ::rtc_init is called multiple times.
* Then ::rtc_init are successfully performed (no exception is generated).
*
*/
void rtc_init_test(void);

/** Test that the RTC keeps counting in the various sleep modes
/** Test that the RTC keeps counting in the various sleep modes.
*
* Given board provides RTC.
* When system enters sleep/deep-sleep mode.
* RTC keeps counting.
*
*/
void rtc_sleep_test(void);

/** Test that the RTC keeps counting even after ::rtc_free has been called
/** Test that the RTC keeps counting even after ::rtc_free has been called.
*
* Given board provides RTC.
* When ::rtc_free has been called.
* RTC keeps counting.
*
*/
void rtc_persist_test(void);

/** Test time does not glitch backwards due to an incorrectly implemented ripple counter driver
/** Test time does not glitch backwards due to an incorrectly implemented ripple counter driver.
*
* Given board provides RTC.
* When RTC is enabled and counts.
* Then time does not glitch backwards due to an incorrectly implemented ripple counter driver.
*
*/
void rtc_glitch_test(void);

/** Test that the RTC correctly handles large time values
/** Test that the RTC correctly handles large time values.
*
* Given board provides RTC.
* When RTC is enabled and counts.
* The RTC correctly handles different time values.
*/
void rtc_range_test(void);

/** Test that the RTC accuracy is at least 10%.
*
* Given platform provides Real Time Clock.
* When delay is performed based on RTC (10 sec delay).
* Then the delay time measured using high frequency timer indicate that RTC accuracy is at least 10%.
*
*/
void rtc_accuracy_test(void);

/** Test that ::rtc_write/::rtc_read functions provides availability to set/get RTC time.
*
* Given platform provides Real Time Clock.
* When an example RTC time is set by means of rtc_write function and rtc_read is performed immediately after this operation.
* Then rtc_read function returns time which has been set.
*
*/
void rtc_write_read_test(void);

/** Test that ::rtc_isenabled function returns 1 if the RTC is counting and the time has been set, 0 otherwise
*
* NOTE: RTC is counting when it has been initialised by means of rtc_init().
* RTC time is set by means of rtc_write() function.
* RTC must be initialised before rtc_isenabled() function can be called.
*
* Given platform provides Real Time Clock.
* When rtc_isenabled() function is called.
* Then the result is 1 if RTC time has been set, otherwise the result is 0.
*
*/
void rtc_enabled_test(void);

/**@}*/

#ifdef __cplusplus
Expand Down
1 change: 1 addition & 0 deletions TESTS/mbed_hal/rtc_reset/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static cmd_status_t handle_command(const char *key, const char *value)
}
}

/* Test that software reset doesn't stop RTC from counting. */
void rtc_reset_test()
{
GREENTEA_SETUP(60, "rtc_reset");
Expand Down
13 changes: 11 additions & 2 deletions TESTS/mbed_hal/rtc_reset/rtc_reset_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** \addtogroup hal_rtc_tests
* @{
*/

#ifndef MBED_RTC_TEST_H
#define MBED_RTC_TEST_H

Expand All @@ -22,8 +27,12 @@
extern "C" {
#endif

/** Test that the RTC does not stop counting after a software reset
* \ingroup hal_rtc_tests
/** Test that the RTC does not stop counting after a software reset.
*
* Given board provides RTC.
* When software reset is performed.
* Then the RTC does not stop counting.
*
*/
void rtc_reset_test();

Expand Down
Loading