1. Home
  2. /
  3. Integra Sources Blog
  4. /
  5. Embedded System Design: Challenges of Hardware and Software Development
Integra Sources logo


Embedded System Design: Challenges of Hardware and Software Development

November 15, 2023 15 min read last update: December 1, 2023
Embedded System Design
Andrey Solovev

Andrey Solovev

Chief Technology Officer, PhD in Physics and Mathematics

Timur Yuldashev

Timur Yuldashev

IT Writer, PhD in Philological Sciences

Embedded system design is associated with various challenges. Since such solutions consist of hardware and software, developers have to deal with issues related to both electronics engineering and programming. In this article, we will touch upon the process of embedded development and discuss the main challenges of embedded software development and hardware design.

What are Embedded Systems?

Embedded systems consist of computer hardware and software; but unlike personal computers or smartphones, they are designed for a specific function or a set of closely related functions. They typically perform only one task, while a PC can perform various tasks – programming, calculating, drawing, gaming, etc.

A typical embedded system has the following structure:

A scheme of a typical embedded system structure consisting of hardware and software.

Thus, embedded system design requires deep knowledge of both electronics engineering and programming. Such projects require the following specialists: 

1. Project managers participate in the pre-sale phase. If you contact Integra Sources, you can discuss your idea with them as they have the necessary skills to make a rough estimation of the project. They also organize and supervise the work of the team on a particular project. For customers, PMs are the main contact person in the development team.

2. A system analyst and a tech lead are responsible for collecting and analyzing the requirements for the future system and thorough project estimation. The tech lead also designs the architecture of the future solution.

3. Embedded developers are front-line layout engineers and software engineers responsible for designing printed circuit boards and coding programs. 

4. QA specialists are responsible for testing solutions under development. 

To make embedded system development faster, the team usually works on hardware and software simultaneously. Nevertheless, for convenience, let’s consider hardware development and embedded software design as separate parts. 

Embedded System Design: Hardware Development

1. Requirements gathering and project development specification

Since Integra specializes in outsource embedded electronics development, the ideas of new products usually belong to our customers. When the team joins a project, our first task is to gather the requirements for the future device:

  • Functional requirements (what the system must do);
  • Non-functional requirements: performance, scalability, security, size, weight, and other important features.

Customers with no technical background find it difficult to formulate requirements for their products. They tend to pay more attention to marketing and functional features but lack an understanding of the technical side and feasibility of the project. So, the key challenge here is to interview the client thoroughly

It’s also important not to promise more than we can do. If what the customer wants is barely realistic, our job is to tell him or her the truth, explain why, and offer feasible alternatives.

Based on this information, the Integra team creates a project development specification – a document that describes the purpose, functions, behavior, and other requirements for the future device. 

2. Technical proposal

At this stage, the team creates a document that describes the architecture of the future system and the solutions we are going to implement. 

We also select components for the future device. The choice here is limited by the product requirements:

  • Technical characteristics: power consumption, memory capacity, MCU performance, size, weight, etc.
  • Operating environment: extreme temperatures, humidity, vibration stress, etc.
  • The cost and quality of the components.
  • The availability of the components (if the device is supposed to be mass-produced).
  • Developers must find a balance between the cost of the future embedded system solution and its performance.

3. Schematics and PCB design and layout

The device under development must not only perform its key functions but also be safe and reliable. During embedded hardware design, the team takes into account the following issues:

  • The design of the board must fully comply with the PCB design rules so that the device can serve as long as possible with no issues.
  • Due attention must be paid to heat dissipation, especially when designing a powerful device. It can be achieved with proper component placement, or by extending the copper area, adding vias, using a cooling radiator, or by other means. 
  • The components we have never used before must be tested to make sure they function as their data sheets indicate.
  • PCBs must be protected from EOS and ESD events, EM interference, environmental hazards, and other factors.
  • If the embedded system is to be mass-produced, we must follow the Design for Manufacturing (DFM) principles.
  • The board must be designed with certification requirements in mind (if the client wants the product to be certified).

Data sheets may contain errors and inaccuracies. And since embedded product development is a costly service, such problems must be revealed before we spend the customer’s money. Besides, if the job requires a non-standard approach, we must make sure it’ll work for a given project. In such cases, the team may want to build a proof-of-concept prototype first. Electronics prototyping allows us to prove an idea, check the work of components, and reveal various issues at an early stage of embedded development.

