如何将 C 中的许多小联合写入 Java
how to write lots of small unions from C into Java
我要把C代码重写成Java。原始 C 代码的核心是硬件包装器。在 C 中,我们为每个 HW 寄存器使用了很多联合,例如:
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;
然后我们像
一样使用它
regABC r;
r.reg=0
r.bits.bit0_abc=1;
call(r.reg)
想象一下有很多这样的寄存器。比方说 40。如何将它实现到 java 而不是 40 class 个文件?我想创建一个 class 像
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;
}
}
然后一个文件可以包含多个枚举,例如:
public static enum RegTst{
b1_abc(0x01),
b2_xyz(0x02),
b3_klm(0x04);
public byte v;
RegTst(int val){
v = (byte)val;
}
}
那么我会像这样使用它:
univerasl_reg<RegTst> rt1;
rt1.set(RegTst.b2_xyz,1)
call(rt1.b)
但它不起作用,因为我似乎无法在 univerasl_reg 中使用枚举变量 .v。它产生 "Java canot find symbol v"。你知道为什么吗?
你知道如何对寄存器进行编码以便
- 最好是一个文件
- 不同寄存器之间的类型控制(例如
new univerasl_reg.set(RegTst_OTHER.b2_xyz,1)
会导致错误,因为我没有使用 RegTst 但 RegTst_OTHER)
- 和位的助记符(例如 RegTst.b1_abc)
Java 泛型只是静态类型系统的一个特性。当你为类型参数接受任何 T
时,静态类型系统没有根据断定此类型具有实例变量 v
。您对枚举的选择使事情变得更加复杂,因为枚举不能具有任意超类。
我建议如下:
- 依赖多态性并隐藏
v
在方法; 后面
- 用这个方法声明一个接口;
- 使所有枚举实现接口;
- 使用接口作为
T
的上限。
在代码中:
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; }
}
我要把C代码重写成Java。原始 C 代码的核心是硬件包装器。在 C 中,我们为每个 HW 寄存器使用了很多联合,例如:
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;
然后我们像
一样使用它regABC r;
r.reg=0
r.bits.bit0_abc=1;
call(r.reg)
想象一下有很多这样的寄存器。比方说 40。如何将它实现到 java 而不是 40 class 个文件?我想创建一个 class 像
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;
}
}
然后一个文件可以包含多个枚举,例如:
public static enum RegTst{
b1_abc(0x01),
b2_xyz(0x02),
b3_klm(0x04);
public byte v;
RegTst(int val){
v = (byte)val;
}
}
那么我会像这样使用它:
univerasl_reg<RegTst> rt1;
rt1.set(RegTst.b2_xyz,1)
call(rt1.b)
但它不起作用,因为我似乎无法在 univerasl_reg 中使用枚举变量 .v。它产生 "Java canot find symbol v"。你知道为什么吗?
你知道如何对寄存器进行编码以便
- 最好是一个文件
- 不同寄存器之间的类型控制(例如
new univerasl_reg会导致错误,因为我没有使用 RegTst 但 RegTst_OTHER).set(RegTst_OTHER.b2_xyz,1)
- 和位的助记符(例如 RegTst.b1_abc)
Java 泛型只是静态类型系统的一个特性。当你为类型参数接受任何 T
时,静态类型系统没有根据断定此类型具有实例变量 v
。您对枚举的选择使事情变得更加复杂,因为枚举不能具有任意超类。
我建议如下:
- 依赖多态性并隐藏
v
在方法; 后面
- 用这个方法声明一个接口;
- 使所有枚举实现接口;
- 使用接口作为
T
的上限。
在代码中:
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; }
}