|
|
  |
Вопрос к пользователям CW 1.7, бага ? |
|
|
|
Dec 26 2008, 17:36
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Скачал последний CrossWorks v1.7b15 вот такой текст: Код unsigned int Adc[4], adcSum, indexAdc;
static void AdcISR(void) __attribute__ ((interrupt ("IRQ"))); static void AdcISR(void) { unsigned int tmp; unsigned int adc;
tmp = AD0GDR; // считали показания АЦП adc = (tmp >> 6) & 0x03FF; // только результат преобразования adcSum -= Adc[indexAdc]; // вычитаем самый старый семпл Adc[indexAdc] = adc; // сохранили последнее adcSum += adc; // обновили скользящее среднее
if (++indexAdc >= 4) indexAdc = 0;
IO0PIN = (adcSum >> 2) & 0x03FF; // вывели в порт скользящее среднее if (tmp & 0x01000000) IO0SET = 0x0400; // диагностика
VICVectAddr = 0; } дает багу(варнинг) при компиляции на любых уровнях оптимизации кроме "none". ругаетца так: Compiling main.c — 1 error D:/Work/LpcAdc/ARM Flash Release/\s3nk.7: Assembler messages: Warning: writeback of base register is UNPREDICTABLE после этого прога нормально не работает конечно, никакие танцы с бубном не помагают, может кто-нить проверить такое поведение ? вот результат компиляции: Код 000002c0 <AdcISR>: 2c0: e24ee004 sub lr, lr, #4; 0x4 2c4: e92d500f stmdb sp!, {r0, r1, r2, r3, ip, lr} 2c8: e59f0090 ldr r0, [pc, #144]; 360 <.text+0xa0> 2cc: e59fc090 ldr ip, [pc, #144]; 364 <.text+0xa4> 2d0: e59f3090 ldr r3, [pc, #144]; 368 <.text+0xa8> 2d4: e59f1090 ldr r1, [pc, #144]; 36c <.text+0xac> 2d8: e593e004 ldr lr, [r3, #4] 2dc: e59c3000 ldr r3, [ip] 2e0: e5902000 ldr r2, [r0] 2e4: e7912102 ldr r2, [r1, r2, lsl #2] 2e8: e0623003 rsb r3, r2, r3 2ec: e58c3000 str r3, [ip] 2f0: e1a0232e mov r2, lr, lsr #6 2f4: e5903000 ldr r3, [r0] 2f8: e1a02b02 mov r2, r2, lsl #22 2fc: e1a02b22 mov r2, r2, lsr #22 300: e7812103 str r2, [r1, r3, lsl #2] 304: e59c3000 ldr r3, [ip] 308: e0833002 add r3, r3, r2 30c: e58c3000 str r3, [ip] 310: e5903000 ldr r3, [r0] 314: e2833001 add r3, r3, #1; 0x1 318: e5803000 str r3, [r0] 31c: e5903000 ldr r3, [r0] 320: e3530003 cmp r3, #3; 0x3 324: 83a03000 movhi r3, #0; 0x0 328: 85803000 strhi r3, [r0] 32c: e59c3000 ldr r3, [ip] 330: e1a03123 mov r3, r3, lsr #2 334: e59f2034 ldr r2, [pc, #52]; 370 <.text+0xb0> 338: e1a03b03 mov r3, r3, lsl #22 33c: e1a03b23 mov r3, r3, lsr #22 340: e31e0401 tst lr, #16777216; 0x1000000 344: e5823000 str r3, [r2] 348: 13a03b01 movne r3, #1024; 0x400 34c: 15823004 strne r3, [r2, #4] 350: e3a02000 mov r2, #0; 0x0 354: e3e03000 mvn r3, #0; 0x0 358: e5032fcf str r2, [r3, #-4047] 35c: e8fd500f ldmia sp!, {r0, r1, r2, r3, ip, lr}^ 360: 40000054 andmi r0, r0, r4, asr r0 364: 4000003c andmi r0, r0, ip, lsr r0 368: e0034000 and r4, r3, r0 36c: 40000040 andmi r0, r0, r0, asr #32 370: e0028000 and r8, r2, r0 Забыл сказать: проц LPC2138
|
|
|
|
|
Dec 26 2008, 19:47
|
Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847

