Skip to content

Commit 9073a48

Browse files
authored
Merge pull request ARMmbed#13489 from rajkan01/hal_directory_restructuring
Refactor hal directory
2 parents 29f54fe + fafa0c4 commit 9073a48

File tree

147 files changed

+1050
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+1050
-5
lines changed

.codecheckignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
^storage/filesystem/littlefsv2/littlefs/
1818
^features/unsupported/
1919
^hal/storage_abstraction
20+
^hal/tests/TESTS/mbed_hal/trng/pithy
21+
^hal/tests/TESTS/mbed_hal/trng/pithy
2022
^platform/cxxsupport
2123
^platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV
2224
^platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM
@@ -25,8 +27,6 @@
2527
^rtos/source/TARGET_CORTEX/rtx4
2628
^rtos/source/TARGET_CORTEX/rtx5
2729
^targets
28-
^TESTS/mbed_hal/trng/pithy
29-
^TESTS/mbed_hal/trng/pithy
3030
^tools
3131
^UNITTESTS
3232
^storage/blockdevice/tests/UNITTESTS

UNITTESTS/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ set(unittest-includes-base
126126
"${PROJECT_SOURCE_DIR}/../drivers/include/drivers"
127127
"${PROJECT_SOURCE_DIR}/../drivers/include/drivers/internal"
128128
"${PROJECT_SOURCE_DIR}/../hal"
129+
"${PROJECT_SOURCE_DIR}/../hal/include"
129130
"${PROJECT_SOURCE_DIR}/../events/include"
130131
"${PROJECT_SOURCE_DIR}/../events/include/events/internal"
131132
"${PROJECT_SOURCE_DIR}/../events/source"

UNITTESTS/stubs/us_ticker_stub.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
#include "stdlib.h"
20-
#include "us_ticker_api.h"
20+
#include "hal/us_ticker_api.h"
2121

2222
const ticker_data_t *get_us_ticker_data(void)
2323
{

UNITTESTS/stubs/watchdog_api_stub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
#include "watchdog_api.h"
17+
#include "hal/watchdog_api.h"
1818

1919
#if DEVICE_WATCHDOG
2020

UNITTESTS/target_h/PinNames.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ typedef enum {
4747
#ifdef __cplusplus
4848
}
4949
#endif
50-
#include "pinmap.h"
50+
#include "hal/pinmap.h"
5151

5252
#endif
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
"""
2+
Copyright (c) 2018-2019 Arm Limited and affiliates.
3+
SPDX-License-Identifier: Apache-2.0
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+
import time
18+
from mbed_host_tests import BaseHostTest
19+
20+
DEFAULT_SYNC_DELAY = 4.0
21+
22+
MSG_VALUE_WATCHDOG_PRESENT = 1
23+
MSG_VALUE_DUMMY = '0'
24+
MSG_VALUE_RESET_REASON_GET = 'get'
25+
MSG_VALUE_RESET_REASON_CLEAR = 'clear'
26+
MSG_VALUE_DEVICE_RESET_NVIC = 'nvic'
27+
MSG_VALUE_DEVICE_RESET_WATCHDOG = 'watchdog'
28+
29+
MSG_KEY_DEVICE_READY = 'ready'
30+
MSG_KEY_RESET_REASON_RAW = 'reason_raw'
31+
MSG_KEY_RESET_REASON = 'reason'
32+
MSG_KEY_DEVICE_RESET = 'reset'
33+
MSG_KEY_SYNC = '__sync'
34+
MSG_KEY_RESET_COMPLETE = 'reset_complete'
35+
36+
RESET_REASONS = {
37+
'POWER_ON': '0',
38+
'PIN_RESET': '1',
39+
'BROWN_OUT': '2',
40+
'SOFTWARE': '3',
41+
'WATCHDOG': '4',
42+
'LOCKUP': '5',
43+
'WAKE_LOW_POWER': '6',
44+
'ACCESS_ERROR': '7',
45+
'BOOT_ERROR': '8',
46+
'MULTIPLE': '9',
47+
'PLATFORM': '10',
48+
'UNKNOWN': '11'
49+
}
50+
51+
52+
def raise_if_different(expected, actual, text=''):
53+
"""Raise a RuntimeError if actual is different than expected."""
54+
if expected != actual:
55+
raise RuntimeError('{}Got {!r}, expected {!r}'
56+
.format(text, actual, expected))
57+
58+
59+
class ResetReasonTest(BaseHostTest):
60+
"""Test for the Reset Reason HAL API.
61+
62+
Given a device supporting a Reset Reason API.
63+
When the device is restarted using various methods.
64+
Then the device returns a correct reset reason for every restart.
65+
"""
66+
67+
def __init__(self):
68+
super(ResetReasonTest, self).__init__()
69+
self.device_reasons = None
70+
self.device_has_watchdog = None
71+
self.raw_reset_reasons = set()
72+
self.sync_delay = DEFAULT_SYNC_DELAY
73+
self.test_steps_sequence = self.test_steps()
74+
# Advance the coroutine to it's first yield statement.
75+
self.test_steps_sequence.send(None)
76+
77+
def setup(self):
78+
sync_delay = self.get_config_item('forced_reset_timeout')
79+
self.sync_delay = sync_delay if sync_delay is not None else DEFAULT_SYNC_DELAY
80+
self.register_callback(MSG_KEY_DEVICE_READY, self.cb_device_ready)
81+
self.register_callback(MSG_KEY_RESET_REASON_RAW, self.cb_reset_reason_raw)
82+
self.register_callback(MSG_KEY_RESET_REASON, self.cb_reset_reason)
83+
self.register_callback(MSG_KEY_DEVICE_RESET, self.cb_reset_reason)
84+
self.register_callback(MSG_KEY_RESET_COMPLETE, self.cb_reset_reason)
85+
86+
def cb_device_ready(self, key, value, timestamp):
87+
"""Request a raw value of the reset_reason register.
88+
89+
Additionally, save the device's reset_reason capabilities
90+
and the watchdog status on the first call.
91+
"""
92+
if self.device_reasons is None:
93+
reasons, wdg_status = (int(i, base=16) for i in value.split(','))
94+
self.device_has_watchdog = (wdg_status == MSG_VALUE_WATCHDOG_PRESENT)
95+
self.device_reasons = [k for k, v in RESET_REASONS.items() if (reasons & 1 << int(v))]
96+
self.send_kv(MSG_KEY_RESET_REASON_RAW, MSG_VALUE_RESET_REASON_GET)
97+
98+
def cb_reset_reason_raw(self, key, value, timestamp):
99+
"""Verify that the raw reset_reason register value is unique.
100+
101+
Fail the test suite if the raw reset_reason value is not unique.
102+
Request a platform independent reset_reason otherwise.
103+
"""
104+
if value in self.raw_reset_reasons:
105+
self.log('TEST FAILED: The raw reset reason is not unique. '
106+
'{!r} is already present in {!r}.'
107+
.format(value, self.raw_reset_reasons))
108+
self.notify_complete(False)
109+
else:
110+
self.raw_reset_reasons.add(value)
111+
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_GET)
112+
113+
def cb_reset_reason(self, key, value, timestamp):
114+
"""Feed the test_steps coroutine with reset_reason value.
115+
116+
Pass the test suite if the coroutine yields True.
117+
Fail the test suite if the iterator stops or raises a RuntimeError.
118+
"""
119+
try:
120+
if self.test_steps_sequence.send(value):
121+
self.notify_complete(True)
122+
except (StopIteration, RuntimeError) as exc:
123+
self.log('TEST FAILED: {}'.format(exc))
124+
self.notify_complete(False)
125+
126+
def test_steps(self):
127+
"""Generate a sequence of test steps.
128+
129+
This coroutine calls yield to wait for the input from the device
130+
(the reset_reason). If the device gives the wrong response, the
131+
generator raises a RuntimeError exception and fails the test.
132+
"""
133+
# Ignore the first reason.
134+
__ignored_reset_reason = yield
135+
self.raw_reset_reasons.clear()
136+
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
137+
__ignored_clear_ack = yield
138+
139+
# Request a NVIC_SystemReset() call.
140+
expected_reason = 'SOFTWARE'
141+
if expected_reason not in self.device_reasons:
142+
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason))
143+
else:
144+
# Request a NVIC_SystemReset() call.
145+
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_NVIC)
146+
__ignored_reset_ack = yield
147+
time.sleep(self.sync_delay)
148+
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
149+
reset_reason = yield
150+
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ')
151+
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
152+
__ignored_clear_ack = yield
153+
154+
# Reset the device using DAP.
155+
expected_reason = 'PIN_RESET'
156+
if expected_reason not in self.device_reasons:
157+
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason))
158+
else:
159+
self.reset()
160+
__ignored_reset_ack = yield # 'reset_complete'
161+
time.sleep(self.sync_delay)
162+
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
163+
reset_reason = yield
164+
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ')
165+
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
166+
__ignored_clear_ack = yield
167+
168+
# Start a watchdog timer and wait for it to reset the device.
169+
expected_reason = 'WATCHDOG'
170+
if expected_reason not in self.device_reasons or not self.device_has_watchdog:
171+
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason))
172+
else:
173+
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_WATCHDOG)
174+
__ignored_reset_ack = yield
175+
time.sleep(self.sync_delay)
176+
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
177+
reset_reason = yield
178+
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ')
179+
180+
# The sequence is correct -- test passed.
181+
yield True
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
"""
2+
Copyright (c) 2011-2020, Arm Limited and affiliates
3+
SPDX-License-Identifier: Apache-2.0
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+
18+
from mbed_host_tests import BaseHostTest
19+
import time
20+
import calendar
21+
import datetime
22+
23+
class RTC_time_calc_test(BaseHostTest):
24+
"""
25+
This is the host part of the test to verify if:
26+
- _rtc_mktime function converts a calendar time into time since UNIX epoch as a time_t,
27+
- _rtc_localtime function converts a given time in seconds since epoch into calendar time.
28+
29+
The same algoritm to generate next calendar time to be tested is used by both parts of the test.
30+
We will check if correct time since UNIX epoch is calculated for the first and the last day
31+
of each month and across valid years.
32+
33+
Mbed part of the test sends calculated time since UNIX epoch.
34+
This part validates given value and responds to indicate pass or fail.
35+
Additionally it sends also encoded day of week and day of year which
36+
will be needed to verify _rtc_localtime.
37+
38+
Support for both types of RTC devices is provided:
39+
- RTCs which handles all leap years in the mentioned year range correctly. Leap year is determined by checking if
40+
the year counter value is divisible by 400, 100, and 4. No problem here.
41+
- RTCs which handles leap years correctly up to 2100. The RTC does a simple bit comparison to see if the two
42+
lowest order bits of the year counter are zero. In this case 2100 year will be considered
43+
incorrectly as a leap year, so the last valid point in time will be 28.02.2100 23:59:59 and next day will be
44+
29.02.2100 (invalid). So after 28.02.2100 the day counter will be off by a day.
45+
46+
"""
47+
48+
edge_date = datetime.datetime(2100, 2, 28, 0, 0, 0)
49+
50+
# Test the following years:
51+
# - first - 1970
52+
# - example not leap year (not divisible by 4)
53+
# - example leap year (divisible by 4 and by 100 and by 400)
54+
# - example leap year (divisible by 4 and not by 100)
55+
# - example not leap year (divisible by 4 and by 100)
56+
# - last fully supported - 2105
57+
years = [1970, 1971, 2000, 2096, 2100, 2105]
58+
year_id = 0
59+
60+
61+
62+
full_leap_year_support = False
63+
64+
RTC_FULL_LEAP_YEAR_SUPPORT = 0
65+
RTC_PARTIAL_LEAP_YEAR_SUPPORT = 1
66+
67+
def _set_leap_year_support(self, key, value, timestamp):
68+
if (int(value) == self.RTC_FULL_LEAP_YEAR_SUPPORT):
69+
self.full_leap_year_support = True
70+
else:
71+
self.full_leap_year_support = False
72+
73+
self.first = True
74+
self.date = datetime.datetime(1970, 1, 1, 23, 0, 0)
75+
self.year_id = 0
76+
77+
def _verify_timestamp(self, key, value, timestamp):
78+
# week day in python is counted from sunday(0) and on mbed side week day is counted from monday(0).
79+
# year day in python is counted from 1 and on mbed side year day is counted from 0.
80+
week_day = ((self.date.timetuple().tm_wday + 1) % 7)
81+
year_day = self.date.timetuple().tm_yday - 1
82+
83+
# Fix for RTC which not have full leap year support.
84+
if (not self.full_leap_year_support):
85+
if self.date >= self.edge_date:
86+
# After 28.02.2100 we should be one day off - add this day and store original
87+
date_org = self.date
88+
self.date += datetime.timedelta(days = 1)
89+
90+
# Adjust week day.
91+
week_day = ((self.date.timetuple().tm_wday + 1) % 7)
92+
93+
# Adjust year day.
94+
if (self.date.year == 2100):
95+
year_day = self.date.timetuple().tm_yday - 1
96+
else:
97+
year_day = date_org.timetuple().tm_yday - 1
98+
99+
# Last day in year
100+
if (self.date.month == 1 and self.date.day == 1):
101+
if (self.date.year == 2101):
102+
# Exception for year 2100 - ivalid handled by RTC without full leap year support
103+
year_day = 365
104+
else:
105+
year_day = date_org.timetuple().tm_yday - 1
106+
107+
t = (self.date.year , self.date.month, self.date.day, self.date.hour, self.date.minute, self.date.second, 0, 0, 0)
108+
109+
expected_timestamp = calendar.timegm(t)
110+
actual_timestamp = int(value) & 0xffffffff # convert to unsigned int
111+
112+
# encode week day and year day in the response
113+
response = (week_day << 16) | year_day
114+
115+
if (actual_timestamp == expected_timestamp):
116+
# response contains encoded week day and year day
117+
self.send_kv("passed", str(response))
118+
else:
119+
self.send_kv("failed", 0)
120+
print("expected = %d, result = %d" % (expected_timestamp , actual_timestamp))
121+
122+
# calculate next date
123+
if (self.first):
124+
days_range = calendar.monthrange(self.date.year, self.date.month)
125+
self.date = self.date.replace(day = days_range[1], minute = 59, second = 59)
126+
self.first = not self.first
127+
else:
128+
self.date += datetime.timedelta(days = 1)
129+
if (self.date.month == 1):
130+
self.year_id += 1
131+
if (len(self.years) == self.year_id):
132+
# All years were processed, no need to calc next date
133+
return
134+
self.date = self.date.replace(year = self.years[self.year_id])
135+
self.date = self.date.replace(day = 1, minute = 0, second = 0)
136+
self.first = not self.first
137+
138+
def setup(self):
139+
self.register_callback('timestamp', self._verify_timestamp)
140+
self.register_callback('leap_year_setup', self._set_leap_year_support)

0 commit comments

Comments
 (0)