Перейти к содержанию
    

Портирование linux на С64x+

Спасибо, немного уменьшили мне возни. Но вопрос - а с какой целью проверка на выравнивание стоит? Это же в принципе можно и обойти в ф-циях пересылки в самом драйвере nand, проверяя выравнивание, и обходя невыравненные случаи отдельным путем, ну а из nand_base убрать, хотя бы по условной компиляции по типу драйвера железа nand.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проверка на выравнивание стоит только при записи. Задумана, как я понимаю, оттого, что NAND пишет данные страницами, и перед записью необходимо загрузить всю страницу в буфер страницы (статическоого ОЗУ внутри NAND-чипа). Буфер страницы используется и для записи, и для чтения страниц, при обмене по внешней шине. Для того, чтобы записать правильную страницу, весь буфер должен быть обновлен. Именно поэтому и возникает требование выравнивания. По сути оно означает, что мы даем данные на N целых страниц, а значит, можно их писать целиком, и буфер страницы после операции будет снова свободен. Если же буфер заполнить только частично, то любое чтение массива NAND его перепишет новыми данными.

 

NB: строго говоря, нынешние NAND допускают дозапись страниц, если при этом лишь некоторые единички выжигаются в нолики. Правда количество таких дозаписей ограничено пальцами одной руки, если верить даташитам. Мы пробовали в одном проекте на MSP430 писать лог работы системы и ввиду малости ресурсов ОЗУ решили попробовать дозапись страниц, причем страница заполнялась за 200-300 дозаписей. И ничего, работает уже года два. Но даташит такое не позволяет :) В драйверах mtd/nand, по-видимому, вообще запрещено дозапись вести, чтобы никого не искушать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

После переписывания mtdchar.c имеем следующие результаты:

1) Драйвер davinci_nand (оригинал)

/mnt # time dd if=/dev/mtd4 of=/dev/null bs=4K count=10000
10000+0 records in
10000+0 records out
real    0m 4.36s
user    0m 0.00s
sys     0m 4.35s

 

2) Драйвер c6x-aemif-nand (мой)

/mnt # time dd if=/dev/mtd5 of=/dev/null bs=4K count=10000
10000+0 records in
10000+0 records out
real    0m 3.13s
user    0m 0.03s
sys     0m 0.65s

 

Как видим, общая скорость достигла 13МБ/с, выросла на 40% по сравнению с davinci_nand, и на 55% по сравнению с исходным замером (давно делался). Настройки строба AEMIF сейчас имеют предел в 20 МБ/с при потоковом чтении. То есть, удалось использовать до 65-66% пропускной способности шины AEMIF.

 

Но, что особенно приятно, занятость CPU в копировании удалось сократить со 100% до 20%!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для истории положим сюда осциллограммы стробов чтения C6424 AEMIF для NAND.

Настройки AEIMF такие: A1CR = 0x04100108, частота 100МГц (CPU/6).

 

Обращаю внимание, что:

1) Строб чтения соответствует настройкам, 5 тактов на частоте 100 МГц.

2) Стробы сгруппированы по 8, видимо это как раз размер фифо у контроллера DMA.

3) Между группами имеется лишь небольшой зазор в 25 нс, который повторяется регулярно много раз подряд, что говорит о том, что других циклических процессов (например, префетча на 128 байт) там нет.

4) Зазор между группами составляет примерно 6% трафика. Максимальная скорость передачи составляет примерно 18.8 МБ/с вместо 20 МБ/с. С оверхедом драйвера достигнуто 13.3 МБ, то есть около 70% от практического потолка.

 

Вот собственно картинки.

post-56107-1367835833_thumb.jpg

post-56107-1367835839_thumb.jpg

post-56107-1367835847_thumb.jpg

post-56107-1367835853_thumb.jpg

Изменено пользователем Hoodwin

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для меня это ОЧЕНЬ актуальная тема

 

