fn+ 设置虚拟按键_从一个虚拟input device驱动掌握input device驱动开发

在前面几章,我们分析了input子系统的框架,以及input handler的注册与实现,本章我们通过一个虚拟的input device驱动,说明如何开发一个input device驱动。本章涉及的内容如下:

  1. Platform device、driver的使用
  2. Input device的注册与注销;
  3. sysfs下属性文件的注册与注销。

一、input device驱动开发流程

针对input device的驱动开发主要涉及如下几个开发步骤:

  1. 调用input_allocate_device,申请一个input device
  2. 设置该input device的支持事件类型,主要设置input_dev->evbit变量以及该事件类型对应的code值等;
  3. 若该input device支持输出事件,则需要实现event函数;
  4. 调用input_register_device将该事件注册至系统中;
  5. 当该input device接收到一个事件后(一般是发生了中断),可在中断处理函数中调用input_report将该事件分发给具体的input_handler(至于分发过程,请参考之前的文章)。

基本上实现以上功能,即可完成一个input device。

二、虚拟input device驱动实现说明

此处我们实现的input device,主要支持如下功能:

  1. 我们实现EV_KEY类型的事件,主要是实现key的上报;
  2. 因是虚拟设备,因此我们通过向sysfs的属性文件写入数据,模拟按键事件的发生(即模拟按键中断),而在sysfs的store接口中,我们通过调用input_report_key,实现事件的分发;
  3. 在应用层通过打开/dev/input/eventX文件,并通过读取事件,监控按键事件;
  4. 我们在platform driver的probe接口中,完成input device的注册、sysfs属性文件的注册操作。

数据结构

如下即为虚拟input device定义的数据结构,其中key表示key id,key_value用于记录key值

typedef struct virtual_input_info_s

{

struct input_dev *input_dev;

int key_value;

int key;

}virtual_input_info_t;

Platform device的代码

如下即是本次虚拟input设备的platform device的定义

5a2cdb80f1529dc0363b7ca8db03c503.png

Platform driver的代码

如下即是虚拟input设备的platform driver,在其probe函数中,完成input device的注册,并完成相应sysfs属性文件的注册。

39a80b016303fa172f142d63f0336372.png

虚拟input设备的sysfs属性定义

如下即为虚拟input设备的属性定义,其中vinput_key_value_store即用于模拟接收按钮事件并分发的功能,在具体的input设备驱动中,该函数实现的内容应由具体的中断处理函数实现。然后调用input_report_key、input_sync即实现事件的分发(注意此处若不调用input_sync,则事件不会及时分发,若不调用input_sync,则必须等到该input_device存储的事件大于等于max_event_size-2时才会发送)。

601dfad73e2f41145b5b9f0e0445b644.png

应用测试程序代码

测试程序代码如下,当接收到按键事件后,打印key code和key value

e02028a4de28931b44d93512416223fa.png

测试验证

向属性文件vinput_key中写入1

1f58337908cb66ab21c1813eeeae77fb.png

测试程序接收的事件打印如下:

4b906a5d3fa6713e1e53e16d1060f414.png

其中code0为report事件,可以在应用程序过滤掉即可。通过以上测试,说明虚拟input device驱动工作正常。

以上就是本文的全部内容,主要是通过实现一个虚拟的input设备,理解input 设备驱动的开发流程,针对按键等需求,可以通过input device实现。至此我们完成了input子系统的代码分析及驱动开发验证工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码中加一个test loss功能 class LSTM(nn.Module): def __init__(self, input_size, hidden_size, num_layers, output_size, batch_size, device): super().__init__() self.device = device self.input_size = input_size self.hidden_size = hidden_size self.num_layers = num_layers self.output_size = output_size self.num_directions = 1 # 单向LSTM self.batch_size = batch_size self.lstm = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True) self.linear = nn.Linear(65536, self.output_size) def forward(self, input_seq): h_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(self.device) c_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(self.device) output, _ = self.lstm(input_seq, (h_0, c_0)) pred = self.linear(output.contiguous().view(self.batch_size, -1)) return pred if __name__ == '__main__': # 加载已保存的模型参数 saved_model_path = '/content/drive/MyDrive/危急值/model/dangerous.pth' device = 'cuda:0' lstm_model = LSTM(input_size=1, hidden_size=64, num_layers=1, output_size=3, batch_size=256, device='cuda:0').to(device) state_dict = torch.load(saved_model_path) lstm_model.load_state_dict(state_dict) dataset = ECGDataset(X_train_df.to_numpy()) dataloader = DataLoader(dataset, batch_size=256, shuffle=True, num_workers=0, drop_last=True) loss_fn = nn.CrossEntropyLoss() optimizer = optim.SGD(lstm_model.parameters(), lr=1e-4) for epoch in range(200000): print(f'epoch:{epoch}') lstm_model.train() epoch_bar = tqdm(dataloader) for x, y in epoch_bar: optimizer.zero_grad() x_out = lstm_model(x.to(device).type(torch.cuda.FloatTensor)) loss = loss_fn(x_out, y.long().to(device)) loss.backward() epoch_bar.set_description(f'loss:{loss.item():.4f}') optimizer.step() if epoch % 100 == 0 or epoch == epoch - 1: torch.save(lstm_model.state_dict(), "/content/drive/MyDrive/危急值/model/dangerous.pth") print("权重成功保存一次")
最新发布
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值