imx8qxp正常倒车

1. 背景

        Android很多事件都是通过uevent跟kernel来异步通信的。Uevent是内核通知android有状态变化的一种方法,比如USB线插入、拔出,电池电量变化等等。其本质是内核发送(可以通过socket)一个字符串,应用层(android)接收并解释该字符串,获取相应信息。

2. uevent简述

        sysfs 是 Linux userspace 和 kernel 进行交互的一个媒介。通过 sysfs,userspace 可以主动去读写 kernel 的一些数据,同样的, kernel 也可以主动将一些“变化”告知给 userspace。也就是说,通过sysfs,userspace 和 kernel 的交互,本质上是双向的。

        userspace 通过 sysfs 访问 kernel 数据的方法,便是大名鼎鼎的 show() / store() 方法:只要在 kernel 提供了对应的 show() / store() 方法,用户便可以通过 shell 用户,cd 进入到相应的目录,使用 cat / echo 操作对应的文件节点即可。而 kernel ,通过 sysfs 将一些 kernel 的“变化”“告知”给 userspace 则是通过 uevent 的方式。

        一般来说,Kernel 会发送一个字符串给 userspace,然后 userspace 来解析处理该字符串,比如android7.0上 HDMI 热插拔的 event 字符串: change@/devices/virtual/switch/hdmi 。 该字符串的路径为 “/sys/devices/virtual/switch/hdmi/change” ,届时 userspace 的监听线程去读取该文件节点即可。

3. uevent kernel实现

        kernel 关于 uevent 的实现代码,大约可参考文件 kobject_uevent.c ,其简要调用如下:

kobject_uevent(&drv->p->kobj, KOBJ_ADD);  
kobject_uevent_env(kobj, action, NULL);  
retval = netlink_broadcast_filtered(uevent_sock, skb,0, 1, GFP_KERNEL,kobj_bcast_filter,kobj);  

        其中,kobject_uevent(struct kobject *kobj, enum kobject_action action) 中的 action 对应着以下几种:

 KOBJ_ADD,  
 KOBJ_REMOVE,  
 KOBJ_CHANGE,  
 KOBJ_MOVE,  
 KOBJ_ONLINE,                                                                                                                             
 KOBJ_OFFLINE,  

        而 kobject_uevent() 其实就是直接调用了 kobject_uevent_env() 函数。一切的操作,将在该函数中完成,比如 kset uevent ops (struct kset_uevent_ops)的获取、字符串的填充组合、netlink message 的发送等。

        其中, kset_uevent_ops 有以下几种:

  slab_uevent_ops  
  bus_uevent_ops  
  device_uevent_ops  
  gfs2_uevent_ops  
  module_uevent_ops 

        这些 uevent ops 在 start_kernel() 就会被注册。

4. uevent实例

        在imx8qxp正常倒车功能中,MCU检测到倒车CAN信号后会拉高一个gpio,BSP轮询gpio的状态并将状态的变化通过uevent主动报告给Android,Android层会监视uevent并处理,如果检测到倒车uevent就会启动正常倒车APP。

        imx8qxp快速倒车功能是通过在M4核上运行RTOS实现的。

4.1 M4核

rear_view_camera_task
	can_event_init
		can_event_task
			GPIO_ReadPinInput	//轮询gpio状态
			send_event2RVC	//根据gpio状态将档位信息放到XXX栈中
			
vehicle_state_monitor_task
	xQueueReceive
		AUTO_SRTM_SendCommand	//从XXX栈中读取档位信息,处理过后通过核间通信的方式发送到A核

4.2 A核

drivers/mxc/vehicle/vehicle_rpmsg_m4.c
vehicle_rpmsg_cb	//对从M4核发送过来的信息进行解析并分类处理
	extcon_set_state_sync(ev_edev, EXTCON_VEHICLE_RPMSG_EVENT, 0);	//对倒车档进行处理
	extcon_set_state_sync(ev_edev, EXTCON_VEHICLE_RPMSG_EVENT, 1);
		extcon_sync
			kobject_uevent_env(&edev->dev.kobj, KOBJ_CHANGE, envp);		//主动上报倒车uevent事件

drivers/extcon/extcon.c
[EXTCON_VEHICLE_RPMSG_EVENT] = {
	.type = EXTCON_TYPE_MISC,
    .id = EXTCON_VEHICLE_RPMSG_EVENT,
    .name = "VEHICLE_RPMSG_EVENT",
}

4.3 Android上层

监控倒车uevent事件,发现倒车uevent事件后进入正常倒车
STATE=VEHICLE_RPMSG_EVENT

猜你喜欢

转载自blog.csdn.net/qq_41076734/article/details/124693384