Bläddra i källkod

添加1668e显示,声音相关文档

huangliang 1 år sedan
förälder
incheckning
375d526c47
2 ändrade filer med 713 tillägg och 0 borttagningar
  1. 212 0
      doc/ARK1668E声卡配置说明.pdf
  2. 501 0
      doc/ARK1668E显示相关说明文档.pdf

+ 212 - 0
doc/ARK1668E声卡配置说明.pdf

@@ -0,0 +1,212 @@
+                  ARK1668E 声卡配置说明
+
+一、ark1668e 开发板 i2s 设计说明
+      i2s0:MICIN/LINEIN、CS5343
+      i2s1:LINEOUT、ES8316(支持全双工)
+      i2s2:CS4334
+
+提示:LINEOUT、ES8316、CS4334 均经过 BD37033 音效 IC 的不同通道输入(参考说明四进
+行通道切换)
+
+二、CPU 内置/外部免驱声卡配置说明:
+2.1、内核配置:(命令:build/build.sh XXXXXX config linux)
+Device Drivers --->
+
+      <*> Sound card support --->
+            <*> Advanced Linux Sound Architecture --->
+                  <*> ALSA for SoC audio support --->
+                        <*> ASoC support for Arkmicro
+                        < > ARKN141 I2S Device Driver
+                        < > Soc Internal DAC for Audio out
+                        < > Soc Internal ADC for Audio In
+                        <*> ARK1668E I2S Device Driver
+                              <*> ARK1668E Internal audio codec for Audio In/out
+                                CODEC drivers --->
+                              < > Everest Semi ES8316 CODEC
+                              <*> Everest Semi CS4334 CODEC
+                              <*> Everest Semi CS5343 CODEC
+                        <*> Support Audio BD37033 IC Driver
+                        <*> ASoC Simple sound card support
+
+2.2、配置设备树(linux-arkmicro\linux\arch\arm\boot\dts\ark1668e_devb.dts)
+      <1>、ark1668e_devb.dts 修改:
+      关闭宏://#define I2S_FULL_DUPLEX_CODEC_SUPPORT
+
+      sound {
+            .....
+            simple-audio-card,aux-devs = <&amp>;
+            simple-audio-card,dai-link@0 { /* I2S0 - adc */
+                  format = "i2s";
+                  bitclock-master = <&capture_codec>;
+                  frame-master = <&capture_codec>;
+                  capture_cpu: cpu {
+                        sound-dai = <&i2s_adc>;
+                  };
+                  capture_codec: codec {
+                    sound-dai = <&cs5343_codec>;//External(ADC):cs5343_codec    ;
+
+Internal:ark_codec
+
+    };
+
+};
+
+simple-audio-card,dai-link@1 { /* I2S1 - dac */
+
+    format = "i2s";
+
+    bitclock-master = <&playback_codec>;
+
+    frame-master = <&playback_codec>;
+
+    playback_cpu: cpu {
+
+                    sound-dai = <&i2s_dac>;
+
+    };
+
+    playback_codec: codec {
+
+                    sound-dai = <&ark_codec>;//Internal:ark_codec
+
+    };
+
+};
+
+simple-audio-card,dai-link@2 { /* I2S2 - dac */
+
+    format = "i2s";
+
+    bitclock-master = <&cpu_master>;
+
+    frame-master = <&cpu_master>;
+
+    cpu_master: cpu {
+
+                    sound-dai = <&i2s2_dac>;
+
+    };
+
+    codec_master: codec {
+
+                    sound-dai = <&cs4334_codec>;//External(DAC):cs4334_codec ;
+
+    };
+
+};
+
+}
+
+<2>、ark1668e.dtsi 修改:
+      i2s_dac: i2s-dac@e4200000 {
+            .....
+            //full-duplex-mode;//需要 i2s1 全双工支持,需要打开配置
+            .....
+      };
+
+配置说明:
+      指定 codec 和 cpu 的 master/slave 关系:
+            i2s0:
+            bitclock-master = <&capture_codec>;//ark1668e 开发板:默认配置 codec 为
+
+master,cpu 为 slave,反之则改为 capture_cpu
+            frame-master = <&capture_codec>;
+            i2s1:
+            bitclock-master = <&playback_codec>;//ark1668e 开发板:默认配置 codec 为
+
+master,cpu 为 slave,反之则改为 playback_cpu
+            frame-master = <&playback_codec>;
+            i2s2:
+            bitclock-master = <&cpu_master>;//ark1668e 开发板:默认配置 codec 为 slave,
+cpu 为 master,反之则改为 codec_master
+            frame-master = <&cpu_master>;
+
+      指定 audio codec:                                                         i2s2-
+            sound-dai = <&ark_codec>;//i2s0->External:cs5343_codec( 免 驱 ADC)
+
+>cs4334_codec(免驱 DAC,只能做 slave 模式); Internal:ark_codec(MICIN)
+
+      指定音效 IC:
+            simple-audio-card,aux-devs = <&amp>;//开发板默认配置音效 IC(BD37033),如目
+
+标板未使用或改用其他免驱型号音效 IC 可以屏蔽或重新指定
+
+三、外部全双工声卡配置说明:(开发版 codec:es8316(支持全双工))
+3.1、内核配置:(命令:build/build.sh XXXXXX config linux)
+Device Drivers --->
+
+      <*> Sound card support --->
+            <*> Advanced Linux Sound Architecture --->
+                  <*> ALSA for SoC audio support --->
+                        <*> ASoC support for Arkmicro
+                        < > ARKN141 I2S Device Driver
+                        < > Soc Internal DAC for Audio out
+                        < > Soc Internal ADC for Audio In
+                        <*> ARK1668E I2S Device Driver
+                              < > ARK1668E Internal audio codec for Audio In/out
+                                 CODEC drivers --->
+                              <*> Everest Semi ES8316 CODEC
+                              < > Everest Semi CS4334 CODEC
+                              < > Everest Semi CS5343 CODEC
+                        <*> Support Audio BD37033 IC Driver
+                        <*> ASoC Simple sound card support
+
+3.2、配置设备树(linux-arkmicro\linux\arch\arm\boot\dts\目录:ark1668e_devb.dts、
+ark1668e.dtsi)
+
+      <1>、ark1668e_devb.dts 修改:
+      打开宏:#define I2S_FULL_DUPLEX_CODEC_SUPPORT
+
+      sound {
+            .....
+            .....
+            simple-audio-card,aux-devs = <&amp>;
+simple-audio-card,format = "i2s";
+simple-audio-card,bitclock-master = <&dailink0_cpu>;
+simple-audio-card,frame-master = <&dailink0_cpu>;
+dailink0_cpu:simple-audio-card,cpu {
+
+      sound-dai = <&i2s_dac>;
+};
+dailink0_codec:simple-audio-card,codec {
+
+      sound-dai = <&es8316_codec>;
+};
+.....
+.....
+}
+
+<2>、ark1668e.dtsi 修改:
+      i2s_dac: i2s-dac@e4200000 {
+            .....
+            full-duplex-mode;//需要 i2s1 全双工支持,需要打开配置
+            .....
+      };
+
+配置说明:
+      指定 codec 和 cpu 的 master/slave 关系:
+         bitclock-master = <&dailink0_cpu>;//ark1668e 开发板:默认配置 codec 为 slave,
+
+cpu 为 master,反之则改为 dailink0_codec
+            frame-master = <&dailink0_cpu>;
+
+      指定音效 IC:
+            simple-audio-card,aux-devs = <&amp>;//开发板默认配置音效 IC(BD37033),如目
+
+标板未使用或改用其他型号音效 IC 可以屏蔽或重新指定
+
+四、开发板 BD37033 音源输出通道切换                                       //LINEOUT
+查看通道控件:
+
+      amixer controls
+      amixer cget iface=MIXER,name='PA Input Select'
+设置通道:
+LINEOUT ->BD37033
+      切换命令:amixer cset iface=MIXER,name='PA Input Select' 1
+
+ES8316 OUTPUT->BD37033
+      切换命令:amixer cset iface=MIXER,name='PA Input Select' 3 //ES8316 OUTPUT
+
+CS4334 OUTPUT->BD37033
+      切换命令:amixer cset iface=MIXER,name='PA Input Select' 2 //CS4334 OUTPUT
+

