Johny 0 3 сентября, 2009 Опубликовано 3 сентября, 2009 · Жалоба В связи с переводом проекта под 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 0 3 сентября, 2009 Опубликовано 3 сентября, 2009 · Жалоба Спасибо, очень интересно, посмотрим. :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johny 0 15 сентября, 2009 Опубликовано 15 сентября, 2009 · Жалоба Идея у драйвера на мой взгляд неплохая. Но косяков там немеряно. Сейчас тестирую и пытаюсь бороться по мере сил. Кстати, максимально возможный размер буфера приема/передачи у исходного драйвера <32кБ. Сейчас расширяю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johny 0 16 сентября, 2009 Опубликовано 16 сентября, 2009 · Жалоба Ребята весьма вольно работают с указателями. Как результат, при конфигурировании 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 0 17 сентября, 2009 Опубликовано 17 сентября, 2009 · Жалоба Запостил свои предложения по bag-fix на суд мировой общественности: http://blackfin.uclinux.org/gf/tracker/4589 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться