hecatia-elegua / bilge

Use bitsized types as if they were a feature of rust.
Apache License 2.0
173 stars 18 forks source link

Add field layout attr to manually specify bit range #81

Closed fubupc closed 1 year ago

fubupc commented 1 year ago

Hi @hecatia-elegua,

I was trying to learn low-level programming, e.g. SD driver, which interact a lot with MMIO register. Then I found several bitfield projects like modular-bitfield, bitbybit and this one, bilge.

After testing a while, to be honest, I feel bitbybit's design a little more fit for my usecase, especially the #[bit(<bit index>, rw)]/#[bits(<start bit>..=<end bit>)] syntax to manually specify field bit range, which is more readable when there are many gaps (reserved bits) between fields. But bitbybit misses an important feature : derive sensible Debug impl. Then I found bilge already resolved it by using "#[bitsize] as a scope" trick, brilliant idea!

So here I'm trying to add bitbybit style #[bit(..)]/#[bits(...)] to bilge. As a side-effect it allows overlapping field which might be helpful in some cases, e.g. multi-version register, or dangerous. (Maybe better to add a flag to switch between non-overlap and overlap mode?).

Here is a brief overview of the changes I made:

  1. Add an optional field layout argument to #[bitsize(...)], e.g. #[bitsize(32, manual)] means manually specify bit range for fields. Default is auto pack fields like before.
  2. Add 2 helper attributes, #[bit(<bit index>, <access mode>) for single bit field and #[bits(<start bit>..=<end bit>, <access mode>)] for multi bits field, which only allowed in manual layout. (For simplicity, access mode is not implemented yet.)

I'd appreciate it if you could review my changes and let me know if you have any feedback.

Thanks!

hecatia-elegua commented 1 year ago

See #28 and #9. I don't want to (basically) merge bitbybit into bilge, but go in a different direction.

Funny enough, you could build your own macro which converts your #[bits(...)] attributes to put reserved fields in any holes, before bilge takes over. I'm not so sure about overlapping fields, though. Have you encountered those? Can you send me some usecases? Thank you.

fubupc commented 1 year ago

Funny enough, you could build your own macro which converts your #[bits(...)] attributes to put reserved fields in any holes, before bilge takes over.

This is an interseting idea, didn't think of it before.

I'm not so sure about overlapping fields, though. Have you encountered those? Can you send me some usecases?

One case might be Card-Specific Data Register (CSD) in SD Card specification. The field structure of the CSD register are different depend on the specification version and card capacity. Alougth this can be model by enum or union in Rust, so it maybe not a very good case.

See https://github.com/hecatia-elegua/bilge/issues/28 and https://github.com/hecatia-elegua/bilge/issues/9. I don't want to (basically) merge bitbybit into bilge, but go in a different direction.

Got it, I'll close this issue then.