|
Не срабатывает прерывание при чтении по DMA |
|
|
|
Aug 21 2018, 18:22
|
Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564

|
Я общаюсь с SPI флэшкой через USART в синхронном режиме. Передача и прием организованы по DMA каналам. Посылки фиксированной длины (1024 байта). Алгоритм обмена выглядит так: 1. Активирую флэш (CS=0) 2. Настраиваю DMA канал на прием 1024 байт. Разрешаю прерывание по чтению IRQ_RX 3. Настраиваю другой DMA канал на передачу 1024 байт. Разрешаю прерывание по передаче IRQ_TX - в этот момент начинается передача/прием 4. В обработчике IRQ_TX очищаю флаг разрешения прерывания, отключаю DMA канал передачи 5. В обработчике IRQ_RX очищаю флаг разрешения прерывания, отключаю DMA канал чтения + деактивирую флэш (CS=1)
Ну то есть стандартный SPI обмен: посылаю 1024 байта - одновременно принимаю 1024 байта. По окончанию передачи/приема обрабатываю прерывания.
И все вроде бы работает. Но иногда (очень и очень редко) бывает ситуация, когда прерывание по передаче срабатывает, а прерывание по чтению нет! Что я вижу в дебагере в этот момент: 1. Счетчик DMA по передаче равен 0, а по чтению 1. То есть DMA отправил 1024 байта, а прочитал почему-то только 1023. Соответственно, прерывание по чтению не сработает никогда. 2. Ошибки переполнения при чтении (overrun error) нет. Все флаги ошибок равны 0. 3. В регистре чтения USART лежит последний байт посылки (0x89). То есть последний (1024-й) байт посылки похоже таки пришел в регистр. Но счетчик не обнулился 4. Аппаратный флаг прерывания по чтению равен 0. То есть, последний байт был вычитан из регистра буфер. Либо он даже не устанавливался в 1, когда последний байт пришел в регистр
Не могу понять чем это все вызвано. Ведь если отправлено 1024 байта, то и прочитать шина должна была 1024 байта. Байт ведь не мог "потеряться". Или мог? В чем может быть причина такого поведения? Повторюсь, ошибка проявляется крайне редко, в остальном алгоритм четко работает
Сообщение отредактировал avg33 - Aug 21 2018, 18:24
|
|
|
|
|
 |
Ответов
|
Sep 12 2018, 15:36
|
Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564

|
Цитата(haker_fox @ Aug 23 2018, 11:21)  Почитайте мои пути про SPI + DMA. Там LPC4337, но вдруг поможет. Логика, в целом, одинаковая. 1. https://electronix.ru/forum/index.php?showt...=145765&hl=2. https://electronix.ru/forum/index.php?showt...=146837&hl=В кратце: приоритет канала на приём (RX) должен быть выше (выше!!!), чем приоритет канала на передачу! спасибо, с интересом почитал. но сколько не бился ничего не помогает. приоритет на чтение у меня, кстати, выше. не пойму в чем может быть дело
|
|
|
|
|
Sep 12 2018, 19:34
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(avg33 @ Sep 12 2018, 18:36)  спасибо, с интересом почитал. но сколько не бился ничего не помогает. приоритет на чтение у меня, кстати, выше. не пойму в чем может быть дело Значит Вы чего-то не понимаете в работе периферии своего МК. И не зная Ваш МК никто тут не сможет помочь. Кстати, непонятно - зачем и TX-прерывания и RX? При работе с SPI обычно достаточно или того или другого (обычно RX), но никак не вместе. Да и судя по сообщениям, Вы путаете прерывания с DMA-запросами. Это вообще то совершенно разные вещи.
|
|
|
|
|
Sep 12 2018, 20:31
|
Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564

