Jump to content
parovoZZ

Философия аппаратного SPI - чем занять МК?

Recommended Posts

Я сейчас про случай, когда тактовая частота SPI равна половине или даже равна тактовой процессора. Соответственно, чем занять МК, пока идет отправка данных? У нас есть всего 16 тактов (или меньше). Обычно идет проверка флага опустошения буфера. Но тогда в чем профит аппаратного SPI, если на том же USI данные отправляются за те же 16 тактов, но МК занят тактированием(!)?. Вот чем занять МК? Отправить в остановку? Так дольше будем подготавливаться к остановке, потом уход на вектор прерывания (4 такта как минимум) и возврат из него. Ежели заниматься чем-то параллельно, то так же теряем время на обработку прерывания. Получается - только тупить в троттлинге?

Share this post


Link to post
Share on other sites

Занять чем-то современный МК - это вообще вопрос вопросов. Или вы достигли такого уровня, что у вас каждый такт на пользу делу тратится?

Обычно поступают так: сначала ждут готовности SPI, а затем пихают данные. И пока он отправляет полученный байт, занимаются чем-то полезным. Если к моменту, когда можно слать следующий байт, SPI успеет завершить передачу, никакого ожидания не будет. А если не успеет - будет минимальное ожидание. А уж чем МК занять - это вам надо думать...

// не правильный подход - бессмысленное ожидание
uint8_t spi(uint8_t d){
   UDR = d;
   while(!(SPSR & (1<<UDRE));
   return UDR;
}

// правильный подход - минимальное ожидание
uint8_t spi(uint8_t d){
   while(!(SPSR & (1<<UDRE));
   uint8_t res = UDR;
   UDR = d;
   return res;
}

 

Share this post


Link to post
Share on other sites

Конечно ждать. На большой скорости много посторонней задачи в ущерб скорости передачи не сделаешь.
Поэтому на старших контроллерах такие задачи делаются через DMA. И у нас появлется не много кусочков свободы по 16 тактов, а один большой кусок времени, пропорциональный объёму передачи.

Share this post


Link to post
Share on other sites

Вебинар STM32G0 – новый лидер бюджетных 32-битных микроконтроллеров от STMicroelectronics

Компания Компэл приглашает вас 25 сентября принять участие в вебинаре, который посвящен новому семейству микроконтроллеров STM32G0. Вебинар рассчитан на технических специалистов и тех, кто хорошо знаком с семейством STM32. На вебинаре будут освоены современные методы тестирования производительности микроконтроллеров на примере самых бюджетных 32-битных семейств общего назначения STM32G0 и STM32F0 и проведено их подробное сравнение.

Подробнее

14 часа назад, Alexeyslav сказал:

Поэтому на старших контроллерах такие задачи делаются через DMA.

А кроме ARM, есть в каких ядрах DMA?

15 часов назад, ARV сказал:

Или вы достигли такого уровня, что у вас каждый такт на пользу делу тратится?

Не достиг, но всячески стремлюсь.

15 часов назад, ARV сказал:

Если к моменту, когда можно слать следующий байт, SPI успеет завершить передачу, никакого ожидания не будет. А если не успеет - будет минимальное ожидание. А уж чем МК занять - это вам надо думать...

Обычно, массив уже готов полностью к передаче. Я так понимаю, это с технологией DMA мы можем отослать за раз 5 байтов, а на простых МК типа восьмибиток придется отвлекаться на каждый байт.

Share this post


Link to post
Share on other sites

Вот не жалею что перешел на стм32 :D

По сабжу. А что если не 16 тактов занять? Спи отвалится? Если нет то можно что угодно.

Как показали выше, ждать нужно до отправки, а потом смысла нет. Вы отправили последний байт и ждете пока улетит, хотя могли уже что то делать :)

Думаю если можно слать кусками, то есть не имея лимита в 16 тактов, то можно что угодно делать)

while () {
  if (spi_ready()) {
    spi_send(buf++);
  } else {
    work();
  }
}

 

Share this post


Link to post
Share on other sites
                     

Литиевые батарейки Fanso в беспроводных датчиках пожарно-охранной сигнализации

Выбор подходящего элемента питания, способного обеспечивать требуемый уровень напряжения и выдавать необходимый ток на протяжении всего периода эксплуатации беспроводной пожарно-охранной системы является одной из первостепенных задач. Наиболее подходящим для этих целей элементом являются литий-тионилхлоридные элементы питания, а одним из наиболее конкурентоспособных производителей – компания Fanso, предлагающая своим клиентам продукты как универсальные, так и разработанные специально для решения конкретных задач.

Подробнее...

10 минут назад, DrobyshevAlex сказал:

Вы отправили последний байт и ждете пока улетит

А где тут отправляется последний байт, интересно, по вашему мнению???

buf++

это навсегда!!!

надо было какую то проверку наличия данных в буфере куда-нить присобачить, да ведь? типа:

