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

 
 
 
Reply to this topicStart new topic
> Управление периферией HPS из под OS
R6L-025
сообщение Aug 29 2016, 06:01
Сообщение #1


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

Группа: Свой
Сообщений: 76
Регистрация: 8-04-11
Из: Ростов-на-Дону
Пользователь №: 64 227



Доброго времени суток!
Недавно начал ковырять альтеровский SoC, в связи с чем возник довольно глупый вопрос - как правильно работать с периферией HPS из под OS (linux)?
Например пробовал поднять контроллер SPI. Пробовал из под userspace вручную управлять его регистрами - ничего хорошего не получилось.
Правильно ли я понимаю что самый корректный способ в данном случае работа с драйвером? Или есть иные решения?
И поможет ли чем альтеровская HWLIB при работе из под OS? Как я понял она больше рассчитана на работу с baremetal, да и в сорцах альтеровских драйверов я не встречал упоминаний о ней.
Go to the top of the page
 
+Quote Post
Jury093
сообщение Aug 29 2016, 08:53
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050



Цитата(R6L-025 @ Aug 29 2016, 09:01) *
Недавно начал ковырять альтеровский SoC, в связи с чем возник довольно глупый вопрос - как правильно работать с периферией HPS из под OS (linux)?
Например пробовал поднять контроллер SPI. Пробовал из под userspace вручную управлять его регистрами - ничего хорошего не получилось.

а вы работу узла SPI в прелоадере разрешили?
если разрешили, то через обычный mmap все должно работать, т.к. через драйвер линукса работает, но с заморочным CS
Go to the top of the page
 
+Quote Post
R6L-025
сообщение Aug 29 2016, 11:26
Сообщение #3


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

Группа: Свой
Сообщений: 76
Регистрация: 8-04-11
Из: Ростов-на-Дону
Пользователь №: 64 227



to Jury093
Извиняюсь, немного недопонял, что Вы подразумеваете под "разрешением работы узла в прелоадере"? Я пытался адаптировать example для SPI отсюда:
https://www.altera.com/support/support-reso...amples/soc.html
Но этот пример ориентирован под baremetall. В нем используется последовательность функций из HWLIB для инициализации контроллера SPI, контрллера прерываний и пр., но под OS это по идее и не нужно. (я скопипастил оттуда ту часть которая отвечает только за работу SPI, выдрал часть кода из HWLIB, подправил так, чтоб работало с виртуальными а не физическими адресами, но в итоге получил частоту SCLK вместо 2 МГц около 100, и почему то принятые данные всегда были в нулях rolleyes.gif ).
Собственно сам вопрос больше не о том как конкретно с SPI работать, а как вообще считается корректно работать с подобной периферией.
Go to the top of the page
 
+Quote Post
Jury093
сообщение Aug 29 2016, 13:02
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050



Цитата(R6L-025 @ Aug 29 2016, 14:26) *
Извиняюсь, немного недопонял, что Вы подразумеваете под "разрешением работы узла в прелоадере"? Я пытался адаптировать example для SPI отсюда:

видимо я неудачно выразился.. под прелоадером имеется в виду u-boot, который состоит из двух этапов - прелоадер и собственно u-boot
а начальная конфигурация узлов в т.ч. и SPI производится из оболочки Qsys из-под Quartus
т.о. Qsys формирует хидеры с настройками, на основе которых u-boot настраивает периферию HPS

Цитата
Собственно сам вопрос больше не о том как конкретно с SPI работать, а как вообще считается корректно работать с подобной периферией.

в линуксе? желательно по законам линукса, конечно.. со спецификой embedded
если совсем прямой путь - в Qsys включили SPI, в ядре разрешили SPI и свой чип, в dts прописали SPI и свой чип, далее после перезагрузки, если все корректно и правильно, то получили канал или устройство в /dev, далее софт для пользователя..
если хочется экстрима/нестандарта, то на любом этапе после u-boot перехватываете и самостоятельно пишете всё, что касается обмена с SPI ну и сервис в сторону пользователя..
Go to the top of the page
 
+Quote Post
R6L-025
сообщение Aug 30 2016, 06:08
Сообщение #5


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

Группа: Свой
Сообщений: 76
Регистрация: 8-04-11
Из: Ростов-на-Дону
Пользователь №: 64 227



Да, в Qsys все описано, в ядре поддержка SPI включена, он даже видится в /dev. Если с драйвером работать то осталось только разобраться как им рулить. Было интересно как вообще управление железом делается. По видимому да, самое логичное наитивными для OS путями - через драйвер)
Go to the top of the page
 
+Quote Post
Jury093
сообщение Aug 30 2016, 06:53
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050



