ff_replay ff_effect 中的子结构为空
ff_replay substructure in ff_effect empty
我正在为尚未支持的游戏手柄开发力反馈驱动程序 (linux)。
每当用户空间中的应用程序请求 ff 效果(例如隆隆声)时,我的驱动程序中的一个函数就会被调用:
static int foo_ff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
这是由我的初始化函数中的以下代码设置的:
input_set_capability(dev, EV_FF, FF_RUMBLE);
input_ff_create_memless(dev, NULL, foo_ff_play);
我正在访问 ff_effect
结构(传递给我的 foo_ff_play
函数),如下所示:
static int foo_ff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
{
u16 length;
length = effect->replay.length;
printk(KERN_DEBUG "length: %i", length);
return 0;
}
问题是,报告的长度(在 ff_effect->replay
中)始终为零。
这很令人困惑,因为我在我的设备上 运行 fftest,而 fftest 肯定设置了长度属性:https://github.com/flosse/linuxconsole/blob/master/utils/fftest.c(第 308 行)
/* a strong rumbling effect */
effects[4].type = FF_RUMBLE;
effects[4].id = -1;
effects[4].u.rumble.strong_magnitude = 0x8000;
effects[4].u.rumble.weak_magnitude = 0;
effects[4].replay.length = 5000;
effects[4].replay.delay = 1000;
这跟"memlessness"有关系吗?为什么 ff_replay
中的数据似乎为零(如果不是)?
提前致谢
为什么重播结构是空的?
看看 https://elixir.free-electrons.com/linux/v4.4/source/drivers/input/ff-memless.c#L406 我们发现:
static void ml_play_effects(struct ml_device *ml)
{
struct ff_effect effect;
DECLARE_BITMAP(handled_bm, FF_MEMLESS_EFFECTS);
memset(handled_bm, 0, sizeof(handled_bm));
while (ml_get_combo_effect(ml, handled_bm, &effect))
ml->play_effect(ml->dev, ml->private, &effect);
ml_schedule_timer(ml);
}
ml_get_combo_effect
通过调用 ml_combine_effects
来设置效果,但是 ml_combine_effects
根本不会将 replay.length
复制到传递给我们的 ff_effect
结构foo_play_effect
(至少如果效果类型是 FF_RUMBLE 则不会):https://elixir.free-electrons.com/linux/v4.4/source/drivers/input/ff-memless.c#L286
这就是我们无法在 foo_play_effect
函数中读出 ff_replay-data 的原因。
好的,replay 是空的 - 那么我们如何确定我们必须播放多长时间的效果(例如 FF_RUMBLE)?
看来回放结构是我们甚至不需要随身携带的东西。是的,fftest设置了长度,然后把效果上传给驱动,但是如果我们看一下ml_ff_upload
(https://elixir.free-electrons.com/linux/v4.4/source/drivers/input/ff-memless.c#L481),可以看到如下:
if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
__clear_bit(FF_EFFECT_PLAYING, &state->flags);
state->play_at = jiffies +
msecs_to_jiffies(state->effect->replay.delay);
state->stop_at = state->play_at +
msecs_to_jiffies(state->effect->replay.length);
state->adj_at = state->play_at;
ml_schedule_timer(ml);
}
这意味着持续时间已经由 输入-子系统处理。它启动效果并根据需要停止它。
此外,我们可以在 https://elixir.free-electrons.com/linux/v4.4/source/include/uapi/linux/input.h#L279 处看到
/*
* All duration values are expressed in ms. Values above 32767 ms (0x7fff)
* should not be used and have unspecified results.
*/
也就是说我们的效果至少要播放32767ms。其他一切(之前停止效果)取决于调度程序 - 这不是我们的部分 :D
我正在为尚未支持的游戏手柄开发力反馈驱动程序 (linux)。
每当用户空间中的应用程序请求 ff 效果(例如隆隆声)时,我的驱动程序中的一个函数就会被调用:
static int foo_ff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
这是由我的初始化函数中的以下代码设置的:
input_set_capability(dev, EV_FF, FF_RUMBLE);
input_ff_create_memless(dev, NULL, foo_ff_play);
我正在访问 ff_effect
结构(传递给我的 foo_ff_play
函数),如下所示:
static int foo_ff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
{
u16 length;
length = effect->replay.length;
printk(KERN_DEBUG "length: %i", length);
return 0;
}
问题是,报告的长度(在 ff_effect->replay
中)始终为零。
这很令人困惑,因为我在我的设备上 运行 fftest,而 fftest 肯定设置了长度属性:https://github.com/flosse/linuxconsole/blob/master/utils/fftest.c(第 308 行)
/* a strong rumbling effect */
effects[4].type = FF_RUMBLE;
effects[4].id = -1;
effects[4].u.rumble.strong_magnitude = 0x8000;
effects[4].u.rumble.weak_magnitude = 0;
effects[4].replay.length = 5000;
effects[4].replay.delay = 1000;
这跟"memlessness"有关系吗?为什么 ff_replay
中的数据似乎为零(如果不是)?
提前致谢
为什么重播结构是空的?
看看 https://elixir.free-electrons.com/linux/v4.4/source/drivers/input/ff-memless.c#L406 我们发现:
static void ml_play_effects(struct ml_device *ml)
{
struct ff_effect effect;
DECLARE_BITMAP(handled_bm, FF_MEMLESS_EFFECTS);
memset(handled_bm, 0, sizeof(handled_bm));
while (ml_get_combo_effect(ml, handled_bm, &effect))
ml->play_effect(ml->dev, ml->private, &effect);
ml_schedule_timer(ml);
}
ml_get_combo_effect
通过调用 ml_combine_effects
来设置效果,但是 ml_combine_effects
根本不会将 replay.length
复制到传递给我们的 ff_effect
结构foo_play_effect
(至少如果效果类型是 FF_RUMBLE 则不会):https://elixir.free-electrons.com/linux/v4.4/source/drivers/input/ff-memless.c#L286
这就是我们无法在 foo_play_effect
函数中读出 ff_replay-data 的原因。
好的,replay 是空的 - 那么我们如何确定我们必须播放多长时间的效果(例如 FF_RUMBLE)?
看来回放结构是我们甚至不需要随身携带的东西。是的,fftest设置了长度,然后把效果上传给驱动,但是如果我们看一下ml_ff_upload
(https://elixir.free-electrons.com/linux/v4.4/source/drivers/input/ff-memless.c#L481),可以看到如下:
if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
__clear_bit(FF_EFFECT_PLAYING, &state->flags);
state->play_at = jiffies +
msecs_to_jiffies(state->effect->replay.delay);
state->stop_at = state->play_at +
msecs_to_jiffies(state->effect->replay.length);
state->adj_at = state->play_at;
ml_schedule_timer(ml);
}
这意味着持续时间已经由 输入-子系统处理。它启动效果并根据需要停止它。
此外,我们可以在 https://elixir.free-electrons.com/linux/v4.4/source/include/uapi/linux/input.h#L279 处看到
/*
* All duration values are expressed in ms. Values above 32767 ms (0x7fff)
* should not be used and have unspecified results.
*/
也就是说我们的效果至少要播放32767ms。其他一切(之前停止效果)取决于调度程序 - 这不是我们的部分 :D