Как множество манипулатори на прекъсвания споделят адрес 0x00000018

Чета за това как прекъсванията се обработват в ARM и разбрах, че всеки път, когато дойде хардуерно прекъсване, се изпълнява инструкция на адрес 0x00000018, което обикновено е прескачане към уважаван манипулатор на прекъсвания, но може да има много манипулатори на прекъсвания за различни модули.

Тогава как тези различни манипулатори се нанасят на адрес 0x00000018?

Също така, как arm CPU разбира, че прекъсването е irq или fiq, кой го решава и кое устройство е повдигнало прекъсването, как да се насочи към уважаван манипулатор за това прекъсване.

Може ли някой да ме насочи към прост код за манипулиране на прекъсвания, където мога да видя какво прави един манипулатор на прекъсвания?


person Amit Singh Tomar    schedule 09.11.2013    source източник


Отговори (2)


ARM CPU обикновено има два пина (FIQ и IRQ), които се заявяват от устройствата, когато искат да генерират прекъсване. Когато това се случи, процесорът просто превключва режимите и преминава към адрес 0x00000018.

Въпреки това, тъй като обикновено има повече устройства от броя на щифтовете за прекъсване, обикновено има контролер за прекъсване, който преминава между процесора и устройствата. Можете да мислите за това като за хъб за свързване на повече прекъсвания към процесора. Контролерът на прекъсванията може да бъде конфигуриран да заявява FIQ за определени видове прекъсвания, които получава.

Манипулаторът на прекъсване обикновено пита контролера на прекъсването кой щифт е причинил прекъсването, след което извиква подходящия манипулатор.

Ето съкратена версия без проверка на грешки на кода за обработка на прекъсвания, който използвах в малък проект.

#include <types.h>
#include <irq.h>

static void (*irq_handlers[32])(void);

void __attribute__((interrupt)) handle_irq() {
    int irq = irq_hw_get_and_ack();

    if (irq_handlers[irq]) {
        irq_handlers[irq]();
    }
}

void setup_irq() {
    irq_hw_init();
    cpu_enable_irq();
}

void irq_request(int irq, void (*func)(void)) {
    irq_handlers[irq] = func;
    irq_hw_enable(irq);
}

void irq_unrequest(int irq) {
    irq_hw_disable(irq);
    irq_handlers[irq] = NULL;
}
person tangrs    schedule 09.11.2013
comment
Благодаря ви много @tangrs. Имам съмнения, които също поисках да остана, предполагам, че има само един манипулатор на прекъсвания, който е картографиран на адрес 0x0000018 и този манипулатор отговаря за грижата за други манипулатори, специфични за модулите? Освен това би бъди страхотен, можеш да ми предложиш някакъв код за Манипулаторът на прекъсвания обикновено пита контролера за прекъсване кой щифт е причинил прекъсването, след което извиква подходящия манипулатор, имам предвид как манипулаторът на прекъсвания пита контролера за прекъсване кой щифт е причинил прекъсването? - person Amit Singh Tomar; 10.11.2013
comment
Зависи от точния SoC и конфигурацията, която използвате, но обикновено включва четене на някакъв вид картографиран IO регистър на паметта. - person tangrs; 10.11.2013
comment
fine tangrs, бихте ли потвърдили, ако разбирам, че има само един манипулатор на прекъсвания, който е картографиран на адрес 0x0000018 и този манипулатор отговаря за грижата за други манипулатори, специфични за модулите? - person Amit Singh Tomar; 10.11.2013

За процесорите е доста типично да имат само едно прекъсване. x86 беше така известно време, може би все още е така. Arm традиционно има две, но по-новите ядра вече имат много 32, 256 и т.н.

Когато имате споделена линия за прекъсване, както tangrs спомена, обикновено имате нещо извън процесора, в случай на рамо, в рамките на чипа, но извън самото ядро ​​на ръката. Нещо, което има много входове за прекъсване и изхода или изходите, които отиват към процесорите, едно или няколко прекъсвания. Когато възникне прекъсване на процесора, проверявате с тази логика/хардуер извън процесора/ядрото, за да видите кой го е причинил, и ето го.

също така не е нетипично да има вложени контролери за прекъсване, да речем например 8 входа с един изход. И за някои или всеки от тези 8 входа друг 8 към 1 контролер за прекъсване. Тогава софтуерът ще трябва просто да следва пътя. проверете контролера за прекъсване от първо ниво, за да видите кой(ите) е изстрелял прекъсването, след което оттам знаете контролера на следващия слой, с който трябва да говорите и така нататък, докато изолирате отделното прекъсване.

Също така знайте и разберете, че за тези споделени системи за прекъсване е напълно възможно да се случват множество прекъсвания „по едно и също време“ основно от момента, в който вашата програма започне да спира и се извика векторът за прекъсване, и вие правите вашите неща за стартиране на прекъсване и в крайна сметка прочетете регистъра за състоянието на прекъсването, повече от един може да влезе. Трябва да решите как да се справите с това и в зависимост от системата/логиката, ако трябва да се върнете от един от тях, другите, които се заявяват, може да ви върнат обратно в манипулатора на прекъсвания, така че изпълнението ще/може да се справи само с един от висящите. Друга логика може да изисква от вас да обработите всички чакащи преди да се върнете.

Тъй като arm не контролира непременно това, което е свързано с линиите за прекъсване или fiq, можете да получите всякакви решения от различни доставчици за това как системата за прекъсване работи за конкретен чип arm.

person old_timer    schedule 10.11.2013
comment
Благодаря @dwelch, когато възникне прекъсване на процесора, тогава проверявате с тази логика/хардуер извън процесора/ядрото, за да видите кой го е причинил. Имате предвид тук под проверка на процесора с контролера за прекъсване кой го е причинил? Предполагам, че има само един манипулатор на прекъсвания, който е картографиран на адрес 0x0000018 и този манипулатор отговаря за грижата за други манипулатори, специфични за модулите. - person Amit Singh Tomar; 10.11.2013
comment
Току-що намерих един код за обработка на прекъсвания github.com /xinu-os/xinu/blob/master/system/arch/arm/ и предполагам, че на ред номер 69 има прескачане към специфичен за модула код за обработка на прекъсвания. Добре ли е това разбиране? - person Amit Singh Tomar; 10.11.2013
comment
Да, софтуерът проверява с контролера на прекъсванията и/или периферните устройства (евентуално проверява с периферните устройства, които могат да генерират прекъсвания). - person old_timer; 10.11.2013