Peter____ Ответов: 2

Плохой адрес на IOCTL


Привет,

У меня есть проблема с Usb Ioctl через Jna на Linux Mint 19. На платформе Android Ioctl может быть отправлен, но на Linux я получаю плохую ошибку адреса. Код программы показан ниже.

Есть еще несколько ioctls, вызываемых на usb-устройстве. Первые 2 работают без ошибки msg:

rc = libc.ioctl(fileDescriptor, USBDEVFS_SETINTERFACE, p.getPointer());

и
int rc = libc.ioctl(fileDescriptor, USBDEVFS_SUBMITURB, urbAddr);


Светодиод устройства usb - камеры начинает светиться.

Следующий ioctl теперь терпит неудачу на моем linux-ПК. Он должен отправить команду ReapUrbNDelay в камеру, чтобы собрать кадры камеры.

rc = libc.ioctl(fileDescriptor, func, urbPointer);

Код заголовка C для ioctl выглядит следующим образом: (usbdevice_fs.h)
#define USBDEVFS_REAPURBNDELAY     _IOW('U', 13, void *)

Если вам нужна дополнительная информация из заголовочных файлов linux mint 19, пожалуйста, сообщите об этом.

Вопрос в том, от какой из 3 переменных исходит ошибка плохого адреса?

Может быть, это переменная PointerByReference, но почему она работает на android-устройстве с теми же параметрами и кодом для отправки ioctl?

Спасибо,
Питер

Что я уже пробовал:

Вот код для функции ioctl.

private static final int USBDEVFS_REAPURBNDELAY = (1 << 30) | (указатель.Размер << 16) | (0x55 << 8) | 13;

--> метод reapRequest вызывается с параметром true

публичный запрос reapRequest(boolean wait) вызывает исключение IOException {
PointerByReference urbPointer = новый PointerByReference();
int func = ждать ? USBDEVFS_REAPURB : USBDEVFS_REAPURBNDELAY;
int rc;
пробовать {
rc = libc.ioctl(fileDescriptor, func, urbPointer);
} е (е LastErrorException) {
если (электронная.getErrorCode() == или &&усилителя; !ждать) {
возвращать null;
}
бросить е;
}}

Если вам нужны более подробные сведения, пожалуйста, сообщите...

2 Ответов

Рейтинг:
5

Peter____

Решение:

Код, который я опубликовал, был в основном для 32-битной платформы:
Int имеет разные размеры на c#, java и других языках. Переписать все исходные функции IOCTL ядра на Java (используется JNA interface class) и установить размеры структуры urb класса new (с JNA Structure class @override fieldOffset) привело к успешному ioctl "reapUrb" с помощью метода "PointerByRefernece". Ioctl были переписаны с помощью класса структуры Jna и связаны с каждой функцией IOCTL с ее размером. Теперь, когда я вызываю новые функции, больше не было ошибок "плохого адреса".

хороший день,

Питер


Рейтинг:
1

KarstenK

Вы создали PointerByReference без какого-либо указателя. Используйте другой конструктор с указателем на a действительный область памяти.


Peter____

Привет Карстен,

Спасибо за ваш ответ, но не могли бы вы сказать мне, почему он работает с первым конструктором на платформе android без какой-либо плохой ошибки адреса?
Здесь все данные могут быть переданы через ioctl в переменную PointerByReference.

Есть предложения?

Спасибо, Питер.

Еще немного кода:

//--- Static parts -------------------------------------------------------------

    /**
     * Returns a completed request.
     * <p>
     * A <code>Request</code> object returned by this method has been removed from the queue and can be re-used by calling {@link Request#initialize} and {@link Request#submit}.
     *
     * @param wait <code>true</code> to wait until a completed request is available. <code>false</code> to return immediately when no
     *             completed request is available.
     * @return A <code>Request</code> object representing a completed request, or <code>null</code> if
     * <code>wait</code> is <code>false</code> and no completed request is available at the time.
     */
    public Request reapRequest(boolean wait) throws IOException {
        PointerByReference urbPointer = new PointerByReference();
        int func = wait ? USBDEVFS_REAPURB : USBDEVFS_REAPURBNDELAY;
        int rc;
        try {
            rc = libc.ioctl(fileDescriptor, func, urbPointer);
        } catch (LastErrorException e) {
            if (e.getErrorCode() == EAGAIN && !wait) {
                return null;
            }
            throw e;
        }
        if (rc != 0) {
            throw new IOException("ioctl(USBDEVFS_REAPURB*) failed, rc=" + rc + ".");
        }
        int urbNdx = Urb.getUserContext(urbPointer.getValue());
        if (urbNdx < 0 || urbNdx >= requests.size()) {
            throw new IOException("URB.userContext returned by ioctl(USBDEVFS_REAPURB*) is out of range.");
        }
        Request req = requests.get(urbNdx);
        if (req.urbAddr != Pointer.nativeValue(urbPointer.getValue())) {
            throw new IOException("Address of URB returned by ioctl(USBDEVFS_REAPURB*) does not match.");
        }
        if (!req.queued) {
            throw new IOException("URB returned by ioctl(USBDEVFS_REAPURB*) was not queued.");
        }
        req.queued = false;
        req.initialized = false;
        return req;
    }


    private interface Libc extends Library {

        int ioctl(int fileHandle, int request, PointerByReference p) throws LastErrorException;

        int ioctl(int fileHandle, int request, Pointer p) throws LastErrorException;

        int ioctl(int fileHandle, int request, int i) throws LastErrorException;
    }