Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:1
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:5
Форум » starterkit.ru » Embedded Linux
imx53, nanosleep и прерывания
buletz
Добавлено 28.02.2013 17:06
0
Сообщение: 1
buletz
3

Пункты: 5920
Регистрация: 16.11.2011
Пол: Мужчина
I. Вводная
Пытаюсь отладить работу аппарантого SPI в режиме slave, на борде SK-MX53-OEM.
Написал простенький драйвер (модуль в kernel-space), который по прерыванию читает данные из RX FIFO (SPI) и сохраняет их в мегабайтный буфер, т.к. FIFO больно маловат, всего 64 байта.

Прерывание назначил по признаку заполнения RX FIFO 24 байтами (т.е. как только получил 24 байта - генерит прерывание). Это дает хороший запас от переполнения FIFO (24 байта далеко от 64).
Драйвер создает девайс /dev/spislave и по команде read выдает данные из буфера.

Сделал простенькую програмку, которая читает /dev/spislave.

II. Суть проблемы

Все работает нормально (данные идут без потерь) пока программа жрет все 100% ресурсов, т.е. тупо сидит в while(1) цикле и постоянно опрашивает /dev/spislave.
Как только я добавляю в цикл nanosleep(1 наносек), чтобы разгрузить проц, то сразу идут потери данных, прерывание генерится реже чем положено.

iii. Вопрос

Не может ли быть так, что nanosleep включает какой-то режим энергосбережения который вырубает клоки на аппаратном SPI и в результате я теряю данные ?

В описании nanosleep ничего про это не нашел, но других объяснений тоже пока нет.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 28.02.2013 20:45 Сообщение: 2
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата

по прерыванию читает данные из RX FIFO (SPI) и сохраняет их в мегабайтный буфер


Я что-то не пойму, если буфер на мегабайт - зачем его все время вычитывать и как чтение из памяти может влиять на прерывания ? Где-то у вас ошибка драйвере.
Спуститься к концу Подняться к началу
Персональная информация
titan83
Добавлено 01.03.2013 13:55 Сообщение: 3
titan83
3

Пункты: 3141
Регистрация: 16.12.2012
если вы хотите задержку в 1нс, то вряд ли у вас это получится в линуксе. у меня 9g45, на ней в поставляемом стартеркитом линуксе разрешение таймера было установлено в 10 000 000 нс (10 мс), естественно, выйти быстрее из нанослипа не получалось. после пересборки ядра с таймером высокого разрешения 10 мс превратились в 1нс, и дело пошло бодрее - задержка при выходе из нанослипа стала 20-30 мкс, это на стандартном ядре, без RT-патчей, там, видимо, эту цифру можно еще снизить.
посмотрите cat /proc/timer_list, если в поле Resolution у вас стоит не 1 нс, то вы не сможете быстро выходить из нанослипа
Спуститься к концу Подняться к началу
Персональная информация
buletz
Добавлено 01.03.2013 15:39 Редактировалось 01.03.2013 20:48 Сообщение: 4
buletz
3

Пункты: 5920
Регистрация: 16.11.2011
Пол: Мужчина
Чтобы говорить предметно, исходник тут:
http://pastebin.com/MFnVSYGr

Цитата
Я что-то не пойму, если буфер на мегабайт - зачем его все время вычитывать и как чтение из памяти может влиять на прерывания ? Где-то у вас ошибка драйвере.


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

2. Я убрал nanosleep и вместо него поставил просто пачку пустых циклов - так все работает норм. Даже если ставлю пустые циклы на 500 милисек, то драйвер все успешно накапливает в буфере и потом через 500 милисек выдает (через read устройства /dev/spislave) накопившиеся данные без ошибок.
Это говорит о том, что данные по прерыванию переносятся в мегабайтный буфер нормально, без всяких пропусков и переполнений RX FIFO (который всего 64 байта).

Картинка входа и выхода из прерываний выглядит нормально, вот так:
(здесь единица - вход в прерывание SPI, ноль - выход).

title

Когда ставлю nanosleep то получается так:
(бледные импульсы это те которые с переменным джиттером, то есть их появление плавает во времени)

title

3. Выходит, что nanosleep почему-то мешает драйверу нормально работать.
Почему - для меня пока вопрос открытый...
Спуститься к концу Подняться к началу
Персональная информация
buletz
Добавлено 01.03.2013 15:44 Редактировалось 01.03.2013 15:45 Сообщение: 5
buletz
3

Пункты: 5920
Регистрация: 16.11.2011
Пол: Мужчина
а вот исходник user-space программки, которая читает из драйвера.
http://pastebin.com/ZRduKynP
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 01.03.2013 16:33 Редактировалось 01.03.2013 16:37 Сообщение: 6
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Почитайте про средства синхронизации в ядре Linux и забудьте про переменные которые вы используете (static char locked;). Например тут
http://www.ibm.com/developerworks/ru/library/l-linux-synchronization/
Сделайте например 2 буфера - тогда вам вообще не нужно будет разруливать доступ к указателям - пока заполняете 1, второй доступен для чтения и наоборот. Реализуйте ф-цию poll в драйвере по заполнению одного из буферов - тогда вам не надо постоянно вычитывать буфер в юзерспейс, система передаст управление poll/select в юзерспейс как только очередной буфер будет готов для чтения.
Спуститься к концу Подняться к началу
Персональная информация
buletz
Добавлено 01.03.2013 17:13 Сообщение: 7
buletz
3

Пункты: 5920
Регистрация: 16.11.2011
Пол: Мужчина
спасибо за подсказку. попробую.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 01.03.2013 17:35 Редактировалось 01.03.2013 17:37 Сообщение: 8
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Потом как получится - уберите чтение FIFO в прерывании и примените DMA, после этого сделайте не 2 а побольше буферов и менеджер памяти как в v4l2 :) и добавьте поддержку mmap в драйвере. В общем надо знать какая задача - непрерывный поток принимать или еще отвечать надо что-то по spi.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux