当前位置:   article > 正文

autochip RVC

autochip RVC

目录

RVC RTOS 代码流程分析

创建vBackcarGPIOMonitorTask监控线程

 获取backcar gpio的值

接收eBCStartEvent 事件

autochip ipc arm1&arm2核间通信

构建ipc_chan  将chan list node 挂到chan->dev->ipc_list 上获取ipc msg

 memcpy_fromio 获取send 到arm1 上的ipc msg

 将ipc msg 拷贝到内核的buf

 Kernel  backcar 接收RVC_IPC_KEY_ARM2_NOTIFY

IPC send

更新msg_free

 获取chan msg 发送到ipc msg

backcar 使用backcardrv ioctl 发送ipc msg

RVC  hal 层

通过metazone 获取METAZONE_BACKCAR_VDO_SOURCE的值

通过backcardrv文件节点获取msg

 arm 2 上的rtos 获取倒车的gpio的信息通过backcar驱动解析后将event事件挂在notify_event_list

arm ap 侧使用驱动read的接口获取backcardrv arm2 的msg

hal层rvcDataChangeNotify将回调java注册callback函数

 java层backcar service 注册hal 回调函数

backcar service  callbac函数 sendmsg EVENT_TYPE_RVC_DATA_CHANGE给app 

触发app start RVC


RVC RTOS 代码流程分析

dtsi 中配置的gpio 用于触发RVC 

g_device_dtb_info->avin_info.gpio_trigger_backcar

vendor/autochips/proprietary/tinysys/viss/os/drivers/backcar/

  1. /*********************************************************************
  2. * Task for handle backcar events: start/stop/update/suspend/resume.
  3. *********************************************************************/
  4. void vBackcarMainTask( void *pvParameters )
  5. {
  6. //TickType_t xQueueReceiveWait = pdMS_TO_TICKS( 0 );
  7. BCEventType_t xBCEventType = eBCNoneEvent;
  8. RVCData_t xRVCData;
  9. BC_INFO("backcar main task start. videoin viss time: %dms\n", get_current_time_ms());
  10. (void)pvParameters;
  11. /*check backcar status and notify apm first to ensure LOGO/ANI can show in time*/
  12. BC_INFO("backcarGPIO_NUM=%d\r\n", backcarGPIO_NUM);
  13. if( pdPASS != xBCGPIOInit( backcarGPIO_NUM ) )
  14. {
  15. BC_ERR("init backcar gpio fail\r\n");
  16. }
  17. xBCEventType = xBCGPIOGetCurEvent();
  18. if( eBCStopEvent == xBCEventType )
  19. {
  20. BC_INFO("backcar at stop status before backcar init \r\n");
  21. if( NULL != pxBCCallback )
  22. {
  23. pxBCCallback( xBCEventType );
  24. }
  25. }
  26. if( pdFAIL == xBCModulesInit() )
  27. {
  28. BC_ERR("backcar task init failed \r\n");
  29. if( eBCStartEvent == xBCEventType )
  30. {
  31. xBCEventType = eBCStopEvent;
  32. pxBCCallback( xBCEventType );
  33. }
  34. }
  35. for( ; ; )
  36. {
  37. if( NULL == xBCEventQueue )
  38. {
  39. BC_ERR("backcar event queue is null \r\n");
  40. break;
  41. }
  42. if( pdPASS == xQueueReceive( xBCEventQueue, &xBCEventType, portMAX_DELAY ) ) //always block for events
  43. {
  44. BC_INFO("backcar event received: %d \r\n", xBCEventType);
  45. if( pdTRUE == xStopHandleEvent )
  46. {
  47. BC_INFO("viss rvc will exit, stop handle any rvc event!\r\n");
  48. continue;
  49. }
  50. switch( xBCEventType )
  51. {
  52. case eBCStartEvent:
  53. BC_INFO("get start event. videoin viss time: %dms\n", get_current_time_ms());
  54. if( xArm1BCIsReady || !xScreenMCUOn || !xDisplayPowerOn )
  55. {
  56. BC_INFO("arm1 backcar is ready or screen is off, do not respond to eBCStartEvent\r\n");
  57. break;
  58. }
  59. if( pdPASS != xBackcarShow() )
  60. {
  61. BC_ERR("backcar start failed \r\n");
  62. break;
  63. }
  64. if( NULL != pxBCCallback )
  65. {
  66. pxBCCallback( xBCEventType );
  67. }
  68. g_xRVCCurDataSet.lRVCStatus = 0;
  69. memset( &xRVCData, 0, sizeof( RVCData_t ) );
  70. strcpy( xRVCData.ipc_key, RVC_IPC_KEY_ARM2_NOTIFY );
  71. xRVCData.type = RVC_DATA_RVC_STATUS;
  72. xRVCData.data[0] = g_xRVCCurDataSet.lRVCStatus;
  73. xBackcarSendMsgToArm1( (void *)&xRVCData );
  74. break;
  75. case eBCStopEvent:
  76. if( !xScreenMCUOn || !xDisplayPowerOn )
  77. {
  78. BC_INFO("screen is off, do not respond to eBCStopEvent\r\n");
  79. break;
  80. }
  81. if( pdPASS != xBackcarHide() )
  82. {
  83. BC_ERR("backcar stop failed \r\n");
  84. }
  85. if( xArm1BCIsReady )
  86. {
  87. BC_INFO("arm1 backcar is ready, quit arm2 backcar forever\r\n");
  88. xStopHandleEvent = pdTRUE;
  89. xBCEventType = eBCQuitEvent;
  90. }
  91. if( NULL != pxBCCallback )
  92. {
  93. pxBCCallback( xBCEventType );
  94. }
  95. g_xRVCCurDataSet.lRVCStatus = 1;
  96. memset( &xRVCData, 0, sizeof( RVCData_t ) );
  97. strcpy( xRVCData.ipc_key, RVC_IPC_KEY_ARM2_NOTIFY );
  98. xRVCData.type = RVC_DATA_RVC_STATUS;
  99. xRVCData.data[0] = g_xRVCCurDataSet.lRVCStatus;
  100. xBackcarSendMsgToArm1( (void *)&xRVCData );
  101. break;
  102. case eBCUpdateEvent:
  103. if( pdPASS != xBackcarUpdate() )
  104. {
  105. BC_ERR("backcar update failed \r\n");
  106. break;
  107. }
  108. break;
  109. case eBCSuspendEvent:
  110. if( pdPASS != xBackcarSuspend() )
  111. {
  112. BC_ERR("backcar suspend failed \r\n");
  113. break;
  114. }
  115. break;
  116. case eBCResumeEvent:
  117. if( pdPASS != xBackcarResume() )
  118. {
  119. BC_ERR("backcar resume failed \r\n");
  120. break;
  121. }
  122. break;
  123. default:
  124. BC_ERR("backcar unknown event occured \r\n");
  125. break;
  126. }
  127. }
  128. }
  129. vTaskDelete(NULL);
  130. }

创建vBackcarGPIOMonitorTask监控线程

触发倒车eBCStartEvent

  1. /**********************************************************************
  2. * Task for monitor backcar switch event through polling gpio value
  3. **********************************************************************/
  4. void vBackcarGPIOMonitorTask( void *pvParameters )
  5. {
  6. TickType_t xDelay = pdMS_TO_TICKS( 200 );
  7. TickType_t xQueueSendWait = pdMS_TO_TICKS( 0 ); //no wait, if queue is full and send fail, do not change last gpio value, wait for next task circle to send
  8. int lCurGPIOVal = gpioUNKNOWN;
  9. int lLastGPIOVal = gpioUNKNOWN;
  10. BCEventType_t xBCEventType = eBCNoneEvent;
  11. BC_INFO("backcar gpio monitor task start\r\n");
  12. (void)pvParameters;
  13. for( ; ; )
  14. {
  15. if( NULL == xBCEventQueue )
  16. {
  17. BC_ERR("backcar event queue is null \r\n");
  18. goto end;
  19. }
  20. //获取gpio_trigger_backcar gpio value
  21. lCurGPIOVal = lBCGPIOGetValue();
  22. if( lLastGPIOVal != lCurGPIOVal )
  23. {
  24. if( gpioHIGH == lCurGPIOVal )
  25. {
  26. BC_INFO("[%d ms] _lyq backcar start event occured \r\n",get_current_time_ms());
  27. //触发倒车
  28. xBCEventType = eBCStartEvent;
  29. }
  30. else if( gpioLOW == lCurGPIOVal )
  31. {
  32. BC_INFO("_lyq backcar stop event occured \r\n");
  33. //结束倒车
  34. xBCEventType = eBCStopEvent;
  35. }
  36. else
  37. {
  38. BC_ERR("backcar unknow event occured \r\n");
  39. goto end;
  40. }
  41. //Notice: if many other events sent to queue after xQueueReset and before xQueueSend. this event may send fail
  42. xQueueReset( xBCEventQueue ); //clean event queue.The interface always return pdPASS since FreeRTOS V7.2.0
  43. if( pdPASS != xQueueSend( xBCEventQueue, &xBCEventType, xQueueSendWait ) )
  44. {
  45. BC_ERR("send backcar start/stop event to queue fail \r\n");
  46. goto end;
  47. }
  48. lLastGPIOVal = lCurGPIOVal;
  49. }
  50. xDelay = pdMS_TO_TICKS( 10 );
  51. vTaskDelay( xDelay );
  52. continue;
  53. end:
  54. xBCEventType = eBCNoneEvent;
  55. xDelay = pdMS_TO_TICKS( 100 ); //change frequence of checking gpio value when error accured
  56. vTaskDelay( xDelay );
  57. }
  58. vTaskDelete(NULL);
  59. }

 获取backcar gpio的值

  1. static int lBCGPIOGetValue()
  2. {
  3. int lGPIOValue = gpioUNKNOWN;
  4. if( ulBCGPIONum != 0 )
  5. {
  6. lGPIOValue = xGpioGetPinValue( ulBCGPIONum );
  7. }
  8. return lGPIOValue;
  9. }
  1. int xGpioGetPinValue(long lPin)
  2. {
  3. unsigned int ext_info = 0;
  4. unsigned int group = 0, offset = 0;
  5. unsigned int value = 0;
  6. if (lPin >= GPIO_NUM) {
  7. GPIO_ERR("Input pin number is %ld, Not support!\n", lPin);
  8. return -1;
  9. }
  10. ext_info = gpio_ext_info[lPin];
  11. group = GET_GROUP_NUM(ext_info);
  12. if (group == GPIO_UNSUPPORT) {
  13. GPIO_INFO("Input pin number is %ld, Not support!\n", lPin);
  14. return -1;
  15. }
  16. offset = GET_GROUP_OFFSET(ext_info);
  17. value = gpio_hal_input_value_get(group);
  18. return (value >> offset & GPIO_BITMASK);
  19. }

