ARM:使用来自C或C++的位带内存



ARM Cortex支持位带状存储器,其中单个位映射到";字节";在某些地区。我相信RAM只有某些部分是带状的。我想使用C和C++的位带。

我该怎么做?看来我需要:

  1. 告诉编译器将某些变量放置在位带状区域中。怎样如果变量是struct的元素,该怎么办
  2. 当我想访问一个位时,告诉编译器将if (flags & 0x4)转换为if (flags_bb_04)。理想情况下,我希望这是自动的,如果不能使用位带,就回到前者

最简单的解决方案是使用正则变量并通过其位带地址访问它们。为此,您不需要";告诉编译器";任何东西例如,给定:

extern "C" volatile uint32_t* getBitBandAddress( volatile const void* address, int bit )
{
volatile uint32_t* bit_address = 0;
uint32_t addr = reinterpret_cast<uint32_t>(address);
// This bit maniplation makes the function valid for RAM
// and Peripheral bitband regions
uint32_t word_band_base = addr & 0xf0000000;
uint32_t bit_band_base = word_band_base | 0x02000000;
uint32_t offset = addr - word_band_base;
// Calculate bit band address
bit_address = reinterpret_cast<volatile uint32_t*>(bit_band_base + (offset * 32u) + (static_cast<uint32_t>(bit) * 4u));
return bit_address ;
}

你可以创建一个32位的";阵列";因此:

uint32_t word = 0 ;
uint32_t* bits = getBitbandAddress( word, 0 ) ;
bits[5] = 1 ; // word now == 32 (bit 5 set).

现在,如果您有一个具有外部或CCM内存的部件(例如(不可位带,则需要确保链接器(而不是编译器(将正常内存对象放置在可位带内存中。如何做到这一点是特定于工具链的,但例如在gnu中,您可能会有:

uint32_t word __attribute__ ((section ("ISRAM1"))) = 0 ;

位带可能对于原子访问外围寄存器中的单个位最有用。用于快速和线程安全访问。

一些编译器具有比特带意识,可以使用比特带自动优化单个比特比特字段访问。例如;

struct
{
bit1 : 1 ;
bit2 : 1 ;
} bits __attribute__ ((section ("BITBANDABLE")));

编译器(至少armcc v5(可以对此进行优化,以利用对bits.bit1bits.bit2的比特带访问。YMMV。

相关内容

  • 没有找到相关文章

最新更新