Product Development

Embedded Artistry's Technology Radar

I was introduced to the Technology Radar concept while at Bredemeyer Consulting's Software Architecture Workshop. The Technology Radar concept was created by ThoughtWorks, and they regularly publish updates to their own radar.

I immediately latched onto the concept as an effective way to track the technologies and techniques that we are investigating at Embedded Artistry. Our technology radar can also serve as a reference and source of inspiration for other embedded systems teams.

We’ve identified four categories that we plan to explore as an embedded systems consulting firm:

  1. Tools
  2. Libraries and Frameworks
  3. Platforms (both hardware and RTOS)
  4. Techniques

We've released the first-draft of our technology radar and will update it on an ongoing basis.

You can find our Technology Radar on the website under the Resources menu.

For more on technology radars:

Building a Team that Delivers Business Value

Today we have a guest post by Saket Vora about building a product development team aligned with your company's business value propositions.

Saket is a hardware product developer who has helped create iPods, iPhones, and Watch at Apple, and was a founding team member at Pearl Automation. You can contact him via email or on Twitter

Building a Team that Delivers Business Value

It’s hard to overstate the importance of team composition in a successful business. This is especially true for early stage companies that are trying to build their first product. The early team will define the company’s culture, create foundational processes & priorities around product development, and help attract additional talent & investment.

A beginning is the time for taking the most delicate care that the balances are correct.
~ Frank Herbert, Dune.

Early stage companies are laser focused on transforming their product from a concept to a shipping product as quickly as possible. Recruiting and hiring are focused directly on achieving that goal. However, it is essential to ensure that the team composition is aligned with the company’s business positioning. At the core of every company is the belief that it has a unique approach to a business problem, and so the company’s full-time core team should be a reflection of that particular approach.

Consider a young company in the IoT, robotics, or similar embedded systems-related space. Such startups commonly outsource functions like payroll, HR, and IT. While these roles are vital to running a business, they are not roles that directly contribute the company’s unique value proposition.

Leveraging external resources for such activities keeps the company’s headcount lean and reduces operating expenses. Most importantly, outsourcing enables increased agility with respect to changes in direction. When needs change, it is much easier for companies to scale up and down external resources than it is to hire and lay off employees.

If outsourcing works for payroll, HR, and IT, then we can apply the same mentality to product and engineering functions which do not directly contribute to our business’s value proposition.

What differentiates your product?

With limited resources in the form of team size, money, and brand awareness, trying to do many things at once results in doing nothing particularly well. It is critical to decide what your company should focus on, and thus tradeoffs must be evaluated. How do you intend for your product to be different than your competitors?

Is it through:

  • Hardware design or production quality?

  • Software features or user experience?

  • Marketing?

  • Distribution?

  • Pricing?

Of course, you may wish to differentiate in all these ways over the long term, but it is important to identify the main differentiating factor in the short term. Choosing your area of focus will constrain your options in other areas.

For example, Dropcam’s key advantage involved a superior user experience that was tied into a cloud-based service model. Their original hardware cameras were essentially commodity technology, which allowed them to get their hardware product to market faster and cheaper.    

The Pebble smart watch focused on their unique e-ink ‘always-on display’ that also enabled a long battery life. The tradeoffs for these features meant that they could not offer as rich a software feature set as other smartwatches with conventional LCD displays.

GoPro action cameras and Beats headphones emphasized high profile marketing & content to boost their brand identities & sales, rather than push the envelope in device performance.

Roku licensed their hardware reference designs to OEM TV manufacturers in addition to making their own streaming media sticks. While this enabled them to get their OS platform into wider distribution channels, their designs had to be very conscious of cost and compatibility.

The composition of your full-time employees, even in the early stages, should ideally reflect where your company’s strategic advantage aims to be.

NPI and On-Going Support are Different Disciplines

Creating a product for the first time, referred to as New Product Introduction (NPI), requires different skill-sets than sustaining or expanding an existing product line.  For example, contract manufacturers in Asia will often have completely different teams for the NPI phase and Production phase.

For engineers, the goal of the NPI phase is twofold:

  1. To get working prototypes functional as quickly as possible to unblock all other cross functional teams

  2. To build a platform that is production worthy.