接收eBCStartEvent 事件

发送RVC_IPC_KEY_ARM2_NOTIFY给arm1 ap 侧

  1. /*********************************************************************
  2. * Task for handle backcar events: start/stop/update/suspend/resume.
  3. *********************************************************************/
  4. void vBackcarMainTask( void *pvParameters )
  5. {
  6. //TickType_t xQueueReceiveWait = pdMS_TO_TICKS( 0 );
  7. BCEventType_t xBCEventType = eBCNoneEvent;
  8. RVCData_t xRVCData;
  9. BC_INFO("backcar main task start. videoin viss time: %dms\n", get_current_time_ms());
  10. (void)pvParameters;
  11. /*check backcar status and notify apm first to ensure LOGO/ANI can show in time*/
  12. BC_INFO("backcarGPIO_NUM=%d\r\n", backcarGPIO_NUM);
  13. if( pdPASS != xBCGPIOInit( backcarGPIO_NUM ) )
  14. {
  15. BC_ERR("init backcar gpio fail\r\n");
  16. }
  17. xBCEventType = xBCGPIOGetCurEvent();
  18. if( eBCStopEvent == xBCEventType )
  19. {
  20. BC_INFO("backcar at stop status before backcar init \r\n");
  21. if( NULL != pxBCCallback )
  22. {
  23. pxBCCallback( xBCEventType );
  24. }
  25. }
  26. if( pdFAIL == xBCModulesInit() )
  27. {
  28. BC_ERR("backcar task init failed \r\n");
  29. if( eBCStartEvent == xBCEventType )
  30. {
  31. xBCEventType = eBCStopEvent;
  32. pxBCCallback( xBCEventType );
  33. }
  34. }
  35. for( ; ; )
  36. {
  37. if( NULL == xBCEventQueue )
  38. {
  39. BC_ERR("backcar event queue is null \r\n");
  40. break;
  41. }
  42. if( pdPASS == xQueueReceive( xBCEventQueue, &xBCEventType, portMAX_DELAY ) ) //always block for events
  43. {
  44. BC_INFO("backcar event received: %d \r\n", xBCEventType);
  45. if( pdTRUE == xStopHandleEvent )
  46. {
  47. BC_INFO("viss rvc will exit, stop handle any rvc event!\r\n");
  48. continue;
  49. }
  50. switch( xBCEventType )
  51. {
  52. case eBCStartEvent:
  53. BC_INFO("get start event. videoin viss time: %dms\n", get_current_time_ms());
  54. if( xArm1BCIsReady || !xScreenMCUOn || !xDisplayPowerOn )
  55. {
  56. BC_INFO("arm1 backcar is ready or screen is off, do not respond to eBCStartEvent\r\n");
  57. break;
  58. }
  59. if( pdPASS != xBackcarShow() )
  60. {
  61. BC_ERR("backcar start failed \r\n");
  62. break;
  63. }
  64. if( NULL != pxBCCallback )
  65. {
  66. pxBCCallback( xBCEventType );
  67. }
  68. //arm2 对arm1 发送ipc 消息
  69. g_xRVCCurDataSet.lRVCStatus = 0;
  70. memset( &xRVCData, 0, sizeof( RVCData_t ) );
  71. strcpy( xRVCData.ipc_key, RVC_IPC_KEY_ARM2_NOTIFY );
  72. xRVCData.type = RVC_DATA_RVC_STATUS;
  73. xRVCData.data[0] = g_xRVCCurDataSet.lRVCStatus;
  74. xBackcarSendMsgToArm1( (void *)&xRVCData );
  75. break;
  76. case eBCStopEvent:
  77. if( !xScreenMCUOn || !xDisplayPowerOn )
  78. {
  79. BC_INFO("screen is off, do not respond to eBCStopEvent\r\n");
  80. break;
  81. }
  82. if( pdPASS != xBackcarHide() )
  83. {
  84. BC_ERR("backcar stop failed \r\n");
  85. }
  86. if( xArm1BCIsReady )
  87. {
  88. BC_INFO("arm1 backcar is ready, quit arm2 backcar forever\r\n");
  89. xStopHandleEvent = pdTRUE;
  90. xBCEventType = eBCQuitEvent;
  91. }
  92. if( NULL != pxBCCallback )
  93. {
  94. pxBCCallback( xBCEventType );
  95. }
  96. g_xRVCCurDataSet.lRVCStatus = 1;
  97. memset( &xRVCData, 0, sizeof( RVCData_t ) );
  98. strcpy( xRVCData.ipc_key, RVC_IPC_KEY_ARM2_NOTIFY );
  99. xRVCData.type = RVC_DATA_RVC_STATUS;
  100. xRVCData.data[0] = g_xRVCCurDataSet.lRVCStatus;
  101. xBackcarSendMsgToArm1( (void *)&xRVCData );
  102. break;
  103. case eBCUpdateEvent:
  104. if( pdPASS != xBackcarUpdate() )
  105. {
  106. BC_ERR("backcar update failed \r\n");
  107. break;
  108. }
  109. break;
  110. case eBCSuspendEvent:
  111. if( pdPASS != xBackcarSuspend() )
  112. {
  113. BC_ERR("backcar suspend failed \r\n");
  114. break;
  115. }
  116. break;
  117. case eBCResumeEvent:
  118. if( pdPASS != xBackcarResume() )
  119. {
  120. BC_ERR("backcar resume failed \r\n");
  121. break;
  122. }
  123. break;
  124. default:
  125. BC_ERR("backcar unknown event occured \r\n");
  126. break;
  127. }
  128. }
  129. }
  130. vTaskDelete(NULL);
  131. }

autochip ipc arm1&arm2核间通信

构建ipc_chan  将chan list node 挂到chan->dev->ipc_list 上获取ipc msg

  1. #define ipc_request_chan_detailed(proc, direction, snd, rcv) \
  2. 163 ({ \
  3. 164 ipc_chan_t *__chan = ipc_request_chan(proc, direction); \
  4. 165 if (__chan) { \
  5. 166 strncpy(__chan->sender, snd, 8); \
  6. 167 strncpy(__chan->receiver, rcv, 8); \
  7. 168 } \
  8. 169 __chan; \
  9. 170 })

  1. 482 ipc_chan_t *ipc_request_chan(enum IPC_CORE proc, enum IPC_DIRECTION direction)
  2. 483 {
  3. 484 ipc_chan_t *chan = NULL;
  4. 485
  5. 486 if (proc != CORE_VEHICLE) {
  6. 487 pr_err("[AIPC] %s unsupport communicate with core=%d\n", __func__,
  7. 488 proc);
  8. 489 return NULL;
  9. 490 }
  10. 491
  11. 492 chan = kzalloc(sizeof(ipc_chan_t), GFP_KERNEL);
  12. 493 if (!chan) {
  13. 494 pr_err("[AIPC] %s no memory\n", __func__);
  14. 495 return NULL;
  15. 496 }
  16. 497
  17. 498 spin_lock_init(&chan->lock);
  18. 499
  19. 500 if (direction == MSGSEND) { //send
  20. 501 chan->dev = dev_ap2viss;
  21. 502 } else if (direction == MSGRECV) {
  22. //receive
  23. //接收msg
  24. 503 chan->dev = dev_viss2ap;
  25. 504 init_waitqueue_head(&chan->wait);
  26. 505
  27. 506 mutex_lock(&ipc_mutex);
  28. //将chan list node 挂到chan->dev->ipc_list 上获取ipc msg
  29. 507 list_add(&chan->list_node, &(chan->dev->ipc_list));
  30. 508 chan->dev->idr_ref++;
  31. 509 mutex_unlock(&ipc_mutex);
  32. 510 }
  33. 511
  34. 512 return chan;
  35. 513 }
  36. 514
  37. 515 EXPORT_SYMBOL_GPL(ipc_request_chan);

 memcpy_fromio 获取send 到arm1 上的ipc msg

