-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13489 from rajkan01/hal_directory_restructuring
Refactor hal directory
- Loading branch information
Showing
147 changed files
with
1,050 additions
and
5 deletions.
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
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
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
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
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 |
---|---|---|
|
@@ -47,6 +47,6 @@ typedef enum { | |
#ifdef __cplusplus | ||
} | ||
#endif | ||
#include "pinmap.h" | ||
#include "hal/pinmap.h" | ||
|
||
#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.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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,181 @@ | ||
""" | ||
Copyright (c) 2018-2019 Arm Limited and affiliates. | ||
SPDX-License-Identifier: Apache-2.0 | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
""" | ||
import time | ||
from mbed_host_tests import BaseHostTest | ||
|
||
DEFAULT_SYNC_DELAY = 4.0 | ||
|
||
MSG_VALUE_WATCHDOG_PRESENT = 1 | ||
MSG_VALUE_DUMMY = '0' | ||
MSG_VALUE_RESET_REASON_GET = 'get' | ||
MSG_VALUE_RESET_REASON_CLEAR = 'clear' | ||
MSG_VALUE_DEVICE_RESET_NVIC = 'nvic' | ||
MSG_VALUE_DEVICE_RESET_WATCHDOG = 'watchdog' | ||
|
||
MSG_KEY_DEVICE_READY = 'ready' | ||
MSG_KEY_RESET_REASON_RAW = 'reason_raw' | ||
MSG_KEY_RESET_REASON = 'reason' | ||
MSG_KEY_DEVICE_RESET = 'reset' | ||
MSG_KEY_SYNC = '__sync' | ||
MSG_KEY_RESET_COMPLETE = 'reset_complete' | ||
|
||
RESET_REASONS = { | ||
'POWER_ON': '0', | ||
'PIN_RESET': '1', | ||
'BROWN_OUT': '2', | ||
'SOFTWARE': '3', | ||
'WATCHDOG': '4', | ||
'LOCKUP': '5', | ||
'WAKE_LOW_POWER': '6', | ||
'ACCESS_ERROR': '7', | ||
'BOOT_ERROR': '8', | ||
'MULTIPLE': '9', | ||
'PLATFORM': '10', | ||
'UNKNOWN': '11' | ||
} | ||
|
||
|
||
def raise_if_different(expected, actual, text=''): | ||
"""Raise a RuntimeError if actual is different than expected.""" | ||
if expected != actual: | ||
raise RuntimeError('{}Got {!r}, expected {!r}' | ||
.format(text, actual, expected)) | ||
|
||
|
||
class ResetReasonTest(BaseHostTest): | ||
"""Test for the Reset Reason HAL API. | ||
Given a device supporting a Reset Reason API. | ||
When the device is restarted using various methods. | ||
Then the device returns a correct reset reason for every restart. | ||
""" | ||
|
||
def __init__(self): | ||
super(ResetReasonTest, self).__init__() | ||
self.device_reasons = None | ||
self.device_has_watchdog = None | ||
self.raw_reset_reasons = set() | ||
self.sync_delay = DEFAULT_SYNC_DELAY | ||
self.test_steps_sequence = self.test_steps() | ||
# Advance the coroutine to it's first yield statement. | ||
self.test_steps_sequence.send(None) | ||
|
||
def setup(self): | ||
sync_delay = self.get_config_item('forced_reset_timeout') | ||
self.sync_delay = sync_delay if sync_delay is not None else DEFAULT_SYNC_DELAY | ||
self.register_callback(MSG_KEY_DEVICE_READY, self.cb_device_ready) | ||
self.register_callback(MSG_KEY_RESET_REASON_RAW, self.cb_reset_reason_raw) | ||
self.register_callback(MSG_KEY_RESET_REASON, self.cb_reset_reason) | ||
self.register_callback(MSG_KEY_DEVICE_RESET, self.cb_reset_reason) | ||
self.register_callback(MSG_KEY_RESET_COMPLETE, self.cb_reset_reason) | ||
|
||
def cb_device_ready(self, key, value, timestamp): | ||
"""Request a raw value of the reset_reason register. | ||
Additionally, save the device's reset_reason capabilities | ||
and the watchdog status on the first call. | ||
""" | ||
if self.device_reasons is None: | ||
reasons, wdg_status = (int(i, base=16) for i in value.split(',')) | ||
self.device_has_watchdog = (wdg_status == MSG_VALUE_WATCHDOG_PRESENT) | ||
self.device_reasons = [k for k, v in RESET_REASONS.items() if (reasons & 1 << int(v))] | ||
self.send_kv(MSG_KEY_RESET_REASON_RAW, MSG_VALUE_RESET_REASON_GET) | ||
|
||
def cb_reset_reason_raw(self, key, value, timestamp): | ||
"""Verify that the raw reset_reason register value is unique. | ||
Fail the test suite if the raw reset_reason value is not unique. | ||
Request a platform independent reset_reason otherwise. | ||
""" | ||
if value in self.raw_reset_reasons: | ||
self.log('TEST FAILED: The raw reset reason is not unique. ' | ||
'{!r} is already present in {!r}.' | ||
.format(value, self.raw_reset_reasons)) | ||
self.notify_complete(False) | ||
else: | ||
self.raw_reset_reasons.add(value) | ||
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_GET) | ||
|
||
def cb_reset_reason(self, key, value, timestamp): | ||
"""Feed the test_steps coroutine with reset_reason value. | ||
Pass the test suite if the coroutine yields True. | ||
Fail the test suite if the iterator stops or raises a RuntimeError. | ||
""" | ||
try: | ||
if self.test_steps_sequence.send(value): | ||
self.notify_complete(True) | ||
except (StopIteration, RuntimeError) as exc: | ||
self.log('TEST FAILED: {}'.format(exc)) | ||
self.notify_complete(False) | ||
|
||
def test_steps(self): | ||
"""Generate a sequence of test steps. | ||
This coroutine calls yield to wait for the input from the device | ||
(the reset_reason). If the device gives the wrong response, the | ||
generator raises a RuntimeError exception and fails the test. | ||
""" | ||
# Ignore the first reason. | ||
__ignored_reset_reason = yield | ||
self.raw_reset_reasons.clear() | ||
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR) | ||
__ignored_clear_ack = yield | ||
|
||
# Request a NVIC_SystemReset() call. | ||
expected_reason = 'SOFTWARE' | ||
if expected_reason not in self.device_reasons: | ||
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason)) | ||
else: | ||
# Request a NVIC_SystemReset() call. | ||
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_NVIC) | ||
__ignored_reset_ack = yield | ||
time.sleep(self.sync_delay) | ||
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY) | ||
reset_reason = yield | ||
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ') | ||
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR) | ||
__ignored_clear_ack = yield | ||
|
||
# Reset the device using DAP. | ||
expected_reason = 'PIN_RESET' | ||
if expected_reason not in self.device_reasons: | ||
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason)) | ||
else: | ||
self.reset() | ||
__ignored_reset_ack = yield # 'reset_complete' | ||
time.sleep(self.sync_delay) | ||
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY) | ||
reset_reason = yield | ||
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ') | ||
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR) | ||
__ignored_clear_ack = yield | ||
|
||
# Start a watchdog timer and wait for it to reset the device. | ||
expected_reason = 'WATCHDOG' | ||
if expected_reason not in self.device_reasons or not self.device_has_watchdog: | ||
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason)) | ||
else: | ||
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_WATCHDOG) | ||
__ignored_reset_ack = yield | ||
time.sleep(self.sync_delay) | ||
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY) | ||
reset_reason = yield | ||
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ') | ||
|
||
# The sequence is correct -- test passed. | ||
yield True |
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,140 @@ | ||
""" | ||
Copyright (c) 2011-2020, Arm Limited and affiliates | ||
SPDX-License-Identifier: Apache-2.0 | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
""" | ||
|
||
from mbed_host_tests import BaseHostTest | ||
import time | ||
import calendar | ||
import datetime | ||
|
||
class RTC_time_calc_test(BaseHostTest): | ||
""" | ||
This is the host part of the test to verify if: | ||
- _rtc_mktime function converts a calendar time into time since UNIX epoch as a time_t, | ||
- _rtc_localtime function converts a given time in seconds since epoch into calendar time. | ||
The same algoritm to generate next calendar time to be tested is used by both parts of the test. | ||
We will check if correct time since UNIX epoch is calculated for the first and the last day | ||
of each month and across valid years. | ||
Mbed part of the test sends calculated time since UNIX epoch. | ||
This part validates given value and responds to indicate pass or fail. | ||
Additionally it sends also encoded day of week and day of year which | ||
will be needed to verify _rtc_localtime. | ||
Support for both types of RTC devices is provided: | ||
- RTCs which handles all leap years in the mentioned year range correctly. Leap year is determined by checking if | ||
the year counter value is divisible by 400, 100, and 4. No problem here. | ||
- RTCs which handles leap years correctly up to 2100. The RTC does a simple bit comparison to see if the two | ||
lowest order bits of the year counter are zero. In this case 2100 year will be considered | ||
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 | ||
29.02.2100 (invalid). So after 28.02.2100 the day counter will be off by a day. | ||
""" | ||
|
||
edge_date = datetime.datetime(2100, 2, 28, 0, 0, 0) | ||
|
||
# Test the following years: | ||
# - first - 1970 | ||
# - example not leap year (not divisible by 4) | ||
# - example leap year (divisible by 4 and by 100 and by 400) | ||
# - example leap year (divisible by 4 and not by 100) | ||
# - example not leap year (divisible by 4 and by 100) | ||
# - last fully supported - 2105 | ||
years = [1970, 1971, 2000, 2096, 2100, 2105] | ||
year_id = 0 | ||
|
||
|
||
|
||
full_leap_year_support = False | ||
|
||
RTC_FULL_LEAP_YEAR_SUPPORT = 0 | ||
RTC_PARTIAL_LEAP_YEAR_SUPPORT = 1 | ||
|
||
def _set_leap_year_support(self, key, value, timestamp): | ||
if (int(value) == self.RTC_FULL_LEAP_YEAR_SUPPORT): | ||
self.full_leap_year_support = True | ||
else: | ||
self.full_leap_year_support = False | ||
|
||
self.first = True | ||
self.date = datetime.datetime(1970, 1, 1, 23, 0, 0) | ||
self.year_id = 0 | ||
|
||
def _verify_timestamp(self, key, value, timestamp): | ||
# week day in python is counted from sunday(0) and on mbed side week day is counted from monday(0). | ||
# year day in python is counted from 1 and on mbed side year day is counted from 0. | ||
week_day = ((self.date.timetuple().tm_wday + 1) % 7) | ||
year_day = self.date.timetuple().tm_yday - 1 | ||
|
||
# Fix for RTC which not have full leap year support. | ||
if (not self.full_leap_year_support): | ||
if self.date >= self.edge_date: | ||
# After 28.02.2100 we should be one day off - add this day and store original | ||
date_org = self.date | ||
self.date += datetime.timedelta(days = 1) | ||
|
||
# Adjust week day. | ||
week_day = ((self.date.timetuple().tm_wday + 1) % 7) | ||
|
||
# Adjust year day. | ||
if (self.date.year == 2100): | ||
year_day = self.date.timetuple().tm_yday - 1 | ||
else: | ||
year_day = date_org.timetuple().tm_yday - 1 | ||
|
||
# Last day in year | ||
if (self.date.month == 1 and self.date.day == 1): | ||
if (self.date.year == 2101): | ||
# Exception for year 2100 - ivalid handled by RTC without full leap year support | ||
year_day = 365 | ||
else: | ||
year_day = date_org.timetuple().tm_yday - 1 | ||
|
||
t = (self.date.year , self.date.month, self.date.day, self.date.hour, self.date.minute, self.date.second, 0, 0, 0) | ||
|
||
expected_timestamp = calendar.timegm(t) | ||
actual_timestamp = int(value) & 0xffffffff # convert to unsigned int | ||
|
||
# encode week day and year day in the response | ||
response = (week_day << 16) | year_day | ||
|
||
if (actual_timestamp == expected_timestamp): | ||
# response contains encoded week day and year day | ||
self.send_kv("passed", str(response)) | ||
else: | ||
self.send_kv("failed", 0) | ||
print("expected = %d, result = %d" % (expected_timestamp , actual_timestamp)) | ||
|
||
# calculate next date | ||
if (self.first): | ||
days_range = calendar.monthrange(self.date.year, self.date.month) | ||
self.date = self.date.replace(day = days_range[1], minute = 59, second = 59) | ||
self.first = not self.first | ||
else: | ||
self.date += datetime.timedelta(days = 1) | ||
if (self.date.month == 1): | ||
self.year_id += 1 | ||
if (len(self.years) == self.year_id): | ||
# All years were processed, no need to calc next date | ||
return | ||
self.date = self.date.replace(year = self.years[self.year_id]) | ||
self.date = self.date.replace(day = 1, minute = 0, second = 0) | ||
self.first = not self.first | ||
|
||
def setup(self): | ||
self.register_callback('timestamp', self._verify_timestamp) | ||
self.register_callback('leap_year_setup', self._set_leap_year_support) |
Oops, something went wrong.