ucos2-cpu_c.c-位带操作

在uC-CPU/ARM-Cortex-M3/cpu_c.c中有两个位带访问的函数

//使用位带访问技术来对内存或外设地址addr中的第bit_nbr位进行清零操作
void  CPU_BitBandClr (CPU_ADDR       addr,
                      CPU_INT08U  bit_nbr)
{
	// CPU_ADDR 为16位
    CPU_ADDR  bit_word_off;
    CPU_ADDR  bit_word_addr;

	// 地址范围的判断
    if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
        (addr <= CPU_BIT_BAND_SRAM_REG_HI)) 
    {
    	/*
			 CPU_BIT_BAND_SRAM_BASE + ((addr‐CPU_BIT_BAND_SRAM_REG_LO)*8+bit_nbr)*4 =0x22000000 + (addr‐0x20000000)*32 + bit_nbr*4
		*/
        bit_word_off  = ((addr - CPU_BIT_BAND_SRAM_REG_LO) * 32) + (bit_nbr * 4);
        bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;

       *(volatile CPU_INT32U *)(bit_word_addr) = 0;

    } else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
               (addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
        bit_word_off  = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
        bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;

       *(volatile CPU_INT32U *)(bit_word_addr) = 0;
    }
}
//使用位带访问技术来对内存或外设地址addr中的第bit_nbr位进行置1操作
void  CPU_BitBandSet (CPU_ADDR    addr,
                      CPU_INT08U  bit_nbr)
{
    CPU_ADDR  bit_word_off;
    CPU_ADDR  bit_word_addr;


    if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
        (addr <= CPU_BIT_BAND_SRAM_REG_HI)) {
        bit_word_off  = ((addr - CPU_BIT_BAND_SRAM_REG_LO) * 32) + (bit_nbr * 4);
        bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;

       *(volatile CPU_INT32U *)(bit_word_addr) = 1;

    } else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
               (addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
        bit_word_off  = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
        bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;

       *(volatile CPU_INT32U *)(bit_word_addr) = 1;
    }
}

什么是位带访问技术:

它的对象可以是SRAM、I/O和外设空间。要实现对这些地方的某一位的操作。
它是这样做:*在寻址空间(32位对应的地址空间为 4GB)的另一地方,取个别名区空间,从这个地址开始处,每一个字(32BIT)对应SRAM或I/O的一位。

1MB SRAM 就可以有 32MB 的对应别名区空间,就是1位膨胀到32位(1 BIT 变为1个字节)。我们对这个别名区空间内的某一字操作(置0或置1),就等于它映射的 SRAM 或 I/O 相应的某地址的某一位的操作。

位带访问的好处

1、代码缩小、速度更快、效率更高、更安全。
2、一般操作是读-改-写,而位带别名区只有写的操作,防止了中断对读改写方式的影响。

应用

支持了位带操作(bit_band),位带别名区把每个比特膨胀成一个 32 位的字。 每个比特膨胀成一个32 位的字,就是把 1M 扩展为 32M 。位于 RAM 地址 0X200000000 的一个字节扩展为8个32位的字,扩展后每位相对应的的地址是:0X220000000,0X220000004,0X220000008。

支持位带操作的两个内存区的范围是:
0x2000 0000‐0x200F FFFF(SRAM 区中的最低1MB)
0x4000 0000‐0x400F FFFF(片上外设区中的最低1MB)

对 SRAM 位带区的某个比特,记该比特所在字节的地址为A,位序号为 n (0<=n<=7),则它在别名区的地址为:
AliasAddr = 0x22000000 + ((A‐0x20000000)*8+n)*4 =0x22000000 + (A‐0x20000000)*32 + n*4
(“*4”表示一个字为 4 个字节,“*8”表示一个字节中有 8 个比特。)

使用地址宏:
#define BITBAND(addr, bitnum) ((addr &0xF0000000)+0x2000000 + ((addr & 0xFFFFF)<<5) + (bitnum<<2))

使用指针的方式
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
MEM_ADDR(BITBAND((U32)&CRCValue, 1)) = 0x1

函数中的应用

bit_word_off  = ((addr - CPU_BIT_BAND_SRAM_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;

映射公式:
bit_word_offset = (byte_offset x 32) + (bit_number × 4)
bit_word_addr = bit_band_base + bit_word_offset
其中:
bit_word_offset是目标位在存取器位段区中的位置
bit_word_addr 是别名存储器区中字的地址,它映射到某个目标位。
bit_band_base 是别名区的起始地址。
byte_offset 是包含目标位的字节在位段中的序号
bit_number 是目标位所在位置(0-31)

参考博客:
http://blog.sina.com.cn/s/blog_9f27507501011gg1.html

在此感谢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章