| Real-Time Workshop User's Guide | ![]() |
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 Asynchronous Interrupt 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 Asynchronous Interrupt 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. By default, Real-Time Workshop limits the number of bytes for local variables in all of the generated code to 8192 bytes (see assignment of 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 Asynchronous Interrupt 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 STOPONOVERRUNlogMsg("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;...
}
| Asynchronous Interrupt Block | Asynchronous Buffer Block | ![]() |