Semántica de los subsistemas de Simulink
Este conjunto de ejemplos muestra diferentes tipos de subsistemas de Simulink® y qué semántica se usa al simular estos subsistemas. Cada ejemplo proporciona una descripción del modelo y las sutilezas que rigen cómo se ejecuta el modelo.
Se proporcionan ejemplos para los tipos de subsistemas.
Virtual Subsystems y Nonvirtual Subsystems
Function-Call Subsystems
Triggered Subsystems
Enabled Subsystems
Enabled and Triggered Subsystems
If Action Subsystem y Switch Case Action Subsystem
While Iterator Subsystems
For Each Subsystems
For Iterator Subsystems
Abra los modelos.
open('SimulinkSubsystemSemantics.prj'); open_system('sl_subsys_semantics');
Visión general de los subsistemas virtuales y no virtuales
El software de Simulink tiene dos clases de subsistemas.
Los subsistemas virtuales proporcionan una jerarquía gráfica en los modelos. Los subsistemas virtuales no afectan a la ejecución de los modelos. Durante la ejecución de los modelos, el motor de Simulink convierte todos los subsistemas virtuales en jerarquía plana.
Los subsistemas no virtuales proporcionan jerarquía de ejecución y gráfica en los modelos. Los subsistemas no virtuales se ejecutan como una sola unidad, lo que se conoce como ejecución atómica. Todos los subsistemas no virtuales aparecen con un borde resaltado en el área de diseño de Simulink.
open_system('sl_subsys_semantics'); open_system('sl_subsys_semantics/Virtual and nonvirtual subsystem overview');
Para crear un subsistema no virtual, haga clic con el botón secundario en el bloque Subsystem y seleccione Block Parameters (Subsystem). En el cuadro de diálogo Block Parameters, seleccione Treat as atomic unit y haga clic en Apply.
El subsistema virtual da como resultado una lista de ejecución plana, mientras que el subsistema no virtual incluye una jerarquía de ejecución. Para mostrar el orden de ejecución, en el editor de Simulink, en la pestaña Debug, seleccione Information Overlays y haga clic en Execution order.
En el área de diseño de Simulink aparece una lista con el orden de ejecución de los bloques.
La lista con el orden de ejecución de los bloques muestra que el subsistema no virtual Subsystem2
se ejecuta como una sola unidad.
Un subsistema no virtual da como resultado un bucle algebraico dentro de la jerarquía de ejecución. Cuando se actualiza el diagrama, el software genera una advertencia sobre el bucle algebraico.
set_param(gcs,'SimulationCommand','Update')
Warning: Block diagram 'sl_subsys_overview' contains 1 algebraic loop(s). To see more details about the loops use the command <a href="matlab:Simulink.BlockDiagram.getAlgebraicLoops(bdroot);">Simulink.BlockDiagram.getAlgebraicLoops('sl_subsys_overview') </a> or the command line Simulink debugger by typing <a href="matlab:sldebug(bdroot);">sldebug('sl_subsys_overview') </a> in the MATLAB command window. To eliminate this message, set Algebraic loop to "none".
Function-Call Subsystems
Un bloque Function-Call Subsystem contiene un subsistema ejecutado de manera condicional que se ejecuta cada vez que el puerto de control recibe un evento de llamada a función. Los subsistemas de llamada a función implementan funciones invocables usando bloques de Simulink. Un Chart (Stateflow) de Stateflow®, un bloque Function-Call Generator, un bloque MATLAB Function, un bloque S-Function o un bloque Hit Crossing pueden proporcionar eventos de llamada a función.
Para obtener más información, consulte Function-Call Subsystem.
Estos ejemplos muestran usos válidos y no válidos de los subsistemas de llamada a función.
close_system('sl_subsys_overview',0) open_system('s_Function_call_subsystems')
Llamada a función anidada
En este modelo, el bloque Chart es un iniciador de llamada a función que ejecuta la función, [d1,d2]=f()
. La función f
, a su vez, ejecuta la función g
. Después de invocar a f
y g
, el bloque Chart usa los valores d1
y d2
calculados por f
y g
.
open_system('sl_subsys_fcncall1')
close_system('sl_subsys_fcncall1')
Llamada a función anidada con uso compartido de datos
El bloque Chart ejecuta la función, [d1,d2]=f()
, y f
, a su vez, ejecuta g
. Después de invocar a f
, el bloque Chart usa los valores d1
y d2
calculados por f
y g
. Las funciones f
y g
comparten datos a través de la señal s(f/Out2 feeds g/In1)
. Simulink trata la señal s
como si la señal fuera un almacén de datos.
open_system ('sl_subsys_fcncall2')
En general, las entradas para un subsistema de llamada a función deben ejecutarse antes del iniciador de la llamada a función (Chart), excepto cuando la señal viene de un bloque ejecutado por un iniciador de llamada a función común. En este ejemplo, f()
es un iniciador de llamada a función de g()
. Sin embargo, el bloque Chart es un iniciador de llamada a función de f()
, lo que convierte al bloque Chart en un iniciador de llamada a función común tanto de f()
como de g()
.
En ese sentido, la señal s
siguiente se puede considerar como un almacén de datos donde f()
y g()
pueden leer y escribir en cualquier orden definido por el bloque Chart.
close_system('sl_subsys_fcncall2')
Compartir datos entre dos subsistemas de llamada a función con iniciador común
El bloque Chart ejecuta las funciones d1=g()
y d2=f()
invocando f()
d
g()
y, después, usando d1
y d2 calculados por g()
y f()
. Las funciones f
y g
comparten datos a través de la señal s
. (f/Out1)
alimenta (g/In1)
. El software trata la señal s
como si la señal fuera un almacén de datos.
open_system ('sl_subsys_fcncall3')
En general, las entradas para un subsistema de llamada a función deben ejecutarse antes del iniciador de la llamada a función (Chart), excepto cuando la señal viene de un bloque ejecutado por un iniciador de llamada a función común. En este ejemplo, el bloque Chart es un iniciador de llamada a función común tanto de f()
como de g()
. Por lo tanto, la señal s
se puede considerar un almacén de datos.
close_system('sl_subsys_fcncall3')
Subsistema activado que contiene un iniciador de llamada a función con uso compartido de datos
Este subsistema activado contiene un gráfico de Stateflow que llama a las funciones f()
y g()
. El subsistema activado en el modelo sl_subsys_fcncall3
es un iniciador de llamada a función común tanto de f()
como de g()
, de forma que el software trata la señal d2
como un almacén de datos.
open_system ('sl_subsys_fcncall4')
close_system('sl_subsys_fcncall4')
Subsistema de llamada a función con bloques Merge
Este modelo contiene un gráfico que ejecuta dos llamadas a función. El modelo utiliza bloques Merge para asignar varias señales a una sola ubicación de la memoria. Las señales f/d1_out
y g/d1_out
se fusionan en una sola ubicación de la memoria y vuelven a alimentar al bloque Chart como d1
. Las señales f/k_out
y g/k_
out se fusionan en una sola ubicación de la memoria y vuelven a alimentar a f/k_in
. Al fusionar señales en una sola ubicación de la memoria y volver a alimentar el bloque Chart con ellas, permite al bloque Chart tomar decisiones complejas sobre cómo calcular valores.
open_system ('sl_subsys_fcncall5')
close_system('sl_subsys_fcncall5')
Múltiples iniciadores del subsistema de llamada a función
Para llamar a este subsistema de llamada a función se usan dos iniciadores de llamada a función diferentes, Chart1
y Chart2
. La conexión de datos entre Chart1/out1
y Chart2/d1
garantiza que Chart1
se ejecute antes que Chart2
. Debe tener cuidado cuando cree subsistemas de llamada a función con múltiples llamadores.
Por ejemplo, si elimina la conexión de datos entre Chart1
y Chart2
, deberá añadir prioridades a Chart1
y Chart2
para especificar el orden de ejecución correspondiente de estos bloques. En caso contrario, se generará un orden de ejecución ambiguo.
Sin embargo, el software no genera un error para esta condición porque la condición puede ser válida en determinados casos. A modo de ejemplo, si elimina todos los estados de f()
y elimina la línea que conecta Chart1/out1
con Chart2/d1
, el orden en el que se ejecutan Chart1
y Chart2
no importa.
open_system ('sl_subsys_fcncall6')
close_system('sl_subsys_fcncall6')
Subsistema activado que contiene subsistemas de llamada a función que especifican el comportamiento de reinicio
Este subsistema activado contiene dos subsistemas de llamada a función. El subsistema de llamada a función de la izquierda está configurado para mantener el valor de sus estados cuando está activado y para mantener el valor de su salida cuando está desactivado. El subsistema de llamada a función de la derecha está configurado para reiniciar el valor de sus estados cuando está activado, y para reiniciar el valor de su salida cuando está desactivado.
open_system ('sl_subsys_fcncall7')
close_system('sl_subsys_fcncall7')
Los subsistemas de llamada a función especifican una ejecución periódica
Este gráfico de Stateflow planifica el orden de ejecución de subsistemas de llamada a función en el modelo. Sin embargo, los subsistemas de llamada a función se ejecutan exactamente una vez por unidad de tiempo. Las llamadas a función no especifican una ejecución condicional, sino que controlan el orden de ejecución correspondiente de los subsistemas. Esta configuración puede resultar útil cuando se transfieren datos entre los subsistemas usando almacenes de datos para garantizar la secuencia adecuada para leer y escribir en los almacenes de datos. Dado que los subsistemas de llamada a función están destinados a ejecutarse incondicionalmente, se debe especificar que tienen un tiempo de muestreo periódico usando el parámetro Sample time de los bloques Trigger de los subsistemas. Como consecuencia, durante la simulación, el motor de Simulink verifica que los subsistemas de llamada a función periódicos se ejecutan exactamente una vez por unidad de tiempo.
Además, cuando se genera código, el tiempo transcurrido dentro de los subsistemas de llamada a función se representa con un valor literal (el tiempo de muestreo constante especificado) en lugar de mantenerse y calcularse a partir de temporizadores, como es normal en un subsistema de llamada a función. Por lo tanto, el código generado es considerablemente más eficiente.
Para ver el tiempo de muestreo de los subsistemas, en el editor de Simulink, en la pestaña Debug, seleccione Information Overlays y haga clic en Colors.
open_system ('sl_subsys_fcncall8')
El color del tiempo de muestreo de los subsistemas de llamada a función es rojo en lugar de cian, lo que indica un tiempo de muestreo periódico en lugar de activado. Si se intercambian las conexiones de la llamada a función, el resultado se retrasa una unidad de tiempo debido a la interacción modificada entre los bloques Data Store Read y Data Store Write de los subsistemas.
close_system('sl_subsys_fcncall8')
El iniciador de llamadas a función genera eventos activos e inactivos
Este gráfico de Stateflow especifica que el evento activate
está limitado al estado ON
. Cuando el estado ON
pasa a estar activo, el subsistema de llamada a función Integrate
, iniciado por ese evento, se activa. Asimismo, cuando el estado pasa a inactivo, el subsistema de llamada a función iniciado por ese evento se desactiva. Si el subsistema de llamada a función está configurado para restablecer estados cuando esté activado o salidas cuando esté desactivado, tendrán lugar estas acciones. En este ejemplo, el subsistema restablece sus estados y salidas al activarse y desactivarse, respectivamente.
open_system ('sl_subsys_fcncall9')
close_system('sl_subsys_fcncall9')
Interpretar las salidas de los subsistemas de llamada a función
1) El valor de retorno de la llamada a función es la conexión directa desde la salida de un subsistema de llamada a función hasta su iniciador de llamada a función. Por ejemplo, el gráfico de Stateflow Chart1
siguiente es un iniciador de llamada a función que ejecuta la función d1=f1()
. Después de invocar a f1
, el bloque Chart usa el valor de retorno d1
calculado por f1
con la misma unidad de tiempo.
2) En el segundo ejemplo, la ejecución del bloque Unit Delay no se activa mediante Chart2
. Por lo tanto, durante la ejecución de Chart2
, la señal d2
mantiene el valor de la unidad de tiempo anterior en la que se llamó al bloque Unit Delay.
open_system ('sl_subsys_fcncall10')
close_system('sl_subsys_fcncall10')
División de las señales de llamada a función
Este gráfico de Stateflow inicia una señal de llamada a función periódica con un periodo de 1 durante el intervalo de tiempo en el que su señal de entrada u
es 1. En cada invocación de llamada a función, los subsistemas se ejecutan en el orden f
seguido de h
seguido de g
. Este orden de ejecución es un resultado del orden especificado en los bloques Function-Call Split, donde el puerto anotado con un punto se ejecuta en primer lugar.
Si se exporta este modelo a las versiones anteriores a R2015b, se produce un error porque la señal b
se trata como una infracción de dependencia de datos.
open_system ('sl_subsys_fcncall11')
Este gráfico de Stateflow inicia una señal de llamada a función periódica con un periodo de 1 durante el intervalo de tiempo en el que su señal de entrada u
es 1.
En cada invocación de llamada a función, el subsistema f1
se ejecuta antes que el subsistema g1
. Este orden de ejecución es un resultado del orden especificado en el bloque Function-Call Split, donde el puerto anotado con un punto se ejecuta en primer lugar.
Si se exporta este modelo a versiones anteriores a R2015b, se produce un error porque la señal b
se trata como una infracción de dependencia de datos cuando se desactiva el parámetro Latch input for feedback signals of function-call subsystem outputs en el bloque Inport del subsistema f1
.
close_system('sl_subsys_fcncall11')
Subsistemas de llamada a función ilegales
Esta lista identifica los subsistemas de llamada a función ilegales que se enumeran. Las correcciones se explican en el subsistema correspondiente del modelo.
open_system('s_Function_call_subsystems')
Error de orden de ejecución ambiguo
Infracción de dependencia de datos con bloque impulsado por el iniciador de la llamada a función
Infracción de dependencia de datos con un bloque entre dos subsistemas de llamada a función
Error por orden de ejecución ambiguo debido a la retroalimentación de la salida modificada de la llamada a función
Error por orden de ejecución ambiguo debido a la retroalimentación de la salida modificada de la llamada a función entre dos subsistemas
Infracción de dependencia de datos con un bloque Merge y un gráfico de Stateflow
Infracción de dependencia de datos con Atomic Subsystem y bloque Gain
Infracción de dependencia de datos cíclica del subsistema de llamada a función
Infracción de dependencia de datos indirecta
Infracción de dependencia de datos anidada
Subsistemas de llamada a función especifican la ejecución periódica incorrectamente
Entradas de subsistemas de llamada a función calculadas dentro del contexto llamado
Infracción de dependencia de datos con señal de llamada a función ramificada y un bloque que conecta subsistemas de llamada a función
close_system('s_Function_call_subsystems',0)
If Action Subsystem y Switch Case Action Subsystem
Los subsistemas If Action se ejecutan en cada unidad de tiempo cuando una condición lógica es verdadera. Los subsistemas Switch Case Action se ejecutan cuando una señal tiene uno de los valores especificados en un conjunto.
Para obtener más información, consulte If Action Subsystem y Switch Case Action Subsystem.
Estos ejemplos muestran cómo usar los subsistemas If Action y Switch Case Action.
open_system('sl_subsys_semantics') open_system('sl_subsys_semantics/If Action and Switch Case Action subsystems')
close_system('sl_subsys_semantics/If Action and Switch Case Action subsystems')
Triggered Subsystems
Los subsistemas activados permiten implementar una activación de software, de hardware o ambas. Puede añadir el bloque Triggered Subsystem desde Library Browser de Simulink. De forma alternativa, puede crear este subsistema colocando el bloque Trigger dentro de un bloque Subsystem.
Para obtener más información, consulte Triggered Subsystem.
Estos ejemplos muestran cómo usar subsistemas activados.
open_system('sl_subsys_semantics'); open_system('sl_subsys_semantics/Triggered subsystems')
La activación de software se define en este código:
if (trigger_signal_edge_detected) {
out(t) = f(in(t));
}
La activación de hardware se define en este código:
if (trigger_signal_edge_detected) {
out(t) = f(in(t-h)); // h == last step size
}
Cada puerto de entrada de un subsistema activado configura si el valor de entrada debe ser capturado o no. Un valor de entrada capturado proporciona semántica para ese puerto de entrada. El software marca un puerto de entrada capturado con el símbolo <L>
.
close_system('sl_subsys_semantics/Triggered subsystems')
Enabled Subsystems
Los subsistemas habilitados permiten crear subsistemas ejecutados de manera condicional que solo se ejecutan cuando la señal de habilitación sea mayor que cero. Los subsistemas habilitados otorgan el control sobre el valor inicial de las señales de salida y la posibilidad de restablecer los estados cada vez que se habilita el subsistema.
Puede añadir el bloque Enabled Subsystem desde Library Browser de Simulink. De forma alternativa, puede crear este subsistema colocando el bloque Enable dentro de un bloque Subsystem.
Para obtener más información, consulte Enabled Subsystem.
Los siguientes ejemplos muestran cómo usar subsistemas habilitados.
open_system('sl_subsys_semantics'); open_system('sl_subsys_semantics/Enabled subsystems')
close_system('sl_subsys_semantics/Enabled subsystems')
Enabled Subsystem y Triggered Subsystem
Los siguientes subsistemas ilustran la opción de restablecer los estados y los puertos de salida. Los subsistemas Enabled y Triggered se ejecutan cuando ocurren ambas condiciones de activación y habilitación.
Puede añadir el bloque Enabled and Triggered Subsystem desde Library Browser de Simulink. De forma alternativa, puede crear este subsistema colocando tanto el bloque Enable como el bloque Trigger dentro de un bloque Subsystem.
Para obtener más información, consulte Enabled and Triggered Subsystem.
Este ejemplo muestra cómo usar los subsistemas Enabled y Triggered.
open_system('sl_subsys_semantics') open_system('sl_subsys_enabtrig1.slx')
close_system('sl_subsys_enabtrig1.slx')
Resettable Subsystems
Los subsistemas Resettable Subsystems permiten restablecer los estados de los bloques dentro del subsistema en función de la señal de restablecimiento. Puede añadir el bloque Resettable Subsystem desde Library Browser de Simulink.
Para obtener más información, consulte Resettable Subsystem.
Estos ejemplos muestran cómo usar Resettable Subsystems.
open_system('sl_subsys_semantics') open_system('sl_subsys_semantics/Resettable subsystems')
close_system('sl_subsys_semantics/Resettable subsystems')
For Each Subsystem
El subsistema For Each Subsystem repite la ejecución durante una unidad de tiempo de simulación en cada elemento o subarreglo de una señal de entrada o arreglo del parámetro de máscara. Puede añadir el bloque For Each Subsystem desde Library Browser de Simulink. De forma alternativa, puede crear este bloque colocando un bloque For Each dentro de un bloque Subsystem. Un subsistema For Each Subsystem repite el algoritmo en los elementos individuales o subarreglos de una señal de entrada. Un subsistema For Each Subsystem mantiene los estados de bloque separados para cada elemento o subarreglo que procesa el subsistema.
Para obtener más información, consulte For Each Subsystem.
Estos ejemplos muestran cómo usar For Each Subsystems.
open_system('sl_subsys_semantics'); open_system('sl_subsys_semantics/For Each subsystems')
close_system('sl_subsys_semantics/For Each subsystems')
While Iterator Subsystem
El subsistema While Iterator Subsystem repite la ejecución durante una unidad de tiempo de simulación mientras una condición lógica sea true
. Puede añadir el bloque While Iterator Subsystem desde Library Browser de Simulink. De forma alternativa, puede crear este subsistema colocando un bloque While Iterator dentro de un bloque Subsystem. Un subsistema While Iterator Subsystem ejecuta varias iteraciones en cada unidad de tiempo del modelo. El número de iteraciones se controla mediante la condición While Iterator.
El subsistema While Iterator Subsystem es parecido a un subsistema de llamada a función: puede ejecutarse durante cualquier número de iteraciones en una unidad de tiempo dada.
El subsistema While Iterator Subsystem es diferente de un subsistema de llamada a función: no contiene un iniciador separado, como un gráfico de Stateflow. Además, el subsistema While Iterator Subsystem tiene acceso al número de iteraciones actual producido de forma opcional por el bloque While Iterator.
Para obtener más información, consulte While Iterator Subsystem.
Estos ejemplos muestran cómo usar While Iterator Subsystems.
open_system('sl_subsys_semantics'); open_system('sl_subsys_semantics/While Iterator subsystems')
close_system('sl_subsys_semantics/While Iterator subsystems')
For Iterator Subsystem
El subsistema For Iterator Subsystem repite la ejecución durante una unidad de tiempo de simulación por un número determinado de iteraciones. Puede añadir el bloque For Iterator Subsystem desde Library Browser de Simulink. De forma alternativa, puede crear este subsistema colocando un bloque For Iterator dentro de un bloque Subsystem. Un subsistema For Iterator Subsystem ejecuta un número fijo de iteraciones en cada unidad de tiempo del modelo. El número de iteraciones puede ser una entrada externa para el subsistema For Subsystem o puede estar especificada internamente en el bloque For Iterator.
Un subsistema For Iterator se parece mucho a un subsistema While Iterador con la diferencia que el número de iteraciones en una unidad de tiempo dada es fijo.
Para obtener más información, consulte For Iterator Subsystem.
Estos ejemplos siguientes muestran cómo usar For Iterator Subsystems.
open_system('sl_subsys_semantics'); open_system('sl_subsys_semantics/For Iterator subsystems')
close_system('sl_subsys_semantics/For Iterator subsystems')