Volkov 0 25 мая, 2020 Опубликовано 25 мая, 2020 · Жалоба Пытаюсь понять причину, и уже долго с эти сам подвис. Задача - передавать с PL в PS по DMA 262656 байт, с периодичностью 6.4 мс, и записывать их на SSD. Но передача, временами останавливается на время большее чем 10 мс. Я использую драйвер dma-proxy, прерывания через AXI GPIO. В прикладном приложении, я ожидаю прерывания, завершения передачи по ДМА, и записываю буфер в файл. while (file_number < max_files) { rx_proxy_interface_p->length = test_size; u_int32_t info = 1; /* unmask */ ssize_t nb = write(fd, &info, sizeof(info)); if (nb < sizeof(info)) { perror("write"); close(fd); exit(EXIT_FAILURE); } t0 = clock(); int ret = poll(&fds, 1, -1); if (ret >= 1) { nb = read(fd, &info, sizeof(info)); if (nb == sizeof(info)) { *((volatile unsigned *)(gpio_ptr + GPIO_IP_ISR)) = 0x1; ioctl(rx_proxy_fd, 0, &dummy); if (rx_proxy_interface_p->status != PROXY_NO_ERROR) printf("Proxy rx transfer error %d\n",row_counter); fwrite(rx_proxy_interface_p->buffer, 1, row_length, fp); t1 = clock(); } } else { printf("ret is not >= 1\n"); perror("poll()"); close(fd); exit(EXIT_FAILURE); } time_in_seconds = (double)(t1 - t0) / CLOCKS_PER_SEC; printf("max_time : %12.9f row : %d \n", time_in_seconds,row_counter); } И как бы оно все работает, время выполнения, которое я меряю не больше 2.5 мс. Но это не так. В плисе я вижу что время передачи по ДМА больше 8 мс. Изначально я писал в два буфера - один писал другой записывал в отдельном потоке. Но там, так же были большие задержки, да и memcpy - отбирало 2 мс, а когда запускался второй поток, то это время удваивалось. Поэтому я и решил писать по 200 КБ сразу в файл. Но и тут беда - непонятно почему ДМА простаивает. dma-p-test.c Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Volkov 0 25 мая, 2020 Опубликовано 25 мая, 2020 · Жалоба Эх, нужно было раньше попробовать без записи запустить В общем это не дма - это запись на диск, в какой то момент больше 10 мс. Тогда - один вариант писать большим буфером. То есть, один наполняется - memcpy(args0.data_buf0[row_counter], rx_proxy_interface_p->buffer, row_length*sizeof(unsigned char)); другой в этот момент, в созданном потоке пишется pthread_create(&tid, NULL, file_save_thread, (void*) &args0); Но как я понимаю - скоростей, используя memcopy не достичь. Но как по другому - я не нашел нормального примера. Да и те, что у ксалинкса - вот пишут они что нужно добавить дерево устройств &sata { dma-coherent; } Но после этого у меня SATA диск не распознается. xilinx-psgtr fd400000.zynqmp_phy: Lane:0 type:2 protocol:2 pll_locked:yes [ 2.624206] ahci-ceva fd0c0000.ahci: AHCI 0001.0301 32 slots 2 ports 6 Gbps 0x3 impl platform mode [ 2.633162] ahci-ceva fd0c0000.ahci: flags: 64bit ncq sntf pm clo only pmp fbs pio slum part ccc sds apst [ 2.643471] scsi host0: ahci-ceva [ 2.647084] zynqmp_pll_disable() clock disable failed for dpll_int, ret = -13 [ 2.654258] scsi host1: ahci-ceva [ 2.657710] ata1: SATA max UDMA/133 mmio [mem 0xfd0c0000-0xfd0c1fff] port 0x100 irq 37 [ 2.665622] ata2: SATA max UDMA/133 mmio [mem 0xfd0c0000-0xfd0c1fff] port 0x180 irq 37 2.983884] ata2: SATA link down (SStatus 0 SControl 330) 12.673522] ata1: softreset failed (1st FIS failed) [ 13.138302] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 330) [ 18.514306] ata1.00: qc timeout (cmd 0xec) [ 18.518401] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4) [ 18.986302] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 330) [ 29.266301] ata1.00: qc timeout (cmd 0xec) [ 29.270394] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4) [ 29.276486] ata1: limiting SATA link speed to 3.0 Gbps [ 29.746302] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 320) [ 59.986302] ata1.00: qc timeout (cmd 0xec) [ 59.990399] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4) [ 69.996715] ata1: softreset failed (1st FIS failed) [ 80.001475] ata1: softreset failed (1st FIS failed) [ 115.006649] ata1: softreset failed (1st FIS failed) [ 115.011520] ata1: limiting SATA link speed to 1.5 Gbps [ 120.016630] ata1: softreset failed (1st FIS failed) [ 120.021503] ata1: reset failed, giving up И вроде бы все делаешь по AR#71584, как бы должно было работать. И ДМА, так же, где то у них в вики, может использовать когерентную память, но если добавить dma_proxy { dma-coherent; compatible ="xlnx,dma_proxy"; dmas = <&axi_dma_0 0 &axi_dma_0 1>; dma-names = "dma_proxy_tx", "dma_proxy_rx"; }; Буфер возвращает какую то кашу, из различных посылок. Видно, что данные содержат данные предидущих посылок, в каком то хаотичном порядке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 2 25 мая, 2020 Опубликовано 25 мая, 2020 · Жалоба А прямой дорогой - DMA client driver с маппингом DMA-буфера в userspace - пойти не судьба? И вопрос: CMA блок какого размера выделяете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Volkov 0 25 мая, 2020 Опубликовано 25 мая, 2020 · Жалоба 7 minutes ago, gosha-z said: А прямой дорогой - DMA client driver с маппингом DMA-буфера в userspace - пойти не судьба? И вопрос: CMA блок какого размера выделяете? 256 МБ, по умолчанию в настройках ядра стоит. Я увеличивал до 512, но это ничего не меняло. А есть простой пример, как по этой дороге пройти? Я не подниму это все, кажется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 2 25 мая, 2020 Опубликовано 25 мая, 2020 · Жалоба 1 hour ago, Volkov said: А есть простой пример, как по этой дороге пройти? Есть Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Volkov 0 25 мая, 2020 Опубликовано 25 мая, 2020 · Жалоба 11 minutes ago, gosha-z said: Есть Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aleksei_Rostov 0 29 мая, 2020 Опубликовано 29 мая, 2020 · Жалоба On 5/25/2020 at 2:42 PM, Volkov said: 256 МБ, по умолчанию в настройках ядра стоит. Я увеличивал до 512, но это ничего не меняло. А есть простой пример, как по этой дороге пройти? Я не подниму это все, кажется. Можно свой модуль DMA написать. Модуль через регистры работает с DMA и выделяет буфер. Только Xilinx драйвер в настройках ядра необходимо отключить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться