maxis 0 24 декабря, 2012 Опубликовано 24 декабря, 2012 (изменено) · Жалоба Необходимо сгенерировать прерывание по фронту импульса поступающему на одну из ног GPIO и моргнуть светодиодом (ARM ядро OMAP L138). Выполняю следующий код: void INTInit(void) { unsigned int savePinmux = 0; /* Enable GPIO */ PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE); /* Read pinmux and clean pins 0[6] */ savePinmux = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) & \ ~(SYSCFG_PINMUX1_PINMUX1_7_4)); /* Enable in pinmux pins 0[6] in GPIO 7 */ HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) = \ (PINMUX1_INT_ENABLE | savePinmux); /* Set GPIO 7 as input */ GPIODirModeSet(SOC_GPIO_0_REGS, 7, GPIO_DIR_INPUT); /* ** Configure rising edge and falling edge triggers on pin 7 to generate ** an interrupt */ GPIOIntTypeSet(SOC_GPIO_0_REGS, 7, GPIO_INT_TYPE_RISEDGE); /* Enable interrupts for Bank 0.*/ GPIOBankIntEnable(SOC_GPIO_0_REGS, 0); /* Configuring the AINTC to handle interrupts.*/ // Setup ARM or DSP interrupt controller #ifdef _TMS320C6X // Initialize the DSP Interrupt Controller IntDSPINTCInit(); // Enable DSP Interrupts Globally IntGlobalEnable(); #else /* Initialize the ARM Interrupt Controller.*/ IntAINTCInit(); /* Enable IRQ in CPSR.*/ IntMasterIRQEnable(); /* Enable the interrupts in GER of AINTC.*/ IntGlobalEnable(); /* Enable the interrupts in HIER of AINTC.*/ IntIRQEnable(); #endif /* Configure GPIO interrupts */ // Configure GPIO interrupts for ARM or DSP #ifdef _TMS320C6X // Register the ISR in the Interrupt Vector Table IntRegister(C674X_MASK_INT0, GPIOIsr); // Map the system interrupt to the DSP maskable interrupt IntEventMap(C674X_MASK_INT0, SYS_INT_GPIO_B0INT); // Enable DSP maskable interrupt IntEnable(C674X_MASK_INT0); #else // Register the ISR in the Interrupt Vector Table. IntRegister(SYS_INT_GPIOB0, GPIOIsr); // Map the channnel number 2 of AINTC to GPIO BANK 0 system interrupt. IntChannelSet(SYS_INT_GPIOB0, 2); // Enable the System Interrupts for AINTC. IntSystemEnable(SYS_INT_GPIOB0); #endif } /* ** \brief Interrupt Service Routine to be executed on GPIO interrupts. ** This disables the bank interrupts, clears the system interrupt ** status and pin interrupt status. This also sets flag as 1. */ void GPIOIsr(void) { /* Disable the interrupts for pins of bank 0 in GPIO.*/ GPIOBankIntDisable(SOC_GPIO_0_REGS, 0); #ifdef _TMS320C6X // Clear the system interrupt status in the DSPINTC IntEventClear(SYS_INT_GPIO_B0INT); #else /* Clears the system interrupt status of GPIO in AINTC.*/ IntSystemStatusClear(SYS_INT_GPIOB0); #endif /* Clears the Interrupt Status of GP0[6] in GPIO.*/ GPIOPinIntClear(SOC_GPIO_0_REGS, 7); GPIOPinWrite(SOC_GPIO_0_REGS, 1, GPIO_PIN_HIGH); GPIOPinWrite(SOC_GPIO_0_REGS, 2, GPIO_PIN_LOW); GPIOPinWrite(SOC_GPIO_0_REGS, 3, GPIO_PIN_HIGH); Delay(1000000); GPIOPinWrite(SOC_GPIO_0_REGS, 2, GPIO_PIN_HIGH); GPIOPinWrite(SOC_GPIO_0_REGS, 3, GPIO_PIN_LOW); /* Enable interrupts for pins of bank 0.*/ GPIOBankIntEnable(SOC_GPIO_0_REGS, 0); } При этом по приходу прерывания программа слетает куда-то в область 0xfffd45dc. В чём может быть причина? Изменено 25 декабря, 2012 пользователем maxis Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 24 декабря, 2012 Опубликовано 24 декабря, 2012 · Жалоба При этом по приходу прерывания программа слетает куда-то в область 0xfffd45dc. В чём может быть причина? Причина может быть в отсутствии у вас таблицы прерываний. У ARM-ядра L137 (и думаю L138) таблица прерываний находится с адреса 0xFFFF0000. PS: Такие длинные портянки кода, как у вас, следует оформлять используя CODEBOX, а не CODE. Чтобы не листать по неск. экранов.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maxis 0 25 декабря, 2012 Опубликовано 25 декабря, 2012 · Жалоба Причина может быть в отсутствии у вас таблицы прерываний. У ARM-ядра L137 (и думаю L138) таблица прерываний находится с адреса 0xFFFF0000. Нет, таблица прерываний на месте. Global Prioritized Vector Register = 0x80005D00 Соответственно по адресу 0x80005D00 лежит одна запись 0x80003980. В дизасемблере вижу что по адресу 0x80003980 находится функция GPIOIsr. PS: Такие длинные портянки кода, как у вас, следует оформлять используя CODEBOX, а не CODE. Чтобы не листать по неск. экранов.... Исправил. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 25 декабря, 2012 Опубликовано 25 декабря, 2012 · Жалоба Нет, таблица прерываний на месте. Global Prioritized Vector Register = 0x80005D00 Причём здесь Global Prioritized Vector Register??? Вы ещё раз внимательнее перечитайте моё письмо и почитайте в даташите как работает система прерываний в ARM-ядре. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maxis 0 25 декабря, 2012 Опубликовано 25 декабря, 2012 · Жалоба Причём здесь Global Prioritized Vector Register??? Вы ещё раз внимательнее перечитайте моё письмо и почитайте в даташите как работает система прерываний в ARM-ядре. Таблица на месте. Вот она: fnRAMVectors 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 80003980 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Vector base register содержет правильную ссылку на эту таблицу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 25 декабря, 2012 Опубликовано 25 декабря, 2012 · Жалоба Вы совсем не хотите читать то, что я пишу. Тогда зачем спрашиваете если не слушаете советов? Повторяю ещё раз: таблица прерываний находится с адреса 0xFFFF0000 И ещё раз: почитайте в даташите как работает система прерываний в ARM-ядре Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maxis 0 25 декабря, 2012 Опубликовано 25 декабря, 2012 (изменено) · Жалоба Вы совсем не хотите читать то, что я пишу. Тогда зачем спрашиваете если не слушаете советов? Повторяю ещё раз: таблица прерываний находится с адреса 0xFFFF0000 И ещё раз: почитайте в даташите как работает система прерываний в ARM-ядре Где это почитать можно? Я перерыл OMAP-L138 Technical Reference Manual и нигде ни слова по поводу 0xFFFF0000 и что там должно находится. udp А нет, нашёл что там действительно содержится вектор табле, и на этом всё. Вот что у меня там находится: 0xEAFF7FFE 0xEAFFFFFD 0xEAFFFFFC 0xEAFFFFFB 0xEAFFFFFA 0xEAFFFFF9 0xEAFFFFF8 0xEAFFFFF7 Изменено 25 декабря, 2012 пользователем maxis Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 26 декабря, 2012 Опубликовано 26 декабря, 2012 · Жалоба А нет, нашёл что там действительно содержится вектор табле, и на этом всё. Вот что у меня там находится: 0xEAFF7FFE 0xEAFFFFFD 0xEAFFFFFC 0xEAFFFFFB 0xEAFFFFFA 0xEAFFFFF9 0xEAFFFFF8 0xEAFFFFF7 Вот - уже теплее ;) Да - это команды переходов на процедуры обработки исключений. Не знаю, где это описано в документации L138, но в "OMAP-L137 Applications Processor System Reference Guide" (SPRUG84,C) надо см. раздел "2.4 Exceptions and Exception Vectors" - там описано, и вектора FIQ и IRQ, которые вам нужны. А ещё почитайте описание на ядро ARM926EJ-S - там описано как работает система прерываний в этом ядре. То, про что Вы писали (контроллер прерываний AINTC), идёт уже после этого и может опционально использоваться для FIQ и IRQ прерываний. Или не использоваться вовсе :) Вот как у меня описана таблица векторов, которая располагается с адреса 0xFFFF0000: exceptionsInit: LDR PC, ___c_int00 ;Reset Interrupt LDR PC, __UND_handler ;Undefined Instruction Interrupt LDR PC, __SWI_handler ;Software Interrupt LDR PC, __PAB_handler ;Prefetch Abort Interrupt LDR PC, __DAB_handler ;Data Abort Interrupt .long 0 ;Reserved For Future Expansion LDR PC, __IRQ_handler ;IRQ Interrupt LDR PC, __FIQ_handler ;FIQ Interrupt ___c_int00 .long _c_int00 __UND_handler .long UND_handler __SWI_handler .long SWI_handler __PAB_handler .long PAB_handler __DAB_handler .long DAB_handler .long 0 __IRQ_handler .long IRQ_handler __FIQ_handler .long FIQ_handler Вот ISR IRQ (видите где только начинает использоваться GPVR?): IRQ_handler: SUBS LR, LR, #4 STMFD SP!, {R0-R3, R12, LR} ;Store registers on IRQ stack LDR R0, AINTC_GPVR ;R0 contains address of GPVR (which contains ISR address) LDR R1, [R0] ;R1 contains address of highest prioritized ISR ADD LR, PC, #0 ;Save return address in LR, LDR PC, [R1] ;Go to ISR (still in IRQ mode), will return to following line LDMFD SP!, {R0-R3, R12, PC}^ ;Restore registers from IRQ stack. Return to program current status Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
olebon 0 9 октября, 2014 Опубликовано 9 октября, 2014 · Жалоба Наткнулся на вашу тему в надежде решить аналогичную проблему. В ОМАР-L137 загружаю DSP (полностью функционален, проблем нет) и затем ARM. Также, как и в этой теме, АРМ работает, все мигает, но прерывания использовать не выходит. В качестве исходника использовал пример с сайта TI http://processors.wiki.ti.com/index.php/Bo...s_for_OMAP-L137 В проект АРМ кроме boot.asm, использованного в примере, добавил ARM9_handler, ARM9_intvecs и ARM9_initstack.asm из qCSL примеров. Что интересно, если запускаю через дебаггер, все работает, но если программа загружается из флеш-памяти, АРМ замирает после первого же прерывания. Для АРМа никакого GEL-файла не используется, для DSP- все инициализируется из кода, в GEL все закомментировано. Буду очень признателен, если чего подскажете. Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 10 октября, 2014 Опубликовано 10 октября, 2014 · Жалоба В проект АРМ кроме boot.asm, использованного в примере, добавил ARM9_handler, ARM9_intvecs и ARM9_initstack.asm из qCSL примеров. Что интересно, если запускаю через дебаггер, все работает, но если программа загружается из флеш-памяти, АРМ замирает после первого же прерывания. Для АРМа никакого GEL-файла не используется, для DSP- все инициализируется из кода, в GEL все закомментировано. Буду очень признателен, если чего подскажете. Спасибо! После первого прерывания, т.е. - одно выполняется, а потом всё? Или не выполняется ни одно? Таблицу прерываний ARM-ядра формируете (с адреса 0xFFFF0000)? Её должно сформировать DSP-ядро перед снятием RESET с ARM-ядра. См. соответствующий раздел мануала по порядку старта ARM-ядра. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
olebon 0 12 октября, 2014 Опубликовано 12 октября, 2014 · Жалоба Спасибо, что откликнулись, боялся, что темя уже заброшена :) На ARM я объявил два прерывания: таймер и CHIPSIG (от DSP). Если прерывание от таймера не активировно, то АРМ молотит как угодно долго (мигает светодиодами и мотает счетчик в адресе общей памяти, так, что я могу через DSP считывать значение счетчика). Как только DSP шлет CHIPSIG, АРМ зависает. Если же таймер прерывание активно с самого начала, то и АРМ вырубается моментально. Что касается инициализации АРМа, то я ее скопировал из того самого примера: DSP загружается сам, подает питание на PRUSS, который делает некие таинственные манипуляции, чтобы врубить АРМ, после чего АРМ таки включается и работает, пока не произойдет первое прерывание. К несчастью, через дебаггер все работает нормально, то есть и таймер и CHIPSIG прерывания происходят как и положено, но стоит загрузить программу в флеш, проблема с прерываниями налицо. Не совсем понятно, что имеется в виду под формированием таблицы прерываний через DSP. Получается, boot.asm, ARM9_IRQ_handler.arm,ARM9_intvecs.asm и ARM9_initstack.asm в проекте дла ARM недостаточно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
olebon 0 13 октября, 2014 Опубликовано 13 октября, 2014 · Жалоба Кажется, нащупал причину: возможно, проблема в части кода, загружаемой через PRUSS. Попробую разобраться, что он конкретно делает ( в примере он грузится в виде массива). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 13 октября, 2014 Опубликовано 13 октября, 2014 · Жалоба Не совсем понятно, что имеется в виду под формированием таблицы прерываний через DSP. Получается, boot.asm, ARM9_IRQ_handler.arm,ARM9_intvecs.asm и ARM9_initstack.asm в проекте дла ARM недостаточно? Не код, а именно таблица векторов прерываний. Т.е. это таблица команд перехода на стартовые адреса ISR. Для старта ARM-ядра DSP ядро должно сделать: 1. С помощью PRUSS скопировать начальную таблицу векторов прерываний в область с адреса 0xFFFF0000. Сам DSP не может её туда скопировать, так как не имеет доступа к этой области памяти. 2. Снять сигнал RESET c ARM-ядра. После этого ARM-ядро начинает выполнять код начиная с адреса 0xFFFF0000. Начальная таблица векторов прерываний может содержать только валидный переход по 0-му вектору (вектор RESET), в остальных векторах могут быть просто заглушки. Я обычно так делал. Вот она из моего проекта: static const u32 codeARM[] = { 0xE59FF018, //vt0: B boot 0xEAFFFFFE, //vt0: Self loop 0xEAFFFFFE, //vt0: Self loop 0xEAFFFFFE, //vt0: Self loop 0xEAFFFFFE, //vt0: Self loop 0xEAFFFFFE, //vt0: Self loop 0xEAFFFFFE, //vt0: Self loop 0xEAFFFFFE, //vt0: Self loop RAM_SDRAM_ARM_RX_BEGIN //jump: DATA: }; Как видите - прописан только вектор сброса, передающий управление на начало кода (по адресу RAM_SDRAM_ARM_RX_BEGIN). Чтобы в дальнейшем нормально обрабатывать прерывания, ARM-ядро после старта должно проинициализировать таблицу прерываний уже валидными векторами. Если оставить заглушки, естественно при первом-же прерывании ARM-ядро зациклится в заглушке. PS: Всё это освещено в мануале, в разделе посвящённом старту ARM-ядра. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться