{"id":4319,"date":"2013-01-28T08:00:45","date_gmt":"2013-01-28T07:00:45","guid":{"rendered":"https:\/\/blogs.mentor.com\/colinwalls\/?p=4319"},"modified":"2026-03-26T16:39:42","modified_gmt":"2026-03-26T20:39:42","slug":"write-only-ports-in-c","status":"publish","type":"post","link":"https:\/\/blogs.sw.siemens.com\/embedded-software\/2013\/01\/28\/write-only-ports-in-c\/","title":{"rendered":"Write-only ports in C++"},"content":{"rendered":"<p>I recently wrote about <a href=\"https:\/\/blogs.mentor.com\/colinwalls\/blog\/2013\/01\/14\/write-only-ports\/\" target=\"_blank\" rel=\"noopener noreferrer\">write-only ports<\/a> and discussed how they worked and the challenges presented to software developers who need to program them. The solutions proposed were quite straightforward, but the challenge remained to ensure that all the code utilizing the ports complied with the requirements.<\/p>\n<p>I commented at the time that there are several ways to mandate the correct handing of write-only ports, but an approach that interested me was the use of C++ &#8230;<!--more--><\/p>\n<p>In C++, the power of object oriented programming can be very useful for embedded developers. Complex, hard to understand code may be hidden inside objects, which can then be used safely by applications programmers. In this case, I am going to create a class [in effect, a new data type] called <strong>write_only_port<\/strong> which deals with all the necessary usage of a shadow copy of the port data. Here is my first shot at it:<\/p>\n<pre>class write_only_port<\/pre>\n<pre>{<\/pre>\n<pre style=\"padding-left: 30px\">unsigned shadow;<\/pre>\n<pre style=\"padding-left: 30px\">volatile unsigned* address;<\/pre>\n<pre>public:<\/pre>\n<pre style=\"padding-left: 30px\">write_only_port(unsigned);<\/pre>\n<pre style=\"padding-left: 30px\">~write_only_port();<\/pre>\n<pre style=\"padding-left: 30px\">void operator|=(unsigned);<\/pre>\n<pre style=\"padding-left: 30px\">void operator&amp;=(unsigned);<\/pre>\n<pre>};<\/pre>\n<p>&nbsp;<\/p>\n<p>This needs the 4 member functions defined too [but I will skip the destructor for the moment]:<\/p>\n<pre>write_only_port::write_only_port(unsigned port)<\/pre>\n<pre>{<\/pre>\n<pre style=\"padding-left: 30px\">address = (unsigned*) port;<\/pre>\n<pre style=\"padding-left: 30px\">shadow = 0;<\/pre>\n<pre style=\"padding-left: 30px\">*address = 0;<\/pre>\n<pre>}<\/pre>\n<p>&nbsp;<\/p>\n<pre>void write_only_port::operator|=(unsigned val)<\/pre>\n<pre>{<\/pre>\n<pre style=\"padding-left: 30px\">shadow |= val;<\/pre>\n<pre style=\"padding-left: 30px\">*address = shadow;<\/pre>\n<pre>}<\/pre>\n<p>&nbsp;<\/p>\n<pre>void write_only_port::operator&amp;=(unsigned val)<\/pre>\n<pre>{<\/pre>\n<pre style=\"padding-left: 30px\">shadow &amp;= val;<\/pre>\n<pre style=\"padding-left: 30px\">*address = shadow;<\/pre>\n<pre>}<\/pre>\n<p>This enables <strong>write_only_port<\/strong> objects to be created and assigned an address [and initialized to 0]. The applications programmer then has [only] the <strong>|=<\/strong> and <strong>&amp;=<\/strong> operators available, which are quite sufficient to set and clear bits. Application code using this class may look like this:<\/p>\n<pre>main()<\/pre>\n<pre>{<\/pre>\n<pre style=\"padding-left: 30px\">write_only_port myport(0x10000);<\/pre>\n<pre style=\"padding-left: 30px\">myport |= 0x30;<\/pre>\n<pre style=\"padding-left: 30px\">myport &amp;= ~7;<\/pre>\n<pre>};<\/pre>\n<p>&nbsp;<\/p>\n<p>This sets bits 4 and 5 and clears bits 0, 1 and 2. The applications programmer needs to have no knowledge of how a write only port works, but can use them safely.<\/p>\n<p>The next job would be to make the member functions reentrant, but I will save that for another day &#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently wrote about write-only ports and discussed how they worked and the challenges presented to software developers who need&#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,435,511,300],"industry":[],"product":[],"coauthors":[],"class_list":["post-4319","post","type-post","status-publish","format-standard","hentry","category-news","tag-c","tag-device-drivers","tag-drivers","tag-embedded-software"],"_links":{"self":[{"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/4319","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/users\/71677"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/comments?post=4319"}],"version-history":[{"count":1,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/4319\/revisions"}],"predecessor-version":[{"id":10139,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/4319\/revisions\/10139"}],"wp:attachment":[{"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/media?parent=4319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/categories?post=4319"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/tags?post=4319"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/industry?post=4319"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/product?post=4319"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/coauthors?post=4319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}