Цитата(R6L-025 @ Aug 30 2016, 09:08) *
Да, в Qsys все описано, в ядре поддержка SPI включена, он даже видится в /dev. Если с драйвером работать то осталось только разобраться как им рулить.

SPI не может "видится" в /dev, обычно он представлен устройством на канале или /dev/spidevX.X
смотрите в исходниках драйвера - чем он занимается и что создает в системе

Цитата
Было интересно как вообще управление железом делается. По видимому да, самое логичное наитивными для OS путями - через драйвер)

поищите в разделе OS->linux треды, там где-то выкладывались названия литературы - устройство линукса, линукс для чайников, линукс и драйверы..
возможно на местном фтп они есть или в сети

напрямую к железу HPS можно обратиться примерно так (прописав адреса HPS и имея права на доступ)
Код
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)
{
printf("Cannot open /dev/mem.\n");
exit(EXIT_FAILURE);
}
printf("/dev/mem opened.\n");
mapped_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_BASE & ~MAP_MASK);
if (mapped_base == (void *) -1)
{
printf("Memory mapping error.\n");
exit(EXIT_FAILURE);
}
mapped_base+=(MAP_BASE & MAP_MASK);
printf("Target address mapped 0x%08x-->0x%08x\n",(int) MAP_BASE,(int)mapped_base);
// -----------------------------------------------------------------------
printf("GPIOH_DIR=%08X\n", GPIOH_DIR);

но это чисто почитать/пописать в регистры, задействовать, например, прерывания или DMA уже не получится - такие вещи делают через драйвер..
Go to the top of the page
 
+Quote Post
R6L-025
сообщение Aug 30 2016, 09:03
Сообщение #7


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

Группа: Свой
Сообщений: 76
Регистрация: 8-04-11
Из: Ростов-на-Дону
Пользователь №: 64 227



Цитата
SPI не может "видится" в /dev, обычно он представлен устройством на канале или /dev/spidevX.X

Я и подразумевал, что он представлен как устройство в /dev каталоге.
В целом понятно, спасибо! sm.gif
Go to the top of the page
 
+Quote Post
goodsoul
сообщение Aug 30 2016, 09:04
Сообщение #8


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

Группа: Участник
Сообщений: 136
Регистрация: 3-09-09
Пользователь №: 52 178



https://rocketboards.org/foswiki/view/Documentation/WebHome
https://rocketboards.org/foswiki/view/Docum...rAlteraSoCLinux
https://rocketboards.org/foswiki/pub/Docume..._Altera_SoC.pdf
Go to the top of the page
 
+Quote Post
R6L-025
сообщение Aug 30 2016, 09:41
Сообщение #9


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

Группа: Свой
Сообщений: 76
Регистрация: 8-04-11
Из: Ростов-на-Дону
Пользователь №: 64 227



Да, спасибо, сейчас в этом и копаюсь. Собственно, чтение/запись через отображение на память получилось, хочу попробовать простые модули пособирать
Go to the top of the page
 
+Quote Post
R6L-025
сообщение Oct 28 2016, 14:11
Сообщение #10


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

Группа: Свой
Сообщений: 76
Регистрация: 8-04-11
Из: Ростов-на-Дону
Пользователь №: 64 227



Возвращаясь к этой теме - заметил не понятную для меня особенность.
Использую DE-0 SoC Nano. Конфигурирую ядро наподобие описания здесь https://rocketboards.org/foswiki/view/Docum...xBeginnerSGuide , с версией ядра 4.1 (как там и указано).
В этом случае у меня работает FPGA manager, но не работает Ethernet, если использовать ядро 4.4 - то все наоборот. При этом SPI не запускается вообще. Если использовать скомпиленный example от Terasic все работает хорошо.
Пытался сравнивать содержание файла .config версий ядра 4.1 и 4.4 - особых отличий не нашел.
Кто нибудь сталкивался с подобным поведением? Можете скинуть рабочий .config с произвольной версией?


P.S. при конфигурации сети использовал дефолтные настройки
Go to the top of the page
 
+Quote Post
bugdesigner
сообщение Oct 31 2016, 07:11
Сообщение #11


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

Группа: Участник
Сообщений: 123
Регистрация: 12-06-15
Из: Земля
Пользователь №: 87 133



Цитата(R6L-025 @ Oct 28 2016, 16:11) *
Кто нибудь сталкивался с подобным поведением? Можете скинуть рабочий .config с произвольной версией?

Я использую ядро 4.1.22-ltsi+ отсюда: https://github.com/altera-opensource/linux-socfpga.git
Прикрепленный файл  config.txt ( 71.3 килобайт ) Кол-во скачиваний: 56

