Формат описания встроенной структуры

У меня есть структура C, которая позволяет пользователям настраивать параметры встроенной системы. В настоящее время графический интерфейс, который мы используем для этого, специально написан для каждой версии этой структуры конфигурации. Я хотел бы иметь возможность описывать элементы структуры в некотором формате, который может быть прочитан клиентским приложением конфигурации, что делает его универсальным для всех наших систем.

Я экспериментировал с описанием структуры в XML и заставлял клиента читать файл; это работает в большинстве случаев, кроме тех, где некоторые поля взаимозависимы. Таким образом, формат, который я использую, должен иметь способ их указать; например, элемент A всегда должен быть меньше или равен половине элемента B.

Заранее спасибо за ваши мысли и предложения.

ИЗМЕНИТЬ:

Прочитав первый ответ, я понял, что мой вопрос действительно слишком расплывчатый, поэтому вот еще одна попытка:

Встроенная система должна иметь доступ к данным в виде структуры C, запуск любого другого языка на процессоре невозможен. По сути, все, что мне нужно, это способ определить метаданные со структурой, эти метаданные будут загружены на флэш-память вместе с прошивкой. Утилита конфигурации клиента затем прочитает файл метаданных через RS-232, CAN и т. д. и заполнит окно (древовидное представление), которое пользователь может затем использовать для редактирования параметров.

XML-файл, о котором я упоминал, делал именно это, он содержал имя члена структуры, тип данных, количество элементов и т. д. Расположение члена в XML-файле неявно определяло его положение в структуре C. Этот файл находится на флэш-памяти и считывается программой конфигурации; единственное, чего не хватает, — это способа определения зависимостей между полями структуры.

Код генерируется автоматически с помощью MATLAB / Simulink, поэтому у меня есть доступ к языку сценариев, чтобы помочь с созданием структуры. Например, если я в конечном итоге использую XML, структура будет определена только в формате XML, и я буду использовать сценарий для создания структуры C во время генерации кода.

Надеюсь, это понятнее.


person Praetorian    schedule 15.03.2010    source источник


Ответы (3)


В простом случае, когда отношения либо нет, либо есть отношение с одним другим полем, вы можете добавить в структуру два поля: номер «другого» поля и указатель на функцию, которая их сравнивает. Затем вам нужно будет создать функции, которые сравнивают два значения и возвращают true или false в зависимости от того, соблюдаются ли отношения. Предположим, вам нужно создать две функции, которые проверяют связь и обратную связь (т. е. если поле 1 должно быть больше, чем поле 2, то поле 2 должно быть меньше или равно полю 1). Если вам нужно наложить более одного ограничения на диапазон, вы можете сохранить указатель на список пар функция/поле.

Альтернативой является создание функции проверки для каждого поля и вызов ее при изменении поля. Очевидно, что эта функция может быть настолько сложной, насколько вы хотите, но может потребовать больше ручного кодирования.

Теоретически вы можете сгенерировать функции проверки для любого из вышеперечисленных методов из описания XML, которое вы описали.

person jamesv    schedule 17.03.2010

Я ожидал, что вы уже получите некоторые ответы, но позвольте мне посмотреть, что я могу сделать.

Ваш вопрос немного расплывчатый, но похоже, что вы хотите один из

  • Генерация кода
  • Встроенный язык расширений
  • Написанный вручную мини-язык времени выполнения

Генерация кода

Вы говорите, что в настоящее время вручную обрабатываете код конфигурации каждый раз, когда меняете это. Готов поспорить, что это очень повторяющаяся задача, поэтому нет никаких причин, по которым вы не можете написать программу, которая сделает это за вас. Ваш генератор должен использовать какой-то специфичный для предметной области язык и создавать код C и файлы заголовков, которые вы впоследствии встраиваете в свое приложение. Примером того, о чем я здесь говорю, может быть GNU gengetopt. Нет ничего плохого в идее использования xml в качестве языка ввода.

Преимущества:

  • полученный код может быть как быстрым, так и компактным
  • нет необходимости в интерпретаторе, работающем на целевой платформе

Недостатки:

  • надо написать генератор
  • изменение вещей требует перекомпиляции

Язык расширения

Tcl, python и другие языки хорошо работают в сочетании с кодом c и позволят вам указать поведение конфигурации на динамическом языке, а не возиться с типизацией c и строками, и, и...

Преимущества:

  • динамический язык, вероятно, означает, что код конфигурации проще
  • изменить параметры конфигурации без перекомпиляции

Недостатки:

  • вам нужен динамический язык, работающий на целевой платформе

Мини язык

Вы можете написать свой собственный встроенный мини-язык.

Преимущества:

  • Нет необходимости перекомпилировать
  • Поскольку вы пишете это, оно будет работать на вашей цели

Недостатки:

  • Вы должны написать это сами
person dmckee --- ex-moderator kitten    schedule 15.03.2010

Насколько структура меняется от версии к версии? Когда я делал такие вещи, я жестко запрограммировал их в приложение для ПК, которое затем определяло, что означает пакет, исходя из версии прошивки, но единственными изменениями обычно были дополнительное поле, добавляемое в конце каждые пару месяцев.

Я полагаю, что я бы использовал что-то вроде следующего, если бы хотел пойти по маршруту метаданных.

typedef struct
{
    unsigned char field1;
    unsigned short field2;
    unsigned char a_string[4];
} data;

typedef struct
{
    unsigned char name[16];
    unsigned char type;
    unsigned char min;
    unsigned char max;
} field_info;

field_info fields[3];

void init_meta(void)
{
    strcpy(fields[0].name, "field1");
    fields[0].type = TYPE_UCHAR;
    fields[0].min = 1;
    fields[0].max = 250;

    strcpy(fields[1].name, "field2");
    fields[1].type = TYPE_USHORT;
    fields[1].min = 0;
    fields[1].max = 0xffff;

    strcpy(fields[2].name, "a_string");
    fields[2].type = TYPE_STRING;
    fields[2].min = 0 // n/a
    fields[2].max = 0 // n/a
}

void send_meta(void)
{
    rs232_packet packet;

    memcpy(packet.payload, fields, sizeof(fields));

    packet.length = sizeof(fields);

    send_packet(packet);
}
person James    schedule 15.03.2010
comment
Джеймс, это почти идентично тому, что я сделал с XML для описания метаданных. Встроенному коду не нужен доступ к метаданным, поэтому IMO проще сделать это в XML или чем-то подобном, потому что проще описать вложенные структуры и т. д., чем с C. В любом случае, в любом случае, проблема, с которой я сталкиваюсь, заключается в указании inter -зависимость между полями. Из ответов на данный момент кажется, что для действительно общего решения этой проблемы мне нужно придумать какой-то метод для идентификации полей структуры и написать синтаксический анализатор для некоторых простых арифметических проверок. - person Praetorian; 16.03.2010