Скажите, возможно ли добиться скорости отклика сопоставимой со standalone, или SYS/BIOS, применив linux портированый на C6000 ?

 

Для ARM есть интересная статья http://www.at91.com/linux4sam/bin/view/Linux4SAM/RealTime

как можно увидеть максимальная задержка в лучшем случае составляет порядка 600мкс. Думаю в standalone дела будут обстоять намного лусше.

 

а как в вашем случае с Linux+C6000?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не надо читать всякие устаревшие LDD2 :)

1) В ядре 2.6 map_user_kiobuf не и в помине. Для выковыривания физических адресов есть вызов get_user_pages. С тучей параметров. Можете посмотреть реализацию copy_to_user для x86 (arch/x86/lib/usercopy_32.c).

2) Сами функции copy_to|from_user определяются для каждой платформы отдельно, поэтому они не обязаны работать с mmu в явном виде, а могут использовать положения отдельной архитектуры. Ну, то есть, попросту говоря, на платформах без MMU можно просто использовать один вызов memcpy. Кстати, смотрел тут как раз на ветку ARM, чтобы подсмотреть, какое условие используется для разделения случаев, когда можно считать виртуальные адреса физическими, а когда нужно страницы листать. Так вот (arch/arm/include/asm/uacess.h):

#ifdef CONFIG_MMU
extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n);
extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned long n);
#else
#define __copy_from_user(to,from,n)     (memcpy(to, (void __force *)from, n), 0)
#define __copy_to_user(to,from,n)       (memcpy((void __force *)to, from, n), 0)
#define __clear_user(addr,n)            (memset((void __force *)addr, 0, n), 0)
#endif

 

3) Что касается конкретно модуля mtdchar.c, то я оставил этот изврат с kmalloc/copy_*_user только для архитектур с MMU. В моем случае я сделал оптимизированный вариант, который сразу пользовательский буфер передает драйверу. Действительно, в этом случае EDMA пересылает сразу пользователю и вызов copy_to_user не нужен. Но copy_to_user - это общий интерфейс передачи данных из ядра пользователю, и он много где используется. Правда, в основном копируются небольшие структуры, менее 256 байт. Но при больших размерах буферов выигрыш может быть ощутим, EDMA копирует, а процессор обработкой занят.

 

 

--

Добавление. Надо сказать, что семантика фрагментированного копирования по страницам для mtdchar не вполне подходит. Если посмотреть в исходник drivers/mtd/nand/nand_base.c, то в самом начале функции nand_do_write_ops видим:

        /* reject writes, which are not page aligned */
        if (NOTALIGNED(to) || NOTALIGNED(ops->len)) {
                printk(KERN_NOTICE "%s: Attempt to write not "
                                "page aligned data\n", __func__);
                return -EINVAL;
        }

 

А если делать обход пользовательского буфера по страницам, то возможна ситуация, когда смещение в странице произвольно, и длина данных до конца страницы не будет удовлетворять критерию выровненности данных для NAND. И тогда запись вообще обломится. Для обхода этой проблемы и придумано копирование copy_from_user в непрерывный буфер ядра.

Так его реализация и есть memcpy в обертке. Вообще, поработав довольно плотно с v4l - сильно разочаровался в линуксе. Пишут черти как, только дыры латают. Теперь можно мне не странно, что мой телефон с 4 ядрами по 2.4 ГГц тормозит иногда - велкам в удивительный мир линукса... Для которого кстати нет ни одного приличного файлменеджера.. Жертва аборта короче имхо он, все вцепились в его призрачную халявность.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Меня больше всего вот это выражение интересует:

 

Вообще-то ядро 2.6 уже значительно переработано в плане блокировок. Оно почти полностью реентрантно, а обработчики прерываний разделены на две фазы, быструю (до планировщика) и медленную (после планировщика), что при правильном проектировании может дать определенную выгоду в производительности и реактивности. ну и, кроме того, если что-то требует быстрой реакции, то почему не провести это вообще в обход ядра, перехватив прерывание напрямую. Можно и модуль написать и в рантайме его (пере)запускать.

 

