Ваш анализ имеет две фатальные недостатки: во-первых, вы смотрите на него с точки зрения ядра процессора, во-вторых, это неправильно.
Второй недостаток, я не уверен, почему руководство ARM7TDMI имеет такую странно чрезмерно конкретную формулировку (вы не можете реалистично делать все эти вещи в любом случае), но все 3 аспекта выполняются по линии subs pc, lr, #4
в вашем код. subs pc, lr
is specifically an exception return instruction - он автоматически восстанавливает CPSR из SPSR и возвращается к фиксированному адресу LR. Поскольку флаги отключения прерываний CPU находятся в CPSR, тогда предполагается, что бит I в этом значении SPSR является ясным (что вы ожидаете, учитывая, что вы взяли IRQ, чтобы получить здесь ...), IRQ также будут автоматически отключены в процессе.
Таким образом, от точки ядра процессора зрения, ваш код уже (в силу своей окончательной инструкции) делает все, что нужно обработчик исключений для, т.е. он возобновляет выполнение в той же точке и в том же состоянии, когда произошел IRQ - в компиляторе нет ничего плохого. Однако то, что оно не делает, связано с тем, что периферийный путь за пределами ядра все еще утверждает его прерывание, поэтому следующая вещь, которую вы после возвращения из IRQ, должна с радостью снова принять тот же IRQ. Повторите бесконечность.
Вы, по крайней мере, вышли за пределы ядра до контроллера прерываний; записывая в VICVectAddr
acknowledges the interrupt at the VIC, но это просто освобождает VIC самостоятельно, чтобы приоритизировать любые ожидающие прерывания и доставить следующий, который, поскольку внешний источник все еще утверждается (и при условии, что IRQ с более высоким приоритетом не появился в другом месте), по-прежнему остается тот самый.
Фактически ручка прерывание и прогресс, вам необходимо обслуживать периферийное устройство I2C, поднимающее его. В разделе 13.9 из the LPC213x manual описано, что необходимо сделать для каждого условия прерывания, но с точки зрения устранения заявленного прерывания вам необходимо написать поле SIC для I2C0CONCLR.
Каким образом он не работает должным образом; какое поведение вы видите по сравнению с тем, что вы ожидаете?Предполагая, что 'VICVectAddr = 0;' очищает прерывание, тогда этот код выполняет все 3 кавычки соответственно (подсказка: прочитайте, что на самом деле делает 'subs pc, ...') – Notlikethat
@Notlikethat Когда I2C запускается условие прерывания должен быть сгенерирован. Работает. Но после процедуры прерывания элемент управления не возвращается к прерванному коду. В коде сборки отсутствует шаг 2. – sreeyesh
Как я уже сказал, шаг 2 _is_ выполняется в этом коде под 'subs pc ...'. Уйдя и нашел руководство LPC213x, я вижу, что эта запись делает прерывание в VIC, но прерывание, по-видимому, вызвано уровнем, и вы ничего не делаете, чтобы отключить его на конце контроллера I2C (см. Раздел 13.9). Следовательно, когда вы возвращаетесь, вы сразу же снова принимаете то же прерывание, до бесконечности. – Notlikethat