LINUX.ORG.RU

Помогите «смонтировать» два физических блока памяти в один виртуальный:-)


0

0

Граблю кадры с v4l2 камеры mmapом. Микрозадача: нужно прикрутить в конец аппаратного буфера камеры свой маленький буфер, в который нужно сохранять свою инфу, ну или прикрутить свой буфер перед аппаратным. Т.е. чтобы в виртуальном пространстве получилось |мой буфер|аппаратный буфер| или |аппаратный буфер|мой буфер|, чтобы я смог этот составной буфер писать через write(fd, buf, size) за один вызов ну и вообще оперировать только одним указателем. Копировать аппаратный буфер в другой нельзя - софтинка крутиться на ARMе, там это очень замедляет работу, pwrite тоже нельзя использовать - т.к. кадр дальше передается другой библиотеке (libavformat), которая имеет только интерфейс write. Как пробовал - после mmapа аппаратного буфера создавал разделяемую память и ммапил ее в конец буфера кадра (тут код без проверок после вызовов):

v4l2_buffer buf;
...
ioctl(fd_cam, VIDIOC_QUERYBUF, &buf);
data = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd_cam, 0);
m_pFrameList[index].m_desc = shm_open("desc", O_RDWR | O_CREAT, 0777));
p_void field = mmap(p_void(ptrdiff_t(data) + buf.length), sizeof(float64), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, m_pFrameList[index].m_desc, 0);
Log::echo("Mapping result: must be: %p, actually: %p\n", ptrdiff_t(data) + buf.length, field);


Вроде все клево, но когда я запрашиваю кадр:
ioctl(fd_cam, VIDIOC_DQBUF, ...) приложение валится с ошибкой "Ошибка шины". в чем собака может быть зарыта?


Обычно все буферы мапятся в память одним куском, буфер за буфером. Если девайс льёт данные в память по DMA, то ты ему вторым ммапом испортил настройки DMA-контроллера.

Выделяй память сам, в VIDIOC_REQBUFS передавай V4L2_MEMORY_USERPTR, а не V4L2_MEMORY_MMAP. Имей в виду, что для DMA нужен адрес, выровненный на страницу, поэтому просто от malloc() адрес без предварительного выравнивания подсунуть не получится.

mv ★★★★★
()
Ответ на: комментарий от mv

> вторым ммапом испортил настройки DMA-контроллера.

Хотя, на вряд ли, в физической памяти буфер всё равно одним куском идёт.

mv ★★★★★
()
Ответ на: комментарий от sotlef

> Использовать USERPTR не получится, ибо не поддерживается драйвером...(

1. Модифицировать драйвер для поддержки userptr, отослать в апстрим.
2. Модифицировать драйвер, чтобы куски физического буфера добавлял в vma процесса не друг за другом, а с разрывом в одну страницу (куда ты потом сможешь с MAP_FIXED заммапить нужную тебе страничку).

Второе проще.

mv ★★★★★
()
Ответ на: комментарий от mv

3. Делать reqbufs по одному, потом ммапить за ним свою страничку, loop.

mv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.