Модератор: Модераторы разделов
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 26.04.2010 13:43
Доброго дня!
Имеется следющий код:
Код: Выделить всё
Int8 *virtPtr;
cout << "[" << __FILE__ "] displaySize before mmap " << displaySize << endl;
cout << "[" << __FILE__ "] attrs->numBufs before mmap " << attrs->numBufs << endl;
virtPtr = (Int8 *) mmap (NULL,
displaySize * attrs->numBufs,
PROT_READ | PROT_WRITE,
MAP_SHARED,
hDisplay->fd, 0);
if (MAP_FAILED == virtPtr) {
cout << "Failed mmap on " << attrs->displayDevice
<< " (" << strerror(errno) << ")" << endl;
cout << "MMAP errno ";
switch (errno) {
case EINVAL:
cout << "EINVAL";
break;
}
cout << endl;
return NULL;
}
При запуске
Failed mmap on /dev/fb/3 (Invalid argument) MMAP errno EINVAL
Сперва я решил, что это из за нулевого размера displaySize. После того, как я вручную задал displaySize вывод не изменился.
displaySize == 0
Код: Выделить всё
[display.cpp] displaySize before mmap 0
[display.cpp] attrs->numBufs before mmap 2
Failed mmap on /dev/fb/3 (Invalid argument)
MMAP errno EINVAL
displaySize != 0
Код: Выделить всё
[display.cpp] displaySize before mmap 1228800
[display.cpp] attrs->numBufs before mmap 2
Failed mmap on /dev/fb/3 (Invalid argument)
MMAP errno EINVAL
В чём может быть проблема и как её решить?
Спасибо.
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64
Сообщение
NickLion » 26.04.2010 23:54
В мане сказано:
EINVAL
We don't like addr, length, or offset (e.g., they are too large, or not aligned on a page boundary).
Может попробовать грубо так:
Код: Выделить всё
virtPtr = (Int8 *) mmap (NULL,
( displaySize * attrs->numBufs + 4095) & ~4095,
PROT_READ | PROT_WRITE,
MAP_SHARED,
hDisplay->fd, 0);
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 09:22
Спасибо за вариант, но увы - результат не изменился.
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux
Сообщение
eddy » 27.04.2010 09:42
IMB писал(а): ↑ 26.04.2010 13:43
/dev/fb/3
Вы уверены, что не /dev/fb3 ?
RTFM
-------
KOI8-R - патриотичная кодировка
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 10:08
Вы знаете - без разницы. Да и SDK производителя оперируют файлами именно в /dev/fb.
Что самое неприятное аналогичная конструкция в другой части программы работает, но там идёт работа с /dev/video0.
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux
Сообщение
watashiwa_daredeska » 27.04.2010 10:13
А этот самый /dev/fb-то имеется?
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 10:18
Да
Он нормально открывается и к нему можно обращаться, в частности перед вызовом mmap произодится несколько ioctl и они проходят без ошибок.
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux
Сообщение
watashiwa_daredeska » 27.04.2010 11:12
IMB писал(а): ↑ 26.04.2010 13:43
[display.cpp] displaySize before mmap 0
[display.cpp] attrs->numBufs before mmap 2
(man mmap) писал(а): EINVAL (since Linux 2.6.12) length was 0.
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 11:31
Если Вы обратите внимание, я создал условия при которых length != 0 и это ничего не изменило.
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64
Сообщение
NickLion » 27.04.2010 13:04
А не пробовали играться с флагами? Вроде MAP_NONBLOCK… И адрес не NULL попробовать. А что вообще за устройство /dev/fb/3?
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 13:09
Вместо адреса NULL пробовал подставить 0 - без разницы. С флагами не игрался, так как они подходят.
grep fb -C2 linux-2.6.18_pro500/Documentation/devices.txt
29 char Universal frame buffer
0 = /dev/fb0 First frame buffer
1 = /dev/fb1 Second frame buffer
...
31 = /dev/fb31 32nd frame buffer
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64
Сообщение
NickLion » 27.04.2010 13:17
Стоп. Не получается ли то, что и говорил
eddy ?
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 13:29
Нет, устройство создано корректно, в соответствии с SDK /dev/fb. Вывод из документации я привёл только для объяснения того какую роль выполняет устройство.
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux
Сообщение
eddy » 27.04.2010 13:56
IMB писал(а): ↑ 27.04.2010 13:29
устройство создано корректно
А вы все-таки попробуйте вместо /dev/fb/3 написать /dev/fb3 - вдруг поможет. Да, а какие права доступа к этому файлу?
RTFM
-------
KOI8-R - патриотичная кодировка
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 14:08
# ls -l /dev/fb*
crw-r--r-- 1 root root 29, 3 Apr 27 2010 /dev/fb3
/dev/fb:
crw-r--r-- 1 root root 29, 0 Apr 6 2010 0
crw-r--r-- 1 root root 29, 1 Apr 15 2010 1
crw-r--r-- 1 root root 29, 2 Apr 15 2010 2
crw-r--r-- 1 root root 29, 3 Apr 15 2010 3
# ./prog
............................
[display.cpp] displaySize before mmap 614400
[display.cpp] attrs->numBufs before mmap 2
Failed mmap on /dev/fb3 (Invalid argument)
MMAP errno EINVAL
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux
Сообщение
eddy » 27.04.2010 15:03
Запускаете из-под рута?
RTFM
-------
KOI8-R - патриотичная кодировка
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 15:16
Да, на это также указывает традиционная #
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux
Сообщение
eddy » 27.04.2010 15:38
IMB писал(а): ↑ 27.04.2010 15:16
традиционная #
[offtop]У меня везде при работе из-под рута пишется красным:
[ROOT SESSION 27.04 15:39 ~]
[offtop]
Это я к тому, что # - не факт
RTFM
-------
KOI8-R - патриотичная кодировка
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 15:44
[offtop]Сделайте мне цвет при доступе к устройству по RS232 при ч/б minicom-е[offtop]
Не факт, но "широко известно в узких кругах"
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux
Сообщение
watashiwa_daredeska » 27.04.2010 17:45
eddy писал(а): ↑ 27.04.2010 15:38
Это я к тому, что # - не факт
«#» — это общепринятое соглашение, даже в управляющих последовательностях для $PS1 нашло отражение в некоторых шеллах.
IMB , только с /dev/fb3 проблема или с другими /dev/fb* тоже не работает?
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 17:56
Да можно сказать, что со всеми. По SDK возможны /dev/fb/1 и /dev/fb/3, на обоих эта картина.
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux
Сообщение
watashiwa_daredeska » 27.04.2010 18:09
IMB писал(а): ↑ 27.04.2010 17:56
По SDK
Какой-такой SDK? А без всяких SDK пробовали?
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 27.04.2010 19:32
SDK от TexasInstruments для работы с ихнеми ARM-процессорами серии DaVinci.
Пробовал, переписал стандартную фукцию, ничего не меняется. Что при использовании фукции от производителя, что моя - всё стопорится с этой же ошибкой.
Вы скажите - нет поддержке в ядре. Увы нет, поддержка в ядре присутвует. Завтра вставлю в фукцию больше отладочного вывода и предъявлю.
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux
Сообщение
eddy » 27.04.2010 19:42
А вы не пробовали как-нибудь вот так:
Код: Выделить всё
fd = open("/dev/fb3");
mmap (NULL, 1024, PROT_WRITE, MAP_SHARED, fd, 0);
просто для проверки? Вдруг это устройство нельзя отображать в память (ioctl'ов, например, таких нет...).
RTFM
-------
KOI8-R - патриотичная кодировка
IMB
Сообщения: 2567
ОС: Debian
Сообщение
IMB » 28.04.2010 09:53
Фукция
Код: Выделить всё
Display_Handle Display::create (Display_Attrs *attrs, unsigned int imageWidth,
unsigned int imageHeight)
{
cout << "[" << __FILE__ << "] Starting Display create!" << endl;
if (NULL == attrs) {
cout << "[" << __FILE__ << "] Display_Attrs can't be NULL! " << endl;
return NULL;
}
Display_Handle hDisplay = (Display_Handle) calloc(1, sizeof(Display_Object));
if (NULL == hDisplay) {
cout << "[" << __FILE__
<< "] Failed to allocate space for Dispaly Object!" << endl;
return NULL;
}
cout << "[" << __FILE__ << "] Calloc successfully" << endl;
hDisplay->fd = open(attrs->displayDevice, O_RDWR);
if (-1 == hDisplay->fd) {
cout << "[" << __FILE__ << "] Failed to open fb device "
<< attrs->displayDevice << " (" << strerror(errno) << ")" << endl;
return NULL;
}
cout << "[" << __FILE__ << "] Open " << attrs->displayDevice
<< " successfully" << endl;
struct fb_fix_screeninfo fixInfo;
if (-1 == ioctl(hDisplay->fd, FBIOGET_FSCREENINFO, &fixInfo)) {
cout << "Failed FBIOGET_FSCREENINFO on " << attrs->displayDevice
<< " (" << strerror(errno) << ")" << endl;
return NULL;
}
cout << "[" << __FILE__ << "] FBIOGET_FSCREENINFO successfully" << endl;
struct fb_var_screeninfo varInfo;
if (-1 == ioctl(hDisplay->fd, FBIOGET_VSCREENINFO, &varInfo)) {
cout << "Failed FBIOGET_VSCREENINFO on " << attrs->displayDevice
<< " (" << strerror(errno) << ")" << endl;
return NULL;
}
cout << "[" << __FILE__ << "] FBIOGET_VSCREENINFO successfully" << endl;
varInfo.xres = imageWidth;
varInfo.yres = imageHeight;
varInfo.yres_virtual = imageHeight * attrs->numBufs;
if (-1 == ioctl(hDisplay->fd, FBIOPUT_VSCREENINFO, &varInfo)) {
cout << "Failed FBIOPUT_VSCREENINFO on " << attrs->displayDevice
<< " (" << strerror(errno) << ")" << endl;
return NULL;
}
cout << "[" << __FILE__ << "] FBIOPUT_VSCREENINFO successfully" << endl;
varInfo.xres = imageWidth;
varInfo.yres = imageHeight;
varInfo.yres_virtual = imageHeight * attrs->numBufs;
BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT;
if (strcmp("/dev/fb/1", attrs->displayDevice) == 0 ||
strcmp("/dev/fb/3", attrs->displayDevice) == 0) {
/* Color format of a video window */
gfxAttrs.colorSpace = ColorSpace_UYVY;
}
else {
/* Color format of the OSD window */
gfxAttrs.colorSpace = ColorSpace_RGB565;
}
gfxAttrs.dim.width = varInfo.xres;
gfxAttrs.dim.height = varInfo.yres;
gfxAttrs.dim.lineLength = fixInfo.line_length;
gfxAttrs.bAttrs.reference = TRUE;
//unsigned int displaySize = fixInfo.line_length * varInfo.yres;
unsigned int displaySize = 1280 * varInfo.yres;
BufTab_Handle hBufTab = BufTab_create(attrs->numBufs, displaySize,
BufferGfx_getBufferAttrs(&gfxAttrs));
if (NULL == hBufTab) {
cout << "Failed to allocate BufTab for display buffers" << endl;
return NULL;
}
cout << "[" << __FILE__ << "] BufTab_create successfully" << endl;
Buffer_Handle hBuf = BufTab_getBuf(hBufTab, 0);
cout << "[" << __FILE__ << "] BufTab_getBuf successfully" << endl;
Buffer_setNumBytesUsed(hBuf, varInfo.xres * varInfo.yres *
varInfo.bits_per_pixel / 8);
cout << "SetNumBytesUsed "
<< varInfo.xres * varInfo.yres * varInfo.bits_per_pixel / 8 << endl;
Int8 *virtPtr;
cout << "[" << __FILE__ "] displaySize before mmap "
<< displaySize << endl;
cout << "[" << __FILE__ "] attrs->numBufs before mmap "
<< attrs->numBufs << endl;
//cout << "Machine page size " << sysconf(_SC_PAGESIZE) << endl;
virtPtr = (Int8 *) mmap (NULL,
displaySize * attrs->numBufs,
PROT_READ | PROT_WRITE,
MAP_SHARED,
hDisplay->fd, 0);
if (MAP_FAILED == virtPtr) {
cout << "Failed mmap on " << attrs->displayDevice
<< " (" << strerror(errno) << ")" << endl;
cout << "MMAP errno ";
switch (errno) {
case EINVAL:
cout << "EINVAL";
break;
}
cout << endl;
return NULL;
}
if (0 > Buffer_setUserPtr(hBuf, virtPtr))
return NULL;
unsigned char bufIdx;
Int32 physPtr;
for (bufIdx=1; bufIdx < attrs->numBufs; bufIdx++) {
hBuf = BufTab_getBuf(hBufTab, bufIdx);
Buffer_setNumBytesUsed(hBuf, varInfo.xres * varInfo.yres *
varInfo.bits_per_pixel / 8);
virtPtr = virtPtr + displaySize;
Buffer_setUserPtr(hBuf, virtPtr);
cout << "Display buffer " << bufIdx
<< "mapped to " << virtPtr
<< " ,physical address " << physPtr << endl;
}
hDisplay->hBufTab = hBufTab;
hDisplay->displayIdx = 0;
hDisplay->workingIdx = attrs->numBufs > 1 ? 1 : 0;
hDisplay->displayStd = Display_Std_FBDEV;
if (0 > setDisplayBuffer(hDisplay, hDisplay->displayIdx))
return NULL;
if (ioctl(hDisplay->fd, FBIOBLANK, 0)) {
cout << "Error enabling " << attrs->displayDevice << endl;
return NULL;
}
return hDisplay;
}
Вывод
# ./prog
[display.cpp] Starting Display create!
[display.cpp] Calloc successfully
[display.cpp] Open /dev/fb/3 successfully
[display.cpp] FBIOGET_FSCREENINFO successfully
[display.cpp] FBIOGET_VSCREENINFO successfully
[display.cpp] FBIOPUT_VSCREENINFO successfully
@0x000eba83:[T:0x40b06490] ti.sdo.dmai - [BufTab] Allocating BufTab for 2 buffers
[display.cpp] BufTab_create successfully
[display.cpp] BufTab_getBuf successfully
SetNumBytesUsed 614400
[display.cpp] displaySize before mmap 614400
[display.cpp] attrs->numBufs before mmap 2
Failed mmap on /dev/fb/3 (Invalid argument)
MMAP errno EINVAL
Failed to create display device!