To pursue this, you might quickly hire several engineers skilled at prototyping. They will likely hack together Arduinos, Raspberry PIs, or Particles, bring up an OS and write drivers, and fab out quick-turn circuit boards and 3D print enclosures. With the tools and services available today, teams can make incredibly quick progress towards delivering functional prototypes.

However, jump ahead in your mind to when the basic functional prototypes are ready.

The product team will be using them to get user feedback, refine the product experience, and inevitably start requesting new or changed features. If the product is tied to a smartphone app and/or cloud service, you’ll be defining how the different pieces of your product interface with each other -- not just to enable core features, but also around protocols, logging, analytics, device updates, and product health. Your team will need to support diagnostic and manufacturing needs, including first-time programming, provisioning, and preparing the devices for shipment. End-to-end security is required across all levels of the software stack. There will be regular new and urgent requests to support one-off product demos for investors, press, or partners.  And of course, supporting quality assurance testing & validation throughout the product development lifecycle.

The truth is that these tasks are of a different nature compared to early platform bringup. Technically, it involves higher level systems level architecture and understanding the needs of manufacturing, field testing, security, QA, etc. Culturally, it’s about grinding through long bug lists, dealing with constant change requests from all cross functional teams, chasing difficult to reproduce issues, and addressing edge cases. It’s during this phase of the development cycle that the overall product quality and customer experience comes to be defined.   

It’s extremely difficult to find embedded engineers who can easily run the gamut from early prototyping platforms to production-ready systems. It is common for even well connected, experienced technical recruiters to take six months or more to fill an embedded position.

If you want to keep a lean full-time team, do you hire the early stage prototypers to get going quickly and trust they’ll figure out the rest? Or do you spent months hunting for the unicorn engineers who you know will be able to deliver everything?

Aligning Your Core Team to Deliver Your Business Value

When building your company’s early core team, focus on what you believe is your company’s key strategic advantages -- then leverage outside services and resources for the rest.

Think carefully before pursuing that ‘full stack company’ org chart or insisting that the entire product needs to be done in house.

Engineering design firms can cover a range of industrial design, mechanical, electrical, firmware, and even manufacturing needs. Software consultants with expertise in platform bringup, sensors, wireless connectivity, and security can help fill in gaps in your team’s skillsets without burdening headcount with narrowly-focused experts. You could hire a full-time WiFi expert to enable your product’s wireless connectivity, but what will that person do when that task is complete? When done right, it can be faster & cheaper to bring your product to market if you leverage outside resources for tasks that are not central to your long-term business strategy.

Valuable core roles to fill are the connectors -- the systems-savvy engineers who know how to interface between the device, app, cloud, manufacturing, and business layers of the product. These are the people who drive the architecture, implement the top level features that differentiate your company, and execute the business logic. With their holistic understanding of how your product comes together, they also should be able to identify the most optimal way to leverage external resources. For these reasons, connectors are more valuable to early stage companies than the experts.

Investors, founders, and industry veterans all acknowledge how important the people are to a company, especially the company’s early core team. Building a team that is closely aligned to what makes your company unique -- and being smart about leveraging outside resources for the rest -- will give your company the best chance to succeed.

 

Related Posts

Musings on Tight Coupling Between Firmware and Hardware

Firmware applications are often tightly coupled to their underlying hardware and RTOS. There is a real cost associated with this tight coupling, especially in today's increasingly agile world with its increasingly volatile electronics market.

I've been musing about the sources of coupling between firmware and the underlying platform. As an industry, we must focus on creating abstractions in these areas to reduce the cost of change.

Let's start the discussion with a story.

Table of Contents

  1. The Hardware Startup Phone Call
  2. Coupling Between Firmware and Hardware
    1. Processor Dependencies
    2. Platform Dependencies
    3. Component Dependencies
    4. RTOS Dependencies
  3. Why Should I Care?

The Hardware Startup Phone Call

I'm frequently contacted by companies that need help porting their firmware from one platform to another. These companies are often on tight schedules with a looming development build, production run, or customer release. Their stories follow a pattern:

  1. We built our first version of software on platform X using the vendor SDK and vendor-recommended RTOS
  2. We need to switch to platform Y because:
    1. X is reaching end of life
    2. We cannot buy X in sufficient quantities because Big Company bought the remaining stock
    3. Y is cheaper
    4. Y's processor provides better functionality / power profile / peripherals / GPIO availability
    5. Y's components are better for our application's use case
  3. Platform Y is based on a different processor vendor (i.e. SDK) and/or RTOS
  4. Our engineer is not familiar with Platform Y's processor/components/SDK/RTOS
  5. The icing on the cake: We need to have our software working on Platform Y within 30-60 days

