CTS-SAT-1-OBC-Firmware
|
Satellites do things both as a result of us earthlings sending telecommands, as a result of scheduled telecommands, and as a result of other autonomous actions (e.g., automatically turning off subsystems when the power gets low).
Nearly everything the satellite does must be logged so that it can be audited in the case of problems.
In general embedded systems development, you commonly print data to a UART terminal for debugging purposes. The DEBUG_uart_print_str(...)
function is used for this purpose.
This is a simple and effective way to debug code, but it is not a good way to log data in a satellite. We can't plug a UART cable into a satellite flying through space at 8 km/s.
The logging system on this satellite is rather simple: call the LOG_message(...)
function with the message you want, and it will be logged to a file, sent over the radio, stored in memory, and passed through the umbilical UART debug console (if connected on earth).
LOG_message(...)
YOU, a developer, must use the LOG_message(...)
function. Here's how:
.c
file, include: #include "log/log.h"
LOG_message(...)
with the message you want to log with the relevant subsystem, log severity, which sinks (LOG_SINK_ALL
by default), a message, and any printf-like arguments for format strings in the message: LOG_message(...)
Args:The following are very small and specific details about the arguments to LOG_message(...)
.
There are several subsystems, defined in an enum in log/log.h
. Use the right one.
There are several log levels, defined in an enum.
Sometimes, stuff works (use LOG_SEVERITY_NORMAL
). Sometimes it doesn't (use LOG_SEVERITY_WARNING
or LOG_SEVERITY_ERROR
). Sometimes, the thing not working can cause other things to not work (use LOG_SEVERITY_CRITICAL
).
There are several sinks (i.e., log message destinations):
Generally, all log messages should go to all sinks (LOG_SINK_ALL
).
Sometimes, however, there may be a time where you want to exclude a specific sink. For example, if you are logging a message saying "using the filesystem failed", you probably don't want to log that message to the failing filesystem. In such a case, use LOG_all_sinks_except(LOG_SINK_FILE)
.
Several sinks can chained together with the bitwise OR operator (|
). For example, to log to the UART and the radio, use LOG_SINK_UART | LOG_SINK_RADIO
. To log to everything except the filesystem and radio, use LOG_all_sinks_except(LOG_SINK_FILE | LOG_SINK_RADIO)
.
The timekeeping clock on satellites drifts due to temperature variations, inaccuracies in the crystal oscillator, etc; it is re-synced with the GNSS and/or ground station every so often.
The system time is stored in "unix timestamp format" (seconds since 1970-01-01). This is a very well-known date/time representation.
In the log printouts, each log is shown in the format of the following example:
The timestamp on logs is stored in "sync time + source + offset" format. In the example above, the fields are:
T
, meaning the time was last synced via the set_system_time()
telecommand.CTS1+set_system_time(1723331067154)!
.By adding together the sync time and the offset, the absolute order of the log message can be determined by sorting the logs lexicographically (i.e., first by the sync time value, then by the offset value).
The timestamp for each log message could be stored as just a single number of ms since 1970-01-01, but the "sync time + source + offset" format is used to allow absolute chronological sorting of the logs, even if the satellite's time moves "backwards" during a time sync.
For more information about the timestamp format, see the Timestamp Format Rationale docs.
In the log printouts, each log is shown in the format of the following example:
In the first log example, T:
indicates that the "log context" (the reason the log call was executed) is an immediate telecommand. In the second example, A:
indicates that the attempted EPS communication was autonomous.
The following "log contexts" exist: