Вопрос интервью — Как непрерывно читать буфер без потери данных

#c #embedded-linux #i2c #spi #can-bus

#c #встроенный-linux #i2c #spi #can-bus

Вопрос:

Я инженер по встраиванию, с небольшим опытом. Я был на собеседовании, и мне задали вопрос, который, я думаю, не является новым и на который уже есть ответы:

У вас есть периферийное устройство, которое постоянно получает входные данные из внешнего мира, у периферийного устройства есть буфер. Скорость ввода время от времени меняется. Периферийное устройство должно прочитать входной буфер и обработать его. Он проверяет входное сообщение и видит, соответствует ли оно настроенному фильтру. Если он совпадает, он пересылается, иначе он отбрасывается.

Вопросы были похожи:

  1. Как вам это удается?
  2. Что, если буфер заполнится? У вас есть только буфер ограниченного размера? Периферийное устройство имеет только определенную скорость обработки сообщений буфера.
  3. Как вы адаптируете буфер к различным скоростям ввода?

Ценю вашу помощь. Спасибо.

Ответ №1:

В основном они проверяют, кодировали ли вы когда-либо программу для какого-либо последовательного периферийного устройства, так что это довольно хороший вопрос для интервью, чтобы проверить, является ли кто-то полным новичком.

Обычным способом сделать это «старым школьным» способом было бы настроить прерывание rx. Если данные могут поступать нерегулярно, и нам не разрешается терять данные, то прерывание — практически единственный разумный способ. Особенно, если планируется поддерживать и другие скорости передачи данных.

Затем проверка фильтра может быть помещена внутри ISR (за исключением CAN, где такие проверки фактически выполняются аппаратно). И с этого момента действительные данные передаются в кольцевой буфер программного обеспечения. Это минимизирует время выполнения внутри ISR, одновременно решая проблему с ограниченными аппаратными буферами. Защита повторного входа данных предпочтительно должна выполняться кодом кольцевого буфера.

Современный способ скорее состоял бы в том, чтобы избегать прерываний и вместо этого использовать DMA, если микроконтроллер поддерживает это. Это освобождает процессор от необходимости иметь дело с частыми прерываниями rx. Тогда мы можем просто менять целевой адрес буфера DMA каждый раз, когда буфер заполняется, и работать с необработанным буфером оттуда. Или, альтернативно, просто грубо скопируйте весь буфер DMA в другом месте, если мы по какой-то причине не можем поменять адрес буфера DMA.

Комментарии:

1. Спасибо за ответ. Это очень логично. Прерывания — это правильный путь. Может ли это применяться ко всем протоколам последовательной связи, таким как SPI, I2C, ..? Неубедительный вопрос:: Что, если входные данные поступают с высокой скоростью? Поскольку прерывания не могут быть поставлены в очередь, не теряем ли мы входные данные, если ISR недостаточно быстр? (ISR требуется время для обработки прерывания время для проверки фильтра время для копирования данных в буфер SW)

2. @Naveen Да, вышеуказанное универсально для всех последовательных шин. И если входные данные поступают со скоростью, с которой ваш процессор не может справиться, никакое количество очередей вас не спасет. Время обработки самих фактических данных, скорее всего, больше, чем накладные расходы на прерывание задержка, поэтому, если вы даже не можете получить данные вовремя, как вы ожидаете, что у вас будет время сделать что-то значимое с этим позже?. Инженерной практикой № 1 было бы написать разумную спецификацию, а № 2 — задать вопрос, имеет ли спецификация какой-либо смысл.

3. Итак, если у вас есть 10 МГц SPI, бомбардирующий паршивый AVR, работающий на 8 МГц системных часах, проблема не в том, как заставить AVR отвечать вовремя (этого не произойдет), а в том, чтобы подвергнуть сомнению общий дизайн системы и поставить под сомнение выбор скорости передачи данных и микроконтроллера.