After hearing the details of the project, I ask my first question, which is always greeted with the same answer:

Phillip: Did you create abstractions to keep your code isolated from the vendor SDK or RTOS?

Company: No. We're a startup and we were focused on moving as quickly as possible

I'll then ask my second question, which is always greeted with the same answer:

Phillip: Do you have a set of unit/functional tests that I can run to make sure the software is working correctly after the port?

Company: No. We're a startup and we were focused on moving as quickly as possible

Then I'll ask the final question, which is always greeted with the same answer:

Phillip: How can I tell whether or not the software is working correctly after I port it?

Company: We'll just try it out and make sure everything works

Given these answers, there's practically no chance I can help the company and meet their deadlines. If there are large differences in SDKs and RTOS interfaces, the software has to be rewritten from scratch using the old code base as a reference.

I also know that if I take on the project, I'm in for a risky business arrangement. How can I be sure that my port was successful? How can I defend myself from the client's claim that I introduced issues without having a testable code base to compare against?

Why am I telling you this story?

Because this scenario arises from a single strategic failure: failure to decouple the firmware application from the underlying RTOS, vendor SDK, or hardware. And as an industry we are continually repeating this strategic failure in the name of "agility" and "time to market".

These companies fail to move quickly in the end, since the consequences of this strategic blunder are extreme: schedule delays, lost work, reduced morale, and increased expenditures.

Coupling Between Firmware and Hardware

Software industry leaders have been writing about the dangers of tight coupling since the 1960s, so I'm not going to rehash coupling in detail. If you're unfamiliar with the concept, here is some introductory reading:

In Why Coupling is Always Bad, Vidar Hokstad brings up consequences of tight coupling, two of which are relevant for this musing:

  • Changing requirements that affect the suitability of some component will potentially require wide ranging changes in order to accommodate a more suitable replacement component.
  • More thought need to go into choices at the beginning of the lifetime of a software system in order to attempt to predict the long term requirements of the system because changes are more expensive.

We see these two points play out in the scenario above.

If your software is tightly coupled to the underlying platform, changing a single component of the system - such as the processor - can cause your company to effectively start over with firmware development.

The need to swap components late in the program (and the resulting need to start over with software) is a failure to perform the up-front long-term thinking required by tightly coupled systems. Otherwise, the correct components would have been selected during the first design interation, rendering the porting process unnecessary.

Let's review on a quote from Quality Code is Loosely Coupled:

Loose coupling is about making external calls indirectly through abstractions such as abstract classes or interfaces. This allows the code to run without having to have the real dependency present, making it more testable and more modular.

Decoupling our firmware from the underlying hardware is As Simple As That™.

Up front planning and design is usually minimized to keep a company "agile". However, without abstractions that easily enable us to swap out components, our platform becomes tied to the initial hardware selection.

You may argue that taking the time to design and implement abstractions for your platform introduces an unnecessary schedule delay. How does that time savings stack up against the delay caused by the need to rewrite your software?

We all want to be "agile", and abstractions help us achieve agility.

What is more agile than the ability to swap out components without needing to rewrite large portions of your system? You can try more designs at a faster pace when you don't need to rewrite the majority of your software to support a new piece of hardware.

Your abstractions don't need to be perfect. They don't need to be reusable on other systems. But they need to exist if you want to move quickly.

We need to start producing abstractions that minimize the four sources of tight coupling in our embedded systems:

  1. Processor Dependencies
  2. Platform Dependencies
  3. Component Dependencies
  4. RTOS Dependencies

Processor Dependencies

Processor dependencies are the most common form of coupling and arise from two major sources:

  1. Using processor vendor SDKs
  2. Using APIs or libraries which are coupled to a target architecture (e.g. CMSIS)

Processor-level function calls are commonly intermixed with application logic and driver code, ensuring that the software becomes tightly coupled to the processor. De-coupling firmware from the underlying processor is one of the most important for design portability and reusability.

