A workshop report
Authors: Dr. Andreas Wagener, Dr. Fritz Faulhaber GmbH & Co. KG, Robert Stemplinger and Markus Pauls, b1 Engineering Solutions GmbH
Contribution – Embedded Software Engineering Congress 2015
Tools like Rhapsody allow code for embedded systems to be generated directly from the model. In the project under consideration, the entire system is designed and implemented in Rhapsody using this approach. Stacks and signal processing code are also integrated. This requires some preliminary work, increasing the level of abstraction for all involved – but with the added benefit of implementing a clearly recognizable architecture and thus a highly maintainable product.
Dr. Fritz Faulhaber GmbH & Co. KG develops, manufactures, and sells small and micro motors, along with matching position encoders and controllers for the controlled operation of these motors. The controllers are available as simple speed controllers or as position controllers. These are implemented as embedded controllers based on microcontrollers, in which all stages of the control process are handled digitally. This section will focus on the positioning systems.
The software of a motor control system for a servo drive can be roughly divided into the following parts:
- Hardware drivers,
- Motor control,
- Control and diagnostics,
- communication and
- Parameter speaker (object directory or Management Information Base (MIB))
The existing systems need to be structured. Extensions and adaptations to changing requirements, as well as limitations of the target system, necessitated abandoning the clear design of the existing systems. This leads to the classic situation with embedded control units, where software components overlap significantly.
Despite these limitations, the motion controller is a very stable device; however, expansions require greater effort and development time. Therefore, it was clear that for the next generation of controllers, maintainability and expandability, in particular, should be significantly improved through a clear and modular software architecture.
Functional requirements included:
- a significantly increased range of supporting operating modes,
- Support for at least one Ethernet-based fieldbus as an option,
- significantly increased flexibility in configuration.
The requirements were linked to the expectation of being able to respond to customer requests much faster in the future.
At the same time, the switch should be made to a current and future-proof processor family, but the software should be developed in such a way that future processor changes are also significantly simplified.
Fundamental decisions
Due to the highly interwoven structure shown in Figure 1 (see PDFIt quickly became clear that only the experience gained from operating small electric drives could be salvaged from the existing product. All parts of the software had to be redesigned.
One task was therefore to find a processor platform that met the specific requirements of integrated small drives. The other task was to find a suitable design methodology, combined with the search for suitable tools that would allow the fundamental design decisions to be validated during implementation.
In contrast to the previous approach, an object-oriented approach should be pursued, also in order to structure the design using the mechanisms of UML.
Previously, Target Link was used to generate code from SIMULINK models for the development of signal processing software components in control and position evaluation. However, this approach is not suitable for describing and implementing the more event-based software components from the driver layer, parameter handling, communication, and drive control.
Following an initial evaluation and based on experience from previous projects [1], the decision was made to use Rhapsody, specifically the embedded version offered by Willert. The main arguments were:
- Works natively in OO design
- Support for typical embedded platforms, also in C, with good readability.
- Sufficient continuity from design to implementation
- A good entry point is possible, as there are few legacy shares to inherit.
However, it was clear from the outset that this would also entail a significant learning curve, both in terms of the tool's user-friendliness and the design methodology. It was therefore also clear that we needed to find an experienced partner for the key issues at hand, which we found in Tieto, or rather Tieto Embedded Systems – now b1 Engineering Solution (see also Fig. 2)., PDF).
Architecture & Design
Based on the developed specification, the system's use cases, and the insights gained from the existing system, a rough architecture was initially created:
- Division of the overall function into packages and partly also into objects
- Definition of the driving activities of the system
- Clarification of data management regarding the handling of parameters and their storage.
Implementation
The applied patterns were layering, in particular with a clear assignment of responsibilities for the encapsulation of the µController-typical peripheral units in the HAL and a middleware layer built on top of it (see Fig. 3, PDFThe middleware layer provides clearly abstracted information such as the motor speed as a result of various sensor systems or calculates control variables from general specifications, such as the appropriate control for the connected motor from the target voltage of the controller.
To implement a signal flow opposite to the defined dependency relationships, the publish/subscribe pattern, or observer pattern, was used. Information consumers from higher layers register callback functions and instance pointers with the information producers in the lower layers. This pattern is used for the transition between interrupt contexts and task contexts, as well as between task contexts. To manage concurrency, the callback functions generally send an event from the runtime environment to the addressed object instance. In many cases, it is sufficient to register exactly one subscriber during initialization (see Fig. 4)., PDF).
The system's activities can be divided into strictly time-driven activities on the one hand:
- the timer interrupt for motor control (100µs, synchronous with PWM)
- a timer interrupt with a 1ms cycle time for diagnostic tasks
Both are triggered via an interrupt and also executed within the interrupt context. These signal-processing system components are designed in SIMULINK and translated into C code via TargetLink with an interface design that matches the system architecture.
On the other hand, there are the more reactive activities:
- External events, such as the receipt of a complete message from the communication stacks (the processing of individual characters, e.g., from the RS232 interface, is carried out entirely in the interface interrupt context).
- Timeouts via a lower priority timer
In both cases, the interrupt context is exited and an event is triggered, which is typically handled by a state machine. The interaction can be advantageously modeled using communication diagrams, and the system response can be designed using state machines.
parts of the runtime environment
Within the Willert Framework, state machines and the necessary event handling are offered natively, meaning that executable code can be generated directly from state diagrams and their associated events. Since the response to each event is processed in a run-to-completion manner, state machines can also be used to serialize quasi-simultaneous events by placing the events in a state machine's event queue – for example, to process requests received via the serial interface in competition with internally generated asynchronous messages.
Implementation in Rhapsody
The overall system was broken down into a series of parallel Rhapsody projects, each containing the implementation and test environment for a single component. This allows the components to be worked on largely independently – important for teamwork.
The components were then combined from the beginning according to the dependencies and layers for integration (top down), whose functionality could then gradually grow.
The foundation is a project containing only type and stereotype definitions derived from the programming guidelines. On top of this, the functional packages are built, each consisting of the component to be developed and, optionally, a test package. Executable test components can be generated from the functional package via the test package, each utilizing only the scope of the functional component under consideration. At the highest level, the components are referenced in the integration project (see Fig. 5)., PDF file)
Integration of C code
The Rhapsody projects provide the build environment for integration and the creation of the binary files. All code is moved from these projects to a project in the C development environment (here Keil µVision), where it is only built and debugged. The exported C files are therefore not subject to configuration management.
Nevertheless, existing C code components, such as purchased communication stacks or code generated via TargetLink, must also be integrated. Tasks include copying the existing code into the C project and, if necessary, designing interfaces to utilize the external code components within the project.
The first part of the task is accomplished via make-file extensions, which can be created within the components created in Rhapsody and contain the copy instructions.
For integration into the model, wrapper classes were typically created. For example, TargetLink can be used to create a controller very effectively. Parameters and variables can also be collected in class-like structures and used at the function interface of the actual calculation routine. The resulting C module can then be included in the project as external code. However, TargetLink does not provide suitable access methods for the individual parameters of the controller structure. This leaves direct access to the structure's members, or a wrapper that provides the read and write handlers and encapsulates the knowledge about the C structure.
Advantages
The project is not yet completed, but a preliminary assessment reveals the following advantages:
- By structuring the system using the mechanisms of object-oriented architecture, the basic architectural design remains constantly in focus. Dependencies are deliberately established, and the layered model is consistently adhered to.
- With a clean separation between the system's time-driven and event-driven tasks, the mechanisms of the event queues implemented in the runtime environment can be fully utilized. Despite a number of concurrency issues, developers no longer need to deal with the mechanisms required for synchronization, such as semaphores and interrupt locks.
- The generated code is generally highly readable, but it remains the responsibility of the developers or project manager to ensure that the complexity of the methods and classes remains manageable. The tool provides no support in this regard.
Challenges and efforts
From the developer's perspective, in particular, the daily use of Rhapsody presents several hurdles that one has to learn to live with. A few examples are given below. In our opinion, many of these could be easily resolved if there were a stronger commitment to product maintenance.
The RPY Code and Model Editor
- Copying, pasting, and modifying model elements (a commonly used development pattern) often works, but not always. Problems arise particularly with elements below the standard "Components" package, or when copying between different projects.
- Copying from read-only windows (e.g., into an email) is not possible. Scrolling is also not possible in read-only windows.
- Windows key mapping (Ctrl-Del, Ctrl-Insert) does not work, only Ctrl-C and Ctrl-V.
- Auto-completion in the code editor only works incompletely (only once per line, only local elements, no literals, …)
- Generated code that is to be assigned to a package cannot be automatically prefixed.
- Refactoring is tedious because the manually entered code is not included in the tool.
Properties
How and when properties are used during code generation is very unclear. Often, trial and error is the only solution. For example, the property C_CG::Type::ReturnType is ineffective if you want to automatically generate an accessor using the property C_CG::Attribute::AccessorGenerate. In this case, a const pointer to the structure should be returned instead of a copy of the structure (the default).
Versioning
Unfortunately, the files where Rhapsody stores its information are not very merge-friendly. In particular, timestamps and GUIDs are frequently changed in files, even though they haven't undergone any other modifications. To facilitate collaboration, we often manually checked which files had actually been changed before committing, using the configuration management tool. In cases of actual conflicts, manual intervention with the merge tool was sometimes necessary, unless these conflicts could be avoided through prior agreement.
OO in C
We frequently work with constant, private data tables, which are then evaluated by the code. Unfortunately, staircase members cannot be created for classes (as is possible in C++). Examples of use would be:
- Table-based CRC algorithm
- HW configurations
- Tables of callback functions
Some workarounds arise from the definitions using types, but not, for example, for callback functions, since the function prototypes in the generated code are only placed after the types.
Requirements
Experience shows that the right conditions need to be established early on for efficient work with Rhapsody. From our perspective, the following points are important:
- A profile should be created from the outset for the project-specific settings and referenced consistently throughout (see Figure 5, PDFSince it is usually unclear at the beginning, due to a lack of experience, which property settings should be set and how, this method makes it relatively easy to introduce otherwise far-reaching subsequent changes.
- Certain property settings should be linked to stereotypes. This makes them clearly identifiable in the model and allows for consistent handling. Examples:
- SimpleType: e.g. for enums, which should generally be passed by value.
- Volatile: sets the property C_CG::Attribute::PreDeclarationModifier to “volatile” and should be used for volatile attributes.
- PackedT: sets the property C_CG::Type::PreDeclarationModifier to “__packed” and should be used for packed structures.
- Packages should be used liberally to facilitate collaboration among multiple developers. These packages can then be referenced in the respective developer projects. By default, packages are stored as their own unit in a separate file.
- It is advantageous to define a "helper" package with universal types and algorithms (e.g., CRC) at the very bottom of the layering, which can be reused for all layers above it. We hadn't done this—apart from the usual integer data types. Adding this later would be extremely difficult.
Regardless of the specific development methodology, a solid understanding of domain-specific problems is always a key success factor. In this case, for example, it's understanding the driving activities and their assignment to the time-driven interrupt context or the event-based task context.
The more abstract, model-based approach demands even more expertise from the developers involved. One shouldn't immediately retreat into the bits and bytes and then try to piece everything together afterward. The advantages of appropriate modeling and coding guidelines certainly don't need further emphasis.
Results
The results obtained so far need to be considered in a nuanced way. From the architect's perspective, model-based work allows for a rapid transition from architecture to implementation. In particular, the explicit notations ensure that the fundamental architectural decisions are always kept in mind.
For the developers, switching to object-oriented programming and Rhapsody represents a significant change in their workflow. Instead of writing in C files and using highly sophisticated C editors, the code is now written in the Rhapsody editor. Changes made to the C files during testing must be carefully rolled back. The paradigm shift from a main loop to an event-based system architecture should also not be underestimated.
From the project manager's perspective, the biggest challenge was finding suitable partners. Switching to an object-oriented design doesn't happen overnight. Rhapsody is a very powerful tool with relatively manageable documentation. Despite a preliminary evaluation project and accompanying training, a project of this scope and novelty would not have been manageable within the already tight deadline without the experienced partners.
It should be noted that a significant portion of the time – typical for embedded systems – was spent developing middleware layers. While these layers, like the application itself, have a clear structure, they do not serve to differentiate the product. In the future, more standardized middleware packages would be helpful, but these would certainly need to be implemented according to industry and application specifics.
Bibliography and list of sources
[1] A. Wagener, Ch. Körner, P. Seger, H. Kabza, Adaptation of an embedded target for distributed control tasks to the RTW of Matlab/Simulink, Embedded Intelligence 2001, Nuremberg
[2] U. Lefarth, T. Beck, Quality and efficiency improvement in the development of control unit software, 3rd Stuttgart Symposium on Automotive Engineering and Internal Combustion Engines, 1999, Stuttgart.
[3] Dr. Gary Morgang, AUTOSAR – a project for the development of control unit software, Elektronik automotive 1/2006
Modeling – MicroConsult Training & Coaching
Do you want to bring yourself up to date with the latest technology?
Then find out more here MircoConsult offers training courses/seminars/workshops and individual coaching on the topic of modeling/embedded and real-time software development.
Training & coaching on the other topics in our portfolio can be found here. here.
Modeling – Expertise
Valuable expertise in modeling/embedded and real-time software development is available. here Available for you to download free of charge.
You can find expertise on other topics in our portfolio here. here.