Linux-IO端口、IO内存详解_memcpy_fromio-CSDN博客

  1. static void ipc_find_work(struct work_struct *work)
  2. 145 {
  3. 146 uint8_t first_entry = 0;
  4. 147 ipc_msg_t *ipc_msg = NULL;
  5. 148 ipc_chan_t *chan = NULL;
  6. 149 ipc_chan_dev_t *dev = dev_viss2ap; // AP <- VEHICLE
  7. 150 void *msg;
  8. 151 unsigned idx = 0;
  9. 152 unsigned long flags;
  10. 153
  11. 154 // 2. account all.
  12. 155 mutex_lock(&ipc_mutex);
  13. 156 while (ipc_hal_responder_get_number_valid(dev->oid, dev->rid)) {
  14. 157 first_entry = ipc_hal_responder_get_first_valid(dev->oid, dev->rid);
  15. 158 ipc_msg =
  16. 159 (ipc_msg_t *) (dev->base_addr + first_entry * IPC_PACKET_SIZE);
  17. 160
  18. //循环遍历ipc_list的list_node 匹配receiver
  19. 161 list_for_each_entry(chan, &dev->ipc_list, list_node) {
  20. 162 if (!strncmp(chan->receiver, ipc_msg->receiver, 8)) {
  21. 163 //pr_info("[AIPC] the lucker %s\n", chan->receiver);
  22. 164 spin_lock_irqsave(&chan->lock, flags);
  23. 165 if (chan->msg_count == IPC_MSG_QUEUE_LEN) {
  24. 166 spin_unlock_irqrestore(&chan->lock, flags);
  25. 167 continue;
  26. 168 }
  27. 169
  28. 170 idx = chan->msg_free;
  29. 171 //判断ipc msg不为空
  30. 172 if (ipc_msg->msg && ipc_msg->size) {
  31. 173 msg = kmalloc(ipc_msg->size, GFP_KERNEL);
  32. 174 if (!msg) {
  33. 175 pr_err("[AIPC] %s no memory\n",
  34. __func__);
  35. 176 spin_unlock_irqrestore(&chan->lock,
  36. flags);
  37. 177 continue;
  38. 178 }
  39. 179 //获取ipc msg 保存到chan msg_data
  40. 180 memcpy_fromio(msg, ipc_msg->msg,
  41. ipc_msg->size);
  42. 181 chan->msg_data[idx].msg = msg;
  43. 182 chan->msg_data[idx].size = ipc_msg->size;
  44. 183 } else {
  45. 184 chan->msg_data[idx].msg = NULL;
  46. 185 chan->msg_data[idx].size = 0;
  47. 186 }
  48. 187
  49. 188 pr_debug("[AIPC] ipc_find_work %s->%s, %s, %d, %u, %u\n", chan->sender, chan->receiver,
  50. 189 (char *)(chan->msg_data[idx].msg), chan-
  51. >msg_data[idx].size,
  52. 190 chan->msg_count, chan->msg_free);
  53. 191
  54. 192 chan->msg_count++;
  55. 193
  56. 194 if (idx == IPC_MSG_QUEUE_LEN - 1)
  57. 195 chan->msg_free = 0;
  58. 196 else
  59. 197 chan->msg_free++;
  60. 198
  61. 199 spin_unlock_irqrestore(&chan->lock, flags);
  62. 200
  63. 201 wake_up_interruptible(&chan->wait);
  64. 202 }
  65. 203 }//1: no luck receiver, publish ,account it
  66. 204
  67. 205 ipc_ack(dev);
  68. 206 }
  69. 207 mutex_unlock(&ipc_mutex);
  70. 208 }
  1. #define ipc_receivemsg_timeout(c, m, s, t) \
  2. 183 ({ \
  3. 184 int __rc = 0; \
  4. 185 __rc = ipc_receive_timeout(c, t); \
  5. 186 if (__rc == 0) { \
  6. 187 __rc = (int)ipc_read(c, m, s); \
  7. 188 } \
  8. 189 __rc; \
  9. 190 })
  10. 191
  11. 192 #define ipc_receive(c) ipc_receive_timeout(c, 0)
  12. 193
  13. 194 #define ipc_receivemsg(c, m, s) ipc_receivemsg_timeout(c, m, s, 0)

 将ipc msg 拷贝到内核的buf

  1. ssize_t ipc_read(ipc_chan_t *chan, void *buf, size_t nbytes)
  2. 309 {
  3. 310 unsigned long flags;
  4. 311 ssize_t n = 0;
  5. 312 unsigned idx = 0;
  6. 313 unsigned count = 0;
  7. 314
  8. 315 spin_lock_irqsave(&chan->lock, flags);
  9. 316 count = chan->msg_count;
  10. 317 if (count == 0) {
  11. 318 spin_unlock_irqrestore(&chan->lock, flags);
  12. 319 return 0;
  13. 320 }
  14. 321
  15. 322 idx = chan->msg_free;
  16. 323 if (idx >= count)
  17. 324 idx -= count;
  18. 325 else //初始化 msg_free
  19. 326 idx += IPC_MSG_QUEUE_LEN - count;
  20. 327
  21. 328 pr_debug("[AIPC] ipc_read %s->%s, %s, %d, %u, %u\n", chan->sender, chan- >receiver,
  22. 329 (char *)(chan->msg_data[idx].msg), chan->msg_data[idx].size,
  23. 330 chan->msg_count, chan->msg_free);
  24. 331
  25. 332 n = nbytes < chan->msg_data[idx].size ? nbytes : chan->msg_data[idx].size;
  26. 333 if (chan->msg_data[idx].msg && n) {
  27. 334 memcpy(buf, chan->msg_data[idx].msg, n);
  28. 335 }
  29. 336
  30. 337 if (chan->msg_data[idx].msg){
  31. 338 kfree(chan->msg_data[idx].msg);
  32. 339 chan->msg_data[idx].msg = NULL;
  33. 340 }
  34. 341
  35. 342 chan->msg_count--;
  36. 343
  37. 344 spin_unlock_irqrestore(&chan->lock, flags);
  38. 345
  39. 346 return n;
  40. 347 }
  41. 348
  42. 349 EXPORT_SYMBOL_GPL(ipc_read);

 Kernel  backcar 接收RVC_IPC_KEY_ARM2_NOTIFY

  1. #ifndef CONFIG_BACKCAR_NO_ARM2
  2. 202 static int backcar_ipc_receive_thread(void *data)
  3. 203 {
  4. 204 int ret = 0;
  5. 205 char arm2_msg[ipcMSG_LENGTH] = {0,};
  6. 206 struct rvc_data received_rvc_data;
  7. 207 struct arm2_rvc_event *event = NULL;
  8. 208 BACKCAR_LOG(BACKCAR_INFO, "backcar_ipc_receive_thread start\n");
  9. 209
  10. 210 do {
  11. 211 if (!g_ipc_receive_chan) {
  12. 212 BACKCAR_LOG(BACKCAR_INFO, "ipc receive chan is null, request chan first.\n");
  13. //一个创建ipc recevice chan
  14. //sender= g_ipc_arm1_ap 
  15. //receiver=g_ipc_arm2_rvc
  16. 213 g_ipc_receive_chan = ipc_request_chan_detailed(CORE_VEHICLE, MSGRECV, , g_ipc_arm1_ap);
  17. 214 if (!g_ipc_receive_chan) {
  18. 215 BACKCAR_LOG(BACKCAR_ERR, "ipc request receive chan fail\n");
  19. 216 continue;
  20. 217 }
  21. 218 }
  22. 219
  23. 220 memset(arm2_msg, 0, sizeof(arm2_msg));
  24. //IPC通信接收小核 arm2的msg
  25. 221 ret = ipc_receivemsg(g_ipc_receive_chan, arm2_msg, ipcMSG_LENGTH);
  26. 222 if (ret < 0) {
  27. 223 BACKCAR_LOG(BACKCAR_ERR, "ipc receive fail %d\n", ret);
  28. 224 continue;
  29. 225 }
  30. 226
  31. 227 BACKCAR_LOG(BACKCAR_DEBUG, "ipc receive arm2_msg %s\n", arm2_msg);
  32. 228 if (!strncmp(cIpcMsgRcvArm2BCExit, arm2_msg, ipcMSG_LENGTH)) {
  33. 229 BACKCAR_LOG(BACKCAR_INFO, "backcar receive msg %s success \n", cIpcMsgRcvArm2BCExit);
  34. 230 if (NULL != g_ioctlwaitq) {
  35. 231 wake_up(g_ioctlwaitq);
  36. 232 } else {
  37. 233 BACKCAR_LOG(BACKCAR_WARNING, "g_ioctl waitq has been waked. but not by arm2 msg\n");
  38. 234 }
  39. 235 } else {
  40. 236 memset(&received_rvc_data, 0, sizeof(struct rvc_data));
  41. 237 memcpy(&received_rvc_data, arm2_msg, ipcMSG_LENGTH);
  42. 238 if (0 == strcmp(received_rvc_data.ipc_key, RVC_IPC_KEY_ARM2_RESPOND)) {
  43. 239 BACKCAR_LOG(BACKCAR_DEBUG, "RVC_IPC_KEY_ARM2_NOTIFY received. type = %d, data[0]= %d\n",
  44. 240 received_rvc_data.type, received_rvc_data.data[0]);
  45. 241 memset(&g_responsed_rvc_data, 0, sizeof(struct rvc_data));
  46. 242 memcpy(&g_responsed_rvc_data, arm2_msg, ipcMSG_LENGTH);
  47. 243 } else if (0 == strcmp(received_rvc_data.ipc_key, RVC_IPC_KEY_ARM2_NOTIFY)) {
  48. 244 BACKCAR_LOG(BACKCAR_INFO, "RVC_IPC_KEY_ARM2_NOTIFY received. type = %d, data[0]= %d\n",
  49. 245 received_rvc_data.type, received_rvc_data.data[0]);
  50. 246 event = kzalloc(sizeof(*event), GFP_KERNEL);
  51. 247 if (!event) {
  52. 248 BACKCAR_LOG(BACKCAR_ERR, "kzalloc failed \n");
  53. 249 break;
  54. 250 }
  55. 251 memset(&(event->data), 0, sizeof(struct rvc_data));
  56. 252 memcpy(&(event->data), arm2_msg, ipcMSG_LENGTH);
  57. 253 mutex_lock(&g_event_manager.event_mutex);
  58. 254 list_add_tail(&event->list, &g_event_manager.notify_event_list);
  59. 255 mutex_unlock(&g_event_manager.event_mutex);
  60. 256 wake_up(&g_event_manager.event_queue_wait);
  61. 257 } else {
  62. 258 BACKCAR_LOG(BACKCAR_INFO, "ipc not receive request msg \n");
  63. 259 break;
  64. 260 }
  65. 261 }
  66. 262 msleep(1);
  67. 263 } while (!kthread_should_stop());
  68. 264
  69. 265 BACKCAR_LOG(BACKCAR_INFO, "backcar_ipc_receive_thread leave \n");
  70. 266 return 0;
  71. 267 }
  72. 268 #endif

IPC send

  1. 102 static long ipc_send_msg(const char* msg)
  2. 103 {
  3. 104 int ret = 0;
  4. 105 if (!g_ipc_send_chan) {
  5. 106 BACKCAR_LOG(BACKCAR_INFO, "ipc send chan is null, request chan first.\n");
  6. 107 g_ipc_send_chan = ipc_request_chan_detailed(CORE_VEHICLE, MSGSEND, g_ipc_arm1_ap, g_ipc_arm2_apm);
  7. 108 if (!g_ipc_send_chan) {
  8. 109 BACKCAR_LOG(BACKCAR_ERR, "ipc request send chan fail\n");
  9. 110 return -EFAULT;
  10. 111 }
  11. 112 }
  12. 113
  13. 114 ret = ipc_sendmsg(g_ipc_send_chan, msg, ipcMSG_LENGTH);
  14. 115 if (ret < 0) {
  15. 116 BACKCAR_LOG(BACKCAR_ERR, "ipc send fail %d\n", ret);
  16. 117 return -EFAULT;
  17. 118 }
  18. 119 return 0;
  19. 120 }

  1. #define ipc_sendmsg(c, m, s) \
  2. 173 ({ \
  3. 174 int __rc = 0; \
  4. 175 preempt_disable(); \
  5. 176 ipc_write(c, m, s); \
  6. 177 __rc = ipc_send(c); \
  7. 178 preempt_enable(); \
  8. 179 __rc; \
  9. 180 })

更新msg_free

  1. 351 ssize_t ipc_write(ipc_chan_t *chan, const void *buf, size_t nbytes)352 {
  2. 353 unsigned long flags;
  3. 354 unsigned idx = 0;
  4. 355 ssize_t n = 0;
  5. 356
  6. 357 spin_lock_irqsave(&chan->lock, flags);
  7. 358 if (chan->msg_count == IPC_MSG_QUEUE_LEN) {
  8. 359 spin_unlock_irqrestore(&chan->lock, flags);
  9. 360 return 0;
  10. 361 }
  11. 362
  12. 363 idx = chan->msg_free;
  13. 364
  14. 365 n = nbytes < MAX_MSG_LEN ? nbytes : MAX_MSG_LEN;
  15. 366 chan->msg_data[idx].size = n;
  16. 367 chan->msg_data[idx].msg = (void *)buf;
  17. 368
  18. 369 pr_debug("[AIPC] ipc_write %s->%s, %s, %d, %u, %u\n", chan->sender, chan- >receiver,
  19. 370 (char *)(chan->msg_data[idx].msg), chan->msg_data[idx].size,
  20. 371 chan->msg_count, chan->msg_free);
  21. 372
  22. 373 chan->msg_count++;
  23. 374
  24. 375 if (idx == IPC_MSG_QUEUE_LEN - 1)
  25. 376 chan->msg_free = 0;
  26. 377 else
  27. 378 chan->msg_free++;
  28. 379
  29. 380 spin_unlock_irqrestore(&chan->lock, flags);
  30. 381
  31. 382 return n;
  32. 383 }
  33. 384
  34. 385 EXPORT_SYMBOL_GPL(ipc_write);

 获取chan msg 发送到ipc msg

  1. int ipc_send(ipc_chan_t *chan)
  2. 388 {
  3. 389 uint32_t n = 0;
  4. 390 uint8_t last_entry = 0;
  5. 391 ipc_chan_dev_t *dev = NULL;
  6. 392 ipc_msg_t *ipc_msg = NULL;
  7. 393 unsigned count = 0;
  8. 394 unsigned idx = 0;
  9. 395 unsigned long flags;
  10. 396
  11. 397 if (!chan || !(chan->dev)) {
  12. 398 pr_err("[AIPC] %s invalid chan\n", __func__);
  13. 399 return -EINVAL;
  14. 400 }
  15. 401
  16. 402 dev = chan->dev;
  17. 403
  18. 404 spin_lock_irqsave(&chan->lock, flags);
  19. 405 count = chan->msg_count;
  20. 406
  21. 407 while (count) {
  22. 408 if (ipc_hal_originator_not_full(dev->oid, dev->rid) == 0) {
  23. 409 pr_err("[AIPC] %s chan is full\n", __func__);
  24. 410 spin_unlock_irqrestore(&chan->lock, flags);
  25. 411 return -EBUSY;
  26. 412 }
  27. 413
  28. 414 last_entry = ipc_hal_originator_get_last_valid(dev->oid, dev->rid);
  29. 415 ipc_msg = (ipc_msg_t *) (dev->base_addr + last_entry * dev- >packet_size);
  30. 416
  31. 417 strncpy(ipc_msg->sender, chan->sender, 8);
  32. 418 strncpy(ipc_msg->receiver, chan->receiver, 8);
  33. 419
  34. 420 idx = chan->msg_free;
  35. 421 if (idx >= count)
  36. 422 idx -= count;
  37. 423 else
  38. 424 idx += IPC_MSG_QUEUE_LEN - count;
  39. 425
  40. 426 n = chan->msg_data[idx].size < MAX_MSG_LEN ? chan->msg_data[idx].size : MAX_MSG_LEN;
  41. 427 if (chan->msg_data[idx].msg && n) {
  42. 428 memcpy_toio(ipc_msg->msg, chan->msg_data[idx].msg, n);
  43. 429 } else { // NULL msg
  44. 430 n = 0;
  45. 431 }
  46. 432
  47. 433 ipc_msg->size = n;
  48. 434
  49. 435 wmb();
  50. 436
  51. 437 pr_debug("[AIPC] ipc_send %s->%s, %s, %d, %u, %u\n", chan->sender, chan->receiver,
  52. 438 (char *)(chan->msg_data[idx].msg), chan- >msg_data[idx].size,
  53. 439 chan->msg_count, chan->msg_free);
  54. 440
  55. 441 ipc_notify(dev);
  56. 442
  57. 443 chan->msg_count--;
  58. 444 count = chan->msg_count;
  59. 445 }
  60. 446
  61. 447 spin_unlock_irqrestore(&chan->lock, flags);
  62. 448
  63. 449 return n;
  64. 450 }
  65. 451
  66. 452 EXPORT_SYMBOL_GPL(ipc_send);

backcar 使用backcardrv ioctl 发送ipc msg

  1. 284 static long backcar_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  2. 285 {
  3. 286 void __user *argp = (void __user *)arg;
  4. 287 u_long size = 0;
  5. 288 int ret = 0;
  6. 289 unsigned gpio_value = 0;
  7. 290 struct rvc_solution_info rvc_solution;
  8. 291 #ifndef CONFIG_BACKCAR_NO_ARM2
  9. 292 wait_queue_head_t wait_queue_head;
  10. 293 DECLARE_WAITQUEUE(cur_wait_queue, current);
  11. 294 #endif
  12. 295
  13. 296 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
  14. 297
  15. 298 if (cmd & IOC_IN) {
  16. 299 if (!access_ok(VERIFY_READ, argp, size)) {
  17. 300 BACKCAR_LOG(BACKCAR_ERR, "backcar_ioctl(): error 1, so bc_failed\n");
  18. 301 return -EFAULT;
  19. 302 }
  20. 303 }
  21. 304
  22. 305 if (cmd & IOC_OUT) {
  23. 306 if (!access_ok(VERIFY_WRITE, argp, size)) {
  24. 307 BACKCAR_LOG(BACKCAR_ERR, "backcar_ioctl(): error 2, so bc_failed\n");
  25. 308 return -EFAULT;
  26. 309 }
  27. 310 }
  28. 311
  29. 312 switch(cmd){
  30. 313 case IOCTL_FSC_NOTIFY_APP_READY:
  31. 314 BACKCAR_LOG(BACKCAR_INFO,
  32. 315 "execute IOCTL_FSC_NOTIFY_APP_READY ioctl\n");
  33. 316 memset(&rvc_solution, 0, sizeof(struct rvc_solution_info));
  34. 317 if (!videoin_get_rvc_solution_info(&rvc_solution)) {
  35. 318 BACKCAR_LOG(BACKCAR_WARNING,
  36. 319 "get rvc solution info from metazone fail!");
  37. 320 }
  38. 321 if (RVC_SOLUTION_ARM2_ONLY != rvc_solution.solution) {
  39. 322 BACKCAR_LOG(BACKCAR_INFO, "wait arm2 exit start\n");
  40. 323 mutex_lock(&g_ioctl_mutex);
  41. 324 if (gArm2AlreadyExit) {
  42. 325 BACKCAR_LOG(BACKCAR_INFO, "wait arm2 already exit done\n");
  43. 326 mutex_unlock(&g_ioctl_mutex);
  44. 327 break;
  45. 328 }
  46. 329 #ifndef CONFIG_BACKCAR_NO_ARM2
  47. 330 init_waitqueue_head(&wait_queue_head);
  48. 331 add_wait_queue(&wait_queue_head, &cur_wait_queue);
  49. 332 g_ioctlwaitq = &wait_queue_head;
  50. 333 set_current_state(TASK_INTERRUPTIBLE);
  51. 334
  52. 335 BACKCAR_LOG(BACKCAR_INFO, "Inform Arm2, Arm1 Backcar apk is ready\n");
  53. 336 BACKCAR_LOG(BACKCAR_INFO, "send arm1 ready to arm2 start\n");
  54. 337 ipc_send_msg(cIpcMsgSendArm1BCReady);
  55. 338 BACKCAR_LOG(BACKCAR_INFO, "send arm1 ready to arm2 end\n");
  56. 339 BACKCAR_LOG(BACKCAR_INFO, "wait arm2 interrupt before schedule\n");
  57. 340 schedule();
  58. 341 BACKCAR_LOG(BACKCAR_INFO, "wait arm2 interrupt after schedule\n");
  59. 342
  60. 343 if (signal_pending(current)) {
  61. 344 BACKCAR_LOG(BACKCAR_WARNING, "interrupted by system signal\n");
  62. 345 ret = -ERESTARTSYS;
  63. 346 } else {
  64. 347 BACKCAR_LOG(BACKCAR_INFO, "wait arm2 interrupt done\n");
  65. 348 }
  66. 349
  67. 350 remove_wait_queue(&wait_queue_head, &cur_wait_queue);
  68. 351 set_current_state(TASK_RUNNING);
  69. 352 g_ioctlwaitq = NULL;
  70. 353 gArm2AlreadyExit = true;
  71. 354 #ifdef CONFIG_MEMBLK_RELEASE_POLICY
  72. 355 backcar_free_viss_reserve_mem("autochips,backcar_rt");
  73. 356 backcar_free_viss_reserve_mem("autochips,backcar_mrf");
  74. 357 #endif
  75. 358 #endif //CONFIG_BACKCAR_NO_ARM2
  76. 359 }
  77. 360 videoin_dma_config();
  78. 361 BACKCAR_LOG(BACKCAR_INFO, "videoin_dma_config have successfully\n");
  79. 362
  80. 363 mutex_unlock(&g_ioctl_mutex);
  81. 364 BACKCAR_LOG(BACKCAR_INFO, "wait arm2 exit done\n");
  82. 365 break;
  83. 366 case IOCTL_BC_GPIOINIT:
  84. 367 GPIO_Init();
  85. 368 BACKCAR_LOG(BACKCAR_INFO, "init GPIO success!\n");
  86. 369 break;
  87. 370 case IOCTL_BC_DETECTGPIO:
  88. 371 gpio_value = GPIO_Get_value();
  89. 372 ret = copy_to_user(argp, &gpio_value, sizeof(gpio_value));
  90. 373 if (ret != 0) {
  91. 374 BACKCAR_LOG(BACKCAR_ERR, "copy gpio status to userspace bc_failed\n");
  92. 375 }
  93. 376 break;
  94. 377 case IOCTL_BC_FORCE_STOP_ARM2:
  95. 378 backcar_force_stop_arm2();
  96. 379 break;
  97. 380 case IOCTL_BC_NOTIFY_VBA_EXIT:
  98. 381 #ifndef CONFIG_BACKCAR_NO_ARM2
  99. 382 BACKCAR_LOG(BACKCAR_INFO, "Send MSG_IPC %s\n", cIpcMsgSendVbaExit);
  100. 383 ret = ipc_send_msg(cIpcMsgSendVbaExit);
  101. 384 if (ret < 0) {
  102. 385 BACKCAR_LOG(BACKCAR_ERR, "IPC Request Send failed\n");
  103. 386 }
  104. 387 #endif
  105. 388 break;
  106. 389 case IOCTL_BC_NOTIFY_AUDIO_MUTE:
  107. 390 #ifndef CONFIG_BACKCAR_NO_ARM2
  108. 391 {
  109. 392 unsigned mute = 0;
  110. 393 const char *muteMsg = NULL;
  111. 394 if (get_user(mute, (unsigned __user *)arg)) {
  112. 395 BACKCAR_LOG(BACKCAR_INFO, "get_user error\n");
  113. 396 ret = -EFAULT;
  114. 397 break;
  115. 398 }
  116. 399 muteMsg = mute ? cIpcMsgRcvArm2AudioMute : cIpcMsgRcvArm2AudioUnMute;
  117. 400 BACKCAR_LOG(BACKCAR_INFO, "Send MSG_IPC %s\n", muteMsg);
  118. 401 ret = ipc_send_msg(muteMsg);
  119. 402 if (ret < 0) {
  120. 403 BACKCAR_LOG(BACKCAR_ERR, "IPC Request Send failed\n");
  121. 404 }
  122. 405 }
  123. 406 #endif
  124. 407 break;
  125. 408 case IOCTL_MCU_BC_START_SUCCESS:
  126. 409 if (!gpio_is_valid(backcar_mcu_gpio_num)) {
  127. 410 BACKCAR_LOG(BACKCAR_ERR, "get backcar mcu notify gpio number bc_failed\n");
  128. 411 } else {
  129. 412 gpio_direction_output(backcar_mcu_gpio_num, BACKCAR_NOTIFY_MCU_GPIO_HIGH);
  130. 413 gpio_set_value_cansleep(backcar_mcu_gpio_num, BACKCAR_NOTIFY_MCU_GPIO_HIGH);
  131. 414 BACKCAR_LOG(BACKCAR_INFO, "MCU Test: current gpio number = %d, gpio value = %d\n", backcar_mcu_gpio_num, gpio_get_value(backcar_mcu_gpio_num));
  132. 415 }
  133. 416 break;
  134. 417 case IOCTL_MCU_BC_START_STOP:
  135. 418 if (!gpio_is_valid(backcar_mcu_gpio_num)) {
  136. 419 BACKCAR_LOG(BACKCAR_ERR, "get backcar mcu notify gpio number bc_failed\n");
  137. 420 } else {
  138. 421 gpio_direction_output(backcar_mcu_gpio_num, BACKCAR_NOTIFY_MCU_GPIO_LOW);
  139. 422 gpio_set_value_cansleep(backcar_mcu_gpio_num, BACKCAR_NOTIFY_MCU_GPIO_LOW);
  140. 423 BACKCAR_LOG(BACKCAR_INFO, "MCU Test: current gpio number = %d, gpio value = %d\n", backcar_mcu_gpio_num, gpio_get_value(backcar_mcu_gpio_num));
  141. 424 }
  142. 425 break;
  143. 426 case IOCTL_GET_RVC_DATA_FROM_ARM2:
  144. 427 case IOCTL_SET_RVC_DATA_TO_ARM2:
  145. 428 #ifndef CONFIG_BACKCAR_NO_ARM2
  146. 429 {
  147. 430 struct rvc_data data;
  148. 431 int wait_time = 0;
  149. 432 mutex_lock(&g_ioctl_mutex);
  150. 433 memset(&data, 0, sizeof(struct rvc_data));
  151. 434 if (copy_from_user(&data, argp, sizeof(struct rvc_data ))) {
  152. 435 BACKCAR_LOG(BACKCAR_ERR, "copy_from_user error\n");
  153. 436 ret = -EFAULT;
  154. 437 mutex_unlock(&g_ioctl_mutex);
  155. 438 break;
  156. 439 }
  157. 440 if ((0 == strcmp(data.ipc_key, RVC_IPC_KEY_GET_DATA)) ||
  158. 441 (0 == strcmp(data.ipc_key, RVC_IPC_KEY_SET_DATA))) {
  159. 442 BACKCAR_LOG(BACKCAR_DEBUG, "ipc_key(%s), data_type(%d)\n", data.ipc_key, data.type);
  160. 443 } else {
  161. 444 BACKCAR_LOG(BACKCAR_ERR, "ipc_key(%s) is invalid\n", data.ipc_key);
  162. 445 ret = -EFAULT;
  163. 446 mutex_unlock(&g_ioctl_mutex);
  164. 447 break;
  165. 448 }
  166. 449 memset(&g_responsed_rvc_data, 0, sizeof(struct rvc_data));
  167. 450 ret = ipc_send_msg((const char *)&data);
  168. 451 if (ret < 0) {
  169. 452 BACKCAR_LOG(BACKCAR_ERR, "IPC Request Send failed\n");
  170. 453 ret = -EFAULT;
  171. 454 mutex_unlock(&g_ioctl_mutex);
  172. 455 break;
  173. 456 }
  174. 457 // wait arm2 response
  175. 458 msleep(50);
  176. 459 while (0 != strcmp(g_responsed_rvc_data.ipc_key, RVC_IPC_KEY_ARM2_RESPOND)
  177. 460 && (wait_time < 500)) {
  178. 461 msleep(20);
  179. 462 wait_time += 20;
  180. 463 }
  181. 464 if (500 == wait_time) {
  182. 465 BACKCAR_LOG(BACKCAR_ERR, "wait arm2 response time out\n");
  183. 466 ret = -EFAULT;
  184. 467 mutex_unlock(&g_ioctl_mutex);
  185. 468 break;
  186. 469 }
  187. 470
  188. 471 BACKCAR_LOG(BACKCAR_DEBUG, "get rvc data success:ipc_key:%s, type:%d, data[%d, %d, %d, %d]\n",
  189. 472 g_responsed_rvc_data.ipc_key, g_responsed_rvc_data.type,
  190. 473 g_responsed_rvc_data.data[0], g_responsed_rvc_data.data[1],
  191. 474 g_responsed_rvc_data.data[2], g_responsed_rvc_data.data[3]);
  192. 475 if (g_responsed_rvc_data.type != data.type) {
  193. 476 BACKCAR_LOG(BACKCAR_ERR, "data type is not match. request(%d), receive(%d)\n",
  194. 477 data.type, g_responsed_rvc_data.type);
  195. 478 ret = -EFAULT;
  196. 479 mutex_unlock(&g_ioctl_mutex);
  197. 480 break;
  198. 481 }
  199. 482
  200. 483 if (copy_to_user(argp, &g_responsed_rvc_data, sizeof(struct rvc_data))) {
  201. 484 BACKCAR_LOG(BACKCAR_ERR, "copy_to_user error\n");
  202. 485 ret = -EFAULT;
  203. 486 mutex_unlock(&g_ioctl_mutex);
  204. 487 break;
  205. 488 }
  206. 489 mutex_unlock(&g_ioctl_mutex);
  207. 490 }
  208. 491 #endif
  209. 492 break;
  210. 493 default:
  211. 494 BACKCAR_LOG(BACKCAR_WARNING, "this ioctl(%d) is not supported", cmd);
  212. 495 ret = -1;
  213. 496 break;
  214. 497 }
  215. 498
  216. 499 return ret;
  217. 500 }