|
Цитата(singlskv @ Dec 26 2008, 19:36)  Скачал последний CrossWorks v1.7b15 вот такой текст: Код unsigned int Adc[4], adcSum, indexAdc;
static void AdcISR(void) __attribute__ ((interrupt ("IRQ"))); ... Мм... Тк не пробовал, у меня обработчик на ассемблере, вызывает обычную функцию. Цитата дает багу(варнинг) при компиляции на любых уровнях оптимизации кроме "none". ругаетца так: Compiling main.c — 1 error D:/Work/LpcAdc/ARM Flash Release/\s3nk.7: Assembler messages: Warning: writeback of base register is UNPREDICTABLE вот результат компиляции: Код 000002c0 <AdcISR>: 2c0: e24ee004 sub lr, lr, #4; 0x4 2c4: e92d500f stmdb sp!, {r0, r1, r2, r3, ip, lr} ... 35c: e8fd500f ldmia sp!, {r0, r1, r2, r3, ip, lr}^ ... Забыл сказать: проц LPC2138 А чего бы ей работать если нет возврата? Ну стек восстановили, а где возврат PC? Точно не помню, но была бага в компиляторе gcc-4.x.x связанная с некорректным прологом/эпилогом IRQ обработчика. Сам не наступал на нее потому как обработчики делаю на асм. Вот мой вариант на ассемблере для LPC2368, но думаю, что и Вам подойдет. Код IRQ_handler: @ Adjust and save LR_irq to IRQ stack sub lr, lr, #4 stmdb sp!, {r0, r1, lr} @ Save IRQ mode registers @ Read ISR address from VIC ldr r0, =VIC_VECT_ADDR ldr r1, [r0] @ Save SPSR in IRQ stack mrs r0, SPSR stmdb sp!, {r0} @ Enable Interrupts and Switch in SYS Mode mrs r0, CPSR @ bic r0, r0, #I_BIT orr r0, r0, #SYS_MODE msr CPSR, r0 @ Branch to ISR stmdb sp!, {r2-r12, lr} @ Save SYS mode registers @ Save return address then call user defined handler. @ Handler _MUST_ be defined with "naked" attribute @ _MUST_ starts with asm("stmdb sp!, {lr}") and @ _MUST_ ends with asm("ldmia sp!, {pc}") mov lr, pc bx r1 ldmia sp!, {r2-r12, lr} @ Restore SYS mode registers @ Disable Interrupt and switch back in IRQ mode mrs r0, CPSR bic r0, r0, #SYS_MODE orr r0, r0, #(I_BIT| IRQ_MODE) msr CPSR, r0 @ Update the priority hardware mov r1, #0 @ Value have no meaning (may be any value) ldr r0, =VIC_VECT_ADDR str r1, [r0] @ Restore SPSR_irq from IRQ stack ldmia sp!, {r0} msr SPSR, r0 @ Restore adjusted LR_irq from IRQ stack directly in the PC ldmia sp!, {r0, r1, pc}^ @ Restore IRQ mode registers Полностью см. во вложении.
Прикрепленные файлы
crt0.S.zip ( 2.92 килобайт )
Кол-во скачиваний: 25
--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть. © Lewis Carroll. Alice's adventures in wonderland.
|
|
|
|
|
Dec 26 2008, 22:14
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(amw @ Dec 26 2008, 22:47)  Мм... Тк не пробовал, у меня обработчик на ассемблере, вызывает обычную функцию. в том то и дело что на CW1.5(GCC 3.4.4) для SAM7A3 все корректно, на CW1.7(GCC 4.3.1?) для LPC получаю какую-то фигню... Ваш обработчик посмотрю, спасибо.. вот инициализация VIC и запуск АЦП: Код int main(void) { MAMCR = 2;
IO0DIR |= 0x000007FF; // выход PINSEL1 = (0x01 << 22) | (0x01 << 24); // Установить пин P0.27(28) в AD0.0(1)
ADCR = 0x03 + (8 << 8) + (0x1 << 16) + (0x1 << 21); // Регистр управления АЦП // D0-D7 выбор входного пина. // D8-D15 - Частота преобразования CLKDIV // D16 - BURST - Непрерывный (1) или событийный (0) старт АЦП // D17-D19 - CLKS - Число тиков (разрядность) в BURST=1 режиме // D21 - PDN - Включение питания АЦП // D24-D26 - Режим событийного старта: 0 - Нет старта // 1 - Немедленный старт 2 - Старт по EDGE P0.16 3 - Старт по EDGE P0.22 // 4 - Старт по EDGE MAT0.1 5 - Старт по EDGE MAT0.3 // 6 - Старт по EDGE MAT1.0 7 - Старт по EDGE MAT1.1 // D27 - EDGE. EDGE =1 - По фронту. EDGE = 0 - По срезу
VICVectCntl0 = 0x20 + 18; // Разрешить Слот 0 + Задать номер прерывания AD0
VICIntSelect = 0x00; // IRQ прерывание
VICVectAddr0 = (unsigned)AdcISR; // Задать адрес прерывания от ADC0
VICIntEnable = 1 << 18; // Разрешить ADC0 прерывание
__ARMLIB_enableIRQ(); while (1); return 0; } если что... Цитата(amw @ Dec 26 2008, 22:47)  Мм... Тк не пробовал, у меня обработчик на ассемблере, вызывает обычную функцию. .......... А чего бы ей работать если нет возврата? Ну стек восстановили, а где возврат PC? Точно не помню, но была бага в компиляторе gcc-4.x.x связанная с некорректным прологом/эпилогом IRQ обработчика. Сам не наступал на нее потому как обработчики делаю на асм. Ну да, возврата то и нет: без оптимизации: Код ....................................... 3c4: e5832000 str r2, [r3] 3c8: e24bd018 sub sp, fp, #24; 0x18 3cc: e89d680e ldmia sp, {r1, r2, r3, fp, sp, lr} 3d0: e8bd1000 ldmia sp!, {ip} 3d4: e25ef004 subs pc, lr, #4; 0x4 С оптимизацией -s Код ....................................... 340: e5032fcf str r2, [r3, #-4047] 344: e8fd51ff ldmia sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, ip, lr}^ 348: 40000050 andmi r0, r0, r0, asr r0 // <- data!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Чего-то gcc 4.x.x на АРМ мне уже тоже не так нравиться  Ваш обработчик посмотрел, но он ведь вроде не для vectored interrupt ? а мне нужно максимально быстро, на самом деле один обработчик будет на fiq и второй на vectored irq
|
|
|
|
|
Dec 27 2008, 13:20
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Qwertty @ Dec 27 2008, 15:37)  Если Thumb не используете - отключите ARM/THUMB Interworking и проблема уйдет. Или обертки ассемблерные придется делать. О том, что в CW 1.5 было нормально - не знал. Может там THUMB отключен по умочанию? Да, это оно! Я упустил это из виду при настройке проекта, при отключении ARM/THUMB Interworking компилит правильно. в CW1.5 работает тоже при отключенном ARM/THUMB Interworking. Спасибо
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|