Обменивайтесь структурированными и перечислимыми данными между сгенерированным и внешним кодом

Этот пример показывает, как сгенерировать код, который обменивается данными с внешним, существующим кодом. Создайте и сконфигурируйте модель, чтобы совпадать с типами данных внешнему коду и постараться не копировать определения типа и выделение памяти (определение глобальных переменных). Затем скомпилируйте сгенерированный код вместе с внешним кодом в отдельное приложение.

Осмотрите внешний код

Создайте файл ex_cc_algorithm.c в вашей текущей папке.

#include "ex_cc_algorithm.h"

inSigs_T inSigs;

float_32 my_alg(void)
{
    if (inSigs.err == TMP_HI) {
        return 27.5;
    }
    else if (inSigs.err == TMP_LO) {
        return inSigs.sig1 * calPrms.cal3;
    }
    else {
        return inSigs.sig2 * calPrms.cal3;
    }
}
        

Код С задает глобальную переменную структуры под названием inSigs. Код также задает функцию, my_alg, который использует inSigs и другую переменную структуры под названием calPrms.

Создайте файл ex_cc_algorithm.h в вашей текущей папке.

#ifndef ex_cc_algorithm_h
#define ex_cc_algorithm_h

typedef float float_32;

typedef enum {
    TMP_HI = 0,
    TMP_LO,
    NORM,
} err_T;

typedef struct inSigs_tag {
    err_T err;
    float_32 sig1;
    float_32 sig2;
} inSigs_T;

typedef struct calPrms_tag {
    float_32 cal1;
    float_32 cal2;
    float_32 cal3;
} calPrms_T;

extern calPrms_T calPrms;
extern inSigs_T inSigs;

float_32 my_alg(void);

#endif

Файл задает float_32 как псевдоним типа данных C float. Файл также задает перечислимый тип данных, err_T, и два типа структуры, inSigs_T и calPrms_T.

Функциональный my_alg разработан, чтобы вычислить возвращаемое значение при помощи полей inSigs и calPrms, которые являются глобальными переменными структуры типов inSigs_T и calPrms_T. Функция требует, чтобы другой алгоритм предоставил данные сигнала, которые хранит inSigs.

Этот код выделяет память для inSigs, но не для calPrms. Создайте модель чей сгенерированный код:

  • Задает и инициализирует calPrms.

  • Вычисляет значения для полей inSigs.

  • Снова использует определения типа (такие как err_T и float_32), который задает внешний код.

Создайте модель Simulink

  1. Так, чтобы можно было создать перечисленные и структурированные данные в модели Simulink®, сначала создать представления Simulink типов данных, которые задает внешний код. Сохраните типы Simulink в новом словаре данных под названием ex_cc_integ.sldd.

    Simulink.importExternalCTypes('ex_cc_algorithm.h',...
        'DataDictionary','ex_cc_integ.sldd');
    

    Словарь данных появляется в вашей текущей папке.

  2. Чтобы осмотреть содержимое словаря в Model Explorer, в вашей текущей папке, дважды кликают файл, ex_cc_integ.sldd.

    Функция Simulink.importExternalCTypes создает Simulink.Bus, Simulink.AliasType и объекты Simulink.data.dictionary.EnumTypeDefinition, которые соответствуют пользовательским типам данных C от ex_cc_algorithm.h.

  3. Создайте новую модель и сохраните ее в своей текущей папке как ex_struct_enum_integ.

  4. Соедините модель со словарем данных. В модели выберите File> Model Properties> Link to Data Dictionary.

  5. Добавьте алгоритмические блоки, которые вычисляют поля inSigs.

Теперь, когда у вас есть модель алгоритма, вы должны:

  • Организуйте выходные сигналы в переменную структуры под названием inSigs.

  • Создайте переменную calPrms структуры.

  • Включайте ex_cc_algorithm.c в процесс сборки, который компилирует код после генерации кода.

Сконфигурируйте сгенерированный код, чтобы записать выходные данные в существующую переменную структуры

  1. Добавьте блок Bus Creator около существующих блоков Выходного порта. Вывод блока Bus Creator является сигналом шины, который можно сконфигурировать, чтобы появиться в сгенерированном коде как структура.

  2. В блоке Bus Creator, установленном эти параметры:

    • Number of inputs к 3

    • Output data type к Bus: inSigs_T

    • Output as nonvirtual bus к выбранному

  3. Удалите три существующих блока Выходного порта (но не сигналы, которые вводят блоки).

  4. Соедините три остающихся сигнальных линии с входными параметрами блока Bus Creator.

  5. Добавьте блок Outport после блока Bus Creator. Соедините вывод Создателя Шины к Выходному порту.

  6. В блоке Outport, установленном параметр Data type на Bus: inSigs_T.

  7. В модели выберите View> Model Data Editor.

  8. На вкладке Inports/Outports, для блоков Inport маркировал In2 и In3, изменение Data Type от Inherit: auto до float_32.

  9. Измените Change View выпадающий список от Design до Code.

  10. Для блока Outport, набор Signal Name к inSigs.

  11. Установите Storage Class на ImportFromFile.

  12. Установите Header File на ex_cc_algorithm.h.

  13. Осмотрите вкладку Signals.

  14. В модели выберите выходной сигнал Многопортового блока switch.

  15. В Model Data Editor, для выбранного сигнала, устанавливает Name на err.

  16. Определите имя выходного сигнала блока Gain к sig1.

  17. Определите имя выходного сигнала блока Gain1 к sig2.

