Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to write lots of small unions from C into Java

Tags:

java

enums

union

I shall rewrite C code into Java. The core of original C code is a HW wrapper. In C we were using lots of unions for each HW register eg:

typedef union RegIntStatus
{
   u8 reg;
   struct
   {
      u8 bit0_abc:1;
      u8 bit1_cde:1;
      u8 bit2_xyz:1;
      u8 bit3_7_rsvd:5;
   } bits;
} regABC;

then we used it like

regABC r;
r.reg=0
r.bits.bit0_abc=1;
call(r.reg)

imagine there is plenty of those registers. Let say 40. How to implement it into java not having 40 class files? I was thinking to create one class like

univerasl_reg<T> { // where T will be some "enum"
  public byte b;
  public byte set(T bit_mask,bool val) {
    // here is compile error it does not know variable bit_mask.v
    if(val) {b |= bit_mask.v}     
    else b &= bit_mask.v ^ 0xFF;
  }
}

then one file can contains multiple enums like:

public static enum RegTst{
        b1_abc(0x01),
        b2_xyz(0x02),
        b3_klm(0x04);
        public byte v;
        RegTst(int val){
            v = (byte)val;
        }
    }

then I would use it like:

univerasl_reg<RegTst> rt1;
rt1.set(RegTst.b2_xyz,1)
call(rt1.b)

But it does not work because it seems I can not use enum variable .v in univerasl_reg. It yields "Java canot find symbol v". Do you know why? Do you know how to code registers in order to have
- preferably one file
- type control between different registers (eg

new univerasl_reg<RegTst>.set(RegTst_OTHER.b2_xyz,1)
shall lead to error as I'm not using RegTst but RegTst_OTHER)
- and mnemonic for bits (eg RegTst.b1_abc)
like image 790
Vit Bernatik Avatar asked Feb 23 '15 17:02

Vit Bernatik


1 Answers

Java Generics are a feature of the static type system only. When you accept any T for the type parameter, the static type system has no basis to conclude that this type has an instance variable v. Your choice of enums complicates things further because enums cannot have an arbitrary superclass.

I would suggest the following:

  1. rely on polymorphism and hide v behind a method;
  2. declare an interface with this method;
  3. make all enums implement the interface;
  4. use the interface as the upper bound on T.

In code:

public interface Mask {
   byte v();
}

public class UniversalReg<T extends Mask> {
  public byte b;
  public byte set(T mask, boolean val) {
     if (val) b |= mask.v();
     else b &= ~mask.v();
  }
}

public enum RegTst implements Mask {
    b1_abc(0x01),
    b2_xyz(0x02),
    b3_klm(0x04);

    private final byte v;
    private RegTst(int val) {
        v = (byte)val;
    }

    @Override public byte v() { return v; }
}
like image 158
Marko Topolnik Avatar answered Nov 15 '22 01:11

Marko Topolnik