while(1)
{
  if(SpiReady())
  {
      if(byteCount != 0)
      {
          send(buf++);
          byteCount--;
      {
  }
  work();
}

...
где то в ворке:
ARRAY[0] = 33;
ARRAY[1] = 34;
buf = ARRAY;
byteCount = 2;

 

Share this post


Link to post
Share on other sites

Что-то я вообще не пойму, нафига ждать флаг. прерывания же есть. Настроить его на окончание передачи и все. тогда работа с SPI будет выглядеть примерно так:

  1. Загрузили данные в буфер.
  2. МК занимается полезной работой
  3. Сработало прерывание по окончанию отправки
  4. Загрузили следующий байт
  5. МК занимается полезной работой
  6. ...

Share this post


Link to post
Share on other sites
9 минут назад, ruhi сказал:

А где тут отправляется последний байт, интересно, по вашему мнению???

Тут это где? Вы о чем вообще? Я написал что если кому то надо отправить вот так

spi_write(b1);

а дальше например уже не надо слать, то в случае ожидания после отправки байта таким способом

16 часов назад, ARV сказал:

// не правильный подход - бессмысленное ожидание uint8_t spi(uint8_t d){ UDR = d; while(!(SPSR & (1<<UDRE)); return UDR; }

как раз бессмысленное ожидание, и я сказал что раньше об этом уже написали

26 минут назад, DrobyshevAlex сказал:

Как показали выше, ждать нужно до отправки

как бы это об этом и было.

 

9 минут назад, ruhi сказал:

buf++

это навсегда!!!

да ну? а не чего что это вообще просто набросок алгоритма, ни чего не имеющего общего с реальной прилой? может у вас всего 1 байт так там вообще не надо смещать указатель.

или вам тут надо готовый 100%  код написать? сами ни как? тогда давайте 100% готовое тз.

9 минут назад, ruhi сказал:

надо было какую то проверку наличия данных в буфере куда-нить присобачить, да ведь?

о, оказывается понимаете, тогда что это было за сообщение? показать что вы гений? :D

ТАк я пойду вашим путем, Я вставил ваш код!!! а он не компилится!!! вы врете!

1 минуту назад, BARS_ сказал:

прерывания же есть

кстати да :)

Edited by DrobyshevAlex

Share this post


Link to post
Share on other sites
5 минут назад, BARS_ сказал:

работа с SPI будет выглядеть примерно так:

так это же как бы DMA и получится!

А мужики то не знают :) !

Share this post


Link to post
Share on other sites
2 минуты назад, ruhi сказал:

ак это же как бы DMA и получится!

это получится простое прерывание. где код в прерывании выполняясь остановит выполнение кода основного цикла.

основное отличие dma от обычных прерываний как раз в тмо что этого нет, так что нет такого понятия как "как бы DMA" :)

 

 

дергать ножками с паузами в цикле - тоже как бы аппаратный  spi получиться тогда :D

 

Share this post


Link to post
Share on other sites

А сколько тактов у того же STM32 занимает переход на вектор прерывания?

Share this post


Link to post
Share on other sites
10 минут назад, ruhi сказал:

так это же как бы DMA и получится!

И близко не он. С DMA это было так:

  1. Сформировали массив данных
  2. Пнули DMА и пошли делать полезную работу
  3. Получили прерывание по окончанию отправки всего буфера.

Ну и DMA есть смысл использовать только на больших объемах данных. Если передавать с его помощью по несколько байт, то получим падение скорости вместо выигрыша.

Share this post


Link to post
Share on other sites

Читал на хабре что чел делал осфиллограф, и с дма его макс скорость замера упала)

Share this post


Link to post
Share on other sites
1 час назад, BARS_ сказал:

то получим падение скорости вместо выигрыша.

тут обычно целью является унификация доступа к функциям периферии, падение скорости (вообще скорость) особо не важна если вы работаете с малыми объемами данных.

1 час назад, DrobyshevAlex сказал:

и с дма его макс скорость замера упала)

значит неправильно было сконфигурировано-использовано. С дуру как говорится все можно сломать :( .

Share this post


Link to post
Share on other sites

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

К тому же на вход в прерывание и выход из него тратится минимум 8 тактов, плюс минимально полезная работа с указателем и пересылка - исчерпывается весь лимит на "ожидание" при высокой скорости SPI. Поэтому в прерываниях есть смысл только при работе SPI на низкой тактовой частоте. Интересно, кому-то хоть раз требовалось реализовать МЕДЛЕННУЮ работу с периферией? ;) 

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

Edited by ARV

Share this post


Link to post
Share on other sites
9 минут назад, ruhi сказал:

падение скорости (вообще скорость) особо не важна если вы работаете с малыми объемами данных.