Prototyping may require creating not only PCBs but other elements of a system. During one of our projects, we were developing a computer vision algorithm that was supposed to control a robotic manipulator. The model we ordered was too short compared to the measurements provided by the customer, so the team had to make a longer arm, using a shaped metal tube and support elements printed on a 3D printer. This way, we could test the algorithm.

A prototype of a robotic manipulator made of a shaped metal tube and support elements printed on a 3D printer.

4. Testing

Our team tests PCBs under development at each phase of the process. Tests can show if the board functions correctly and complies with various certification requirements. Tests are conducted both after and during development so that we can reveal and eliminate all kinds of defects and issues before moving on to mass production. Read our article on PCB and electronics testing to learn more. 

Often, the team needs to create custom testing firmware that checks if the PCB works as expected. When the product is ready for mass production, we also develop factory testing firmware

What is Embedded Software?

Creating software is the other part of embedded system design. Unlike applications that run on PCs or smartphones, embedded software is created for specific hardware, i.e., can only run on the microcontrollers of special-purpose, non-computer devices. A program that controls a smart watch, a digital camera, a multimeter, or a washing machine is embedded software.

Such programs are built into devices or machines to control them and/or perform a limited range of functions. Often embedded software is installed in devices permanently – although nowadays it can be updated through wireless connection (over-the-air (OTA) update). It is stored in non-volatile memory – ROM, EEPROM, or flash memory. Without it, the device won’t work and turn into a piece of metal and plastic. 

Most embedded programs (except for embedded apps) don’t have a graphical user interface (GUI). They are designed to interact with other software through external interfaces rather than with users through a GUI. If a program does have a GUI, it is typically used for configuring the program and outputting limited data (for example, the information about the device’s state).

The purpose of embedded software is to control a device by transmitting data between the hardware and higher-level programs.

Embedded software retrieves signals and data from the hardware. The program interprets them as commands and data sequences, used for creating various objects, and transmits them to higher-level software.

When embedded software receives commands and objects from higher-level software, it translates them into signals and data arrays and transmits them to the hardware.An embedded system solution can have up to four levels of embedded software:

The structure of embedded software.


Firmware is a type of computer program that boots a piece of hardware and provides it with low-level instructions. Operating systems and applications run on top of firmware. It is written in low-level languages (typically in C/C++). To let the device read it and execute the instructions, the program is then converted into machine code.

Embedded operating system

Embedded OSs are specialized software that controls system resources. With drivers and APIs, an OS provides application-level software with access to the device’s hardware. Applications run on top of embedded operating systems.


Some embedded software designs can include middleware. It’s a software layer between the OS and the application. Virtual machines are typical examples of middleware. A VM emulates a platform and executes a computer-independent code, thus making it compatible with different operating systems. For instance, programs written in Kotlin are converted to a Java code (application level) that, in turn, is executed in a virtual machine (middleware level) running on an operating system (OS level).

Embedded application

Just like typical apps for computers, this type of software performs the functions of the embedded system and directly interacts with users. It processes data, interacts with other devices, and performs high-level functions. Embedded applications are written in high-level languages such as C++, Python, and Java.

An embedded system can incorporate firmware only or more levels of embedded software. Additionally, a solution may require desktop or smartphone applications to function properly. Our team can create all these types of programs for your solution, so give us a call to discuss the project in detail.

Sometimes, embedded applications, embedded OSs, and middleware are referred to as firmware, while the term embedded software is extended to include firmware and embedded software development tools. There is no uniform terminology for these concepts.

Embedded Software Development Tools

Developers use the following tools to create embedded software:

  • Integrated Development Environments (IDE) are toolsets that contain various programming instruments such as editors, compilers, debuggers, and more
  • Compilers and cross-compilers translate the code written in a high-level language into a low-level machine code.
  • Debuggers help developers find and eliminate bugs.
  • Linkers can combine different pieces of code and modules into a single executable program. Modern compilers have built-in linkers.
  • Simulators and emulators provide simulated environments close to real-life conditions for testing programs.
  • System configuration and code generation tools automatically generate code for configuring the hardware components of a device. They minimize manual coding and, therefore, error rates.
  • Code suggestion tools are AI-based instruments that analyze the code written by a programmer and autocomplete it with contextually relevant snippets. They considerably speed up embedded system software development.

Disassemblers are used to reveal errors made by compilers. Sometimes, it is easier to eliminate errors at the assembler level.