+ 501 - 0
doc/ARK1668E显示相关说明文档.pdf

@@ -0,0 +1,501 @@
+          ARK1668E 显示相关说明文档
+
+一、倒车轨迹和雷达信息文件制作及使用说明:
+
+      存放路径:linux-arkmicro/tool/arktrack-tool.rar
+二.LIBARKAPI 常用接口函数说明:
+
+(1)常用函数接口说明(函数原型所在头文件路径如下图)
+
+/*
+**-->函数功能说明:设置当前的显示模式
+**-->参数说明:(1)mode:目前使用的模式主要有:播放多媒体(DISP_PLAYER)、显示手机
+互联(DISP_PHONELINK)
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_video_set_display_mode(int mode);
+
+/*
+**-->函数功能说明:初始化解码器,显示层,分配内存等
+**-->参数说明:(1)stream_type:例如当前的视频流格式是 h264,这里参数设置为
+RAW_STRM_TYPE_H264 其余格式可参考 mfcapi.h 里的枚举
+**-->返回值说明:正确:返回 video_handle *指针 错误:返回空
+*/
+video_handle *arkapi_video_init(int stream_type);
+
+/*
+**-->函数功能说明:设置当前要显示的信息,比如要显示的宽高,偏移值,源的窗口大小等
+**-->参数说明:(1)handle:初始化返回的指针 (2)cfg_vid:参考 ark_api.h 里的
+video_cfg 结构体
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_video_set_config(video_handle *handle, video_cfg *cfg_vid);
+
+/*
+**-->函数功能说明:获取当前要显示的信息,比如要显示的宽高,偏移值,源的窗口大小等
+**-->参数说明:(1)handle:初始化返回的指针 (2)cfg_vid:参考 ark_api.h 里的
+video_cfg 结构体
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_video_get_config(video_handle *handle, video_cfg *cfg_vid);
+
+/*
+**-->函数功能说明:启动解码器,并调用 scale 模块缩放显示到屏幕上
+**-->参数说明:(1)handle:初始化返回的指针 (2)src_addr:视频数据的源地址 (3)len:
+数据的大小 (4)fps:播放视频流的帧率
+**-->返回值说明:正确:返回解码显示的帧数 错误:小于 0
+*/
+int arkapi_video_play(video_handle *handle, const void *src_addr, int len, int
+fps);
+
+/*
+**-->函数功能说明:针对一些特殊的视频流,会有最后几帧不放不完全的现象,调用这个
+这个函数会将剩余的帧播放完成
+**-->参数说明:(1)handle:初始化返回的指针 (2)fps:播放视频流的帧率
+**-->返回值说明:正确:返回 0 错误:小于 0
+*/
+int arkapi_video_play_eof(video_handle *handle, int fps);
+/*
+**-->函数功能说明:打开对应的显示层
+**-->参数说明:(1)handle:初始化返回的指针 (2)enable: 1 打开 0 关闭
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_video_show(video_handle *handle, int enable);
+
+/*
+**-->函数功能说明:打开对应的显示层并判断当前的显示模式是否和已经设置的模式一样
+**-->参数说明:(1)handle:初始化返回的指针 (2)mode:DISP_PLAYER || DISP_PHONELINK
+(3)enable:1 打开 0 关闭
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_video_show_mode(video_handle *handle, int mode, int enable);
+
+/*
+**-->函数功能说明:释放解码器,内存,显示层等
+**-->参数说明:(1)handle:初始化返回的指针
+**-->返回值说明:无
+*/
+void arkapi_video_release(video_handle *handle);
+
+/*
+**-->函数功能说明:通知显示库现在已经进入倒车
+**-->参数说明:无
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_enter_carback(void);
+
+/*
+**-->函数功能说明:通知显示库现在已经退出倒车
+**-->参数说明:无
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_exit_carback(void);
+
+/*
+
+**-->函数功能说明:打开显示层
+
+**-->参数说明:(1)PRIMARY_LAYER  -->对应 OSD2 层 //UI
+
+    VIDEO_LAYER             -->对应 VIDEO2 层 //倒车、手机互联、多媒体
+
+    OVER_LAYER              -->对应 OSD1 层 //倒车轨迹、雷达信息
+
+    TVOUT_LAYER             -->对应 VIDEO1 层 //开机动画、LOGO
+
+    AUX_LAYER               -->对应 OSD3 层 //保留
+
+注:(1)1668E 有五个显示层,同时只能用四个层,对于 app 开发者来说主要涉及到需要处
+理的显示层是 PRIMARY_LAYER,其他层一般由底层处理,一般情况下不要关心。
+
+    (2)显示层的优先级: TVOUT_LAYER VIDEO_LAYER OVER_LAYER PRIMARY_LAYER
+
+    0  1                                               2            3
+
+    --------------------------------------------------------->
+
+    显示层按以上次序从上往下叠加,数字越大,显示就在越上面。
+
+**-->返回值说明:正确:返回空 错误:返回 disp_handle 指针
+
+*/
+
+disp_handle *arkapi_display_open_layer(enum ark_disp_layer layer);
+
+/*
+**-->函数功能说明:关闭显示层
+**-->参数说明:(1)handle:初始化返回的指针
+**-->返回值说明:无
+*/
+void arkapi_display_close_layer(disp_handle *handle);
+
+/*
+**-->函数功能说明:显示对应的显示层
+**-->参数说明:(1)handle:初始化返回的指针
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_show_layer(disp_handle *handle);
+
+/*
+**-->函数功能说明:隐藏对应的显示层
+**-->参数说明:(1)handle:初始化返回的指针
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_hide_layer(disp_handle *handle);
+
+/*
+**-->函数功能说明:强制显示对应的显示层
+**-->参数说明:参考 arkapi_display_open_layer 的参数说明
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_force_show_layer(enum ark_disp_layer layer);
+
+/*
+**-->函数功能说明:强制隐藏对应的显示层
+**-->参数说明:参考 arkapi_display_open_layer 的参数说明
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_force_hide_layer(enum ark_disp_layer layer);
+/*                                                                    (3)y:
+**-->函数功能说明:设置显示层位于屏幕的偏移值
+**-->参数说明:(1):handle:初始化返回的指针 (2)x: 位于屏幕水平方向的偏移值
+位于屏幕垂直方向的偏移值
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_set_layer_pos(disp_handle *handle, int x, int y);
+
+/*
+**-->函数功能说明:设置显示层的大小
+**--> 参 数 说 明 :(1) : handle : 初 始 化 返 回 的 指 针 (2)width: 水 平 方 向 显 示 的 宽 度
+(3)height:垂直方向显示的高度
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_set_layer_size(disp_handle *handle, int width, int height);
+
+/*
+**-->函数功能说明:设置显示层的格式
+**--> 参 数 说 明 :(1) : handle : 初 始 化 返 回 的 指 针 (2)format: 参 考 ark_api.h 里 的
+ark_disp_format 枚举
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_set_layer_format(disp_handle *handle, int format);
+
+/*
+**-->函数功能说明:设置显示层的显示地址
+**-->参数说明:(1):handle:初始化返回的指针 (2)pyrgbaddr:y 地址 (2)pcbaddr: u 地
+址 (3)pcraddr:v 地址
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_set_layer_addr(disp_handle *handle, u32 pyrgbaddr, u32
+pcbaddr, u32 pcraddr);
+
+/****************************************************************************/
+
+//以下 xxx_atomic 函数,作用和上述不带 atomic 函数相同,不同的是下面的函数设置时不
+会马上生效,需要调用
+arkapi_display_layer_update_commit 后才统一生效,主要用于避免视频播放过程中改变
+显示分辨率造成的花屏。
+int arkapi_display_set_layer_pos_atomic(disp_handle *handle, int x, int y);
+int arkapi_display_set_layer_size_atomic(disp_handle *handle, int width, int
+height);
+int arkapi_display_set_layer_format_atomic(disp_handle *handle, int format);
+int arkapi_display_set_layer_addr_atomic(disp_handle *handle, u32 pyrgbaddr, u32
+pcbaddr, u32 pcraddr);
+int arkapi_display_layer_update_commit(disp_handle *handle);
+
+/****************************************************************************/
+
+/*
+**-->函数功能说明:设置显示层的亮度饱和度对比度等参数
+**-->参数说明:(1)layer:参考 arkapi_display_open_layer 的参数说明 (2)vp:参考
+ark_api.h 里的 ark_disp_color 结构体
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_layer_set_color(enum ark_disp_layer layer, disp_color* vp);
+
+/*
+**-->函数功能说明:获取设置显示层的亮度饱和度对比度等参数
+**-->参数说明:(1)layer:参考 arkapi_display_open_layer 的参数说明 (2)vp:参考
+ark_api.h 里的 ark_disp_color 结构体
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_layer_get_color(enum ark_disp_layer layer, disp_color* vp);
+
+/*
+**-->函数功能说明:等待一个帧缓冲
+**-->参数说明:(1)handle:初始化返回的指针
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_wait_for_vsync(disp_handle *handle);
+
+/*
+**-->函数功能说明:获取显示层的显示地址
+**-->参数说明:(1):handle:初始化返回的指针 (2)pyrgbaddr:y 地址 (2)pcbaddr: u 地
+址 (3)pcraddr:v 地址
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_get_layer_addr(disp_handle *handle, u32 *pyrgbaddr, u32
+*pcbaddr, u32 *pcraddr);
+
+/*
+**-->函数功能说明:获取当前的屏幕分辨率
+**-->参数说明:(1)screen:包含了屏幕的大小信息的结构体,调用后直接读取该结构体的
+成员变量的值即可
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_display_get_screen_info(screen_info *screen);
+/*                                                      错误:空
+**-->函数功能说明:内存的初始化
+**-->参数说明:无
+**-->返回值说明:正确:返回 memalloc_handle 结构体指针
+*/
+memalloc_handle *arkapi_memalloc_init(void);
+
+/*
+**-->函数功能说明:申请 buffer
+**-->参数说明:(1)handle:初始化返回的指针 (2)reqbuf:需要申请的 buffer 配置,大
+小,数量等
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_memalloc_reqbuf(memalloc_handle *handle, reqbuf_info *reqbuf);
+
+/*
+**-->函数功能说明:释放内存,初始化的句柄
+**-->参数说明:(1)handle:初始化返回的指针
+**-->返回值说明:无
+*/
+void arkapi_memalloc_release(memalloc_handle *handle);
+
+/*                          错误:小于 0
+**-->函数功能说明:打开 vin 设备
+**-->参数说明:无
+**-->返回值说明:正确:返回文件描述符
+*/
+int arkapi_open_vin(void);
+
+/*
+**-->函数功能说明:关闭 vin 设备
+**-->参数说明:(1)vin_fd:初始化返回的描述符
+**-->返回值说明:正确: 错误:
+*/
+int arkapi_close_vin(int vin_fd);
+
+/*
+**-->函数功能说明:配置信号以及初始化底层驱动
+**-->参数说明:(1)vin_fd:初始化返回的描述符 (2)progressive:信号是隔行 1 还是逐
+行 0 (3)itu601en:信号是 601 信号 1 不是 0
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_vin_config(int vin_fd,int progressive, int itu601en);
+/*
+**-->函数功能说明:启动 vin,开始解码显示信号
+**-->参数说明:(1)vin_fd:初始化返回的描述符
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_vin_start(int vin_fd);
+
+/*
+**-->函数功能说明:停止 vin
+**-->参数说明:(1)vin_fd:初始化返回的描述符
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_vin_stop(int vin_fd);
+
+/*                                         错误:小于 0
+**-->函数功能说明:检测当前配置的通道是否有信号
+**-->参数说明:(1)vin_fd:初始化返回的描述符
+**-->返回值说明:正确:返回 1 有信号 或者 0 无信号
+*/
+int arkapi_vin_detect_signal(int vin_fd);
+
+/*
+**-->函数功能说明:设置解码器的通道
+**-->参数说明:(1)vin_fd:初始化返回的描述符 (2)source:解码器对应的通道 参考
+ark_api.h 里的 dvr_source 枚举
+**-->返回值说明:正确:等于 0 错误:小于 0
+*/
+int arkapi_vin_switch_channel(int vin_fd, enum dvr_source source);
+
+(2)avin 接口使用示例:
+
+      进入 avin 的时候调用如下接口:
+      退出 AVIN 时调用如下接口
+      注:调用顺序要先调用 arkapi_vin_config 之后,再调用 arkapi_vin_switch_channel
+配置解码芯片的 AVIN 输入通道,然后才能调用 arkapi_vin_start 开始。
+
+(3)基于应用倒车时控制 UI 层的使用示例:
+
+     应用和倒车控制 ui 说明:控制 ui 层开启或者关闭分为两种,一种是驱动层开关,一种
+是应用层开关。具体事是由哪一个去操作,取决于应用是否调用如下接口
+
+1.1 应用不调用接口的情况:
+      在倒车的时候,应用不去调用倒车驱动的这三个接口的情况下,此时在进出倒车时的开
+
+关 ui 层的操作是在倒车驱动里去做好的,应用不需要关心开关层的处理,底层会自动进倒
+车的时候关闭 ui 层,退出倒车时候开 ui 层。
+1.2 应用调用接口的情况:
+
+      应用调用这三个接口之后,驱动就不会去对 ui 层去做操作, 也就是开关 ui 层都在应
+用里面去操作。调用 demo 及方法简介请看下面代码:
+
+      /**************************************************************************
+********************/
+#include "carback.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <QDebug>
+#include "ark_api.h"
+
+#define CARBACK_IOCTL_BASE                           0x9A
+#define CARBACK_IOCTL_SET_APP_READY                  _IO(CARBACK_IOCTL_BASE, 0)
+#define CARBACK_IOCTL_APP_ENTER_DONE                 _IO(CARBACK_IOCTL_BASE, 1)
+#define CARBACK_IOCTL_APP_EXIT_DONE                  _IO(CARBACK_IOCTL_BASE, 2)
+#define CARBACK_IOCTL_GET_STATUS                     _IOR(CARBACK_IOCTL_BASE, 3,
+int)
+#define CARBACK_IOCTL_DETECT_SIGNAL                  _IOR(CARBACK_IOCTL_BASE, 4,
+int)
+
+Carback::Carback(QObject *parent) : QObject(parent)
+{
+
+      exitThread = 1;
+      carbackFd = -1;
+}
+
+Carback::~Carback()
+{
+
+      exitThread = -1;
+      carbackFd = -1;
+}
+
+disp_handle *disp_layer_ui;
+
+void *Carback::readCarbckStatus(void *arg)
+{
+      Carback *pThis = (Carback *)arg;
+
+   unsigned char data;
+
+   while (pThis->exitThread) {
+
+      if (1 == read(pThis->carbackFd, &data, 1)) {
+
+         if (data == CBS_On) {
+
+         //告诉显示库此时已经进入倒车,这里必须要调用,否则显示切换会有问题
+
+            arkapi_enter_carback();
+
+         //下面这个 ioctl 就是告诉驱动不要关闭 ui 层,交由应用处理
+
+            if (0 != ioctl(pThis->carbackFd, CARBACK_IOCTL_APP_ENTER_DONE))
+
+            {
+
+                qDebug("ioctl CARBACK_IOCTL_APP_ENTER_DONE fail.");
+
+            }
+
+      //这里应用就是关闭 ui,看自己需求,如果不需要关闭 ui,需要显示别的 Ui,这里
+
+可以不需要调用
+
+         arkapi_display_hide_layer(disp_layer_ui);  //close ui
+
+            pThis->CarbackStatusChange(CBS_On);
+
+         } else if (data == CBS_Off) {
+
+         //告诉显示库此时已经退出倒车,这里必须要调用,否则显示切换会有问题
+
+            arkapi_exit_carback();
+
+         //下面这个 ioctl 就是告诉驱动不要开启 ui 层,交由应用处理
+
+            if (0 != ioctl(pThis->carbackFd, CARBACK_IOCTL_APP_EXIT_DONE))
+
+            {
+
+                qDebug("ioctl CARBACK_IOCTL_APP_ENTER_DONE fail.");
+
+            }
+
+   //这里应用就是开启 ui,看自己需求,如果不需要关闭 ui,需要显示别的 Ui,这里可以
+
+不需要调用
+
+      arkapi_display_show_layer(disp_layer_ui);     //open ui
+
+            pThis->CarbackStatusChange(CBS_Off);
+
+         }
+
+      } else {
+
+         qDebug("read /dev/carback fail.");
+
+      }
+
+   }
+
+}
+
+void Carback::initialize()
+{
+
+      pthread_t pthead;
+      int ret = -1;
+
+   carbackFd = open("/dev/carback", O_RDONLY);
+      if (carbackFd < 0) {
+            qDebug("open /dev/carback fail.");
+            return;
+
+      }
+      //这里是初始化 ui 层句柄,后面检测到进出倒车时需要用到
+      disp_layer_ui = arkapi_display_open_layer(PRIMARY_LAYER); //UI
+      //必须要在应用上电初始化的时候去调用下面这个 ioctl,代表应用已经准备好了,可
+以去控制 ui 层了
+      if (0 != ioctl(carbackFd, CARBACK_IOCTL_SET_APP_READY)) {
+
+            qDebug("ioctl CARBACK_IOCTL_SET_APP_READY fail.");
+            return;
+      }
+
+      ret = pthread_create(&pthead, NULL, readCarbckStatus, this);
+      if(ret != 0) {
+
+            printf("pthread_create failed!\n");
+      }
+}
+
+(4)显示模式切换应用调用接口说明:
+
+     显示模式切换目前主要用于倒车、多媒体视频播放、手机互联之间的相互切换。
+1. 倒 车 调 用 : 进 入 倒 车 时 调 用 arkapi_enter_carback() , 退 出 倒 车 时 调 用
+
+     arkapi_exit_carback(),具体实现可以参考上面说到的(基于应用倒车时控制 UI 层的
+     使用示例)里的代码。
+2. 应用在点击对应 ui 界面进入多媒体视频或者手机互联之前要设置对应的显示模式,进
+     入多媒体视频调用 arkapi_video_set_display_mode(DISP_PLAYER),进入手机互联调用
+     arkapi_video_set_display_mode(DISP_PHONELINK)
+     注:如果没有 ui 界面的交互,比如在应用准备调用 mplayer 播放之前就需要设置对应
+的模式
+
+三.常见问题配置修改:
+
+(1)屏参(以 ark1668e_devb 分支为例):
+
+1.uboot 屏参修改:
+2.kernel 屏参修改:
+      kernel 和 uboot 中一样,kernel 里设备树所在路径如下图所示
+
+(2)GPIO-I2C:参考设备树中对模拟 i2c 的配置,如下图:
+