tag:blogger.com,1999:blog-241728832024-03-07T09:48:38.517+01:00Timo's weblogAnatomy of One Agile Development ExperienceUnknownnoreply@blogger.comBlogger135125tag:blogger.com,1999:blog-24172883.post-8448664545631442792015-03-05T14:21:00.000+01:002015-03-05T14:21:44.617+01:00Agile Hardware - Support from a Surprising Source<div dir="ltr" style="text-align: left;" trbidi="on">
<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--><br />
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:TrackMoves/>
<w:TrackFormatting/>
<w:PunctuationKerning/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:DontVertAlignCellWithSp/>
<w:DontBreakConstrainedForcedTables/>
<w:DontVertAlignInTxbx/>
<w:Word11KerningPairs/>
<w:CachedColBalance/>
<w:UseFELayout/>
</w:Compatibility>
<w:DoNotOptimizeForBrowser/>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="--"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
DefSemiHidden="true" DefQFormat="false" DefPriority="99"
LatentStyleCount="267">
<w:LsdException Locked="false" Priority="0" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" Priority="39" Name="toc 1"/>
<w:LsdException Locked="false" Priority="39" Name="toc 2"/>
<w:LsdException Locked="false" Priority="39" Name="toc 3"/>
<w:LsdException Locked="false" Priority="39" Name="toc 4"/>
<w:LsdException Locked="false" Priority="39" Name="toc 5"/>
<w:LsdException Locked="false" Priority="39" Name="toc 6"/>
<w:LsdException Locked="false" Priority="39" Name="toc 7"/>
<w:LsdException Locked="false" Priority="39" Name="toc 8"/>
<w:LsdException Locked="false" Priority="39" Name="toc 9"/>
<w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/>
<w:LsdException Locked="false" Priority="10" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" Priority="11" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" Priority="22" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" Priority="20" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" Priority="59" SemiHidden="false"
UnhideWhenUsed="false" Name="Table Grid"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/>
</w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:"Cambria","serif";
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:minor-latin;}
</style>
<![endif]--><i style="mso-bidi-font-style: normal;">“Agile development may
be suitable for software development, but for hardware development we have to
use something more formalized and waterfall just works for this”. </i>
<br />
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Some time ago I stumbled across the above comment. I can’t
disagree more. </div>
<div class="MsoNormal">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTTacCQ9a6BeXhPZ7Lx8oeh7nPqphjobr48WhSjBfk6AijuqPIIGsMZHK8WpPZOneRzRzkHN6BxLH_MzyQeMVoi7eNlC4-ab1CIG2994YmU02zwkXvwbERhFcoO-InDtHbMGe0/s1600/mainboard-851167-m.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTTacCQ9a6BeXhPZ7Lx8oeh7nPqphjobr48WhSjBfk6AijuqPIIGsMZHK8WpPZOneRzRzkHN6BxLH_MzyQeMVoi7eNlC4-ab1CIG2994YmU02zwkXvwbERhFcoO-InDtHbMGe0/s1600/mainboard-851167-m.jpg" height="132" width="200" /></a></div>
<div class="MsoNormal">
I have electrical engineering background and for two decades
I have been involved with embedded systems development. I have never seen a
specification being complete nor frozen before the design for electronics. To me
that’s completely irrational idea. Further, I have yet to witness a project during
which changes, and/or discovery, did not affect the pcb and mechanical co-design.
Fast-paced iterative process models fit the challenge much better than up-front
plan-driven. I have been lucky to work for more than a decade with people who think the
same (at least on this topic).</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Software development domain faced the same challenge and answered with Agile software development. But based on my own observation, product
development is very similar ball game – despite the engineering discipline. Yet,
in hardware development domain it is still not so rare to hear comments like
above and for some reason waterfall mindset prevails.<span style="mso-spacerun: yes;"> </span>This leads us to the main point of this post. Actually flexible hardware development is supported by a very
surprising source; the authors that are cited to “demand the waterfall process
model”!</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
To begin with, of course we, members of agile community,
know that the original "waterfall paper" by Winston Royce actually argued against
using waterfall approach (<a href="http://pragtob.wordpress.com/2012/03/02/why-waterfall-was-a-big-misunderstanding-from-the-beginning-reading-the-original-paper/" target="_blank">link</a>).</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Second, the N&N paper, which inspired Scrum framework
for software development, did not talk about software development. The case
projects developed copiers, cameras and cars. And this was decades ago, when
these products were not that software intensive either (<a href="https://hbr.org/1986/01/the-new-new-product-development-game/ar/1" target="_blank">link</a>). </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Further, PMI’s PMBOK is not that exclusive either. It
presents the waterfall approach, but only as one alternative process model. As
equally considerable alternatives the guide presents models with overlapping
phases and iterative approach.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Finally, Stage-Gate process model introduced to us by Robert
Cooper has gone through several generations since its first introduction in 1986
and has continuously moved towards recommending the fast paced iterative
development. However, the very first edition already recommended iterative,
collaborative approach; </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<i style="mso-bidi-font-style: normal;">“…parallel marketing
and operations activities are also undertaken. For example, market-analysis and
customer-feedback work continue concurrently with the technical development,
with customer opinion sought on the product as it takes shape during
development. These activities are back-and-forth or iterative, with each
development result – for example, rapid prototype, working model, or first
prototype – taken to the customer for assessment and feedback</i>”.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
After this brief review, I summarize the situation to be
exactly like the case with misunderstanding of Winston Royce’s paper but on a
larger scale. People read the material to find what they want to find. Beauty
is in the eye of the beholder. Or they skip reading altogether, and just go
with their hard-wired mental model. As an example, several years ago I had a
presentation with quotes from a process manual of a very large enterprise. The
quotes were 100% supportive to agile development. I presented this to a room
full of project managers and PMO directors. I asked if they knew from where the
quotes were. None was able to answer. I asked who had read the complete process
manual, their own by the way. None had. Despite this, they were very consistent
in arguing that the very manual “demanded waterfall”. </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
This would be funny, if only it wasn’t true.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Incremental and iterative models are recommended for
hardware development in the literature. For some reason, the adaptation rate
seems much higher in software development domain. I think it is worth checking
what actually made agile software development methods so popular in the
industry and is there something to be learned for the system development
domain. Yes, software development has certain characteristics increasing the
flexibility, but my belief is that this is not the whole picture. Further, in
systems development the product development challenges are shared between the
engineering disciplines and it would be beneficial to have a shared approach
to development.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Luckily, there’s been signs of more and more people getting
interested in transforming the agile development knowledge from software
development domain to system development domain (containing for example
electronics and mechanical engineering), f.ex (<a href="http://www.eetimes.com/document.asp?doc_id=1279137" target="_blank">link</a>)</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Knowledge about iterative hardware development exists, but
learning together between the domains can’t hurt anyone. Agile Alliance has
just recently initiated a program for Agile Engineering aiming at this (<a href="http://www.agilealliance.org/programs/agile-engineering-program/" target="_blank">link</a>)</div>
<div class="MsoNormal">
<br /></div>
</div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-24172883.post-77637768715407585042013-12-05T14:46:00.000+01:002014-02-04T06:27:35.581+01:00Scaling the Product Owner Role<div dir="ltr" style="text-align: left;" trbidi="on">
At <a href="http://www.xpday.net/Xpday2013/XPDays/Program.html">XP Days Benelux 2013</a> we talked about why and how the Product Owner role is scaled in organizations. You can find my slides <a href="http://www.ngware.eu/blog/papers/xp_days_benelux_2013_punkka.pdf">here</a> (pdf).<br />
<em> </em><br />
[EDIT 1.2.2014]<br />
InfoQ Interview on the topic can be found <a href="http://www.infoq.com/news/2013/11/scale-product-owner-xpdays">here</a>.<br />
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<strong><em>Abstract</em></strong></div>
<div style="text-align: justify;">
<strong><em></em></strong> </div>
<div style="text-align: justify;">
<em>Come to this workshop to learn how to scale the Product Owner role in order to harness the true potential of self-organizing Agile teams. You will learn by doing, but you will be also hear a real-life story.</em></div>
<div style="text-align: justify;">
<em></em> </div>
<div style="text-align: justify;">
<em>Using Agile development methods development teams improve their capability to deliver through transparency and predictability. However, this does not bring the outcome companies are seeking if the developed features are not the right ones. The product owner role in Scrum simplifies the interface between business and development. This obviously brings immediate relief in many cases, but in practice, the responsibility of the Product Owner is far too wide for a single person in all except the most simplistic scenarios. Naturally the pragmatic Product Owner works with number of domain experts and other stakeholders. Things in real-life get even more complicated, as organizations have multiple product lines, yet the development should be aligned with the company’s strategy. To add to the challenge, for example embedded system development including own hardware platform development brings additional concerns, such as less flexibility than software development and dependency on external suppliers. To date, the practical information on how to do this remains limited.</em></div>
<div style="text-align: justify;">
<em></em> </div>
<div style="text-align: justify;">
<em>During this workshop you will will create a framework for scaling the Product Owner role. Continuous customer collaboration at different levels, with different focus, will also be covered. Your work will be guided with a real-life story linking the exercise to reality.</em></div>
</div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-24172883.post-29323699668008691532013-10-11T05:40:00.000+02:002013-10-11T05:40:08.218+02:00My Hardware and Co-Design talk at Scrum Gathering<br />
Couple of weeks ago I attended my first Scrum Gathering in the city of light, Paris. On the first day I was offered an opportunity to present my Hardware and Co-Design talk. You can find the abstract below, and slides are available <a href="http://www.ngware.eu/blog/papers/Scrum_for_Hardware_And_Codesign_2013_Punkka.pdf">here.</a><br />
<br />
<h4>
Summary</h4>
Agile methods are gaining foothold in embedded software development. Embedded software is not developed in isolation, but it has dependencies to hardware development. The system development is facing the demands of ever increasing amount of change and learning. Agile methods aim at helping in these challenges. This talk summarizes authors observations on hardware development teams using Scrum during the past 10 years. Teams have varied in terms of disciplines involved and collocation.<br />
<br />
Come to this session to get the practitioner’s view on using Scrum beyond embedded software development.<br />
<br />
<h4>
Description </h4>
<br />
Agile software development is getting more and more attention also in embedded software development. Embedded system development on the other hand requires different engineering disciplines working together towards a shared goal. When embedded software development begins using agile methods it triggers a need for change also in other disciplines. Agile development emphasizes continuous learning through experimenting and collaboration instead of following a detailed up-front plan. Agile embedded software team expects different behavior in system co-design.<br />
<br />
In addition to the above, product development in general and not only software development is facing the demands of ever increasing amount of change and learning. Change happens in several areas, such as technology, competition and marketplace. This is what agile methods aim at tackling. This implies that new product development in general could benefit from knowledge created on agile development.<br />
<br />
This presentation summarizes authors observations on hardware development team members and hardware teams using Scrum and agile methods during the past 10 years. Team configurations range from collocated cross-disciplined team (electronics, printed circuit board, mechanics and embedded software) to globally distributed teams of different disciplines. Several real-life products will be used as examples. <br />
<br />Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-24172883.post-83500077405017942642012-10-08T18:24:00.000+02:002012-10-08T18:24:47.834+02:00Invasion of Agile Hardware at Design East, BostonTopics around Agile Development have slowly but steadily been making their way into Embedded Systems Conference program. Couple of weeks ago <a href="http://east.ubmdesign.com/conference/esc-boston/">Design East in Boston</a> had several sessions on Agile Development, but most noticeably 3 talks on Agile Hardware. One of them by yours truly. You can find the slides and technical paper associated with it via these links (<a href="http://www.ngware.eu/blog/papers/ESC-3008Slides_Punkka.pdf">slides</a>, <a href="http://www.ngware.eu/blog/papers/ESC-3008Paper_Punkka.pdf">technical paper</a>).<br />
<br />
<blockquote class="tr_bq">
<br />
<i>Agile methods are gaining foothold in embedded software development.
Embedded software is not developed in isolation, but it often has strong
dependencies to hardware development. The system development is facing
the demands of ever increasing amount of change and learning. Agile methods
aim at helping in these challenges. This session summarizes authors
observations on hardware development team members and hardware teams
working with Agile methods during the past 10 years. Team configurations
range from collocated cross-disciplined team (electronics, printed
circuit board, mechanics and embedded software) to globally distributed
teams of different disciplines. This session will give you the
practitioner’s view to applicability of Agile methods beyond embedded
software development.</i></blockquote>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-24172883.post-42172343284159608022011-12-28T18:14:00.000+01:002011-12-28T19:15:59.786+01:00TDD and design<div><div><br /></div><div><div>Earlier I wrote about the long distance I went with mac driver design (<a href="http://ng-embedded.blogspot.com/2010/08/fiddling-around-before-tdd.html">link</a>). The current design is sketched below with examples of functions, and responsibilities (green). The clouds are C files. The design has 95% unit test line coverage. Tests have proven their power. I refactored the code using a local repository while traveling on vacation on remote island (during off-days from diving) and obviously no access to real target for testing. I made 53 commits. My commit frequency is very high, so many of the refactorings were just renaming and extracting helpers, but there were also more fundamental design changes. When I finaly, and sadly, made it back to the lab, I was kind of afraid that the code won't run and the fastest thing to do is to throw away all the refactorings. The next fastest thing would be to repeat them one by one in real repository. I gotta say I was surprised when the code worked right out the cross-compiler and all I needed to do was one massive merge from local to real repository. This is very rewarding. During the refactoring there was a handfull of incidents when tests caught a stupid mistake made by me. This is worthy even if you had the access to real target. The nice thing is that unit tests on dev environment tell it right away.</div><div>There is no need to make tradeoffs and large/long changes without feedback because of lengthy burning times, or lengthty stepping path to debug newly written code.</div></div><div><br /></div><div><br /></div><div><br /></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNf_UOxfFyXwt1TGZT7-ZF4cC2tEFn-mIOESyztC91Sb7BJTRUGAseX1qfC5RbkBZgsr6CDarAfrmjn6a2NmHaONittXU7AiXwvcyZIh5DHAlHlzKMHUBpqAZqWP2d4ArBxHTQ/s1600/mac+driver+design.png"><img style="margin: 0px auto 10px; width: 320px; height: 269px; text-align: center; display: block; cursor: pointer;" id="BLOGGER_PHOTO_ID_5636710098640217938" border="0" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNf_UOxfFyXwt1TGZT7-ZF4cC2tEFn-mIOESyztC91Sb7BJTRUGAseX1qfC5RbkBZgsr6CDarAfrmjn6a2NmHaONittXU7AiXwvcyZIh5DHAlHlzKMHUBpqAZqWP2d4ArBxHTQ/s320/mac+driver+design.png" /></a><br /><div><br /></div><div><br /><div><div>But it wasn't the biggest learning. The biggest learning was that the design resulted quite the different from what one would expect. I base this claim to investigation of several example MAC driver source codes available in the internet. The design has proven to be good, in terms of testability (that was the driver) and adaptability (this was the proof). More about adaptability later below. The thing that differentiates this style of design is the emphasis it puts to testing. Design is good if it is easy to test. If the tests are complicated to understand or difficult to write all together, then there is a good chance that design has flauses.</div><div><br /></div><div>I think what I experienced is well explained by Michael Feathers in his talk "The Deep Synergy Between Testability and Good Design" (<a href="http://www.testingtv.com/2010/12/13/the-deep-synergy-between-testability-and-good-design/">video</a>). Take a look, and don't think this applies only to OO languages. You'd be wrong. The driver we are talking about here is written in C. </div><div><br /></div><div>Current design was tested when the hw team decided to have a second option for MAC driver. They wanted the final pcb so they could proceed with emission tests and we together did not have enough information to do the decision either way. The candidate for production pcb has routing for both options. One implementation of set based design. But back to the sw side of it...</div><div><br /></div><div>The concepts in driver design kept most of the files completely untouched. SPI and DMA drivers were independent compile units and they needed no touching. This also means that no code was duplicated in the production code mass. </div><div><br /></div><div>The original design was done with just testability in mind. At that time there was no knowledge about the extra hardware the design needs to comply with. </div><div><br /></div><div>In my opinion the code became adaptable and reusable by designing it for testability.</div><div><br /></div><div>I don't think writing code this way, by seprating concerns, focusing on single responsibility, and not mixing abstraction levels, is slower to write. Is it different? Oh yeah. You have to really develop a new sense for good coding. As a remark, which I did earlier, I wouldn't refactor the code after fiddling around, but write a decent design based on learning from exploring, aka spike.</div><div><br /></div><div>In the current MAC driver code one detailed design decision may make you raise your eye browse; Single function ClockByte() is in separate file. This is because I wanted to assert through just the bytes been send, not through processor register dummies. Other option would have been to inject a function pointer for this. I chose to use link time seam.</div><div><br /></div><div>On the other hand just few simple tests for basic correctness of ClockByte() function are enough. This can also been seen as principle of separation of concerns and keeping the files at the same level of abstraction.</div><div><br /></div><div>Current design is far away from being perfect. It is not what I think should be achieved. It continues to offer me opportunities for deeper understanding of tdd, and synergy between design and tests, more deeply. The next lesson will be available when it gets factored to enable irq based interfacing between uC and mac driver. So far it has been just message polling.</div></div><div><br /></div><div><br /></div><div></div></div></div>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-24172883.post-63781394756751548582011-09-10T07:05:00.008+02:002011-09-10T08:01:54.853+02:00Slides from Agile 2011Agile 2011 ended in Salt Lake City, Utah a few weeks ago. It was again great to meet the growing circle of friends in agile community. This year my own conference was a bit different as I submitted two talks and participated in the review process for Agile for Embedded Systems Development -track.<br /><br />Indeed, we had dedicated track for embedded stuff. It was the 10 year anniversary for agile manifesto and this was the first time the embedded got this much attention. The track had quality sessions and averaged around 20 attendees for each session.<br /><br />You can find my slide decks via the links below:<br /><br /><br /><br /><a href="http://www.ngware.eu/blog/papers/Agile2011_embedded%20tdd%20cycle%20_Punkka_Ahman.pdf"><strong>Embedded Testing Cycle - the First 3 Years, Markku Åhman and Timo Punkka</strong></a><strong><br /></strong><br /><em>James Grenning presented the embedded test-driven development (TDD) cycle already in 2004. Whispers on the hallways of conference hotels tell that somebody is actually implementing this idea. However, there are only few documented implementation details available. Schneider Electric’s fire security team has been implementing TDD cycle as an integral part of the development process for 3 years. Come to learn from their real-life experience and mistakes in automated testing at different levels: unit testing, acceptance testing using simulation, and in real target hardware. </em><br /><br /><br /><br /><em><br /></em><a href="http://www.ngware.eu/blog/papers/Agile2011_agile%20hardware%20and%20co-design_Punkka.pdf"><strong>Agile Hardware and Co-Design, Timo Punkka</strong></a><strong><br /></strong><br /><em>Agile software development is getting attention also in embedded software development. Embedded system development on the other hand requires different engineering disciplines working together. When embedded software team starts using agile methods, it affects also other disciplines. Agile development emphasizes continuous learning through experimenting and collaboration instead of following a detailed up-front plan. Agile embedded software team expects different behavior in system co-design. This talk discusses reasons and ways to adapt agile development to co-design of system development. </em><br /><br /><br /><br />Lots of other presentations, including all other embedded track presentations, are available via <a href="http://program2011.agilealliance.org/">the conference program site</a>.<br /><br /><br /><br /><img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 200px; DISPLAY: block; HEIGHT: 110px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5650606741594679282" border="0" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-IDov6QNinJqdtCFIc4JF6T-xb8MLqcT6wWfy2_jy9pFunccYRLG1lek7gCXr8LpVrFohwuY1Ce3nQKNhTOkJllEm5nNnVvU4dYPV9pC0Ev_9GcotR5yUHpOz2DSDt_4CN66V/s320/Agile2011-badge.jpg" />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-45317395042438032512011-08-18T15:06:00.006+02:002011-08-18T15:20:22.247+02:00A New Home<div style="text-align: center;">
<br /></div>A fiend of mine did fantastic job on <a href="http://www.ngware.eu/">my new site</a>. My fuzzy ideas and his zero-whining attitude made a good pair. It was truly an agile project. The site was up and running from day 1, and it emerged during number of customer-developer pairing sessions. Final outlook is a result of countless "you know, why don't we just try it"s.<div>
<br /><div>
<br /></div><div><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi89cbOYg6umvu2sUvgrzOlShYVHyS6NGqJpWvyUVa172CYB47EXDb_Oo7I6_qlq08sEYSkd7LV2SURrZIYzElDV_8pum9_66QfHWaTeIm6hwAU0FwpXOMWwYR66Nf3ZkpGLj3l/s320/ngware_home.png" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 215px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5642183132992854466" /></div></div>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-24172883.post-46105231189256706492010-12-17T20:20:00.003+01:002010-12-17T20:30:02.940+01:00Embedded Agile, ESC2010, BostonHere are the <a href="http://www.ngware.eu//blog/papers/ESC-241Slides_Punkka.pdf">slides</a> and <a href="http://www.ngware.eu//blog/papers/ESC-241Paper_Punkka.pdf">technical paper</a> from my talk on Embedded Agile at <a href="http://esc-boston.techinsightsevents.com/">Embedded Systems Conference 2010, Boston</a>.<br /><br />I had a good time at the conference. Hope you can find the material useful!<br /><br /><em><strong>Abstract.</strong> New product development (NPD) is getting more and more challenging. Change happens all the time in all dimensions, including own organization, technology, competition, and marketplace. Agile development is targeted at working in a turbulent environment driven by continuous learning. Originated from software industry, its applicability to embedded system development has been analyzed over the years. In this paper, I present some observations on implications of embedded system development to agile development. I introduce findings on frequent releasing, automated testing, co-design including non-SW development and quality systems like ISO9001.</em><br /><em></em>Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-24172883.post-82603996712865201432010-11-08T17:10:00.002+01:002010-11-08T17:16:51.111+01:00See you in GrenobleI'll be in Grenoble, France November 22.-24.11.2010 to attend <a href="http://agile-grenoble.org/">Agile Grenoble</a>.<br /><br />If you happen to be around, get in touch.<br /><br /><br /><p align="left"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMdb8nUanJ_ORTHDZWB-ODvkjgdH0a53IJJo3y1ngBszwvZQ9XoJWDaeb8TrAFozYgXpCjyaNhwKV-jdOdaGKTEsKJ5MAAt_-ER3DVd6yEm4MmqI-pWttsHjW24E1qSedRwB96/s1600/speaker+Agile+Grenoble+2010.PNG"><img id="BLOGGER_PHOTO_ID_5537212305857710722" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 197px; CURSOR: hand; HEIGHT: 147px" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMdb8nUanJ_ORTHDZWB-ODvkjgdH0a53IJJo3y1ngBszwvZQ9XoJWDaeb8TrAFozYgXpCjyaNhwKV-jdOdaGKTEsKJ5MAAt_-ER3DVd6yEm4MmqI-pWttsHjW24E1qSedRwB96/s200/speaker+Agile+Grenoble+2010.PNG" border="0" /></a></p>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-24172883.post-79835900142473043572010-09-11T19:21:00.004+02:002010-09-11T19:31:01.160+02:00See you in Boston<a href="http://i.cmpnet.com/eetimes/Logos/125x600-speaker-boston.gif"><img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 125px; CURSOR: hand; HEIGHT: 600px" alt="" src="http://i.cmpnet.com/eetimes/Logos/125x600-speaker-boston.gif" border="0" /></a><br /><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_QG_7PkQZnyBZlLALWKm9u8f-99xYvOQcCAcl5ZzusEB4dQqzYg5t8FL-oanOwWt_08AFNTWRvaHP3OLf2PcbjMzklIcV8D_5bdWKkn43p8AHBBGGBLqZdB4is9Y0mCUUoTEL/s1600/125x600-speaker-boston.gif"></a> </div><div> </div><div> </div><div> </div><div>I'll be attending ESC 2010 in Boston in a couple of weeks. You can <a href="https://www.cmpevents.com/ESCe10/a.asp?option=G&V=3&id=679181">catch me speaking</a> about embedded agile on Tuesday 21st. You can find me somewhere in the conference throughout the week. Let me know if you're around.</div><div></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-2225352929592365272010-08-27T18:51:00.001+02:002010-08-27T18:51:00.336+02:00Fiddling around before TDDThe first of the Uncle Bob's <a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd">Three Rules of tdd</a> states:<br /><br />1. You are not allowed to write any production code unless it is to make a failing unit test pass.<br /><br />A few recent discussions among embedded developers revealed that this rule has caused some confusion among fellow beginners of embedded tdd. So, let me first point you to another tip from the same source(<a href="http://blog.objectmentor.com/articles/2009/10/08/tdd-triage">Uncle Bob advises to do fiddling around on things that you are not sure of how they work</a>). I will share a short story:<br /><br />I've been writing a proof-of-concept driver for serial to Ethernet controller. It was not sure if the serial port on uC could be configured to work with the MAC controller, or if it would be possible to use the DMA controller to manage longer transfers. I needed the proof-of-concept for the hardware team fast. I learned how to use the controller by trial and error, glueing together several bits from application notes and examples and running them in combination of two evaluation kits. Needless to say it was a mess. It even turned out I couldn't get the job done without a few circuits from my hardware pals. It would have been really awkward and laborous to have tests written during this fast paced back and forth experimenting based on a sample code which of course didn't come with tests. All this was done in C, with the tools for C.<br /><br />After I knew which bits worked and which didn't, I wanted to illustrate this learning in tests. I harnessed the quickly hammered code with tests and then massaged the tests and code hand in hand into better shape. In retrospective, I should have treated the original code as a throw away prototype (aka code from Spike). I thought I would be faster by continuing to work with the code I had. Sad, but lacking the discipline made my overall cycle time propably massively longer. I believe that this is more of a rule.<br /><br />It might be from the first XP book, I'm not sure, but when I was first introduced to agile methods people always listed the last rule; rules are just rules. Based on this experience I do believe it is pragmatic to fiddle things around without tests. But when you start sculpting the solution towards production code, you should take a fresh start and drive test-first based on your newly acquired knowledge. I know I will next time.Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-24172883.post-90720940990528151992010-04-03T08:13:00.004+02:002010-04-03T08:20:30.725+02:00Test Driven Development for Embedded C in beta<a href="http://www.renaissancesoftware.net/">James Grenning's</a> book <a href="http://www.pragprog.com/titles/jgade/test-driven-development-for-embedded-c">Test Driven Development for Embedded C</a> is now available in beta from <a href="http://www.pragprog.com/">The Pragmatic Bookshelf</a>.<br /><br />I have taken a peek and checking it out is strongly recommended.Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-24172883.post-6809139122382696672009-12-19T07:35:00.003+01:002009-12-19T07:44:10.936+01:00Bowling Game Kata in C<a href="http://olvemaudal.wordpress.com/">Olve Maudal</a> has shared his presentation of <a href="http://olvemaudal.wordpress.com/2007/11/27/test-driven-development-in-c/">Bowling Game Kata using C</a>. You can find the slides directly here (<a href="http://www.pvv.org/~oma/TDDinC_Smidig2007.pdf">pdf</a>).<br /><br />I'll add a link to my TDD in C <a href="http://delicious.com/timo.punkka/">delicious</a>.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-48365100647369982652009-06-30T07:22:00.000+02:002009-06-30T07:24:19.240+02:00Coverage with lcov, and so what?<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifVqS1JgKdgBY2Luzn0ot7fLmTMZrNY4ub6DSMoh6Xm5oKmPEtVY7S56rCLAHvkom4N6JjIBHf6F22OwkV52u_6-30h1kDBMSZzxA1uUqxIi0k5tBYQsXqXqoSCyBdQxqInCtU/s1600-h/percentage.jpg"><img id="BLOGGER_PHOTO_ID_5339024878812392642" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 169px; CURSOR: hand; HEIGHT: 159px" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifVqS1JgKdgBY2Luzn0ot7fLmTMZrNY4ub6DSMoh6Xm5oKmPEtVY7S56rCLAHvkom4N6JjIBHf6F22OwkV52u_6-30h1kDBMSZzxA1uUqxIi0k5tBYQsXqXqoSCyBdQxqInCtU/s200/percentage.jpg" border="0" /></a><br /><div>A while back we ran an experimental line coverage analysis on our acceptance test suite. The result was 68% on the code for the main control board. I got the result from nightly build and mentioned it in Daily Scrum, and prompted "so what do we think about it, should we track it"? Everyone on the team had a blank stare and then finally a team member came forward "yeah, that's a good question. So, what?"<br /><br />Coverage is information. It is just that, an additional piece of information, not by any means the final truth. I don't remember who teached me this, but;</div><br /><br /><div><em>"If you take all your assert's away you still have the same coverage. You just ain't testing anything at all."</em></div><br /><br /><p>This has been explained <a href="http://googletesting.blogspot.com/2008/03/tott-understanding-your-coverage-data.html">here</a> and of course in <a href="http://www.exampler.com/">Brian Marick</a>'s classic <a href="http://www.exampler.com/testing-com/writings/coverage.pdf">How to Misuse Code Coverage</a> (pdf).</p><div>Well, maybe the good coverage can not say anything about the quality of your tests, but poor coverage can certainly say thing or two of opposite nature. If your coverage is 20% we can say quite confidently that you ain't there yet.</div><br /><div>I started with acceptance test line coverage, but the rest is about unit test line coverage. Some embedded teams use gcov and I have heard people fiddling the data to generate fancier reports. Being lazy as I am I didn't do it myself. I did what I'm good at and searched for what others have already done. I found lgov, which is a tool in Perl to format gcov data.</div><br /><div>We run lcov under Cygwin. You can get lcov for example from <a href="http://ltp.sourceforge.net/coverage/lcov.php">here</a>, extract, and execute "make install". Next compile and link unit tests with gcc using flags "-fprofile-arcs" and "-ftest-coverage". We have a special build target for intrumenting the unit test executables with debug and coverage information so that we don't unnecessary slow down the bulk of builds. Next execute your full suite just like you normally would.<br /></div><br /><div>In our case all .obj files from test build are in ./bin directory, and that's where all the coverage data files go to. Our unit test script moves them to ./bin/code_coverage directory away from .obj files, and we want the final html report to be in ./build/test/code_coverage. Now we have the information necessary to create a shell script to do the actual analysis and reporting of coverage data:</div><code><br /><div><span style="font-size:85%;">path=`dirname $0` </span></div><div><span style="font-size:85%;">lcov --directory $path/bin/code_coverage -b $path --capture --output-file $path/ic.info</span></div><div><span style="font-size:85%;">genhtml -o $path/build/test/code_coverage $path/ic.info</span></div></code><br /><div>Vola', your disappointing(?) results are ready to be browsed, like so:</div><div></div><br /><br /><div></div><br /><img id="BLOGGER_PHOTO_ID_5338927567248686978" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 246px; CURSOR: hand; HEIGHT: 226px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxdqsn9a-UZ8ESVb-8N1f7J_O6HgkAepryRiWFOY1byrpH2N5zFQlLQFTZjMF7ioa7FWT87qOUUF3-I6_FP4rCeAHyJHoneGBAmRMsbvUYrxXBPPbDhlhv5oW56NPhwR_l792C/s200/coverage.png" border="0" /><br /><br /><div>What the heck, it's all green, while you only have tests for simple utils files? In this approach there is a limitation - you only get coverage information for the files that are involved with your test suite. With huge legacy code, this would yield too promising picture early on. Again you need to think for yourself. </div><br /><div></div><div>Experiment with coverage in your team, I think it's worth every penny but even when you start closing 100%, remember to keep analyzing, "so what?"</div><div></div>Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-24172883.post-25667368890916260892009-02-06T11:32:00.002+01:002009-02-06T11:34:10.861+01:00Learning to cope with legacy C<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkG5PVEDgUi6pMCWpcdv2CC6AatzSzmlU5dSNt-rDoqnyjoGBn5urRZlnDiACVpPqVDvMBEYllXUXG1LPo7HH9hbQUUI3_RfOoEigjXlIZu0JfTdYqznNou983_T69Bfi7yZCM/s1600-h/learn.jpg"><img id="BLOGGER_PHOTO_ID_5299629984294815858" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 231px; CURSOR: hand; HEIGHT: 132px" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkG5PVEDgUi6pMCWpcdv2CC6AatzSzmlU5dSNt-rDoqnyjoGBn5urRZlnDiACVpPqVDvMBEYllXUXG1LPo7HH9hbQUUI3_RfOoEigjXlIZu0JfTdYqznNou983_T69Bfi7yZCM/s200/learn.jpg" border="0" /></a> New responsibilities during the past year have been a great learning experience. The key learning is that now I really know how incompetent I am. I can’t wait to move again and learn how many more things I do really badly, or what would be even better, can't do at all. This is a brief story of one such finding during this joyrney.<br /><br />For the past year we have focused on <a href="http://www.methodsandtools.com/archive/archive.php?id=72">ATDD</a> with our own framework written in Python. We have 200+ automated acceptance tests for the system. With unit tests we however have struggled. While we have over 100 (well, it’s a start) of them, without the exception of the latest ones they are not really meaningful.<br /><br />What's different with the latest tests then? They focus on higher level. I’m not sure what these tests as programmer tests should be called, but a programmer test will do for now. I do believe unit tests should be focused when doing TDD, but, wait, wait, I have an excuse… The code is old. It has its dependencies, and while maybe not the worst case in the world, it is a pain to get something compiled in isolation. The code has responsibility based structure (or should have had), and this structure is expressed in the source code folder structure. Each of the responsible "modules", or folders, typically contain own task. A typical task looks something like this:<br /><br />task_specific_inits();<br /><br />for(;;) {<br />s = OS_wait_for_something();<br />switch(s) {<br />case 1:<br />do_something1(s);<br />break;<br />}<br />}<br /><br />Sometimes do_something1(s) is inlined and you may get a bitter sweet taste of those infamous 1000+ line functions. Other times you are lucky and the whole high level event parsing is already done in own function, along with lines do_something_with_the_event_from_X(s). This function continues the handling with loooong switch case, hopefully just calling further functions.<br /><br />So, when we decide to test something inside a selected "module", or a folder in our case, we compile and link single test file, all the production code from a single responsible module/folder, production code for everything considered utils, like linked lists etc., and fake everything else. For faking we use Atomic Object's Cmock and manually written stuff when appropriate. We choose the task handling for injecting the test actions.<br /><br />We arrange the test execution environment as we wish by initializing all the parties to expected state and teaching the mocked neighbours accordingly. We inject a single event, or short sequence of events, into task's handling routine and we try to find ways to assert if everything went as we wished for. Sometimes we can use this to learn what really happens when you give such and such event. After all the default assumption is that the code works, as it has been in production for years. We want to make sure it stays that way, when we change it. We have several options for observing the behavior:<br /><br />1. Automatically generated mocks will tell us if the interaction was as expected<br />2. We can use getters of utilities, like linked lists<br />3. We can sense the internal status of any of the production code files with few nasty little tricks like #define STATIC<br /><br />When the first test, and maybe her friend, is running it is time to start refactoring your code. Refactoring your test code, that is. If you take a closer look on what you have done, you most likely see 1-2 300 lines long test cases, which look pretty much the same. Now it is a good time to start extracting helpers. When creating an event sequence to be run you probably generate similar data structures. These can be extracted into functions. You probably do a bunch of similar assertions on many of your test. These can be extracted to helper functions. And so on, and so on. Each refactoring is likely to reveal more opportunities for cleaning the code. This can't be emphasized more. It is important to keep the code clean from the beginning. Otherwise you will have a 10KLOC test file on your hands, and it is much more work to start cleaning it only at that point.<br /><br />This is very far from TFD (test first design). It is a battle to get some tests going to be in better place to continue improving and changing the code. The code is not going to disappear anywhere soon, so there will be lots of changes.<br /><br />Why it took us a year to get to this point? Blame is on me. I got bitten by the test bug while writing a really hard real-time firmware app with a former colleague bunch of years back, and we learned that small exact tests leading into small steps of coding lead into zero debugging time. This was type of SW where we earlier had spent majority of our time debugging the code with oscilloscope and manually monitoring led blinks with throw away debugging code. During that experiment I saw the light (as saw my colleague), and thought that this is how also firmware should be written. Write each line of code to make a small test pass. However it is fairly rare in embedded domain to get your hands on a green project. This may not be a characteristic of just embedded sw, but sw in general today. We mostly write enhancements to existing products. Existing products in 2009 are not typically delivered with automated tests, and even less so developed this in mind. There is going to be plenty of opportunities for battles like this. Letting go on the ideal very low level unit testing took a year for me. It is still my ideal way of coding, but we can not get there overnight with legacy code.<br /><br />If getting first tests in place sounds easy(?), calm down. It is only a starting place. You will notice how hard it is to test your code for example because of scattered initialization routines or that there is no structure in the first place. You should concider all these problems as good things. They are indicators for places of improvement. Those problems are in the code, building tests only make it more visible. If you work on those problems, you should be able to see more dependency breaking opportunities and eventually get to more focused tests. That’s the plan at the moment.<br /><br />Michael Feathers uses term pinch point in <a href="http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052/ref=sr_1_1?ie=UTF8&s=books&qid=1233915919&sr=8-1">his book</a> about working with legacy code. Pinch point is a function or small collection of functions that you can write tests against and cover changes in many more functions. I guess event handlers for tasks are our first natural pinch points. This at least is the current step on the learning ladder for me. Hope the ladders won’t fall.<br /><br />James Grenning also made a nice job articulating the whole legacy code testing process in C language (<a href="http://www.renaissancesoftware.net/blog/archives/27">link</a>).<br /><br />Atomic Object also presented the importance of refactoring the test code from the beginning (<a href="http://www.atomicobject.com/pages/Embedded+Feature-Driven+Design">link</a>).Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-84111299885379938332009-01-27T11:51:00.004+01:002009-01-27T11:56:15.520+01:00My Delicious Embedded TDD LinksAfter a hint from a friend I recalled that I actually did start to collect embedded TDD links on <a href="http://delicious.com/">delicious.com</a> a while ago.<br /><br />So not having anything more interesting to do, I updated the collection a bit and placed a link on the sidebar.<br /><br /><a href="http://delicious.com/timo.punkka/embedded_tdd">My Delicious Links on Embedded TDD</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-90133732559839467842008-11-10T08:27:00.001+01:002008-11-10T07:32:20.795+01:00The Complex Velocity of True TeamsUsing velocity for long term planning of a project is a wonderful idea. With minimal effort we get fairly good estimates. At least this would be the case in ideal situations, meaning new team without maintenance or obsolete component replacement obligations etc. If you are a believer in true teams as I am, you do realize that all the urgent work and even absence due personal issues affect team dynamics. Just calculating velocity in terms of team member availability isn't realistic with true teams. The velocity, or team achievement, is not linear function of sum of available team member hours. If one person is for example pulled away from team activities for taking care of urgent manufacturing issue, this will affect the team dynamics. This has deeper impact than just missing those hours. To be honest, in some teams the impact can be positive as well. In that case I suppose they were non functioning work group, which now due the changed dynamics has a chance to become a team. <br /><br />This said, no, we have not solved the issue of maintenance and other urgent work disrupting normal work. We are struggling with bouncing velocity. This is for several reasons, but it also woke me to think about true teams again. Anyway, I'd like to pay more attention to this and give true teams a chance to grow.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-54176522026649064532008-07-12T21:45:00.001+02:002008-07-12T21:50:28.195+02:00Even More Guns for Embedded DevelopmentA while back <a href="http://www.benoitlavigne.com/blog/2007/12/06/embedded-development-with-ruby/">Benoit</a> saw the light of using modern languages (<a href="http://www.ruby-lang.org/en/">Ruby</a> in that case) to help in developing embedded software, which still in most cases is developed in C for very well known reasons. I though I will throw additional ingradient to this soup. We are also using <a href="http://www.python.org/">Python</a> for our test-driven development, for acceptance test-driven development to be precise. There are few concepts that has lead us to do this.<br /><br /><br />1. You remember <a href="http://ng-embedded.blogspot.com/2007/07/wrap-it-thinly.html">wrapping thinly with hexagonal architecture</a>, right?<br /><br />2. Company that I work for has a long history of using embedded PC simulation system called E-SIM from <a href="http://www.mentor.com/">Mentor Graphics</a>. This product has <a href="http://www.mentor.com/products/embedded_software/development_tools/simtest/index.cfm">evolved</a>, but we are using the old version.<br /><br />3. E-SIM simulation tool has a Python API wrapper<br /><br />A continuum is to develop own embedded acceptance test framework using Python, right? Well, we did it anyway. It is fairly simple, really. E-SIM communicates with the application interfaces using the mechanism called channels. There is a Windows service running called Communication Manager. And this fellow is responsible for gathering and sharing values in these channels to various C applications and our test driver written in Python. Indeed, we can have several applications running on one PC and simulate multi-device/processor/board systems as we wish. A channel can be a package in communication, a binary input as push button, binary output as LED, and so on.<br /><br />Now, wanting to be able to write acceptance tests in a domain language that could be more readily understood by the business, we created a script parser using Python's reflection. This test driver parses the test script file and launches all the application .exe's as needed and then stimulates and senses the system using of E-SIM channel accessors. Sounds simple? The nice part is that it really is simple.<br /><br />These tests run automatically on our continuous integration server, but we also have a GUI which simulates UI of a real system. Now we can watch the UI in action during the test sequence scripts.<br /><br />Here is a snippet of .test acceptance test script written in (almost) domain language<br /><pre><br /><br />sendFire 0,1,2,3,Delay Fire<br />wait 2<br />sendDelayed 0,1,100<br />wait 2<br />checkRow 1,FIRE in zone 00021/1<br /><br /><br /></pre><br />Here is the reflection part of the parser in Python. I have no idea how good of a Python code this is being an average embedded C programmer, but it looks simple to me.<br /><pre><br /><br /><br /><strong>for</strong> <span style="color:#2040a0;">line</span> <span style="color:#2040a0;">in</span> <span style="color:#2040a0;">tp</span>.<span style="color:#2040a0;">getTestLines</span><span style="color:#4444ff;">(</span><span style="color:#4444ff;">)</span><span style="color:#4444ff;">:</span><br /> <span style="color:#2040a0;">self</span>.<span style="color:#2040a0;">currentScriptLine</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">line</span><br /> <span style="color:#2040a0;">self</span>.<span style="color:#2040a0;">currentScriptLineNumber</span> <span style="color:#4444ff;">+</span><span style="color:#4444ff;">=</span> <span style="color:#ff0000;">1</span><br /> <br /> <strong>if</strong> <span style="color:#2040a0;">len</span><span style="color:#4444ff;">(</span><span style="color:#2040a0;">line</span><span style="color:#4444ff;">)</span> <span style="color:#4444ff;">></span> <span style="color:#ff0000;">1</span><span style="color:#4444ff;">:</span><br /> <span style="color:#2040a0;">elements</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">line</span>.<span style="color:#2040a0;">split</span><span style="color:#4444ff;">(</span><span style="color:#008000;">' '</span>,<span style="color:#ff0000;">1</span><span style="color:#4444ff;">)</span><br /><br /> <span style="color:#2040a0;">try</span><span style="color:#4444ff;">:</span><br /> <strong>if</strong> <span style="color:#2040a0;">len</span><span style="color:#4444ff;">(</span><span style="color:#2040a0;">elements</span><span style="color:#4444ff;">)</span> <span style="color:#4444ff;">></span> <span style="color:#ff0000;">1</span><span style="color:#4444ff;">:</span><br /> <span style="color:#2040a0;">getattr</span><span style="color:#4444ff;">(</span><span style="color:#2040a0;">self</span>, <span style="color:#2040a0;">elements</span><span style="color:#4444ff;">[</span><span style="color:#ff0000;">0</span><span style="color:#4444ff;">]</span><span style="color:#4444ff;">)</span><span style="color:#4444ff;">(</span><span style="color:#2040a0;">elements</span><span style="color:#4444ff;">[</span><span style="color:#ff0000;">1</span><span style="color:#4444ff;">]</span>.<span style="color:#2040a0;">lstrip</span><span style="color:#4444ff;">(</span><span style="color:#008000;">' '</span><span style="color:#4444ff;">)</span><span style="color:#4444ff;">)</span><br /> <strong>else</strong><span style="color:#4444ff;">:</span><br /> <span style="color:#2040a0;">getattr</span><span style="color:#4444ff;">(</span><span style="color:#2040a0;">self</span>, <span style="color:#2040a0;">elements</span><span style="color:#4444ff;">[</span><span style="color:#ff0000;">0</span><span style="color:#4444ff;">]</span><span style="color:#4444ff;">)</span><span style="color:#4444ff;">(</span><span style="color:#4444ff;">)</span><br /> <span style="color:#2040a0;">except</span><span style="color:#4444ff;">:</span><br /> <span style="color:#2040a0;">self</span>.<span style="color:#2040a0;">myReporter</span>.<span style="color:#2040a0;">addWarning</span><span style="color:#4444ff;">(</span><span style="color:#4444ff;">)</span><br /> <span style="color:#2040a0;">self</span>.<span style="color:#2040a0;">warning</span><span style="color:#4444ff;">(</span><span style="color:#008000;">"Could not execute line: %s"</span> <span style="color:#4444ff;">%</span> <span style="color:#2040a0;">line</span><span style="color:#4444ff;">)</span><br /><br /><br /></pre><br /><br />And finally here is a simple method in the TestDriver class. You can see that the method's name matches the action word in the test script snippet above. The rest of the test script line is passed as an argument to the method.<br /><br /><br /><pre><br /> <span style="color:#2040a0;">def</span> <span style="color:#2040a0;">checkRow</span><span style="color:#4444ff;">(</span><span style="color:#2040a0;">self</span>, <span style="color:#2040a0;">parameters</span><span style="color:#4444ff;">)</span><span style="color:#4444ff;">:</span><br /> <span style="color:#2040a0;">elements</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">parameters</span>.<span style="color:#2040a0;">split</span><span style="color:#4444ff;">(</span><span style="color:#008000;">','</span><span style="color:#4444ff;">)</span><br /> <span style="color:#2040a0;">row</span> <span style="color:#4444ff;">=</span> <strong>int</strong><span style="color:#4444ff;">(</span><span style="color:#2040a0;">elements</span><span style="color:#4444ff;">[</span><span style="color:#ff0000;">0</span><span style="color:#4444ff;">]</span><span style="color:#4444ff;">)</span><br /> <br /> <span style="color:#2040a0;">expected</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">string</span>.<span style="color:#2040a0;">replace</span><span style="color:#4444ff;">(</span><span style="color:#2040a0;">elements</span><span style="color:#4444ff;">[</span><span style="color:#ff0000;">1</span><span style="color:#4444ff;">]</span>, <span style="color:#008000;">"<span style="color:#77dd77;">\n</span>"</span>, <span style="color:#008000;">""</span><span style="color:#4444ff;">)</span><br /> <span style="color:#2040a0;">actual</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">self</span>.<span style="color:#2040a0;">currentLCD_Rows</span><span style="color:#4444ff;">(</span><span style="color:#2040a0;">row</span><span style="color:#4444ff;">)</span><br /> <br /> <span style="color:#2040a0;">self</span>.<span style="color:#2040a0;">checkEqual</span><span style="color:#4444ff;">(</span> <span style="color:#2040a0;">expected</span>, <span style="color:#2040a0;">actual</span> <span style="color:#4444ff;">)</span><br /><br /><br /></pre><br /><br />Similar approaches are Atomic Object's <a href="http://rubyforge.org/projects/systir/">Systir</a>, and Exoftware's <a href="http://exactor.sourceforge.net/">Exactor</a>. These can be labeled as script frameworks in contrast to table frameworks like FIT/<a href="http://fitnesse.org/">Fitnesse</a>.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-10665903312707061792008-06-18T09:00:00.000+02:002008-12-09T17:24:38.901+01:00Impossible, I Have Never Done That<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1uXiPEAN4zf1eYc32duTFNmuEi6-UHksVfdf_RWfLLe6v7pF0CwDGLvDqvuY_YAvYkQJsROBaTl8uAPghkAoc01lHZ5sF6xtR0WR1g74HfPjIuAgu6qaR6TqGPuEzvObP9_oQ/s1600-h/science_experiment.jpg"><img id="BLOGGER_PHOTO_ID_5198049540570818354" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 188px; CURSOR: hand; HEIGHT: 250px" height="279" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1uXiPEAN4zf1eYc32duTFNmuEi6-UHksVfdf_RWfLLe6v7pF0CwDGLvDqvuY_YAvYkQJsROBaTl8uAPghkAoc01lHZ5sF6xtR0WR1g74HfPjIuAgu6qaR6TqGPuEzvObP9_oQ/s200/science_experiment.jpg" width="227" border="0" /></a> When adopting agile planning techniques to non-software development activities an often heard argument against estimating the complexity of, say, schematic is:<br /><br />"it is impossible to say, I have never done that before"<br /><br />Well, firstly, in embedded software that's the situation pretty much allways, yet agile planning has proven to be efficient enough over and over again.<br /><br />Secondly, we are living the era of enlightened experimentation. Prototyping hardware is drop dead cheap and fast nowadays. Buying yourself a status of "I have done that once" instead of "haven't done that before" is as easy as deciding to do so.<br /><br />Thirdly, schematics can be estimated with relative complexity.<br /><br />Fourthly, Parkinson's law works everywhere where humans are involved. Timeboxing early prototypes will help making the progress reliable and visible. This is however understandably very counter intuitive to the "get it right the first time" camp.<br /><br />This is what is called up-front prototyping. In contrast to traditional hardware prototyping trying to validate something at the end, up-front prototyping focuses on learning. We may even know that the prototype will not work on most parts, but we just want a reliable measure of how far are we. It is even advisable to design a prototype to prove just one thing. More than one uncertanty will make the work unnecessarily complex.<br /><br />This distinction between the goals of traditional validating and new era learning prototyping has gotten me concidering a new word to replace "prototype". So far the best candidate is 'product'. Using a word product throughout the lifecycle we would realise that this is aiming to production quality, but the maturity of the desing is evolving.<br /><br />Of course I'm talking about prototypes that can be assembled within reasonable cycle cost. The bar however is getting lower and lower every day. Interesting exercise is to take your latest embedded development project, draw a bar of development salary cost and a second bar illustrating your prototype cycle cost. You may be surprised how cheap "expensive unnecessary prototyping" is in the big picture.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-24172883.post-22163009291213121752008-05-06T20:05:00.002+02:002008-05-06T21:36:07.691+02:00At least have a tasteWe teach our children to at least have a taste before they judge anything as "yak".<br /><br />We also teach engineers to try out practices before they judge anything as "yak".<br /><br /><br /><blockquote>"Just try it, if it does not work - ditch it".<br /></blockquote><br /><p>TDD (test-driven development) is probably the most difficult technical skill associated with so called agile development especially in constrained embedded environment. It is also probably the most rewarding when in use.<br /><br />The problem with TDD is that it has a learning curve. To make things worse the earlier debug-later development model has an unlearning curve. Most of the true benefits can concretely be seen after a fairly long period of time. It is not enough just to have a taste before judging, you actually need a prolonged tryout period. You most likely need some external help in the beginning. Your short term productivity suffers because of learning new skills and solving new kinds of problems.<br /></p><p>You need someone in customer's role who is willing to talk about long term productivity as well.<br /><br />Never the less I recommend to just have a taste.</p><p></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-53312551447243403772008-04-01T22:40:00.000+02:002008-04-01T21:32:09.506+02:00Just remembered when I was just nodding on embedded TDDRecently I have been talking a lot about embedded TDD to different, mostly experienced, embedded programmers. I thought I would jump right into a bit more advanced issues, to start a discussion, and maybe walk out with few new things myself. After all they were excellent programmers. I didn't want to waste the opportunity to learn.<br /><br /><br />During these sessions I have seen a lot of nodding people. I have though that "wow, I'm pretty good at explaining this". I have left with a smile on my face after a huge sense of agreement. I know better now. It's a much longer journey than one day seminar.<br /><br />The challenge, or one of them, as I realize now, is that if you give a basic introduction with mickey mouse stuff examples to experienced embedded developers you will be immediatelly shot down with "that won't work in our environment, because [<a href="http://tech.groups.yahoo.com/group/AgileEmbedded/message/191">choose your favorite item identified on Embedded Agile Yahoo group</a>]".<br /><br /><br />On the other hand if you rush straight into embedded TDD specific stuff, people are going to just nod.<br /><br />And this is the other end of the same challenge. They are nodding so that you would go away faster. Not understanding fully is scary for a seasoned engineer who has not opened a book in the past 15 years or so. This nodding experience alone is not going to make anyone start practicing TDD. The best is to give a hands-on experience on TDD itself, show the benefit, and not on mickey mouse stuff but on real deal.<br /><br /><br />Advice that I'm going to follow is to try to remember when I was also just nodding and how many years, books, articles, conferences, talks, discussions, trials, failures, small successes, and so on, it took for me to get it. And I'm still only beginning to understand TDD.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-40103738017787105962008-03-10T05:12:00.001+01:002008-03-10T07:58:39.860+01:00Embedded Blogosphere Gets StrongerA while ago we took <a href="http://ng-embedded.blogspot.com/2007/06/embedded-blogosphere.html">a look </a>at embedded blogospehere. That sphere is now even stronger - <a href="http://www.objectmentor.com/omTeam/grenning_j.html">James Grenning</a> has a <a href="http://www.renaissancesoftware.net/blog">new blog</a>. He is "<em>blogging about Agile Development, especially embedded</em>". That should be interesting enough. There's already two posts about techniques that can be used to test-drive hw driver development (<a href="http://www.renaissancesoftware.net/blog/?p=7">1</a>, <a href="http://www.renaissancesoftware.net/blog/?p=8">2</a>).Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-24172883.post-67988742515282044992008-02-29T04:53:00.003+01:002008-02-29T04:57:28.405+01:00Only few seats left in Agile Finland Seminar<a href="http://agilefinland.com/">Agile Finland</a> is organizing yet another <a href="http://events.agilefinland.com/events/show/5">seminar</a>. It takes place March 4th in Helsinki. This morning there was only some twenty seats available.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-41289729063922697192008-01-30T09:56:00.000+01:002008-12-09T17:24:39.053+01:00Islands of Expertise Can Get You Lost<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiChE3YKSR2k6CAOcITm3Jgx9XCT2chzEj_vuo7dVO7vfInq66eeaPSMZF8qKNnAQo2GNlThv47fyM6COS7xMeUZTBInbtbvYicv9zDm7KznK8XLInAK2Z904x6dIcB7BrswirE/s1600-h/we_are_lost.jpg"><img id="BLOGGER_PHOTO_ID_5161193264385873106" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" height="168" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiChE3YKSR2k6CAOcITm3Jgx9XCT2chzEj_vuo7dVO7vfInq66eeaPSMZF8qKNnAQo2GNlThv47fyM6COS7xMeUZTBInbtbvYicv9zDm7KznK8XLInAK2Z904x6dIcB7BrswirE/s200/we_are_lost.jpg" width="211" border="0" /></a>You may be familiar with the following scenario. The embedded software development department has finally launched a large new system. The system obviously immediately gets new feature requests and other modification needs. During the initial development each developer has found a pet part in the overall system. When the improvements/modifications start it is intuitive to assign these smaller projects to a person whose area the change mostly concerns. In this approach we launch several, as many as there are developers, projects to run in parallel. This seems like a natural way to go.<br /><p>While tempting at the first look, there are several problems in the above scenario. First is the customer’s role. It is difficult enough to get a functioning product owner for one project. Running multiple projects at the same time is ridiculously challenging. If we get one person to act as a customer proxy for all these small projects, this person soon becomes a bottleneck for all these projects. A project needs collaboration with the customer representative, and the sooner we get the feedback the better. The customer needs to be available at all times, and this is easier to achieve for one project at the time.</p><p>Second problem follows from the fact that it is rare that all these projects are completely independent. While we think that no one works on more than one project at the time, we actually have created a highly complex hidden multi-project environment. Typically one, or few, developers know something about everything. This means that people that are supposed to be working for their own project need to consult other projects continuously. These people become the bottlenecks for other projects, and their own project is impossible to estimate. As a net result we push all our projects to be more, and more, late without any control to what is going on. </p><p>Thirdly, assigning a developer to her previous pet part of the system further develops the specialization in a narrow part of the overall system, creating small islands of expertice. More and more closed silos of expertice emerge in the department. This is a high risk path as in an unfortunate case of loosing that person for one reason, or another we halt the development of that part for unpredictable period of time. Yes, I have heard that documentation should be there for allowing anyone to work on new part. Well, having been in the development game for nearly 15 years I kind of have lost faith to that approach. Maybe if the previous developers have focused their energy mainly on enabling future work –type of documentation. Never the less, safer path is to several developers to know the work. </p><p>The fourth problem is the lack of possibility to gain from the superior performance of true teams. Assigning each person to a single small project will at its best only accomplish the sum of each developer in development department. If we are successful in getting a true team to jell we can accomplish a lot higher performance that the sum of team members. This is important especially when the work we are engaged with gets more complex, and needs higher problem solving capability.</p><p>Changing to work in teams and in the same part of the system may feel difficult and weird at the beginning. Progress may also appear slow as most of the team members are unfamiliar with the parts of the system they need to work with. It may also take old school engineers by the surprise that they also need the softer skills, interaction and communication. It is crucial that collective ownership is still enforced. Teams have a remarkable capability in finding the ways to work. The practices supporting the work of team will merge rapidly. You don’t have to know everything to start working this way. Just follow the basics; </p><ol><li>do fast paced iterative development, </li><li>have reflective retrospectives, and</li><li>create open, learning-driven culture.<br /></li></ol>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-24172883.post-45160221161148272652008-01-22T05:39:00.000+01:002008-01-22T05:58:44.949+01:00Post leakA <span class="blsp-spelling-error" id="SPELLING_ERROR_0">friend</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_1">told</span> me <span class="blsp-spelling-error" id="SPELLING_ERROR_2">that</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_3">one</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_4">of</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_5">my</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_6">drafts</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_7">leaked</span> into <span class="blsp-spelling-error" id="SPELLING_ERROR_8">feed</span>. <span class="blsp-spelling-error" id="SPELLING_ERROR_9">It</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_10">was</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_11">probably</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_12">an</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_13">user</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_14">error</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_15">by</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_16">yours</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_17">truly</span>. I <span class="blsp-spelling-error" id="SPELLING_ERROR_18">apologize</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_19">for</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_20">your</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_21">incovenience</span>.<br /><br /><span class="blsp-spelling-error" id="SPELLING_ERROR_22">What</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_23">comes</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_24">to</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_25">that</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_26">draft</span>, I <span class="blsp-spelling-error" id="SPELLING_ERROR_27">hope</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_28">to</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_29">find</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_30">time</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_31">to</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_32">finish</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_33">writing</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_34">about</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_35">Preston</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_36">Smith's</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_37">latest</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_38">book</span> "<a href="http://www.amazon.co.uk/Flexible-Product-Development-Building-Changing/dp/0787995843/ref=pd_bbs_sr_1?ie=UTF8&s=gateway&qid=1200976949&sr=8-1"><span class="blsp-spelling-error" id="SPELLING_ERROR_39">Flexible</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_40">Product</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_41">Development</span></a>" <span class="blsp-spelling-error" id="SPELLING_ERROR_42">and</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_43">agile</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_44">in</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_45">non-software</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_46">development</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_47">soon</span>.Unknownnoreply@blogger.com0