{"id":8524,"date":"2018-01-22T10:26:24","date_gmt":"2018-01-22T09:26:24","guid":{"rendered":"https:\/\/blogs.mentor.com\/colinwalls\/?p=8524"},"modified":"2018-01-22T10:26:24","modified_gmt":"2018-01-22T09:26:24","slug":"5-embedded-software-programming-tips","status":"publish","type":"post","link":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/2018\/01\/22\/5-embedded-software-programming-tips\/","title":{"rendered":"5 embedded software programming tips"},"content":{"rendered":"<p>Most software developers will have received some kind of training or education in programming techniques. Others may be self-taught. But either way, many will agree that much of the real learning comes later. When programming, it is possible to stumble across useful techniques or get advice from colleagues during a code review. Even very experienced programmers pick up new tips from time to time.<\/p>\n<p>This posting is the first in an occasional series in which I will outline 5 useful [I hope!] snippets of advice for embedded software developers \u2026<!--more--><\/p>\n<p>Here, in no particular order, are today\u2019s 5 tips:<\/p>\n<h3>Set a pointer to NULL after use<\/h3>\n<p>Pointers are very a useful and powerful language feature, but this power can result in errors. A common mistake is for code to make use of a pointer when its value is no longer valid. For example, it may point to some memory that had been dynamically allocated, but has since been relinquished. Using an invalid pointer can cause adverse effects that do not become apparent for some time and are, thus, a very hard to find bug. If you routinely set a pointer to NULL after its use is over, later erroneous use will cause an immediate error that enables the bug to be located easily.<\/p>\n<h3>In C, it is lazy programming to use int for unsigned data<\/h3>\n<p>In C, the <strong>int<\/strong> data type is almost a default. Indeed, in the original language definition, it was the default return data type for a function [which really should have been <strong>void<\/strong>, but that came later]. Most C programmers tend to select <strong>int<\/strong> for a variable unless it is very clearly inappropriate. I would argue that they should really elect for <strong>unsigned<\/strong>, as more data is unsigned than signed. It is best to consider exactly what the range of values is that you need to store. Is it signed or unsigned? Do you need 8, 16, 32 or more bits? Surprisingly, time\/date counters have commonly be made signed, which had led to <a href=\"https:\/\/blogs.mentor.com\/colinwalls\/blog\/2009\/07\/20\/y2k-redux\/\" target=\"_blank\" rel=\"noopener noreferrer\">Y2K style bugs<\/a>.<\/p>\n<h3>Beware of creeping elegance<\/h3>\n<p>When is a piece of software finished? The obvious answer is when it provides all the specified functionality, with no known bugs. There are a couple of circumstances in which completion may be compromised. Firstly, many engineers are perfectionists and can always see things to \u201cimprove\u201d in their code. In their hands, without care and supervision, a project can over-run badly. Another, less obvious situation, is when some code has been written for a specific purpose\/project and is then reused elsewhere. It is very easy to \u201cbuild on experience\u201d and make some improvements to the code prior to reuse. Without care, this can become a version control nightmare. I experienced this issue with an <a href=\"https:\/\/blogs.mentor.com\/colinwalls\/blog\/2009\/09\/21\/creeping-elegance\/\" target=\"_blank\" rel=\"noopener noreferrer\">in-house RTOS<\/a> many years ago.<\/p>\n<h3>With an RTOS, an event flag or signal is the most efficient way to send simple logic data<\/h3>\n<p>A modern RTOS, like our own <a href=\"https:\/\/www.mentor.com\/embedded-software\/nucleus\/\" target=\"_blank\" rel=\"noopener noreferrer\">Nucleus RTOS<\/a> product, includes a great many facilities. Being scalable, such an OS enables the developer to pick and choose which facilities to use, without suffering a code size penalty from the unused facilities. Inter-task communication is important in any multi-threaded design, so a number of different capabilities are likely to be available and they should be selected with care. If one task simply needs to flag to another that something has occurred, the simplest communication method &#8211; event flags or signal &#8211; are likely to be the most efficient option.<\/p>\n<h3>Recursive code can look very elegant, but is very dangerous<\/h3>\n<p>A number of mathematical processes may be described using recursive functions &#8211; i.e. functions that directly or indirectly call themselves. This may be an apparently elegant way to solve a problem, that uses minimal code. Here is a simple example:<\/p>\n<pre>void printbase(int number, int base)\n{\n   if (number &gt;= base)\n   {\n      printbase(number\/base, base);\n   }\n   printf(\"%X\", number%base);\n}\n\n<\/pre>\n<p>Is it clear what this code does? The answer is probably \u201cnot immediately\u201d and this is one reason to avoid the technique, Clarity of meaning in code is essential to aid further maintenance. Additionally, recursive functions make heavy use of the stack and this may go out of control without care. Stack overflows are quite subtle bugs to locate.<\/p>\n<p><a href=\"http:\/\/www.linkedin.com\/in\/colinwalls\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6579\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/linkedin.png\" alt=\"\" width=\"40\" height=\"40\" \/><\/a><a href=\"https:\/\/twitter.com\/colin_walls\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6583\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/twitter.png\" alt=\"\" width=\"40\" height=\"40\" \/><\/a><a href=\"https:\/\/www.facebook.com\/colinwalls.author\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6591\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/facebook.png\" alt=\"\" width=\"40\" height=\"40\" \/><\/a><a href=\"https:\/\/plus.google.com\/116301748426290440139\/posts?hl=en%3Fhl=en\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6587\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/google.png\" alt=\"\" width=\"40\" height=\"40\" \/><\/a><a href=\"http:\/\/www.slideshare.net\/ColinWalls\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6595\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/slideshare.jpg\" alt=\"\" width=\"41\" height=\"41\" \/><\/a><a href=\"http:\/\/blogs.mentor.com\/colinwalls\/\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6599\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/wordpress.jpg\" alt=\"\" width=\"44\" height=\"44\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Most software developers will have received some kind of training or education in programming techniques. Others may be self-taught. But&#8230;<\/p>\n","protected":false},"author":71677,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spanish_translation":"","french_translation":"","german_translation":"","italian_translation":"","polish_translation":"","japanese_translation":"","chinese_translation":"","footnotes":""},"categories":[1],"tags":[313,339,300,304,374,378,309],"industry":[],"product":[],"coauthors":[],"class_list":["post-8524","post","type-post","status-publish","format-standard","hentry","category-news","tag-c","tag-development-tools","tag-embedded-software","tag-nucleus","tag-nucleus-os","tag-nucleus-rtos","tag-rtos"],"_links":{"self":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/8524","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/users\/71677"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/comments?post=8524"}],"version-history":[{"count":0,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/8524\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/media?parent=8524"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/categories?post=8524"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/tags?post=8524"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/industry?post=8524"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/product?post=8524"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/coauthors?post=8524"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}