vendor/autochips/proprietary/hardware/backcar/backcar/src/BackcarImpl.cpp

  1. bool BackcarImpl::waitArm2Exit()
  2. 309 {
  3. 310 BACKCAR_LOGI("enter");
  4. 311 unsigned int status = 0;
  5. 312 int ret = ::ioctl(mBackcarFd, IOCTL_FSC_NOTIFY_APP_READY, &status);
  6. 313 if (ret < 0) {
  7. 314 BACKCAR_LOGE("execute IOCTL_FSC_NOTIFY_APP_READY failed, and error message is %s",strerror(errno));
  8. 315 return false;
  9. 316 }
  10. 317 BACKCAR_LOGI("leave arm2 status is %d", status);
  11. 318
  12. 319 return true;
  13. 320 }

RVC  hal 层

/autochips/proprietary/hardware/backcar/backcar/src/BackcarImpl.cpp

define BACKCAR_DRIVER_NAME "/dev/backcardrv"

  1. 54 BackcarImpl::BackcarImpl():
  2. 55 mBackcarFd(-1),
  3. 56 mArm2Status(ARM2_RVC_STATUS_RUNNING),
  4. 57 mBackcarEnable(0),
  5. 58 mProcessThread(nullptr),
  6. 59 mRvcDataThread(nullptr)
  7. 60 {
  8. 61 BACKCAR_LOGI("enter");
  9. 62 Mutex::Autolock _l(mLock);
  10. //open backcardrv
  11. 63 mBackcarFd = ::open(BACKCAR_DRIVER_NAME, O_RDWR | O_NONBLOCK);
  12. 64 if (mBackcarFd < 0) {
  13. 65 BACKCAR_LOGE("open %s fail. %s", BACKCAR_DRIVER_NAME, strerror(errno));
  14. 66 return;
  15. 67 } else {
  16. 68 BACKCAR_LOGI("open success %d ", mBackcarFd);
  17. 69 }
  18. 70 //获取RVC的metazone的配置信息
  19. 71 mRvcSolution = getRVCSolutionType();
  20. 72 switch (mRvcSolution) {
  21. 73 case RVC_SOLUTION_ARM2_WITH_ARM1:
  22. 74 mProcessThread = new FunctionThread(std::bind(&BackcarImpl::mainThreadLoop, this));
  23. 75 mProcessThread->run("mainThreadLoop");
  24. 76 BACKCAR_LOGI("rvc solution is arm1 with arm2 rvc. run mainThreadLoop");
  25. 77 break;
  26. 78 case RVC_SOLUTION_AVM:
  27. 79 buttonInit();
  28. 80 mArm2Status = ARM2_RVC_STATUS_EXIT;
  29. 81 mProcessThread = new FunctionThread(std::bind(&BackcarImpl::mainThreadLoop, this));
  30. 82 mProcessThread->run("mainThreadLoop");
  31. 83 BACKCAR_LOGI("rvc solution is avm. run mainThreadLoop");
  32. 84 break;
  33. 85 case RVC_SOLUTION_ARM2_ONLY:
  34. 86 mRvcDataThread = new FunctionThread(std::bind(&BackcarImpl::rvcDataThreadLoop, this));
  35. 87 mRvcDataThread->run("rvcDataThreadLoop");
  36. 88 BACKCAR_LOGI("rvc solution is arm2 rvc only. run rvcDataThreadLoop");
  37. 89 break;
  38. 90 default:
  39. 91 break;
  40. 92 }
  41. 93 BACKCAR_LOGI("leave");
  42. 94 }

通过metazone 获取METAZONE_BACKCAR_VDO_SOURCE的值

  1. 734 int BackcarImpl::getRVCSolutionType()
  2. 735 {
  3. 736 unsigned int metazoneValue = 0;
  4. 737 int rvcSolution = -1;
  5. 738 if (MZ_SUCCESS == ::MetaZone_Init()) {
  6. 739 if (MZ_SUCCESS == ::MetaZone_Read(METAZONE_BACKCAR_VDO_SOURCE, &metazoneValue)) {
  7. 740 auto source = (unsigned char *)(&metazoneValue);
  8. 741 rvcSolution = source[METAZONE_RVC_SOLUTION_BYTE_INDEX];
  9. 742 } else {
  10. 743 BACKCAR_LOGW("MetaZone_Read(METAZONE_SOURCE_MODE) fail.");
  11. 744 }
  12. 745 ::MetaZone_Deinit();
  13. 746 } else {
  14. 747 BACKCAR_LOGE("metazone init failed\n");
  15. 748 }
  16. 749
  17. 750 BACKCAR_LOGI("get rvc solution type(%d) success", rvcSolution);
  18. 751 return rvcSolution;
  19. 752 }
  20. 753

通过backcardrv文件节点获取msg

  1. #define SELECT_TIMEOUT 5000 //ms
  2. 191 bool BackcarImpl::rvcDataThreadLoop()
  3. 192 {
  4. 193 int ret = 0;
  5. 194 RVCData halData;
  6. 195 struct rvc_data drvData;
  7. 196 struct timeval tv;
  8. 197 fd_set rd_set;
  9. 198
  10. 199 do {
  11. 200 memset(&halData, 0, sizeof(RVCData));
  12. 201 memset(&drvData, 0, sizeof(struct rvc_data));
  13. 202 memset(&tv, 0, sizeof(tv));
  14. 203 tv.tv_sec = SELECT_TIMEOUT / 1000;
  15. 204 tv.tv_usec = (SELECT_TIMEOUT % 1000) * 1000;
  16. 205 FD_ZERO(&rd_set);
  17. 206 FD_SET(mBackcarFd, &rd_set);
  18. 207 if (!FD_ISSET(mBackcarFd, &rd_set)) {
  19. 208 BACKCAR_LOGE("FD_ISSET fail. error %s", strerror(errno));
  20. 209 break;
  21. 210 }
  22. 211 ret = select(mBackcarFd + 1, &rd_set, nullptr, nullptr, &tv);
  23. 212 if (ret < 0) {
  24. 213 BACKCAR_LOGE("select fail. error %s", strerror(errno));
  25. 214 } else if (ret == 0) {
  26. 215 BACKCAR_LOGD("select timeout. ");
  27. 216 } else {
  28. 217 read(mBackcarFd, (char *)&drvData, sizeof(struct rvc_data));
  29. 218 if (0 == strcmp(drvData.ipc_key, RVC_IPC_KEY_ARM2_NOTIFY)) {
  30. 219 halData.type = (RVCDataType)drvData.type;
  31. 220 halData.data[0] = drvData.data[0];
  32. 221 halData.data[1] = drvData.data[1];
  33. 222 halData.data[2] = drvData.data[2];
  34. 223 halData.data[3] = drvData.data[3];
  35. 224 BACKCAR_LOGI("type: %d, data: [%d, %d, %d, %d]", drvData.type, drvData.data[0], drvData.data[1], drvData.data[2], drvData.data[3]);
  36. 225 rvcDataChangeNotify(halData);
  37. 226 if (RVC_DATA_RVC_STATUS == drvData.type) {
  38. 227 mBackcarEnable = drvData.data[0];
  39. 228 }
  40. 229 }
  41. 230 }
  42. 231 usleep(1000000 / 100);
  43. 232 } while (0);
  44. 233
  45. 234 return true;
  46. 235 }

 arm 2 上的rtos 获取倒车的gpio的信息通过backcar驱动解析后将event事件挂在notify_event_list

  1. #ifndef CONFIG_BACKCAR_NO_ARM2
  2. 202 static int backcar_ipc_receive_thread(void *data)203 {
  3. 204 int ret = 0;
  4. 205 char arm2_msg[ipcMSG_LENGTH] = {0,};
  5. 206 struct rvc_data received_rvc_data;
  6. 207 struct arm2_rvc_event *event = NULL;
  7. 208 BACKCAR_LOG(BACKCAR_INFO, "backcar_ipc_receive_thread start\n");
  8. 209
  9. 210 do {
  10. 211 if (!g_ipc_receive_chan) {
  11. 212 BACKCAR_LOG(BACKCAR_INFO, "ipc receive chan is null, request chan first.\n");
  12. 213 g_ipc_receive_chan = ipc_request_chan_detailed(CORE_VEHICLE, MSGRECV, g_ipc_arm2_rvc, g_ipc_arm1_ap);
  13. 214 if (!g_ipc_receive_chan) {
  14. 215 BACKCAR_LOG(BACKCAR_ERR, "ipc request receive chan fail\n");
  15. 216 continue;
  16. 217 }
  17. 218 }
  18. 219
  19. 220 memset(arm2_msg, 0, sizeof(arm2_msg));
  20. 221 ret = ipc_receivemsg(g_ipc_receive_chan, arm2_msg, ipcMSG_LENGTH);
  21. 222 if (ret < 0) {
  22. 223 BACKCAR_LOG(BACKCAR_ERR, "ipc receive fail %d\n", ret);
  23. 224 continue;
  24. 225 }
  25. 226
  26. 227 BACKCAR_LOG(BACKCAR_DEBUG, "ipc receive arm2_msg %s\n", arm2_msg);
  27. 228 if (!strncmp(cIpcMsgRcvArm2BCExit, arm2_msg, ipcMSG_LENGTH)) {
  28. 229 BACKCAR_LOG(BACKCAR_INFO, "backcar receive msg %s success \n", cIpcMsgRcvArm2BCExit);
  29. 230 if (NULL != g_ioctlwaitq) {
  30. 231 wake_up(g_ioctlwaitq);
  31. 232 } else {
  32. 233 BACKCAR_LOG(BACKCAR_WARNING, "g_ioctl waitq has been waked. but not by arm2 msg\n");
  33. 234 }
  34. 235 } else {
  35. 236 memset(&received_rvc_data, 0, sizeof(struct rvc_data));
  36. 237 memcpy(&received_rvc_data, arm2_msg, ipcMSG_LENGTH);
  37. 238 if (0 == strcmp(received_rvc_data.ipc_key, RVC_IPC_KEY_ARM2_RESPOND)) {
  38. 239 BACKCAR_LOG(BACKCAR_DEBUG, "RVC_IPC_KEY_ARM2_NOTIFY received. type = %d, data[0]= %d\n",
  39. 240 received_rvc_data.type, received_rvc_data.data[0]);
  40. 241 memset(&g_responsed_rvc_data, 0, sizeof(struct rvc_data));
  41. 242 memcpy(&g_responsed_rvc_data, arm2_msg, ipcMSG_LENGTH);
  42. 243 } else if (0 == strcmp(received_rvc_data.ipc_key, RVC_IPC_KEY_ARM2_NOTIFY)) {
  43. //解析小核 arm2 RTOS的 ipc msg
  44. 244 BACKCAR_LOG(BACKCAR_INFO, "RVC_IPC_KEY_ARM2_NOTIFY received. type = %d, data[0]= %d\n",
  45. 245 received_rvc_data.type, received_rvc_data.data[0]);
  46. 246 event = kzalloc(sizeof(*event), GFP_KERNEL);
  47. 247 if (!event) {
  48. 248 BACKCAR_LOG(BACKCAR_ERR, "kzalloc failed \n");
  49. 249 break;
  50. 250 }
  51. //将arm2 msg 填充event data
  52. 251 memset(&(event->data), 0, sizeof(struct rvc_data));
  53. 252 memcpy(&(event->data), arm2_msg, ipcMSG_LENGTH);
  54. 253 mutex_lock(&g_event_manager.event_mutex);
  55. //将event list 挂到notify_event_list
  56. 254 list_add_tail(&event->list, &g_event_manager.notify_event_list);
  57. 255 mutex_unlock(&g_event_manager.event_mutex);
  58. 256 wake_up(&g_event_manager.event_queue_wait);
  59. 257 } else {
  60. 258 BACKCAR_LOG(BACKCAR_INFO, "ipc not receive request msg \n");
  61. 259 break;
  62. 260 }
  63. 261 }
  64. 262 msleep(1);
  65. 263 } while (!kthread_should_stop());
  66. 264
  67. 265 BACKCAR_LOG(BACKCAR_INFO, "backcar_ipc_receive_thread leave \n");
  68. 266 return 0;
  69. 267 }
  70. 268 #endif

