We're hiring!

We're actively seeking developers and designers for our Detroit & Ann Arbor locations.

How to Write Good Requirements

Requirements are pretty ubiquitous in the embedded world. They are used to define tasks, help coordinate large development efforts, and to communicate the behavior of the desired end product between the developers and the customer. When done right, requirements can be very useful. Unfortunately, if you spend much time working in the embedded world you quickly discover that there are a lot of bad requirements. And then when you try to go fix them, you quickly discover that writing good requirements is hard. Here are some tips that will hopefully make the process more clear:

At a high level, the purpose of requirements is to provide a useful description of the desired behavior of a blackbox system that is detailed enough that:

  • An engineer can make an implementation of said system.
  • A tester could verify that a given device satisfies the requirements (without talking to the engineer)
  • The resulting system satisfies the desires of the end user.


Writing good requirements:


The basic rule of thumb is this: Requirements should be the simplest, most understandable description of a system that constrains the system to the intended behavior. If you aim for this, the rest of the important stuff (testability, avoiding internal detail, etc…) tends to fall into place by itself.

Often it’s helpful to have some more granular guidelines to go by. Here are a few steps to writing good requirements:

  1. Define the boundaries of the system. Where are you going to draw the blackbox
  2. Define the inputs and outputs. These should be your only view into the internals of the system.
  3. Write down an easy to understand description of the desired behavior of the system.
  4. Does your requirement reference a part of the system besides the input and output? If so, your requirement has unnecessarily detail. Refactor and simplify.
  5. Is your requirement too ambiguous? Add more specifics. Note: Some ambiguity is a good thing, as long as all the potential interpretations are still within the set of acceptable behaviors and you don’t need any additional information to test the requirement, then you’re good. You don’t need to (and you shouldn’t try to) fully constrain the behavior of the system.
  6. Is your requirement testable? (blackbox testable) If not, you most likely messed up step 4. If this is happening a lot you might have defined the box around your system poorly or you might need better tools for testing. In either case an untestable requirement is nearly worthless.
  7. Is your requirement easy to understand? If your requirements are hard to understand then you are doing it wrong and you’ll just cause pain to everyone who uses the requirement down the road. Go back to step 3
  8. Are you sure you didn’t violate rule 4? Are you SURE? Go make sure.


Example:


As an example, lets write requirements for a contrived embedded device that blinks an LED at different rates depending on a reading from a flex sensor.

Hey look! We’ve already done step 2 and 3!

  •  Input: Reading from flex sensor
  •  Output: LED

But we’ve skipped step 1:

  • For our example we are going to draw our blackbox around the microprocessor on the device.

Lets move on,

Step 4: Do we reference a part of the system besides the input and output?

  • The microprocessor doesn’t really care that we’re reading from a flex sensor, from it’s perspective we will be measuring the voltage on an ADC pin.
  • And the LED will just be controlled by digital output pin.

So lets fix that:

Requirement Version 0:

  1. The device shall toggle a digital output pin at different rates depending on the voltage at an ADC pin.

 

Step 5: Is the requirement too ambiguous?
Hmmm, our description is quite ambiguous. How fast should the output be toggle? How does it relate to the voltage? What are the expected ranges of input voltage? Lets add some detail:

Version 0.1:

  1. The digital output pin shall be controlled by a free running timer
  2. The free running timer shall tigger at a maximum rate of 10 times a second and a minimum rate of once per second.
  3. The trigger rate of the free running timer shall vary linearly between the minimum and maximum rate, directly proportional to the input voltage on the ADC pin
  4. The input voltage on the ADC pin shall be read once every 100 milliseconds.
  5. When the input voltage on the ADC pin is read the register value controlling the free running timer cycle time will be updated.
  6. The valid range of input voltage on the ADC pin shall be between 0 an 1 volts

Step 6: Is your requirement testable?

  • First of all, the free running timer doesn’t need to be mentioned here at all. It’s probably impossible to black box test, it is neither an input, or an output, and does a poor job of relating the two.
    Lets use “The digital output pin shall be toggled at maximum rate of 10 times a second and a minimum rate of once per second.” instead.
  • It might be tricky to test #4, lets use “The input voltage on the ADC pin shall be read at least once every 100 milliseconds” as it’s more obviously what the intended behavior is and what we’d need to test.
  • #5 is also tricky. How do we check that the valid range is only between 0 and 1 volts? Give it 2 volts and see if it blows up?
    How about: “The system shall accept the range of input voltages on the ADC pin be between 0 an 1 volts”. This is much easier test. Requirements should be positive. They should describe how the device should behave, not how the device shouldn’t behave, otherwise testing becomes impossible.

Version 0.2:

1. The digital output pin shall be toggled at maximum rate of 10 times a second and a minimum rate of once per second.
2. The toggle rate of the digital output pin shall vary linearly between the minimum and maximum rate, directly proportional to the input voltage on the ADC pin
3. The input voltage on the ADC pin shall be read at least once every 100 milliseconds.
4. The system shall accept the range of input voltages on the ADC pin between 0 an 1 volts

Step 7: Is your requirement easy to understand?
These requirements are much harder to read and comprehend than our original “blinks an LED at different rates depending on a reading from a flex sensor

The easiest way I’ve found to make requirements more readable is to break the finer details out into terms and then define them separately:

Version 1:

  1. The flex-sensor shall be read at least once every 100 milliseconds (see comments)
  2. LED-state shall toggle at a rate linearly proportional to the flex-sensor reading
  3. The number of LED-state toggles shall average 10 timers per second when the flex-sensor reading is 1 volt, and 1 toggle per second when the flex-sensor reading is 0 volts.

