Skip to content

Commit 49a410b

Browse files
committed
Add documentation and test the HAL RTC API
Add requirements, tests, an example implementation and additional function documentation to the HAL RTC API.
1 parent f9d67db commit 49a410b

File tree

5 files changed

+528
-7
lines changed

5 files changed

+528
-7
lines changed

TESTS/host_tests/rtc_reset.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
"""
2+
mbed SDK
3+
Copyright (c) 2017-2017 ARM Limited
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
"""
17+
from __future__ import print_function
18+
19+
from mbed_host_tests import BaseHostTest
20+
from time import sleep
21+
22+
23+
class RtcResetTest(BaseHostTest):
24+
"""This test checks that a device's RTC keeps count through a reset
25+
26+
It does this by setting the RTC's time, triggering a reset,
27+
delaying and then reading the RTC's time again to ensure
28+
that the RTC is still counting.
29+
"""
30+
31+
"""Start of the RTC"""
32+
START_TIME = 50000
33+
START_TIME_TOLERANCE = 10
34+
"""Time to delay after sending reset"""
35+
DELAY_TIME = 4.0
36+
DELAY_TOLERANCE = 1.0
37+
VALUE_PLACEHOLDER = "0"
38+
39+
def setup(self):
40+
"""Register callbacks required for the test"""
41+
self._error = False
42+
generator = self.rtc_reset_test()
43+
generator.next()
44+
45+
def run_gen(key, value, time):
46+
"""Run the generator, and fail testing if the iterator stops"""
47+
if self._error:
48+
return
49+
try:
50+
print("Calling generator")
51+
generator.send((key, value, time))
52+
except StopIteration:
53+
self._error = True
54+
55+
for resp in ("start", "read"):
56+
self.register_callback(resp, run_gen)
57+
58+
def teardown(self):
59+
"""No work to do here"""
60+
pass
61+
62+
def rtc_reset_test(self):
63+
"""Generator for running the reset test
64+
65+
This function calls yield to wait for the next event from
66+
the device. If the device gives the wrong response, then the
67+
generator terminates by returing which raises a StopIteration
68+
exception and fails the test.
69+
"""
70+
71+
# Wait for start token
72+
key, value, time = yield()
73+
if key != "start":
74+
return
75+
76+
# Initialize, and set the time
77+
self.send_kv("init", self.VALUE_PLACEHOLDER)
78+
self.send_kv("write", str(self.START_TIME))
79+
self.send_kv("read", self.VALUE_PLACEHOLDER)
80+
key, value, time = yield()
81+
if key != "read":
82+
return
83+
dev_time_start = int(value)
84+
85+
# Unitialize, and reset
86+
self.send_kv("free", self.VALUE_PLACEHOLDER)
87+
self.send_kv("reset", self.VALUE_PLACEHOLDER)
88+
sleep(self.DELAY_TIME)
89+
90+
# Restart the test, and send the sync token
91+
self.send_kv("__sync", "00000000-0000-000000000-000000000000")
92+
key, value, time = yield()
93+
if key != "start":
94+
return
95+
96+
# Initialize, and read the time
97+
self.send_kv("init", self.VALUE_PLACEHOLDER)
98+
self.send_kv("read", self.VALUE_PLACEHOLDER)
99+
key, value, time = yield()
100+
if key != "read":
101+
return
102+
dev_time_end = int(value)
103+
104+
# Check result
105+
elapsed = dev_time_end - dev_time_start
106+
start_time_valid = (self.START_TIME <= dev_time_start <
107+
self.START_TIME + self.START_TIME_TOLERANCE)
108+
elapsed_time_valid = elapsed >= self.DELAY_TIME - self.DELAY_TOLERANCE
109+
passed = start_time_valid and elapsed_time_valid
110+
if not start_time_valid:
111+
self.log("FAIL: Expected start time of %i got %i" %
112+
(self.START_TIME, dev_time_start))
113+
elif not passed:
114+
self.log("FAIL: Delayed for %fs but device "
115+
"reported elapsed time of %fs" %
116+
(self.DELAY_TIME, elapsed))
117+
self.send_kv("exit", "pass" if passed else "fail")
118+
yield() # No more events expected
119+

