[PX4-W3PE4] PTX_GET_CNRからCN比を取得しようとするとENOSYSが返却される
kazuki0824 opened this issue · 3 comments
特殊設定になりますが、原因の切り分け方法が分からないため、ご質問させてください。
環境
- Ubuntu Server 22.04
- developブランチの最新のドライバ(7fa9f05)
- PX4-W3PE4
- エリアは東京都で、視聴自体は正しく行うことができる
できていること
checksignal 18
を実行した結果
device = /dev/px4video2
C/N = 30.716024dB^C
つまり、https://github.com/stz2012/recpt1 のchecksignal を使うと、
ioctl(fd, GET_SIGNAL_STRENGTH, &rc) の結果として
rcに正しいC/N比が格納されていることがわかる。
できないこと
use std::os::unix::io::AsRawFd;
nix::ioctl_write_ptr!(set_ch, 0x8d, 0x01, Freq);
nix::ioctl_none!(start_rec, 0x8d, 0x02);
nix::ioctl_none!(stop_rec, 0x8d, 0x03);
nix::ioctl_read!(ptx_get_cnr, 0x8d, 0x04, i32);
nix::ioctl_write_int!(ptx_enable_lnb, 0x8d, 0x05);
nix::ioctl_none!(ptx_disable_lnb, 0x8d, 0x06);
nix::ioctl_write_int!(ptx_set_sys_mode, 0x8d, 0x0b);
#[repr(C)]
pub struct Freq {
pub ch: i32,
pub slot: i32,
}
fn main() {
let path = std::path::Path::new("/dev/px4video2");
let freq = Freq {
ch: 68,
slot: 0,
};
let mut output = 0i32;
let f = std::fs::OpenOptions::new().read(true).open(path).unwrap();
let _errno = unsafe { set_ch(f.as_raw_fd(), &freq) }.unwrap();
let _errno = unsafe { ptx_get_cnr(f.as_raw_fd(), &mut output) }.unwrap();
}
以上のプログラムをRust 1.60でコンパイルし実行すると、
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ENOSYS', src/main.rs:27:69
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
SET_CHANNELは成功するのに、
なぜかPTX_GET_CNRはENOSYSが返却されてしまう。
疑問点
- なぜCで書かれたioctlは機能するのに、Rustからioctlを叩いたときに限ってENOSYSが返るのか
- (Rustで書いたせいで互換性が失われた可能性はかなり低いと考えています。実際SET_CHANNELは成功していますし、START_STREAMINGとSTOP_STREAMINGも同じ方法で呼び出して正しく機能する(録画できる)ことを確認しています)
- PTX_GET_CNRがENOSYSを返すコードパスは
Lines 418 to 421 in d528b9b
再現に使用したコードです
https://github.com/kazuki0824/px4_drv_cnr_test
recisdb-rs を使わせて頂こうとして checksignal が上手くいかなかった者です。
px4_drv のissueに書き込むのも違う気はするのですが、こちらの件だと思うので、ここに記載させていただきます。
px4_drv にprintk() を追記して試してみたところ、
switch(cmd) の default (ptx_chrdev.c の 518行目) を通っているために、
ENOSYS が返っているみたいです。
c も Rust も分かっているわけではないですが、
switch文の処理から c の _IOR(0x8d, 0x04, int *) と
Rust の nix::ioctl_read!(ptx_get_cnr, 0x8d, 0x04, i32) が一致しないことが原因に見えます。
%dでの出力ですが、こちらの環境では
PTX_GET_CNR が -2146923260 で
呼び出し時の cmd が -2147185404 と、異なっていました。
kernel関係もRustも全然わからないので解決策は示せないですが、参考までに。
@sakuei-ld ありがとうございます!
Lines 518 to 520 in d528b9b
指摘頂いた部分はノーマークでした...助かります。
switch文の処理から c の _IOR(0x8d, 0x04, int *) と
Rust の nix::ioctl_read!(ptx_get_cnr, 0x8d, 0x04, i32) が一致しないことが原因に見えます。
%dでの出力ですが、こちらの環境では
PTX_GET_CNR が -2146923260 で
呼び出し時の cmd が -2147185404 と、異なっていました。
このあたりから察するに、私の書いた
nix::ioctl_read!(ptx_get_cnr, 0x8d, 0x04, i32);
が間違いであると判断して良さそうに思いましたので、このissueは一旦クローズいたします