Definitions:

  • flex-sensor : The input voltage on ADC pin X. Voltages between 0 and 1 volts, shall be accepted.(see comments)
  • LED-state : The state of digital output pin Y

 

These are much better (though not perfect). They are easy to read. They don’t specify any internals of the system. They are easy to test. They constrain the behavior of the system to what is desired, but not much further. (For example, the implementer is free to sample the flex sensor at a faster rate, and this is OK since it won’t cause undesired behavior).

Requirements are kinda like software for the human brain. Try to make them easy to execute.

Job Vranish (26 Posts)

This entry was posted in Embedded Systems and tagged , . Bookmark the permalink. Both comments and trackbacks are currently closed.

10 Comments

  1. Bryan Ash
    Posted February 14, 2012 at 9:20 pm

    Thank you for this article, it’s a good introduction.

    You stated a problem with #4 of Version 0.2 that still exists in the first requirement of the Version 1. Input requirements are always a red flag for me. A handy trick is to keep asking “why” until you get to the real requirement.

    I this case, what you’re trying to specify is the rate at which the output frequency can change.

    • Job Vranish
      Posted February 14, 2012 at 10:15 pm

      I think you’re right. I shouldn’t have the “Voltages between 0 and 1 volts, shall be accepted.” it’s redundant. #3 covers in the final version covers it just fine.

  2. Posted February 14, 2012 at 9:48 pm

    Very nice article, I agree with every step, I only would add a step that should be done bettewen steps: check the purpose of the requirement around the goal of the system and weight against others, as Bryan stated, the why is really what gives shape to the requirements.

    The requirements should be tied in their description to their purpose and burden on the system and some kind of weight. As you say in the embedded world difficulty and burden of requirements vary as the project matures and is way too common to drop/change requirements in order to best match the system against the goal of the project.

    It’s not uncommon to see requirement changes as the team and customer understand more of the why of them or the project.

    • Job Vranish
      Posted February 14, 2012 at 10:33 pm

      “It’s not uncommon to see requirement changes” – So unbelievably true.

      I’ve seen a lot of teams charge ahead under the implied assumption that requirements are not going to change much. So they’ll do things like make really long manual tests instead of automated ones since “We’re only going to have to test it a few times, and the manual test will take less time than developing the automated test”. Naturally this is disastrous.

      I’m glad that at least some people are planning ahead a little.

  3. Posted February 15, 2012 at 6:06 am

    Requirements are really really hard to get right

    “The flex-sensor shall be read at least once every 100 milliseconds” – what happens if it is *not* read ?

    • Job Vranish
      Posted February 15, 2012 at 11:20 am

      I think you could just say that the device fails to meet the requirements.

      Though, the more that I think about it, I think that #1 is adequately covered by #3. I should get rid of it.

      • Posted February 15, 2012 at 3:19 pm

        What happens on system failures?, how are they captured and what kind of mechanisms do they trigger?, most embedded systems tend to work/fail silently as output is always limited, but system inspection, error reporting and status assessment should be considered when planning reqs as well, if not a set of reqs themselves.

        Phil’s question about your example is an excellent example on the dependency on how hard is the realtime requeriment, other tasks and what should be done when not met.

        It’s charming how a badly written requirement can ruin your life for weeks, when the task was assigned the wrong realtime priority

  4. Karl
    Posted February 17, 2012 at 10:07 am

    Great write-up! Question for you though; where in the process do you address the ‘why?’ of the requirement?
    “Lets write requirements for a contrived embedded device that blinks an LED at different rates depending on a reading from a flex sensor.”
    Great! We go through and create a couple versions of the requirement, show it to the client and they approve saying ‘Yes, exactly what I asked for!’, then we go off and build it, test it, and deliver it. Then the customer comes back and tells you that it doesn’t do what they want it to do. You finally ask ‘why?’, and they tell you that when they try to take a temperature reading with the device, the blinking speed doesn’t change. You then say ‘uh… flex sensors don’t measure temperature, they measure… flex…’.
    I bring this up only because I’ve been burned a few times by not asking ‘why’ and ultimately not understanding the true intentions of the request. Then delivering exactly what was asked for, but nothing of what was wanted. By asking ‘why?’, you can also then suggest alternatives if you know of something better than what was asked for. Though be careful who you press with ‘why?’, as some can take it as a challenge rather than a request for understanding. I think having an answer to ‘why?’ for each of your requirements is vital, and informs all subsequent tasks.

    • Job Vranish
      Posted February 17, 2012 at 11:08 am

      Yes, this a very important point. I tried to keep my post down to a reasonable size and so only focused on the writing of the requirement itself, but I originally had a whole section on this. Understanding the end users needs wants is critical. And the value of getting early mockups/prototypes to the end user still huge even in the embedded world. This can be very hard though because the end user is often not the customer. I’ve found that a lot of companies play a sad game of telephone with the requirements.
      Common pattern:
      User communicates desire with company X
      company X hires company Y make something
      Y builds what X wanted
      X gives thing to user
      user doesn’t like feature A says it should be more like B
      X gets mad at Y, tells them feature A must be like C
      months later Y finishes making A like C
      X gives to user
      user doesn’t like feature A says it should be more like B
      repeat until someone runs out of money….

      Closing this feedback loop and taking the time early on to truly understand the end users needs is probably the easiest and cheapest way to add value to product.

  5. Posted February 17, 2012 at 1:25 pm

    Requirements is a new area for me, but it is a fascinating topic. Great article.

2 Trackbacks

  1. [...] the tips How to write good requirments | Atomic Spin. [...]

  2. By How to write good requirments | Brent Sordyl's blog on February 21, 2012 at 1:13 pm

    [...] Story: How to write good requirments) Like this:LikeBe the first to like this post. requirements requirements Polyglot [...]