К1921ВГ015 общее
Модераторы: ea, dav, bkolbov, Alis, pip, _sva_
Re: К1921ВГ015 общее
В процессе отладки выявился баг с приоритетом прерывания TMR32.
Разрешенное прерывание TMR32 с установленным самым низким приоритетом 0х1 перебивает все другие прерывания несмотря на их приоритет (вплоть до 0х7 - самый высокий). Несколько других прерывания между собой ведут себя вроде бы адекватно (кроме TMR32 проверены ADC, CAN1, I2C, TMR0, TMR2, RTC, UART1).
Пробовал также для TMR32 другие приоритеты устанавливать - реагирует только на 0х0 (запрет прерывания), все остальное как наивысший приоритет - перебивает все остальные прерывания. Все прерывания machine - настроены однотипно.
Отладчиком посмотрел дамп памяти, где находятся приоритеты - там значения в соответствии с заданными в программе - как задано для TMR32 для вектора PRI[6] по адресу 0x0C000018 значение 0х01, так отладчиком и считывается 0x01.
Чипы имеются только с дата-кодом "2436".
Вопрос к НИИЭТ - есть ли смысл другие экземпляры К1921ВГ015 заказывать?
Разрешенное прерывание TMR32 с установленным самым низким приоритетом 0х1 перебивает все другие прерывания несмотря на их приоритет (вплоть до 0х7 - самый высокий). Несколько других прерывания между собой ведут себя вроде бы адекватно (кроме TMR32 проверены ADC, CAN1, I2C, TMR0, TMR2, RTC, UART1).
Пробовал также для TMR32 другие приоритеты устанавливать - реагирует только на 0х0 (запрет прерывания), все остальное как наивысший приоритет - перебивает все остальные прерывания. Все прерывания machine - настроены однотипно.
Отладчиком посмотрел дамп памяти, где находятся приоритеты - там значения в соответствии с заданными в программе - как задано для TMR32 для вектора PRI[6] по адресу 0x0C000018 значение 0х01, так отладчиком и считывается 0x01.
Чипы имеются только с дата-кодом "2436".
Вопрос к НИИЭТ - есть ли смысл другие экземпляры К1921ВГ015 заказывать?
Re: К1921ВГ015 общее
TMR32 ни причем оказался. Перепроверил. Надо с обработчиком прерываний из startup_k1921vg015.S подробнее разбираться.mkf писал(а): ↑17 июл 2026, 16:50 В процессе отладки выявился баг с приоритетом прерывания TMR32.
Разрешенное прерывание TMR32 с установленным самым низким приоритетом 0х1 перебивает все другие прерывания несмотря на их приоритет (вплоть до 0х7 - самый высокий). Несколько других прерывания между собой ведут себя вроде бы адекватно (кроме TMR32 проверены ADC, CAN1, I2C, TMR0, TMR2, RTC, UART1).
Пробовал также для TMR32 другие приоритеты устанавливать - реагирует только на 0х0 (запрет прерывания), все остальное как наивысший приоритет - перебивает все остальные прерывания. Все прерывания machine - настроены однотипно.
Отладчиком посмотрел дамп памяти, где находятся приоритеты - там значения в соответствии с заданными в программе - как задано для TMR32 для вектора PRI[6] по адресу 0x0C000018 значение 0х01, так отладчиком и считывается 0x01.
Re: К1921ВГ015 общее
Здравствуйте! Других плат у меня нет. Изначально готовые отладочные платы покупать не планировал. Не видел в этом смысла, так как имею положительный опыт работы с STM32 и по той же технологии пошел осваивать К1921ВГ015. На данный момент занят проектом на STM32 и, как освобожусь, продолжу свою борьбу с К1921ВГ015 и его средой разработки. Планирую купить новый К1921ВГ015 и установить на действующую плату. В вопросе решения проблем с настройкой среды разработки я слаб, поэтому много времени уходит на устранение простых препятствий.vg015boy писал(а): ↑13 июл 2026, 23:04 Максим, у Вас есть возможность проверить на заведомо рабочей плате (уже готовой и которая успешно прошивалась)? Чтобы исключить ошибки настройки ПО и проблемы с программатором.
1. Попробовать на той, которая точно должна работать
2. Потом пробовать на своих платам.
Re: К1921ВГ015 общее
Не получилось сделать вытесняющие прерывания на одном уровне привилегий.mkf писал(а): ↑20 июл 2026, 05:57TMR32 ни причем оказался. Перепроверил. Надо с обработчиком прерываний из startup_k1921vg015.S подробнее разбираться.mkf писал(а): ↑17 июл 2026, 16:50 В процессе отладки выявился баг с приоритетом прерывания TMR32.
Разрешенное прерывание TMR32 с установленным самым низким приоритетом 0х1 перебивает все другие прерывания несмотря на их приоритет (вплоть до 0х7 - самый высокий). Несколько других прерывания между собой ведут себя вроде бы адекватно (кроме TMR32 проверены ADC, CAN1, I2C, TMR0, TMR2, RTC, UART1).
Пробовал также для TMR32 другие приоритеты устанавливать - реагирует только на 0х0 (запрет прерывания), все остальное как наивысший приоритет - перебивает все остальные прерывания. Все прерывания machine - настроены однотипно.
Отладчиком посмотрел дамп памяти, где находятся приоритеты - там значения в соответствии с заданными в программе - как задано для TMR32 для вектора PRI[6] по адресу 0x0C000018 значение 0х01, так отладчиком и считывается 0x01.
Задумка была в начале обработчика разрешить прерывания (mstatus.mie=1) предварительно сохранив mepc и mcause:
Код: Выделить всё
uint32_t __MCAUSE, __MEPC;
__MCAUSE=read_csr(mcause);
__MEPC=read_csr(mepc);
set_csr(mstatus, MSTATUS_MIE);
Код: Выделить всё
clear_csr(mstatus, MSTATUS_MIE);
write_csr(mepc,__MEPC);
write_csr(mcause,__MCAUSE);
Так не получилось.
PLIC не выставляет запрос на прерывание (в данном случае №11, в регистре mip - "intr[context]" на рисунке), пока предыдущий обработчик не пошлет в PLIC->MICC свой номер по завершению своей работы (отладчиком эта ячейка памяти не видится - там всегда ноль). Только после этого блок выбора наивысшего приоритета начинает работать снова.
То есть, сигнал о взятии прерывания на обработку "PLIC->MICC" блокирует не только свой источник, но и все остальные тоже.
С чего бы это вдруг? По картинке сигналы блокировки у каждого свои: Посылать сигнал о завершении сразу при входе в прерывание не хотелось бы, так как вложенные прерывания от одного источника не нужны. Нужна только возможность вытеснения прерывания другим с более высоким приоритетом.
Документация riscv также пишет:
• Interrupt Completion registers: The register to send interrupt completion message to the associated gateway. То есть не должен обработчик текущего прерывания блокировать запросы остальных. А получается, что не смотря на то, что прерывания разрешены, сигнала ядру на прерывание (регистр mip) все равно нет, так как PLIC у к1921вг015 почему-то не устанавливает флаг в регистре mip, пока текущий обработчик не закроется:
Код: Выделить всё
void PLIC_ClaimComplete (uint8_t target, uint32_t isrnum)
{
if(target == Plic_Mach_Target) {
PLIC->MICC = isrnum;
} else {
PLIC->UICC = isrnum;
}
}
Получается фактически всего два приоритета осталось (machine и user) вытесняющих прерываний
Re: К1921ВГ015 общее
Проверил.
Если выполнить в начале обработчика
то длинное тело обработчика прерывания, может быть прервано другим прерыванием с бОльшим приоритетом.
Но! И этот же самый обработчик теперь может быть снова (по сигналу прерывания) вызван до окончания предыдущей обработки.
То есть, появляется возможность для вложенных вызовов. А такой футбол нам не нужен
.
Нужно как-то вытеснение по приоритетам сделать без вложенности обработчика самого в себя.
Если выполнить в начале обработчика
Код: Выделить всё
PLIC->MICC = isrnum;Но! И этот же самый обработчик теперь может быть снова (по сигналу прерывания) вызван до окончания предыдущей обработки.
То есть, появляется возможность для вложенных вызовов. А такой футбол нам не нужен
Нужно как-то вытеснение по приоритетам сделать без вложенности обработчика самого в себя.
-
RabidRabbit
- Сообщения: 202
- Зарегистрирован: 10 июн 2025, 12:11
- Предприятие: HomeWork
Re: К1921ВГ015 общее
Взвел флаг и вышел. А потом взведенные флаги опять по приоритетам обрабатывать? Если неспеша, то можно разными вариантами выкрутиться.RabidRabbit писал(а): ↑23 июл 2026, 02:07Возможно, стоит применить минимальные обработчики прерываний (взвёл флаг и вышел)? Тогда наверняка никакие вытеснения не будут нужны.
В критических условиях (например авария) может возникнуть несколько событий почти одновременно. И первым будет исполняться прерывание, которое первое возникло (его PLIC сразу в обработку возьмет), а не то, у которого выше приоритет (оно пришло чуть позже и будет стоять в очереди).
Тут два уровня привилегий. Поэтому можно часть прерываний с уровня machine на уровень user спустить. Будет работать также, как по флагам.
Система с флагами уже есть, называется PLIC.
В документации riscv и в документации к1921вг015 к PLIC прописано, что работающий обработчик блокирует только свой вход (gataway) прерывания, а не все входы... хмм... тут надо еще раз проверить, чего он блокирует, а то ведь, если блокируются gataway всех входов, то и с user режимом ничего не получится.
---
ушел экспериментировать
-
RabidRabbit
- Сообщения: 202
- Зарегистрирован: 10 июн 2025, 12:11
- Предприятие: HomeWork
Re: К1921ВГ015 общее
Каждый обработчик прерывания просто отправляет сигнал ожидающему потоку обработки, и завершается. В прерывании проведёте очень мало времени. А уж потоки обработки делаете с разными приоритетами - переключение на поток с более высоким приоритетом обеспечит ОС. Так и "вытесняющие прерывания" образуются.
Re: К1921ВГ015 общее
С ОСами понятно. Время реакции совсем не то. Как там было: "... не думай о микросекундах с высока..."RabidRabbit писал(а): ↑23 июл 2026, 10:14 Каждый обработчик прерывания просто отправляет сигнал ожидающему потоку обработки, и завершается. В прерывании проведёте очень мало времени. А уж потоки обработки делаете с разными приоритетами - переключение на поток с более высоким приоритетом обеспечит ОС. Так и "вытесняющие прерывания" образуются.
С блокировкой входов (gateway) разобрался - работают они правильно. Сигнал от периферии блокируется только тот, который был взят в обработку (считан номер PLIC->MICC). И разблокируется после подтверждения (запись того же номера в PLIC->MICC). Остальные сигналы видны как флаги в регистре PLIC->IPM - ожидающие обработки. Но Блок выбора прерывания с наивысшим приоритетом (PLIC) не дает им выполняться, так как не посылает сигнал "intr[mach]" ядру, пока не дождется подтверждения завершения (запись того же номера в PLIC->MICC) работающего обработчика. И разрешение прерываний не помогает. А из документации riscv на PLIC, насколько я понимаю, следует, что PLIC должен сразу сигнал ядру посылать на прерывание:
https://docs.riscv.org/reference/plic/v ... laims.html
7.1. Interrupt Claim Process
Sometime after a target receives an interrupt notification, it might decide to service the interrupt. The target sends an interrupt claim message to the PLIC core, which will usually be implemented as a non-idempotent memory-mapped I/O control register read. On receiving a claim message, the PLIC core will atomically determine the ID of the highest-priority pending interrupt for the target and then clear down the corresponding source’s IP bit. The PLIC core will then return the ID to the target. The PLIC core will return an ID of zero, if there were no pending interrupts for the target when the claim was serviced.
After the highest-priority pending interrupt is claimed by a target and the corresponding IP bit is cleared, other lower-priority pending interrupts might then become visible to the target, and so the PLIC EIP bit might not be cleared after a claim. The interrupt handler can check the local meip/seip/ueip bits before exiting the handler, to allow more efficient service of other interrupts without first restoring the interrupted context and taking another interrupt trap.
По тексту "обработка запроса" - это обработка запроса контроллером PLIC (не обработка прерывания ядром)После того как целевое устройство обработает ожидающее прерывание с наивысшим приоритетом и соответствующий бит IP будет сброшен, целевому устройству могут стать видны другие ожидающие прерывания с более низким приоритетом, поэтому бит EIP PLIC может не сбрасываться после обработки запроса.
Вот! А получается, что в к1921вг015 бит EIP запроса к ядру сбрасывается и вновь не выставляется, пока не завершится работа обработчика прерывания.
-
RabidRabbit
- Сообщения: 202
- Зарегистрирован: 10 июн 2025, 12:11
- Предприятие: HomeWork
