RKH (Reative frameworK for Hierarchical state machines) is a state machine framework used to build software for reactive and real-time embedded systems in a safely and timely way. Read on if you want to learn more about the benefits of this flexible, efficient and highly portable state machine framework.
RKH provides not only an unusual, efficient and straightforward method for implementing and executing state machines, but also the needed infrastructure to build applications in embedded systems.
The RKH state machine framework is open source and licensed under the GNU General Public License v3.0. You can find the source code on GitHub.
It is composed of modules, procedures, and supporting tools; such as
- a method for implementing and executing flat state machines and statecharts,
- asynchronous messaging,
- cross-platform abstraction,
- run time tracing
- time management
- dynamic memory mechanism to deal with fragmentation,
- unit-test harness,
- plus others
These elements make up the needed infrastructure to build apps in embedded systems.
Frequently, real-time embedded systems development is slow, hard and error-prone. Thanks to the use of the RKH state machine framework, this has been greatly improved. RKH involves higher quality and functionality, decreasing development time.
Since common software infrastructures do not have to be reimplemented, there is no need to reinvent the wheel over and over again. In this sense, RKH provides service modules to perform many of the housekeeping chores that make up most of the applications, freeing the developer and enabling him to concentrate on domain-specific problems and other issues.
State machines are usually employed to represent the dynamic behaviour of reactive applications, due to their event-driven nature. In the case of RKH, this state machine framework provides a powerful and efficient module for building and executing state machines.
Code fragment L1 represents the state diagram structure shown in Figure 1, using RKH's approach in order to code a state machine in the C/C++ language. This structure, which is defined by vertices and transitions, is static. It is resolved in compile-time without using conditional statements like if-else and switch-case and allocated in non-volatile memory, whereas the actions are resolved by means of function pointers.
This approach prevents us from producing spaghetti code as its complexity is increased. It also turns out to be more efficient in terms of memory consumption and performance than traditional approaches.
As the code in fragment L1 shows, the state machine’s code is readable, maintainable, and it can be easily generated by a software tool from the state diagram. When a state machine has to process an event, its structure is interpreted by RKH according to the state machine's semantics. The RKH almost entirely supports UML state machines semantics.
It should be noted that the name of actions, states, and triggers that are shown in L1 are merely demonstratives. With respect to actions, code fragment L2 shows how they could be implemented.
For example, the entry action of the Idle state has to execute the expression
count = 0, among others, so it is implemented by the SimpleExample_enIdle() function.
This expression is executed by the framework through a function pointer, which is indicated by the macro
RKH_CREATE_BASIC_STATE(), see line 33 in L1.
For more information about how to represent a state machine using RKH syntax, please have a glance at the reference manual.
The RKH state machine framework also provides the complete infrastructure for the execution of state machines and supports both synchronous and asynchronous events. In the case of asynchronous events, the state machine is executed according to the Active Object execution model, which is the UML concurrency unit. In RKH, an Active Object can contain one or more state machines.
If the software system built with RKH requires a preemptive OS/RTOS, RKH completely supports it. In this case, RKH implements this computing model by mapping active objects to threads of an OS/RTOS. In this configuration, the active object model can take full advantage of the underlying OS/RTOS capabilities.
In contrast, if the software system does not require an OS/RTOS, the RKH framework provides a simple cooperative, non-preemptive scheduler to execute active objects. One active object is executed at a time in an infinite loop. Once each event has been processed in the RTC (Run To Completion) fashion, the scheduler is engaged in order to choose the next highest-priority active object ready to process the next event.
RKH not only helps to develop a reactive application from the ground up, but also to reinforce the reactive part of an existing functional and not entirely reactive application. In this sense, RKH supplies enough infrastructure to deal with state machines (reactive part), whereas the rest of the application (non-reactive part) such as
- digital filters
- control loops
- among others
are built by more traditional techniques.
The RKH supports asynchronous events with arguments, which enables events to carry additional information together with the event signal. To do this, RKH employs its own dynamic memory allocation service, which, to avoid memory fragmentation, is a fixed-block memory allocator.
The state machine framework also includes a platform abstraction layer (PAL) which allows the framework to be easily ported to different target platforms. The PAL contains the abstraction of operating system, compiler, IDE, and processor.
RKH has been ported to several processors from tiny 8-bits to modern 32-bits, and to different operating systems like OSEK, FreeRTOS, µ-COS, Windows, and Linux. The last two are frequently used to build cross-platform applications on a more comfortable hardware platform in a fast and easy manner.
Due to this abstraction layer, the RKH state machine framework is very flexible, because it decouples several framework services such as message queue, dynamic memory allocator, timer and scheduler from each other. So they can be provided for example, by a traditional OS/RTOS instead of by RKH itself. Using this capability, it reduces memory consumption drastically.
RKH allows developers to verify and validate a reactive application’s behaviour at runtime by means of its built-in tracer, which is a flexible, configurable and cross-platform software module. In addition, RKH provides a very simple but powerful console application to visualize the trace events’ output in a legible manner.
Each RKH application must have its own configuration file that adapts and configures the framework by means of compiler definitions and macros, thus allowing to restrict the resources consumed by RKH. Adjusting these definitions, ROM and RAM consumption can be reduced, and the system performance can be enhanced in a substantial manner.
Since RKH has been carefully developed from the ground up by using best principles and practices of software engineering, such as
- OOD (object-oriented design)
- software modeling
- design patterns
- TDD (test-driven development)
- continous integration
- coding standard
- static code analysis
- defensive programming
- and more
it is considered a safe, flexible, maintainable, and reusable software.Documentation exists in the reference manual. Also, additional information is located on the official website https://www.vortexmakes.com.
How to collaborate with the RKH community?
Would you like to collaborate with other people working on RKH and enhance it even further? Great, go ahead!. First of all, fetch the project from its official repository:
$ git clone --recurse-submodules https://github.com/vortexmakes/RKH
Now you are ready to share your bug fixes and improvements with other users. Your contributions may enhance your professional training and increase your skills in embedded software development, especially in responsive systems.
As a means of keeping the code quality high, we strongly recommend you to use the “pull request” mechanism to bring your contributions into the framework. Once a pull request is opened, you will be able to discuss and review the potential changes with collaborators. You can then add follow-up commits before your changes are merged into the base branch.
You can also use the test harness that RKH provides.
If you are interested in collaborating with the project but have not made any specific contribution yet, there is a list of desirable features available. This is a good way to become a part of the RKH community. By implementing a feature on the list, you can both develop and contribute it to the project. Our goal is to make it easy for you to join RKH’s developer community.
RKH is a flexible, efficient, highly portable, and freely available open-source state machine framework providing the infrastructure for quickly and safely developing reactive applications for real-time embedded systems. It supplies an efficient method for both implementing and executing statecharts.
RKH allows developers to verify and validate a reactive application’s behaviour at runtime by means of the framework’s built-in tracer. It can utilize any traditional OS/RTOS or work without one. It also encourages the embedded software community to apply best principles and practices of software engineering for building flexible, maintainable and reusable software.
Finally, RKH is available in a public repository in order to not only build embedded applications (or parts of them) in any industry, but also to collaborate with the RKH developer community.