- PVSM.RU - https://www.pvsm.ru -
В статье приводится несколько примеров настройки и использования прерываний MIPS32 Release 2, включая подробное описание задаваемой при этом конфигурации, описывается работа с контроллером внешних прерываний.
Весь описываемый код опубликован на github в составе проекта mipsfpga-plus [L3 [1]].
Предполагается, что читатель:
Написанием этой статьи я не ставлю цель всесторонне изложить все особенности работы с прерываниями для ядер MIPS microAptiv, т.к. это потребовало бы масштабного перевода документации и написания примерно такого же объема комментариев. Цель — показать работающие примеры настройки и использования прерываний в трех возможных режимах: обратной совместимости, векторном и с использованием внешнего контроллера. Поэтому для того, чтобы читатель чувствовал себя более комфортно, рекомендуется бегло ознакомиться со следующими разделами документации:
Во всех примерах для наглядности описывается запуск на системе mipsfpga-plus, работающей в симуляторе. С равным успехом это может быть выполнено и на железе — работоспособность всего кода проверена на плате Terasic DE10-Lite [L4 [7]].
Наименования сигналов выделены курсивом ( SI_Int[7:0] ), если не указано обратное, то все сигналы являются интерфейсными для верхнеуровнего модуля системы MIPSfpga (m14k_top). Для регистров используется насыщенный шрифт ( Count ), названия отдельных битов (полей) приводятся через точку с указанием регистров, к которым они относятся ( Cause.DC ), на отдельных выкопировках из документации поля регистров могут быть обозначены подстрочными символами ( CauseIV ). Для всех регистров предполагается ширина x32, если это не оговаривается отдельно. При указании констант в выкопировках из документации встречается указание системы счисления перед символом "решетка" (16#180, 2#00001).
Т.к. в MIPSfpga, к сожалению, не доступна опция "GPR Shadow Registers" (Shadow Register Set, SRS), то в статье опущены детали, связанные с теневыми регистрами общего назначения. Там, где эта функциональность встречается на схемах — она отражена серым (блеклым) цветом.
Под исключениями понимаются все события, которые приводят к переходу процессора в kernel mode: ошибки доступа к памяти, деление на ноль и т.д., включая запросы прерываний от внешних устройств. Обработка всех возможных исключений является обширной темой, которую не корректно рассматривать в отрыве от ядра операционной системы (ОС), что явно выходит за рамки данной статьи. Вместе с тем, даже если использование ОС не предполагается (Bare Metal code), разработчику все же следует предусмотреть минимальный набор обработчиков в памяти, чтобы узнать о факте возникновения исключения и не допустить ухода выполнения программы в "произвольное плавание".
if Status.EXL = 1 then
vectorOffset ← 16#180
else
if ExceptionType = TLBRefill then
vectorOffset ← 16#000
elseif (ExceptionType = Interrupt) then
// определение смещения вектора обработчика прерывания
if (Cause.IV = 0) then
vectorOffset ← 16#180
else
if (Status.BEV = 1) or (IntCtl.VS = 0) then
vectorOffset ← 16#200
else
if Config3.VEIC = 1 then
VecNum ← Cause.RIPL
else
VecNum ← VIntPriorityEncoder()
endif
vectorOffset ← 16#200 + (VecNum × (IntCtl.VS || 2#00000))
endif
endif
endif
endif
Cause.ExcCode ← ExceptionType
// признак того, что ядро находится в процессе входа в обработчик исключения
Status.EXL ← 1
// вычисление базового адреса, по которому размещена "таблица прерываний"
if Status.BEV = 1 then
vectorBase ← 16#BFC00200
else
// фиксированное значение EBase[31:30] = 2'b10
// ограничивает размещение векторов в сегментах памяти kseg0 или kseg1
vectorBase ← EBase[31:12] || 16#000
endif
// переход для обработки прерывния
// адрес обработчика вычисляется как сумма vectorBase и vectorOffset
// перенос из разряда 29 в разряд 30 при этом не выполняется
PC ← {vectorBase[31:30], (vectorBase[29:0] + vectorOffset[29:0])}
В приведенном алгоритме не учтены следующие моменты:
В полном объеме информацию об исключениях можно найти в [D2 [5]].
Таким образом, даже без использования прерываний, разработчику следует обеспечить наличие обработчиков исключений на следующих смещениях:
Их всего три:
По-умолчанию процессор стартует в режиме совместимости (Compatibility). В дальнейшим он может быть изменен, путем установки соответствующих значений битов (полей):
Полное описание перечисленных битов (полей) и регистров, к которым они относятся приведено в документации, отметим влияние совокупности их значений на режим обработки прерываний:
Перед тем, как переходить к описанию работы с прерываниями рассмотрим один из наиболее частых их источников — системный таймер. Он крайне прост по своим возможностям, но входит в состав процессорного ядра и может работать даже в режиме энергосбережения, а значит доступен в любом окружении.
Для работы с ним используются два регистра:
Для работы с этими регистрами удобно использоваться макросы mips32_setcompare и mips32_setcount, которые объявлены в mips/cpu.h, для инициализации и сброса таймера, фактически, используется один и тот же код [S0 [8]]:
mips32_setcompare(MIPS_TIMER_PERIOD); //set compare (TOP) value to turn on /reset timer
mips32_setcount(0); //reset counter
На скриншоте ниже видны моменты инициализации таймера и его сброса при обработке прерывания.
Наличие сигнала SI_TimerInt не является достаточным для вызова прерывания. Для того, чтобы он был обработан, должна быть выполнена его корректная маршрутизация на уровне RTL, которая зависит от текущего режима обработки прерываний (Interrupt mode), о чем будет сказано ниже.
Режим обратной совместимости с MIPS32 Release 1. Основные особенности:
Те, кто получил первый опыт разработки под встраиваемые системы на относительно современных микроконтроллерах, могут испытать некоторое недоумение от "всего" 6 внешних прерываний и одного общего обработчика на все, включая львиную долю исключений. Здесь следует учесть некоторую историчность архитектуры MIPS: предполагалось, что источники прерываний будут подключаться иерархически, учитывалось, что код входа в (выхода из) прерывание у всех обработчиков общий, а т.к. внешние устройства, по своей сути, медленные (события возникаю редко), то нет и особых потерь в производительности от "ручной" проверки источников и приоритетов, и даже есть некоторый простор для возможных оптимизаций. Пример такого подключения из [L5 [10]] приведен ниже.
Даже если считать эти особенности "недостатком", они легко компенсируются возможностью использования внешнего контроллера прерываний, подключенного через соответствующий интерфейс процессорного ядра MIPSfpga, о чем будет рассказано в соответствующем разделе.
`define MFP_USE_WORD_MEMORY
//`define MFP_USE_IRQ_EIC
#define RUNTYPE COMPATIBILITY
02_compile_and_link.bat
05_generate_verilog_readmemh_file.bat
06_simulate_with_modelsim.bat
установленные в заголовочных файлах RTL настройки приводят к следующей конфигурации интерфейса прерываний процессорного ядра [S3 [13]]:
assign SI_Offset = 17'b0; //not used
assign SI_EISS = 4'b0; //not used
assign SI_Int[7:4] = 4'b0;
assign SI_Int[3] = uart_interrupt;
assign SI_Int[2:0] = 3'b0;
assign SI_EICVector = 6'b0; //not used
assign SI_EICPresent = 1'b0; //no external interrupt controller
assign SI_IPTI = 3'h7; //enable MIPS timer interrupt on HW5
файл exceptions.S содержит необходимые для работы векторы прерываний, они все, практически, однотипные [S4 [14]]:
.org 0x200 # set symbol offset from section beginning
.weak __mips_isr_sw0 # if the symbol does not already exist, it will be created
__isr_vec_sw0:
la $k1, __mips_isr_sw0 # load interrupt handler (__mips_isr_sw0) addr
beqz $k1, __general_exception # if it is not present then go to generic
nop
jr $k1 # jump to irq_sw0
nop
векторы исключений отличаются от векторов прерываний тем, что в случае, если соответствующий обработчик в программе не определен, выполняется зацикливание кода [S5 [15]]:
.org 0x0 # set symbol offset from section beginning
.weak _mips_tlb_refill # if the symbol does not already exist, it will be created
__tlb_refill:
la $k1, _mips_tlb_refill # load exception handler (_mips_tlb_refill) addr
beqz $k1, __tlb_refill # if _mips_tlb_refill doen not exist then just loop here
nop
jr $k1 # jump to _mips_tlb_refill.
# we can use 'j _mips_tlb_refill'
nop # but it works only with 1st 28 bits of addr
в файле mian.c осуществляется последовательная инициализация таймера [S0 [8]]:
mips32_setcompare(MIPS_TIMER_PERIOD); //set compare (TOP) value to turn timer on
mips32_setcount(0); //reset counter
инициализация прерываний [S6 [16]]:
//compatibility mode, one common handler
// Status.BEV 0 - place handlers in kseg0 (0x80000000)
mips32_bicsr (SR_BEV);
// Cause.IV, 0 - general exception handler (offset 0x180)
mips32_biccr (CR_IV);
// interrupt enable, HW5, SR_SINT1 - unmasked
mips32_bissr (SR_IE | SR_HINT5 | SR_SINT1);
и их обработка в одном обработчике, предполагающая последовательные: проверку, является ли данное исключение прерыванием, определение того, какое именно прерывание необходимо обработать, и непосредственно саму обработку [S7 [17]]:
void __attribute__ ((interrupt, keep_interrupts_masked)) _mips_general_exception ()
{
MFP_RED_LEDS = MFP_RED_LEDS | 0x1;
uint32_t cause = mips32_getcr();
//check that this is interrupt exception
if((cause & CR_XMASK) == 0)
{
//check for timer interrupt
if(cause & CR_HINT5)
{
MFP_RED_LEDS = MFP_RED_LEDS | 0x10;
n++;
mipsTimerReset();
mips32_biscr(CR_SINT1); //request for software interrupt 1
MFP_RED_LEDS = MFP_RED_LEDS & ~0x10;
}
//check for software interrupt 1
else if (cause & CR_SINT1)
{
MFP_RED_LEDS = MFP_RED_LEDS | 0x8;
mips32_biccr(CR_SINT1); //clear software interrupt 1 flag
MFP_RED_LEDS = MFP_RED_LEDS & ~0x8;
}
}
MFP_RED_LEDS = MFP_RED_LEDS & ~0x1;
}
в прерывании по таймеру (HW5) осуществляется инкремент счетчика, сброс таймера и выставляется флаг запроса программного прерывания SW1 [S8 [18]]:
n++;
mipsTimerReset();
mips32_biscr(CR_SINT1);
в прерывании SW1 выполняется только сброс флага прерывания [S9 [19]]:
mips32_biccr(CR_SINT1);
в коде функции main выполняется циклический вывод счетчика на 7-сегментные индикаторы [S10 [20]]:
for (;;)
MFP_7_SEGMENT_HEX = n;
Векторный режим обработки прерываний.
Основные особенности:
#define RUNTYPE VECTOR
настройка работы прерываний выполняется следующим образом [S11 [21]]:
//vector mode, multiple handlers
// Status.BEV 0 - place handlers in kseg0 (0x80000000)
mips32_bicsr (SR_BEV);
// Cause.IV, 1 - special int vector (offset 0x200),
// where 0x200 - base for other vectors
mips32_biscr (CR_IV);
// get IntCtl reg value
uint32_t intCtl = mips32_getintctl();
// set interrupt table vector spacing (0x20 in our case)
// see exceptions.S for details
mips32_setintctl(intCtl | INTCTL_VS_32);
// interrupt enable, HW5 and SW0,SW1 - unmasked
mips32_bissr (SR_IE | SR_HINT5 | SR_SINT0 | SR_SINT1);
порядок работы программы абсолютно аналогичен ранее описанному, за исключением того, что в прерывании по таймеру (HW5) осуществляется установка флагов не одного, а сразу двух программных прерываний (SW0 и SW1), которые затем будут обработаны в порядке приоритета [S12 [22]]:
void __attribute__ ((interrupt, keep_interrupts_masked)) __mips_isr_hw5 ()
{
MFP_RED_LEDS = MFP_RED_LEDS | 0x4;
n++;
mipsTimerReset();
mips32_biscr(CR_SINT0); //request for software interrupt 0
mips32_biscr(CR_SINT1); //request for software interrupt 1
MFP_RED_LEDS = MFP_RED_LEDS & ~0x4;
}
для обработки прерывания SW0 используется отдельный вектор [S13 [23]]:
void __attribute__ ((interrupt, keep_interrupts_masked)) __mips_isr_sw0 ()
{
MFP_RED_LEDS = MFP_RED_LEDS | 0x2;
mips32_biccr(CR_SINT0); //clear software interrupt 0 flag
MFP_RED_LEDS = MFP_RED_LEDS & ~0x2;
}
Перед тем, как переходить к описанию работы в режиме External Interrupt Controller, рассмотрим как этот модуль взаимодействует с процессорным ядром и что он из себя представляет.
Задача контроллера — выполнять регистрацию внешних прерываний и выдавать на шину (Interrupt Interface) сведения о наиболее приоритетном из них:
Принимая в обработку очередной запрос на прерывание, процессор сообщает контроллеру:
Типовое взаимодействие контроллера и процессорного ядра показано ниже:
Также следует учесть:
assign eic_offset = 1'b1;
Основные характеристики:
`ifdef MFP_USE_IRQ_EIC
.EIC_input ( EIC_input ),
.EIC_Offset ( SI_Offset ),
.EIC_ShadowSet ( SI_EISS ),
.EIC_Interrupt ( SI_Int ),
.EIC_Vector ( SI_EICVector ),
.EIC_Present ( SI_EICPresent ),
.EIC_IAck ( SI_IAck ),
.EIC_IPL ( SI_IPL ),
.EIC_IVN ( SI_IVN ),
.EIC_ION ( SI_ION ),
`endif //MFP_USE_IRQ_EIC
В состав контроллера входят следующие файлы:
Для того, чтобы сформировать общее представление о настройке контроллера, перечислим его конфигурационные регистры, их полное описание в [D5 [31]]. Для всех регистров, кроме EICR, EISMSK_0 и EISMSK_1 предполагается, что номер бита соответствует номеру входа контроллера. Так, к примеру, EIFR_0[3]=1 — означает, что на входе 3 ожидает необработанное прерывание.
`define MFP_USE_IRQ_EIC
`define MFP_USE_WORD_MEMORY
assign eic_offset = 1'b0;
02_compile_and_link.bat
05_generate_verilog_readmemh_file.bat
06_simulate_with_modelsim.bat
установленные в заголовочных файлах RTL настройки приводят к следующей конфигурации [S16 [32]]:
wire [ `EIC_CHANNELS - 1 : 0 ] EIC_input;
assign EIC_input[`EIC_CHANNELS - 1:8] = {`EIC_CHANNELS - 6 {1'b0}};
assign EIC_input[7] = SI_TimerInt;
assign EIC_input[6] = 1'b0;
assign EIC_input[5] = uart_interrupt;
assign EIC_input[4:2] = 3'b0;
assign EIC_input[1] = SI_SWInt[1];
assign EIC_input[0] = SI_SWInt[0];
assign SI_IPTI = 3'h0;
файл exceptions.S аналогичен двум предыдущим примерам, за исключением именования прерываний и их количества. Так, самое последнее HW63 расположено на смещении 0x9E0 [S22 [33]]:
.org 0x9E0
.weak __mips_isr_eic63
__isr_vec_eic63:
la $k1, __mips_isr_eic63
beqz $k1, __general_exception
nop
jr $k1
nop
инициализация прерываний [S24 [35]]:
//eic mode
//unmask interrupt
MFP_EIC_EIMSK_0 = (1 << IRQSW0) | (1 << IRQSW1) | (1 << IRQTIMER);
MFP_EIC_EIMSK_1 = (1 << IRQ63);
//enable auto clear
MFP_EIC_EIACM_0 = (1 << IRQSW0) | (1 << IRQSW1) | (1 << IRQTIMER);
//set interrupt on rising edge of the signal
MFP_EIC_EISMSK_0 = (SMSK_RIZE << SMSKSW0) |
(SMSK_RIZE << SMSKSW1) |
(SMSK_RIZE << SMSKTIMER);
// Status.BEV 0 - vector interrupt mode
mips32_bicsr (SR_BEV);
// Cause.IV, 1 - special int vector (0x200)
// where 0x200 - base when Status.BEV = 0;
mips32_biscr (CR_IV);
// get IntCtl reg value
uint32_t intCtl = mips32_getintctl();
// set interrupt table vector spacing (0x20 in our case)
// see exceptions.S for details
mips32_setintctl(intCtl | INTCTL_VS_32);
// enable external interrupt controller
// enable interrupts
MFP_EIC_EICR = 0x1;
mips32_bissr (SR_IE);
для того, чтобы включить опцию непосредственного указания смещения (Option 2 — Explicit Vector Offset), необходимо помимо изменения конфигурации процессорного ядра (m14k_cpz_eicoffset_stub.v), раскомментировать в файле mfp_eic_core.vh [S15 [25]] параметр
`define EIC_USE_EXPLICIT_VECTOR_OFFSET
сама обработка прерывания производится аналогично тому, как было показано выше [S26 [39]]:
ISR(IH_SW0)
{
MFP_RED_LEDS = MFP_RED_LEDS | 0x1;
mips32_biccr(CR_SINT0); //clear software interrupt 0 flag
MFP_RED_LEDS = MFP_RED_LEDS & ~0x1;
}
В описании примеров выше не акцентировалось внимание на том, как осуществляется непосредственно вход в прерывание, т.к. необходимый для этого код создается для нас компилятором [L7 [41]]. Рассмотрим этот его для наиболее частых случаев.
В [D3 [6]] перечислен ряд опций компилятора, которые могут быть использованы разработчиком:
void __attribute__ ((interrupt)) v0 ();
void __attribute__ ((interrupt, use_shadow_register_set)) v1 ();
void __attribute__ ((interrupt, keep_interrupts_masked)) v2 ();
void __attribute__ ((interrupt, use_debug_exception_return)) v3 ();
void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked)) v4 ();
void __attribute__ ((interrupt, use_shadow_register_set, use_debug_exception_return)) v5 ();
void __attribute__ ((interrupt, keep_interrupts_masked, use_debug_exception_return)) v6 ();
void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked,
use_debug_exception_return)) v7 ();
void __attribute__ ((interrupt("eic"))) v8 ();
void __attribute__ ((interrupt("vector=hw3"))) v9 ();
Несколько комментариев по поводу их использования:
void __attribute__ ((interrupt, keep_interrupts_masked)) __mips_isr_sw0 ()
{
80001544: 401b7000 mfc0 k1,c0_epc
80001548: 27bdfff0 addiu sp,sp,-16
8000154c: afbb000c sw k1,12(sp)
80001550: 401b6000 mfc0 k1,c0_status
80001554: afbb0008 sw k1,8(sp)
//установить в k1 нули на смещение status.exl,.erl,.um, .ie;
80001558: 7c1b2004 ins k1,zero,0x0,0x5
//записать status
8000155c: 409b6000 mtc0 k1,c0_status
80001560: afbe0004 sw s8,4(sp)
80001564: 03a0f025 move s8,sp
...
}
80001568: 03c0e825 move sp,s8
8000156c: 8fbe0004 lw s8,4(sp)
80001570: 8fbb000c lw k1,12(sp)
80001574: 409b7000 mtc0 k1,c0_epc
80001578: 8fbb0008 lw k1,8(sp)
8000157c: 27bd0010 addiu sp,sp,16
80001580: 409b6000 mtc0 k1,c0_status
80001584: 42000018 eret
void __attribute__ ((interrupt)) __mips_isr_hw5 ()
{
80001588: 401a6800 mfc0 k0,c0_cause
8000158c: 401b7000 mfc0 k1,c0_epc
80001590: 27bdfff0 addiu sp,sp,-16
80001594: afbb000c sw k1,12(sp)
80001598: 401b6000 mfc0 k1,c0_status
//сдвинуть в начало k0 биты cause.ip7-ip2
8000159c: 001ad282 srl k0,k0,0xa
800015a0: afbb0008 sw k1,8(sp)
//загрузить в k1 значения cause.ip6-ip2 на смещение status.im7-im2
800015a4: 7f5b7a84 ins k1,k0,0xa,0x6
//установить в k1 нули на смещение status.exl,.erl,.um;
// .ie при этом не меняется (остается 1)
800015a8: 7c1b2044 ins k1,zero,0x1,0x4
//записать status
800015ac: 409b6000 mtc0 k1,c0_status
800015b0: afbe0004 sw s8,4(sp)
800015b4: 03a0f025 move s8,sp
...
}
800015b8: 03c0e825 move sp,s8
800015bc: 8fbe0004 lw s8,4(sp)
//disable interrupts (status.ie = 0)
800015c0: 41606000 di
800015c4: 000000c0 ehb
800015c8: 8fbb000c lw k1,12(sp)
//восстановить epc
800015cc: 409b7000 mtc0 k1,c0_epc
800015d0: 8fbb0008 lw k1,8(sp)
800015d4: 27bd0010 addiu sp,sp,16
//восстановить status из стека
800015d8: 409b6000 mtc0 k1,c0_status
800015dc: 42000018 eret
Автор выражает благодарность коллективу переводчиков [2] учебника Дэвида Харриса и Сары Харрис «Цифровая схемотехника и архитектура компьютера», компании Imagination Technologies [42] за академическую лицензию на современное процессорное ядро и персонально Юрию Панчулу YuriPanchul [43] за его работу по популяризации MIPSfpga.
[L1] — Цифровая схемотехника и архитектура компьютера [2];
[L2] — Как начать работать с MIPSfpga [3];
[L3] — Проект MIPSfpga-plus на github [1];
[L4] — FPGA плата Terasic DE10-Lite [7];
[L5] — Embedded Linux System Design and Development P. Raghavan, Amol Lad, Sriram Neelakandan [44] (перевод [10]);
[L6] — Проект ahb_lite_eic на github [26];
[L7] — Codescape MIPS SDK [41];
[D1] — MIPS32 microAptiv UP Processor Core Family Integrator’s Guide [4];
[D2] — MIPS32 microAptiv UP Processor Core Family Software User’s Manual [5];
[D3] — Codescape GNU Tools for MIPS Programmer's Guide [6];
[D4] — MIPS32 Architecture For Programmers Volume III: The MIPS32 Privileged Resource Architecture [9];
[D5] — MIPSfpga+ External Interrupt Controller [31];
[D6] — MIPS32 microAptiv UP Processor Core Family Datasheet [45];
[P0] — MIPS 32 microAptiv UP Core Block Diagram [46] (источник: D6 [45]);
[P1] — Режимы работы процессорного ядра с прерываниями [47];
[P2] — Работа системного таймера MIPS. Сигналы [48] (скриншот);
[P3] — Подключение источников прерываний к процессорному ядру [49] (источник: L5 [44]);
[P4] — Работа в режиме обратной совместимости. Сигналы [50] (скриншот);
[P5] — Обработка прерываний в векторном режиме [51] (источник: D2 [5]);
[P6] — Приоритет прерываний для векторного режима [52] (источник: D2 [5]);
[P7] — Смещение адресов обработчиков для векторного режима [53] (источник: D2 [5]);
[P8] — Работа в векторном режиме. Сигналы [54] (скриншот);
[P9] — Обработка прерываний в режиме контроллера внешних прерываний [55] (источник: D2 [5]);
[P10] — Сигналы контроллера внешних прерываний [56] (источник: D1 [4]);
[P11] — Регистры контроллера внешних прерываний [57] (источник: L6 [26]);
[P12] — Работа в режиме контроллера внешних прерываний, передача номера вектора [58] (скриншот);
[P13] — Работа в режиме контроллера внешних прерываний, передача смещения [59] (скриншот).
Ссылки на исходный код
[S0] — Инициализация и сброс таймера [8];
[S1] — Область настройки памяти и прерываний системы mipsfpga-plus [11];
[S2] — Настройка режима работы примера 06_timer_irq [12];
[S3] — Конфигурация mipsfpga-plus при отключенном контроллере внешних прерываний [13];
[S4] — Пример вектора прерывания [14];
[S5] — Пример вектора исключения [15];
[S6] — Настройка прерываний в режиме обратной совместимости [16];
[S7] — Обработка прерываний в режиме обратной совместимости [17];
[S8] — Прерывание по таймеру в режиме обратной совместимости [18];
[S9] — Программное прерывание в режиме обратной совместимости [19];
[S10] — Основной цикл функции main примера 06_timer_irq [20];
[S11] — Настройка прерываний в векторном режиме [21];
[S12] — Прерывание по таймеру в векторном режиме [22];
[S13] — Программное прерывание с отдельным обработчиком в векторном режиме [23];
[S14] — Работа в векторном режиме при отсутствии отдельного обработчика [24];
[S15] — Конфигурационный файл контроллера внешних прерываний mipsfpga-plus [25];
[S16] — Конфигурация mipsfpga-plus при использовании контроллера внешних прерываний [32];
[S17] — Ядро контроллера внешних прерываний [25];
[S18] — Обработка номера прерывания контроллером внешних прерываний [28];
[S19] — Приоритетный шифратор контроллера внешних прерываний [29];
[S20] — Интерфейс контроллера внешних прерываний и шины AHB-Lite [30];
[S21] — Сигналы интерфейса прерываний при обработке контроллером [27]м;
[S22] — Внешнее прерывание HW63 [33];
[S23] — Заголовочный файл программного интерфейса работы с контроллером [34];
[S24] — Настройка прерываний в режиме контроллера внешних прерываний [35];
[S25] — Настройка инкремента смещения вектора в режиме контроллера внешних прерываний [38];
[S26] — Обработчик прерывания в режиме контроллера внешних прерываний [39];
[S27] — Макросы ISR и EH_GENERAL [40];
[S28] — Модуль interrupt_sence [36];
[S29] — Модуль interrupt_channel [37].
Автор: Stanislav Zhelnio
Источник [60]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/verilog/250978
Ссылки в тексте:
[1] L3: https://github.com/MIPSfpga/mipsfpga-plus
[2] L1: https://habrahabr.ru/post/259505/
[3] L2: https://habrahabr.ru/post/275215/
[4] D1: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/D1_MicroAptiv_UP_Integrators_Guide_MD00941.pdf
[5] D2: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/D2_MicroAptiv_UP_Software_Users_Manual_MD00942.pdf
[6] D3: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/D3_MIPS_Toolchain_Codescape_GNU_Tools_for_MIPS_Programmers_Guide_1.1.97.pdf
[7] L4: http://de10-lite.terasic.com/
[8] S0: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L17-L27
[9] D4: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/D4_MIPS32_r1_Vol3.pdf
[10] L5: http://rus-linux.net/MyLDP/BOOKS/Embedded_Linux_system_design_and_development_ru.pdf
[11] S1: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_ahb_lite_matrix_config.vh#L29-L41
[12] S2: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L12
[13] S3: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_system.v#L382-L389
[14] S4: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/exceptions.S#L54-L61
[15] S5: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/exceptions.S#L12-L20
[16] S6: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L32-L35
[17] S7: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L59-L79
[18] S8: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L66-L69
[19] S9: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L76
[20] S10: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L112-L113
[21] S11: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L38-L47
[22] S12: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L93-L104
[23] S13: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/main.c#L84-L91
[24] S14: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/06_timer_irq/exceptions.S#L63-L67
[25] S15: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_eic_core.vh
[26] L6: https://github.com/zhelnio/ahb_lite_eic
[27] S21: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_system.v#L475-L486
[28] S18: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_eic_handler.v
[29] S19: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_eic_priority_encoder.v
[30] S20: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_ahb_lite_eic.v
[31] D5: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/D5_20170320_mfp_EIC.pdf
[32] S16: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_system.v#L372-L380
[33] S22: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/07_eic/exceptions.S#L621-L628
[34] S23: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/07_eic/eic.h
[35] S24: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/07_eic/main.c#L26-L46
[36] S28: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_eic_core.v#L305-L357
[37] S29: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/mfp_eic_core.v#L283-L303
[38] S25: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/07_eic/main.c#L41-L42
[39] S26: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/07_eic/main.c#L67-L74
[40] S27: https://github.com/MIPSfpga/mipsfpga-plus/blob/de22adeead0211de812f9b5b7868f161c03f07fb/programs/07_eic/eic.h#L61-L62
[41] L7: https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/
[42] Imagination Technologies: https://www.imgtec.com/
[43] YuriPanchul: https://habrahabr.ru/users/yuripanchul/
[44] Embedded Linux System Design and Development P. Raghavan, Amol Lad, Sriram Neelakandan: https://pixhawk.ethz.ch/_media/dev/literature/embedded_linux_system_design_and_development.pdf
[45] MIPS32 microAptiv UP Processor Core Family Datasheet: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/D6_MicroAptiv_UP_Datasheet_MD00939.pdf
[46] MIPS 32 microAptiv UP Core Block Diagram: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P0_core.png
[47] Режимы работы процессорного ядра с прерываниями: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P1_modes.png
[48] Работа системного таймера MIPS. Сигналы: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P2_timer_signals.png
[49] Подключение источников прерываний к процессорному ядру: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P3_tree_connection.png
[50] Работа в режиме обратной совместимости. Сигналы: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P4_compat_signals.png
[51] Обработка прерываний в векторном режиме: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P5_vector.png
[52] Приоритет прерываний для векторного режима: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P6_vector_priority.png
[53] Смещение адресов обработчиков для векторного режима: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P7_vector_offset.png
[54] Работа в векторном режиме. Сигналы: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P8_vector_signals.png
[55] Обработка прерываний в режиме контроллера внешних прерываний: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P9_eic.png
[56] Сигналы контроллера внешних прерываний: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P10_eic_interface.png
[57] Регистры контроллера внешних прерываний: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P11_eic_registers.png
[58] Работа в режиме контроллера внешних прерываний, передача номера вектора: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P12_eic_signals_vector.png
[59] Работа в режиме контроллера внешних прерываний, передача смещения: https://github.com/zhelnio/memos/blob/master/public/01_mips_interrupts/doc/P13_eic_signals_offset.png
[60] Источник: https://habrahabr.ru/post/324900/
Нажмите здесь для печати.