Хотелось бы узнать как это писать приложение в обход Linux, если есть Linux на борту? Это уже SYS/Link получается, а это уже SYS/BIOS+Linux

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скажите, возможно ли добиться скорости отклика сопоставимой со standalone, или SYS/BIOS, применив linux портированый на C6000 ?

 

Думаю, что SYS/BIOS без проблем, а насчет standalone не уверен. Ясно что если задачу сузить, то можно ее более эффективно решать. Но тут нужно сделать оговорку на то, что считать скоростью отклика? Тупо скорость реакции на прерывание? Или скорость расчета более сложного, запущенного внешним прерыванием? Уточните, пожалуйста.

 

На данный момент мои наблюдения таковы. Линукс однозначно проигрывает на малых приложениях, которые сами по себе по ресурсам данных влезают в L2. Код более менее сносно отрабатывает за счет кэша L1P, а контроллер внешней памяти L3 откровенно тупой у TI, он для выборки данных CPU не очень годится. Как пример, скорость копирования L1-L1 почти 6ГБ/с, а L3-L3 - всего 100Мб/с с учетом кэша. в 60 раз! Поэтому как только мы линукс выбираем, нужно быть готовым к тому, что L1D и L2 станут кэшами, и все данные пользователя уедут в L3, ну и мы получим среднестатистическое болото в 60 раз медленнее потоковой задачи, заточенной под счет на DSP. Я вот сказал бы, что такие значительные проседания скорости доступа к памяти приводят к заметной разнице в скорости реакции, когда реакция подразумевает какие-то вычисления.

 

Однако справедливости ради надо сказать, что процессор допускает частичное превращение в кэш L1D и L2. И вот тогда открываются возможности по размещению критических к скорости данных в этой памяти. Например, мой процессор C6424 имеет аж 48К памяти L1D, которая вообще никогда кэшем не бывает. То есть, туда можно залить данные и считать со скоростью standalone приложения прямо в линуксе! Но проблема в том, что линукс пока этого не умеет. Для него эти адреса вне закона, он не умеет выделять эту память приложениям. И в итоге они ей вообще не пользуются. Одна из задач оптимизации - научить приложения коллективно использовать эту память. Тогда скорость вычислений можно поднять в разы.

 

Другой проблемой является слабая поддержка аппаратных ускорителей, которая приводит к тому, что многие вещи надо делать через прерывания. Например, драйвер сетки не пользуется аппаратной фичей компоновки пакета из фрагментов, из-за чего он копирует вручную (!) все тело сообщения по кусочкам из L3 в L3 и уже потом посылает. Как я уже упоминал, скорость копирования L3-L3 около 100МБ/с. Скорость сетки порядка 10МБ/с. Итого, если приложение загружает сетку на полную катушку, то только драйвер сетки сжирает 10% ресурса процессора на копирование памяти. На самом деле и больше. Хотя мог бы просто дескрипторы кусочков правильно настроить. Индусы, которые писали драйвер davinci, утверждали, что они умышленно не парились с этим, поскольку, видите ли, контроллер не умеет считать на лету IP контрольные суммы, и их приходится считать ядру, а для этого ему все равно надо прошаривать все пакеты на чтение, и это немногим короче, чем подсчет сумм параллельно с копированием в новый буфер.

 

Подобные проблемы есть и в других подсистемах. Их также можно решать в рамках обычного подхода. Это позволит разгрузить процессор и больше считать.

 

