Для меня стояла задача главным образом унифицировать разбор кадров телеметрии, выполнять отображение данных и сохранение их в файлы. При этом физический канал передачи данных и используемый протокол не важны для этой задачи, и могут меняться в зависимости от треований к конкретному девайсу. Каждое устройство имеет версию в формате major.minor.build. Данные телеметрии передаются кадрами. Каждый кадр имеет свой идентификатор типа и состоит из полей телеметрии. Поле - это логически связанная часть информации. Т.о, зная версию устройства и тип кадра телеметрии можно в принципе одночзначно сказать что содержится в этом кадре. Но для интерпретации содержимого кадра нужны метаданные, описывающие из каких полей он состоит. У меня эти метаданные для устройства каждого типа содержатся в xml-файлах. С помощью этих конфигурационных файлов задаются форматы телеметрии, графическифй интерфейс для отображения данных и то, в какие файлы и как записывать эти данные. Всё это реализовано в виде приложения на Java.
Так описывается формат телеметрии:
<!-- Описание форматов кадров телеметрии-->
<telemetry-format mode="0">
<field id="0" type="FIXED16" length="320" name="Сигнал со второго каскада"/>
<field id="1" type="FIXED16" length="320" name="Сигнал с первого каскада"/>
<field id="param_1" type="INT16" length="1" name="Параметр 1"/>
<field id="param_2" type="BOOL" length="1" name="Параметр 2"/>
<field id="param_3" type="FIXED16" length="1" name="Параметр 3"/>
</telemetry-format>
<telemetry-format mode="1">
<field id="param_1" type="INT16" length="1" name="Параметр 1"/>
<field id="param_2" type="BOOL" length="1" name="Параметр 2"/>
<field id="param_3" type="FIXED16" length="1" name="Параметр 3"/>
</telemetry-format>
Т.е каждому полю телеметрии присваивается строковый идентификатор, напримет '0', '1', 'param_1', который используется для ссылок на это поле.
кроме того, можно указывать тип данных, кол-во элементов и описание.
графический интерфейс отображения данных тоже конфигурируется в XML. Может это кому-то покажется недостатком, но для написания GUI нужно знать Swing.
Хотя можно придумать свой формат описания.
<telemetry-viewer>
<panel layout="borderlayout" constraints="BorderLayout.CENTER">
<!-- Панель телеметрии алгоритма -->
<splitpane oneTouchExpandable="true" dividerLocation="250" resizeWeight="0.4" ContinuousLayout="true" orientation="JSplitPane.VERTICAL_SPLIT">
<splitpane oneTouchExpandable="true" dividerLocation="350" resizeWeight="0.5" orientation="JSplitPane.HORISONTAL_SPLIT">
<chart title="Сигнал с первого каскада" xScale="0.00333333" pointsNumber="3600">
<axis range="-1.0,1.0" title="" autorange="true">
<series color="blue" streamId="1"/>
</axis>
</chart>
<chart title="Сигнал со второго каскада" xScale="0.00333333" pointsNumber="3600">
<axis range="-1.0,1.0" title="" autorange="true">
<series color="blue" streamId="0"/>
</axis>
</chart>
</splitpane>
<chart title="Параметры 1,2,3" xScale="1" pointsNumber="150">
<axis range="-0.01,1" title="1, 2, 3" autorange="true">
<series color="red" streamId="param_1" linewidth="1"/>
<series color="blue" streamId="param_2" linewidth="1"/>
<series color="green" streamId="param_3" linewidth="1"/>
</axis>
</chart>
</splitpane>
</panel>
</telemetry-viewer>
И запись в файлы. В принципе тоже ничего особенного:
<telemetry-writer modes="0,1">
<file name="01_insig.txt" type="column" lineFormat="%f %f" fieldsId="0,1"/>
<file name="02_params.txt" type="column" lineFormat="%f %f %f" fieldsId="param_1,param_2,param_3"/>
</telemetry-writer>
В прикрепленном файле показан сгенерированный на основе описания интерфейс.
Т.о, в приложении есть набор конфигурационных файлов для каждой версии устройства. Как показала практика, такой подход достаточно удобный и наглядный. Есть конечно и недостатки, но это из-за нехватки времени на более качественную реализацию.
И еще дополнение про реализацию для МК.
Инициатором передачи может быть как сам девайс, так и ПК, в зависимости от используемого протокола.
В программе МК вывод осуществляется через такую функцию
Bool tm_put_telemetry_data(TelemetryField type, int const* data, int nBytes);
где список полей задан в перечислении:
typedef enum {
TM_Signal_Chan1=0,
TM_Signal_Chan2,
TM_Parameter1,
TM_Parameter2,
TM_Parameter3,
} TelemetryField;
Для удобства, вызов tm_put_telemetry_data "обертывается" в функции для каждого конкретного параметра:
void telemetry_write_parameter2(Bool value) {
tm_put_telemetry_data(TM_Parameter2, &value, sizeof(Bool));
}
В момент, когда все поля заполнены, вызывается функция
set_telemetry_data_ready() и начинается передача.
Формат кадров телеметрии в МК объявляется декларативно, так что с этим проблем обычно не возникает.