Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unclear use of (void) with register value

Tags:

c

casting

void

I have some example code (from Nordic), which includes next lines:

    NRF_RADIO->EVENTS_END = 0;
    (void)NRF_RADIO->EVENTS_END;

NRF_RADIO->EVENTS_END is an embedded register which is set to 0 at the first line.

Can someone explain what is the meaning of the second line?

Thanks Yaron

like image 326
yaron Avatar asked May 07 '17 09:05

yaron


1 Answers

The second line "only" reads the register back. It does so, explicitly ignoring the actual value which is read, by prepending the (void) cast to void.

The line has two specialties which probably makes understanding it non-trivial:

  1. reading without using the value, why?
  2. apart from not using the value, also say explicitly that it gets ignored, why?

The reason for 1 is very likely the fact that (according to OPs statement) a peripheral register is involved. This can imply mechanisms which require a seemingly useless read. For example:

  • the chip supplier has simply required, that a dummy read is necessary for reliable, chronologically predictable effect of the preceding write access;
    this is sometimes (at least by me and my colleagues) described as the "recommended sequence", i.e. a not neccessarily intuitive set of statements, proscribed by manufacturer to be observed to ensure functionality
  • the write access has a reliable effect, but in order to ensure the desired chronological order of it, in comparison with other statements, it is neccessary to read back from the register
    • this is usually accompanied by a "volatile" keyword in the declarations which represent the register
    • this possibly is a (separate) "recommended sequence" which is only necessary for this chronology-affected use case
    • note that two consecutive statements two different special registers can have differently "fast" effect, so that the second one takes effect before the first one
    • one example is a first access to a peripheral like a port, which is connected via a slow bus;
      followed by a second access to a faster connected peripheral, e.g. a memory-mapped interrupt controller;
      the need for chronological order can arise from not wanting to reconfigure the interrupt before the port has been reconfigured

The reason for 2 is completely separate and can for example be:

  • the (possible special, hardware specific) compiler gives warnings for all ignored return values;
    many compilers do so, because ignoring return values is usually a potential source of errors or could indicate a fundamental misunderstanding by the programmer
  • on top of the compiler, static analysis tools are used, which have similar goals: detect anything, which by experience might indicate errors and improved maintainability via coding styles

Edited for readability and better structure, without changing the basic logic; in order to hopefully prevent misunderstandings, which I assume the two downvoters had. If there are sound reasons for downvoting, please let me know.

like image 134
Yunnosch Avatar answered Oct 03 '22 17:10

Yunnosch



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!