Когда вы закончили, модель хранит данные о выходном сигнале (такие как сигналы err и sig1) в областях переменной структуры под названием inSigs.

Поскольку вы устанавливаете Storage Class на ImportFromFile, сгенерированный код не выделяет память для inSigs.

Сконфигурируйте сгенерированный код, чтобы задать данные о параметре

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

  1. В панели Model Hierarchy Model Explorer, под узлом словаря ex_cc_integ, выбирают узел Design Data.

  2. В панели Contents выберите объект Simulink.Bus calPrms_T.

  3. В Диалоговой панели (правая панель), нажмите Launch Bus Editor.

  4. В Редакторе Шины, на левой панели, выбирают calPrms_T.

  5. На панели инструментов Bus Editor нажмите кнопку Create/Edit a Simulink.Parameter Object from a Bus Object.

  6. В редакторе MATLAB скопируйте сгенерированный код MATLAB и запустите код в командной строке. Код создает объект Simulink.Parameter в базовом рабочем пространстве.

  7. В панели Model Hierarchy Model Explorer выберите Base Workspace.

  8. Используйте Model Explorer, чтобы переместить объект параметра, calPrms_T_Param, от базового рабочего пространства до раздела Design Data словаря данных.

  9. С выбранным словарем данных, в панели Contents, переименовывают объект параметра как calPrms.

  10. В Model Data Editor выберите вкладку Parameters.

  11. Установите Change view выпадающий список на Design.

  12. Для блока Gain замените значение 13.8900013 на calPrms.cal1.

  13. В другом блоке Gain используйте calPrms.cal2.

  14. В то время как редактирование значения другого блока Gain, рядом с calPrms.cal2, кликает по кнопке действий и выбирает calPrms> Open.

  15. В диалоговом окне свойства calPrms, рядом с полем Value, кликают по кнопке действий и выбирают Open Variable Editor.

  16. Используйте Редактора переменных, чтобы установить значения полей в объекте параметра.

    • Для полей cal1 и cal2 используйте числовые значения, которые Усиление блокирует в модели, ранее используемой.

    • Для cal3 используйте ненулевой номер, такой как 15.2299995.

    Когда вы закончили, закрываете Редактора переменных.

  17. В диалоговом окне свойства, набор Storage class к ExportedGlobal. Нажмите OK.

  18. Используйте Model Explorer, чтобы сохранить изменения, которые вы внесли в словарь.

Сгенерируйте, скомпилируйте и осмотрите код

  1. Сконфигурируйте модель, чтобы включать ex_cc_algorithm.c в процесс сборки. Установите Configuration Parameters> Code Generation> Custom Code> Additional build information> Source files к ex_cc_algorithm.c.

  2. Сгенерируйте код из модели.

  3. Осмотрите сгенерированный файл ex_struct_enum_integ.c. Файл задает и инициализирует calPrms.

    /* Exported block parameters */
    calPrms_T calPrms = {
      13.8900013F,
      0.998300076F,
      15.23F
    } ;                                    /* Variable: calPrms
    

    Сгенерированный алгоритм в функции модели step задает локальную переменную для буферизации значения err сигнала.

    err_T rtb_err;
    

    Алгоритм затем вычисляет и хранит данные в областях inSig.

    inSigs.err = rtb_err;
    inSigs.sig1 = (rtU.In2 + rtDW.DiscreteTimeIntegrator_DSTATE) * calPrms.cal1;
    inSigs.sig2 = (real32_T)(calPrms.cal2 * rtDW.DiscreteTimeIntegrator_DSTATE);
    

Замените имена типов данных в модели

Чтобы сгенерировать код, который использует float_32 вместо значения по умолчанию, real32_T, вместо того, чтобы вручную задать типы данных выходных сигналов блока и элементов шины, можно использовать замену типа данных (Configuration Parameters> Code Generation> Data Type Replacement). Для получения дополнительной информации смотрите Замену и Переименуйте Типы данных, чтобы Соответствовать Кодированию Стандартов.

Смотрите также

Похожие темы