реклама на сайте
подробности

 
 
> Драйвер SPORT для Blackfin/uClinux, непрерывная передача
Johny
сообщение Sep 3 2009, 13:18
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 140
Регистрация: 18-10-05
Пользователь №: 9 792



В связи с переводом проекта под 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-дескрипторов).
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Johny
сообщение Sep 16 2009, 10:03
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 140
Регистрация: 18-10-05
Пользователь №: 9 792



Ребята весьма вольно работают с указателями. Как результат, при конфигурировании 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;
...
}
...
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 3rd August 2025 - 11:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01357 секунд с 7
ELECTRONIX ©2004-2016