|
Цитата(jcxz @ Sep 12 2018, 22:34)  Значит Вы чего-то не понимаете в работе периферии своего МК. И не зная Ваш МК никто тут не сможет помочь. Кстати, непонятно - зачем и TX-прерывания и RX? При работе с SPI обычно достаточно или того или другого (обычно RX), но никак не вместе. Да и судя по сообщениям, Вы путаете прерывания с DMA-запросами. Это вообще то совершенно разные вещи. Да, видимо что-то делаю не так. Буду признателен, если покажете рабочий пример SPI обмена по DMA. Любого контроллера. Хочу понять принцип. Вы не первый кто пишет, что TX прерывание не нужно. Но я не могу начать передачу по DMA, не разрешив TX прерывание. После отправки последнего байта DMA передает пришедший запрос на прерывание контроллеру - вот и вызывается обработчик. Как же от этого уйти?
|
|
|
|
|
Sep 13 2018, 05:46
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(avg33 @ Sep 12 2018, 23:31)  Да, видимо что-то делаю не так. Буду признателен, если покажете рабочий пример SPI обмена по DMA. Любого контроллера. Хочу понять принцип. А чем Вам поможет как это сделано в каком-то левом МК? Если даже разберётесь в десятках КБ кода... В разных МК работа DMA-периферия организована по-своему. Цитата(avg33 @ Sep 12 2018, 23:31)  Вы не первый кто пишет, что TX прерывание не нужно. Но я не могу начать передачу по DMA, не разрешив TX прерывание. Вы опять путаете и себя и всех. Прерывания (от периферийного блока) к работе DMA имеют очень мало отношения. Прерывание - это сигнал идущий от периферийного блока к контроллеру прерываний, запрос DMA - сигнал идущий от периферийного блока к DMA-контроллеру. И это как правило - разные сигналы. Более того - в некоторых МК есть несколько разных DMA-запросов (single- и burst-). Во многих МК прерывания от периферии (если она работает через DMA) вообще следует запрещать (например так в LPC, XMC4xxx), а обрабатывать прерывания от DMA-канала. Единственное - что на работу DMA-канала могут влиять сигналы прерываний от самого DMA-контроллера (замораживать работу DMA-канала до обработки прерывания от этого канала). Цитата(avg33 @ Sep 12 2018, 23:31)  После отправки последнего байта DMA передает пришедший запрос на прерывание контроллеру Пришедший откуда и куда? На какой контроллер передаёт? У Вас каша в голове, Вы не понимаете как работает система прерываний и DMA в вашем МК. Читайте мануал на МК. В большинстве МК, с которыми я работал, при работе некоей периферии через DMA, прерывания от неё запрещались, а разрешалось прерывание от DMA-канала, о завершении пересылки блока (или очередного блока). В этом прерывании или завершалась работа с периферией, или обрабатывалась текущая порция данных от неё и DMA-канал программировался на новый блок пересылки. Это - штатный механизм работы через DMA. И поищите примеры работы с DMA для своего секретного МК.
|
|
|
|
|
Sep 13 2018, 13:18
|
Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564

|
Цитата Прерывания (от периферийного блока) к работе DMA имеют очень мало отношения. Очень мало - это сколько?)))) Цитата Прерывание - это сигнал идущий от периферийного блока к контроллеру прерываний, запрос DMA - сигнал идущий от периферийного блока к DMA-контроллеру. И это как правило - разные сигналы Вы с кем общаетесь? Сам с собой?) Объясняю еще раз. В моем контроллере периферия запрашивает передачу DMA путем установки прерывания. Не знаю, как это устроено в других контроллерах - в моем именно так. Чтобы начать DMA передачу нужен запрос прерывания от периферии. Если канал DMA включен и настроен на прерывание, то запрос этого прерывания заставляет DMA начать передачу. После передачи элемента (байт/слово) возможны ситуации: 1. Счетчик переданных данных > 0 - DMA очищает запрос прерывания от периферии и ждет нового 2. Счетчик ==0 - DMA передает запрос прерывания контроллеру прерываний. Вызывается обработчик. То есть, если надо отправить байты - я должен настроить DMA канал на прерывание TX и разрешить его (прерывание). Как только прерывание TX разрешено - возникает запрос на TX прерывание и начинается передача. После передачи блока вызовется обработчик прерывания TX. Аналогично с чтением. Стоит ли объяснять как я организую SPI обмен? Я настраиваю один канал на передачу, другой на чтение и разрешаю прерывания RX и TX. Как только передано/прочитано нужное число байт вызываются обработчики прерываний TX/RX. Это к вашему вопросу "а зачем вам TX прерывание". Если знаете как запустить передачу без него в текущих условиях - поделитесь примером Цитата Пришедший откуда и куда? На какой контроллер передаёт? Я обмениваюсь информацией с флэшкой. Об этом было написано в самом начале. Цитата Это - штатный механизм работы через DMA. И поищите примеры работы с DMA для своего секретного МК. Ну в чем-то штатный, а в чем-то нет. Ну либо разрабы этого камня дураки и вообще все организовали не правильно (судя по вашим словам). Я в общем-то и делаю по примерам. Не надо меня держать за дурака. Просто примера SPI обмена через DMA нет. Есть только пример передачи. От него и отталкиваюсь в написании кода Цитата( @ Sep 13 2018, 02:44)  Может не помочь, если речь конкретно о прерывании. Если не знаешь тип контроллера. У меня была похожая ситуация с миландровским Кортексом, он по SPI управляет DDSом. По итогу отказался обрабатывать прерывания от DMA в их контроллере. Описание там очень плохое, и непонятно, глюк в самом контроллере или в моем понимании работы этого контроллера. Видимо точно что-то с прерываниями. Выше писали, что приоритет канала RX должен быть выше, чем канала TX. Потому что запросы DMA по RX должны обрабатываться в первую очередь. У меня так и было сделано. Но вот вчера вечером уже от безысходности поменял DMA каналы местами. Теперь у чтнения приоритет ниже, чем у отправки. И вот уже несколько часов непрерывного чтения и ни одной ошибки (раньше хватало на несколько минут или даже секунд). Понять бы природу странности, ведь по опыту людей все должно быть ровно наоборот. В даташите толком ничего не написано и примеров нет
Сообщение отредактировал avg33 - Sep 13 2018, 13:19
|
|
|
|
|
Sep 14 2018, 08:43
|
Гуру
     
