درود
یکی از قابلیت های Cortex-M3 مورد bit-banding است .
مطالب زیر اطلاعات من در این باره است اگر اشکال یا نقصی داره در ادامه همین پست اصلاح فرمائید.
اگر به memory -map یک CM3 نگاه کنیید به دو ناحیه بر میخورید که اسمشون عجیب غریبه :
بله Bit-band alias و Bit band region:
حالا این دو ناحیه چی هستند و کاربردشون چیه ؟
تصور کنید که یک ناحیه از حافظه (peripheral یا sram ) وجود دارد که در آنجا شما متغییر های بیتی تعریف کرده اید.
برای اینکه این به این بیت ها دسترسی داشته باشید باید برنامه نویسی کنید (اصطلاح انگلیسی bit manipulation )
http://en.wikipedia.org/wiki/Bit_manipulation
و در واقع عملی که اتفاق میوفته اینه که یک بار محتوای کامل یک word که bit داخل آن قرار دارد خوانده میشه (Read)
در مرحله بعد باید تغیر که مد نظر ما هست اعمال بشه (Modify )
و در نهایت در محل اصلی نوشته شود (Write )
این 3 عمل را R-M-W میگویند
http://infocenter.arm.com/help/index.../Bcfiddig.html
خوب حالا که چی ؟!
حالا تصور کنید بجای اینکار یک ناحیه وجود داره که هر word دقیقا روی یکbit مپ شده!
یعنی چی ؟ یعنی اگر روی این word بنویسی 1 دقیقا یک بیت متناظر در ناحیه از قبل مشخص شده یک میشه و بلعکس.
فقط توجه کنید که هر دو ناحایه مشخص هستند هم بیت و هم word
برای بیت ناحیه به نام Bit-band region در نظر گرفته شده و برای word ناحیه به نام Bit-band alias .
پس شما به هر بیت یصورت مستقیم با استفاده از دستور LDR دسترسی دارید .
Bit-band region در 1MB پایین SRAm و یا Peripheral را جای دارد.
و Bit-band alias در بالای ناحیه قبلی و 32MB از فضای حافظه را دارد.
خب حالا برای اینکه بیت مورد نظر تغییر کنه کدام word باید.........
یک فرمول هست که باید استفاده بشه :
bit_word_offset جایگاه بیت مورد نظر
bit_word_addr آدرس word در alias memory
bit_band_base آدرس شروع alias
byte_offset تعداد بایت های که در ناحیه Bit-banding است
bit_number از 0 تا 7 جایگاه بیت مورد نظر هست .
عکس زیر مسئله رو بهتر نشون میده :
حالا حسن این کار چیه اول یه خروجی این دو روش توجه کنید :
روش اول (R-M-W):
و این خروجی :
و این روش Bit-banding:
و این خروجی :
و یا در کامپایلر keil با __attribute__((bitband));
راه اول (R-M-W):
خروجی :
و راه Bit-banding :
و خروجی :
پس حجم و سرعت رو دید چه کرد!
ولی یک جنبه دیگه هم هست .
در R-M-W یک خطر بلقوه نهفته شده .
شما R کردید میخواید M کنید که یهو اینتراپت میخوره
در روتین اینتراپت دیتای که R شده تغییر میکنه
و حدس بزنید چه فاجعه ای ..............
فراموش نشه این یک قابلیت سخت افزاری نه [s]نرم افزاری [/s]
امیدوارم مفید باشه .
یکی از قابلیت های Cortex-M3 مورد bit-banding است .
مطالب زیر اطلاعات من در این باره است اگر اشکال یا نقصی داره در ادامه همین پست اصلاح فرمائید.
اگر به memory -map یک CM3 نگاه کنیید به دو ناحیه بر میخورید که اسمشون عجیب غریبه :
بله Bit-band alias و Bit band region:
حالا این دو ناحیه چی هستند و کاربردشون چیه ؟
تصور کنید که یک ناحیه از حافظه (peripheral یا sram ) وجود دارد که در آنجا شما متغییر های بیتی تعریف کرده اید.
برای اینکه این به این بیت ها دسترسی داشته باشید باید برنامه نویسی کنید (اصطلاح انگلیسی bit manipulation )
http://en.wikipedia.org/wiki/Bit_manipulation
و در واقع عملی که اتفاق میوفته اینه که یک بار محتوای کامل یک word که bit داخل آن قرار دارد خوانده میشه (Read)
در مرحله بعد باید تغیر که مد نظر ما هست اعمال بشه (Modify )
و در نهایت در محل اصلی نوشته شود (Write )
این 3 عمل را R-M-W میگویند
http://infocenter.arm.com/help/index.../Bcfiddig.html
خوب حالا که چی ؟!
حالا تصور کنید بجای اینکار یک ناحیه وجود داره که هر word دقیقا روی یکbit مپ شده!
یعنی چی ؟ یعنی اگر روی این word بنویسی 1 دقیقا یک بیت متناظر در ناحیه از قبل مشخص شده یک میشه و بلعکس.
فقط توجه کنید که هر دو ناحایه مشخص هستند هم بیت و هم word
برای بیت ناحیه به نام Bit-band region در نظر گرفته شده و برای word ناحیه به نام Bit-band alias .
پس شما به هر بیت یصورت مستقیم با استفاده از دستور LDR دسترسی دارید .
Bit-band region در 1MB پایین SRAm و یا Peripheral را جای دارد.
و Bit-band alias در بالای ناحیه قبلی و 32MB از فضای حافظه را دارد.
خب حالا برای اینکه بیت مورد نظر تغییر کنه کدام word باید.........
یک فرمول هست که باید استفاده بشه :
bit_word_offset = (byte_offset x 32) + (bit_number × 4)
bit_word_addr = bit_band_base + bit_word_offset
bit_word_addr = bit_band_base + bit_word_offset
bit_word_offset جایگاه بیت مورد نظر
bit_word_addr آدرس word در alias memory
bit_band_base آدرس شروع alias
byte_offset تعداد بایت های که در ناحیه Bit-banding است
bit_number از 0 تا 7 جایگاه بیت مورد نظر هست .
عکس زیر مسئله رو بهتر نشون میده :
حالا حسن این کار چیه اول یه خروجی این دو روش توجه کنید :
روش اول (R-M-W):
کد:
int test; test |=1<<1;
کد:
0x0000219A 486C LDR r0,[pc,#432] ; @0x0000234C 0x0000219C 6800 LDR r0,[r0,#0x00] 0x0000219E F0400002 ORR r0,r0,#0x02 0x000021A2 496A LDR r1,[pc,#424] ; @0x0000234C 0x000021A4 6008 STR r0,[r1,#0x00]]
کد:
/* Bit band SRAM definitions */ #define BITBAND_SRAM_REF 0x20000000 #define BITBAND_SRAM_BASE 0x22000000 #define BITBAND_SRAM(a,b) ((BITBAND_SRAM_BASE + ((a-BITBAND_SRAM_REF)<<5) + (b<<2))) // Convert SRAM address /* Bit band PERIPHERAL definitions */ #define BITBAND_PERI_REF 0x40000000 #define BITBAND_PERI_BASE 0x42000000 #define BITBAND_PERI(a,b) ((BITBAND_PERI_BASE + ((a-BITBAND_PERI_REF)<<5) + (b<<2))) // Convert PERI address /* Basic bit band function definitions */ #define BITBAND_SRAM_ClearBit(a,b) (*(volatile uint32_t *) (BITBAND_SRAM(a,b)) = 0) #define BITBAND_SRAM_SetBit(a,b) (*(volatile uint32_t *) (BITBAND_SRAM(a,b)) = 1) #define BITBAND_SRAM_GetBit(a,b) (*(volatile uint32_t *) (BITBAND_SRAM(a,b))) #define BITBAND_PERI_ClearBit(a,b) (*(volatile uint32_t *) (BITBAND_PERI(a,b)) = 0) #define BITBAND_PERI_SetBit(a,b) (*(volatile uint32_t *) (BITBAND_PERI(a,b)) = 1) #define BITBAND_PERI_GetBit(a,b) (*(volatile uint32_t *) (BITBAND_PERI(a,b))) /* Variable address in SRAM * should be in one of two range: * + 0x20000000 - 0x20007FFF: for SRAM * + 0x20098000 - 0x200980BF: for GPIO */ #define VAR_ADDRESS 0x20000000 int var __attribute__((at(0x20000000))); #define VAR_BIT 30 //Bit 0~31
کد:
BITBAND_SRAM_SetBit(VAR_ADDRESS,VAR_BIT);
کد:
0x000021A6 2001 MOVS r0,#0x01 0x000021A8 F04F5108 MOV r1,#0x22000000 0x000021AC 6788 STR r0,[r1,#0x78]
راه اول (R-M-W):
کد:
struct { int b:1; int c:1; int j:1; }test_struct;
کد:
test_struct.b=1;
کد:
0x000021AE 4868 LDR r0,[pc,#416] ; @0x00002350 0x000021B0 6800 LDR r0,[r0,#0x00] 0x000021B2 F0200001 BIC r0,r0,#0x01 0x000021B6 1C40 ADDS r0,r0,#1 0x000021B8 4965 LDR r1,[pc,#404] ; @0x00002350 0x000021BA 6008 STR r0,[r1,#0x00]
کد:
typedef struct { int i : 1; int j :1; int s :1; } BB __attribute__((bitband));
کد:
BB bb __attribute__((at(0x20000004)));
کد:
0x000021BC 2101 MOVS r1,#0x01 0x000021BE 4861 LDR r0,[pc,#388] ; @0x00002344 0x000021C0 67C1 STR r1,[r0,#0x7C]
ولی یک جنبه دیگه هم هست .
در R-M-W یک خطر بلقوه نهفته شده .
شما R کردید میخواید M کنید که یهو اینتراپت میخوره
در روتین اینتراپت دیتای که R شده تغییر میکنه
و حدس بزنید چه فاجعه ای ..............
فراموش نشه این یک قابلیت سخت افزاری نه [s]نرم افزاری [/s]
امیدوارم مفید باشه .
دیدگاه