TESTS/mbed_hal/rtc/main.cpp

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#if !DEVICE_RTC
18+
#error [NOT_SUPPORTED] RTC API not supported for this target
19+
#endif
20+
21+
#include "utest/utest.h"
22+
#include "unity/unity.h"
23+
#include "greentea-client/test_env.h"
24+
25+
#include "mbed.h"
26+
#include "rtc_api.h"
27+
#include "rtc_api_tests.h"
28+
29+
using namespace utest::v1;
30+
31+
static const uint32_t WAIT_TIME = 4;
32+
static const uint32_t WAIT_TOLERANCE = 1;
33+
34+
void rtc_init_test()
35+
{
36+
for (int i = 0; i < 10; i++) {
37+
rtc_init();
38+
}
39+
}
40+
41+
void rtc_sleep_test()
42+
{
43+
const uint32_t start = 100;
44+
rtc_init();
45+
46+
rtc_write(start);
47+
wait(WAIT_TIME);
48+
const uint32_t stop = rtc_read();
49+
50+
rtc_free();
51+
52+
TEST_ASSERT_UINT32_WITHIN(WAIT_TOLERANCE, WAIT_TIME, stop - start);
53+
}
54+
55+
void rtc_persist_test()
56+
{
57+
const uint32_t start = 100;
58+
rtc_init();
59+
rtc_write(start);
60+
rtc_free();
61+
62+
wait(WAIT_TIME);
63+
64+
rtc_init();
65+
const uint32_t stop = rtc_read();
66+
const int enabled = rtc_isenabled();
67+
rtc_free();
68+
69+
TEST_ASSERT_TRUE(enabled);
70+
TEST_ASSERT_UINT32_WITHIN(WAIT_TOLERANCE, WAIT_TIME, stop - start);
71+
}
72+
73+
void rtc_glitch_test()
74+
{
75+
const uint32_t start = 0xffffe;
76+
rtc_init();
77+
78+
rtc_write(start);
79+
uint32_t last = start;
80+
while (last < start + 4) {
81+
const uint32_t cur = rtc_read();
82+
TEST_ASSERT(cur >= last);
83+
last = cur;
84+
}
85+
86+
rtc_free();
87+
}
88+
89+
void rtc_range_test()
90+
{
91+
static const uint32_t starts[] = {
92+
0x00000000,
93+
0xEFFFFFFF,
94+
0x00001000,
95+
};
96+
97+
rtc_init();
98+
for (uint32_t i = 0; i < sizeof(starts) / sizeof(starts[0]); i++) {
99+
const uint32_t start = starts[i];
100+
rtc_write(start);
101+
wait(WAIT_TIME);
102+
const uint32_t stop = rtc_read();
103+
TEST_ASSERT_UINT32_WITHIN(WAIT_TOLERANCE, WAIT_TIME, stop - start);
104+
}
105+
rtc_free();
106+
}
107+
108+
Case cases[] = {
109+
Case("RTC - init", rtc_init_test),
110+
Case("RTC - sleep", rtc_sleep_test),
111+
Case("RTC - persist", rtc_persist_test),
112+
Case("RTC - glitch", rtc_glitch_test),
113+
Case("RTC - range", rtc_range_test),
114+
};
115+
116+
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
117+
GREENTEA_SETUP(30, "default_auto");
118+
return greentea_test_setup_handler(number_of_cases);
119+
}
120+
121+
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
122+
123+
int main() {
124+
Harness::run(specification);
125+
}

TESTS/mbed_hal/rtc_reset/main.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#if !DEVICE_RTC
18+
#error [NOT_SUPPORTED] RTC API not supported for this target
19+
#endif
20+
21+
#include "utest/utest.h"
22+
#include "unity/unity.h"
23+
#include "greentea-client/test_env.h"
24+
25+
#include "mbed.h"
26+
#include "rtc_api.h"
27+
#include "rtc_api_tests.h"
28+
29+
typedef enum {
30+
CMD_STATUS_PASS,
31+
CMD_STATUS_FAIL,
32+
CMD_STATUS_CONTINUE,
33+
CMD_STATUS_ERROR
34+
} cmd_status_t;
35+
36+
static cmd_status_t handle_command(const char *key, const char *value)
37+
{
38+
if (strcmp(key, "init") == 0) {
39+
rtc_init();
40+
return CMD_STATUS_CONTINUE;
41+
42+
} else if (strcmp(key, "free") == 0) {
43+
rtc_free();
44+
return CMD_STATUS_CONTINUE;
45+
46+
} else if (strcmp(key, "read") == 0) {
47+
static char time_buf[64];
48+
memset(time_buf, 0, sizeof(time_buf));
49+
sprintf(time_buf, "%lu", (uint32_t)rtc_read());
50+
greentea_send_kv("read", time_buf);
51+
return CMD_STATUS_CONTINUE;
52+
53+
} else if (strcmp(key, "write") == 0) {
54+
uint32_t time;
55+
sscanf(value, "%lu", &time);
56+
rtc_write(time);
57+
return CMD_STATUS_CONTINUE;
58+
59+
} else if (strcmp(key, "reset") == 0) {
60+
NVIC_SystemReset();
61+
// Code shouldn't read this due to the reset
62+
return CMD_STATUS_ERROR;
63+
64+
} else if (strcmp(key, "exit") == 0) {
65+
return strcmp(value, "pass") == 0 ? CMD_STATUS_PASS : CMD_STATUS_FAIL;
66+
67+
} else {
68+
return CMD_STATUS_ERROR;
69+
70+
}
71+
}
72+
73+
void rtc_reset_test()
74+
{
75+
GREENTEA_SETUP(60, "rtc_reset");
76+
77+
static char _key[10 + 1] = {};
78+
static char _value[128 + 1] = {};
79+
80+
greentea_send_kv("start", 1);
81+
82+
// Handshake with host
83+
cmd_status_t cmd_status = CMD_STATUS_CONTINUE;
84+
while (CMD_STATUS_CONTINUE == cmd_status) {
85+
memset(_key, 0, sizeof(_key));
86+
memset(_value, 0, sizeof(_value));
87+
greentea_parse_kv(_key, _value, sizeof(_key) - 1, sizeof(_value) - 1);
88+
cmd_status = handle_command(_key, _value);
89+
}
90+
91+
GREENTEA_TESTSUITE_RESULT(CMD_STATUS_PASS == cmd_status);
92+
}
93+
94+
int main()
95+
{
96+
rtc_reset_test();
97+
}

0 commit comments

Comments
 (0)