试图为 STM32F4 UART 推出我自己的代码。该芯片的一个特点是,如果您像 GNAT 编译器那样使用字节寻址来设置单个位,则半字的另一个字节中的相应位将被设置。数据表说使用半字寻址。有没有办法告诉编译器这样做?我试过 CR1_register'Size use 16;
但这没有效果。写入整个 16 位字有效,但您无法设置命名位。
在 AdaCore Ada Drivers Library中使用的 GNAT 方法是使用 GNAT-only 方面Volatile_Full_Access,GNAT 参考手册中说到
这在效果上与 pragma Volatile 类似,不同之处在于对对象的任何引用都保证仅通过读取或写入对象所有位的指令来完成。此外,如果对象是复合类型,则对对象子组件的任何引用都保证读取和/或写入对象的所有位。
目的是这适用于某些机器上的内存映射 I/O 设备。请注意,有两个重要方面与 pragma Atomic 不同。首先,对 Volatile_Full_Access 对象的引用不是 RM 9.10 意义上的顺序操作,因此不会创建同步点。其次,在 pragma Atomic 的情况下,如果引用不是对整个对象,则不能保证所有位都将被访问;在这种情况下,编译器只允许(并且通常会)访问对象的一部分。
他们的代码是
-- Control register 1
type CR1_Register is record
-- Send break
SBK : Boolean := False;
...
end record
with Volatile_Full_Access, Size => 32,
Bit_Order => System.Low_Order_First;
for CR1_Register use record
SBK at 0 range 0 .. 0;
...
end record;
Run Code Online (Sandbox Code Playgroud)