tag:blogger.com,1999:blog-41729506268302176432024-03-28T03:20:54.461-04:00Better Embedded System SWCompanion blog to the book Better Embedded System Software by Phil Koopman at Carnegie Mellon UniversityPhil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.comBlogger181125tag:blogger.com,1999:blog-4172950626830217643.post-73648884854108214712022-12-31T07:34:00.000-05:002022-12-31T07:34:43.628-05:00Job and Career Advice<div class="separator" style="clear: both; text-align: center;"><p style="text-align: left;">I sometimes get requests from LinkedIn contacts about help deciding between job offers. I can't provide personalize advice, but here are my thoughts in general.</p><div><br /></div><span style="text-align: left;"></span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPm-U278YbnlT6qhNK1YdZmOuQt81RoQCvsCnL1vzvi38DtVJuBXjHgZBEUb_LL012p8kxh1wasudVtzpAix47v5vIbLH109pL8bggSFoUxXil9MQ4DjeDjqVB_Dz355Pxe2CgNesDGjw/s2048/pexels-ketut-subiyanto-4559532.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2048" data-original-width="1365" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPm-U278YbnlT6qhNK1YdZmOuQt81RoQCvsCnL1vzvi38DtVJuBXjHgZBEUb_LL012p8kxh1wasudVtzpAix47v5vIbLH109pL8bggSFoUxXil9MQ4DjeDjqVB_Dz355Pxe2CgNesDGjw/s320/pexels-ketut-subiyanto-4559532.jpg" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><p>You must accept personal ownership for choosing what you want to do with
at least the next few years of your life. Nobody can do this for you. Some luck is always involved, but fortune favors the prepared. It is up to you to set your own course.</p>Years of your working career are a scarce, non-renewable resource, so spend care in deciding.
On the other hand, it is difficult to make a choice because, as they say, it is difficult to make predictions -- especially if they're about the future. It's
even harder to foresee consequences, especially on your first couple
jobs when you are learning how everything works. And there are always surprises, even for the most experienced of us. But if you end up
making a choice that works out poorly, then figure out the lesson to
learn and switch to something else.<br />
<br />Take a look at how the job fulfills or supports your needs on Maslow's
Hierarchy
(<a href="https://en.wikipedia.org/wiki/Maslow%27s_hierarchy_of_needs">https://en.wikipedia.org/wiki/Maslow%27s_hierarchy_of_needs</a>). Some of
us live to work; some work to live. There is no one right answer, but
at least this gives you a simple checklist of what you want to be
provided by the job -- and what you don't. If you're signing up for a
12 hour x 7 day type job, it had better go a long way to filling up that
pyramid in an acceptable, non-destructive way while you're at work, because you'll always be at work. (And that might be OK for some people in some phases of their career. But not for others.)<div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIDgJKOisBbAN_u_-J5OxgxATu9Czy69VBw277cQNe_Tg0cSli6M49BbD-A-8qFiP-iPPBZF35IuJfhA1uJ1Y1FpD3aZsdxwA07D7Nh5WlX5xKZm61an5eNKwkFWcNDWouHo-9E3yL2PI/s2048/Maslow_Hierarchy_of_Needs2.gif" style="margin-left: 1em; margin-right: 1em;"><img alt="https://en.wikipedia.org/wiki/Maslow%27s_hierarchy_of_needs" border="0" data-original-height="1504" data-original-width="2048" height="470" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIDgJKOisBbAN_u_-J5OxgxATu9Czy69VBw277cQNe_Tg0cSli6M49BbD-A-8qFiP-iPPBZF35IuJfhA1uJ1Y1FpD3aZsdxwA07D7Nh5WlX5xKZm61an5eNKwkFWcNDWouHo-9E3yL2PI/w640-h470/Maslow_Hierarchy_of_Needs2.gif" title="Maslow's Hierarchy of Needs" width="640" /></a></div><div style="text-align: center;">Maslow's Hierarchy of Needs [https://en.wikipedia.org/wiki/Maslow%27s_hierarchy_of_needs]</div><div><br />All organizations have dysfunction. Figure out if this organization's
dysfunctions are going to be irritating to you or get in the way of
satisfying your hierarchy of needs. Most people can stand an irritating environment less well than they think they can over long stretches of time.<br />
<br />When you're young, there is a lot to be said for working in a
structured, mature organization. You can learn a lot by watching how experienced folks work rather than by making rookie mistakes (if you are paying attention). Later on you might
want less structure. Skipping right to an unstructured job at an
immature company will teach
you a lot of bad habits that it can take a lifetime to unlearn, and leave
many holes in your practical education. (Some jump right to a startup
company with no "graybeards." Some skip college. Some get rich by
winning the lottery. Some don't. I can
only tell you how to stack the odds in your favor.) Consider the availability of mentors in your new position. Even the smallest, newest of startups can work for this if the mentorship is there.<br />
<br />Ask if the level of responsibility & authority is a fit both in
terms of scope and structure. My experience has ranged from military
officer (highly structured) to consultant (freedom but few safety nets unless you've already built up a big cushion toward retirement).
Where you want to be will likely change as your career progresses.<br />
<br />Read the general job hunting advice books/web sites for things such as the realities
of accepting a low paying first job and trying to get raises later. The
classic book is "what color is your parachute," but no doubt there are
others, keeping in mind that highly skilled workers are a bit different
than the general work force. It helps to have a realistic understanding
of what you are worth, and to get some objective advice from someone
you trust on whether you're getting taken advantage of in a job offer.</div><div><br /></div><div><u>2023 update:</u> the flood of cheap venture money is drying up along with rising interest rates. It is easier to justify sky-high salaries when investor emphasis is on subsidized growth rather than profit margin. Don't be surprised if there is downward pressure on salaries. Many will find themselves losing to inflation even if they maintain their salary. Junior folks and those with demands easier to fill with new grads will probably be hurt the most here. It's hard to predict how this will play out, but expect a fundamental change from the days of near-0% interest rates driving leveraged speculative investments.<br />
<br />
After you've considered the above, IMHO only then should you worry about
the more common philosophical areas you see mentioned on this topic.
(And really, most of them end up on the upper levels of Maslow's
Hierarchy.) My personal preferences are:<br /><ul style="text-align: left;"><li>Surround yourself with the smartest, most capable people you can. But stop short of jerks. Note that any company with a "no jerks" policy is making a relative statement to their existing staff, rather than an absolute measurement. Pay attention during the interview to this.</li><li>Work for good leaders that support and empower those who work with them.</li><li>Take advantage of any opportunity you can get to improve your communication skills and soft skills.</li><li>If you're taking a job purely for the money, go into that situation
with an exit plan and target exit date. Make sure that is really
how you want to spend a part of your life -- but in some circumstances this can be the right move.</li><li>If you're stressed out, it's time to find a new job. (Or re-invent your job from within.)</li><li>If you're stressed out about your career, it's time to reinvent yourself and find a new career.</li><li>I personally think the whole LeetCode interview process is nothing more than ritualized hazing. More than a two-round interview process is another caution sign unless you are signing up for an extremely senior position. Anyone with a strong GRE score (or top-tier SAT score) has already sacrificed at the altar of preparing for a required hoop sufficiently, and that probably taught them more generalized skills. But apparently others disagree on this point.</li><li>If you strive to be the absolute best at what you do, opportunities will find you. (Being visible helps: speak at conferences, write something that people might see somewhere.)</li><li>If most days you wake up and are eager to get to work, reflect on how fortunate you are to have that.</li></ul>Don't forget the part that you must own your choice. Your preferences will probably differ.<div><br /></div><div>Please do not contact me with questions about your particular individual situation. The hours in my day are already too few to accomplish what I'd like for my personal goals. I took some time to write this to help as many people as I can (one of my goals), but <i><u>I lack the time to provide individual responses</u></i>. So if I don't respond to a personal query, please understand (and better yet, send the personal query to a trusted friend instead).<br /><div><br /></div><div>I hope this is helpful, and wish you the best of luck in your job choices and your career!</div></div></div>Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-7927005593249850512022-12-19T10:11:00.004-05:002023-01-25T20:22:43.879-05:00What compiler warnings should you enable?<p> Here is a brief piece I wrote that Jack Ganssle <a href="http://www.ganssle.com/tem/tem460.html#article3">just ran in The Embedded Muse 460.</a></p><p>The context was <a href="http://www.ganssle.com/tem/tem459.html#article3">a previous discussion about enabling compiler warnings.</a></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8a5ESGE5Np4NUE1SuGRetXwdcQ_ruBFTvSPCil1QbxUlPTKc7OW2twNpggz0Iz5OX8iOHsrm3FmTV6A5zyeJZZrglC3qw9DzSnXqlfxVJqb8pAvI9rkXwO4_eJ9iqotLT6DMh6iPLMO5XiFyfOO3P4_I34k6f35gIKk4d7fYOmzvaZgP65L_drylh/s1544/Capture.JPG" style="margin-left: 1em; margin-right: 1em;"><img alt="List of compiler warnings" border="0" data-original-height="847" data-original-width="1544" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8a5ESGE5Np4NUE1SuGRetXwdcQ_ruBFTvSPCil1QbxUlPTKc7OW2twNpggz0Iz5OX8iOHsrm3FmTV6A5zyeJZZrglC3qw9DzSnXqlfxVJqb8pAvI9rkXwO4_eJ9iqotLT6DMh6iPLMO5XiFyfOO3P4_I34k6f35gIKk4d7fYOmzvaZgP65L_drylh/w400-h220/Capture.JPG" width="400" /></a></div><span><a name='more'></a></span><table border="0" cellpadding="0" style="width: 80%px;"><tbody><tr><td bgcolor="#0070C0" width="5"><br /><br /></td><td><p>John Carter's suggestion to use compiler warnings as a
first step toward coding standards is an important one. I tend to
split these up into "coding style for people" and "coding styles for
the compiler." Often we talk about indenting curly braces and tabs vs.
spaces (for people) -- but making sure the compiler isn't confused
about what you mean is also important. For those who've never
contemplated the difference you might find video lectures #4 and #5 here
of interest: <a href="https://course.ece.cmu.edu/~ece642/">http://course.ece.cmu.edu/~ece642/</a><br /><br />
However, there is a common misconception that someone might take away
from a recommendation of a gcc warning default of "-W -Wall -Werror"
which is that "-Wall" is not actually "all." Apparently the warning
list for "-Wall" got frozen at some point, and there are a whole bunch
more useful baseline warnings included if you add "-Wextra"<br /><br />
So for starting I'd recommend:<br />
-Wall -Wextra -Werror<br /><br />
When I teach better software engineering skills (including clean code)
at Carnegie Mellon University, I require all projects to use these
warnings to produce some interesting learning experiences:<br /><br />
-Werror -Wextra -Wall -Wfloat-equal -Wconversion -Wparentheses -pedantic
-Wunused-parameter -Wunused-variable -Wreturn-type -Wunused-function
-Wredundant-decls -Wreturn-type -Wunused-value -Wswitch-default
-Wuninitialized -Winit-self<br /><br />
No doubt there will be those who find some warnings controversial, but
any warning that helps find a bug provides value, and I'd rather spend a
bit more time structuring my code to enable passing automated compiler
analysis than chase down bugs in production.</p><p>UPDATE 1/23/2023: thanks to a social media commenter for pointing out that some of the listed warnings are redundant. My revised recommendation that implements the same compiler behavior is:</p><p><b>-Werror -Wextra -Wall -Wfloat-equal -Wconversion -Wredundant-decls -Wswitch-default -pedantic</b></p><p><u>Can be omitted because already in -Wall:</u></p><p>-Wparentheses -Wunused-variable -Wreturn-type -Wunused-function -Wreturn-type -Wunused-value -Winit-self -Wuninitialized</p><p><u>Can be omitted because already in -Wextra:<br /></u>-Wuninitialized -Wunused-parameter </p><div>You should also consider enforcing C standard support to avoid gcc-specific features that will be less portable. You can do this by for example adding the flag "-std=c11" or "-std=c++11" as appropriate.</div><div><br /></div><div>If you have a compiler other than GCC, then you will need to consider those proprietary warning flags to achieve a similar outcome.</div><div><br /></div><div><br /></div><div><br /></div><p><br /></p></td></tr></tbody></table><br /><span><!--more--></span><div>For those paying really close attention, you'll note -Wreturn-type appears twice. That does no harm but it is a nice bit of fun to have it appear after -Wredundant-decls :)</div>Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-50661789709736172792021-02-02T00:30:00.006-05:002022-12-17T08:41:27.594-05:00Better Embedded System Software e-Book & Paperback<p>There are only a handful of hardcover books left of the first edition, so I spend some time converting things over to an eBook & Paperback edition.</p><p>Amazon Kindle: <a href="https://amazon.com/gp/product/B08TZ9LYXC">https://amazon.com/gp/product/B08TZ9LYXC</a></p><p>Smashwords (epub): <a href="https://www.smashwords.com/books/view/1264918">https://www.smashwords.com/books/view/1264918</a></p><p>Barnes & Noble (ebook): <a href="https://www.barnesandnoble.com/s/philip%20koopman">https://www.barnesandnoble.com/s/philip%20koopman</a></p><p>This is not a 2nd edition, but more like version 1.1. The changes are:</p><p></p><ul style="text-align: left;"><li>Some minor rewording and cleanup.</li><li>A few small sections rewritten to reflect lessons I've learned about how to better explain things from teaching courses. However, scope remains the same and the hardcover book is still serviceable if you already have that.</li><li>A new summary list of high-level takeaways in the conclusions chapter.</li><li>Publication support for everywhere KDP reaches, with local distribution in all supported markets.</li></ul><div>The paperback is probably what you'd expect given the above, and is Print-On-Demand with production handled directly by Amazon. There is no index due to publication platform issues. However, the table of contents is pretty well structured and in most cases that will get you where you need to go. The price is significantly lower than the hardcover, and non-US readers can get it printed and shipped from someplace much closer to home since KDP has local POD for markets in Europe and Asia.</div><div><br /></div><div>Amazon indicates they will print-on-demand for the following markets: US, DE, ES, FR, IT, UK, JP and CA. Some readers report availability in other markets as well (for example, AU). So try your usual Amazon marketplace first, then one of the others close to you to minimize shipping cost.</div><div><br /></div><div>The eBook is reflowable text for the body text (authored in EPUB format, but Amazon changes formats I believe). Bitmaps are used for figures and equations, so it should look fine on most viewing devices without symbol font issues. The price is significantly lower than the paperback since production and distribution costs are much lower.</div><div><br /></div><div>Amazon has worldwide distribution rights for the eBook, but availability varies based on which country your device is set up for. If your kindle is set up as being in the US market then you should have no troubles purchasing. Many other markets (especially in Europe) should be fine as well. Amazon promises e-boook availability in these specific markets: US (.com), IN, UK, DE, FR, ES, IT, NL, JP, BR, CA, MZ, AU.</div><div><br /></div><div>The book is published via KDP, but Digital Rights Management (DRM) is OFF. That should help folks with non-Amazon viewers (but I'm not able to provide support for how to side-load onto whatever platform). If you have Kindle or a machine that runs the Kindle App then it should be seamless as with any other Kindle book.</div><div><br /></div><div>I really appreciate the support of the thousands of readers of the hardcover edition over the past years. I hope that this makes the material more broadly available!</div><div><br /></div><div><a href="http://www.koopman.us/bess/bess_contents.pdf">Link to free preview (from the hardcover edition)</a></div><div><br /></div><p></p>Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com6tag:blogger.com,1999:blog-4172950626830217643.post-24048014946675562682021-01-09T21:55:00.002-05:002021-01-09T22:03:29.223-05:00The Y2038 Problem. Sooner than you think.<p>In the coming years, there will be other time rollovers beyond Y2K. The next big one isn't all that far away.</p><p>Contrary to what you might have heard, the reason more computers didn't break on Jan 1st 2000 wasn't because it was a false alarm. It was because massive resources were poured into avoiding many of the problems. And many things did in fact break, but backup plans were in place. (I recall not getting financial reports for most of 2000 for my spending accounts at work. So I had to keep my own books and hope I didn't overspend -- because the old accounting system expired at the end of 1999 and the new one wasn't on-line until Fall 2000.)</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq1LzyBKk0QcsbFEAdRu-wroUnylXuQJyQC4XkdoRV3Y0oxBqrwXUU4OfUYmEVKY26qkL-UqsQOGGv0OprLx8msQcbmwzu-LCV1SzLvdOXcOiTKkTrHS60_RYsE_V4OGKbAw8thqrw2lc/s2017/y2038.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1416" data-original-width="2017" height="281" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq1LzyBKk0QcsbFEAdRu-wroUnylXuQJyQC4XkdoRV3Y0oxBqrwXUU4OfUYmEVKY26qkL-UqsQOGGv0OprLx8msQcbmwzu-LCV1SzLvdOXcOiTKkTrHS60_RYsE_V4OGKbAw8thqrw2lc/w400-h281/y2038.JPG" width="400" /></a></div><br /><p>In January 2021 we saw some aftershocks when a 2-year time digit window hack ran out of steam from Y2K patches. But the world didn't come to an end.</p><p>The next potentially huge time problem will be January 2038 when the 32-bit signed Unix time in seconds rolls over. </p><p>Plenty of embedded systems last 20+ years (already we are closer than that to 2038). Plenty of embedded systems are using 32-bit Unix, since 64-bit CPUs just cost too much for the proverbial toaster oven. An increasing number of systems are updatable, but many require manual intervention. Updating your DVD player (if we still have them in 2038) won't be so bad. Updating a natural gas pipeline valve in the middle of nowhere -- not as fun. Updating all your smart light bulbs will range from tedious to buying all new lightbulbs. And so on.</p><p>This is a good time for embedded system designers to decide what their game plan is for Y2038. As your expected product life starts overlapping with that (as I write this, it's only 17 years away), you're accumulating technical debt that will come due in a big chunk that year. Better to have a plan now than a panic later. Later has a way of sneaking up on you when you're not looking.</p><p>For a more detailed list of timer rollover issues, see:</p><p><a href="http://www.lieberbiber.de/2017/03/14/a-look-at-the-year-20362038-problems-and-time-proofness-in-various-systems/">http://www.lieberbiber.de/2017/03/14/a-look-at-the-year-20362038-problems-and-time-proofness-in-various-systems/</a></p><p><br /></p>Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-69956334599962564862021-01-05T13:10:00.001-05:002021-01-05T13:10:40.871-05:0062 Software Experience Lessons by Karl Weigers<p>Karl Weigers has an essay about lessons he's learned from a long career in software development. You should benefit from his experience. The essay covers requirements, project management, quality, process improvement, and other insights.</p><p><a href="https://medium.com/swlh/62-lessons-from-50-years-of-software-experience-2db0f400f706">https://medium.com/swlh/62-lessons-from-50-years-of-software-experience-2db0f400f706</a></p><p>A good example from the article is:</p><p></p><blockquote style="border: none; margin: 0 0 0 40px; padding: 0px;"><p style="text-align: left;"><i>"You don’t have time to make every mistake that every software practitioner before you has already made. Read and respect the literature. Learn from your colleagues. Share your knowledge freely with others." </i></p></blockquote><p></p><p><br /></p><p><br /></p>Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com3tag:blogger.com,1999:blog-4172950626830217643.post-38945120029666012962020-08-01T09:23:00.002-04:002020-08-01T09:29:59.855-04:00LINT does not do peer reviews<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirP8qm9MY6PJ0QOQ5GtmB7hVgTVMSdE1JrrbbNHc0Tz24JJCg9eEWTjKG-yMmq6elRB1HyZ3fGVO-8QHwnvbZfJufrym3X2mOJBxjKWAHQQqv9vH1UsBwDjJ92Duthfd_0CPCU9YLQ58Y/s1600/code-2858768_1280.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1280" data-original-width="1172" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirP8qm9MY6PJ0QOQ5GtmB7hVgTVMSdE1JrrbbNHc0Tz24JJCg9eEWTjKG-yMmq6elRB1HyZ3fGVO-8QHwnvbZfJufrym3X2mOJBxjKWAHQQqv9vH1UsBwDjJ92Duthfd_0CPCU9YLQ58Y/s320/code-2858768_1280.png" width="293" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://pixabay.com/vectors/code-programming-head-computer-2858768/">https://pixabay.com/vectors/code-programming-head-computer-2858768/</a></td></tr>
</tbody></table>
<br />
Once in a while I run into developers who think that peer review can be completely automated by using a good static analysis (generically "lint" or compiler warnings). In other words, run PC-LINT (or whatever), and when you have no warnings peer review is done.<br />
<br />
Nope.<br />
<br />
But the reality has some nuance, so here's how I see it.<br />
<br />
There are two critical aspects to style:<br />
(1) coding style for compilers (will the compiler generate the code you're expecting)<br />
(2) coding style for humans (can a human read the code)<br />
<div>
<br /></div>
A good static analysis tool is good at #1. Should you run a static analysis tool? Absolutely. Pick a good tool. Or at least do better than -Wall for Gcc (hint, "all" doesn't mean what you think it means (*see note below)). When your code compiles clean with all relevant warnings turned on, only then is it time for a human peer review.<br />
<br />
For #2, capabilities vary widely, and no automated tool can evaluate many aspects of good human-centric coding style. (Can they use heuristics to help with #1? Sure. Can they replace a human? Not anytime soon.)<br />
<br />
My peer review checklist template has a number of items that fall into the #1 bin. The reason is that it is common for embedded software teams to not use static analysis at all, or to use inadequate settings. So the basics are there. As they become more sophisticated at static analysis, they should delete the automated checks (subsuming them into item #0 -- has static analysis been done?). Then they should add additional items they've found from experience are relevant to them to re-fill the list to a couple dozen total items.<br />
<br />
Summarizing: static analysis tools don't automate peer reviews. They automate a useful piece of them if you are warning-free, but they are no substitute for human judgement about whether your code is understandable and likely to meet its requirements.<br />
<br />
<b>Pointers:</b><br />
<ul>
<li><a href="https://www.youtube.com/watch?v=YfbsLC1dsjA&list=PL_DQiOR0jhbX3wvzTSOANTccOrX7LEEHe">Coding style for Compilers</a> </li>
<li><a href="https://www.youtube.com/watch?v=26AU7Ks0JOI&list=PL_DQiOR0jhbUo3xlzID2xFKJ7-waHbIcE">Coding style for Humans</a></li>
<li><a href="https://www.youtube.com/watch?v=WxHZ7fNZpg4&list=PL_DQiOR0jhbVIaShDvI4ePNefLFXBF1lT">Peer review tutorial</a></li>
<li><a href="https://betterembsw.blogspot.com/2018/01/new-peer-review-checklist-for-embedded.html">Peer review checklist template</a></li>
</ul>
<div>
<b>* Note:</b> in teaching I require these gcc flags for student projects:<br />
<span style="font-family: monospace;">-Werror -Wextra -Wall -Wfloat-equal -Wconversion -Wparentheses -pedantic -Wunused-parameter -Wunused-variable -Wreturn-type -Wunused-function -Wredundant-decls -Wreturn-type -Wunused-value -Wswitch-default -Wuninitialized -Winit-self</span></div>
<br />
<br />
<br />
<br />
<br />
<br />Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-81075343403481840142019-01-04T19:15:00.000-05:002019-01-04T19:19:48.246-05:00Counter Rollover Brings Down Rail Service<div class="tr_bq">
In October 2018 Hong Kong had "six hours of turmoil" in their rail service due to as signalling outage. The culprit has now been identified as counter roll-over.</div>
<div class="tr_bq">
<a href="https://www.scmp.com/news/hong-kong/transport/article/2178723/unknown-signalling-system-incompatibility-caused-october">https://www.scmp.com/news/hong-kong/transport/article/2178723/unknown-signalling-system-incompatibility-caused-october</a></div>
<div class="tr_bq">
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn7mFv7VGqHWtS9aRGtLIpAjikkgOmtazZyTaR8aqqKxr5ZfAhe2qgeW82oUOyb4yETE6-w2c8Bx2MZ0BC1MI08X5AP9RgHD_4uvgEujDkEuOlyL2YgafNjPrviQ2i7Ca_ti3XiNZYSBU/s1600/Capture.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="554" data-original-width="993" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn7mFv7VGqHWtS9aRGtLIpAjikkgOmtazZyTaR8aqqKxr5ZfAhe2qgeW82oUOyb4yETE6-w2c8Bx2MZ0BC1MI08X5AP9RgHD_4uvgEujDkEuOlyL2YgafNjPrviQ2i7Ca_ti3XiNZYSBU/s320/Capture.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">South China Morning Post<br />
<span style="font-size: 12.8px;">https://www.scmp.com/news/hong-kong/transport/article/2178723/unknown-signalling-system-incompatibility-caused-october</span></td></tr>
</tbody></table>
<br />
<b><u>Summary version:</u></b> a system synchronization counter had been counting away since 1996 and required a system reset when it saturated. (At least it didn't just roll over without anything noticing.) But over the years two different systems with slightly different counter roll-over procedures were installed. When rollover time came, they disagreed with each other on count value, paralyzing the system during the window until the second system shut down due to counter saturation. Details below quoted from the official report. (<a href="https://www.mtr.com.hk/archive/corporate/en/press_release/PR-18-108-E.pdf">https://www.mtr.com.hk/archive/corporate/en/press_release/PR-18-108-E.pdf</a>)</div>
<br />
<u><b>The Detailed version:</b></u><br />
<blockquote>
"5.1.3. Data transmission between sector computers is always
synchronized through an internal software counter in each sector
computer. If any individual sector computer is individually
rebooted, its counter will be re-initialized and will immediately
synchronize to the higher counter figure for the whole
synchronized network. Therefore, when the Siemens sector
computers were commissioned and put into service in
2001/2002, the relevant counters were synchronized to those of
the Alstom sector computers which were installed in 1996. <b><u>If the
counter reaches its ceiling figure, the associated sector
computer will halt and need to be re-initialized</u></b>. However the
counter re-initialization arrangements for the two suppliers’
sector computers are different. The Alstom sector computers will
be re-initialized automatically once their counters reach an inbuilt re-initialization triggering point approximately 5 hours before
reaching the ceiling figure. However, this internal software
function was not made known to the operators and maintainers.
The Siemens sector computers do not have an automatic reinitialization function and therefore need to be manually reinitialized through rebooting in SER by maintenance staff. </blockquote>
<blockquote>
5.1.4 At around 05:26 hours on the incident day, the <b><u>Alstom software
counters reached the triggering point for automatic re-
initialization while the Siemens sector computers continued
counting up</u></b>, creating an inconsistent re-initialization situation
between the two interconnected sector computers at KWT
(Alstom) and LAT (Siemens). This resulted in repeated
execution of re-initialization followed by re-synchronization with
the higher counter figure from LAT, in the KWT sector <u><b>computer
in an endless loop causing corresponding instability</b></u> in all 25
Alstom sector computers in the system. </blockquote>
<blockquote>
5.1.5 When all the Siemens software counters reached the ceiling
figure at around 10:22 hours, some 5 hours after the Alstom
sector computers had passed their automatic re-initialization
triggering point, <u><b>the 8 Siemens sector computers halted as
designed</b></u>. Moreover, trains on the TKL had already encountered
trainborne signalling failure earlier at 10:02 hours due to the
around 20 minutes counter look ahead validity requirements. </blockquote>
<blockquote>
5.1.6 After the interconnections between the signalling systems of the
relevant lines and the Alstom and Siemens sector computers
between KWT and LAT were isolated,<b><u> all sector computers were
effectively rebooted to complete the entire re-initialization
process and the signalling system for the four incident lines
resumed normal. "</u></b></blockquote>
With credit for calling my attention to the report to:<br />
Date: Sun, 30 Dec 2018 15:39:37 +0800<br />
<pre class="moz-quote-pre" wrap="">From: Richard Stein <a class="moz-txt-link-rfc2396E" href="mailto:rmstein@ieee.org"><rmstein ieee.org=""></rmstein></a>
Subject: Re: MTR East Rail disruption caused by failure of both primary </pre>
and backup (Stein, RISKS-30.89)<br />
<br />Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-26550856673645487882019-01-03T09:15:00.000-05:002019-01-03T09:15:06.843-05:00Sometimes Bug Severity Isn't the Most Important ThingGenerally you need to take into account both the consequence of a software defect as well as how often it occurs when doing bug triage. (See: <a href="https://betterembsw.blogspot.com/2011/03/using-risk-analysis-table-to-categorize.html">Using a Risk Analysis Table to Categorize Bug Priority</a>)<br />
<br />
But an important special case is one in which the consequence is a business consequence such as brand tarnish rather than a spectacular software crash. I used to use a hypothetical example of the audience's company name being misspelled on the system display to illustrate the point. Well, it's not hypothetical any more!<br />
<br />
Lamborghini sells a quarter-million dollar SUV with numerous software defects, including spelling the company name as "Lanborghini" Guess which defect gets the press?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM7sp9d6TjoVkxqbtce8Lwgv31b_ZyEtzwxnfSTQ6tgGXCVuu9xGYoxKhODpveO2IZB_p8R9BilmpZfleRrnAf1QVJdLR45QUvUzTFS_e7IA4YEH_dBk2gP-laJnVmiHOEzVPtGvPg0fM/s1600/Capture.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="834" data-original-width="1254" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM7sp9d6TjoVkxqbtce8Lwgv31b_ZyEtzwxnfSTQ6tgGXCVuu9xGYoxKhODpveO2IZB_p8R9BilmpZfleRrnAf1QVJdLR45QUvUzTFS_e7IA4YEH_dBk2gP-laJnVmiHOEzVPtGvPg0fM/s320/Capture.JPG" width="320" /></a></div>
<div style="text-align: center;">
<a href="https://carbuzz.com/news/lamborghini-urus-experiencing-major-software-bugs">https://carbuzz.com/news/lamborghini-urus-experiencing-major-software-bugs</a></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: left;">
And it turns out that a software update not only didn't solve the typo, but also broke a bunch more functionality. </div>
Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-63041030974336559062018-10-02T04:00:00.000-04:002018-10-02T10:40:30.208-04:00Cost of highly safety critical softwareIt's always interesting to see data on industry software costs. I recently came across a report on software costs for the aviation industry. The context was flight-critical radio communications, but the safety standards discussed were DO-178B and DO-254, which apply to flight controls as well.<br />
<br />
Here's the most interesting picture from the report for my purposes:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvSC-6yO6tAShM3aaDPLDLAxspCLLR2Hu0zALEkov35PXaAVlxKp3gtIWrB5sPV7ZqOCYIGaC1h3_rEF9hKiYAeZexMuXC2ITKpIHxGFIPHrklPthx5_1PAp27cwIxNwJZK2rRw5Dc7fE/s1600/sloc_for_DAL.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="428" data-original-width="697" height="245" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvSC-6yO6tAShM3aaDPLDLAxspCLLR2Hu0zALEkov35PXaAVlxKp3gtIWrB5sPV7ZqOCYIGaC1h3_rEF9hKiYAeZexMuXC2ITKpIHxGFIPHrklPthx5_1PAp27cwIxNwJZK2rRw5Dc7fE/s400/sloc_for_DAL.gif" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
(Source: Page 28 <a href="https://www.eurocontrol.int/sites/default/files/content/documents/communications/29012009-certification-cost-estimation-for-fci-platform.pdf.pdf">https://www.eurocontrol.int/sites/default/files/content/documents/communications/29012009-certification-cost-estimation-for-fci-platform.pdf.pdf</a> )<br />
<br />
Translating from <a href="https://en.wikipedia.org/wiki/DO-178B">DO-178B</a> terminology, this means:<br />
<br />
<ul>
<li>DAL A (failure would be "catastrophic"): 3 - 12 SLOC/day</li>
<li>DAL B (failure would be "hazardous"): 8 - 20 SLOC/day</li>
<li>DAL C (failure would be "major"): 15 - 40 SLOC/day</li>
<li>DAL D (failure would be "minor"): 25 - 64 SLOC/day</li>
</ul>
<div>
Worth noting is that, in my experience, really solid mission critical but NOT life-critical embedded <a href="https://betterembsw.blogspot.com/2010/05/only-10-lines-of-code-per-day-really.html">software can be done at up to 16 SLOC per day</a> for well-run experienced teams, so it tends to line up with DAL B costs.</div>
<br />
<br />
For interpretation, "DAL" expresses a criticality level (a "Development Assurance Level"), with more critical software requiring more rigorous processes. The document has quite a lot to say about how the engineering process works, and is worth a read if you want to see how the aviation folks do business. (I'm aware that DO-178C is out, but this paper talks about the older "B" version.) Note that there are other cost models in the paper that are less pessimistic in that report, but this is the one that says "industry experience."<br />
<br />
Have you found other cost of software data for embedded or mission critical systems?Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com2tag:blogger.com,1999:blog-4172950626830217643.post-61900596009913256002018-09-25T08:17:00.046-04:002021-04-24T17:37:54.241-04:00Potentially deadly automotive software defects<div><b>Page moved here:</b></div><div><b><br /></b></div><div><b><a href="https://betterembsw.blogspot.com/p/potentially-deadly-automotive-software.html">https://betterembsw.blogspot.com/p/potentially-deadly-automotive-software.html</a></b></div>Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com4tag:blogger.com,1999:blog-4172950626830217643.post-62920095121963114172018-09-08T17:28:00.000-04:002018-09-08T17:39:01.402-04:00Different types of risk analysis: ALARP, GAMAB, MEMS and moreWhen we talk about how much risk is enough, it is common to do things like compare the risk to current systems, or argue about whether something is more (or less) likely than events such as being killed by lightning. There are established ways to think about this topic, each with tradeoffs.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNFPpkNhKJ4wPcwwQMRDCgnBBz9fy95R2tge2C66rmHONYYWKoqyEQ3WFU_WssDWwt0skkhCzxgEh0BW7fN1elUNWYxKzLdVZmBCsMwNCE63OJ59XHiQ2SZVrga1iPsw81I78TpX-thzs/s1600/Capture.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Tightrope Walker" border="0" data-original-height="552" data-original-width="1113" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNFPpkNhKJ4wPcwwQMRDCgnBBz9fy95R2tge2C66rmHONYYWKoqyEQ3WFU_WssDWwt0skkhCzxgEh0BW7fN1elUNWYxKzLdVZmBCsMwNCE63OJ59XHiQ2SZVrga1iPsw81I78TpX-thzs/s400/Capture.JPG" title="https://pixabay.com/en/waters-movement-river-action-human-3158413/" width="400" /></a></div>
<br />
<br />
The next time you need to think about how much risk is appropriate in a safety-critical system, try these existing approaches on for size instead of making up something on your own:<br />
<br />
<b>ALARP</b>: "As Low As Reasonably Practicable" Some risks are acceptable. Some are unacceptable. Some are worth taking in exchange for benefit, but if that is done the risk must be reduced to be ALARP.<br />
<br />
<b>GAMAB</b>: "Globalement Au Moins Aussi Bon" Offer a level of risk at least as good as the risk offered by an equivalent existing system. (i.e., no more dangerous than what we have already for a similar function)<br />
<br />
<b>MEM</b>: "Minimum Endogenous Mortality" The technical system must not create a significant risk compared to globally existing risks. For example, this should cause a minimal increase in overall death rates compared to the existing population death rates.<br />
<br />
<b>MGS</b>: "Mindestens Gleiche Sicherheit" (At least the same level of safety) Deviations from accepted practices must be supported by an explicit safety argument showing at least the same level of safety. This is more about waivers than whole-system evaluation.<br />
<br />
<b>NMAU</b>: "Nicht Mehr Als Unvermeidbar" (Not more than unavoidable) Assuming there is a public benefit to the operation of the system, hazards should be avoided by reasonable safety measures implemented with reasonable cost.<br />
<br />
Each of these approaches has pros and cons. The above terms were paraphrased from this nice discussion:<br />
<i>Kron, On the evaluation of risk acceptance principles,</i><br />
<a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.455.4506&rep=rep1&type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.455.4506&rep=rep1&type=pdf</a><br />
<br />
There is an interesting set of slides that covers similar ground here, and works some examples. In particular the graphs involving whether risks are taken voluntarily for different scenarios is thought provoking:<br />
<a href="http://agse3.informatik.uni-kl.de/teaching/suze/ws2014/material/folien/SRES_03_Risk_Acceptance.pdf">http://agse3.informatik.uni-kl.de/teaching/suze/ws2014/material/folien/SRES_03_Risk_Acceptance.pdf</a><br />
<br />
In general, if you want to dig deeper into this area, a search on<br />
<a href="https://www.google.com/search?q=gamab+mem+alarp">gamab mem alarp </a><br />
will bring up a number of hits<br />
<br />
Also note that legal and other types of considerations exist, especially regarding <a href="https://en.wikipedia.org/wiki/Product_liability">product liability</a>.Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-74590743898232614642018-07-14T11:09:00.000-04:002018-07-14T11:09:03.597-04:00Activity on my Safe Autonomy BlogFor those who might have missed it, most of my recent blogging has been on my Safe Autonomy Blog: <a href="https://safeautonomy.blogspot.com/">https://safeautonomy.blogspot.com</a><br />
<br />
Recent post topics include slides and paper preprints such as:<br />
<br />
<ul>
<li><a href="https://safeautonomy.blogspot.com/2018/07/robustness-testing-of-autonomy-software.html">Robustness Testing of Autonomy Software (ICSE 2018)</a></li>
<li><a href="https://safeautonomy.blogspot.com/2018/06/safety-validation-and-edge-case-testing.html">Safety Validation and Edge Case Testing for Autonomous Vehicles </a></li>
<li><a href="https://safeautonomy.blogspot.com/2018/06/heavy-tail-ceiling-problem-for-av.html">Heavy Tail Ceiling Problem for AV Testing</a></li>
<li><a href="https://safeautonomy.blogspot.com/2018/04/saewc18.html">Toward a framework for Highly Automated Vehicle Safety Validation</a></li>
</ul>
<br />
<br />Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-32406752922023433182018-03-12T07:00:00.000-04:002018-11-26T14:50:03.332-05:00Embedded Code Quality and Best Practices Training Videos full lengthI've posted the full series of my available embedded system code quality and related best practices videos on YouTube. These are full-length narrated slides of the core set of safety topics from my new course. They concentrate on getting the big picture about code quality and good programming practices.<br />
<ul>
<li><a href="https://www.youtube.com/watch?v=y46uBqqkBrU&list=PL_DQiOR0jhbXFZtjw6U-19X0jPDmg4UoR">Code Quality, Safety, Security overview</a></li>
<li><a href="https://www.youtube.com/watch?v=Ov2QilGv32Y&list=PL_DQiOR0jhbU_vrNhdAfe3KWPiiX38VLZ">Global Variables</a></li>
<li><a href="https://www.youtube.com/watch?v=k7O2IHH7aC8&list=PL_DQiOR0jhbWYXOWeSCQmb45B6iOH8d_k">Spaghetti Code</a></li>
<li><a href="https://www.youtube.com/watch?v=75qaEZBMu_M&list=PL_DQiOR0jhbUo3xlzID2xFKJ7-waHbIcE">Coding Style for Humans</a> </li>
<li><a href="https://www.youtube.com/watch?v=LCsWtXHq8uw&list=PL_DQiOR0jhbX3wvzTSOANTccOrX7LEEHe">Coding Style for Compilers/Language Use</a></li>
<li><a href="https://www.youtube.com/watch?v=1elELAUaEPY&list=PL_DQiOR0jhbV1jmwwclkJhxKf0-0yyxtg">Stack Overflow</a> </li>
<li><a href="https://www.youtube.com/watch?v=rIo9_0_76i8&list=PL_DQiOR0jhbVIaShDvI4ePNefLFXBF1lT">Peer Reviews</a> </li>
<li><a href="https://www.youtube.com/watch?v=GZGfarywnP0&list=PL_DQiOR0jhbUF9uJ1sugBUDaU8VXg4NKo">Key Software Process metrics</a> </li>
</ul>
Each of the videos is posted to YouTube as a playlist, with each video covering a slide or two. The full lecture consists of playing the entire play list, with most lectures being 5-7 videos in sequence. (The slide download has been updated for my CMU grad course, so in general has a little more material than the original video. They'll get synchronized eventually, but for now this is what I have.)<br />
<br />
Obviously there is more to code quality and safety than just these topics. Additional topics are available slides-only. You can see the full set of course slides including for those lectures and others here:<br />
<a href="https://users.ece.cmu.edu/~koopman/lectures/index.html#642">https://users.ece.cmu.edu/~koopman/lectures/index.html#642</a>Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com2tag:blogger.com,1999:blog-4172950626830217643.post-79127745784131527562018-02-25T00:20:00.002-05:002018-02-25T00:20:59.493-05:00New Blog on Self-Driving Car SafetyI'm doing a lot more work on self-driving car (autonomous vehicle) safety, so I've decided to split my blogging for that activity. I'll still post more general embedded system topics here, perhaps with reduced frequency.<br />
<br />
You can see my new blog on self-driving car safety here:<br /> <a href="https://safeautonomy.blogspot.com/">https://safeautonomy.blogspot.com</a><br />
<br />
Just to keep perspective, self-driving cars are still very complex embedded systems. You need to get the basics right (this blog) if you want them to be safe!Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-9998695830438515112018-02-16T07:00:00.000-05:002018-02-16T07:00:11.787-05:00Robustness Testing of Autonomy Software (ASTAA Paper Published)I'm very pleased that our research team will present a paper on Robustness Testing of Autonomy Software at the ICSE Software Engineering in Practice session in a late May. You can see a preprint of the paper here: <span style="color: #444444; font-family: Roboto, Helvetica, Arial, sans-serif; font-size: 13px;"><a href="https://goo.gl/Pkqxy6">https://goo.gl/Pkqxy6</a></span><br />
<br />
The work summarizes what we've learned across several years of research stress testing many robots, including self-driving cars.<br />
<br />
<div style="text-align: center;">
<b>ABSTRACT</b></div>
As robotic and autonomy systems become progressively more present in industrial and human-interactive applications, it is increasingly critical for them to behave safely in the presence of unexpected inputs. While robustness testing for traditional software systems is long-studied, robustness testing for autonomy systems is relatively uncharted territory. In our role as engineers, testers, and researchers we have observed that autonomy systems are importantly different from traditional systems, requiring novel approaches to effectively test them. We present Automated Stress Testing for Autonomy Architectures (ASTAA), a system that effectively, automatically robustness tests autonomy systems by building on classic principles, with important innovations to support this new domain. Over five years, we have used ASTAA to test 17 real-world autonomy systems, robots, and robotics-oriented libraries, across commercial and academic applications, discovering hundreds of bugs. We outline the ASTAA approach and analyze more than 150 bugs we found in real systems. We discuss what we discovered about testing autonomy systems, specifically focusing on how doing so differs from and is similar to traditional software robustness testing and other high-level lessons.<br />
<br />
Authors:<br />Casidhe Hutchison<br />Milda Zizyte<br />Patrick Lanigan<br />David Guttendorf<br />
Mike Wagner<br />
Claire Le Guoes<br />Philip Koopman<br />
<br />
<br />Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0tag:blogger.com,1999:blog-4172950626830217643.post-87304906445767005432018-01-29T21:03:00.000-05:002018-01-29T21:03:42.750-05:00New Peer Review Checklist for Embedded C CodeHere's a new peer review checklist to help improve the quality of your embedded C code.<br />
<br />
To use the checklist, you should do a sit-down meeting with, ideally, three reviewers not including the code author. Divide the checklist up into three portions as indicated. Be sure to run decent static analysis before the review to safe reviewer time -- let the tools find the easy stuff before spending human time on the review.<br />
<br />
After an initial orientation to what the code is supposed to do and relevant background, the review process is:<br />
<ol>
<li>The review leader picks the next few lines of code to be reviewed and makes sure everyone is ONLY focused on those few lines. Usually this is 5-10 lines encompassing a conditional structure, a basic block, or other generally unified small chunk within the code.</li>
<li>Reviewers identify any code problems relevant to their part of the checklist. It's OK if they notice others, but they should focus on individually considering each item in their part of the checklist and ask "do I see a violation of this item" in just the small chunk of code being considered.</li>
<li>Reviewer comments should be recorded in the form: "Line X seems to violate Checklist Item Y for the following reason." Do NOT suggest a fix -- just record the issue.</li>
<li>When all comments have been recorded, go back to step 1. Continue to review up to a maximum of 2 hours. You should be covering about 100-200 lines of code per hour. Too fast and too slow are both a problem.</li>
</ol>
<div>
A text version of the checklist is below. You can also download an <a href="http://users.ece.cmu.edu/~koopman/lectures/ece642/peer_review_checklist.pdf">acrobat version here</a>. Additional pointers to support materials are after the checklist. If you have a static analysis tool that automates any of the checklist item, feel free to replace that item with something else that's important to you.</div>
<br />
===============================================================<br />
<b>Peer Review Checklist: Embedded C Code</b><br />
<br />
<u>
Before Review:</u><br />
0 _____ Code compiles clean with extensive warning checks
(e.g. MISRA C rules)<br />
<br />
<u>
Reviewer #1:</u> <br />
1 _____ Commenting: top of file, start of function, code
that needs an explanation<br />
2 _____ Style is consistent and follows style guidelines<br />
3 _____ Proper modularity, module size, use of .h files and
#includes<br />
4 _____ No orphans (redundant, dead, commented out, unused
code & variables)<br />
5 _____ Conditional expressions evaluate to a boolean value;
no assignments<br />
6 _____ Parentheses used to avoid operator precedence
confusion<br />
7 _____ All switch statements have a default clause;
preferably an error trap<br />
<br />
<u>
Reviewer #2:</u> <br />
8 _____ Single point of exit from each function<br />
9 _____ Loop entry and exit conditions correct; minimum
continue/break complexity<br />
10 _____ Conditionals should be minimally nested (generally
only one or two deep)<br />
11 _____ All functions can be unit tested; SCC or SF
complexity less than 10 to 15<br />
12 _____ Use const and inline instead of #define; minimize
conditional compilation<br />
13 _____ Avoid use of magic numbers (constant values
embedded in code)<br />
14 _____ Use strong typing (includes: sized types, structs
for coupled data, const)<br />
15 _____ Variables have well chosen names and are
initialized at definition<br />
<br />
<u>
Reviewer #3:</u> <br />
16 _____ Minimum scope for all functions and variables;
essentially no globals<br />
17 _____ Concurrency issues? (locking, volatile keyword,
minimize blocking time)<br />
18 _____ Input parameter checking is done (style,
completeness)<br />
19 _____ Error handling for function returns is appropriate<br />
20 _____ Null pointers, division by zero, null strings,
boundary conditions handled<br />
21 _____ Floating point use is OK (equality, NaN, INF,
roundoff); use of fixed point<br />
22 _____ Buffer overflow safety (bound checking, avoid
unsafe string operations)<br />
<br />
<u>
All Reviewers:</u> <br />
23 _____ Does the code match the detailed design (correct
functionality)?<br />
24 _____ Is the code as simple, obvious, and easy to review
as possible?<br />
<br />
For TWO Reviewers assign items: Reviewer#1: 1-11;
23-24 Reviewer#2: 12-24<br />
Items that are covered with static analysis can be removed
from checklist<br />
Template 1/28/2018: Copyright <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>, 2018, Philip Koopman<br />
===============================================================<br />
<br />
Additional material to help you with successful peer reviews:<br />
<br />
<ul>
<li>A <a href="http://users.ece.cmu.edu/~koopman/lectures/ece642/09_peerreview.pdf">slide set about peer reviews</a> </li>
<li>A video tutorial on peer reviews: <a href="https://www.youtube.com/watch?v=rIo9_0_76i8&list=PL_DQiOR0jhbVIaShDvI4ePNefLFXBF1lT">YouTube</a></li>
<li>Peer review reporting spreadsheet <a href="https://betterembsw.blogspot.com/2013/08/peer-review-spreadsheet.html">blog post</a></li>
<li>Other ideas for adding to the peer review checklist are <a href="https://betterembsw.blogspot.com/2016/05/top-5-embedded-software-problem-areas.html">at this blog entry</a>. It's important to keep the checklist brief, so pick your battles and keep the items high level.</li>
<li><a href="https://betterembsw.blogspot.com/2017/08/the-spaghetti-factor-software.html">SF complexity metric blog post</a></li>
<li>Peer reviews and the <a href="https://betterembsw.blogspot.com/2011/01/peer-reviews-and-5050-rule.html">50/50 rule blog post</a></li>
</ul>
<div>
<br /></div>
Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com3tag:blogger.com,1999:blog-4172950626830217643.post-85169120798178499782017-11-27T07:00:00.000-05:002018-08-31T20:38:30.071-04:00Embedded Software Course Notes On-LineI'm just wrapping up my first semester teaching a new course on embedded system software. It covers code quality, safety, and security. Below is table of lecture handouts.<br />
<br />
NOTE: there is an update here:<br /> <a href="https://users.ece.cmu.edu/~koopman/lectures/index.html#642">https://users.ece.cmu.edu/~koopman/lectures/index.html#642</a><br />which includes newer course notes and quite a few YouTube videos of these lectures.<br />You should use that URL instead of this blog post, but I've left this post as-is for Fall 2017.<br />
<br />
<b>18-642 Embedded System Software Engineering</b><br />
Prof. Philip Koopman, Carnegie Mellon University, Fall 2017<br />
<br />
<div>
<br />
<table bgcolor="#f8f8f8" border="0" cellpadding="5" style="color: black;"><tbody>
<tr><td width="5%"></td><td align="CENTER" width="15%"><u><b>Slides</b></u></td><td><u><b>Topics</b></u></td></tr>
<tr><td>1</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/01_intro.pdf">Course Introduction</a></td><td>Software is eating the world; embedded applications and markets; bad code is a problem; coding is 0% of software; truths and management misconceptions</td></tr>
<tr><td>2</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/04_software_process.pdf">Software Development Processes</a></td><td>Waterfall; swiss cheese model; lessons learned in software; V model; design vs. code; agile methods; agile for embedded</td></tr>
<tr><td>3</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/05_globalvariables.pdf">Global Variables</a></td><td>Global vs. static variables; avoiding and removing globals</td></tr>
<tr><td>4</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/06_spaghettiocode.pdf">Spaghetti Code</a></td><td>McCabe Cyclomatic Complexity (MCC); SCC; Spaghetti Factor (SF)</td></tr>
<tr><td>5</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/07_unittest.pdf">Unit Testing</a></td><td>Black box testing; white box testing; unit testing strategies; MCDC coverage; unit testing frameworks (cunit)</td></tr>
<tr><td>6</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/08_modalstatechart.pdf">Modal Code/Statecharts</a></td><td>Statechart elements; statechart example; statechart implementation</td></tr>
<tr><td>7</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/09_peerreview.pdf">Peer Reviews</a></td><td>Effective code quality practices, peer review efficiency and effectiveness; Fagan inspections; rules for peer review; review report; perspective-based reviews; review checklist; case study; economics of peer review</td></tr>
<tr><td>8</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/10_codestylehumans.pdf">Code Style/Humans</a></td><td>Making code easy to read; good code hygiene; avoiding premature optimization; coding style</td></tr>
<tr><td>9</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/11_codestylelanguage.pdf">Code Style/Language</a></td><td>Pitfalls and problems with C; language use guidelines and analysis tools; using language wisely (strong typing); Mars Climate Orbiter; deviations & legacy code</td></tr>
<tr><td>10</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/12_testingquality.pdf">Testing Quality</a></td><td>Smoke testing, exploratory testing; methodical test coverage; types of testing; testing philosophy; coverage; testing resources</td></tr>
<tr><td>11</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/13_requirements.pdf">Requirements</a></td><td>Ariane 5 flight 501; rules for good requirements; problematic requirements; extra-functional requirements; requirements approaches; ambiguity</td></tr>
<tr><td>12</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/14_systemtest.pdf">System-Level Test</a></td><td>First bug story; effective test plans; testing won't find all bugs; F-22 Raptor date line bug; bug farms; risks of bad software</td></tr>
<tr><td>13</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/15_sw_architecture.pdf">SW Architecture</a></td><td>High Level Design (HLD); boxes and arrows; sequence diagrams (SD); statechart to SD relationship; 2011 Health Plan chart</td></tr>
<tr><td>14</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/16_integration_test.pdf">Integration Testing</a></td><td>Integration test approaches; tracing integration tests to SDs; network message testing; using SDs to generate unit tests</td></tr>
<tr><td>15</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/17_traceability.pdf">Traceability</a></td><td>Traceability across the V; examples; best practices</td></tr>
<tr><td>16</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/18_sqa.pdf">SQA isn't testing</a></td><td>SQA elements; audits; SQA as coaching staff; cost of defect fixes over project cycle</td></tr>
<tr><td>17</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/19_lifecycle.pdf">Lifecycle CM</a></td><td>A400M crash; version control; configuration management; long lifecycles</td></tr>
<tr><td>18</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/20_maintenance.pdf">Maintenance</a></td><td>Bug fix cycle; bug prioritization; maintenance as a large cost driver; technical debt</td></tr>
<tr><td>19</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/21_metrics.pdf">Process Key Metrics</a></td><td>Tester to developer ratio; code productivity; peer review effectiveness</td></tr>
<tr><td>33</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/34_datetime.pdf">Date Time Management</a></td><td>Keeping time; time terminology; clock synchronization; time zones; DST; local time; sunrise/sunset; mobility and time; date line; GMT/UTC; leap years; leap seconds; time rollovers; Zune leap year bug; internationalization.</td></tr>
<tr><td>21</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/23_floatingpoint.pdf">Floating Point Pitfalls</a></td><td>Floating point formats; special values; NaN and robots; roundoff errors; Patriot Missile mishap</td></tr>
<tr><td>23</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/25_stackoverflow.pdf">Stack Overflow</a></td><td>Stack overflow mechanics; memory corruption; stack sentinels; static analysis; memory protection; avoid recursion</td></tr>
<tr><td>25</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/27_raceconditions.pdf">Race Conditions</a></td><td>Therac 25; race condition example; disabling interrupts; mutex; blocking time; priority inversion; priority inheritance; Mars Pathfinder</td></tr>
<tr><td>27</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/29_dataintegrity.pdf">Data Integrity</a></td><td>Sources of faults; soft errors; Hamming distance; parity; mirroring; SECDED; checksum; CRC</td></tr>
<tr><td>20</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/22_safetysecurityoverview.pdf">Safety+Security Overview</a></td><td>Challenges of embedded code; it only takes one line of bad code; problems with large scale production; your products live or die by their software; considering the worst case; designing for safety; security matters; industrial controls as targets; designing for security; testing isn't enough<br />
Fiat Chrysler jeep hack; Ford Mytouch update; Toyota UA code quality; Heartbleed; Nest thermostats; Honda UA recall; Samsung keyboard bug; hospital infusion pumps; LIFX smart lightbulbs; German steel mill hack; Ukraine power hack; SCADA attack data; Shodan; traffic light control vulnerability; hydroelectric plant vulnerability; zero-day shopping list</td></tr>
<tr><td>22</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/24_dependability.pdf">Dependability</a></td><td>Dependability; availability; Windows 2000 server crash; reliability; serial and parallel reliability; example reliability calculation; other aspects of dependability</td></tr>
<tr><td>24</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/26_criticalsystems.pdf">Critical Systems</a></td><td>Safety critical vs. mission critical; worst case and safety; HVAC malfunction hazard; Safety Integrity Levels (SIL); Bhopal; IEC 61508; fleet exposure</td></tr>
<tr><td>26</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/28_safetyplan.pdf">Safety Plan</a></td><td>Safety plan elements; functional safety approaches; hazards & risks; safety goals & safety requirements; FMEA; FTA; safety case (GSN)</td></tr>
<tr><td>28</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/30_safetyrequirements.pdf">Safety Requirements</a></td><td>Identifying safety-related requirements; safety envelope; Doer/Checker pattern</td></tr>
<tr><td>29</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/31_singlepointfailures.pdf">Single Points of Failure</a></td><td>Fault containment regions (FCR); Toyota UA single point failure; multi-channel pattern; monitor pattern; safety gate pattern; correlated & accumulated faults</td></tr>
<tr><td>30</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/32_safetycriticalisolation.pdf">SIL Isolation</a></td><td>Isolating different SILs, mixed-SIL interference sources; mitigating cross-SIL interference; isolation and security; CarShark hack</td></tr>
<tr><td>31</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/33_redundancymanagement.pdf">Redundancy Management</a></td><td>Bellingham WA gasoline pipeline mishap; redundancy for availability; redundancy for fault detection; Ariane 5 Flight 501; fail operational; triplex modular redundancy (TMR) 2-of-3 pattern; dual 2-of-2 pattern; high-SIL Doer/Checker pattern; diagnostic effectiveness and proof tests</td></tr>
<tr><td>32</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/42_safetyarchpatterns.pdf">Safety Architecture Patterns</a></td><td>Supplemental lecture with more detail on patterns: low SIL; self-diagnosis; partitioning; fail operational; voting; fail silent; dual 2-of-2; Ariane 5 Flight 501; fail silent patterns (low, high, mixed SIL); high availability mixed SIL pattern</td></tr>
<tr><td>34</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/35_securityplan.pdf">Security Plan</a></td><td>Security plan elements; Target Attack; security requirements; threats; vulnerabilities; mitigation; validation</td></tr>
<tr><td>35</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/36_cryptography.pdf">Cryptography</a></td><td>Confusion & diffusion; Caesar cipher; frequency analysis; Enigma; Lorenz & Colossus; DES; AES; public key cryptography; secure hashing; digital signatures; certificates; PKI; encrypting vs. signing for firmware update</td></tr>
<tr><td>36</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/38_securitythreats.pdf">Security Threats</a></td><td>Stuxnet; attack motivation; attacker threat levels; DirectTV piracy; operational environment; porous firewalls; Davis Besse incident; BlueSniper rifle; integrity; authentication; secrecy; privacy; LG Smart TV privacy; DoS/DDos; feature activation; St. Jude pacemaker recall</td></tr>
<tr><td>37</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/39_securityvulnerabilities.pdf">Security Vulnerabilities</a></td><td>Exploit vs. attack; Kettle spambot; weak passwords; master passwords; crypto key length; Mirai botnet attack; crypto mistakes; LIFX revisited; CarShark revisited; chip peels; hidden functionality; counterfeit systems; cloud connected devices; embedded-specific attacks</td></tr>
<tr><td>38</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/40_securitymitigationvalidation.pdf">Security Mitigation Validation</a></td><td>Password strength; storing passwords & salt/pepper/key stretching; Adobe password hack; least privilege; Jeep firewall hack; secure update; secure boot; encryption vs. signing revisited; penetration testing; code analysis; other security approaches; rubber hose attack</td></tr>
<tr><td>39</td><td><a href="https://users.ece.cmu.edu/~koopman/lectures/ece642/41_securitypitfalls.pdf">Security Pitfalls</a></td><td>Konami code; security via obscurity; hotel lock USB hack; Kerckhoff's principle; hospital WPA setup hack; DECSS; Lodz tram attack; proper use of cryptography; zero day exploits; security snake oil; realities of in-system firewalls; aircraft infotainment and firewalls; zombie road sign hack</td></tr>
</tbody></table>
<br />
Note that in Spring 2018 these are likely to be updated, so if want to see the latest also check the main course page: <a href="https://www.ece.cmu.edu/~ece642/">https://www.ece.cmu.edu/~ece642/</a> For other lectures and copyright notes, please see my general lecture notes & video page: <a href="https://users.ece.cmu.edu/~koopman/lectures/index.html">https://users.ece.cmu.edu/~koopman/lectures/index.html</a><br />
<div>
<br /></div>
<div>
<br /></div>
</div>
Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com7tag:blogger.com,1999:blog-4172950626830217643.post-42812804798875069482017-11-17T15:50:00.000-05:002017-11-17T15:50:16.671-05:00Highly Autonomous Vehicle ValidationHere are the slides from my TechAD talk today.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="485" marginheight="0" marginwidth="0" scrolling="no" src="//www.slideshare.net/slideshow/embed_code/key/Hbptf1JLfP4eB" style="border-width: 1px; border: 1px solid #ccc; margin-bottom: 5px; max-width: 100%;" width="595"> </iframe> <br />
<div style="margin-bottom: 5px;">
<strong> <a href="https://www.slideshare.net/PhilipKoopman1/highly-autonomous-vehicle-validation" target="_blank" title="Highly Autonomous Vehicle Validation">Highly Autonomous Vehicle Validation</a> </strong> from <strong><a href="https://www.slideshare.net/PhilipKoopman1" target="_blank">Philip Koopman</a></strong> <br />
<br />
Highly Autonomous Vehicle Validation: it's more than just road testing!<br />
- Why a billion miles of testing might not be enough to ensure self-driving car safety.<br />
- Why it's important to distinguish testing for requirements validation vs. testing for implementation validation.<br />
- Why machine learning is the hard part of mapping autonomy validation to ISO 26262<br />
<br /></div>
Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com2tag:blogger.com,1999:blog-4172950626830217643.post-79638529635076323282017-10-09T09:00:00.000-04:002017-10-10T08:35:11.752-04:00Top Five Embedded Software Management MisconceptionsHere are five common management-level misconceptions I run into when I do design reviews of embedded systems. How many of these have you seen recently?<br />
<br />
<b>(1) Getting to compiled code quickly indicates progress. (FALSE!)</b><br />
<br />
Many projects are judged by "coding completed" to indicate progress. Once the code has been written, compiles, and kind of runs for a few minutes without crashing, management figures that they are 90% there. In reality,<a href="https://en.wikipedia.org/wiki/Ninety-ninety_rule"> a variant of the 90/90 rule holds:</a> the first 90% of the project is in coding, and the second 90% is in debugging.<br />
<br />
Measuring teams on code completion pressures them to skip design and peer reviews, ending up with buggy code. Take the time to do it right up front, and you'll more than make up for those "delays" with fewer problems later in the development cycle. Rather than measure "code completed" do something more useful, like measure the fraction of modules with "peer review completed" (and defects found in peer review corrected). There are many reasonable ways to manage, but waterfall-ish projects that treat "code completed" as the most critical milestone is not one of them.<br />
<br />
<b>(2) Smart developers can write production-quality code on a long weekend (FALSE!)</b><br />
<br />
<i>Alternate form:</i> marketing sets both requirements and end date without engineering getting a chance to spend enough time on a preliminary design to figure out if it can actually be done.<br />
<br />
The true bit is anyone can slap together some code that doesn't work. Some folks can slap together code in a long weekend that almost works. But even the best of us can only push so many lines of code in a short amount of time without making mistakes, much less producing something anyone else can understand. Many of us remember putting together hundreds or thousands of lines on an all-nighter when we were students. That should not be mistaken for writing production embedded code.<br />
<br />
Good embedded code tends to <a href="https://betterembsw.blogspot.com/2010/05/only-10-lines-of-code-per-day-really.html">cost about an hour for every 1 or 2 lines of non-comment code</a> all-in, including testing (on a really good day 3 lines/hr). Some teams come from the<a href="https://en.wikiquote.org/wiki/Garrison_Keillor#News_from_Lake_Wobegon"> Lake Wobegone school</a>, where all the programmers are above average. (Is that really true for your team? Really? Good for you! But you still have to pay attention to the other four items on this list.) And sure, you can game this metric if you try. Nonetheless, it is remarkable how often I see a number well above about 2 SLOC/hour of deeply embedded code corresponding to a project that is in trouble.<br />
<br />
Regardless of the precise productivity number, if you want your system to really work, you need to treat software development as a core competency. You need an appropriately methodical and rigorous engineering process. Slapping together code quickly gives the illusion of progress, but it doesn't produce reliable products for full-scale production.<br />
<br />
<b>(3) A “mostly working,” undisciplined prototype can be deployed. (FALSE!)</b><br />
<br />
Quick and dirty prototypes provide value by giving stakeholders an idea of what to expect and allowing iterations to converge on the right product. They are invaluable for solidifying nebulous requirements. However, such a prototype should not be mistaken for an actual product! If you've hacked together a prototype, in my experience it's always more expensive to clean up the mess than it is to take a step back and start a project from scratch or a stable production code base. <br />
<br />
What the prototype gives you is a solid sense of requirements and some insight into pitfalls in design.<br />
<br />
A well executed incremental deployment strategy can be a compromise to iteratively add functionality if you don't know all your requirements up front. But an well-run Agile project is not what I'm talking about when I say "undisciplined prototype." A cool proof of concept can be very valuable. It should not be mistaken for production code.<br />
<br />
<b>(4) Testing improves software quality (FALSE!)</b><br />
<br />
If there are code quality problems (possibly caused by trying to bring an undisciplined prototype to market), the usual hammer that is brought to bear is more testing. Nobody ever solved code quality problems by testing. All that testing does is make buggy code a little less buggy. If you've got spaghetti code that is full of bugs, testing can't possibly fix that. And testing will generally miss most subtle timing bugs and non-obvious edge cases.<br />
<br />
If you're seeing lots of bugs in system test, your best bet is to use testing to find bug farms. The 90/10 rule applies: many times 90% of the bugs are in bug farms -- the worst 10% of the modules. That's only an approximate ratio, but regardless of the exact number, if you're seeing a lot of system test failures then there is a good chance some modules are especially bug-prone. Generally the problem is not simply programming errors, but rather poor design of these bug-prone modules that makes bugs inevitable. When you identify a bug farm, throw the offending module away, redesign it clean, and write the code from scratch. It's tempting to think that each bug is the last one, but after you've found more than a handful of bugs in a module, who are you kidding? Especially if it's <a href="https://betterembsw.blogspot.com/2017/08/the-spaghetti-factor-software.html">spaghetti code</a>, bug farms will always be one bug away from being done, and you'll never get out of system test cleanly.<br />
<br />
<b>(5) Peer review is too expensive (FALSE!)</b><br />
<br />
Many, many projects skip peer review to get to completed code (see item #1 above). They feel that they just don't have time to do peer reviews. <a href="https://betterembsw.blogspot.com/2014/09/peer-reviews-and-critical-software.html">However, good peer reviews are going to find 50-75% of your bugs before you ever get to testing, and do so for about 10% of your development budget.</a> How can you not afford peer reviews? (Answer: you don't have time to do peer reviews because you're too busy writing bugs!)<br />
<br />
Have you run into another management misconception on a par with these? Let me know what you think!<br />
<br />Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com4tag:blogger.com,1999:blog-4172950626830217643.post-36065577092782310452017-09-22T07:47:00.000-04:002017-09-22T07:47:51.383-04:00Challenges and Solutions in Autonomous Vehicle ValidationHere are the slides from my AV17 Presentation on self-driving car safety:<br />
<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="485" marginheight="0" marginwidth="0" scrolling="no" src="//www.slideshare.net/slideshow/embed_code/key/wmdHLAWBwQ92Ug" style="border-width: 1px; border: 1px solid #ccc; margin-bottom: 5px; max-width: 100%;" width="595"> </iframe> <br />
<div style="margin-bottom: 5px;">
<strong> <a href="https://www.slideshare.net/PhilipKoopman1/challenges-and-solutions-in-autonomous-vehicle-validation" target="_blank" title="Challenges and Solutions in Autonomous Vehicle Validation">Challenges and Solutions in Autonomous Vehicle Validation</a> </strong> from <strong><a href="https://www.slideshare.net/PhilipKoopman1" target="_blank">Philip Koopman</a></strong> </div>
Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com2tag:blogger.com,1999:blog-4172950626830217643.post-41732070740550517332017-08-28T07:00:00.000-04:002017-08-28T07:00:14.542-04:00The Spaghetti Factor -- A Software Complexity Metric Proposal<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSiWs-cgdwXicGiMwQFd0OcjWG_i5VEHokX1kS9BsRJpRResgtuGsB_Hze-lgT5gkHypXvRg9c8K8c_xB_TAiP2ifPL0Bk7Cray4oV__Xhyphenhyphen3spuZkSRGnVfvjLqD4eTQZgvWfuqy79268/s1600/spaghetti.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="185" data-original-width="540" height="109" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSiWs-cgdwXicGiMwQFd0OcjWG_i5VEHokX1kS9BsRJpRResgtuGsB_Hze-lgT5gkHypXvRg9c8K8c_xB_TAiP2ifPL0Bk7Cray4oV__Xhyphenhyphen3spuZkSRGnVfvjLqD4eTQZgvWfuqy79268/s320/spaghetti.jpg" width="320" /></a></div>
<br />
I've had to review code that has spaghetti-level complexity in control flow (too high cyclomatic complexity). And I've had to review code that has spaghetti-level complexity its data flow (too many global variables mixed together into a single computation). And I've had to review procedures that just go on for page after page with no end in sight. But the stuff that will really make your brain hurt is code that has all of these problems.<br />
<br />
There are many complexity metrics out there. But I haven't seen a one that directly tries to help balance three key points of complexity into a single intuitive number: code complexity, data complexity, and module size. So here is a proposal that could help drive improvement in a lot of the terrible embedded control code I've seen:<br />
<br />
<hr />
<br />
<div style="text-align: left;">
<b><u>The Spaghetti Factor metric (SF):</u></b></div>
<br />
<b>SF = SCC + (Globals*5) + (SLOC/20)</b><br />
<br />
<b>SCC</b> = Strict Cyclomatic Complexity<br />
<b>Globals</b> = # of read/write global variables<br />
<b>SLOC</b> = # source lines of non-comment code (e.g., C statements)<br />
<br />
<u>Scoring:</u><br />
5-10 - This is the sweet spot for most code except simple helper functions<br />
15 - Don't go above this for most modules<br />
20 - Look closely; review to see if refactoring makes sense<br />
30 - Refactor the design<br />
50 - Untestable; throw the module away and fix the design<br />
75 - Unmaintainable; throw the module away; throw the design away; start over<br />
100 - Nightmare; probably you need to throw the whole subsystem away and re-architect it<br />
<div>
<br /></div>
<hr />
<br />
<u>Notation:</u><br />
<br />
<b>SCC</b> is Strict Cyclomatic Complexity (sometimes called CC2). This is a variant of McCabe Cyclomatic complexity (MCC). In general terms, MCC is based on the number of branches in the program. SCC additionally considers complexity based on the number of conditions within each branch. SCC is an approximation of how many test cases it takes to exercise all the paths through code including all the different ways there are to trigger each branch. In other words, it is an estimate of how much work it is to do unit testing. Think of it as an approximation to the effort required for <a href="https://en.wikipedia.org/wiki/Modified_condition/decision_coverage">MC/DC testing</a>. But in practice it is also a measure of how hard it is to understand the code. The idea is to keep SCC low enough that it is feasible to understand and test paths through the code.<br />
<br />
<b>Globals</b> is the number of read/write global variables accessed by the module. This does not include "const" values, nor file static variables. In an ideal world you have zero or near-zero global variables. If you have inherent global state, you should encapsulated that in a state object with appropriate access functions to enforce well-disciplined writes. Referencing an unstructured pile of dozens or hundreds of global variables can make software difficult to test, and can make subsystem testing almost impossible. Partly that is due to the test scaffolding required, but partly that is simply due to the effort of chasing down all the globals and trying to figure out what they do both inbound and outbound. Moreover, too many globals can make it nearly impossible to chase down bugs or understand the effects of changing one part of the code on the rest of the code. An important goal of this part of the metric is to discourage use of many disjoint global variables to implicitly pass data around from routine to routine instead of passing parameters along with function calls.<br />
<br />
<b>SLOC</b> is the number of non-comment "Source Lines of Code." For C programs, this is the number of programming statements. Typical guidelines are a maximum 100-225 maximum lines of code for a module, with most modules being smaller than that.<br />
<br />
As an example calculation, if you have 100 lines of code with an SCC of 9 and 1 global reference, your score will be SF = 9 + (1*5) + (100/20) = 19. A score of 19 is on the upper edge of being OK. If you have a distribution of complexity across modules, you'd want most of them to be a bit lower in complexity than this example calculation.<br />
<br />
<u>Discussion:</u><br />
<br />
The guideline values are taken primarily from MCC, which typically has a guideline of 10 for most modules, 15 as a usual bound, and 30 as limit. To account for globals and length, based on my experience, I've changed that to 15 for most modules, 20 as a soft limit and 30 as a hard limit. You might wish to adjust the threshold and multipliers based on your system and experience. In particular it is easy to make a case that these limits aren't strict enough for life-critical software, and a case can be made for being a little more relaxed in throw-away GUI management code. But I think this is a good starting point for most every-day embedded software that is written by a human (as opposed to auto-generated code).<br />
<br />
The biggest exception is usually what to do about switch statements. If you exempt them you can end up with multiple switches in one module, or multiple switch/if/switch/if layered nesting. (Neither is a pretty sight.) I think it is justifiable to exempt modules that have ONLY a switch and conditional logic to do sanity checking on the switch value. But, because 30 is a pretty generous limit, you're only going to see this rarely. Generally the only legitimate reason to have a switch bigger than that is for something like processing a message type for a communication protocol. So I think you should not blanket exempt switch statements, but rather include them in an overall case-by-case sign-off by engineering management as to which few exceptions are justifiable.<br />
<br />
Some might make the observation that this metric discourages extensive error checking. That's a different topic, and certainly the intent is NOT to discourage error checking. But the simple answer is that error checking has to be tested and understood, so you can't simply ignore that part of the complexity. One way to handle that situation is to put error checking into a subroutine or wrapper function to get that complexity out of the way, then have that wrapper call the actual function that does the work. Another way is to break your overall code down into smaller pieces so that each piece is simple enough for you to understand and test both the functionality and the error checking.<br />
<br />
Finally, any metric can be gamed, and that is surely true of simple metrics like this one. A good metric score doesn't necessarily mean your code is fantastic. Additionally, this metric does not consider everything that's important, such as the total number of globals across your code base. On the other hand, if you score poorly on this metric, most likely your code is in need of improvement.<br />
<br />
What I recommend is that you use this metric as a way to identify code that is needlessly complex. It is the rare piece of code indeed that unavoidably needs to have a high score on this complexity metric. And if all your code has a good score, that means it should be that much easier to do peer review and unit testing to ensure that other aspects of the code are in good shape.<br />
<br />
<u>References:</u><br />
<ul>
<li><a href="https://betterembsw.blogspot.com/2014/06/avoid-high-cyclomatic-complexity.html">Blog post on cyclomatic complexity</a></li>
<ul>
<li>Jack Ganssle on <a href="http://www.ganssle.com/articles/cyclomaticcomplexity.html">how to compute MCC</a></li>
<li>Description of <a href="http://www.aivosto.com/project/help/pm-complexity.html">MCC variants, including SCC (CC2)</a></li>
</ul>
<li><a href="https://betterembsw.blogspot.com/2014/06/minimize-use-of-global-variables.html">Blog post on global variables</a></li>
<li><a href="https://betterembsw.blogspot.com/2014/06/ensure-code-is-modular.html">Blog post on modularity</a></li>
</ul>
<br />
A NIST paper on applying metrics is here: <a href="http://www.mccabe.com/pdf/mccabe-nist235r.pdf">http://www.mccabe.com/pdf/mccabe-nist235r.pdf</a> including an interesting discussion of the pitfalls of handling switch statements within a complexity framework.<br />
<br />Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com10tag:blogger.com,1999:blog-4172950626830217643.post-54772125994509597312017-07-24T07:00:00.000-04:002017-07-24T07:00:04.515-04:00Don't use macros for MIN and MAX<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzXSqrh7_Di7Bt8Kn2xJ4WTnYAJylqEMiNqGEYUs8n7wOcKOXAbl8QgfjPEMsgbBVnBEy9LomEjdulUgOux9mRBeY4HqFtJOXcq_wA8n2u9R0lfXjdr3FUs6TJmx1pVMHyHRGB9Fz6QdU/s1600/minmax_pixabay_2108024.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="256" data-original-width="497" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzXSqrh7_Di7Bt8Kn2xJ4WTnYAJylqEMiNqGEYUs8n7wOcKOXAbl8QgfjPEMsgbBVnBEy9LomEjdulUgOux9mRBeY4HqFtJOXcq_wA8n2u9R0lfXjdr3FUs6TJmx1pVMHyHRGB9Fz6QdU/s320/minmax_pixabay_2108024.jpg" width="320" /></a></div>
<br />
<div>
It is common to see small helper functions implemented as macros, especially in older C code. Everyone seems to do it. But you should avoid macros, and instead use inline functions.<br />
<br />
The motivation for using macros was originally that you needed to use a small function in many places but were worried about the overhead of doing a subroutine call. So instead, you used a macro, which expands into source code in the preprocessor phase. That was a reasonable tradeoff 40 years ago. Not such a great idea now, because macros cause problems for no good reason.</div>
<div>
<br /></div>
<div>
For example, you might look on the Web and find these common macros</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> #define MAX(a,b) ((a) > (b) ? a : b)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> #define MIN(a,b) ((a) < (b) ? a : b)</span></div>
</div>
<div>
<br /></div>
<div>
And you might find that it seems to work for a while. You might get bitten by the missing "()" guards around the second copy of <span style="font-family: "courier new" , "courier" , monospace;">a</span> and <span style="font-family: "courier new" , "courier" , monospace;">b</span> in the above -- which version you get depends on which cut & paste code site you visit. </div>
<div>
<br /></div>
<div>
But then you'll find that there are still weird situations where you get unexpected behavior. For example, what does this do?</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> c = MAX(a++, b);</span></div>
<div>
If a is greater than <span style="font-family: "courier new" , "courier" , monospace;">b</span> executing the code will increment <span style="font-family: "courier new" , "courier" , monospace;">a</span> twice, but if <span style="font-family: "courier new" , "courier" , monospace;">a</span> is less than or equal to <span style="font-family: "courier new" , "courier" , monospace;">b</span> it will only increment <span style="font-family: "courier new" , "courier" , monospace;">a</span> once. And if you start mixing types or putting complicated expressions into the macro things can get weird and buggy in a hurry.</div>
<div>
<br /></div>
<div>
Another related problem is that the macro will expand, increasing the cyclomatic complexity of your code. That's because a macro is equivalent to you having put the conditional branch into the source code. (Remember, macro expansion is done by the preprocessor, the so compiler itself acts as if you'd typed the conditional assignment expression every place you use the macro.) This complexity rating is justified, because there is no actual procedure that can be unit tested independently.</div>
<div>
<br /></div>
<div>
As it turns out, <b><u>macros are evil</u></b>. See the C++ FAQ: <a href="https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-if">https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-if</a> which lists 4 different types of evil behavior. There are fancy hacks to try to get any particular macros such as MIN and MAX to be better behaved, but no matter how hard you try you're really just making a deal with the devil. </div>
<div>
<br /></div>
<div>
<b><u>What's the fix?</u></b></div>
<div>
<br /></div>
<div>
The fix is: don't use macros. Instead use inline procedure calls.</div>
<div>
<br /></div>
<div>
You should already have access to built-in functions for floating point such as fmin() and fmax(). If it's there, use the stuff from your compiler vendor instead of writing it yourself!</div>
<div>
<br /></div>
<div>
If your compiler doesn't have integer min and max, or you are worried about breaking existing macro code, convert the macros into inline functions with minimal changes to your code base:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">inline int32_t MAX(int32_t a, </span><span style="font-family: "courier new" , "courier" , monospace;">int32_t </span><span style="font-family: "courier new" , "courier" , monospace;">b) { return((a) > (b) ? a : b); }</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">inline</span><span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;">int32_t MIN(</span><span style="font-family: "courier new" , "courier" , monospace;">int32_t </span><span style="font-family: "courier new" , "courier" , monospace;">a, </span><span style="font-family: "courier new" , "courier" , monospace;">int32_t </span><span style="font-family: "courier new" , "courier" , monospace;">b) { return((a) < (b) ? a : b); }</span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
If you have other types to deal with you might need different variants depending on the types, but often a piece of code uses predominantly one data type for its calculations, so in practice this is usually not a big deal. And don't forget, if your build environment has a built in min or max you can just set up the macro to call that directly.</div>
<div>
<br /></div>
<div>
<b><u>What about performance?</u></b></div>
<div>
<br /></div>
<div>
The motivation for using macros back in the bad old days was efficiency. A subroutine call involved a lot of overhead. But the inline keyword tells the compiler to expand the code in-place while retaining all the advantages of a subroutine call. Compilers are pretty good at optimization these days. So there is no overhead at run-time. I've also seen advice to put the inline function in a header file so it will be visible to any procedure needing it, and the macro was already there anyway.</div>
<div>
<br /></div>
<div>
Strictly speaking, "inline" is a suggestion to the compiler. However, if you have a decent compiler it will follow the suggestion unless the inline function is so big the call overhead just doesn't matter. Some compilers have a warning flag that will let you know when the inline didn't happen. For example, use -Winline for gcc. If your compiler ignores "inline" for something as straightforward as MIN or MAX, get a different compiler.</div>
<div>
<br /></div>
<div>
<b><u>What about multiple types?</u></b></div>
<div>
<br /></div>
<div>
A perceived advantage of the macro approach is that you can play fast and loose with types. But playing fast and loose with types is a BAD IDEA because you'll get bugs. </div>
<div>
<br /></div>
<div>
If you really hate having to match the function name to the data types then what you need is to switch to a language that can handle this by automatically picking the right function based on the operator types. In other words, switch from a to a language that is 45 years old (C) to one that is only about 35 years old (C++). There's a paper from 1995 that explains this in the context of min and max implemented with templates: <a href="http://www.aristeia.com/Papers/C++ReportColumns/jan95.pdf">http://www.aristeia.com/Papers/C++ReportColumns/jan95.pdf</a></div>
<div>
As it turns out the rabbit hole goes a lot deeper than you might think for a generic solution.</div>
<div>
<br /></div>
<div>
But you don't have to go down the rabbit hole. For most code the best answer is simply to use inline functions and pick the function name that matches your data types. You shouldn't lose any performance at all, and you'll be likely to save a lot of time chasing obscure bugs.</div>
<div>
<br /></div>
Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com3tag:blogger.com,1999:blog-4172950626830217643.post-64664826833679756472017-05-22T07:00:00.000-04:002017-05-22T10:36:45.546-04:00#define vs. constIs your code full of "#define" statements? If so, you should consider switching to the const keyword.<br />
<div>
<br /></div>
<div>
Old school C:</div>
<div>
#define MYVAL 7</div>
<div>
<br /></div>
<div>
Better approach:</div>
<div>
const uint32_t myVal = 7;</div>
<div>
<br /></div>
<div>
Here are some reasons you should use const instead of #define:</div>
<div>
<ul>
<li>#define has global scope, so you're creating (read-only) global values every time you use #define. Global scope is evil, so don't do that. (Read-only global scope for constant values is a bit less evil than global variables per se, especially if you can't use the namespace features of C++. But gratuitous global scope is always a bad idea.) A const alternative can obey scoping rules, including being purely local if defined inside a procedure, or more commonly file static with the "static" keyword.</li>
<li>Const lets you do more aggressive type checking (depending upon your compiler and static analysis tools, especially if you use a typedef more specific than built-in C data types). While C is a bit weak as a language in this area compared to other languages, a classical example is a const lets you identify a number as being in feet or meters, while the #define approach is just as if you'd typed the number 7 in with no units. The #define approach can bite you if you use the wrong value in the wrong place. Type checking is an effective way to find bugs, and using #define gives up an opportunity to let static analysis tools help you with that.</li>
<li>Const lets you use the value as if it were a variable when you need to (e.g., passing an address to the variable) without having to change how the variable is defined.</li>
<li>#define in general is so bug-prone that you should minimize its use just to avoid having to spend time asking "is this one OK?" in a peer review. Most #define uses tend to be const variables in old-school code, so getting rid of them can dramatically reduce the peer review burden of sifting through hundreds of #define statements to look for problems.</li>
</ul>
</div>
<div>
Here are some common myths about this tradeoff. (Note that on some systems these statements might be true, especially if you have and old and lame compiler. But they don't necessarily have to be true and they often are false, especially on newer chips with newer compilers.)</div>
<div>
<ul>
<li>"Const wastes memory." False if you have a compiler that is smart enough to do the right thing. Sure, if you want to pass a pointer to the const it will actually have to live in memory somewhere, but you can't even pass a pointer to a #define at all. One of the points of "const" is to give the compiler a hint that lets it optimize memory footprint.</li>
<li>"Const won't work for X." Generally false if you have a newer compiler, and especially if you are using a mostly-C subset of the capability of a C++ compiler, as is increasingly common. And honestly, most of the time #define is just being used as a plain old integer const to get rid of magic numbers. const will work fine. (If you have magic numbers instead of #define, then you have bigger problems than this even.) Use const for the no-brainer cases. Something is probably wrong if everything about your code is so special you need #define everywhere.</li>
<li>"Const hassles me about type conversions." That's a feature to prevent you from being sloppy! So strictly speaking the compiler doing this is not a myth. The myth is that this is a bad thing.</li>
</ul>
</div>
<div>
There are plenty of discussions on this topic. You'll also see that some folks advocate using enums for some situations, which we'll get to another time. For now, if you change as many #defines as you can to consts then that is likely to improve your code quality, and perhaps flush out a few bugs you didn't realize you had.</div>
<div>
<br /></div>
<div>
Be careful when reading discussion group postings on this topic. There is a lot of dis-information out there about performance and other potential tradeoff factors, usually based on statements about 20 year old versions of the C language or experiences with compilers that have poor optimization capability. In general, you should always use const by default unless your particular compiler/system/usage presents a compelling case not to.</div>
<div>
<br /></div>
<div>
See also the <a href="https://barrgroup.com/Embedded-Systems/Books/Embedded-C-Coding-Standard/General-Rules/Keywords-Static-Volatile-Const">Barr Group C coding standard rule 1.8.b</a> which says to use const, and has a number of other very useful rules.</div>
<div>
<br /></div>
<div>
<br /></div>
Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com14tag:blogger.com,1999:blog-4172950626830217643.post-30734070048486951232017-05-08T07:00:00.000-04:002017-05-08T08:20:30.401-04:00Optimize for V&V, not for writing code<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQsyhxZ5EKYF6QgIhnToR_kdLTmKp7TQFu72ZUcV7WdgsEEpYBUvnyUO_K6Gdtn8z3Sx0pSj3CubX0CauCu9wKKnmd5VTNe9mfna-TRT9tkBeqnnmrjRL2NQ2gUtJpUXJVW7EfW2eZIiw/s1600/robot-2167836_1280.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQsyhxZ5EKYF6QgIhnToR_kdLTmKp7TQFu72ZUcV7WdgsEEpYBUvnyUO_K6Gdtn8z3Sx0pSj3CubX0CauCu9wKKnmd5VTNe9mfna-TRT9tkBeqnnmrjRL2NQ2gUtJpUXJVW7EfW2eZIiw/s320/robot-2167836_1280.jpg" width="320" /></a><br /><span style="font-size: xx-small;"><a href="https://pixabay.com/en/robot-artificial-intelligence-2167836/">Geralt / CC0 PD/noattrib.</a></span></div>
<br />
<div>
<b>Writing code should be made more difficult so that Verification &Validation can be made easier.</b><br />
<b><br /></b>
I first heard this notion years ago at a workshop in which several folks from industry who build high assurance software (think flight controls) stood up and said that V&V is what matters. You might expect that from flight control folks, but their reasoning applies to pretty much every embedded project. That's because it is a matter of economics. </div>
<div>
<br /></div>
<div>
Multiple speakers at that workshop said that aviation software can require 4 or 5 hours of V&V for every 1 hour of creating software. It makes no economic sense to make life easy for the 1 hour side of the ratio at the expense of making life painful for the 5 hour side of the ratio.</div>
<div>
<br /></div>
<div>
Good, but non-life-critical, embedded software requires about 2 hours of V&V for every 1 hour of code creation. So the economic argument still holds, with a still-compelling multiplier of 2:1. I don't care if you're Vee, Agile, hybrid model or whatever. You're spending time on V&V, including at least some activities such as peer review, unit test, created automated tests, performing testing, chasing down bugs, and so on. For embedded products that aren't flaky, probably you spend more time on V&V than you do on creating the code. If you're doing TDD you're taking an approach that has the idea of starting with a testing viewpoint built in already, by starting from testing and working outward from there. But that's not the only way to benefit from this observation.</div>
<div>
<br /></div>
<div>
The good news is that making code writing "difficult" does not involve gratuitous pain. Rather, it involves being smart and a bit disciplined so that the code you produce is easier for others to perform V&V on. A bit of up front thought and organization can save a lot on downstream effort. Some examples include:</div>
<div>
<ul>
<li>Writing concise but helpful code comments so that reviewers can understand what you meant.</li>
<li>Writing code to be obvious rather than clever, again to help reviewers.</li>
<li>Follow a style guide to make your code consistent, and thus easier to understand.</li>
<li>Writing code that compiles clean for static analysis, avoiding time wasted finding defects in test that a tool could have found, and avoiding a person having to puzzle out which warnings matter, and which don't.</li>
<li>Spending some time to make your unit interfaces easier to test, even if it requires a bit more work designing and coding the unit.</li>
<li>Spending time making it easy to trace between your design and the code. For example, if you have a statechart, make sure the statechart uses names that map directly to enum names rather than using arbitrary state variables such as "magic number" integers between 1 and 7. This makes it easier to ensure that the code and design match. (For that matter, just using statecharts to provide a guide to what the code does also helps.)</li>
<li>Spending time up front documenting module interaction so that integration testers don't have to puzzle out how things are supposed to work together. Sequence diagrams can help a lot.</li>
<li>Making the requirements both testable and easy to trace. Make every requirement idea a stand-alone sentence or paragraph and give it a number so it's easy to trace to a specific test primarily designed to test that particular requirement. Avoid having requirements in huge paragraphs of free-form text that mix lots of different concepts together.</li>
</ul>
</div>
<div>
Sure, these sound like a good idea, but many developers skip or skimp on them because they don't think they can afford the time. They don't have time to make their code clean because they're too busy writing bugs to meet a deadline. Then they, and everyone else, pay for this during the test cycle. (I'm not saying the programmers are necessarily the main culprits here, especially if they didn't get a vote on their deadline. But that doesn't change the outcome.)</div>
<div>
<br /></div>
<div>
I'm here to say you can't afford <i>not</i> to follow these basic code quality practices. That's because every hour you're saving by cutting corners up front is probably costing you double (or more) downstream by making V&V more painful than it should be. It's always hard to invest in downstream benefits when the pressure is on, but doing so is costing you dearly when you skimp on code quality.</div>
<div>
<br />
Do you have any tricks to make code easier to understand that I missed?</div>
<div>
<br /></div>
Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com3tag:blogger.com,1999:blog-4172950626830217643.post-65878422795125450822017-04-10T10:25:00.000-04:002017-06-09T07:06:39.026-04:00Challenges & solutions for Embedded Software Security, Safety & Quality (Full Tutorial Video)This is a full-length video that talks about embedded software security, safety and quality: why it matters. What to do about it.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="360" mozallowfullscreen="" src="https://player.vimeo.com/video/179121954" webkitallowfullscreen="" width="640"></iframe><br />
<a href="https://www.edge-case-research.com/full-tutorial-software-quality-1">Embedded Software Quality Safety and Security [ECR]</a><br />
<br />
The purpose of this video is to help you understand why safety and security are such a big deal for embedded systems, tell some war stories, and explain the general ways available to reduce risk when you're creating embedded and IoT products.<br />
<br />
Topics covered include:<br />
<ul>
<li>Case studies of safety and security problems</li>
<li>How to design for safety</li>
<li>How to design for security</li>
<li>Top 10 embedded software warning signs</li>
<li>How to create high quality embedded software</li>
</ul>
<div>
(27 Slides / 45 minutes)<br />
<br /></div>
<b>Slides Only: </b><br />
<iframe allowfullscreen="" frameborder="0" height="485" marginheight="0" marginwidth="0" scrolling="no" src="//www.slideshare.net/slideshow/embed_code/key/dz9S11WVB1tEdD" style="border-width: 1px; border: 1px solid #ccc; margin-bottom: 5px; max-width: 100%;" width="595"> </iframe> <br />
<div style="margin-bottom: 5px;">
<strong> <a href="https://www.slideshare.net/PhilipKoopman1/embedded-software-security-safety-quality" target="_blank" title="Embedded Software Security Safety & Quality">Embedded Software Security Safety & Quality</a> </strong> from <strong><a href="https://www.slideshare.net/PhilipKoopman1" target="_blank">Philip Koopman</a></strong> </div>
Phil Koopmanhttp://www.blogger.com/profile/11849599272360094243noreply@blogger.com0