А для малых объемов и DMA не нужен, особой унификации он не даст. DMA удобен либо в случае пересылки больших объемов данных, либо при организации большого количества измерений. К примеру, запустил АЦП и он пишет в буфер через DMA. 

Share this post


Link to post
Share on other sites
30 минут назад, ARV сказал:

Интересно, кому-то хоть раз требовалось реализовать МЕДЛЕННУЮ работу с периферией?

в последний раз мне пришлось реализовать очень быструю работу по SPI (кстати) - больше 2Мегабайт в секунду непрерывный трафик,

теперь всю свою предыдущую работу с периферией я с полным основанием рассматриваю как "МЕДЛЕННУЮ работу с периферией",

если действительно интересно :) !

300МГц АРМ процессор, если интересно.

Edited by ruhi

Share this post


Link to post
Share on other sites
Только что, ruhi сказал:

больше 2Мегабайт в секунду

Но это явно не из оперы AVR... :) 

Share this post


Link to post
Share on other sites
7 минут назад, ARV сказал:

Но это явно не из оперы AVR...

Написано же - АРМ, 32 бита, хотя какая разница? Он тоже Атмел(бывший) SAME70 - серия, на отладочной плате с ладошку, со светодиодами, с USB программатором, с Атмел студией ...

Share this post


Link to post
Share on other sites

Разница большая. AVR это принципиально не под силу, а для ARM, пожалуй, даже и не много...

Share this post


Link to post
Share on other sites
3 минуты назад, ARV сказал:

AVR это принципиально не под силу

дело не в типе процессора, а в тактовой частоте, если появится AVR 300МегаГерцный, ему тоже будет под силу.

Share this post


Link to post
Share on other sites
7 минут назад, ruhi сказал:

ему тоже будет под силу.

Не получится, он не умеет непрерывно лить по SPI. На счет Atmel не знаю, но STM могут лить данные непрерывным потоком даже без DMA, а вот у AVR будут разрывы в момент прогрузки очередного байта.

Share this post


Link to post
Share on other sites
Только что, BARS_ сказал:

у AVR будут разрывы в момент прогрузки очередного байта

Вроде как у самых последних реинкарнаций уже нет, но это не точно. Вроде там Микрочип сдлал систему событий - местами она почти как DMA...

Share this post


Link to post
Share on other sites
4 минуты назад, BARS_ сказал:

На счет Atmel не знаю,

вообще то AVR это тоже Атмел. Мне казалось что SPI периферийный узел у них (у Атмела) один и тот же во всех процессорах, с точки зрения регистровой модели. Но я могу конечно ошибаться по прошествии времени.

буферизация одного байта на отправку там вроде всегда была предусмотрена.

Share this post


Link to post
Share on other sites
58 минут назад, ARV сказал:

Интересно, кому-то хоть раз требовалось реализовать МЕДЛЕННУЮ работу с периферией?

SPI - нет, I2C - да. Но там тупо частоту МК понижал.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By parovoZZ
      AREF  - внутренний ИОН 1.1в
      Вот такой код снятия результатов:
      temp = ADC; if (ADCH & (1<<ADCH1)) // Если значение отрицательное { temp |= 0xFC00; temp = (~temp) + 1; } Value_current_lsb = (uint8_t)(temp >> 2); Никак не пойму - на выбранные дифф. входы надо подать 85 мВ, чтобы АЦП выдал 0. Но это могу списать на внутренний ОУ в виде УГ. Если подаю  -1,1 в - то получаю 127.  Здесь все верно. Но при подаче положительного смещения те же 127 получаю уже при 0,72в. Что за ерунда? Неужели ОУ на столько УГ? Либо же где-то теряется разряд?
    • By parovoZZ
      Ну, собственно, сабж. Питание - от 2.4 и до 3.6. На сигнальном выводе необходима половина напряжения питания (по постоянке, разумеется).
    • By parovoZZ
      Не секрет, что адресация глобальных переменных прямая, а переменных в стеке - косвенная. Стек в AVR программный, то бишь откусывается от ОЗУ. Так вот вопрос - при передаче в функцию (и обратно) больших объемов данных (которые невозможно передать через РОН) все же что будет производительнее - через глобальные переменные или через параметры? Понятно, что в функцию вида
      uint8_t My_super_function (uint8_t data); переменные уйдут через РОН,  а вот в такую
      void My_super_function (uint8_t *data, uint8_t *ret); через стек? Так может ну его нафик, стек этот?
    • By parovoZZ
      Поставил LUFA, следом абсолютно не нужный мне ASF. Но в упор не понимаю - как создать проект на базе этой библиотеки из студии? Приходится вручную копировать папку с заголовочниками LUFA, прописывать пути в makefile, лишние телодвижения по добавлению папки в свойства проекта. Если я это делаю всё вручную, то тогда для чего это расширение? Примеры я могу и так покрутить. ЗЫ - не слишком высокий скилл в юзании Atmel Studio/
×
×
  • Create New...