In the most common cases, teams will develop software using a vendor's SDK without an intermediary abstraction layer. When the team is required to migrate to another processor or vendor, the coupling to a specific vendor's SDK often triggers a rewrite of the majority of the system. At this point, many teams realize the need for abstraction layers and begin to implement them.

In other cases, software becomes dependent upon the underlying architecture. Your embedded software may work on an ARM system, but not be readily portable to PIC, MIPS, AVR, or x86 machine. This is common when utilizing libraries such as CMSIS, which provides an abstraction layer for ARM Cortex-M processors.

A more subtle form of architecture coupling can occur even when abstraction layers are used. Teams can create abstractions which depend on a specific feature, an operating model particular to a single vendor, or an architecture-specific interaction. This form of coupling is less costly, as the changes are at least isolated to specific areas. Interfaces may need to be updated and additional files may need to change, but at least we don't need to rewrite everything.

Platform Dependencies

Embedded software is often written specifically for the underlying hardware platform. Rather than abstracting platform-specific functionality, embedded software often interacts directly with the hardware.

Without being aware of it, we develop our software based on the assumptions about our underlying hardware. We write our code to work with four sensors, and then in the second version we only need two sensors. However, you need to support both version one and version two of the product with a single firmware image.

Consider another common case, where our software supports multiple versions of a PCB. Whenever a new PCB revision is released, the software logic must be updated to support the changes. Supporting multiple revisions often leads to #ifdefs and conditional logic statements scattered throughout the codebase. What happens when you move to a different platform, with different revision numbers? Wouldn't it be easier if your board revision decisions were contained in a single location?

When these changes come, how much of your code needs to be updated? Do you need to add #ifdef statements everywhere? Do your developers cringe and protest because of the required effort? Or do they smile and nod because it will only take them 15 minutes?

We can abstract our platform/hardware functionality behind an interface (commonly called a Board Support Package). What features is the hardware platform actually providing to the software layer? What might need to change in the future, and how can we isolate the rest of the system from those changes?

Multiple platforms & boards can be created that provide same set of functionality and responsibilities in different ways. If our software is built upon a platform abstraction, we can move between supported platforms with greater ease.

Component Dependencies

Component Dependencies are a specialization of the platform dependency, where software relies on the presence of a specific hardware component instance.

In embedded systems, software is often written to use specific driver implementations rather than generalized interfaces. This means that instead of using a generalized accelerometer interface, software typically works directly with a BMA280 driver or LIS3DH driver. Whenever the component changes, code interacting with the driver must be updated to use the new part. Similar to the board revision case, we will probably find that #ifdefs or conditionals are added to select the proper driver for the proper board revision.

Higher-level software can be decoupled from component dependencies by working with generic interfaces rather than specific drivers. If you use generic interfaces, underlying components can be swapped out without the higher-level software being aware of the change. Whenever parts need to be changed, your change will be isolated to the driver the declaration (ideally found within your platform abstraction).

RTOS Dependencies

An RTOS's functions are commonly used directly by embedded software. When a processor change occurs, the team may find that the RTOS they were previously using is not supported on the new processor.

Migrating from one RTOS to another requires a painful porting process, as there are rarely straightforward mappings between the functionality and usage of two different RTOSes.

Providing an RTOS abstraction allows platforms to use any RTOS that they choose without coupling their application software to the RTOS implementation.

Abstracting the RTOS APIs also allows for host-machine simulation, since you can provide a pthreads implementation for the RTOS abstraction.

Why Should I Care?

It's a fair question. Tight coupling in firmware has been the status quo for a long time. You may claim it still must remain that way due to resource constraints.

Vendor SDKs are readily available. You can start developing your platform immediately. The rapid early progress feels good. Perhaps you picked all the right parts, and the reduced time-to-market will actually happen for your team.

If not, you will find yourself repeating the cycle and calling us for help.

It's not all doom and gloom, however. There are great benefits from reducing coupling and introducing abstractions.

  • We can rapidly prototype hardware without triggering software rewrites
  • We can take better advantage of unit tests, which are often skipped on embedded projects due to hardware dependencies
  • We can implement the abstractions on our host machines, enabling developers to write and test software on their PC before porting it to the embedded system
  • We can reuse subsystems, drivers, and embedded system applications on across an entire product line

I'll be diving deeper into some of these beneficial areas in the coming months.

In the mean time - happy hacking! (and get to those abstractions!)

Related Posts