目前,我正在一个项目上与ARM M4 F的arm-gcc和eclipse。
我已经在结构中声明了位域来访问IO寄存器。请参见示例:
struct abc{
volatile U32 a:1;
volatile U32 b:1;
volatile U32 c:30;
}
现在,这些结构体中的一些被Map到外围设备上,这些外围设备使用一组“设置和清除”寄存器。
将1U写入设置寄存器以设置特定位,将1U写入清除寄存器以清除特定位。
但是如果设置了一个位,它也会反映为在读取的清除寄存器中设置。
所以abc_set.a = 1U;
的结果是abc_clear.a == 1U
在我的代码中,如果已经写了:abc_clear.a = 1U;
这将导致arm-gcc生成:
ldr.w r0, [r1, #128] ; 0x80
orr.w r0, r0, #536870912 ; 0x20000000
str.w r0, [r1, #128] ; 0x80
编译器强制执行读取-修改-写入方法。
但是如果其他位在abc_clear寄存器中反映为“1U”,则它们也会被写入为1U,随后也会被清除。
"我的问题是"
我怎样才能强制gcc对特定的寄存器使用“只写”方案?
我正在寻找类似的东西:
struct abc{
#pragma "Only-Write" / or attribute((only-write))
volatile U32 a:1;
#pragma "R-M-W allowed"
volatile U32 b:1;
volatile U32 c:30;
}
1条答案
按热度按时间zzlelutf1#
我已经在结构中声明了位域来访问IO寄存器。
你不能用位域来做这件事。基本上,位域不适合这个目的。uP没有指令来写或读几个(少于8)位 *。你浪费了时间
你需要用这种传统的方式
和用法:
结果代码:
当你需要RMW时,你只需自己做:
编译器会生成正确的代码
另一种方法是使用临时变量(不是很方便的方法)。