Embedded Software Development

Martijn Bastiaan

Reading time: 7

Table of contents

+
-

  1. The QBayLogic approach to Embedded Software
  2. The advantages of our Embedded Software Design
  3. Technical implementation of Embedded Programming
  4. Real-World Application: Precision Flow Measurement
  5. What makes QBayLogic unique?

Our approach to embedded software is an integral part of our complete hardware design approach. We develop embedded software exclusively in combination with the custom hardware designs we create, ensuring fast iteration and seamless integration between hardware and software from day one.

The QBayLogic approach to Embedded Software

In the type of projects we do, embedded software serves a specific purpose: it manages and coordinates the less time-critical functions of your system while your custom hardware handles performance-critical computations. Deploying FPGAs in conjunction with embedded software gives you a solution where you have the real-time or low-latency performance of our chip designs, but keep certain other functions configurable and adaptable after deployment.

Tasks our embedded programming typically handles:

  • Turning subsystems on and off
  • Managing communication between hardware components
  • Sending results to connected computers
  • Coordinating sensor readings and calculations
  • Managing the overall system workflow

There are many software engineering companies that can develop these software components for you. What sets us apart is how embedded software development fits into our service offering and engineering process. We usually don’t develop embedded software for existing hardware. A typical project here involves developing the software as an integrated part of a complete hardware solution. By designing both the custom silicon and the software, we deliver fully functional systems that work seamlessly from the start.

The advantages of our Embedded Software Design

Our integrated hardware-software development methodology delivers several key benefits that traditional workflows simply cannot match.

We work with modern programming languages, particularly Rust, for our embedded software development. This allows us to reuse data structures from our hardware designs and generate foundational code automatically. A significant advantage over traditional approaches.

Modern type systems prevent errors before they occur. By using algebraic data types (ADTs) available in Rust, we simply make certain categories of errors impossible. For example, when dealing with data validation—checking whether a piece of data is valid before reading it—ADTs enforce these checks at compile time. You literally cannot forget to validate data because the compiler won’t let you. This automatically eliminates many hours of work from the testing and debugging stages of the project.

Single source of truth eliminates synchronization issues. Your hardware description serves as the single source of truth for the entire embedded system design. From this one definition, we automatically generate the base software components. This means hardware and software definitions can never drift apart, a common problem we see when separate teams maintain separate specifications for hardware and software.

Unified development reduces overhead and risk. Unlike traditional setups with separate hardware and software teams, our integrated approach to embedded software design eliminates the overhead of inter-team communication, reduces dependency on documentation accuracy (which is almost always lacking) and prevents duplicate work. When hardware engineers make changes, the software automatically reflects those changes.

Fearless iteration accelerates development. We can even make changes that traditional teams wouldn’t dare attempt. Need to add hardware registers? Modify memory mappings? In traditional workflows, these changes require careful coordination between teams and extensive testing. To a point where workarounds are usually preferred to the actual change process. For us, this type of changes is routine. Everything gets regenerated automatically, maintaining consistency throughout the embedded system design and drastically reducing the risk of failure.

Technical implementation of Embedded Programming

The embedded software in our designs typically runs on a CPU that manages the overall system while specialized hardware handles computation-intensive tasks. We tend to think of it as ‘having specialists for complex work and a manager to coordinate their efforts’.

In most FPGA implementations, we integrate the CPU directly into the FPGA logic using existing processor IP cores. This is often more practical than having a separate CPU chip on the PCB. For projects requiring only one CPU, standard PCBs are available. If a project requires multiple CPUs – like our work with Google where we needed at least 3, potentially 10 processors – we integrate them all within the FPGA rather than developing custom PCBs, which would be significantly more expensive and complex.

Real-World Application: Precision Flow Measurement

A recent project demonstrates our embedded programming approach perfectly. We developed a system for ultra-precise flow meters that measure gas or liquid flow through specialized sensors using crystalline components and electrical measurements. The raw sensor data requires intensive processing that would overwhelm a standard CPU.

Our solution: custom hardware handles the complex calculations for maximum speed and precision, while embedded software on an integrated CPU manages:

  • Initiating measurements
  • Coordinating calculation sequences
  • Managing sensor operations
  • Packaging and transmitting results to connected systems

This division of labor, specialized hardware for performance-critical computation and flexible software for system coordination, is a great example of why our integrated approach delivers superior results.

What makes QBayLogic unique?

At QBayLogic, we’ve developed technology, skills and knowledge that allow us to go directly from software concepts to hardware implementation without intermediate steps. We’re unique in our fundamental approach: starting with a software programming language (Haskell) and compiling this directly to hardware.

Our Clash compiler and our software-based methodology represent a fundamentally different way of thinking about hardware design. One that brings the power of modern software engineering practices to hardware development.

This approach, combined with automatic code generation for embedded software, means fewer errors, faster iteration, and the ability to tackle projects that would be impractical or impossible using traditional methods.

Would you like to share this article?