| Real-Time Workshop® | ![]() |
| On this page… |
|---|
Async Interrupt Block Implementation |
This section describes how to implement asynchronous blocks for use with your target RTOS, using the Async Interrupt and Task Sync blocks as a starting point. (Rate Transition blocks are target-independent, so you do not need to develop customized rate transition blocks.)
You can customize the asynchronous library blocks by modifying the block implementation. These files are
The block's underlying S-function MEX-file
The TLC files that control code generation of the block
In addition, you need to modify the block masks to remove references specific to the Wind River Systems VxWorks RTOS and to incorporate parameters required by your target RTOS.
Custom block implementation is an advanced topic, requiring familiarity with the Simulink MEX S-function format and API, and with the Target Language Compiler (TLC). These topics are covered in the following documents:
The Overview of S-Functions in the Simulink Writing S-Functions documentation describes MEX S-functions and the S-function API in general.
The Target Language Compiler documentation and Writing S-Functions for Real-Time Workshop Code Generation describe how to create a TLC block implementation for use in code generation.
The following sections discuss the C/C++ and TLC implementations of the asynchronous library blocks, including required SimStruct macros and functions in the TLC asynchronous support library (asynclib.tlc).
The source files for the Async Interrupt block are located in matlabroot/rtw/c/tornado/devices:
vxinterrupt1.c: C MEX-file source code, for use in configuration and simulation
vxinterrupt1.tlc: TLC implementation, for use in code generation
asynclib.tlc: library of TLC support functions, called by the TLC implementation of the block. The library calls are summarized in asynclib.tlc Support Library.
Most of the code in vxinterrupt1.c performs ordinary functions that are not related to asynchronous support (for example, obtaining and validating parameters from the block mask, marking parameters nontunable, and passing parameter data to the model.rtw file).
The mdlInitializeSizes function uses special SimStruct macros and SS_OPTIONS settings that are required for asynchronous blocks, as described below.
ssSetAsyncTimerAttributes. ssSetAsyncTimerAttributes declares that the block requires a timer, and sets the resolution of the timer as specified in the Timer resolution (seconds) parameter.
The function prototype is
ssSetAsyncTimerAttributes(SimStruct *S, double res)
where
S is a Simstruct pointer.
res is the Timer resolution (seconds) parameter value.
The following code excerpt shows the call to ssSetAsyncTimerAttributes.
/* Setup Async Timer attributes */ ssSetAsyncTimerAttributes(S,mxGetPr(TICK_RES)[0]);
ssSetAsyncTaskPriorities. ssSetAsyncTaskPriorities sets the Simulink task priority for blocks executing at each interrupt level, as specified in the block's Simulink task priority field.
The function prototype is
ssSetAsyncTaskPriorities(SimStruct *S, int numISRs,
int *priorityArray)
where
S is a SimStruct pointer.
numISRs is the number of interrupts specified in the VME interrupt number(s) parameter.
priorityarray is an integer array containing the interrupt numbers specified in the VME interrupt number(s) parameter.
The following code excerpt shows the call to 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 Settings. The code excerpt below shows the SS_OPTION settings for vxinterrupt1.c. SS_OPTION_ASYNCHRONOUS_INTERRUPT should be used when a function call subsystem is attached to an interrupt. For more information, see the documentation for SS_OPTION and SS_OPTION_ASYNCHRONOUS in matlabroot/simulink/include/simstruc.h
ssSetOptions( S, (SS_OPTION_EXCEPTION_FREE_CODE |
SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME |
SS_OPTION_ASYNCHRONOUS_INTERRUPT |
This section discusses each function of vxinterrupt1.tlc, with an emphasis on target-specific features that you will need to change to generate code for your target RTOS.
Generating #include Directives. vxinterrupt1.tlc begins with the statement
%include "vxlib.tlc"
vxlib.tlc is a target-specific file that generates directives to include VxWorks header files. You should replace this with a file that generates includes for your target RTOS.
BlockInstanceSetup Function. For each connected output of the Async Interrupt block, BlockInstanceSetup defines a function name for the corresponding ISR in the generated code. The functions names are of the form
isr_num_vec_offset
where num is the ISR number defined in the VME interrupt number(s) block parameter, and offset is an interrupt table offset defined in the VME interrupt vector offset(s) block parameter.
In a custom implementation, there is no requirement to use this naming convention.
The function names are cached for use by the Outputs function, which generates the actual ISR code.
Outputs Function. Outputs iterates over all connected outputs of the Async Interrupt block. An ISR is generated for each such output.
The ISR code is cached in the "Functions" section of the generated code. Before generating the ISR, Outputs does the following:
Generates a call to the downstream block (cached in a temporary buffer).
Determines whether the ISR should be locked or not (as specified in the Preemption Flag(s) block parameter).
Determines whether the block connected to the Async Interrupt block is a Task Sync block. (This information is obtained by using the asynclib calls LibGetFcnCallBlock and LibGetBlockAttrribute.) If so,
The preemption flag for the ISR must be set to 1. An error results otherwise.
VxWorks calls to save and restore floating-point context are generated, unless the user has configured the model for integer-only code generation.
When generating the ISR code, Outputs calls the asynclib function LibNeedAsyncCounter to determine whether a timer is required by the connected subsystem. If so, and if the time source is set to be SS_TIMESOURCE_SELF by ssSetTimeSource, LibSetAsyncCounter is called to generate a VxWorks tickGet function call and update the appropriate counter. In your implementation, you should generate either an equivalent call to the target RTOS, or generate code to read the appropriate timer register on the target hardware.
If you are targeting the VxWorks RTOS, you can obtain better timer resolution by replacing the tickGet call and accessing a hardware timer by using your BSP instead. tickGet supports only a 1/60 second resolution.
Start Function. The Start function generates the required VxWorks calls (int_connect and sysInt_Enable) to connect and enable each ISR. You should replace this with appropriate calls to your target RTOS.
Terminate Function. The Terminate function generates the call sysIntDisable to disable each ISR. You should replace this with appropriate calls to your target RTOS.
The source files for the Task Sync block are located in matlabroot/rtw/c/tornado/devices. They are
vxtask1.c: MEX-file source code, for use in configuration and simulation.
vxtask1.tlc: TLC implementation, for use in code generation.
asynclib.tlc: library of TLC support functions, called by the TLC implementation of the block. The library calls are summarized in asynclib.tlc Support Library.
Like the Async Interrupt block, the Task Sync block sets up a timer, in this case with a fixed resolution. The priority of the task associated with the block is obtained from the Simulink task priority parameter. The SS_OPTION settings are the same as those used for the Async Interrupt block.
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 |
}
Generating #include Directives. vxtask1.tlc begins with the statement
%include "vxlib.tlc"
vxlib.tlc is a target-specific file that generates directives to include VxWorks header files. You should replace this with a file that generates includes for your target RTOS.
BlockInstanceSetup Function. The BlockInstanceSetup function derives the task name, block name, and other identifier strings used later in code generation. It also checks for and warns about unconnected block conditions, and generates a storage declaration for a semaphore (stopSem) that is used in case of interrupt overflow conditions.
BlockInstanceData. The BlockInstanceData function generates storage for the semaphore that is used in management of the task spawned by the Task Sync block. Depending on the code format of the target, either a static storage declaration or a dynamic memory allocation call is generated. The ERT target and derived targets use a static memory declaration; the VxWorks target uses malloc.
Start Function. The Start function generates the required VxWorks calls to create a semaphore (semBCreate) and spawn a VxWorks task (taskSpawn). You should replace these with appropriate calls to your target RTOS.
Outputs Function. The Outputs function generates a VxWorks task that waits for a semaphore. When it obtains the semaphore, it updates the block's tick timer and calls the downstream subsystem code, as described in Spawning a Wind River Systems VxWorks Task. Outputs also generates code (called from interrupt level) that grants the semaphore.
Terminate Function. The Terminate function generates the VxWorks call taskDelete to end execution of the task spawned by the block. You should replace this with appropriate calls to your target RTOS.
Note also that if the target RTOS has dynamically allocated any memory associated with the task (see BlockInstanceData), the Terminate function should deallocate the memory.
asynclib.tlc is a library of TLC functions that support the implementation of asynchronous blocks. Some functions are specifically designed for use in asynchronous blocks. For example, LibSetAsyncCounter generates a call to update a timer for an asynchronous block. Other functions are utilities that return information required by asynchronous blocks (for example, information about connected function call subsystems).
The following table summarizes the public calls in the library. For details, see the library source code and the vxinterrupt1.tlc and vxtask1.tlc files, which call the library functions.
Summary of asynclib.tlc Library Functions
Function | Description |
|---|---|
LibGetBlockAttrribute | Returns a field value from a block record. |
LibGetFcnCallBlock | Given an S-Function block and call index, returns the block record for the downstream function call subsystem block. |
LibBlockExecuteFcnCall | For use by inlined S-functions with function call outputs. Generates code to execute a function call subsystem. LibBlockExecuteFcnCall calls the lower-level function LibExecuteFcnCall, but has a simplified argument list. See the Target Language Compiler documentation for more information on LibExecuteFcnCall. |
LibGetCallerClockTickCounter | Provides access to an upstream asynchronous task's time counter. |
LibGetCallerClockTickCounterHighWord | Provides access to the high word of an upstream asynchronous task's time counter. |
LibManageAsyncCounter | Determines whether an asynchronous task needs a counter and manages its own timer. |
LibNeedAsyncCounter | If the calling block requires an asynchronous counter, returns TLC_TRUE, otherwise returns TLC_FALSE. |
LibSetAsyncClockTicks | Returns code that sets clockTick counters that are to be maintained by the asynchronous task. |
LibSetAsyncCounter | Generates code to set the tick value of the block's asynchronous counter. |
LibSetAsyncCounterHighWord | Generates code to set the tick value of the high word of the block's asynchronous counter |
![]() | Using Timers in Asynchronous Tasks | Asynchronous Support Limitations | ![]() |
| © 1984-2008- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |