本文共 7099 字,大约阅读时间需要 23 分钟。
新板子car版本android系统收不到m4发送的资源释放消息,屏不亮,先分析一下逻辑关系。
上图就是car版本AP核和M41核之间的倒车逻辑。
阶段1 系统启动完毕
mek_8q.mk 63: $(IMX_DEVICE_PATH)/init_car_m4.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.car_additional.rc 68: $(IMX_DEVICE_PATH)/init_car_no_m4.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.car_additional.rc也就是说vendor.all.system_server.ready代表系统启动完成。
frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java 159:
SystemProperties.set("vendor.all.system_server.ready", "1");
阶段2
(1)注册vehicle_rpmsg_m4驱动
init_car_m4.rc将被触发:
on property:vendor.all.system_server.ready=1 # register the vehicle_rpmsg_m4 on raw android. write /sys/devices/platform/vehicle_rpmsg_m4/register 1 # register the vehicle_rpmsg_m4 on android running in xen. write /sys/devices/platform/passthrough/passthrough\:vehicle_rpmsg_m4/register 1
write /sys/devices/platform/vehicle_rpmsg_m4/register 1 注册vehicle_rpmsg_driver内核驱动。
vendor/nxp-opensource/kernel_imx/drivers/mxc/vehicle/vehicle_rpmsg_m4.c:
static struct rpmsg_driver vehicle_rpmsg_driver = {
.drv.name = "vehicle_rpmsg", .drv.owner = THIS_MODULE, .id_table = vehicle_rpmsg_id_table, .probe = vehicle_rpmsg_probe, .callback = vehicle_rpmsg_cb, }; /*register ap to M4 once echo 1 > /sys/devices/platform/vehicle_rpmsg/register*/ static ssize_t register_store(struct device *dev, '''省略''' unsigned long state_set = simple_strtoul(buf, NULL, 10); if (state_set == 1 && state_set != state) { err = register_rpmsg_driver(&vehicle_rpmsg_driver); '''省略''' return size; } 其中vehicle_rpmsg_cb为接收m4消息的callback函数,注册驱动成功后执行probe函数,vehicle_init_handler将VEHICLE_RPMSG_REGISTER消息发送给m4static int vehicle_rpmsg_probe(struct rpmsg_device *rpdev)
{ '''省略''' init_completion(&vehicle_rpmsg->cmd_complete); INIT_DELAYED_WORK(&vehicle_rpmsg->vehicle_register_work, vehicle_init_handler); 重要 schedule_delayed_work(&vehicle_rpmsg->vehicle_register_work, 0); return 0; } /* send register event to M4 core * M4 will release camera/display once register successfully. 将regster事件发送到M4核心,M4将在成功注册后释放摄像头/显示器。 */ static void vehicle_init_handler(struct work_struct *work) { msg.header.cmd = VEHICLE_RPMSG_REGISTER; err = sc_rm_get_partition(ipc_handle, &os_part); 获取Android系统分区号 if (err != SC_ERR_NONE) { pr_err("sc_rm_get_partition failed!\n"); msg.partition_id = 0xff; } else { msg.partition_id = os_part; } /* need check whether ap have been unregistered before register the ap*/ if (!vehicle_rpmsg->vehicle_client_registered) { while (vehicle_send_message(&msg, vehicle_rpmsg, true)) { 将VEHICLE_RPMSG_REGISTER消息发送给m4 msleep(REGISTER_PERIOD); } } }阶段3
m4接收到VEHICLE_RPMSG_REGISTER消息,释放资源,进入Android界面。m4逻辑如下:
(1)Auto_register服务注册过程,主要用于监听Android的VEHICLE_RPMSG_REGISTER消息:
main(...)
APP_SRTM_Init(); -->xTaskCreate(SRTM_MonitorTask, "SRTM monitor", 256U, NULL, APP_SRTM_MONITOR_TASK_PRIO, NULL); -->APP_SRTM_InitAutoService(void) -->SRTM_AutoService_Create(&autoAdapter); /* Create and register service */ static struct _srtm_auto_adapter autoAdapter = {.registerEvent = APP_SRTM_Auto_RegisterEvent, .unregisterEvent = APP_SRTM_Auto_UnregisterEvent, .control = APP_SRTM_Auto_Control, .powerReport = APP_SRTM_Auto_PowerReport, .getInfo = APP_SRTM_Auto_GetInfo}; --> APP_SRTM_Auto_RegisterEvent(...) 跟踪注册成功的registerEvent服务 -->stateMsg.reg.enroll = 0x01; 表示m4接收到了 VEHICLE_RPMSG_REGISTER消息,准备进入接下来的释放资源以上表示m4接收到了 VEHICLE_RPMSG_REGISTER消息,准备进入接下来的释放资源。
(2)资源释放过程,主要是根据stateMsg.reg.enroll的数值,android注册成功后,置位标志位AUTO_UI_EVENT_BIT_STOP:
main(...)
xTaskCreate(vehicle_state_monitor_task, "VehicleMonitor"...) -->vehicle_state_monitor_task(void *pvParameters) case STATE_TYPE_ANDROID: android_registered_flag = stateMsg.reg.enroll;/* 1:registered, 0:unregistered */ if (android_registered_flag) { if (!shared_resource_free) /* camera resource is not occupied, stop display and release it*/ xEventGroupSetBits(g_xAutoUiEvent, AUTO_UI_EVENT_BIT_STOP); } 该线程监听到AUTO_UI_EVENT_BIT_STOP位置高,则释放资源。 xTaskCreate(rear_view_camera_task, "RearViewCamera",...) -->rear_view_camera_task(void *pvParameters) if (eventBits & AUTO_UI_EVENT_BIT_STOP) { APP_StopCamera(); APP_DeinitDisplay(); APP_AutoPassResource(); //释放资源 --> SOC_AssignDisplayCamera(android_pt); } 阶段4、5 (1)驱动回调函数接收到m4的释放信息,通过netlink将从m4接收的cmd指令信息以广播的方式传给evs服务,对应阶段6的uevent_kernel_multicast_recv函数,通知上层加载显示/摄像头驱动。register_ready味着AP已经注册为客户机,并且已经准备好加载摄像头/显示模块。当它第一次得到驱动信号并且寄存器就绪为真时,它将加载相关的模块。
kernel_imx/drivers/mxc/vehicle/vehicle_rpmsg_m4.c
/*vehicle_rpmsg_cb is called once get rpmsg from M4*/
vehicle_rpmsg_cb(struct rpmsg_device *rpdev) { if (msg->header.cmd == VEHICLE_RPMSG_REGISTER) { vehicle_rpmsg->register_ready = true; } if (vehicle_rpmsg->register_ready) { notice_evs_released(rpdev); vehicle_rpmsg->register_ready = false; } 此函数是通过netlink将从m4接收的cmd指令信息以广播的方式传给evs服务,对应阶段6的uevent_kernel_multicast_recv函数, 阶段6就是讲的上层完成解析过程及后续步骤。 vehicle_hal_set_property(msg->statetype, msg->index, msg->statevalue); -->send_usrmsg(buffer, stream.bytes_written); -->netlink_unicast(nlsk, nl_skb, user_pid, MSG_DONTWAIT); } 阶段6 (1)设置系统属性 vendor.vehicle.registervendor/nxp-opensource/imx/evs_service/evs_service.c
#define RPMSG_CAN_REGISTER "vendor.vehicle.register"
static void handle_events(int uevent_fd) { char msg[UEVENT_MSG_LEN+2]; n = uevent_kernel_multicast_recv(uevent_fd, msg, UEVENT_MSG_LEN); cp = msg; ...省略... while (*cp) { if (!strncmp(cp, "STATE=VEHICLE_RPMSG_EVENT=0", strlen("STATE=VEHICLE_RPMSG_EVENT=0"))) { if (property_set(RPMSG_CAN_EVENT, "0") < 0) ALOGE("%s: could not set property RPMSG_CAN_EVENT", __FUNCTION__); } else if (!strncmp(cp, "STATE=VEHICLE_RPMSG_EVENT=1", strlen("STATE=VEHICLE_RPMSG_EVENT=1"))) { if (property_set(RPMSG_CAN_EVENT, "1") < 0) ALOGE("%s: could not set property RPMSG_CAN_EVENT", __FUNCTION__); } else if (!strncmp(cp, "STATE=VEHICLE_RPMSG_REGISTER=0", strlen("STATE=VEHICLE_RPMSG_REGISTER=0"))) { if (property_set(RPMSG_CAN_REGISTER, "0") < 0) ALOGE("%s: could not set property RPMSG_CAN_REGISTER", __FUNCTION__); } else if (!strncmp(cp, "STATE=VEHICLE_RPMSG_REGISTER=1", strlen("STATE=VEHICLERPMSG_REGISTER=1"))) { if (property_set(RPMSG_CAN_REGISTER, "1") < 0) ALOGE("%s: could not set property RPMSG_CAN_REGISTER", __FUNCTION__); } ...省略... (2)启动boot_completed_core_sh(setup.core.cfg驱动)/device/fsl/imx8q/mek_8q/init_car_m4.rc
on property:vendor.vehicle.register=1 start boot_completed_core_sh
init_car.rc
service boot_completed_core_sh /vendor/bin/init.insmod.sh /vendor/etc/setup.core.cfg vendor.all.setup_core.ready
class main user root group root system disabled oneshot on property:vendor.all.setup_core.ready=1 start boot_completed_main_sh start selinuxswitch service boot_completed_main_sh /vendor/bin/init.insmod.sh /vendor/etc/setup.main.cfg vendor.all.setup_main.ready class main user root group root system disabled oneshot on property:vendor.all.setup_main.ready=1 # Trigger start adbd service start usbd start zygote_late 以上的意思是用init.insmod.sh脚本安装setup.core.cfg里面的模块,然后将vendor.all.setup_core.ready置为1,然后insmod setup.main.cfg中的模块,最后开启adbd服务。
———————————————— 版权声明:本文为CSDN博主「我前年买了个表」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/u011784994/article/details/105135566