Что касается задержек, то мы стараемся аппаратно придердиваться парадигмы, что данные нужно закачать в память без потерь и обеспечить линуксу большие резервы времени для обработки. Правильное сопряжение с аппаратурой позволяет сделать систему не очень капризной ко времени реакции на конкретное прерывание. В такой парадигме все упирается в итоге в загрузку системы. Там, где нам прямо нужно сделать реакцию в наносекунды, мы просто ставим ПЛИС и рулим ей из линукса. Зато в какой-нибудь чисто вычислительной задаче с у нас C6000 данными в L2/L1D с частотой в 600МГц может запросто уделать Celeron с большей частотой или там ARM. Кодек там какой или фильтр.

 

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

 

Хотелось бы узнать как это писать приложение в обход Linux, если есть Linux на борту?

 

1) Можно критические части кода транслировать компилятором TI а не GCC, это дает все возможности для ускорения кода за счет software pipeline. Можно разогнаться в 5-6 раз при том же исходном коде. Например, я такое наблюдал, когда пересобирал библиотеку упаковки данных для нашего приложения, упаковка ускорилась раз в 5.

2) Можно критические части данных размещать в L2 или L1, если отобрать часть этой памяти у кэша.

3) Про обработку прерывания не скажу сейчас, не доводилось отбирать прерывания у ядра целиком.

 

Вообще, поработав довольно плотно с v4l - сильно разочаровался в линуксе. Пишут черти как, только дыры латают. Теперь можно мне не странно, что мой телефон с 4 ядрами по 2.4 ГГц тормозит иногда - велкам в удивительный мир линукса...

ну так чудес то не бывает. Всем лень оптимизировать код под свое железо. Андроид еще хуже в этом плане, мне кажется. :) С его "мультизадачностью" вообще стыдно хвастаться количеством ядер.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как пример:

есть задача принимать данные по spi от ацп. Часто дискретизации порядка 4800гц. При этом, с приходом каждого отсчета нужно расчитывать ДПФ. Таким образом, частота прерываний составляет 4800гц. Думаю, подсистема linux не способна обрабатывать прерывания на такой скорости.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть задача принимать данные по spi от ацп. Часто дискретизации порядка 4800гц. При этом, с приходом каждого отсчета нужно расчитывать ДПФ. Таким образом, частота прерываний составляет 4800гц. Думаю, подсистема linux не способна обрабатывать прерывания на такой скорости.

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

Продумайте вначале архитектуру вашего приложения прежде чем что-то писать.

Зачем дёргаться на каждый сэмпл, если можно буферизировать их и запускать обработку сразу N сэмплов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Продумайте вначале архитектуру вашего приложения прежде чем что-то писать.

А почему вы решили что архитектура не продумана?

Вы же не знаете специику устройства что я описываю. Это терминал РЗиА и данные обрабатываются именно так: с приходом каждого сэмла делается ДПФ (размер окна ДПФ - 1 период сетевой частоты, т.е. 96 сэмплов).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как пример:

есть задача принимать данные по spi от ацп. Часто дискретизации порядка 4800гц. При этом, с приходом каждого отсчета нужно расчитывать ДПФ. Таким образом, частота прерываний составляет 4800гц. Думаю, подсистема linux не способна обрабатывать прерывания на такой скорости.

 

1) Проблема не в том, что не способна. В среднем на хорошем процессоре скорее всего способна. Например, лет 12 назад я на 6201 @200Mhz успевал вводить данные от E1 с частотой прерываний 8*8000 Гц, правда, в standalone приложении. Но это все равно делало свое черное дело - большие накладные расходы на дергание прерываний Вы никуда не спрячете.

 

2) Вопрос упирается в то, когда нужно выкатить результат по очередному ДПФ: до следующей выборки АЦП или не обязательно. Словом, можно ли ваше требование обработки прерываний на такой скорости свести к требованию отсутствия потери и искажения вводимых данных? Если можно, то есть других, скрытых эффектов в обработке прерывания нет, то задачка решается с помощью буферизации средствами (E)DMA. И позволяет убить двух зайцев: а) в десятки раз ослабить требование к скорости реакции и б) убрать этот совершенно ненужный оверхед по обработке прерываний.

 

