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

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

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

Создайте файл 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. На панели инструментов редактора шин нажмите кнопку 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). Для получения дополнительной информации см. Раздел «Замена и переименование типов данных для соответствия стандартам кодирования».

См. также

Похожие темы