Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос к пользователям CW 1.7
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
singlskv
Скачал последний 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
amw
Цитата(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

Полностью см. во вложении.
singlskv
Цитата(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 на АРМ мне уже тоже не так нравиться sad.gif

Ваш обработчик посмотрел, но он ведь вроде не для vectored interrupt ?
а мне нужно максимально быстро, на самом деле один обработчик будет на fiq
и второй на vectored irq
Qwertty
Если Thumb не используете - отключите ARM/THUMB Interworking и проблема уйдет. Или обертки ассемблерные придется делать. О том, что в CW 1.5 было нормально - не знал. Может там THUMB отключен по умочанию?
singlskv
Цитата(Qwertty @ Dec 27 2008, 15:37) *
Если Thumb не используете - отключите ARM/THUMB Interworking и проблема уйдет. Или обертки ассемблерные придется делать. О том, что в CW 1.5 было нормально - не знал. Может там THUMB отключен по умочанию?
Да, это оно!
Я упустил это из виду при настройке проекта,
при отключении ARM/THUMB Interworking компилит правильно.

в CW1.5 работает тоже при отключенном ARM/THUMB Interworking.

Спасибо a14.gif beer.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.