Создайте индивидуально настраиваемую асинхронную библиотеку

Эта тема описывает, как реализовать асинхронные блоки для использования с вашим целевым RTOS, с помощью Async Interrupt и блоков Task Sync как начальная точка. блоки Rate Transition независимы от цели, таким образом, вы не должны разрабатывать настроенные блоки перехода уровня.

Примечание

Методы интегрирования операционной системы, которые продемонстрированы в этом разделе, используют один или несколько блоков блоки в vxlib1 библиотека. Эти блоки обеспечивают примеры начальной точки, чтобы помочь вам разработать пользовательские блоки для своего целевого окружения.

О реализации асинхронных блоков

Можно настроить асинхронные библиотечные блоки путем изменения реализации блока. Эти файлы

  • Базовый файл MEX S-функции блока

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

Кроме того, необходимо изменить маски блока, чтобы удалить ссылки, характерные для примера RTOS (VxWorks®) и включить параметры, требуемые целевым RTOS.

Реализация пользовательского блока является усовершенствованной темой, требуя знакомства с форматом S-функции Simulink® MEX и API, и с Компилятором выходного языка (TLC). Эти темы затронуты в следующих документах:

Следующие разделы обсуждают C/C++ и реализации TLC асинхронных библиотечных блоков, включая необходимый SimStruct макросы и функции в асинхронной вспомогательной библиотеке TLC (asynclib.tlc).

Асинхронная реализация блока прерывания

Исходные файлы для блока Async Interrupt расположены в matlabroot/rtw/c/tornado/devices открытый:

  • vxinterrupt1.c: Исходный код файла MEX на C, для использования в настройке и симуляции

  • vxinterrupt1.tlc: Реализация TLC, для использования в генерации кода

  • asynclib.tlc: библиотека функций поддержки TLC, вызванных реализацией TLC блока. Вызовы библиотеки получены в итоге в asynclib.tlc Вспомогательной библиотеке.

C реализация блока MEX

Большая часть кода в vxinterrupt1.c выполняет обычные функции, которые не связаны с асинхронной поддержкой (например, получая и подтверждая параметры от маски блока, отмечая параметры ненастраиваемые, и передающие данные о параметре к model.rtw файл).

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

Обратите внимание на то, что следующие макросы не могут быть названы прежде ssSetOutputPortWidth называется:

  • ssSetTimeSource

  • ssSetAsyncTimerAttributes

  • ssSetAsyncTimerResolutionEl

  • ssSetAsyncTimerDataType

  • ssSetAsyncTimerDataTypeEl

  • ssSetAsyncTaskPriorities

  • ssSetAsyncTaskPrioritiesEl

Если одни из вышеупомянутых макросов называются прежде ssSetOutputPortWidth, следующее сообщение об ошибке появляется:

SL_SfcnMustSpecifyPortWidthBfCallSomeMacro {  
S-function '%s' in '%<BLOCKFULLPATH>'
must set output port %d width using
ssSetOutputPortWidth before calling macro %s
 }

ssSetAsyncTimerAttributes.  ssSetAsyncTimerAttributes объявляет, что блок требует таймера и устанавливает разрешение таймера, как задано для параметров блоков Timer resolution (seconds).

Прототип функции

ssSetAsyncTimerAttributes(SimStruct *S, double res)

где

  • S является указателем Simstruct.

  • Параметр Timer resolution (seconds) устанавливается на res.

Следующая выборка кода показывает вызов ssSetAsyncTimerAttributes.

/* Setup Async Timer attributes */
ssSetAsyncTimerAttributes(S,mxGetPr(TICK_RES)[0]);

ssSetAsyncTaskPriorities.  ssSetAsyncTaskPriorities устанавливает приоритет задач Simulink для блоков, выполняющихся на каждом уровне прерывания, как задано для параметров блоков Simulink task priority.

Прототип функции

ssSetAsyncTaskPriorities(SimStruct *S, int numISRs, 
                         int *priorityArray)

где

  • S SimStruct указатель.

  • numISRs количество прерываний, заданных для параметров блоков VME interrupt number(s).

  • priorityarray целочисленный массив, содержащий номера прерывания, заданные для параметров блоков VME interrupt number(s).

Следующая выборка кода показывает вызов ssSetAsyncTaskPriorities:

/* Setup Async Task Priorities */
    priorityArray = malloc(numISRs*sizeof(int_T));
    for (i=0; i<numISRs; i++) {
        priorityArray[i] = (int_T)(mxGetPr(ISR_PRIORITIES)[i]);
    }
    ssSetAsyncTaskPriorities(S, numISRs, priorityArray); 
    free(priorityArray);
    priorityArray = NULL;
}