Группа: Свой
Сообщений: 2 223
Регистрация: 3-03-06
Из: Tomsk
Пользователь №: 14 925

|
Цитата(avg33 @ Sep 13 2018, 20:18)  Очень мало - это сколько?)))) Во всех контроллерах происходит событие(event) - например окончание передачи байта, полный/пустой буфер и др. Физически это выход цифрового компаратора, т.е. один проводок внутри контрллера и он выходит из блока в котором произошло событие(SPI, DMA, UART, etc.). А дальше event можно перенаправить в контроллер прерывания или контроллер DMA, или и туда и туда, можно еще и в другой блок, например АЦП, ЦАП и т.д. И каждый блок предпринимает собственные действия по поступлению события - контроллер прерываний вызывает подпрограмму, DMA начинает или останавливает передачу и т.д. Цитата(avg33 @ Sep 13 2018, 20:18)  В моем контроллере периферия запрашивает передачу DMA путем установки прерывания. Не знаю, как это устроено в других контроллерах - в моем именно так. Возможно при переводе перепутали понятие event и interrupt. А возможно и правда на прерывании висит сигнал запуска DMA, это значит разработчики упростили систему. Цитата(avg33 @ Sep 13 2018, 20:18)  Видимо точно что-то с прерываниями. Выше писали, что приоритет канала RX должен быть выше, чем канала TX. Если бы вы назвали контроллер или архитектуру, тогда возможно что-то сказать, а так осталось только помогать вам гадать на "кофейной гуще"
|
|
|
|
|
Sep 16 2018, 12:24
|
Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564

