Sign In
Forgot Password?
Sign In | | Create Account

Write-only ports

Colin Walls

Colin Walls

Posted Jan 14, 2013
2 Comments

I often joke that my job puts me in a difficult position, as I am a software guy and a very large proportion of Mentor Graphics employees are hardware design specialists; I am consorting with the “the enemy”. Although I am making a light-hearted comment, there is, sadly, something of an “us and them” attitude between software and hardware teams in many companies. It is in everybody’s interest to make this a thing of the past.

Sometimes, it seems as if this view is reasonable, when hardware seems to be designed specifically to make life hard for software developers …

The issue of hardware being challenging to control from software is well known. The whole idea of device drivers was conceived, as much as anything, to hide the nastiness of such interfaces from non-experts. My favorite example of hardware that seems to have designed for intentional aggravation is a write-only port.

This type of interface has a register, to which data may be written, but from which the current value may not be read back. This may be problematic because the 8-, 16- or 32-bit port may consist of a number of single- or multi-bit registers with unrelated functionality. This means that different parts of the software may need to access the port and there are plenty of opportunities for unintentional interference. For example, to set the bottom 2 bits of the port without affecting the other bits, the following code would seem obvious:

WOPORT |= 0x03;

However, this construct will not work, as the |= operator generates code which will read the port [and get invalid data or trigger an exception] before writing an updated value. The solution is simple enough: keep a “shadow” copy of the port data and use that each time an update is required, like this:

woport_shadow |= 0x03;
WOPORT = woport_shadow;

This is quite straightforward, but there are a few things to take care of:

  1. The port and the shadow data must be correctly initialized.
  2. Code which accesses the port must always utilize the shadow.
  3. Re-entrancy may be an issue. If an interrupt occurred between the updating of the shadow and the writing to the port, another thread [task or ISR] might utilize the port and the shadow could get out of synch.

All of these issues may be addressed by careful code design. Probably the best approach is to encapsulate the access to a port inside a function, thus providing a common API. Another approach might be to use C++ to encapsulate the details of write-only port access. I will look at that approach on another occasion.

Incidentally, the code above might be an ideal application for my approach to binary constants, which I wrote about some time ago; instead of 0x03 you would use b00000011.

drivers

More Blog Posts

About Colin Walls Follow on Twitter

Colin WallsI have over twenty-five years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, I am a member of the marketing team of the Mentor Graphics Embedded Systems Division, and am based in the UK. Away from work, I have a wide range of interests including photography and trying to point my two daughters in the right direction in life. Learn more about Colin, including his go-to karaoke song and the best parts of being British: http://go.mentor.com/3_acv Visit The Colin Walls Blog

More Posts by Colin Walls

Comments 2

Post a Comment
This topic (write only ports) also exposes another one of the hazards of bit fields. Seductive as they are, they obscure what's really going on behind the scenes. Typically, writing fields via bit fields involve reading, shifting and/or masking bits, and then writing back. Particularly when only some of the bits are write-only (it happens), it's easy to review the bit-field code and assume everything will work. I believe you (Colin) wrote about bit fields in your book (haven't seen the updated version released earlier this year), and maybe even mentioned something like this? Don't mean to hijack the thread topic & rant against bit fields, but... well, I really feel the need to rant against bit fields. They have their place, but they're too easy to use incorrectly, and their lack of portability can really cause trouble. Finally, I agree about using C++ to encapsulate the details of hardware complexity like this. Looking forward to your follow-up post down the road.

Dan S
12:50 AM Jan 15, 2013

Good input. Thanks Dan. I did not even touch on the idea of a port where just some of the bits are write-only, but the approach would be identical. This is, indeed, a topic that I discuss in greater detail in my book - "Embedded Software: The Works" Incidentally, in defence of hardware designers, a write-only port is not [just] designed to make programming hard. It does eliminate the extra electronics that would be required to support read back. As is so often the case, a saving on hardware has a cost in the software. It was for ever thus.

Colin Walls
10:55 AM Jan 15, 2013

Add Your Comment

Please complete the following information to comment or sign in.

(Your email will not be published)

Archives

 
Online Chat