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

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

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

Создайте файл 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. Соедините модель со словарем данных. На вкладке Modeling, под Design, нажимают Data Dictionary.

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

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

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

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

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

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

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

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

    • Number of inputs к 3

    • Output data type к Bus: inSigs_T

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

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

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

  5. Добавьте блок Outport после блока Bus Creator. Соедините выход Bus Creator к Outport.

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

  7. На вкладке Modeling нажмите 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. В модели выберите выходной сигнал блока Multiport 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, используйте числовые значения, которые Gain блокирует в модели, ранее используемой.

    • Для 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). Для получения дополнительной информации смотрите Замену и Переименуйте Типы данных, чтобы Соответствовать Кодированию Стандартов.

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

Похожие темы