Component reuse is a common use case in any type of software and this is particularly true in automotive applications. Consider the equipment in the cars such as wheels, seats, doors, lights, clutches (e.g., in a dual-clutch transmission), and so on. They are controlled by software and as they exist by pairs, it makes sense to repeat their control algorithm. Indeed, the code can be developed once, instantiated as many times as needed and parametrized. This contributes to an efficient usage of the ROM memory. In this blog article, we will present three options to handle AUTOSAR reusable code.
First of all, I want to give a warm thank to Hriday Ranjan, Modeling Lead at Ford Motor Company in the United States who inspired me writing this blog article. His team develops AUTOSAR software components in model-based which contains reusable code. They use BTC EmbeddedPlatform to test the software. We discussed three possible approaches to develop reusable code as well as their pro and cons arguments. I’m happy to summarize our discussion outcomes as follow:
Approach #1: Define a multi-instance Software Component in the AUTOSAR (Classic) architecture.
To reuse code in several components of the same type, AUTOSAR provides a multi-instance concept for the Software Components. For example, an Application Software Component of a window lifter can implement the functionality and be instantiated four times in the ECU for the respective windows. In the AUTOSAR description, this is specified with the attribute SUPPORTS-MULTIPLE-INSTANTIATION of the component “Internal Behavior”. The instantiated components share the same code but separate memory (RAM) for the internal states. The internal states are typically handled as AUTOSAR PerInstanceMemory (PIM). When coding the function manually, the developer shall take care of a proper management of the PIMs. In model-based development, the code generator automatically converts the state variables into PerInstanceMemories.
The port interfaces (e.g., sender/receiver) of the component instances have to access instance specific data. Therefore, the runnable functions as well as the RTE API calls use an additional function argument to manage the instance specific data.
With this approach, the entire software component is reusable. The “reusability” is specified in the AUTOSAR description and the RTE takes care of the implementation and handling of the instances. However, we should keep some challenges in mind: Shifting the definition of all repeatable code at the component level could increase the number of software components and complicate the AUTOSAR architecture work. The internal states of the algorithms have to be managed via PerInstanceMemories which either have to be anticipated or fed back to the AUTOSAR ARXMLs after the component implementation. Testing the component requires to handle the additional instance specific parameters of the runnable and the RTE functions.
Approach #2: Use AUTOSAR Client/Server interface to define the reusable code a Server function and call it in many Clients.
A Client/Server (C/S) communication is a mechanism based on function definition and function call. A Client/Server interface can define reusable code as an Operation (function) carried by the interface. The operation can have as many input and output variables as needed, configured as Operation arguments. A Server component (the provider of the reusable code) can reference the C/S interface and implement the function. The server component can have additional calibration parameters if needed. Then, several Client components can reference the C/S interface to call the operation. In the example of the window lifter, this would result in:
- 1 server component implementing the reusable code as a server function
- 4 client components (one for each door) calling the server function.
With this second approach, the “reusable” component is defined (again) in the AUTOSAR description and the relationship with the client components is established via the C/S interface. The RTE manages the integration between the server and the client components. During the development, the server component can be implemented and tested once. The implementation of the client components includes the call to the server operation and can add additional client-specific functionally around the call when this is needed. Testing the client component requires that a stub implementation of the server is part of the simulation environment. Depending on the development environment, this is more or less easily handled. The biggest challenge with this C/S approach is the management of internal states. The server function cannot manage the states for the clients. Therefore, if this is required, state variables have to be handled in the client implementation and exchanged with the server function using arguments of the type “INOUT”.
Approach #3: Manage the reusable code as a traditional non-AUTOSAR reusable C-code
In this scenario, we consider that the Application Software Component is implementing the reusable code as a subfunction. The subfunction is defined as a regular C function called inside the component. With the window lifter example, a single software component can control the four windows by calling the same subfunction four times.
In model-based environment such as dSPACE TargetLink or Mathworks Embedded Coder, this is supported with Reusable Subsystems. The configuration starts by defining a library block configured to generate a reusable function. Several information can be configured such as the function name, the function input/output arguments and the definition files. Then, the block is instantiated as many times as needed in the component model.
The management of internal states is much more easier. In fact, during code generation, the state variables of each instance are automatically combined in a structure and passed as pointer argument to the reusable function. The developer effort to manage internal states is almost null compared to the first two AUTOSAR mechanisms. Calibration parameters can be defined in the reusable function or if they are specific to each instance, they can be passed as function arguments.
The traditional non-AUTOSAR reusable code can even be extended to share the code across several software components. This simply requires to manage a modular and independent file structure. The reusable subsystem can declare the function in a specific header file which gets included in each component source file and define the function in its own c-file. While generating code for each component, the reusable subsystem files could be regenerated each time but since their content would be identical (coming from the same library block), only one set of the files can be kept and archived for the final integration. An alternative workflow could be to generate the reusable function from a separate model and the software component models integrate it as external code.
In general, the traditional non-AUTOSAR reusable code is very flexible. The downside is that it cannot be specified with native AUTOSAR elements. Plus, we have to be aware of potential naming conflicts which are normally avoided by the AUTOSAR naming scheme for functions and variables when using native AUTOSAR mechanisms.
The component model has to be designed with the inner reusable subsystems in mind. For practical simplicity, I can recommend to start developing the model as if there was only on instance of the reusable subsystem and once the algorithm is matured, convert it as a library and create the other instances. During testing, unit test can be conducted on one instance of the reusable function and, to test the behavior of the all instances combined, an integration test can be performed on the component level.
In conclusion, several approaches are available to address reusable code in AUTOSAR components. From an approach which is fully handled in AUTOSAR with the multi-instance concept to the one where the reusable function is managed with traditional methods inside the development environment, the project can decide which one fits the best. Configuring everything in AUTOSAR reinforces the architecture definition but reduces the flexibility since any architecture change requires updating the overall AUTOSAR description, plus the management of internal states is a challenge. The traditional method is more flexible but this actually depends on how flexible the development environment can manage the modularity and the independencies between the shared source files.
Thank you again Hriday Ranjan for the interesting discussions!