Real-Time Workshop | ![]() ![]() |
Task Synchronization Block
The VxWorks Task Synchronization block is a function-call subsystem that spawns, as an independent VxWorks task, the function-call subsystem connected to its output. Typically it would be placed between the VxWorks Interrupt Control block and a function-call subsystem block or a Stateflow chart. Another example would be to place the Task Synchronization block at the output of a Stateflow diagram that has an Event, "Output to Simulink," configured as a function-call.
The VxWorks Task Synchronization block performs the following functions:
taskSpawn()
. The task is deleted using taskDelete()
during model termination.
semTake()
. When semTake()
is first called, NO_WAIT
is specified. This allows the task to determine if a second semGive()
has occurred prior to the completion of the function-call subsystem. This would indicate the interrupt rate is too fast or the task priority is too low.
semgive()
, is generated for the Task Synchronization block (a masked function-call subsystem). This allows the output function-call subsystem to run. As an example, if you connect the Task Synchronization block to the output of a VxWorks Interrupt Control block, only a semGive()
would occur inside an ISR.
Task Synchronization Parameters
The picture below shows the VxWorks Task Synchronization block dialog box.
Parameters associated with the Task Synchronization block are:
taskSpawn()
system call. This name is used by VxWorks routines to identify the task they are called from to aid in debugging.
MaxStackSize
in matlabroot
/rtw/c/tornado/tornado.tlc
). As a rule, providing twice 8192 bytes (16384) for the one function that is being spawned as a task should be sufficient.
Task Synchronization Block Example
This example shows a Task Synchronization block as a simple ISR.
The Task Synchronization block inserts this code during the Target Language Compiler phase of code generation:
MdlStart
, the Task Synchronization block is registered by the Interrupt Control block as an ISR. The Task Synchronization block creates and initializes the synchronization semaphore. It also spawns the function-call subsystem as an independent task.
/* Create and spawn task: <Root>/Faster Rate(.015) */
if ((*(SEM_ID *)rtPWork.s6_S_Function.SemID =
semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)) == NULL)
ssSetErrorStatus(rtS,"semBCreate call failed "
"for block <Root>/Faster Rate(.015).\n ");
}
if ((rtIWork.s6_S_Function.TaskID = taskSpawn("root_Faster_", 20, VX_FP_TASK, 1024, (FUNCPTR)Sys_root_Faster__OutputUpdate,
(int_T)rtS, 0, 0, 0, 0, 0, 0, 0, 0, 0)) == ERROR) {
ssSetErrorStatus(rtS,"taskSpawn call failed for block <Root>/ Faster Rate " "(.015).\n");
}
/* Output and update for function-call system: <Root>/Faster Rate(.015) */
void Sys_root_Faster__OutputUpdate(void *reserved, int_T controlPortIdx, int_T tid)
{
/* Wait for semaphore to be released by system: <Root>/Task Synchronization */
for(;;) {
if (semTake(*(SEM_ID *)rtPWork.s6_S_Function.SemID,NO_WAIT) != ERROR) {
logMsg("Rate for function-call subsystem"
"Sys_root_Faster__OutputUpdate() fast.\n",0,0,0,0,0,0);
#if STOPONOVERRUN
logMsg("Aborting real-time simulation.\n",0,0,0,0,0,0);
semGive(stopSem);
return(ERROR);
#endif
} else {
semTake(*(SEM_ID *)rtPWork.s6_S_Function.SemID, WAIT_FOREVER);
}
/* UniformRandomNumber Block: <S3>/Uniform Random Number */
rtB.s3_Uniform_Random_Number =
rtRWork.s3_Uniform_Random_Number.NextOutput;
.
.
.
![]() | Interrupt Control Block | Asynchronous Rate Transition Block | ![]() |