新板子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消息發送給m4
static 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.register
vendor/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