как построить простой замок (мьютекс) на процессоре nios II

Я пытаюсь создать простую видеоигру для университетского курса, используя платы Altera DE0, DE2 или DE1-SoC, я посмотрел на isa для процессора nios II, в ISA нет атомарной инструкции по тестированию и установке. как бы я построил здесь простую блокировку, все, что обеспечивает взаимное исключение на крошечный период, будет работать.

у нас будет код, который будет запускаться из main(), и код, который будет выполняться в подпрограмме обслуживания прерываний, и я хочу заблокировать некоторые переменные, возможно ли это?


person user2567411    schedule 24.11.2015    source источник


Ответы (1)


Похоже, в архитектуре Nios II нет атомарных инструкций проверки и установки. Вместо синхронизации общих ресурсов между несколькими процессорами Nios II в архитектуре используется «ядро аппаратного мьютекса». Он работает как совместно используемое периферийное устройство, обеспечивающее атомарную операцию проверки и проверки. Вы можете прочитать больше об этом в учебнике Altera по созданию многопроцессорных систем Nios II.

Однако вы, вероятно, не выполняете атомарную операцию проверки и установки. Вы можете сделать любую последовательность инструкций атомарной по отношению к прерываниям в системе с одним ядром, просто отключив прерывания.

person Ross Ridge    schedule 24.11.2015
comment
На самом деле мьютекс не защищает между задачей и ISR. Вы должны сделать cli/sti. мьютекс работает только для ядра к ядру. Если многоядерный с ISR: cli,lock,do stuff,unlock,sti - person Craig Estey; 24.11.2015
comment
хм, да, временное отключение прерываний вместо блокировки должно решить мою проблему. но я не понял, почему мьютекс не работает между задачей и ISR, не могли бы вы объяснить это немного подробнее. - person user2567411; 24.11.2015
comment
@ user2567411 Рассмотрим следующую последовательность: task does lock(), does stuff, ISR interrupts, ISR does lock() and is blocked: deadlock! Слабая альтернатива: task does lock(), ..., ISR interrupts, does trylock() [which fails], ISR exits, task does unlock(), ISR interrupts again, does trylock() [which succeeds], does stuff, does unlock(), ISR returns Обратите внимание, что trylock() проверяет блокировку, но не блокирует, если не может ее получить. Возвращает 1=заблокировано, 0=не удалось. - person Craig Estey; 24.11.2015
comment
хм, да, мне пришло в голову прямо перед проверкой этого, что ISR не может ждать даже крошечный период, потому что на одноядерной машине, пока она работает, main() не может снять блокировку, но слабая версия может работать, если ISR имеет idempotent что-то сделать, он может просто попытаться сделать это, а если это невозможно, просто вернуться и дождаться следующего прерывания, чтобы повторить попытку. но в моем случае слишком рискованно предполагать, что я могу сделать все в таких идемпотентных операциях на полпути через проект. Я просто собираюсь использовать отключение/включение прерываний в качестве блокировки. - person user2567411; 25.11.2015