

alxkon
Участник-
Posts
140 -
Joined
-
Last visited
Reputation
0 ОбычныйAbout alxkon
-
Rank
Частый гость
Recent Profile Visitors
3,332 profile views
-
PCIe - начало...
alxkon replied to dde29's topic in Работаем с ПЛИС, области применения, выбор
Отвечу сам себе - глюки связаны с кривизной в rtl дизайне, не с особенностью линукса -
PCIe - начало...
alxkon replied to dde29's topic in Работаем с ПЛИС, области применения, выбор
Подскажите пожалуйста по следующей проблеме: Использую XDMA на Kintex девките. Девкит в свою очередь подключен к Jetson TX2 девкиту. Создал простой AXI4 Lite Slave на 4 регистра. Slave прошел через SV AXI4 BFM тест, использвал готовый который генерит Vivado. Подключен он к 32бит BAR 0, выделен 1МБ. Работаю с Ubuntu, использовал софт по моему автора туториала по XDMA . Получается запись и чтение регистров ведется из user space, а не из ядра линукса. Могут ли быть какие то проблемы с этим? Получается только 1 раз записать и считать определенное значение, далее чтение показывает 0. sudo ./pcie_test /sys/bus/pci/devices/0000\:01\:00.0/resource0 0x00000000 w 0xDEADAB Пока разбираюсь с System ILA, посмотреть что реально просходит на шине. Железо на несколько дней недоступно, хотелось бы понять есть ли риск в том что чтение/запись в регистры из user space на самом деле не работает всегда корректно? #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <signal.h> #include <fcntl.h> #include <ctype.h> #include <termios.h> #include <sys/types.h> #include <sys/mman.h> #include <linux/pci.h> #define PRINT_ERROR \ do { \ fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \ __LINE__, __FILE__, errno, strerror(errno)); exit(1); \ } while(0) #define MAP_SIZE 4096UL #define MAP_MASK (MAP_SIZE - 1) int main(int argc, char **argv) { int fd; void *map_base, *virt_addr; uint32_t read_result, writeval; char *filename; off_t target; int access_type = 'w'; if(argc < 3) { // pcimem /sys/bus/pci/devices/0001\:00\:07.0/resource0 0x100 w 0x00 // argv[0] [1] [2] [3] [4] fprintf(stderr, "\nUsage:\t%s { sys file } { offset } [ type [ data ] ]\n" "\tsys file: sysfs file for the pci resource to act on\n" "\toffset : offset into pci memory region to act upon\n" "\ttype : access operation type : [b]yte, [h]alfword, [w]ord\n" "\tdata : data to be written\n\n", argv[0]); exit(1); } filename = argv[1]; target = strtoul(argv[2], 0, 0); if(argc > 3) access_type = tolower(argv[3][0]); if((fd = open(filename, O_RDWR | O_SYNC)) == -1){ PRINT_ERROR; } printf("%s opened.\n", filename); printf("Target offset is 0x%x, page size is %ld map mask is 0x%lX\n", (int) target, sysconf(_SC_PAGE_SIZE), MAP_MASK); fflush(stdout); /* Map one page */ #if 0 //map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t) (target & ~MAP_MASK)); //map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK); #endif printf("mmap(%d, %ld, 0x%x, 0x%x, %d, 0x%x)\n", 0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (int) (target & ~MAP_MASK)); map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (target & ~MAP_MASK)); if(map_base == (void *) -1){ printf("PCI Memory mapped ERROR.\n"); PRINT_ERROR; close(fd); return 1; } printf("mmap(%d, %ld, 0x%x, 0x%x, %d, 0x%x)\n", 0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (int) (target & ~MAP_MASK)); printf("PCI Memory mapped %ld byte region to map_base 0x%08lx.\n", MAP_SIZE, (unsigned long) map_base); fflush(stdout); virt_addr = map_base + (target & MAP_MASK); printf("PCI Memory mapped access 0x %08X.\n", (uint32_t ) virt_addr); switch(access_type) { case 'b': read_result = *((uint8_t *) virt_addr); break; case 'h': read_result = *((uint16_t *) virt_addr); break; case 'w': read_result = *((uint32_t *) virt_addr); printf("READ Value at offset 0x%X (%p): 0x%X\n", (int) target, virt_addr, read_result); break; default: fprintf(stderr, "Illegal data type '%c'.\n", access_type); exit(2); } fflush(stdout); if(argc > 4) { writeval = strtoul(argv[4], 0, 0); switch(access_type) { case 'b': *((uint8_t *) virt_addr) = writeval; read_result = *((uint8_t *) virt_addr); break; case 'h': *((uint16_t *) virt_addr) = writeval; read_result = *((uint16_t *) virt_addr); break; case 'w': *((uint32_t *) virt_addr) = writeval; read_result = *((uint32_t *) virt_addr); break; } printf("Written 0x%X; readback 0x%X\n", writeval, read_result); fflush(stdout); } if(munmap(map_base, MAP_SIZE) == -1) { PRINT_ERROR;} close(fd); return 0; } -
Efinix Trion FPGA кто нибудь слышал?
alxkon replied to yes's topic in Работаем с ПЛИС, области применения, выбор
Спасибо! Пока в планах IMX. Были замыслы использовать и других производителей, но пока не решили, якобы проблемы с доставаемостью. Если получится, я напишу в эту ветку. -
Efinix Trion FPGA кто нибудь слышал?
alxkon replied to yes's topic in Работаем с ПЛИС, области применения, выбор
Были ли у Вас проблемы с ядром MIPI или все заводится "из коробки"? И еще вопрос возможно ли их софт использовать на 2 компьютерах или там жёсткая привязка? -
передать SLVS-EC на 1м
alxkon replied to Maverick_'s topic in Цифровые схемы, высокоскоростные ЦС
На mouser.com есть FRAMOS, но там только CSI-2 киты и камеры. SLVS-EC пока нет или скорее всего не будет в принципе, так как Framos естественно хочет продать свое IP. Их SLVS-EC решения нужно покупать напрямую -
передать SLVS-EC на 1м
alxkon replied to Maverick_'s topic in Цифровые схемы, высокоскоростные ЦС
Кстати, а где можно купить дев. кит с камерой SLVS-EC ? -
Спасибо за подсказки, изучаю LVDT и емкостные датчики.
-
Или нормальный энкодер и неколхозно-китайский двигатель с другим типом механики типа зубчатой планки или небольшой шаговый двигатель с резьбовым валом. Тогда можно бы выбросить это колесо и пружину. История банальна - один ардуинщик спелся (или спился) с механиком вместе родили устройство - устаревший 5 вольтовый процессор которого теперь днем с огнём, level-shifters к остальной 3.3в логике, китайский двигатель сомнительного исполнения. Зато дёшево. Изваял плату и программу прямо в Arduino IDE, так он и в .ino и осталось. Попробовали работает но не так как хотелось - добавили пружину. Улучшилось. Еще один умный человек на радости заказал тучу механических частей и гору моторчиков. А по факту как минимум 20% процентов этих мотров мусор - энкодеры не работают, на шестернях заусеницы, и пр. Но дёшево. Управление на новой плате нужно уложить в ПЛИС, она там всёравно будет. Можно будет использовать часть этого добра и параллельно подобрать энкодер и двигатель и запилить новую механику.
-
Да, спасибо! Не подумал о влиянии максимального разгона и торможения на ресурс. Наверное тогда лучше не доводить до крайностей и дыма, а экспериментально выбрать приемлимую максимальную скорость на длинных участках.
-
К сожалению не могу конкретизировать все детали в силу определенных обстоятельств. После Вашего комментария о температурном коэфициенте, стало ясно что требование точности в 2микрона скажем весьма оптимистическое. Пока не добился даных на пружину и даных о дуге/спирали Архимеда по которой двигается подшипник заставляющий шток подниматся или опускаться. Переформулирую ТЗ - плавно двигать шток с постоянной скоростью, как можно точней позиционировать, при большом заданом перемещении двигатся быстро. Шток весит около 250г, движется в цилиндре вертикально, весь путь - 3см. Пружина давит на шток для того что бы подшипник плотно касался поверности дуги по которой движется. Т.е. без установленного двигателя с редуктором, шток всегда внизу. С редуктором он стоит на месте, если двигатель выключен. Таким образом пружина помогает движению вниз и наоборот создает необходимость дополнительных усилий при подьеме штока вверх. На двигателе квадратурный энкодер, 2 датчика Холла, 7 магнитов, Pulses-Per-Rotation 7. Буду вникать понемногу как этим всем рулить.
-
Вы как всегда правы - в конструкции присутствует и сталь, и алюминий, и латунь так что все будет еще и по разному изменятся при небольших изменениях температуры. Тогда наверное более реалистичное требование "сколько получится на даных компонентах". Для начала нужно построить хотя бы простой стенд для измерений перемещения. И потом помучить X а лучше N комплектов для разной степени выработки механики. Тогда можно понять реалии. Ну и изучить попутно много чего нового. Какую схему управления Вы бы посоветовали применить?
-
Желаемая точность позиционирования 2 микрона. Я правда пока весьма туманно представляю как ее вывести, что и как влияет на точность, нужно вникнуть. В любом случае нужно смастерить стенд с индикатором измерителем как у фрезеровщиков, есть наверное до 1микрона.
-
Приветствую всех! Имеется такой двигатель, 6в редуктор 1/1000: https://www.donghui-motor.net/en/product/dgr24-n20-reverse-metal-gear-motor.html с экодером как на картинке, 2 датчика Холла размещенных под 90гр, 7 магнитов в диске. Вал редуктора вращает небольшой диск в котором вырезан паз по спирали (как на рисунке, дуга внизу ). По этой дуге катается подшипник который крепится к вертикальному штоку. Вращая диск в определенном направлении можно двигать шток в цилиндре вверх или вниз. Люфта между штоком и цилиндром нет. Шток подпружинен для того что бы при движении вниз подшипник был в сцепке с диском. Имеются концевики для верхней и нижней мертвых точкек. Макс. перемещение около 3см. Драйвер используется STSPIN240, управляется ШИМ с ATMega328P. Положение задается количеством оборотов посчитаных энкодером. Код работает не всегда устойчиво, доехав до точки назначения шток дергается между положениями +1 -1 оборот, Назначение сей поделки максимально быстро и точно позиционировать шток, насколько это возможно с такой механикой. Творец кода недоступен. Проблемы с компонентами, древний процессор и ардуинщина заставляют все переходить на другую базу и улучшить управление. Хотелось бы услышать мнение опытных людей: Чего следует ожидать от энкодеров, они не установлены жестко, припаяны наверняка с большим разбросом? Механика наверное не самая хорошая - нет жесткой связи с валом редуктора, точность исполнения двигателя, редуктора, полировки дуги в диске и пружина будут давать большой разброс по точности? В текущей системе 0 задается каким то верхним уровнем програмы, какой-то калибровкой и он где-то ближе центра общего перемещения. Возможно будет более правильно взять верхнюю точку за 0 отсчёта или я не прав? При небольшом перемещении нужно перемещатся медленно, при большом - начать медленно (из-за редуктора) , ускориться и замедлить движение ближе к точке назначения. Какой регулятор лучше применить что бы нивелировать разброс в точности механики и ее выработки в процессе использования?
-
Для варианта 3 есть готовые ядра, наверное не дешевые https://soc-e.com/products/mes-managed-ethernet-switch-ip-core/ https://www.latticesemi.com/products/designsoftwareandip/intellectualproperty/ipcore/flexibiliscores/flexibilisethernetswitch ну или делать самим. Только доставаемость FPGA в наше судьбоносное время это тоже приключение
-
https://www.efinixinc.com/products-titanium.html Я сам пока даже их Trion не попробовал, кит нужно заказать, но в соседней теме говорят Trion кое-как работает.