A screenshot of GitHub Copilot, an AI-based tool with the function of program code autocompletion.
The autocompletion function of GitHub Copilot and similar solutions considerably speeds up coding. Source: https://github.com/features/copilot

Challenges of Embedded Software Development 

1. Hardware platform selection

The future embedded software design can be roughly estimated when the team creates the technical proposal as experienced developers can see what hardware resources they can expect. 

Of course, the team prefers more powerful MCUs with larger memory capacity. But if it’s not an option and we have to use a less powerful alternative, we need to analyze the project thoroughly to be sure we can implement all the features and optimize the code for this particular hardware.

Since embedded software systems interact with hardware (microcontrollers, sensors, buzzers, etc.), developers need to study the equipment before they start coding. The problem is that certain models may lack the necessary documentation or the data sheets may contain mistakes, inaccuracies, and outdated information.

One of our projects required a module that could simultaneously receive GPS coordinates and transmit data using GSM. The data sheet claimed the module was capable of both, but the device didn’t function properly during tests. The team contacted the manufacturer, and the company admitted that the module couldn’t perform both functions simultaneously. To switch between GSM and GPS modes, it needed to be rebooted. This fact was not mentioned in the data sheet.

This situation is not uncommon for cheap components. Contacting the developer of the hardware usually helps. Sometimes, the developer doesn’t respond, and the team has to analyze the hardware by itself. But these are usually simple components designed by small companies, so studying them is not too difficult.

The manufacturers of expensive hardware typically provide full information in their data sheets but using them makes the final product more expensive.

2. Selecting a programming language and operating system

The choice of programming language is determined by hardware and the type of software we want to create. For example, programs for Android-based devices are created in Java, while software for single board computers is written in C or C++. C is suitable for low-level programming, i.e., for programs that interact directly with the hardware. C++, Python, Java, Rust, and other languages are suitable for high-level programming.

Our team specializes in C/C++ development because a programmer experienced in C++ can use the Qt framework to create both embedded software and application-level programs. Although there are safer alternatives to C/C++ (e.g., Rust), our team is highly qualified and knows how to avoid typical mistakes of this sort. So, by entrusting your project to us, you save money because we don’t need to hire more developers specializing in other languages.

Devices that perform simple actions can function with the so-called bare-metal firmware that doesn’t require an operating system. However, electronics with complicated functions do need an OS.

Here developers have many options: Embedded Linux, Android, Windows IoT, RTEMS, and more. The choice is determined by several factors:

- project goal;

- available hardware resources; and

- development cost.

Powerful hardware can hold resource-demanding operating systems. For instance, writing software for Ubuntu won’t take much time but will require powerful and expensive hardware as Ubuntu has many services, drivers, and packages. Weaker hardware makes developers spend more time optimizing and customizing the code, so embedded software programming grows more expensive.

A scheme showing the dependencies between embedded software development cost and available hardware resources.

Our team prefers free operating systems because creating software for them is easier and cheaper. But we can also create programs for proprietary OSs if the customer insists. 

3. Software architecture design

Before writing the code, developers think through the architecture (structure) of the future solution. The architecture includes software elements, the relations among them, and their properties.

Since we deal with different hardware platforms and are limited in resources, we can’t use a single architecture template for all projects. Embedded system design requires optimal solutions, so a universal architecture won’t work here. We have to pick from a number of architecture templates and customize them for each particular project.

Often embedded products under development are only a part of a bigger system. A project may also require developing application-level software that will interact with the device somehow. In theory, the team can design embedded software first and move on to other tasks after that. But to make the process faster, our embedded team creates a document that describes external interfaces and protocols for interacting with the programs so that the other teams can start their work as soon as possible. It’s a common practice that speeds up the process.

Sometimes, we create a mock service that emulates the work of the embedded program and generates synthetic data for the application-level software under development.

4. Coding

When everything is settled, the team gets to coding. The key difference between embedded software and application software development is that embedded programs don’t have complicated logic. The true challenge is to make the software interact with the hardware and control it correctly.

  • Lack of information

Application software developers have lots of frameworks with ready-made solutions and tons of information on the web. But embedded software developers create code for non-standard, heavily customized equipment. They need to understand how this particular hardware works, so they spend a lot of time studying data sheets and/or testing the hardware manually.

Within one of our projects, the solution under development was supposed to send commands to MacBook computers via a USB port. The commands are represented by sets of bits, but Apple doesn’t provide any information on this matter in official documents. So, the team had to search different forums to find the information.

