An SWC must have at least two runnables. If you apply the stereotype CpSWC
to an existing class, these runnables are not created: you must add them yourselves.
You need some runnables:
The behaviour of how Rhapsody generates the symbol for a runnable can be set via a property, see Profiles
The ARXF-CP uses the RTE generated APIs to enter- and exit exclusive areas as Critical Region handlers, see OS Integration.
Note that for proper code generation, the ARXF-CP needs stereotyped dependencies between runnables towards inter-runnables and runnables towards exclusive areas. For more details, please refer to the section on the SodiusWillert AUTOSAR Profiles.
For sample implementations of runnables, please refer to the Standard Content of an SWC.
If you want that a class runs in its own OS task and processes its own UML event queue, you need an active class, see Concurrency:
These sample implementations use different runnables for a timerTick and event dispatcher, but you can combine these two. The behaviour of how Rhapsody generates the symbol for a runnable can be set via a property, see CpRunnable in Profiles.
The ARXF-CP is instantiated per SW-C instance (in AUTOSAR terminology: prototype). As a result, memory allocation functions need an argument so the memory is allocated from the proper memory pool instance. The macro to send a dynamic event is CGEN(), see section Events. The code generation automatically adds an argument so the event is allocated in the proper memory pool instance.
The macro to send a static event is CGEN_ISR(), see section Events. For compliency reasons, this macro uses the same name of sending an event from within an Interrupt Service Rountine in non-AUTOSAR embedded environments, supported by other RXF products.
In order to prevent an Execution Budget exception by the OS, you can specify the maximum number of events such runnable may process
as argument to the function RXF_Active_eventDispatcher() which is typically called to process the UML event queue for this task.
See Standard Content.
The runnable will return when there are no more UML events in the queue or when this maximum number of events has been processed.
Currently there is no property and/or tag to do so at the UML model level: you must modify this via the Implementation tab when selecting the Features of a runnable.
Profiles on how to do this. Exclusive Area mechanism for an exclusive area as critical region handler for accessing ‘global’ data per SW-C: event list, timer list and memory pools. If you need a Critical Region yourselves, you must use a dedicated exclusive area (which is configured by an AUTOSAR authoring tool) and use the RTE generated enter- and exit functions for your Critical Region.
If you want to use to protect data shared between runnables in your model you must add exclusive areas:
The ARXF-CP allows you to model multiple SW-Cs in a single model. For the active Component in your model, Rhapsody generates code to initialize all packages in scope. At the package level, the init() and startBehavior() functions are called by <someSwc>_Init()() from an ‘init’ runnable.
The ‘init’ runnable is responsible for connecting both worlds: AUTOSAR and Rhapsody. During Initialization of your SWC via a call to <yourSwc>_Init(), addresses of ARXF-CP internal pointers are stored into inter-runnable variables. Other runnables of the same SW-C instance can read these inter-runnable variables and via this pointer, process UML events.
Via this pointer we can access the RXF_SWC structure which relates to the instance of an SWC. It contains a member isInitialized, which we can use to test before calling ARXF-CP functions.
Please inspect the Standard Content for an SWC.
It is good practice to use an initializer in the SWC to call the init() and startBehavior() of the Singleton which belongs to the SWC.
Basically the workaround is to initialize this pointer on forehand, using the property CG::Class::AdditionalInitializationCode
The screenshots below are taken from the SystemTest, where TestPart07_TSK_Controller is a part of SwcB. TestPart07_TSK_Controller in its turn is a structured class, but its parts do not know (or need to know) the relation to SwcB. TestPart07_TSK_Controller itself does know that relation, which is sufficient.
TestPart07_TSK_Controller knows its SwcB as itsTestMain. If you open a Structure Diagram of the SWC you see its parts.
Using your righthandside mouse button, select the Features of the part (in this example TestPart07_TSK_Controller)
We first specify an Init operation for the structured class,
which is passed a pointer to the SWC. It is an InOut parameter, which prevents const from being generated.
Now we must add a call to this initializer: at the righthand side of Initialization press the ... button
Select the argument and press Set Value and set it to me
Finally, add the workaround. Select the SWC and open its properties and browse to CG::Class::AdditionalInitializationCode We must set the relation to the SWC, which results in the generated code, but before initRelations() is called:
Concurrency. All sequential classes run in the so-called swc task. Each active class has its own UML event queue and uses its own OS task.
The sample implementation of runnables use a pointer to the Rhapsody instance of the SWC in order to test if it has been initialized. For this, it needs to know the C structure of the SWC, for example SwcB which is defined in SwcB.h in our Blinky example.
As a consequence, we must make Rhapsody generate an include statement for the Rhapsody SWC which we do by adding a dependency to it:
Browse to the structured class which represents your SWC:
Next we must inform Rhapsody to generate the include statement in the C source of the active class, not its header. We do this by using the stereotype UsageImp in the package Stereotypes_Pkg_Cls_File:
This is the result: a dependency to the SWC and a generated include statement in the its source file:
However, all RTE calls done from a class within such SWC, must use the self pointer as argument. The Code Generation does not offer a <self> in RTE APIs you do. You must add an attribute to the SWC and a relation to the SWC, or pass this self pointer as argument to an initializer of a class which is part of such SWC.BlinkyPlusLegacy example shows how a legacy runnable can send a UML event into your model. The easiest way is to call an operation of a class which sends this event and have your legacy code call this operation.
If the legacy runnable runs in a different OS task then the runnable used as UML eventDispatcher, then you must call the function RXF_Active_signalEventReceived() to trigger that runnable. RXF_Active_signalEventReceived() will use the RTE event dispatcher specified for an SWC or an active class. See AUTOSAR section ARXF-CP Event Dispatcher.