arm ap 侧使用驱动read的接口获取backcardrv arm2 的msg

  1. static ssize_t backcar_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
  2. 534 {
  3. 535 int ret = 0;
  4. 536 struct arm2_rvc_event *event = NULL;
  5. 537 if (!access_ok(VERIFY_WRITE, buf, count))
  6. 538 return -EFAULT;
  7. 539
  8. 540 mutex_lock(&g_event_manager.event_mutex);
  9. 541 if (!list_empty(&g_event_manager.notify_event_list)) {
  10. 542 event = list_first_entry(&g_event_manager.notify_event_list, struct arm2_rvc_event, list);
  11. 543 if (!event) {
  12. 544 BACKCAR_LOG(BACKCAR_ERR, "event is null.\n");
  13. 545 mutex_unlock(&g_event_manager.event_mutex);
  14. 546 return -EFAULT;
  15. 547 }
  16. 548 //获取rvc event data
  17. 549 BACKCAR_LOG(BACKCAR_INFO, "event read: type(%d) ", event->data.type);
  18. 550 if (copy_to_user(buf, &event->data, sizeof(struct rvc_data))) {
  19. 551 BACKCAR_LOG(BACKCAR_ERR, "copy_to_user error\n");
  20. 552 ret = -EFAULT;
  21. 553 }
  22. 554 list_del(&event->list);
  23. 555 kfree(event);
  24. 556 }
  25. 557 mutex_unlock(&g_event_manager.event_mutex);
  26. 558
  27. 559 return ret;
  28. 560 }

hal层rvcDataChangeNotify将回调java注册callback函数

  1. 258 void BackcarImpl::rvcDataChangeNotify(RVCData rvcData)
  2. 259 {
  3. 260 BACKCAR_LOGI("enter. type: %d, data: [%d, %d, %d, %d]",
  4. 261 rvcData.type, rvcData.data[0], rvcData.data[1], rvcData.data[2], rvcData.data[3]);
  5. 262 std::map<const sp<IBackcarCallback>,std::vector<EventType>>::iterator cb_iter;
  6. 263
  7. 264 for (cb_iter = mCallbackMap.begin(); cb_iter != mCallbackMap.end(); cb_iter++) {
  8. 265 const sp<IBackcarCallback>& callback = cb_iter->first;
  9. 266 std::vector<EventType>& evts = cb_iter->second;
  10. 267 for (std::vector<EventType>::iterator iter = evts.begin(); iter != evts.end(); iter++) {
  11. 268 if (*iter == EventType::RVC_DATA_CHANGE) {
  12. //回调java层callback的rvcDataChangeNotify
  13. 269 auto callbackRet = callback->rvcDataChangeNotify(rvcData);
  14. 270 if (!callbackRet.isOk()) {
  15. 271 BACKCAR_LOGE("Callback rvcDataChangeNotify error");
  16. 272 }
  17. 273 break;
  18. 274 }
  19. 275 }
  20. 276 }
  21. 277 BACKCAR_LOGI("leave");
  22. 278 }

 java层backcar service 注册hal 回调函数

vendor/autochips/proprietary/frameworks/base/backcar/java/com/autochips/backcar/BackCar.java

  1. /**
  2. 191 * Construct for RVC
  3. 192 * @param looper handler using this looper
  4. 193 */
  5. 194 public BackCar(Looper looper) {
  6. 195 Log.d(TAG, "RVC() enter");
  7. 196
  8. 197 if (null == looper) {
  9. 198 looper = Looper.myLooper();
  10. 199 if (null == looper) {
  11. 200 looper = Looper.getMainLooper();
  12. 201 }
  13. 202 }
  14. 203
  15. 204 mHandler = new EventHandler(looper);
  16. 205 mCallback = new BackcarCallback();
  17. 206 mDeathRecipient = new DeathRecipient();
  18. 207
  19. 208 try {
  20. 209 mService = IBackcar.getService();
  21. 210 mService.linkToDeath(mDeathRecipient, 0);
  22. 211 } catch (RemoteException e) {
  23. 212 Log.e(TAG, "getService() failure");
  24. 213 e.printStackTrace();
  25. 214 mService = null;
  26. 215 }
  27. 216
  28. 217 Log.d(TAG, "RVC() leave");
  29. 218 }

  1. /saic_cn202sr/vendor/autochips/proprietary/frameworks/base/backcar/java/com/autochips/backcar/BackCar.java
  2. /**
  3. 221 * Set event listener
  4. 222 * @param listener listener object, can be null
  5. 223 * @param evts all event type for listening
  6. 224 * @return true is success, false is fail.
  7. 225 */
  8. 226 public boolean setListener(Listener listener, ArrayList<Integer> evts) {
  9. 227 Log.d(TAG, "setListener() enter");
  10. 228
  11. 229 if (null == mService) {
  12. 230 Log.e(TAG, "mService = null");
  13. 231 return false;
  14. 232 }
  15. 233
  16. 234 mListener = listener;
  17. 235 mEvts = evts;
  18. 236 int status = Status.FAILURE;
  19. 237
  20. 238 try {
  21. 239 if ((null != mListener) && (null != evts)){
  22. 240 mService.registerEventCallback_V2(mCallback, evts, new IBackcar.registerEventCallback_V2Callback() {
  23. 241 @Override
  24. 242 public void onValues(int Status, long callbackId) {
  25. 243 mCallbackId[0] = callbackId;
  26. 244 }
  27. 245 });
  28. 246 } else {
  29. 247 status = mService.unregisterEventCallback_V2(mCallbackId[0]);
  30. 248 }
  31. 249 status = Status.SUCCESS;
  32. 250 } catch (RemoteException e) {
  33. 251 Log.e(TAG, "call registerEventCallback()/unregisterEventCallback() failure");
  34. 252 e.printStackTrace();
  35. 253 status = Status.FAILURE;
  36. 254 }
  37. 255
  38. 256 Log.d(TAG, "setListener() leave");
  39. 257 return (Status.SUCCESS == status);
  40. 258 }
  41. 259

  1. 445 Return<void> BackcarImpl::registerEventCallback_V2(const sp<IBackcarCallback>& callback, const hidl_vec<EventType>& evts, registerEventCallback_V2_cb _hidl_cb) {
  2. 446 Mutex::Autolock _l(mLock);
  3. 447 BACKCAR_LOGI("enter callback = %p, evts.size() = %d", callback.get(), (int)evts.size());
  4. 448
  5. 449 if (mBackcarFd < 0) {
  6. 450 _hidl_cb(Status::FAILURE, 0);
  7. 451 return Void();
  8. 452 }
  9. 453
  10. 454 if (nullptr == callback.get() || 0 == evts.size()) {
  11. 455 BACKCAR_LOGE("Invalid param callback = %p, evts.size() = %d", callback.get(), (int)evts.size());
  12. 456 _hidl_cb(Status::FAILURE, 0);
  13. 457 return Void();
  14. 458 }
  15. 459
  16. 460 mCallbackMap[callback] = evts;
  17. 461
  18. 462 callback->linkToDeath(this, 888);
  19. 463
  20. 464 afterRegisterRun(callback);
  21. 465
  22. 466 BACKCAR_LOGI("leave");
  23. 467 _hidl_cb(Status::SUCCESS, (uint64_t)callback.get());
  24. 468 return Void();
  25. 469 }
  1. 344 void BackcarImpl::afterRegisterRun(const sp<IBackcarCallback>& callback)
  2. 345 {
  3. 346 BACKCAR_LOGI("enter");
  4. 347 if (ARM2_RVC_STATUS_EXIT == mArm2Status) {
  5. 348 std::vector<EventType>& evts = mCallbackMap[callback];
  6. 349 for (std::vector<EventType>::iterator iter = evts.begin(); iter != evts.end(); iter++) {
  7. 350 if (*iter == EventType::ARM2EXIT) {
  8. 351 auto callbackRet = callback->eventNotify(EventType::ARM2EXIT, 0, 0, 0);
  9. 352 if (!callbackRet.isOk()) {
  10. 353 BACKCAR_LOGE("Callback eventNotify error");
  11. 354 }
  12. 355 break;
  13. 356 }
  14. 357 }
  15. 358 }
  16. 359
  17. 360 switch (mRvcSolution) {
  18. 361 case RVC_SOLUTION_ARM2_WITH_ARM1:
  19. 362 case RVC_SOLUTION_AVM:
  20. 363 if (mBackcarEnable) {
  21. 364 BACKCAR_LOGI("rvc button already on");
  22. 365 std::vector<EventType>& evts = mCallbackMap[callback];
  23. 366 for (std::vector<EventType>::iterator iter = evts.begin(); iter != evts.end(); iter++) {
  24. 367 if (*iter == EventType::BC) {
  25. 368 auto callbackRet = callback->eventNotify(EventType::BC, 1, 0, 0);
  26. 369 if (!callbackRet.isOk()) {
  27. 370 BACKCAR_LOGE("Callback eventNotify error");
  28. 371 }
  29. 372 break;
  30. 373 }
  31. 374 }
  32. 375 }
  33. 376 break;
  34. 377 case RVC_SOLUTION_ARM2_ONLY:
  35. 378 {
  36. 379 RVCData halData;
  37. 380 if (__getRVCDataFromArm2(RVCDataType::RVC_DATA_RVC_STATUS, halData)) {
  38. 381 if (1 == halData.data[0]) {
  39. 382 rvcDataChangeNotify(halData);
  40. 383 }
  41. 384 }
  42. 385 }
  43. 386 break;
  44. 387 default:
  45. 388 break;
  46. 389 }
  47. 390
  48. 391 BACKCAR_LOGI("leave");
  49. 392 }