|
Цитата(HardEgor) Возможно при переводе перепутали понятие event и interrupt. А возможно и правда на прерывании висит сигнал запуска DMA, это значит разработчики упростили систему. Если дословно: "The peripheral resource (I/O) requests DMA transfer by asserting an interrupt". У DMA канала есть регистр, в котором указывается номер прерывания, которое инициирует передачу. То есть, если настроить DMA канал на прерывание RX, то event "регистр-приемник полный" инициирует прерывание RX, которое уйдет не в контроллер, а в DMA. DMA прочитает байт из регистра-приемника USART и уменьшит счетчик прочитанных байт. Если счетчик обнулился, DMA передает запрос на прерывание контроллеру и тот вызывает обработчик RX. Вот блок-схема из документации:  Так вот, время от времени возникает ситуация, что отправил я 1029 байт, а получил якобы только 1028. В этот момент счетчик переданных байт = 0, прочитанных = 1. Соответственно и обработчик RX не вызывается и я не могу завершить транзакцию чтения. Хотя последний байт пришел, я вижу его в регистре приемника. Получается по каким-то причинам DMA не обнулил счетчик (прерывание не пришло?) А поциент jcxz выше явно забежал сюда меня потроллить, вот и разводит бесполезный флуд вокруг терминологии Цитата(HardEgor) Если бы вы назвали контроллер или архитектуру, тогда возможно что-то сказать, а так осталось только помогать вам гадать на "кофейной гуще"  F2MC-16FX MB96600 Series http://www.cypress.com/file/241411/downloadКак оказалось, приоритеты каналов тут ни при чем. И новая и старая версии чтения дают сбой при запуске прошивки через отладчик. Если запускаю без отладчика все работает без сбоев. Отладчик может влиять на процесс? Цитата(jcxz) Я не знаю как запустить передачу на сферическом коне в вакууме на неизвестном гипотетическом МК. И никто этого не знает. Я в курсе, что вы не знаете. И сарказма тоже не понимаете, как я вижу. Ну раз не знаете, то и не надо меня убеждать, что я что-то путаю и не понимаю работу своего контроллера. Цитата(jcxz) Вы здесь-то чего хотите? Чтобы Вам посочувствовали? Поплакаться в жилетку?  Если не долбиться в глаза можно увидеть вопросы, которые я задавал. Возможно, у кого-то была похожая проблема. Может быть, у кого-то отладчик тоже влиял на работу и тд. Вас лично никто отвечать не заставляет
Сообщение отредактировал avg33 - Sep 16 2018, 12:25
Эскизы прикрепленных изображений
|
|
|
|
|
Sep 16 2018, 16:41
|
Гуру
     
Группа: Свой
Сообщений: 2 223
Регистрация: 3-03-06
Из: Tomsk
Пользователь №: 14 925

|
Цитата(avg33 @ Sep 16 2018, 19:24)  F2MC-16FX MB96600 Series Это Fujitsu, японцы, с ними мало кто умеет работать. Цитата(avg33 @ Sep 16 2018, 19:24)  Как оказалось, приоритеты каналов тут ни при чем. И новая и старая версии чтения дают сбой при запуске прошивки через отладчик. Если запускаю без отладчика все работает без сбоев. Отладчик может влиять на процесс? В общем случае отладчик может, зависит от отладчика, там есть целая глава "On Chip Debugger". Например в других контроллерах есть биты(флаги), которые сбрасываются, если прочитать определенный регистр - в этом случае отладчик может сломать логику работы. Цитата(avg33 @ Sep 16 2018, 19:24)  Вот блок-схема из документации: Всё правильно, они подразумевают что interrupt - это просто прерывание работы шины ядра на передачу DMA, а есть еще interrupt как последовательность действий по вызову подпрограммы обработки прерывания INT. Собственно на стр. 120 это и нарисовано CASE A когда передача данных идёт с помощью прерывания INT, а в CASE B с помощью DMA. Поверхностно глянул что DMA может маскировать прерывания идущие на контроллер прерываний, да, японцы они такие затейники...
|
|
|
|
Сообщений в этой теме
avg33 Не срабатывает прерывание при чтении по DMA Aug 21 2018, 18:22 zombi Цитата(avg33 @ Aug 21 2018, 21:22) Я обща... Aug 21 2018, 18:42 avg33 Цитата(zombi @ Aug 21 2018, 21:42) В Ваше... Aug 21 2018, 18:55 zombi Цитата(avg33 @ Aug 21 2018, 21:22) В реги... Aug 21 2018, 19:13 avg33 Цитата(zombi @ Aug 21 2018, 22:13) Раз зн... Aug 21 2018, 19:57  controller_m30 Цитата(avg33 @ Aug 21 2018, 22:57) 3. Обр... Aug 21 2018, 20:43   avg33 Цитата(controller_m30 @ Aug 21 2018, 23:4... Aug 22 2018, 20:23 controller_m30 В чём может быть дело не знаю. Тем более не извест... Aug 21 2018, 19:15    V_G Цитата(avg33 @ Sep 13 2018, 06:31) Буду п... Sep 12 2018, 23:44        jcxz Цитата(avg33 @ Sep 16 2018, 15:24) А поци... Sep 16 2018, 13:16      jcxz Цитата(avg33 @ Sep 13 2018, 16:18) Очень ... Sep 14 2018, 10:02       HardEgor Цитата(jcxz @ Sep 14 2018, 17:02) Не обяз... Sep 15 2018, 09:09 Herz Господа! Прошу без грубостей. Если есть какие-... Sep 16 2018, 14:06
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|