Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ULINK2 и AIC (SAM7X)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
AndreyKar
Решил проверить отладку в защищенном режиме, т.е. AT91C_BASE_AIC->AIC_DCR = AT91C_AIC_DCR_PROT. Играться решил с PITом.
Подключил отладчик и стал смотреть прерывания. При первом же срабатывание программа обработки зацикливается и нет возможности выйти.
Доку устал штудировать. Понял только одно, что надо в р-р AIC_IVR писать (хотя по той же доке он только для чтения), но это не помогает.

Стартуп взял из премеров Кейла (board_cstartup_keil.s), так же как и board_lowlevel.c, board_memories.c, sram.sct и sram.ini.
PIT инициализирую так
Код
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (uint)System_Interrupt; // Save the interrupt handler routine pointer
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | (AT91C_AIC_PRIOR_HIGHEST - 2);
    AT91C_BASE_AIC->AIC_ICCR = (0x01 << AT91C_ID_SYS); // Clear interrupt
    AT91C_BASE_AIC->AIC_IECR = (0x01 << AT91C_ID_SYS); // Enable the interrupt on the interrupt controller

Обработчик:
Код
static void System_Interrupt(void) __irq {
    if ( AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS ){   // Read PITC status reg.
//        AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR; // Read the PIVR (to clear PISR)
        AT91C_BASE_PITC->PITC_PIVR; // Read the PIVR (to clear PISR)
    }
    AT91C_BASE_AIC->AIC_EOICR = 0x00;
}

Где то далеко в памяти сидит инфа, что в обработчике надо работать с контекстом AIC, но как - не знаю.
В board_cstartup_keil.s есть irqHandler
Код
irqHandler
       ;  Save interrupt context on the stack to allow nesting */
        SUB     lr, lr, #4
        STMFD   sp!, {lr}
        MRS     lr, SPSR
        STMFD   sp!, {r0,r1,lr}

       ; Write in the IVR to support Protect Mode */
        LDR     lr, =AT91C_BASE_AIC
        LDR     r0, [r14, #AIC_IVR]
        STR     lr, [r14, #AIC_IVR]

       ; Branch to interrupt handler in Supervisor mode */
        MSR     CPSR_c, #ARM_MODE_SVC
        STMFD   sp!, {r1-r4, r12, lr}
        MOV     lr, pc
        BX      r0
           ; Run fun
        LDMIA   sp!, {r1-r4, r12, lr}
        MSR     CPSR_c, #ARM_MODE_IRQ | I_BIT

       ; Acknowledge interrupt */
        LDR     lr, =AT91C_BASE_AIC
        STR     lr, [r14, #AIC_EOICR]

       ; Restore interrupt context and branch back to calling code
        LDMIA   sp!, {r0,r1,lr}
        MSR     SPSR_cxsf, lr
        LDMIA   sp!, {pc}^
Здесь, вроде, всё есть для работы с отладчиком, но этот irqHandler почему то не вызывается, вернее работает до ; Run fun, а по выходу из подпрограммы обработки обратно не возвращается - выполняет другой код.
aaarrr
Цитата(AndreyKar @ Apr 11 2011, 14:13) *
Понял только одно, что надо в р-р AIC_IVR писать (хотя по той же доке он только для чтения), но это не помогает.

Надо. И в доке это написано.

Цитата(AndreyKar @ Apr 11 2011, 14:13) *
PIT инициализирую так

Запись ICCR здесь не нужна.

Цитата(AndreyKar @ Apr 11 2011, 14:13) *
Обработчик

А вот, собственно, и ошибка: если используется обертка (irqHandler из board_cstartup_keil.s), то модификатор __irq не нужен.

Цитата(AndreyKar @ Apr 11 2011, 14:13) *
В board_cstartup_keil.s есть irqHandler[code]irqHandler

Здесь некоторая мешанина: LR и R14 - это одно и то же, лишнее сохранение R1.
AndreyKar
Спасибо.
Цитата(aaarrr @ Apr 11 2011, 14:51) *
Здесь некоторая мешанина: LR и R14 - это одно и то же, лишнее сохранение R1.

Ну, что Кейл дал то и пользую.
Не подскажите, где взять "правильный" стартуп или что подправить в этом?
aaarrr
Цитата(AndreyKar @ Apr 11 2011, 15:35) *
Ну, что Кейл дал то и пользую.
Не подскажите, где взять "правильный" стартуп или что подправить в этом?

Правильный только написать самому. В этом можете смело убрать R1 из:
Код
STMFD   sp!, {r0,r1,lr}
...
LDMIA   sp!, {r0,r1,lr}

Ну и заменить R14 на lr или наоборот для лучшей читаемости.

Что принципиально плохо в этой обертке, так это явный оверхед для прерываний самого низкого и самого высокого приоритета. Для первого нет нужды сохранять LR_irq и SPSR_irq, т.к. оно никого не прерывает, для последнего вообще не нужна подобная обертка, т.к. его никто не может прервать.
AndreyKar
aaarrr, по поводу AIC_IVR
Цитата(aaarrr @ Apr 11 2011, 14:51) *
Надо. И в доке это написано.

я правильно понял эти строки:
Код
       ; Write in the IVR to support Protect Mode */
        LDR     lr, =AT91C_BASE_AIC ; загрузить адрес AT91C_BASE_AIC в R14
        LDR     r0, [r14, #AIC_IVR] ; читать AT91C_BASE_AIC->AIC_IVR
        STR     lr, [r14, #AIC_IVR] ; записать в AT91C_BASE_AIC->AIC_IVR

и в подпрограммах обработок прерывания не нужно вставлять AT91C_BASE_AIC->AIC_IVR?

ЗЫ: зачем Кейл для этого процессора в скаттере вставляет строки
Код
    ARM_LIB_HEAP 0x20E000 EMPTY 0x1000 {
    }
? В доке на проц нет ни слова про кучи. И если это нужно, то как это использовать с пользой?
aaarrr
Цитата(AndreyKar @ Apr 12 2011, 07:43) *
я правильно понял эти строки:
Код
      ; Write in the IVR to support Protect Mode */
        LDR     lr, =AT91C_BASE_AIC; загрузить адрес AT91C_BASE_AIC в R14
        LDR     r0, [r14, #AIC_IVR]; читать AT91C_BASE_AIC->AIC_IVR
        STR     lr, [r14, #AIC_IVR]; записать в AT91C_BASE_AIC->AIC_IVR

и в подпрограммах обработок прерывания не нужно вставлять AT91C_BASE_AIC->AIC_IVR?

Да, все правильно. А из-за этого:
Код
        SUB     lr, lr, #4
        STMFD   sp!, {lr}
...
        LDMIA   sp!, {pc}^

в подпрограммах не нужен модификатор __irq.

Цитата(AndreyKar @ Apr 12 2011, 07:43) *
ЗЫ: зачем Кейл для этого процессора в скаттере вставляет строки
Код
    ARM_LIB_HEAP 0x20E000 EMPTY 0x1000 {
    }
? В доке на проц нет ни слова про кучи. И если это нужно, то как это использовать с пользой?

К процессору куча отношения и не имеет. Это пул памяти для библиотечного malloc(). Если динамическое выделение не используется, то можно сократить его размер до 0.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.