A portable, reusable collection of components which provides a standard environment upon which an embedded application can be implemented…
The purpose of a framework is to improve the efficiency of creating new software. Frameworks can improve developer productivity and improve the quality…
The obvious qualities embedded frameworks should have consist of (at a minimum in the author’s eyes)…
The best way to create an embedded framework if you don’t have millions and minions to do it from scratch would be…
We could start the discussion of the history of embedded frameworks by surveying what was way back when and then move forward to today…
The closest things we can find to “embedded frameworks” as of early 2021. If you dig in to these, you’ll see that they’re all over the place…
A portable, reusable collection of components which provides a standard environment upon which an embedded application can be implemented. Allows you to focus on the application (user features) instead of being consumed getting your infrastructure working. A framework should include utilities and tools to significantly reduce development time of embedded software while increasing the quality of the software. This framework is used by embedded software development team members to implement the features of a product during development. The software components of the framework should contain code that encapsulates and automates common peripherals in the CPU as well as provides often used functionality to reduce the effort of developing embedded software. An embedded framework should jumpstart your embedded development project and significantly reduce the time to market.
“The purpose of a framework is to improve the efficiency of creating new software. Frameworks can improve developer productivity and improve the quality, reliability and robustness of new software. Developer productivity is improved by allowing developers to focus on the unique requirements of their application instead of spending time on application infrastructure (“plumbing”)”. This quote is from reddit or cimetrix (someone copied someone but we just want to quote them). Either way, we like it.
Bottom line: REAL embedded frameworks should reduce the product development workload while increasing embedded software quality while making the product’s features (and device drivers) portable across all the platforms that the framework runs on.
The obvious qualities embedded frameworks should have consist of (at a minimum in the author’s eyes):
- Portability. Obviously the preference here would be that the framework is portable to as many other CPU variants as possible. Given how common ARM is, being portable to multiple vendor’s ARM families would go a long way towards making the framework able to go everywhere.
- Reusability. This does not mean copy/modify. It means true reusability where new projects reference the framework instead of copying it to the new project. This should also apply to your user-facing features and your device drivers. Once a developer has created a user-facing feature and/or device drivers, they should be able to reuse them the way they are, preferably from the configuration management tool rather than copy-from-the-last-project-and-modify-it-as-you-go. We should all stop accepting copy/modify as the norm because it is so old school (copy modify creates 2 copies which means 2 places to fix bugs but in different ways since the environments the copied code exists in will be different)!
- Execution speed (lack of overhead). Frameworks can become very bloated with a multitude of layers and abstractions needed to generalize and fit the needs of the masses. A framework should be thin. So thin in fact that the API calls are what-you-see-is-what-you-get.
- Ease-of-learning. We’ve all seen massive frameworks that have phone-book-sized documentation that takes months to learn. It is all too common to get stuck in a situation where you implement something and it doesn’t work the way you want and you spend hours/days/weeks chasing down problems only to find that you called methodX(uint64_t, struct*) that you thought did X and find out that you need to call methodY(uint32_t, char*) instead. Complex is often unavoidable. But simple should be the goal.
- Good documentation. This does not mean lots of the phone-book-sized docs. This means docs that actually help and actually answer questions in a thorough and complete way.
- Available technical support. We’re not talking about available-at-our-beck-and-call. You should be able to email them and get an answer in a day or two (worst case) or call them and get someone who can actually help real time or visit their website and consult the knowledge base.
- Long term maintenance. Meaning not at end-of-life in the developer’s array of products. Everyone has had to deal with finding out that the enablement they’re using is no longer supported. Had we known going in that the vendor was going to drop it in a year, we probably would have selected a different solution. We want a product that is going to be around for a long time.
- Flexibility. We want to avoid “inversion of control” where the framework is in charge and your code is merely along for the ride. We want to be able to enhance where we need to or add our own implementations in parallel so that the framework’s limitations are not our limitations.
- Well tested. Users should not be the Guinea pigs. A framework should be developed in a continuous integration environment where a well-rounded set of unit tests is automatically performed before every release.
The best way to create an embedded framework if you don’t have millions and minions to do it from scratch would be to endure decades of developing a continuous stream of embedded systems. At some point, it becomes obvious that you’re doing the same thing over and over. You would start finding ways to implement each system using what you’d done before. But soon you’d find that you need to generalize what you’ve already implemented for past projects. So, you’d start to take a higher level perspective with what you’re working on and start implementing basic capability in a general, reusable, portable fashion. You’d want to separate the user-facing features of the customer’s product from the basic, always-need-this functionality.
You’d discover that you need an abstraction of the RTOS so that using different RTOS’ does not cause your code to have to change. So, you’d want to create a thin API that your embedded code calls to start tasks and such. Then you’d realize that every RTOS does things differently so that would cause you to have to get around this problem in the reusable/portable code. You’d land in a world where you don’t want the RTOS API to be a part of your user-facing functionality. In fact, you’d realize that most (like 99%) of your embedded functionality is time driven and so often used that you create a slew of various time-based tasks (like this
/* (Name, Period, Priority, StackSize) */
RTI_TASK_RATE_1mS, 1, 0, 2048
RTI_TASK_RATE_5mS, 5, 1, 3000
RTI_TASK_RATE_10mS, 10, 3, 2048
RTI_TASK_RATE_20mS, 20, 4, 2048
and so on)
Then use those to implement your functionality. Then you’d finally see the light and realize that if all of your tasks ran to completion instead of waiting for their custom time delays/semaphores/whatever and your time-based tasks had some kind of priority associated with them you would be RTOS agnostic. What a luxury. Then you’d notice that there are event based tasks and periodic tasks. You’d design an RTOS infrastructure:
- RTOS agnostic so it does not care what RTOS the customer wants.
- All tasks run to completion.
- All tasks are time-based.
- Tasks are either event or periodic.
- Never do tasks call time delay, semaphore wait, etc.
- This RTOS interface becomes foundational.
Having reached RTOS nirvana, you’d be able to address this nagging realization in the back of your mind that shared data is a glaring failure in your design because EVERY task needs data from other tasks and wants to provide data to other tasks. It feels like what you need is a central data center where a software component can say “hey create this data item and make it so that I am the only one who can write to it but make it possible for others to be able to read it whenever they want”. But as soon as you got that working for an int32_t you’d see that you need it for uint64_t and all the others. Then you’d realize that you want to do the same thing for user defined types (messages and structs and such). So you’d fashion a data center that does all these things. This would become a new foundational concept.
And you’d also realize that while you’re creating software components that can be reused the way they are means that you need to implement some mechanism so that you can tailor them to each new environment WITHOUT modifying the code. You want to do this because you know that testing (being the bane of software’s existence) is costly and painful and fraught with constant issues. You’d like to be able to develop your basic component (ALWAYS used on every project) and test them ONCE and then reuse them untouched on every project. This tailoring (configuration) aspect of behavior again becomes foundational.
You notice that the basic functionality (software components) that are used again and again and again consists of (here’s that same Vtrek image you’ve probably seen before):
- A/D and D/A conversions (and their storage, calibration, filtering, manipulation, etc.).
- GPIO (and their inputs, outputs, filtering and manipulation, etc.).
- Fault tracking (and their events, collection, storage and retrieval, etc.).
- Communications (input, queueing, output and translation of I2C, SPI, serial, USB, ethernet, etc.).
- Modes (POST/BIT mode, manufacturing test mode, service mode, and the publish/distribution to all entities, etc.).
- File (and their storage, retrieval and manipulation, etc.).
These software components use your custom RTOS API to manage when they run but always run to completion and they store data in the data center for centralized management and sharing and are configurable so that every project uses the exact same code but is tailored (configurable) for the customer’s needs in the product. Now you’re talking reusability and portability. Your embedded framework has a thin API that is fast and easy but also comprehensive enough to include all the basics. And you can separate the user-facing features (which utilizes the exact same architecture and design philosophy) from the basic functionality. And now you find that you can crank out an embedded system quickly (saving time and money) and with quality (all of which translates into higher profitability). Job well done!
You realize that this methodology could be useful in embedded systems of all sizes (excluding perhaps tiny because those systems have such a limited amount of RAM/ROM that pretty much EVERYTHING has to be coded from scratch).
Not truly part of a framework but still just as important are the tools. We all know that
Of course, no discussion of frameworks (embedded or otherwise) would be complete if it didn’t discuss the well-known big boys of operating systems:
- Green Hills Integrity
- Wind River’s VxWorks
- Many others shown on wikipedia
But while these are clearly capable of being embedded frameworks, they are far more than simply a framework as they’re full-featured operating systems. They include full-featured management of disk drives, printers, USB of all types including host/hub, SPI/I2C/Ethernet and everything else commonly found in computer systems both embedded and non. But if you’re developing an embedded system that operates the seats of a car or a hospital bed controller or a stove, your price point of CPU can’t afford the heavy resource requirements of true operating systems like these. Historically they matter but they’re out of our realm entirely.
So this discussion of the history of embedded frameworks constrains the embedded platform significantly to those having less than 2 MB of RAM and/or flash. And now we’re talking about embedded frameworks like Vtrek or those listed elsewhere on this page. What history could we discuss that is meaningful and applicable? Head over to the history of Vtrek to find out.
The closest things we can find to “embedded frameworks” as of early 2021. If you dig in to these, you’ll see that they’re all over the place. We included them because they appeared in search results when we were trying to find competitive “embedded frameworks” products on the market (meaning the authors call them an embedded framework, not us). If you understand what we’re getting at here, we think that the concept of an embedded framework is so overloaded as to be almost useless.
|Quantum Leaps: Modern Embedded Software||State-machine.com – Finite State Machines & Tools|
for Embedded Systems.
|.NET nanoFramework – Making it easy to write C# code for …||Nanoframework.net – a free/open-source platform that enables the writing of managed code applications like desktop application developers.|
|IOT embedded framework in GO. My experience in using GO …||Rferrazz.medium.com – Chik A framework made in GO that allows you to create IOT monolithic applications just by assembling or creating components called Handlers.|
|HCC Embedded Expands Advanced Embedded Framework …||Hcc-embedded.com – Developers of ChibiOS-based designs can leverage HCC’s complete suite of middleware for networking, storage, and security to rapidly create highly reliable products.|
|ChibiOS free embedded RTOS – ChibiOS Homepage||Chibios.org – ChibiOS is a complete development environment for embedded applications including RTOS, an HAL, peripheral drivers, support files and tools.|
|Embedded Simple Frameworks | Custom XCoS & RTOS Design||Indesign-llc.com – our Embedded SF framework divides system software into three layers of code. High level feature code drives the user interface and other state control logic. Middle layer task software handles communications between layers and implements algorithms basic to system operation. Low level driver code directly controls hardware interfaces of the device (used for their engineering services only – not for sale).|
|Introducing EMBD: A Superheroic Embedded Programming …||Thoughtworks.com – …Golang…EMBD…a framework for Go which does GPIO (General Purpose I/O), talks the I²C protocol (+ many more) and provides the drivers necessary to interact with many hardware sensors.|
|GitHub – embvm/embvm-core: Core components, subsystems, and utilities for the Embedded Virtual Machine / EmbeddedArtistry||Github.com – The Embedded Virtual Machine (Embedded VM or embvm for short) is an embedded software framework that helps developers create portable and reusable embedded software components / strive to provide in-depth and highly technical embedded systems content that will help teach you advanced skills and modern software practices|
|NASA – GSFC Open Source Software||Opensource.gsfc.nasa.gov – The main goal of the cFE is to form the basis for a platform and project independent reusable software framework. The cFE with the OSAL allow the development of portable embedded system software that is independent of a particular Real Time Operating System and hardware platform.|
|Microsoft® .NET Micro Framework||Github.io – is an open source platform that enables you to write managed code C# applications using Visual Studio for resource constrained embedded devices. No longer supported.|
|TinyCLR OS – GHI Electronics||Ghielectronics.com – a modern, managed operating system that brings .NET to embedded devices.|
|MBED||Mbed.com gives you a free open source IoT operating system with networking and security built-in|
|MicroEJ||Microej.com is an embedded software platform|
|MPLAB Harmony||microchip.com is “MPLAB Harmony 3 provides a Chip Support Package (CSP), core hardware abstraction libraries, extensive middleware, and a graphical configuration tool for development of C language embedded software for Microchip 32-bit microcontrollers and microprocessors”.|
|Redblocks||With the Rapid Embedded Software Development Toolkit redBlocks you can substantially shorten the development time, save expenses and improve the quality of your deeply embedded software applications|
|Segger||25+ years of experience in providing highly efficient software libraries that lay the groundwork for modern embedded systems.|
|pnp-software/fwprofile||C Implementation of an unambiguous definition of State Machines and Activity Diagrams for Safety-Critical, Real-Time and Embedded Applications.|
|CORDET Framework||A software framework for service-oriented applications. It defines an application in terms of the services it provides to other applications and in terms of the services it uses from other applications.|
|the Zephyr Project||The Zephyr Project is a Linux Foundation hosted Collaboration Project. It’s an open source collaborative effort uniting developers and users in building a best-in-class small, scalable, real-time operating system (RTOS) optimized for resource-constrained devices, across multiple architectures.|
PS: If you find or know of an embedded framework that should be added, please email us at info @ omniembedded.com?
An embedded system consists of an embedded controller (processor, memory, I/O drivers and software or firmware) that has a specific set of control functions within a larger system. The larger system is typically a mechanical system or machine. Combining digital control with electro-mechanical devices can result in higher efficiencies, smoother operation, longer life and complex features that cannot be accomplished with mechanical solutions alone.
Along with digital and analog circuitry, power supply, the digital core and the I/O driver set you need controller-specific software. Traditionally, software development for embedded systems has been the highest cost element of the control system. Vtrek was conceived to bring that cost in check by creating an API style of embedded code library joined with common componentry, tools, and practices.
Past practice among organizations that develop embedded controllers has been to perform all software development internally and, in some cases, to develop proprietary development and product support tools. For various reasons such as processor size limitations and cost, this was the only way to get a product to market. Times have started to change and the “not invented here” mindset is starting to melt away. The cost of silicon, as Moore’s Law predicted, has made it possible to get far more power per unit cost, and has opened the door to adapting more 3rd-party solutions to proprietary products. Vtrek is intended to be a development platform that makes the most of this trend.
Vtrek is meant to run on 32-bit ARM Cortex M0, M4 cores and beyond, and runs on top of CMSIS (Cortex Microcontroller Software Interface Standard) BSP solutions. Vtrek’s source code library provides an efficient framework and services that work well for applications such as vehicular (ABS, body controllers, HVAC controllers, comfort control, steering, etc.), hydraulic system control for machines such as backhoes and excavators, smart home automation and many other similar (mechatronic) applications.