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

在此感謝。

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