Код
void MailboxWrite(uint32_t val, uint8_t channel)
{
while(*((uint32_t *)(0x2000B898))&0x80000000);
*((uint32_t *)(0x2000B8A0))=val+channel;
}
{
while(*((uint32_t *)(0x2000B898))&0x80000000);
*((uint32_t *)(0x2000B8A0))=val+channel;
}
Функция читает регистр статуса по адресу 0x2000B898 и ждет нолика в старшем бите, после этого записывает в 0x2000B8A0 значения.
Компилятор версии ARM/GNU C Compiler 4.7.3, шел в комплекте с Atmel Studio 6.1 (папка с именем 4.7.3.1029)
Опции компилятора использую следующие:
Код
-marm -DBCM2835 -DDEBUG -O0 -ffunction-sections -mlong-calls -g2 -Wall -mcpu=arm1176jzf-s -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)"
Опции линкера:
Код
-marm -nostartfiles -nodefaultlibs -nostdlib -Wl,-Map="$(OutputFileName).map" -Wl,--start-group -lm -Wl,--end-group -L"../cmsis/linkerScripts" -Wl,--gc-sections -mcpu=arm1176jzf-s
Компилирую с оптимизацией 0 (-O0), получаю листинг:
Код
void MailboxWrite(uint32_t val, uint8_t channel)
{
8028: e52db004 push {fp}; (str fp, [sp, #-4]!)
802c: e28db000 add fp, sp, #0
8030: e24dd00c sub sp, sp, #12
8034: e50b0008 str r0, [fp, #-8]
8038: e1a03001 mov r3, r1
803c: e54b3009 strb r3, [fp, #-9]
while(*((uint32_t *)(0x2000B898))&0x80000000);
8040: e1a00000 nop; (mov r0, r0)
8044: e59f3028 ldr r3, [pc, #40]; 8074 <MailboxWrite+0x4c>
8048: e5933000 ldr r3, [r3]
804c: e3530000 cmp r3, #0
8050: bafffffb blt 8044 <MailboxWrite+0x1c>
*((uint32_t *)(0x2000B8A0))=val+channel;
8054: e59f301c ldr r3, [pc, #28]; 8078 <MailboxWrite+0x50>
8058: e55b1009 ldrb r1, [fp, #-9]
805c: e51b2008 ldr r2, [fp, #-8]
8060: e0812002 add r2, r1, r2
8064: e5832000 str r2, [r3]
}
8068: e28bd000 add sp, fp, #0
806c: e8bd0800 pop {fp}
8070: e12fff1e bx lr
8074: 2000b898 .word 0x2000b898
8078: 2000b8a0 .word 0x2000b8a0
{
8028: e52db004 push {fp}; (str fp, [sp, #-4]!)
802c: e28db000 add fp, sp, #0
8030: e24dd00c sub sp, sp, #12
8034: e50b0008 str r0, [fp, #-8]
8038: e1a03001 mov r3, r1
803c: e54b3009 strb r3, [fp, #-9]
while(*((uint32_t *)(0x2000B898))&0x80000000);
8040: e1a00000 nop; (mov r0, r0)
8044: e59f3028 ldr r3, [pc, #40]; 8074 <MailboxWrite+0x4c>
8048: e5933000 ldr r3, [r3]
804c: e3530000 cmp r3, #0
8050: bafffffb blt 8044 <MailboxWrite+0x1c>
*((uint32_t *)(0x2000B8A0))=val+channel;
8054: e59f301c ldr r3, [pc, #28]; 8078 <MailboxWrite+0x50>
8058: e55b1009 ldrb r1, [fp, #-9]
805c: e51b2008 ldr r2, [fp, #-8]
8060: e0812002 add r2, r1, r2
8064: e5832000 str r2, [r3]
}
8068: e28bd000 add sp, fp, #0
806c: e8bd0800 pop {fp}
8070: e12fff1e bx lr
8074: 2000b898 .word 0x2000b898
8078: 2000b8a0 .word 0x2000b8a0
Вроде всё работает по плану, только какие-то ненужные манипуляции с sp и fp, вобщем, много лишнего.
Компилирую с оптимизацией 1 (-O1), получаю листинг:
Код
void MailboxWrite(uint32_t val, uint8_t channel)
{
while(*((uint32_t *)(0x2000B898))&0x80000000);
8020: e59f301c ldr r3, [pc, #28]; 8044 <MailboxWrite+0x24>
8024: e5933898 ldr r3, [r3, #2200]; 0x898
8028: e3530000 cmp r3, #0
802c: ba000003 blt 8040 <MailboxWrite+0x20>
*((uint32_t *)(0x2000B8A0))=val+channel;
8030: e0810000 add r0, r1, r0
8034: e59f3008 ldr r3, [pc, #8]; 8044 <MailboxWrite+0x24>
8038: e58308a0 str r0, [r3, #2208]; 0x8a0
803c: e12fff1e bx lr
8040: eafffffe b 8040 <MailboxWrite+0x20>
8044: 2000b000 .word 0x2000b000
{
while(*((uint32_t *)(0x2000B898))&0x80000000);
8020: e59f301c ldr r3, [pc, #28]; 8044 <MailboxWrite+0x24>
8024: e5933898 ldr r3, [r3, #2200]; 0x898
8028: e3530000 cmp r3, #0
802c: ba000003 blt 8040 <MailboxWrite+0x20>
*((uint32_t *)(0x2000B8A0))=val+channel;
8030: e0810000 add r0, r1, r0
8034: e59f3008 ldr r3, [pc, #8]; 8044 <MailboxWrite+0x24>
8038: e58308a0 str r0, [r3, #2208]; 0x8a0
803c: e12fff1e bx lr
8040: eafffffe b 8040 <MailboxWrite+0x20>
8044: 2000b000 .word 0x2000b000
Вот тут лишних манипуляций не происходит, но пропадает цикл while, один раз проверяется статусный бит (802с) и проц уходит в бесконечный цикл (8040).
Компилирую с оптимизацией 2 (-O2), получаю листинг:
Код
void MailboxWrite(uint32_t val, uint8_t channel)
{
while(*((uint32_t *)(0x2000B898))&0x80000000);
8020: e59f3018 ldr r3, [pc, #24]; 8040 <MailboxWrite+0x20>
8024: e5932898 ldr r2, [r3, #2200]; 0x898
8028: e3520000 cmp r2, #0
802c: ba000002 blt 803c <MailboxWrite+0x1c>
*((uint32_t *)(0x2000B8A0))=val+channel;
8030: e0810000 add r0, r1, r0
8034: e58308a0 str r0, [r3, #2208]; 0x8a0
8038: e12fff1e bx lr
803c: eafffffe b 803c <MailboxWrite+0x1c>
8040: 2000b000 .word 0x2000b000
{
while(*((uint32_t *)(0x2000B898))&0x80000000);
8020: e59f3018 ldr r3, [pc, #24]; 8040 <MailboxWrite+0x20>
8024: e5932898 ldr r2, [r3, #2200]; 0x898
8028: e3520000 cmp r2, #0
802c: ba000002 blt 803c <MailboxWrite+0x1c>
*((uint32_t *)(0x2000B8A0))=val+channel;
8030: e0810000 add r0, r1, r0
8034: e58308a0 str r0, [r3, #2208]; 0x8a0
8038: e12fff1e bx lr
803c: eafffffe b 803c <MailboxWrite+0x1c>
8040: 2000b000 .word 0x2000b000
Тут тоже самое, что и О1, но не происходит перезагрузки регистра с адресом, цикл while так же отсутствует.
Компилирую с оптимизацией 3 (-O3), получаю листинг:
Код
void MailboxWrite(uint32_t val, uint8_t channel)
{
8020: e59f3018 ldr r3, [pc, #24]; 8040 <MailboxWrite+0x20>
8024: e5932898 ldr r2, [r3, #2200]; 0x898
8028: e3520000 cmp r2, #0
802c: aa000000 bge 8034 <MailboxWrite+0x14>
8030: eafffffe b 8030 <MailboxWrite+0x10>
while(*((uint32_t *)(0x2000B898))&0x80000000);
*((uint32_t *)(0x2000B8A0))=val+channel;
8034: e0810000 add r0, r1, r0
8038: e58308a0 str r0, [r3, #2208]; 0x8a0
803c: e12fff1e bx lr
8040: 2000b000 .word 0x2000b000
{
8020: e59f3018 ldr r3, [pc, #24]; 8040 <MailboxWrite+0x20>
8024: e5932898 ldr r2, [r3, #2200]; 0x898
8028: e3520000 cmp r2, #0
802c: aa000000 bge 8034 <MailboxWrite+0x14>
8030: eafffffe b 8030 <MailboxWrite+0x10>
while(*((uint32_t *)(0x2000B898))&0x80000000);
*((uint32_t *)(0x2000B8A0))=val+channel;
8034: e0810000 add r0, r1, r0
8038: e58308a0 str r0, [r3, #2208]; 0x8a0
803c: e12fff1e bx lr
8040: 2000b000 .word 0x2000b000
Тут уже сразу зацикливается никуда не перепрыгивая (8030)
Компиляция с оптимизацией s (-Os), приводит к результату -O2.
Еще есть опция -Ofast
Код
void MailboxWrite(uint32_t val, uint8_t channel)
{
8020: e59f3018 ldr r3, [pc, #24]; 8040 <MailboxWrite+0x20>
8024: e5932898 ldr r2, [r3, #2200]; 0x898
8028: e3520000 cmp r2, #0
802c: aa000000 bge 8034 <MailboxWrite+0x14>
8030: eafffffe b 8030 <MailboxWrite+0x10>
while(*((uint32_t *)(0x2000B898))&0x80000000);
*((uint32_t *)(0x2000B8A0))=val+channel;
8034: e0810000 add r0, r1, r0
8038: e58308a0 str r0, [r3, #2208]; 0x8a0
803c: e12fff1e bx lr
8040: 2000b000 .word 0x2000b000
{
8020: e59f3018 ldr r3, [pc, #24]; 8040 <MailboxWrite+0x20>
8024: e5932898 ldr r2, [r3, #2200]; 0x898
8028: e3520000 cmp r2, #0
802c: aa000000 bge 8034 <MailboxWrite+0x14>
8030: eafffffe b 8030 <MailboxWrite+0x10>
while(*((uint32_t *)(0x2000B898))&0x80000000);
*((uint32_t *)(0x2000B8A0))=val+channel;
8034: e0810000 add r0, r1, r0
8038: e58308a0 str r0, [r3, #2208]; 0x8a0
803c: e12fff1e bx lr
8040: 2000b000 .word 0x2000b000
Подскажите, как можно ришить мою проблему? Может еще какие опции добавить компилятору? Может я неверно пишу программу??? ))