Sets of bits representing “Reboot” and “Switch to DFU” commands for MacBook.
These sets of bits represent the commands “Reboot” and “Switch to DFU mode.”
  • Data security

Many embedded devices have access to the Internet. If they transmit sensitive data, the communication must be secure. Here we have a range of standard encryption methods. For instance, right now the Integra team is working on a medical device that transmits biometrics via the Internet. This kind of data must be protected. However, encryption raises the hardware requirements, so developers don’t use it when data carries no sensitive information.

  • Memory and performance shortage

Embedded devices are getting smaller, while the performance requirements for them are increasing. Although memory shortage isn’t as critical today as it used to be, it is still a problem for embedded software development.

Power limitation is another typical problem for battery-powered devices. The work of its software must be programmed in such a way as to minimize electricity consumption. To do so, developers can reduce the number of instructions for the processor core. Another way is to put the processor core to sleep mode until an outside event (such as timer interruption) occurs. We mentioned both these techniques in our article devoted to firmware development practices

  • Stability

Although software can’t “break” like hardware components do, it can still crash. Most of such problems are caused by incorrect memory access.

Here is a typical example. Process 1 calculates a variable and puts the value into a memory cell. This value is required by Process 2. Since the two processes run in parallel, Process 2 may access the memory cell before Process 1 calculates the value, which causes a crash. 

When coding, developers must foresee such situations and give processes proper instructions – for instance, instruct Process 2 to make sure Process 1 has calculated the value before using it.

  • New requirements

Sometimes this phase becomes challenging because the customer decides to extend the functionality of the device or wants to change the requirements for the project. The hardware platform chosen at the preparation phase may not be sufficient for the new features, and the team may even be forced to start over. 

  • Optimization

Software optimization plays a huge role in embedded system design as we are always limited in resources. Programmers can make software fast but memory-intensive or vice-versa – memory-friendly but slow. Modern compilers offer many types of optimizations so that developers can find a balance between these extremes.

Drawing showing the importance of finding a balance between the performance and memory intensiveness of embedded software.

5. Testing and debugging

A typical application can be tested on a computer, but embedded software is designed for devices and equipment. So, developers need a fully featured test station or even field trials. QA specialists have to be very resourceful.For example, when working on the aircraft towing system, the team had to test the distance-measuring module somehow. Our QA specialist designed and created a special stand with a 3D printer. The module was fixed on the stand, while the stand was attached to the hood of a car with a magnet.

A 3D model of a test stand with an embedded device attached to it.
The team tested the device by driving around parking lots.

Sometimes we need to develop software for a device that we don’t have – for example, if it’s too heavy to transport or when we design a PCB for a larger system. This makes testing even more difficult.

In that case, the customer can install TeamViewer or a similar solution on a computer and connect the PC to a camera and the device under test. This way the team can connect to the PC to give commands to the device and see what’s happening through the camera.

Applications are usually standalone products, while embedded programs always interact with hardware. When an error occurs, it’s difficult to tell whether the problem was caused by hardware or software – especially during field trials when the testers are limited in diagnostic tools. The only way to see if the software is working properly is to upload logs to a connected laptop in real time. 

As for hardware, QA specialists use oscilloscopes, voltmeters, multimeters, and other tools to check if the PCB and its components are working properly.

Our team designed a device consisting of a single-board computer and two PCBs. The SBC was supposed to send a heartbeat package to one of the boards to confirm it’s still working. If the PCB did not receive the package, it was supposed to reboot the computer automatically, which the board did all the time during tests.

The team checked the bus with a logic analyzer and confirmed the SBC sent the correct signal, which proved the problem was caused by the firmware of the PCB that didn’t process the package correctly.

If the device fails due to an equipment defect, the team can fix it “manually” instead of manufacturing a new PCB, which would raise the development cost. 


Embedded system design is a complicated process consisting of many steps and requiring professionals specializing in electronics engineering and embedded programming. The team has to overcome many challenges at each phase from requirements gathering to testing. Moreover, to speed up the process, hardware design and embedded software development must be done in parallel. Integra Sources is a well-knit team with rich experience in embedded electronics development. We know what challenges to expect at each step and how to deal with them. Don’t hesitate to contact us if you need help with your project idea.

Andrey Solovev
Andrey Solovev
Chief Technology Officer, PhD in Physics and Mathematics

Timur Yuldashev
Timur Yuldashev
IT Writer, PhD in Philological Sciences