Table of Content
Krasamo is one of the top firmware development companies in Dallas, Texas, with more than 12 years of experience in IoT development
Introduction
Embedded Systems (ES) are electronic systems that perform a specific function that uses microcontrollers with built-in software (firmware). They are common in industries for controlling and monitoring problems related to equipment, machinery, or plants, typically operating in isolation without fully utilizing their potential for interaction.
When connected to the internet and integrated with IoT systems, embedded systems enable their interaction with the environment through sensors and actuators. They are properly powered to ensure a sustained and autonomous operation within the ecosystem.
These systems present challenges for IoT developers that require expertise and design criteria for creating a customized solution that minimizes energy consumption, incorporates specific sensors, establishes connectivity, processes data to generate useful information, and ensures the robustness, security, and reliability of the systems operating in open environments.
Firmware development is an essential component of IoT that enables the creation of reliable and high-performance IoT devices that operate seamlessly and effectively.
What Is Firmware?
Firmware is a type of software embedded into hardware devices responsible for controlling their operation and device-specific low-level functions. Firmware provides devices with the instructions to carry out functions such as network connectivity, screen control, and interactions with other hardware components. Firmware is typically stored in flash memory (non-volatile) or read-only memory (ROM) (non-volatile) and written in a low-level language such as C, C++, or Assembly.
Understanding Firmware Development for IoT
Firmware development is the process of programming and maintaining the firmware embedded into IoT devices (hardware). Firmware is designed to access and control the device resources (input/output interfaces, memory, timers, controller, etc.).
Developing firmware for embedded systems requires understanding of device system-level components, hardware architecture, and experience with low-level programming languages (assembly or C programming language). Understanding hardware components ensures IoT device performance, reliability, and security. Hardware components are tightly coupled and require precise interactions and control for operation.
In addition, firmware development requires skills for diagnosing issues and implementing techniques for creating testing and debugging code running in microcontrollers.
A well-implemented firmware development process with the right tools and techniques can make a difference in reducing costs and leveraging existing components to improve time to market.
Due to their increased processing power, modern microcontrollers can execute complex programs, making it possible to develop firmware that can work with multiple platforms and software products with minimal modifications.
Firmware development involves following a well-established process and creating essential elements such as hardware abstraction layers (HAL), APIs, drivers, and application frameworks. Firmware development is a time-consuming task that may require firmware modification due to changes in hardware design, firmware porting, or updating firmware remotely.
IoT developers must have experience and knowledge about the different architectures of microcontrollers and peripherals.
Firmware Architecture and Components
To fully utilize the capabilities of microcontrollers, it is critical to understand their firmware architecture and system components, including the CPU for executing firmware instructions, memory types, sizes, and I/O peripherals such as sensors and actuators.
An organized firmware architecture defines the relationship between components and their environment, providing a foundation for software implementation. Developers can identify dependencies and interactions and typically divide firmware development into separate software layers, improving efficiency and maintainability in IoT development.
A firmware engineer can create an architecture diagram representing the system components and their relationships. Additionally, this can give an overview of the firmware system and software layers and their interaction with the hardware.
In the next paragraphs, we will discuss some of the critical components of the microcontroller system that are necessary to comprehend firmware development.
Microcontroller Processor
The central processing unit (CPU) is a microcontroller component responsible for executing instructions and controlling the microcontroller’s hardware. It can be either an 8-bit or 32-bit processor, optimized for low power consumption and performing in real-time.
The processor, or CPU, has a control unit, an arithmetic logic unit, and a register file. It is connected to the peripherals and memory. It fetches instructions from memory to control peripherals, decodes instructions, executes steps, and writes back data.
The processor is where the firmware is stored and includes features for embedded applications, such as Input/Output operations for controlling the operation of a machine or motor or collecting data from sensors.
Memory
ROM (Read-Only Memory) is non-volatile, meaning its contents are retained after the device turns off. ROM memory is usually where the microcontroller’s firmware is programmed and stored at the factory, and it cannot be altered.
Flash memory is like ROM, also non-volatile, yet it can be erased and reprogrammed. It is typically used for storing data that needs to be frequently updated, such as operating systems, program counters, etc.
Another type of non-volatile memory is the EEPROM memory (Electrically Erasable Programmable Read-Only Memory) that can be erased and reprogrammed electrically, typically for applications where data changes frequently.
Random access memory (RAM) is used to temporarily store data that needs to be accessed while the microcontroller is running. It is volatile, meaning data is deleted after the device turns off.
I/O Peripherals
I/O peripherals enable the microcontroller to interact with the external world. They are built into the microcontroller or connected externally. I/O peripherals are classified as input and output. Input peripherals are for receiving data, and output is for sending data.
Input peripherals include digital-to-analog converters (DACs), analog-to-digital converters (ADCs), counters, timers, sensors, and other components.
DACs convert digital signals generated by microcontrollers into analog signals for use by control actuators. ADCs convert analog signals created by sensors into digital signals to be used by microcontrollers.
Output peripherals allow microcontrollers to send data externally, control physical devices, and include motors, relays, LEDs, displays, etc.
Interfaces
Interfaces connecting to other devices can include various serial communication protocols, such as I2C, SPI, UART, and other proprietary or standard interfaces. These interfaces enable the microcontroller to communicate with other devices in the system, such as sensors, actuators, and other microcontrollers.
Interfaces are a component of a microcontroller system and essential for communicating with other devices. Therefore, expertise in serial communication protocols such as I2C, SPI, UART, and other proprietary interfaces is required for designing firmware efficiently and reliably.
Modular Firmware: Benefits and Strategies
A modular structure can bring significant advantages to embedded firmware projects. By developing a flexible firmware architecture that builds firmware in modules, functionality can be separated into independent modules with minimum dependencies and high cohesion. Furthermore, this approach enables the modules to be used in new applications, making it a versatile solution.
Separating the application and low-level code boundaries is recommended to improve the scalability and maintainability of the device firmware. This separation allows for creating clear interfaces and function prototypes specific to each software module, enabling them to perform their intended functions efficiently.
An architecture based on layers can hide the implementation details from other software layers and provide an interface with specifications for accessing hardware functions. A hardware abstraction layer (HAL) is a specific API designed with higher-level function calls to facilitate interaction with hardware.
Although this topic is beyond the scope of this paper, it is recommended to pick the simplest architecture that meets the requirements of the project’s use case.
Firmware Programming
Firmware programming creates software that provides the functionality of the device operations and control of the hardware components; therefore, it is critical to ensure the security and reliability of the firmware code.
Firmware programmers with IoT skills and secure coding practices help protect from threats and attacks. They also follow firmware security practices such as encrypting data stored in the firmware, implementing access control, securing booth mechanisms, and using code signing, input validation, patch management, etc.
As mentioned, programming firmware in resource-constrained devices is challenging and requires optimization techniques.
Embedded Linux systems running on 64-bit microcomputers are powerful and have gained popularity in recent years, making it possible to create embedded systems using the Flutter UI toolkit and Dart language, offering a high level of abstraction.
When choosing a low-level firmware programming language, consider the specific needs of the project: target hardware, developer skill level, and the development environment. As a starting point, in the following paragraphs, we briefly describe the most important firmware programming languages.
- C Language. C is the most popular general language choice for developing firmware and is supported by manufacturers and tools. IoT developers must select a standard version of C language, such as the C99, ensuring safe constructs and useful features that support variable-length arrays, designated initializers, and restrict keywords. However, C language produces highly optimized code, requires memory management, and is more complex than C++.
- C++ Language. C++ is a low-level language, an extension of the C firmware programming language that is used for programming complex systems, including portability across hardware platforms, providing direct access to hardware components and advanced concepts such as pointers, structs, memory management, etc. In addition, C++ supports object orientation; it is harder to optimize but gives the developer a higher level of abstraction.
- Assembly. Assembly is a programming language specific to hardware platforms with low-level instruction set architecture and limited power and memory. It is a highly efficient program that controls hardware resources and enables code execution with low overhead. It is much less common than C or C++ and less complex, but it can be highly optimized.
- Rust. Rust is a programming language that provides features for memory security and memory safety. It is a flexible firmware programming language that offers low-level access to resources and cross-platform compatibility. Rust creates an optimized executable and provides proper memory management, a high abstraction level, and fast running in embedded systems.
- Python. Python is a high-level programming language that requires high memory and processing. It is commonly used for testing and validating design prototyping and firmware algorithms. It can also be used for building user interfaces that interact with the embedded system. However, it runs slowly unless there are many resources, making it unsuitable for embedded development.
IDEs Used in Firmware Development
Integrated development environments (IDEs) are essential for firmware development; these provide the necessary tools, including a source code editor, debugger, and other tools such as a version control system, compiler, debugger, text editors, assemblers, emulators, linkers, and development environment.
We recommend using an IDE that combines tools, is compatible with the hardware platforms and development environment, and supports the programming language.
Some popular IDEs offering tools for programming firmware are Eclipse, Visual Studio, Keil uVision, Atmel Studio, IAR Embedded Workbench, and MPLAB X IDE.
Many microcontroller manufacturers support a wide range of IDEs and offer their own IDEs.
For example:
- Silicon Labs – Simplicity Studio
- ST Microelectronics – STM32CubeIDE
- Texas Instruments – Code Composer Studio (CCS)
- NXP Semiconductors – MCUXpresso IDE and CodeWarrior
RTOS in Firmware Development
Real-time operating systems (RTOS) are an essential component of IoT devices, as they enable the integration of software components that facilitate the programming of functionality in IoT devices. In addition, these operating systems also provide the processing capabilities to achieve superior operating performance in IoT devices.
It is essential to evaluate the capabilities of the RTOS to ensure it meets functional requirements such as response time, system reliability, and interrupt handling. Also, it must be capable of supporting the hardware platform and development tools to ensure it meets the performance requirements (responsiveness).
RTOSs are designed to meet the unique challenges of real-time systems, including the need for fast and reliable data transfer, interrupt handling, and synchronization of multiple tasks or processes, making them an essential component of many embedded systems and firmware applications.
Most RTOSs are available under open-source licenses, allowing customization to fit specific use case applications. This makes them versatile for deployment across various operations and devices.
Firmware Debugging
A debugger is a software tool that allows testing the code. Firmware debugging is an essential task in the firmware development process, requiring specialized tools and techniques for identifying errors, issues, and bugs in the code. It involves using tools (debuggers, trace tools, emulators, etc.) to help identify issues and track errors. These tools are integrated into an IDE or are independent.
Developers use specialized techniques in debugging: code review, logging statements, setting breakpoints, using emulators, and tracing to record and analyze the code execution.
Firmware Testing
Firmware testing is an essential part of the embedded firmware development process that brings its own challenges and best practices. Firmware is tightly coupled to the hardware, making it more complex than other types of software.
Firmware is embedded in a hardware device and interacts with components, making it difficult to modify and test in isolation. In addition, the firmware may need to be tested on the hardware because of complex dependencies with components, libraries, and other modules.
Firmware is safety-critical, meaning that a bug in the system could cause the device to fail, so it must be thoroughly tested. Since firmware operates in real time, it must ensure it meets timing requirements and the complexities of low-level programming languages, making it difficult to use standard tools and testing techniques.
Several techniques can be combined to test firmware, such as debugging, simulation in virtual environments, and hardware-in-the-loop (HIL) testing. HIL techniques test the firmware on the actual hardware where it is running. But it is harder to create simulation scenarios when testing firmware, due to the limited resources of devices.
Individual modules and functions are tested using unit testing to ensure they meets specific requirements before integrating them into the firmware build.
The compiled and linked firmware code is then tested and ready to be loaded onto the target hardware platform.
Firmware Compiling and Linking
Linking firmware code is a process that combines object files, libraries, and dependencies into an executable image (firmware build) that is loaded onto the target platform.
The firmware is compiled into object files that are linked together with dependencies and contain machine-readable instructions to create a “firmware build” or “firmware binary” file (firmware image) to be loaded and executed by the hardware.
Linking combines the code and dependencies into an optimized firmware image tailored to the project and the hardware platform.
Portable Firmware Development
Nowadays, clients consider building firmware code that can be reused and portable to other hardware, applications, and environments. Developing firmware should have a clean interface and detailed documentation that is easy to understand and helps to keep the firmware updated.
Ideally, engineers design firmware that can run on different MCUs and processor architectures with minor modifications.
As a firmware development company, Krasamo recommends building products on microcontrollers with defined generic interfaces that allow testing of new components, simplifying reusing code, and combining software components from various vendors.
Developing code in programming languages such as C or C++ in a standard accepted version using a well-defined implementation mechanism improves portability.
Also, developing firmware code modularly or loosely coupled with few dependencies and cohesive elements can help execute specific functions on I/O peripherals.
A Krasamo firmware engineer is available to discuss how to create firmware and approach portability options adapted to your use case.
Embedded Software Development Services
When searching for a firmware company, it is critical to understand existing embedded architecture solutions for IoT and find a partner with firmware engineers who can technically influence your embedded system project.
Firmware engineers must be capable of designing a fully embedded system for IoT with different options based on the design objectives criteria.
In addition, firmware engineers must deeply understand the technical possibilities and limitations of sensors and actuators to enable advanced firmware design.
Krasamo has more than 12 years of experience developing firmware and helping clients with embedded projects. Krasamo offers:
- A proven track record in embedded software development (firmware programming, connectivity, hardware platforms, and development tools)
- Firmware Customization and Optimization
- Experience Developing Software for Real-time Systems
- Testing and Debugging Services
- Firmware Support and Maintenance
- Troubleshooting and Debugging of Complex Issues