Так вот, вариант с (E)DMA сближает реализации standalone и linux. от проблемы со скоростью реакции на прерывание мы переходим к проблеме средней загрузки системы, которая в первую очередь обусловлена только производительностью процессора в вычислениях. Иными словами, Вы можете произвести замер скорости ДПФ в standalone приложении и в linux, и уже на основе объективных данных принять решение, сколько ресурсов на это потребуется, и есть ли столько в каждом конкретном DSP.

 

В качестве примера могу привести продолжение той темы с C6201. На C6201 делалась восьмиканальная система для IP-телефонии, но в следующем проекте задача была сделать одноканальную, на C5403. C54 - вообще семейство скорее для экономии питания, чем для мощных вычислений. И тем не менее, там также удалось задачу ввода-вывода по SPI решить с помощью DMA полностью. То есть, автомат DMA запускался при старте приложения и циклически вводил данные в массив на 4096 отсчетов, вообще не выдавая никаких прерываний. А приложение периодически просто опрашивало регистр записи DMA и делало выводы о размере введенных данных, подвигая свой маркер чтения по мере обработки. Главное - такая система гарантировала ввод данных без потерь и искажений. Величина буфера выбиралась с учетом возможных задержек в разных ветках обработки.

 

И вот ровно то же самое можно воплотить и в Linux. Естественно, на это придется положить часть ресурсов, но зато взамен открываются новые возможности: портирование стандартных приложений, сеть TCP/IP, файловая система и т.п. Ну и модульное проектирование приложений, а не тупо монолитная прошивка, цикл разработки и отладки которой драматически удлиняется по мере наращивания функциональности.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему вы решили что архитектура не продумана?

Вы же не знаете специику устройства что я описываю. Это терминал РЗиА и данные обрабатываются именно так: с приходом каждого сэмла делается ДПФ (размер окна ДПФ - 1 период сетевой частоты, т.е. 96 сэмплов).

Важно не сколько ДПФ делается на сэмлп, а какая нужна минимальная задержка между входным аргументом (сэмплом) и выходным результатом (ДПФ или что там у вас).

Время реакции вобщем.

Ну если РЗА, то наверное может быть и 1 сэмпл...

 

Только в устройство РЗА ставить линух.... :wacko:

Вы уверены в том что делаете???

Защитные устройства должны быть тупыми и дубовыми насколько возможно. Чтобы обеспечить надёжность. Так что всё-таки - думаю архитектура именно не продумана....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Важно не сколько ДПФ делается на сэмлп, а какая нужна минимальная задержка между входным аргументом (сэмплом) и выходным результатом (ДПФ или что там у вас).

Время реакции вобщем.

Ну если РЗА, то наверное может быть и 1 сэмпл...

 

Только в устройство РЗА ставить линух.... :wacko:

Вы уверены в том что делаете???

Защитные устройства должны быть тупыми и дубовыми насколько возможно. Чтобы обеспечить надёжность. Так что всё-таки - думаю архитектура именно не продумана....

Тупыми и дубовыми? Нуну... поддержка 61850 как нельзя лучше отражает дубовость современных устройств. :)) сейчас архитектура "дубовых" устройств выглядит так: dsp/fpga(bare metall) + host(от arm и влоть до x86 c операционной системой на борту). Хотя знаю решение где все(математическая обработка и интерфейсная часть) сделано на sam9260+ecos.

Вот и думаю, можно ли взять мощный современный процессор с linux и сделть все на нем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот и думаю, можно ли взять мощный современный процессор с linux и сделть все на нем.

 

Думаю, что можно. Во всяком случае у нас это получилось. Но, вероятно, потребуется делать свои драйверы для периферии, которые наиболее точно соответствуют вашей задаче. Рассчитывать на готовую поддержку можно, но ценой потери части производительности.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...