Собирал все (ядро и модуль) кросс-компилятором arm-none-eabi-gcc версии 4.8.4 на Debian 8.1.
По поводу fpga manager не могу ничего сказать, я его не использую, тк мой проект использует DMA через fpga2sdram и поэтому битстрим загружается бутлоадером u-boot.
С ethernet проблем не обнаружено.
Что касается SPI. Я "завернул" сигналы SPI0 master в FPGA, чтоб потом вывести их на разъем DE0-Nanao. Такой метод дополнительно позволяет получить контроль над 4 выводами SS.
Я не использовал драйверов SPI из ядра, а написал свой модуль - так мне удобней. Сейчас у меня через SPI управляется 3 устройства - 2 DAC и DDS. DAC получает 16-битные команды, а DDS 32-битные.
Вот пример кода для 32 бит
CODE

static void __iomem *SPI0;
// ---8<---- from module init
request_mem_region(SPIM0_ADDR, SPIM0_LEN, DRV_NAME);
SPI0 = ioremap(SPIM0_ADDR, SPIM0_LEN);
// ---8<----

// initialize SPI0
iowrite32(0, SPI0+SPIM_SPIENR_OFF); // Disable SPI0
iowrite32(0x1CF, SPI0+SPIM_CTRLR0_OFF); // TxOnly, scpol=1 scph=1 length=16 bit
iowrite32(0, SPI0+SPIM_CTRLR1_OFF);
iowrite32(0, SPI0+SPIM_SER_OFF); // Disable All SS
iowrite32(100, SPI0+SPIM_BAUDR_OFF); // set baudrate
iowrite32(1, SPI0+SPIM_SPIENR_OFF); // Enable SPI0
// sending data
iowrite16((value >> 16) & 0xFFFF, SPI0+SPIM_DR_OFF);
iowrite16(value & 0xFFFF, SPI0+SPIM_DR_OFF);

iowrite32(2, SPI0+SPIM_SER_OFF); // Enable SS1
udelay(5);
while(ioread32(SPI0+SPIM_SR_OFF) & 1); //wait for busy==0
iowrite32(0, SPI0+SPIM_SER_OFF); // Disable All SS


Используемые константы.
CODE
// SPIMx registers
#define SPIM0_ADDR 0xFFF00000
#define SPIM0_LEN 0x1000
#define SPIM1_ADDR 0xFFF01000
#define SPIM1_LEN 0x1000
//
#define SPIM_CTRLR0_OFF 0x00
#define SPIM_CTRLR1_OFF 0x04
#define SPIM_SPIENR_OFF 0x08
#define SPIM_MWCR_OFF 0x0C
#define SPIM_SER_OFF 0x10
#define SPIM_BAUDR_OFF 0x14
#define SPIM_TXFTLR_OFF 0x18
#define SPIM_RXFTLR_OFF 0x1C
#define SPIM_TXFLR_OFF 0x20
#define SPIM_RXFLR_OFF 0x24
#define SPIM_SR_OFF 0x28
#define SPIM_IMR_OFF 0x2C
#define SPIM_ISR_OFF 0x30
#define SPIM_RISR_OFF 0x34
#define SPIM_TXOICR_OFF 0x38
#define SPIM_RXOICR_OFF 0x3C
#define SPIM_RXUICR_OFF 0x40
#define SPIM_ICR_OFF 0x48
#define SPIM_DMACR_OFF 0x4C
#define SPIM_DMATDLR_OFF 0x50
#define SPIM_DMARDLR_OFF 0x54
#define SPIM_DR_OFF 0x60

Подробно о регистрах и режимах написано в документе Cyclone V HPS TRM.
Если есть какие-либр вопросы - пишите.

Важный момент: при любом изменении в настройках HPS (которые вы делаете в Qsys) нужно пересобирать preloader! Те запускать bsp-editor, потом make. Иначе перефирия может работать некорректно или совсем не работать.
Go to the top of the page
 
+Quote Post
R6L-025
сообщение Nov 1 2016, 07:55
Сообщение #12


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

Группа: Свой
Сообщений: 76
Регистрация: 8-04-11
Из: Ростов-на-Дону
Пользователь №: 64 227



bugdesigner, спасибо! Попробую собрать с Вашей конфигурацией. У меня, собственно, тоже используется u-boot для заливание битстрима, хотя хотелось бы прикрутить к проекту возможность перепрошивки из под OS.
Отдельное спасибо за код модуля. Попробую реализовать, если с встроенным не выйдет. Если честно, пока в kernel space ничего не писал, поэтому хотелось встроенный поднять.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 14:26
Рейтинг@Mail.ru


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