Architecture of Generated C Code : Main Task: Partition and Flow Control for C

Main Task: Partition and Flow Control for C

This section describes how different generated modules are put together into a single thread, and what is the control flow of the main task. The whole execution starts with an initialization phase, where all components are initialized: the timer, the threads scheduler (if needed) and basic activity tasks are created. In addition the user_init procedure is called.

The user_init procedure resides in a file called user_activities.c. When you generate code, the Code Generator automatically creates the user_activities.c file and the user_init procedure. Prior to executing the model, you may initialize values in the user_init procedure.

After the initialization phase, the main-task starts processing in a cyclic manner, where every cycle corresponds to a single “go-step.” In every cycle, all the concurrent state machines are traversed, process their inputs and generate outputs, issue timing requests and take the necessary state transitions.

This is how the main program looks:

int main(argc, argv)
int argc;
char **argv;
{
pr_initialize();
while(TRUE) {
if (pr_make_step()) /* if system is in stable status,
pr_pause; it enters the pause mode, waiting
for external inputs */
}
}
 
 

The C function pr_make_step returns TRUE when system is in a stable status.

The main program is written as a task, which calls all the state machines within the profile. pr_initialize is the initialization procedure, and pr_make_step completes a single-step of the whole system. Note the user-tasks, including basic activities are processing independently, as well as the asynchronous timer.

The following diagram shows the calling sequence within the main task:

The C procedure pr_make_step follows:

boolean pr_make_step()
{
boolean step_has_changes = FALSE;
 
incr_stepN(); /* increment step counter */
sched_disable(); /* disable async timer interrupts
during execution of step */
lo_main(); /* step execution */
step_has_changes = update(); /* perform all deferred
assignments */
garbage_collect() ; /* clearing intra-step allocations */
sched_enable() ; /* enable accepting of elapsed
timeouts */
scheduler(); /* yield control to other ready
tasks, including panel driver */
if (!step_has_changes) /* no changes:
return TRUE; system is in a stable status */
pge_start_graphics(); /* start critical section of panel
updates */
call_cbks(FALSE); /* evaluate callbacks,
including panel outputs */
pge_end_graphics(); /* end critical section of panel
updates */
return FALSE; /* step finished;
system status is not stable */
}
 
 

The pr_make_step procedure activates all the functions that complete the execution of a step.