Настройки SS_OPTION.  Выборка кода ниже показов SS_OPTION настройки для vxinterrupt1.c. SS_OPTION_ASYNCHRONOUS_INTERRUPT должен использоваться, когда подсистема вызова функции присоединена к прерыванию. Для получения дополнительной информации см. документацию для SS_OPTION и SS_OPTION_ASYNCHRONOUS в matlabroot/simulink/include/simstruc.h.

ssSetOptions( S, (SS_OPTION_EXCEPTION_FREE_CODE |
              SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME |
              SS_OPTION_ASYNCHRONOUS_INTERRUPT |

Если S-функция задает SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME опция и наследовала шаг расчета Inf, ​ генератор кода определяет, как произвести код для блока на основе того, является ли блок инвариантным. Блок является инвариантным, если его сигналы порта являются инвариантными. Сигнал является инвариантным, если он имеет постоянное значение во время целой симуляции. Если вы задаете шаг расчета блока Constant, не принимайте, что сигналы порта являются инвариантными. Для получения дополнительной информации ​ видят Встроенные Инвариантные Сигналы. Если блок не является инвариантным, ​ генератор кода производит код только в инициализировать функции точки входа. Если блок является инвариантным, ​ генератор кода не производит код для блока.

Реализация TLC

В этом разделе рассматриваются каждую функцию vxinterrupt1.tlc, с акцентом на целевые функции, которые необходимо будет изменить, чтобы сгенерировать код для целевого RTOS.

Сгенерируйте #include директивы.  vxinterrupt1.tlc начинается с оператора

%include "vxlib.tlc"

vxlib.tlc целевой файл, который генерирует директивы, чтобы включать заголовочные файлы для примера RTOS (VxWorks). Необходимо заменить это на файл, который генерирует, включает для целевого RTOS.

Функция BlockInstanceSetup.  Поскольку каждый соединил выход блока Async Interrupt, BlockInstanceSetup задает имя функции для соответствующего ISR в сгенерированном коде. Имена функций имеют форму

isr_num_vec_offset

где num номер ISR, заданный для параметров блоков VME interrupt number(s) и offset смещение таблицы прерываний, заданное параметрами блоков VME interrupt vector offset(s).

В пользовательской реализации это соглашение о присвоении имен является дополнительным.

Имена функций кэшируются для использования Outputs функция, которая генерирует фактический код ISR.

Выходная функция.  Outputs выполняет итерации по связанным выходным параметрам блока Async Interrupt. ISR сгенерирован для каждого такого выхода.

Код ISR кэшируется в "Functions" раздел сгенерированного кода. Прежде, чем сгенерировать ISR, Outputs делает следующее:

  • Генерирует вызов нисходящего блока (кэшируемый во временном буфере).

  • Определяет, должен ли ISR быть заблокирован или не (как задано параметрами блоков Preemption Flag(s)).

  • Определяет, является ли блок, соединенный с блоком Async Interrupt, блоком Task Sync. (Эта информация получена при помощи asynclib вызовы LibGetFcnCallBlock и LibGetBlockAttribute.) Если так,

    • Флаг вытеснения для ISR должен быть установлен в 1. Ошибка заканчивается в противном случае.

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

При генерации кода ISR, Outputs вызывает asynclib функция LibNeedAsyncCounter определить, требуется ли таймер связанной подсистемой. Если так, и если источник времени собирается быть SS_TIMESOURCE_SELF ssSetTimeSource, LibSetAsyncCounter называется, чтобы сгенерировать RTOS (VxWorks) tickGet вызов функции и обновление счетчик. В вашей реализации необходимо сгенерировать или эквивалентный вызов целевого RTOS или сгенерировать код, чтобы считать регистр таймера на целевом компьютере.

Запустите функцию.  Start функция генерирует необходимый RTOS (VxWorks) вызовы (int_connect и sysInt_Enable) соединить и включить каждый ISR. Необходимо заменить это на вызовы целевого RTOS.

Оконечная функция.  Terminate функция генерирует вызов sysIntDisable отключить каждый ISR. Необходимо заменить это на вызовы целевого RTOS.

Синхронизация задачи блокирует реализацию

Исходные файлы для блока Task Sync расположены в matlabroot/rtw/c/tornado/devices открытый. Они

  • vxtask1.cpp: Исходный код файла MEX, для использования в настройке и симуляции.

  • vxtask1.tlc: Реализация TLC, для использования в генерации кода.

  • asynclib.tlc: библиотека функций поддержки TLC, вызванных реализацией TLC блока. Вызовы библиотеки получены в итоге в asynclib.tlc Вспомогательной библиотеке.

C реализация блока MEX

Как блок Async Interrupt, блок Task Sync настраивает таймер, в этом случае с фиксированным разрешением. Приоритет задачи, сопоставленной с блоком, получен из параметров блоков Simulink task priority. SS_OPTION настройки совпадают с используемыми для блока Async Interrupt.

ssSetAsyncTimerAttributes(S, 0.01);

priority  = (int_T) (*(mxGetPr(PRIORITY)));
ssSetAsyncTaskPriorities(S,1,&priority);

ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE |
                 SS_OPTION_ASYNCHRONOUS |
                 SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME |
}

Реализация TLC

Сгенерируйте #include директивы.  vxtask1.tlc начинается с оператора

%include "vxlib.tlc"

vxlib.tlc целевой файл, который генерирует директивы, чтобы включать заголовочные файлы для примера RTOS (VxWorks). Необходимо заменить это на файл, который генерирует, включает для целевого RTOS.

Функция BlockInstanceSetup.  BlockInstanceSetup функция выводит имя задачи, имя блока и другие идентификаторы, используемые позже в генерации кода. Это также проверяет на и предупреждает о несвязанных условиях блока и генерирует объявление устройства хранения данных для семафора (stopSem) это используется в случае условий переполнения прерывания.

Запустите функцию.  Start функция генерирует необходимый RTOS (VxWorks) вызовы, чтобы задать устройство хранения данных для семафора, который используется в управлении задачей, порожденной блоком Task Sync. В зависимости от значения CodeFormat Переменная TLC цели, или статическое объявление устройства хранения данных или вызов динамического выделения памяти сгенерированы. Эта функция также создает семафор (semBCreate) и порождает задачу RTOS (taskSpawn). Необходимо заменить их на вызовы целевого RTOS.

Выходная функция.  Outputs функция генерирует пример RTOS (VxWorks) задача, которая ожидает семафора. Когда это получает семафор, это обновляет таймер метки деления блока и вызывает нисходящий код подсистемы, как описано в Икре, и Синхронизируйте Выполнение Задачи RTOS. Outputs также генерирует код (названный от уровня прерывания), который предоставляет семафор.

Оконечная функция.  Terminate функция генерирует пример RTOS (VxWorks) вызов taskDelete закончить выполнение задачи, порожденной блоком. Необходимо заменить это на вызовы целевого RTOS.

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

Вспомогательная библиотека asynclib.tlc

asynclib.tlc библиотека функций TLC, которые поддерживают реализацию асинхронных блоков. Некоторые функции специально предназначены для использования в асинхронных блоках. Например, LibSetAsyncCounter генерирует вызов, чтобы обновить таймер для асинхронного блока. Другие функции являются утилитами, которые возвращают информацию, запрошенную асинхронными блоками (например, информацию о связанных подсистемах вызова функции).

Следующая таблица обобщает общедоступные вызовы в библиотеке. Для получения дополнительной информации см. исходный код библиотеки и vxinterrupt1.tlc и vxtask1.tlc файлы, которые вызывают библиотечные функции.

Сводные данные asynclib.tlc Библиотечных функций

Функция

Описание

LibBlockExecuteFcnCall

Для использования встроенными S-функциями с вызовом функции выходные параметры. Генерирует код, чтобы выполнить подсистему вызова функции.

LibGetBlockAttribute

Возвращает значение поля от записи блока.

LibGetFcnCallBlock

Учитывая Блок s-function и индекс вызова, возвращает запись блока для нисходящего блока подсистемы вызова функции.

LibGetCallerClockTickCounter

Обеспечивает доступ к счетчику времени восходящей асинхронной задачи.

LibGetCallerClockTickCounterHighWord

Обеспечивает доступ к высокому слову счетчика времени восходящей асинхронной задачи.

LibManageAsyncCounter

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

LibNeedAsyncCounter

Если блок вызова требует асинхронного счетчика, возвращает TLC_TRUE, в противном случае возвращает TLC_FALSE.

LibSetAsyncClockTicks

Возвращает код, который устанавливает clockTick счетчики, которые должны быть обеспечены асинхронной задачей.

LibSetAsyncCounter

Генерирует код, чтобы установить значение деления асинхронного счетчика блока.

LibSetAsyncCounterHighWord

Генерирует код, чтобы установить значение деления высокого слова асинхронного счетчика блока

Похожие темы