backcar service  callbac函数 sendmsg EVENT_TYPE_RVC_DATA_CHANGE给app 

  1. private class BackcarCallback extends IBackcarCallback.Stub {
  2. 169 public void eventNotify(int evt, int param1, int param2, int param3) {
  3. 170 Log.d(TAG, "eventNotify() enter evt = " + evt + ", param1 = " + param1);
  4. 171 mHandler.sendMessage(Message.obtain(mHandler, evt, param1, param2));
  5. 172 Log.d(TAG, "eventNotify() leave");
  6. 173 }
  7. 174
  8. 175 public void rvcDataChangeNotify(vendor.autochips.hardware.backcar.V1_0.RVCData hidlRVCData) {
  9. 176 Log.d(TAG, "rvcDataChangeNotify() enter rvcDataType =" + hidlRVCData.type + ", data = [" + hidlRVCData.data[0]
  10. 177 + ", " + hidlRVCData.data[1] + ", " + hidlRVCData.data[2] + ", " + hidlRVCData.data[3] + "]" );
  11. 178 mHandler.sendMessage(Message.obtain(mHandler, EVENT_TYPE_RVC_DATA_CHANGE, hidlRVCData.type, hidlRVCData.data[0]));
  12. 179 Log.d(TAG, "rvcDataChangeNotify() leave");
  13. 180 }
  14. 181 }

触发app start RVC

  1. /vendor/autochips/proprietary/packages/apps/AtcCamera/src/com/autochips/camera/CameraService.java
  2. public class CameraService extends Service{
  3. 38 private static final String TAG = "CameraService";
  4. 39
  5. 40 private CameraServiceImpl mCameraServiceImpl;
  6. 41
  7. 42 private static final String ACTION_QB_OFF = "autochips.intent.action.QB_POWEROFF";
  8. 43 private static final String ACTION_QB_ON = "autochips.intent.action.QB_POWERON";
  9. 44 private static final String ACTION_PREQB_ON =
  10. "autochips.intent.action.PREQB_POWERON";
  11. 45 private static final String ACTION_PREQB_OFF =
  12. "autochips.intent.action.PREQB_POWEROFF";
  13. 46 private static final String NOTIFICATION_CHANNEL_ID_SERVICE =
  14. "com.autochips.camera.CameraService";
  15. 47 private static final int NOTIFICATION_ID = 105;
  16. 48 private static final int BC_TYPE_ADDR =
  17. MetazoneIndex.DwordIndex.METAZONE_BACKCAR_VDO_SOURCE;
  18. 49 private static final int ADDR_RVC_CAMERA_ID =
  19. MetazoneIndex.DwordIndex.METAZONE_RVC_AVM_CAMERA_ID;
  20. 50 private static final int TYPE_RVC = 0;
  21. 51
  22. 52 private BackCar mBackcar;
  23. 53 private String mCurrentBackcarCameraId;
  24. 54 private boolean mIsArm2Exited;
  25. 55 private boolean mIsQBOn = true;
  26. 56 private boolean mNeedStartBackcarAfterQBOn;
  27. 57 private boolean mHasShownTouchInputFilterView;
  28. 58 private boolean mhasEnableBackcarAudio = false;
  29. 59 private boolean mIsBackcarOn = false;
  30. 60 private boolean mIsRVCMode = false;
  31. 61 private int mCurrentUserId = UserHandle.myUserId();
  32. 62 private final Thread.UncaughtExceptionHandler mDefaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
  33. 63 private Handler mHandler = new Handler();
  34. 64
  35. 65 private BackCar.Listener mListenerSignal = new BackCar.Listener() {
  36. 66 public void onEvent(int event, int param1, int param2) {
  37. 67 LogUtil.d(TAG,"onSignal - event:" + event);
  38. 68 if (BackCar.EVENT_TYPE_BC == event) {
  39. 69 if (param1 != 0) {
  40. 70 LogUtil.i(TAG,"onSignal():BACKCAR_START");
  41. 71 if (!mhasEnableBackcarAudio) {
  42. 72 mCameraServiceImpl.enableBackcarAudio();
  43. 73 mhasEnableBackcarAudio = true;
  44. 74 }
  45. 75
  46. 76 if (!mIsArm2Exited && !mHasShownTouchInputFilterView) {
  47. 77 mCameraServiceImpl.showTouchInputFilterView();
  48. 78 mHasShownTouchInputFilterView = true;
  49. 79 return;
  50. 80 }
  51. 81 if (!mIsQBOn) {
  52. 82 mNeedStartBackcarAfterQBOn = true;
  53. 83 LogUtil.d(TAG, "start backcar later after qb on");
  54. 84 return;
  55. 85 }
  56. 86 if (mCurrentUserId == UserHandle.myUserId() && getBackcarCameraId()) {
  57. 87 mCameraServiceImpl.startBackcar(mCurrentBackcarCameraId);
  58. 88 }
  59. 89 mIsBackcarOn = true;
  60. 90 }else {
  61. 91 LogUtil.i(TAG,"onSignal():BACKCAR_STOP");
  62. 92 if (mhasEnableBackcarAudio) {
  63. 93 mCameraServiceImpl.disableBackcarAudio();
  64. 94 mhasEnableBackcarAudio = false;
  65. 95 }
  66. 96
  67. 97 if (mNeedStartBackcarAfterQBOn) {
  68. 98 mNeedStartBackcarAfterQBOn = false;
  69. 99 LogUtil.d(TAG, "cancel stop backcar");
  70. 100 return;
  71. 101 }
  72. 102 if (mCurrentBackcarCameraId != null) {
  73. 103 mCameraServiceImpl.stopBackcar(mCurrentBackcarCameraId);
  74. 104 }
  75. 105 mIsBackcarOn = false;
  76. 106 }
  77. 107 }else if (BackCar.EVENT_TYPE_ARM2EXIT == event) {
  78. 108 mIsArm2Exited = true;
  79. 109 if (mHasShownTouchInputFilterView) {
  80. 110 mCameraServiceImpl.cancelTouchInputFilterView();
  81. 111 mHasShownTouchInputFilterView = false;
  82. 112 }
  83. 113 mCameraServiceImpl.notifyCameraResourceAvailable();
  84. 114
  85. 115 if (mhasEnableBackcarAudio) {
  86. 116 mCameraServiceImpl.disableBackcarAudio();
  87. 117 mhasEnableBackcarAudio = false;
  88. 118 }
  89. 119 LogUtil.i(TAG, "exit arm2 backcar");
  90. //cemera app 接收EVENT_TYPE_RVC_DATA_CHANGE
  91. 120 } else if (BackCar.EVENT_TYPE_RVC_DATA_CHANGE == event) {
  92. 121 LogUtil.i(TAG,"param2 =" + param2);
  93. 122 if (param2 != 0 && mIsRVCMode) {
  94. 123 LogUtil.i(TAG,"handle ARM2 start backcar");
  95. 124 mCameraServiceImpl.handleARM2RVCStart(mBackcar);
  96. 125 } else {
  97. 126 LogUtil.i(TAG,"handle ARM2 stop backcar");
  98. 127 mCameraServiceImpl.handleARM2RVCStop();
  99. 128 }
  100. 129 }else {
  101. 130 LogUtil.i(TAG, "do nothing");
  102. 131 }
  103. 132 }
  104. 133 };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/379901
推荐阅读
相关标签
  

闽ICP备14008679号