-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I2C API is mixing two incompatible definitions of bit-fields #4009
Comments
by Andy Ross: Agreed, that's sort of a mess. Even beyond the portability issues, providing an un-typechecked variant to a typesafe API is kinda crazy. Any idea how much existing code uses the "raw" field? Guess I could run sanitycheck to find out... |
by Piotr Mienkowski: Actually, looking at the state of current Zephyr API we tend not to use C bit-fields but rather #defines to implement bit-fields. The only other driver using C bit-fields in its API is DMA. One difference between using C style bit-fields and #defines is that with C bit-fields if we are assigning to an automatic variable we have to explicitly assign values of all bit-fields. With #define only those bit-fields that we want to change from its default behavior (assuming value 0 is the default). Defining configurations with many optional flags is much more handy with #defines. Another advantage of using #defines is much more compact assembly code. Here is an example:
But then of course with #defines there is no type checking. And setting and getting a value of e.g. 4 bit wide bit-field is a challenge of its own. In fact the above assignment to cfg.raw contains a bug. |
by Andy Ross: Nah, it's true it's not a common paradigm in OS code, but the assembly example is specious. Those two examples do different things: one writes the whole word assuming everything not specified is zero, the other carefully changes only the bits requested. You can write an assignment for a whole word with C bitfields using a structure literal and it generates the same code that the integer assignment would. It's not like I think preprocessor bitfields should be disallowed, but if we're going to take an API that has both, we should choose to keep the typesafe one. :) |
by Piotr Mienkowski:
Good point. I should have used an initializer list
But the resulting assembly code is the same.
I'm using Zephyr SDK 0.9.2-rc2 and CONFIG_DEBUG is not set, so all the optimizations are on. Also an initializer list can only be used at the place the variable is defined. That's a bit limiting. |
I think we can close this with the merger of PR #4254 |
Reported by Piotr Mienkowski:
Zephyr's I2C API contains the following construct
This is incorrect. C99 §6.7.2.1, paragraph 10 says: "The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined.". I.e. - using union dev_config as an example - compiler is free to map use_10_bit_addr either to MSB or to LSB. The two methods of specifying bit fields are not equivalent and should not be mixed.
(Imported from Jira ZEP-2579)
The text was updated successfully, but these errors were encountered: