Compare commits
52 Commits
move_seman
...
b814e7198f
Author | SHA1 | Date | |
---|---|---|---|
b814e7198f | |||
6328b70d7b | |||
a937b457f9 | |||
4415dc24e1 | |||
e704295cce | |||
d16b3c7e67 | |||
3b86545725 | |||
cf6150cc18 | |||
bfb5c2ff03 | |||
bf02061d47 | |||
2c4e110254 | |||
7ed75ea87b | |||
db4587bb59 | |||
33ac395072 | |||
f8a7c1d4ed | |||
341437df13 | |||
227524a21d | |||
43fd0b2f59 | |||
d0607824ad | |||
cf27954a86 | |||
f84e3284ab | |||
5250423d1d | |||
522bd41d6e | |||
c61c85280b | |||
afbe5e1f65 | |||
4c88ab80c8 | |||
5ba69b169f | |||
40405fe6c7 | |||
aac32e763c | |||
bf980d74c0 | |||
b6b9d1d790 | |||
0973ba6bf2 | |||
1cfebb5d47 | |||
0b0a0299bc | |||
8382d61b92 | |||
7208343b6d | |||
dc7afc5415 | |||
9bf3ff95b7 | |||
61562b18ab | |||
d76d97a36b | |||
76b377c4c0 | |||
3562bf11b9 | |||
fffb2b61e5 | |||
94e5f62331 | |||
0a9c563bbc | |||
5b92247fbd | |||
d9da55fdab | |||
066f7a6f9b | |||
c1f42618db | |||
61df451dd8 | |||
29ea89044e | |||
e487f5be87 |
123
CHANGELOG.md
123
CHANGELOG.md
@ -8,17 +8,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v6.0.0]
|
||||
# [v6.0.0] 2023-02-10
|
||||
|
||||
## Fixes
|
||||
|
||||
- Add monotonic watchdog Clock API and use it in `Countdown` and `Stopwatch` class.
|
||||
- Bugfix in `Service11TelecommandScheduling` which allowed commands
|
||||
time tagged in the past to be inserted.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/738
|
||||
- Mode Service: Add allowed subservice
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/739
|
||||
- `CService200ModeManagement`: Various bugfixes which lead to now execution complete being generated
|
||||
on mode announcements, duplicate mode reply generated on announce commands, and the mode read
|
||||
subservice not working properly.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/736
|
||||
- Memory leak fixes for the TCP/IP TMTC bridge.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/737
|
||||
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
|
||||
@ -27,16 +26,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
|
||||
only the X scaling factor was used.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/724
|
||||
- Bugfix for RM3100 MGM sensors. Z value was previously calculated
|
||||
with bytes of the X value.
|
||||
- HAL MGM3100 Handler: Z value was previously calculated with bytes of the X value.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/733
|
||||
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
|
||||
to false correctly because the `read` and `write` calls were missing.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/728
|
||||
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
|
||||
of the correct unsegmented flags (0b11) as specified in the standard.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/727
|
||||
- TC Scheduler Service 11: Add size and CRC check for contained TC.
|
||||
Bug: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/issues/719
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/720
|
||||
- Only delete health table entry in `HealthHelper` destructor if
|
||||
health table was set.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710/files
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710
|
||||
- I2C Bugfixes: Do not keep iterator as member and fix some incorrect handling with the iterator.
|
||||
Also properly reset the reply size for successfull transfers and erroneous transfers.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/700
|
||||
@ -46,6 +49,36 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- `TcpTmTcServer.cpp`: The server was actually not able to handle
|
||||
CCSDS packets which were clumped together. This has been fixed now.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/673
|
||||
- `CServiceHealthCommanding`: Add announce all health info implementation
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/725
|
||||
- various fixes related to linux Unittests and memory leaks
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/715
|
||||
- small fix to allow teardown handling
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/713
|
||||
- fix compiler warning for fixed array list copy ctor
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/704
|
||||
- missing include
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/703
|
||||
- defaultconfig did not build anymore
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/702
|
||||
- hotfix
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/699
|
||||
- small fix for helper
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/698
|
||||
- missing retval conv
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/697
|
||||
- DHB Countdown Bug
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/693
|
||||
- doc corrections
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/687
|
||||
- better error printout
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/686
|
||||
- include correction
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/683
|
||||
- better warning for missing include paths
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/676
|
||||
- Service 11 regression
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/670
|
||||
|
||||
## Added
|
||||
|
||||
@ -64,17 +97,36 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/709
|
||||
- Add new `UnsignedByteField` class
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/660
|
||||
- publish documentation for development and master branch
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/681
|
||||
- Add Linux HAL options
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/663
|
||||
- Expand SerializeIF
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/656
|
||||
- PUS Service 11: Additional Safety Check
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/666
|
||||
- improvements for auto-formatter script
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/665
|
||||
- provide a weak print char impl
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/674
|
||||
|
||||
## Removed
|
||||
|
||||
- now that doc server is up, remove markdown files
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/688
|
||||
- remove bsp specific code
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/679
|
||||
|
||||
## Changes
|
||||
|
||||
- `CService201HealthCommanding` renamed to `CServiceHealthCommanding`,
|
||||
service ID customizable now. `CServiceHealthCommanding` expects configuration struct
|
||||
`HealthServiceCfg` now
|
||||
PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/122
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/725
|
||||
- `AcceptsTelemetryIF`: `getReportReceptionQueue` is const now
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/712
|
||||
- Moved some container returnvalues to dedicated header and namespace
|
||||
to they can be used without template specification.
|
||||
so they can be used without template specification.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/707
|
||||
- Remove default secondary header argument for
|
||||
`uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)` and
|
||||
@ -104,18 +156,41 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- `DeviceHandlerBase`: New signature of `handleDeviceTm` which expects
|
||||
a `const SerializeIF&` and additional helper variant which expects `const uint8_t*`
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/671
|
||||
- Move some generic `StorageManagerIF` implementations from `LocalPool` to
|
||||
interface itself so it can be re-used more easily. Also add new
|
||||
abstract function `bool hasDataAtId(store_address_t storeId) const`.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/685
|
||||
- Improvements for `AcceptsTelemetryIF` and `AcceptsTelecommandsIF`:
|
||||
- Make functions `const` where it makes sense
|
||||
- Add `const char* getName const` abstract function
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/684
|
||||
- Move some generic `StorageManagerIF` implementations from `LocalPool` to
|
||||
interface itself so it can be re-used more easily. Also add new
|
||||
abstract function `bool hasDataAtId(store_address_t storeId) const`.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/685
|
||||
- Generic TMTC Bridge Update
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/734
|
||||
- comment tweak to event parser can read everything
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/732
|
||||
- CMakeLists file updates
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/731
|
||||
- improve srv20 error messages
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/723
|
||||
- I2C Linux: remove duplicate printout
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/718
|
||||
- printout handling improvements
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/717
|
||||
- vec getter, reset for content
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/716
|
||||
- updates for source sequence counter
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/714
|
||||
- SP reader getPacketData is const now
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/708
|
||||
- refactoring of serial drivers for linux
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/705
|
||||
- Local Pool Update Remove Add Data Ignore Fault Argument
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/701
|
||||
- Switch to new documentation server
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/694
|
||||
- Windows Tweaks
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/691
|
||||
- Refactor Local Pool API
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/667
|
||||
- group MGM data in local pool vectors
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/664
|
||||
|
||||
|
||||
## CFDP
|
||||
|
||||
@ -135,17 +210,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
implementation without an extra component
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/682
|
||||
|
||||
## HAL
|
||||
|
||||
- SPI: Cache the SPI device in the communication interface. Architecturally, this makes a
|
||||
lot more sense because each ComIF should be responsible for one SPI bus.
|
||||
- SPI: Move the empty transfer to update the line polarity to separate function. This means
|
||||
it is not automatically called when calling the setter function for SPI speed and mode.
|
||||
The user should call this function after locking the CS mutex if multiple SPI devices with
|
||||
differing speeds and modes are attached to one bus.
|
||||
- SPI: Getter functions for SPI speed and mode.
|
||||
|
||||
# [v5.0.0] 25.07.2022
|
||||
# [v5.0.0] 2022-07-25
|
||||
|
||||
## Changes
|
||||
|
||||
|
@ -13,7 +13,7 @@ list(APPEND CMAKE_MODULE_PATH
|
||||
# Version file handling #
|
||||
# ##############################################################################
|
||||
|
||||
set(FSFW_VERSION_IF_GIT_FAILS 5)
|
||||
set(FSFW_VERSION_IF_GIT_FAILS 6)
|
||||
set(FSFW_SUBVERSION_IF_GIT_FAILS 0)
|
||||
set(FSFW_REVISION_IF_GIT_FAILS 0)
|
||||
|
||||
|
110
scripts/check_release.py
Executable file
110
scripts/check_release.py
Executable file
@ -0,0 +1,110 @@
|
||||
#! /bin/python
|
||||
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import urllib.request
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="List undocumented PRs"
|
||||
)
|
||||
parser.add_argument("-v", "--version", type=str, required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
match = re.search("([0-9]+\.[0-9]+\.[0-9]+)", args.version)
|
||||
|
||||
if not match:
|
||||
print("invalid version")
|
||||
exit(1)
|
||||
|
||||
version = "v" + match.group(1)
|
||||
|
||||
print("looking for milestone for " + version + " ...")
|
||||
|
||||
|
||||
with urllib.request.urlopen("https://egit.irs.uni-stuttgart.de/api/v1/repos/fsfw/fsfw/milestones?name=" + version) as milestone_json:
|
||||
milestones = json.load(milestone_json)
|
||||
if (len(milestones) == 0):
|
||||
print("did not find any milestone")
|
||||
exit(1)
|
||||
if (len(milestones) > 1):
|
||||
print("found multiple milestons")
|
||||
milestone_title = milestones[0]['title']
|
||||
milestone = str(milestones[0]['id'])
|
||||
print("Using Milestone \""+ milestone_title + "\" with id " + milestone)
|
||||
|
||||
milestone_prs = []
|
||||
|
||||
page = 1
|
||||
last_count = 1;
|
||||
while last_count != 0:
|
||||
with urllib.request.urlopen("https://egit.irs.uni-stuttgart.de/api/v1/repos/fsfw/fsfw/pulls?state=closed&milestone=" + str(milestone) + "&limit=100&page=" + str(page)) as pull_requests_json:
|
||||
pull_requests = json.load(pull_requests_json)
|
||||
for pr in pull_requests:
|
||||
milestone_prs.append({'number': str(pr['number']), 'title' : pr['title']})
|
||||
page += 1
|
||||
last_count = len(pull_requests)
|
||||
|
||||
print("Found " + str(len(milestone_prs)) + " closed PRs in Milestone")
|
||||
|
||||
print("looking for CHANGELOG.md ...")
|
||||
|
||||
path = Path(".")
|
||||
|
||||
files = list(path.glob("CHANGELOG.md"))
|
||||
|
||||
if (len(files) != 1):
|
||||
files = list(path.glob("../CHANGELOG.md"))
|
||||
|
||||
if (len(files) != 1):
|
||||
print("did not find CHANGELOG.md. Run script in either root directory or scripts subfolder.")
|
||||
exit(1)
|
||||
|
||||
print("Scanning CHANGELOG.md ...")
|
||||
|
||||
changelog_prs = []
|
||||
|
||||
with open(files[0]) as changelog:
|
||||
line = changelog.readline()
|
||||
while (line):
|
||||
#print("line: " + line)
|
||||
match = re.search("\#.+(v[0-9]+\.[0-9]+\.[0-9]+)", line)
|
||||
if (match):
|
||||
if match.group(1) == version:
|
||||
#print("found version")
|
||||
line = changelog.readline()
|
||||
continue
|
||||
else:
|
||||
#print("done with " + match.group(1))
|
||||
break
|
||||
|
||||
match = re.search("PR: https://egit\.irs\.uni-stuttgart\.de/fsfw/fsfw/pulls/([0-9]+)", line)
|
||||
if match:
|
||||
changelog_prs.append(match.group(1))
|
||||
|
||||
line = changelog.readline()
|
||||
|
||||
print("Found " + str(len(changelog_prs)) + " PRs in CHANGELOG.md")
|
||||
|
||||
print("")
|
||||
|
||||
copy_array = changelog_prs.copy()
|
||||
print("PRs in CHANGELOG.md that are not in Milestone:")
|
||||
for pr in milestone_prs:
|
||||
if pr['number'] in copy_array:
|
||||
copy_array.remove(pr['number'])
|
||||
for pr in copy_array:
|
||||
print("https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/" + pr)
|
||||
|
||||
print("")
|
||||
|
||||
print("PRs in milestone that are not in CHANGELOG.md:")
|
||||
|
||||
for pr in milestone_prs:
|
||||
if pr['number'] not in changelog_prs:
|
||||
print("- " + pr['title'] + "\n PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/" + pr['number'])
|
||||
|
||||
main()
|
@ -70,8 +70,7 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::initializeAfterTaskCreation(uint8_t nonDiagInvlFactor) {
|
||||
setNonDiagnosticIntervalFactor(nonDiagInvlFactor);
|
||||
ReturnValue_t LocalDataPoolManager::initializeAfterTaskCreation() {
|
||||
return initializeHousekeepingPoolEntriesOnce();
|
||||
}
|
||||
|
||||
@ -661,10 +660,6 @@ ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(HousekeepingPacke
|
||||
return hkPacket.serialize(&dataPtr, serializedSize, maxSize, SerializeIF::Endianness::MACHINE);
|
||||
}
|
||||
|
||||
void LocalDataPoolManager::setNonDiagnosticIntervalFactor(uint8_t nonDiagInvlFactor) {
|
||||
this->nonDiagnosticIntervalFactor = nonDiagInvlFactor;
|
||||
}
|
||||
|
||||
void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
||||
sid_t sid = receiver.dataId.sid;
|
||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||
@ -718,7 +713,7 @@ ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool ena
|
||||
|
||||
if ((LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and enable) or
|
||||
(not LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and not enable)) {
|
||||
return REPORTING_STATUS_UNCHANGED;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enable);
|
||||
|
@ -102,7 +102,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
* @param nonDiagInvlFactor
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t initializeAfterTaskCreation(uint8_t nonDiagInvlFactor = 5);
|
||||
ReturnValue_t initializeAfterTaskCreation();
|
||||
|
||||
/**
|
||||
* @brief This should be called in the periodic handler of the owner.
|
||||
@ -152,17 +152,6 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
MessageQueueId_t targetQueueId,
|
||||
bool generateSnapshot) override;
|
||||
|
||||
/**
|
||||
* Non-Diagnostics packets usually have a lower minimum sampling frequency
|
||||
* than diagnostic packets.
|
||||
* A factor can be specified to determine the minimum sampling frequency
|
||||
* for non-diagnostic packets. The minimum sampling frequency of the
|
||||
* diagnostics packets,which is usually jusst the period of the
|
||||
* performOperation calls, is multiplied with that factor.
|
||||
* @param factor
|
||||
*/
|
||||
void setNonDiagnosticIntervalFactor(uint8_t nonDiagInvlFactor);
|
||||
|
||||
/**
|
||||
* @brief The manager is also able to handle housekeeping messages.
|
||||
* @details
|
||||
|
@ -250,9 +250,8 @@ void LocalPoolDataSetBase::setReportingEnabled(bool reportingEnabled) {
|
||||
bool LocalPoolDataSetBase::getReportingEnabled() const { return reportingEnabled; }
|
||||
|
||||
void LocalPoolDataSetBase::initializePeriodicHelper(float collectionInterval,
|
||||
dur_millis_t minimumPeriodicInterval,
|
||||
uint8_t nonDiagIntervalFactor) {
|
||||
periodicHelper->initialize(collectionInterval, minimumPeriodicInterval, nonDiagIntervalFactor);
|
||||
dur_millis_t minimumPeriodicInterval) {
|
||||
periodicHelper->initialize(collectionInterval, minimumPeriodicInterval);
|
||||
}
|
||||
|
||||
void LocalPoolDataSetBase::setChanged(bool changed) { this->changed = changed; }
|
||||
|
@ -191,8 +191,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
||||
*/
|
||||
bool reportingEnabled = false;
|
||||
|
||||
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
||||
uint8_t nonDiagIntervalFactor = 5);
|
||||
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval);
|
||||
|
||||
/**
|
||||
* If the valid state of a dataset is always relevant to the whole
|
||||
|
@ -12,10 +12,8 @@ class LocalPoolDataSetAttorney {
|
||||
static bool isDiagnostics(LocalPoolDataSetBase& set) { return set.isDiagnostics(); }
|
||||
|
||||
static void initializePeriodicHelper(LocalPoolDataSetBase& set, float collectionInterval,
|
||||
uint32_t minimumPeriodicIntervalMs,
|
||||
uint8_t nonDiagIntervalFactor = 5) {
|
||||
set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs,
|
||||
nonDiagIntervalFactor);
|
||||
uint32_t minimumPeriodicIntervalMs) {
|
||||
set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs);
|
||||
}
|
||||
|
||||
static void setReportingEnabled(LocalPoolDataSetBase& set, bool enabled) {
|
||||
|
@ -49,6 +49,7 @@ class DeviceCommunicationIF {
|
||||
// is this needed if there is no open/close call?
|
||||
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x05);
|
||||
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x06);
|
||||
static constexpr ReturnValue_t BUSY = MAKE_RETURN_CODE(0x07);
|
||||
|
||||
virtual ~DeviceCommunicationIF() {}
|
||||
|
||||
|
@ -567,7 +567,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
continueToNormal = false;
|
||||
// TODO: Check whether the following two lines are okay to do so.
|
||||
transitionSourceMode = MODE_ON;
|
||||
transitionSourceSubMode = submode;
|
||||
transitionSourceSubMode = newSubmode;
|
||||
mode = _MODE_TO_NORMAL;
|
||||
return;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ enum : uint8_t {
|
||||
CDH = 28,
|
||||
TCS_1 = 59,
|
||||
PCDU_1 = 42,
|
||||
PCDU_2 = 43,
|
||||
POWER_SWITCH_IF = 43,
|
||||
HEATER = 50,
|
||||
T_SENSORS = 52,
|
||||
FDIR = 70,
|
||||
|
@ -8,10 +8,8 @@ PeriodicHousekeepingHelper::PeriodicHousekeepingHelper(LocalPoolDataSetBase* own
|
||||
: owner(owner) {}
|
||||
|
||||
void PeriodicHousekeepingHelper::initialize(float collectionInterval,
|
||||
dur_millis_t minimumPeriodicInterval,
|
||||
uint8_t nonDiagIntervalFactor) {
|
||||
dur_millis_t minimumPeriodicInterval) {
|
||||
this->minimumPeriodicInterval = minimumPeriodicInterval;
|
||||
this->nonDiagIntervalFactor = nonDiagIntervalFactor;
|
||||
collectionIntervalTicks = intervalSecondsToIntervalTicks(collectionInterval);
|
||||
/* This will cause a checkOpNecessary call to be true immediately. I think it's okay
|
||||
if a HK packet is generated immediately instead of waiting one generation cycle. */
|
||||
@ -36,42 +34,17 @@ uint32_t PeriodicHousekeepingHelper::intervalSecondsToIntervalTicks(
|
||||
if (owner == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
bool isDiagnostics = owner->isDiagnostics();
|
||||
|
||||
/* Avoid division by zero */
|
||||
if (minimumPeriodicInterval == 0) {
|
||||
if (isDiagnostics) {
|
||||
/* Perform operation each cycle */
|
||||
return 1;
|
||||
} else {
|
||||
return nonDiagIntervalFactor;
|
||||
}
|
||||
/* Perform operation each cycle */
|
||||
return 1;
|
||||
|
||||
} else {
|
||||
dur_millis_t intervalInMs = collectionIntervalSeconds * 1000;
|
||||
uint32_t divisor = minimumPeriodicInterval;
|
||||
if (not isDiagnostics) {
|
||||
/* We need to multiply the divisor because non-diagnostics only
|
||||
allow a multiple of the minimum periodic interval */
|
||||
divisor *= nonDiagIntervalFactor;
|
||||
}
|
||||
uint32_t ticks = std::ceil(static_cast<float>(intervalInMs) / divisor);
|
||||
if (not isDiagnostics) {
|
||||
/* Now we need to multiply the calculated ticks with the factor as as well
|
||||
because the minimum tick count to generate a non-diagnostic is the factor itself.
|
||||
|
||||
Example calculation for non-diagnostic with
|
||||
0.4 second interval and 0.2 second task interval.
|
||||
Resultant tick count of 5 is equal to operation each second.
|
||||
|
||||
Examle calculation for non-diagnostic with 2.0 second interval and 0.2 second
|
||||
task interval.
|
||||
Resultant tick count of 10 is equal to operatin every 2 seconds.
|
||||
|
||||
Example calculation for diagnostic with 0.4 second interval and 0.3
|
||||
second task interval. Resulting tick count of 2 is equal to operation
|
||||
every 0.6 seconds. */
|
||||
ticks *= nonDiagIntervalFactor;
|
||||
}
|
||||
return ticks;
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,7 @@ class PeriodicHousekeepingHelper {
|
||||
public:
|
||||
PeriodicHousekeepingHelper(LocalPoolDataSetBase* owner);
|
||||
|
||||
void initialize(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
||||
uint8_t nonDiagIntervalFactor);
|
||||
void initialize(float collectionInterval, dur_millis_t minimumPeriodicInterval);
|
||||
|
||||
void changeCollectionInterval(float newInterval);
|
||||
float getCollectionIntervalInSeconds() const;
|
||||
@ -20,7 +19,6 @@ class PeriodicHousekeepingHelper {
|
||||
|
||||
private:
|
||||
LocalPoolDataSetBase* owner = nullptr;
|
||||
uint8_t nonDiagIntervalFactor = 0;
|
||||
|
||||
uint32_t intervalSecondsToIntervalTicks(float collectionIntervalSeconds);
|
||||
float intervalTicksToSeconds(uint32_t collectionInterval) const;
|
||||
|
@ -20,16 +20,18 @@ TaskFactory::~TaskFactory() = default;
|
||||
|
||||
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
|
||||
|
||||
PeriodicTaskIF* TaskFactory::createPeriodicTask(
|
||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
||||
PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
|
||||
TaskStackSize stackSize_,
|
||||
TaskPeriod periodInSeconds_,
|
||||
TaskDeadlineMissedFunction deadLineMissedFunction_,
|
||||
void* args) {
|
||||
return new PeriodicTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
||||
deadLineMissedFunction_);
|
||||
}
|
||||
|
||||
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
|
||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, void* args) {
|
||||
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
||||
deadLineMissedFunction_);
|
||||
}
|
||||
|
@ -7,10 +7,15 @@
|
||||
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
|
||||
|
||||
FixedTimeslotTask::FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
|
||||
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_)
|
||||
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_,
|
||||
PosixThreadArgs* args)
|
||||
: FixedTimeslotTaskBase(periodSeconds_, dlmFunc_),
|
||||
posixThread(name_, priority_, stackSize_),
|
||||
started(false) {}
|
||||
posixThread(name_, SchedulingPolicy::REGULAR, priority_, stackSize_),
|
||||
started(false) {
|
||||
if (args != nullptr) {
|
||||
posixThread.setSchedPolicy(args->policy);
|
||||
}
|
||||
}
|
||||
|
||||
void* FixedTimeslotTask::taskEntryPoint(void* arg) {
|
||||
// The argument is re-interpreted as PollingTask.
|
||||
|
@ -23,7 +23,8 @@ class FixedTimeslotTask : public FixedTimeslotTaskBase {
|
||||
* @param deadlineMissedFunc_
|
||||
*/
|
||||
FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
|
||||
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_);
|
||||
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_,
|
||||
PosixThreadArgs* args);
|
||||
~FixedTimeslotTask() override = default;
|
||||
|
||||
ReturnValue_t startTask() override;
|
||||
|
@ -4,10 +4,15 @@
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
|
||||
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
|
||||
TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_)
|
||||
TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_,
|
||||
PosixThreadArgs* args)
|
||||
: PeriodicTaskBase(period_, dlmFunc_),
|
||||
posixThread(name_, priority_, stackSize_),
|
||||
started(false) {}
|
||||
posixThread(name_, SchedulingPolicy::REGULAR, priority_, stackSize_),
|
||||
started(false) {
|
||||
if (args != nullptr) {
|
||||
posixThread.setSchedPolicy(args->policy);
|
||||
}
|
||||
}
|
||||
|
||||
void* PeriodicPosixTask::taskEntryPoint(void* arg) {
|
||||
// The argument is re-interpreted as PollingTask.
|
||||
|
@ -24,7 +24,7 @@ class PeriodicPosixTask : public PeriodicTaskBase {
|
||||
* @param deadlineMissedFunc_
|
||||
*/
|
||||
PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_,
|
||||
TaskDeadlineMissedFunction dlmFunc_);
|
||||
TaskDeadlineMissedFunction dlmFunc_, PosixThreadArgs* args);
|
||||
~PeriodicPosixTask() override = default;
|
||||
|
||||
/**
|
||||
|
@ -7,8 +7,9 @@
|
||||
#include "fsfw/osal/linux/unixUtility.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_)
|
||||
: thread(0), priority(priority_), stackSize(stackSize_) {
|
||||
PosixThread::PosixThread(const char* name_, SchedulingPolicy schedPolciy, int priority_,
|
||||
size_t stackSize_)
|
||||
: thread(0), schedPolicy(schedPolciy), priority(priority_), stackSize(stackSize_) {
|
||||
name[0] = '\0';
|
||||
std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
|
||||
}
|
||||
@ -178,20 +179,30 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
||||
#ifndef FSFW_USE_REALTIME_FOR_LINUX
|
||||
#error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1"
|
||||
#endif
|
||||
if (schedPolicy == SchedulingPolicy::RR) {
|
||||
// RR -> This needs root privileges for the process
|
||||
#if FSFW_USE_REALTIME_FOR_LINUX == 1
|
||||
// FIFO -> This needs root privileges for the process
|
||||
status = pthread_attr_setschedpolicy(&attributes, SCHED_FIFO);
|
||||
if (status != 0) {
|
||||
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy");
|
||||
status = pthread_attr_setschedpolicy(&attributes, SCHED_RR);
|
||||
if (status != 0) {
|
||||
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy");
|
||||
}
|
||||
sched_param scheduleParams;
|
||||
scheduleParams.sched_priority = priority;
|
||||
status = pthread_attr_setschedparam(&attributes, &scheduleParams);
|
||||
if (status != 0) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "PosixThread: Setting priority failed" << std::endl;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning
|
||||
<< "Real time priorities are only allowed if FSFW_USE_REALTIME_FOR_LINUX is set to 1"
|
||||
<< std::endl;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
sched_param scheduleParams;
|
||||
scheduleParams.__sched_priority = priority;
|
||||
status = pthread_attr_setschedparam(&attributes, &scheduleParams);
|
||||
if (status != 0) {
|
||||
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedparam");
|
||||
}
|
||||
#endif
|
||||
// Set Signal Mask for suspend until startTask is called
|
||||
sigset_t waitSignal;
|
||||
sigemptyset(&waitSignal);
|
||||
@ -243,3 +254,5 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
||||
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_destroy");
|
||||
}
|
||||
}
|
||||
|
||||
void PosixThread::setSchedPolicy(SchedulingPolicy policy) { this->schedPolicy = policy; }
|
||||
|
@ -9,10 +9,15 @@
|
||||
|
||||
#include "../../returnvalues/returnvalue.h"
|
||||
|
||||
enum SchedulingPolicy { REGULAR, RR };
|
||||
struct PosixThreadArgs {
|
||||
SchedulingPolicy policy = SchedulingPolicy::REGULAR;
|
||||
};
|
||||
|
||||
class PosixThread {
|
||||
public:
|
||||
static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16;
|
||||
PosixThread(const char* name_, int priority_, size_t stackSize_);
|
||||
PosixThread(const char* name_, SchedulingPolicy schedPolicy, int priority_, size_t stackSize_);
|
||||
virtual ~PosixThread();
|
||||
/**
|
||||
* Set the Thread to sleep state
|
||||
@ -20,6 +25,9 @@ class PosixThread {
|
||||
* @return Returns Failed if sleep fails
|
||||
*/
|
||||
static ReturnValue_t sleep(uint64_t ns);
|
||||
|
||||
void setSchedPolicy(SchedulingPolicy policy);
|
||||
|
||||
/**
|
||||
* @brief Function to suspend the task until SIGUSR1 was received
|
||||
*
|
||||
@ -72,6 +80,7 @@ class PosixThread {
|
||||
|
||||
private:
|
||||
char name[PTHREAD_MAX_NAMELEN];
|
||||
SchedulingPolicy schedPolicy;
|
||||
int priority;
|
||||
size_t stackSize = 0;
|
||||
|
||||
|
@ -12,18 +12,20 @@ TaskFactory::~TaskFactory() = default;
|
||||
|
||||
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
|
||||
|
||||
PeriodicTaskIF* TaskFactory::createPeriodicTask(
|
||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
||||
PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
|
||||
TaskStackSize stackSize_,
|
||||
TaskPeriod periodInSeconds_,
|
||||
TaskDeadlineMissedFunction deadLineMissedFunction_,
|
||||
void* args) {
|
||||
return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
||||
deadLineMissedFunction_);
|
||||
deadLineMissedFunction_, reinterpret_cast<PosixThreadArgs*>(args));
|
||||
}
|
||||
|
||||
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
|
||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, void* args) {
|
||||
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
||||
deadLineMissedFunction_);
|
||||
deadLineMissedFunction_, reinterpret_cast<PosixThreadArgs*>(args));
|
||||
}
|
||||
|
||||
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "fsfw/osal/rtems/BinarySemaphore.h"
|
||||
//#include "fsfw/osal/rtems/CountingSemaphore.h"
|
||||
// #include "fsfw/osal/rtems/CountingSemaphore.h"
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/tasks/SemaphoreFactory.h"
|
||||
|
@ -32,7 +32,7 @@ class Fuse : public SystemObject,
|
||||
gp_id_t poolIdPower;
|
||||
};
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1;
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::POWER_SWITCH_IF;
|
||||
//! PSS detected that current on a fuse is totally out of bounds.
|
||||
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(1, severity::LOW);
|
||||
//! PSS detected a fuse that went off.
|
||||
|
@ -28,7 +28,9 @@ class PowerSwitchIF {
|
||||
static const ReturnValue_t SWITCH_TIMEOUT = MAKE_RETURN_CODE(2);
|
||||
static const ReturnValue_t FUSE_ON = MAKE_RETURN_CODE(3);
|
||||
static const ReturnValue_t FUSE_OFF = MAKE_RETURN_CODE(4);
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_2;
|
||||
static const ReturnValue_t SWITCH_UNKNOWN = MAKE_RETURN_CODE(5);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::POWER_SWITCH_IF;
|
||||
//!< Someone detected that a switch went off which shouldn't. Severity:
|
||||
//!< Low, Parameter1: switchId1, Parameter2: switchId2
|
||||
static const Event SWITCH_WENT_OFF = MAKE_EVENT(0, severity::LOW);
|
||||
@ -50,6 +52,7 @@ class PowerSwitchIF {
|
||||
* @return
|
||||
* - @c SWITCH_ON if the specified switch is on.
|
||||
* - @c SWITCH_OFF if the specified switch is off.
|
||||
* - @c SWITCH_UNKNOWN if the state of the specified switch is unknown.
|
||||
* - @c returnvalue::FAILED if an error occured
|
||||
*/
|
||||
virtual ReturnValue_t getSwitchState(power::Switch_t switchNr) const = 0;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
#include <fsfw/subsystem/helper.h>
|
||||
|
||||
PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher,
|
||||
power::Switch_t pwrSwitch)
|
||||
@ -28,6 +29,9 @@ ReturnValue_t PowerSwitcherComponent::performOperation(uint8_t opCode) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (getHealth() == FAULTY) {
|
||||
performFaultyOperation();
|
||||
}
|
||||
if (switcher.active()) {
|
||||
switcher.doStateMachine();
|
||||
auto currState = switcher.getState();
|
||||
@ -111,9 +115,11 @@ const HasHealthIF* PowerSwitcherComponent::getOptHealthIF() const { return this;
|
||||
const HasModesIF& PowerSwitcherComponent::getModeIF() const { return *this; }
|
||||
|
||||
ReturnValue_t PowerSwitcherComponent::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||
return parent.registerChild(*this);
|
||||
return modetree::connectModeTreeParent(parent, *this, &healthHelper, modeHelper);
|
||||
}
|
||||
|
||||
object_id_t PowerSwitcherComponent::getObjectId() const { return SystemObject::getObjectId(); }
|
||||
|
||||
ModeTreeChildIF& PowerSwitcherComponent::getModeTreeChildIF() { return *this; }
|
||||
|
||||
void PowerSwitcherComponent::performFaultyOperation() {}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef _FSFW_POWER_POWERSWITCHERCOMPONENT_H_
|
||||
#define _FSFW_POWER_POWERSWITCHERCOMPONENT_H_
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/health/HasHealthIF.h>
|
||||
#include <fsfw/health/HealthHelper.h>
|
||||
@ -37,9 +36,11 @@ class PowerSwitcherComponent : public SystemObject,
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||
|
||||
protected:
|
||||
PowerSwitcher switcher;
|
||||
|
||||
private:
|
||||
MessageQueueIF *queue = nullptr;
|
||||
PowerSwitcher switcher;
|
||||
|
||||
Mode_t mode = MODE_OFF;
|
||||
Submode_t submode = 0;
|
||||
@ -49,24 +50,23 @@ class PowerSwitcherComponent : public SystemObject,
|
||||
|
||||
void setMode(Mode_t newMode, Submode_t newSubmode);
|
||||
|
||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
MessageQueueId_t getCommandQueue() const override;
|
||||
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
|
||||
void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) override;
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
virtual void performFaultyOperation();
|
||||
void setToExternalControl() override;
|
||||
void announceMode(bool recursive) override;
|
||||
|
||||
ReturnValue_t setHealth(HealthState health) override;
|
||||
HasHealthIF::HealthState getHealth() override;
|
||||
|
||||
object_id_t getObjectId() const override;
|
||||
const HasHealthIF *getOptHealthIF() const override;
|
||||
const HasModesIF &getModeIF() const override;
|
||||
[[nodiscard]] object_id_t getObjectId() const override;
|
||||
[[nodiscard]] const HasHealthIF *getOptHealthIF() const override;
|
||||
[[nodiscard]] const HasModesIF &getModeIF() const override;
|
||||
};
|
||||
|
||||
#endif /* _FSFW_POWER_POWERSWITCHERCOMPONENT_H_ */
|
||||
|
@ -10,9 +10,23 @@
|
||||
CServiceHealthCommanding::CServiceHealthCommanding(HealthServiceCfg args)
|
||||
: CommandingServiceBase(args.objectId, args.apid, "PUS 201 Health MGMT", args.service,
|
||||
args.numParallelCommands, args.commandTimeoutSeconds),
|
||||
healthTable(args.table),
|
||||
healthTableId(args.table),
|
||||
maxNumHealthInfoPerCycle(args.maxNumHealthInfoPerCycle) {}
|
||||
|
||||
ReturnValue_t CServiceHealthCommanding::initialize() {
|
||||
ReturnValue_t result = CommandingServiceBase::initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
healthTable = ObjectManager::instance()->get<HealthTable>(healthTableId);
|
||||
if (healthTable == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CServiceHealthCommanding::isValidSubservice(uint8_t subservice) {
|
||||
switch (subservice) {
|
||||
case (Subservice::COMMAND_SET_HEALTH):
|
||||
@ -91,14 +105,6 @@ ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message,
|
||||
return EXECUTION_COMPLETE;
|
||||
}
|
||||
return result;
|
||||
while (true) {
|
||||
ReturnValue_t result = iterateHealthTable(false);
|
||||
if (result != returnvalue::OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
default: {
|
||||
// Should never happen, subservice was already checked
|
||||
@ -145,7 +151,7 @@ void CServiceHealthCommanding::doPeriodicOperation() {
|
||||
ReturnValue_t CServiceHealthCommanding::iterateHealthTable(bool reset) {
|
||||
std::pair<object_id_t, HasHealthIF::HealthState> pair;
|
||||
|
||||
ReturnValue_t result = healthTable.iterate(&pair, reset);
|
||||
ReturnValue_t result = healthTable->iterate(&pair, reset);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
} else {
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "fsfw/tmtcservices/CommandingServiceBase.h"
|
||||
|
||||
struct HealthServiceCfg {
|
||||
HealthServiceCfg(object_id_t objectId, uint16_t apid, HealthTable &healthTable,
|
||||
HealthServiceCfg(object_id_t objectId, uint16_t apid, object_id_t healthTable,
|
||||
uint16_t maxNumHealthInfoPerCycle)
|
||||
: objectId(objectId),
|
||||
apid(apid),
|
||||
@ -14,7 +14,7 @@ struct HealthServiceCfg {
|
||||
maxNumHealthInfoPerCycle(maxNumHealthInfoPerCycle) {}
|
||||
object_id_t objectId;
|
||||
uint16_t apid;
|
||||
HealthTable &table;
|
||||
object_id_t table;
|
||||
uint16_t maxNumHealthInfoPerCycle;
|
||||
uint8_t service = 201;
|
||||
uint8_t numParallelCommands = 4;
|
||||
@ -40,6 +40,8 @@ class CServiceHealthCommanding : public CommandingServiceBase {
|
||||
CServiceHealthCommanding(HealthServiceCfg args);
|
||||
~CServiceHealthCommanding() override = default;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
protected:
|
||||
/* CSB abstract function implementations */
|
||||
ReturnValue_t isValidSubservice(uint8_t subservice) override;
|
||||
@ -57,7 +59,8 @@ class CServiceHealthCommanding : public CommandingServiceBase {
|
||||
void doPeriodicOperation() override;
|
||||
|
||||
private:
|
||||
HealthTable &healthTable;
|
||||
const object_id_t healthTableId;
|
||||
HealthTable *healthTable;
|
||||
uint16_t maxNumHealthInfoPerCycle = 0;
|
||||
bool reportAllHealth = false;
|
||||
ReturnValue_t iterateHealthTable(bool reset);
|
||||
|
@ -10,11 +10,11 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// RMAP command bits
|
||||
//#define RMAP_COMMAND_BIT_INCREMENT 2
|
||||
//#define RMAP_COMMAND_BIT_REPLY 3
|
||||
//#define RMAP_COMMAND_BIT_WRITE 5
|
||||
//#define RMAP_COMMAND_BIT_VERIFY 4
|
||||
//#define RMAP_COMMAND_BIT 6
|
||||
// #define RMAP_COMMAND_BIT_INCREMENT 2
|
||||
// #define RMAP_COMMAND_BIT_REPLY 3
|
||||
// #define RMAP_COMMAND_BIT_WRITE 5
|
||||
// #define RMAP_COMMAND_BIT_VERIFY 4
|
||||
// #define RMAP_COMMAND_BIT 6
|
||||
|
||||
namespace RMAPIds {
|
||||
|
||||
@ -32,14 +32,14 @@ static const uint8_t RMAP_COMMAND_READ = ((1 << RMAP_COMMAND_BIT) | (1 << RMAP_C
|
||||
static const uint8_t RMAP_REPLY_WRITE =
|
||||
((1 << RMAP_COMMAND_BIT_WRITE) | (1 << RMAP_COMMAND_BIT_REPLY));
|
||||
static const uint8_t RMAP_REPLY_READ = ((1 << RMAP_COMMAND_BIT_REPLY));
|
||||
//#define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE)
|
||||
// #define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE)
|
||||
//| (1<<RMAP_COMMAND_BIT_REPLY)) #define RMAP_COMMAND_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT) |
|
||||
//(1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define
|
||||
// RMAP_COMMAND_READ ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY))
|
||||
// RMAP_COMMAND_READ ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY))
|
||||
|
||||
//#define RMAP_REPLY_WRITE ((1<<RMAP_COMMAND_BIT_WRITE) |
|
||||
// #define RMAP_REPLY_WRITE ((1<<RMAP_COMMAND_BIT_WRITE) |
|
||||
//(1<<RMAP_COMMAND_BIT_REPLY))
|
||||
//#define RMAP_REPLY_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT_WRITE) |
|
||||
// #define RMAP_REPLY_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT_WRITE) |
|
||||
//(1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define RMAP_REPLY_READ
|
||||
//((1<<RMAP_COMMAND_BIT_REPLY))
|
||||
|
||||
@ -49,9 +49,9 @@ static const uint8_t RMAP_COMMAND_HEADER_LEN = 16;
|
||||
static const uint8_t RMAP_WRITE_REPLY_HEADER_LEN = 8;
|
||||
static const uint8_t RMAP_READ_REPLY_HEADER_LEN = 12;
|
||||
static const uint8_t RMAP_DATA_FOOTER_SIZE = 1; // SIZE OF CRC
|
||||
//#define RMAP_COMMAND_HEADER_LEN 16
|
||||
//#define RMAP_WRITE_REPLY_HEADER_LEN 8
|
||||
//#define RMAP_READ_REPLY_HEADER_LEN 12
|
||||
// #define RMAP_COMMAND_HEADER_LEN 16
|
||||
// #define RMAP_WRITE_REPLY_HEADER_LEN 8
|
||||
// #define RMAP_READ_REPLY_HEADER_LEN 12
|
||||
|
||||
} // namespace RMAPIds
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "fsfw/FSFW.h"
|
||||
|
||||
PoolManager::PoolManager(object_id_t setObjectId, const LocalPoolConfig& localPoolConfig)
|
||||
: LocalPool(setObjectId, localPoolConfig, true) {
|
||||
: LocalPool(setObjectId, localPoolConfig, true, true) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,8 @@ class TaskFactory {
|
||||
*/
|
||||
PeriodicTaskIF* createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
|
||||
TaskStackSize stackSize_, TaskPeriod periodInSeconds_,
|
||||
TaskDeadlineMissedFunction deadLineMissedFunction_);
|
||||
TaskDeadlineMissedFunction deadLineMissedFunction_,
|
||||
void* args = nullptr);
|
||||
|
||||
/**
|
||||
* The meaning for the variables for fixed timeslot tasks is the same as for periodic tasks.
|
||||
@ -62,7 +63,8 @@ class TaskFactory {
|
||||
FixedTimeslotTaskIF* createFixedTimeslotTask(TaskName name_, TaskPriority taskPriority_,
|
||||
TaskStackSize stackSize_,
|
||||
TaskPeriod periodInSeconds_,
|
||||
TaskDeadlineMissedFunction deadLineMissedFunction_);
|
||||
TaskDeadlineMissedFunction deadLineMissedFunction_,
|
||||
void* args = nullptr);
|
||||
|
||||
/**
|
||||
* Function to be called to delete a task
|
||||
|
@ -112,8 +112,9 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
|
||||
if (i2cCookie->errorCounter < 3) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "I2cComIF::sendMessage: Failed to send data to I2C "
|
||||
"device from " << deviceFile << " with error code "
|
||||
<< errno << ". Error description: " << strerror(errno) << std::endl;
|
||||
"device from "
|
||||
<< deviceFile << " with error code " << errno
|
||||
<< ". Error description: " << strerror(errno) << std::endl;
|
||||
#endif
|
||||
}
|
||||
return returnvalue::FAILED;
|
||||
|
@ -88,11 +88,11 @@ int SerialComIF::configureUartPort(SerialCookie* uartCookie) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
uart::setParity(options, uartCookie->getParity());
|
||||
serial::setParity(options, uartCookie->getParity());
|
||||
setStopBitOptions(&options, uartCookie);
|
||||
setDatasizeOptions(&options, uartCookie);
|
||||
setFixedOptions(&options);
|
||||
uart::setMode(options, uartCookie->getUartMode());
|
||||
serial::setMode(options, uartCookie->getUartMode());
|
||||
if (uartCookie->getInputShouldBeFlushed()) {
|
||||
tcflush(fd, TCIFLUSH);
|
||||
}
|
||||
@ -101,7 +101,7 @@ int SerialComIF::configureUartPort(SerialCookie* uartCookie) {
|
||||
options.c_cc[VTIME] = 0;
|
||||
options.c_cc[VMIN] = 0;
|
||||
|
||||
uart::setBaudrate(options, uartCookie->getBaudrate());
|
||||
serial::setBaudrate(options, uartCookie->getBaudrate());
|
||||
|
||||
/* Save option settings */
|
||||
if (tcsetattr(fd, TCSANOW, &options) != 0) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
void uart::setMode(struct termios& options, UartModes mode) {
|
||||
void serial::setMode(struct termios& options, UartModes mode) {
|
||||
if (mode == UartModes::NON_CANONICAL) {
|
||||
/* Disable canonical mode */
|
||||
options.c_lflag &= ~ICANON;
|
||||
@ -12,7 +12,7 @@ void uart::setMode(struct termios& options, UartModes mode) {
|
||||
}
|
||||
}
|
||||
|
||||
void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
|
||||
void serial::setBaudrate(struct termios& options, UartBaudRate baud) {
|
||||
switch (baud) {
|
||||
case UartBaudRate::RATE_50:
|
||||
cfsetspeed(&options, B50);
|
||||
@ -114,7 +114,7 @@ void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
|
||||
}
|
||||
}
|
||||
|
||||
void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
|
||||
void serial::setBitsPerWord(struct termios& options, BitsPerWord bits) {
|
||||
options.c_cflag &= ~CSIZE; // Clear all the size bits
|
||||
if (bits == BitsPerWord::BITS_5) {
|
||||
options.c_cflag |= CS5;
|
||||
@ -127,11 +127,11 @@ void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
|
||||
}
|
||||
}
|
||||
|
||||
void uart::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
|
||||
void serial::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
|
||||
|
||||
void uart::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
|
||||
void serial::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
|
||||
|
||||
void uart::setParity(struct termios& options, Parity parity) {
|
||||
void serial::setParity(struct termios& options, Parity parity) {
|
||||
/* Clear parity bit */
|
||||
options.c_cflag &= ~PARENB;
|
||||
switch (parity) {
|
||||
@ -148,11 +148,11 @@ void uart::setParity(struct termios& options, Parity parity) {
|
||||
}
|
||||
}
|
||||
|
||||
int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
|
||||
int serial::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
|
||||
return ioctl(serialPort, TIOCGICOUNT, &icounter);
|
||||
}
|
||||
|
||||
void uart::setStopbits(struct termios& options, StopBits bits) {
|
||||
void serial::setStopbits(struct termios& options, StopBits bits) {
|
||||
if (bits == StopBits::TWO_STOP_BITS) {
|
||||
// Use two stop bits
|
||||
options.c_cflag |= CSTOPB;
|
||||
@ -161,3 +161,7 @@ void uart::setStopbits(struct termios& options, StopBits bits) {
|
||||
options.c_cflag &= ~CSTOPB;
|
||||
}
|
||||
}
|
||||
|
||||
void serial::flushRxBuf(int fd) { tcflush(fd, TCIFLUSH); }
|
||||
|
||||
void serial::flushTxRxBuf(int fd) { tcflush(fd, TCIOFLUSH); }
|
||||
|
@ -45,7 +45,7 @@ enum class UartBaudRate {
|
||||
RATE_4000000
|
||||
};
|
||||
|
||||
namespace uart {
|
||||
namespace serial {
|
||||
|
||||
void setMode(struct termios& options, UartModes mode);
|
||||
/**
|
||||
@ -64,8 +64,11 @@ void setParity(struct termios& options, Parity parity);
|
||||
|
||||
void ignoreCtrlLines(struct termios& options);
|
||||
|
||||
void flushRxBuf(int fd);
|
||||
void flushTxRxBuf(int fd);
|
||||
|
||||
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
||||
|
||||
} // namespace uart
|
||||
} // namespace serial
|
||||
|
||||
#endif /* FSFW_HAL_LINUX_UART_HELPER_H_ */
|
||||
|
Reference in New Issue
Block a user