Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Драйвер SPORT для Blackfin/uClinux
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
Johny
В связи с переводом проекта под Blackfin/uClinux понадобился драйвер SPORT-порта, обеспечивающий непрерывную прием/передачу.
Нашел bfin_sport (2D-DMA, Autobuffering, MDMA Transfers to userspace).

В кратце посмотрев, пришел к выводу:
При установке режима DMA=2, используется 2-мерная DMA-передача. Два буфера (длиной не обязательно кратной степени 2).
Считывать надо буфер целиком. Считывание синхронное (read уходит в спячку). После завершения read() как можно быстрее надо запустить повторный read(), чтобы не "пропустить" буфер (максимальная длина буфера DMA-передачи 64К слов). То же самое относится к write().
Конфигурирование DMA для автобуферинга происходит только один раз, после этого тут-же запускается прием/передача. Вызов IOCTL для конфигурирования SPORT возвращает -EBUSY, если включена прием и/или передача.

В общем, для моих целей наверное подойдет (64К слов вычитываются за 400 мс - должно хватить на обработку в user-spaсe и повторный запуск read()

Тем не менее, может кому попадались другие варианты (для PXA я использовал самописный драйвер SPI с использованием связного списка DMA-дескрипторов).
cpl
Спасибо,
очень интересно, посмотрим.
rolleyes.gif
Johny
Идея у драйвера на мой взгляд неплохая. Но косяков там немеряно. Сейчас тестирую и пытаюсь бороться по мере сил.
Кстати, максимально возможный размер буфера приема/передачи у исходного драйвера <32кБ. Сейчас расширяю.
Johny
Ребята весьма вольно работают с указателями. Как результат, при конфигурировании SPORT с длиной передаваемого/принимаемого слова менее 17 бит,, DMA - пересылка dma_memcpy() идет совсем не туда:

Цитата
...
static unsigned int *data_rx;
static unsigned int *data_tx;
static short pinpon_rx;
static short pinpon_tx;
static short pinpon_old;
...
static ssize_t sport_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
...
dma_memcpy((void *)(data_tx+pinpon_tx), (const void *)buf, count);
...
}
...
static irqreturn_t dma_tx_irq_handler(int irq, void *dev_id)
{
...
/* Index jump for pinpon_tx */
pinpon_tx ^= dev->config.tx_data_len;
...
}
...
static int sport_configure(struct sport_dev *dev, struct sport_config *config)
{
...
int word_bytes = (config->word_len + 7) / 8;
if (word_bytes == 3) word_bytes = 4;
...
if ((data_tx = kmalloc (config->tx_data_len*word_bytes*2, __GFP_DMA)) == NULL) {
...
/* Initialize pinpon index */
pinpon_rx = config->rx_data_len;
pinpon_tx = config->tx_data_len;
pinpon_old = -1;
...
}
...
Johny
Запостил свои предложения по bag-fix на суд мировой общественности: http://blackfin.uclinux.org/gf/tracker/4589
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.