• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Standard System Solution – Yangfan Porting Case
2
3This document describes how to port standard system functions based on the yangfan development board of the RK3399 chip from Rockchip. The porting processing mainly includes product configuration adding, kernel startup and upgrade, ADM-based conversion of audio, case summary of the camera, TP, LCD, Wi-Fi, BT, vibrator, sensor, and graphics display modules, as well as related function adaptation.
4The development board system porting uses the solution where the board warehouse and SoC code are separated. The board warehouse stores adaptation code of on-board modules, such as audio, camera, TP, and Wi-Fi. The SoC warehouse stores adaptation codes of SoC driver modules, such as I2C, ISP, and RGA.
5
6## Product Configuration and Directory Planning
7
8### Product Configuration
9
10Create a **config.json** file in the `//vendor/yangfan` directory of the product and specify the CPU architecture. Configuration of `//vendor/yangfan/rk3399.json` is as follows:
11
12```
13{
14    "product_name": "yangfan",--- Product name: yangfan
15    "device_company": "rockchip",--- Board vendor: Rockchip
16    "device_build_path": "device/board/isoftstone/yangfan",--- Device building path: device/board/isoftstone/yangfan
17    "target_cpu": "arm",--- Target CPU: arm
18    "type": "standard",--- OS type: standard
19    "version": "3.0",--- Version: 3.0
20    "board": "yangfan",--- Board name: yangfan
21    "enable_ramdisk": true,--- Enable memory virtual disk: true
22    "build_selinux": true,--- Build selinux: true
23    "inherit": [ "productdefine/common/inherit/rich.json", "productdefine/common/inherit/chipset_common.json" ],
24    "subsystems": [
25    {
26      "subsystem": "security",
27      "components": [
28        {
29          "component": "selinux",
30          "features": []
31        }
32      ]
33    },
34    {
35      "subsystem": "communication",
36      "components": [
37        {
38          "component": "netmanager_ext",
39          "features": []
40        }
41      ]
42    },
43    ...
44}
45```
46
47
48The main configurations are as follows:
49
501. "product_name": "yangfan",--- Product name: yangfan
512. "device_company": "rockchip",--- Board vendor: Rockchip
523. "device_build_path": "device/board/isoftstone/yangfan",--- Device building path: device/board/isoftstone/yangfan
534. "target_cpu": "arm",--- Target CPU: arm
545. "type": "standard",--- OS type: standard
556. "version": "3.0",--- Version: 3.0
567. "board": "yangfan",--- Board name: yangfan
578. "enable_ramdisk": true,--- Enable memory virtual disk: true
58
59You can find defined subsystems in `//build/subsystem_config.json`. You can also customize subsystems.
60
61You are advised to copy the configuration file of Hi3516DV300 and delete the **hisilicon_products** subsystem, which is used to compile the kernel for Hi3516DV300 and is not suitable for RK3568.
62
63### Directory Planning
64
65This solution designs the directory structure using the [board and SoC decoupling idea](https://gitee.com/openharmony-sig/sig-content/blob/master/devboard/docs/board-soc-arch-design.md), and plans the SoC adaptation directory as follows:
66
67```
68device
69├── board                                --- Board vendor directory
70│   └── isoftstone                       --- Board vendor
71│       └── yangfan                      --- Board name: yangfan
72└── soc									 --- SoC vendor directory
73    └── rockchip                         --- SoC vendor: Rockchip
74        └── rk3399						 --- SoC series: RK3399, mainly solutions provided by the SoC manufacturer and closed-source libraries
75
76
77```
78The planned product demo directory is as follows:
79```
80vendor
81└── isoftstone
82    └── yangfan         			         --- Product name: product, HCS, and demo related
83```
84
85## **Kernel Startup**
86
87### Secondary Boot
88
89Unlike traditional boot that directly mounts **system** and boots using **init** of **system**, secondary boot is to mount **ramdsik**, boot using **init** of **ramdsik**, perform necessary initialization operations (such as mounting the **system** and **vendor** partitions, and then switch to **init** of **system**.
90
91RK3399 adaptation is to pack **ramdisk** compiled in the mainline version into **boot_linux.img**. The procedure is as follows:
92
931. Enable secondary boot.
94
95Enable **enable_ramdisk** in **//vendor/yangfan/rk3399.json**.
96
97  ```
98  {
99      "product_name": "yangfan",
100      "device_company": "rockchip",
101      "device_build_path": "device/board/isoftstone/yangfan",
102      "target_cpu": "arm",
103      "type": "standard",
104      "version": "3.0",
105      "board": "yangfan",
106      "enable_ramdisk": true,
107      "build_selinux": true,
108      ...
109  }
110  ```
111
1122. Pack the **ramdsik.img** file compiled in the mainline version to **boot_linux.img**.
113
114Configuration:
115
116RK supports **uboot** from **ramdisk**. You only need to add **ramdisk.img** to the configuration file of the packed **boot_linux.img**. Therefore, the **its** format of the mainline version is not used. Specifically, add the following content to the kernel compilation script **make-ohos.sh**:
117
118```
119function make_extlinux_conf()
120{
121	dtb_path=$1
122	uart=$2
123	image=$3
124
125	echo "label rockchip-kernel-5.10" > ${EXTLINUX_CONF}
126	echo "	kernel /extlinux/${image}" >> ${EXTLINUX_CONF}
127	echo "	fdt /extlinux/${TOYBRICK_DTB}" >> ${EXTLINUX_CONF}
128	if [ "enable_ramdisk" == "${ramdisk_flag}" ]; then
129		echo "	initrd /extlinux/ramdisk.img" >> ${EXTLINUX_CONF}
130	fi
131	cmdline="append earlycon=uart8250,mmio32,${uart} root=PARTUUID=614e0000-0000-4b53-8000-1d28000054a9 rw rootwait rootfstype=ext4"
132	echo "  ${cmdline}" >> ${EXTLINUX_CONF}
133}
134```
135
136### Packing
137
138Add the **make-boot.sh** script for packing the boot image. This script can be called when the boot image is packed after **ramdisk** is compiled. The main content is as follows:
139
140```
141genext2fs -B ${blocks} -b ${block_size} -d boot_linux -i 8192 -U boot_linux.img
142```
143
144For details about modification for calling **make-boot.sh**, see [RK3568 adaptation to secondary boot]( https://gitee.com/openharmony/build/pulls/569/files).
145
146### INIT Configuration
147
148For details about the init configuration, see [Startup Subsystem](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E5%90%AF%E5%8A%A8%E6%81%A2%E5%A4%8D%E5%AD%90%E7%B3%BB%E7%BB%9F.md).
149
150## **Audio**
151
152### Introduction
153
154This section describes how to develop the audio driver framework based on the Hardware Driver Foundation (HDF) in OpenHarmony 3.0, including detailed introduction to the composition of the audio driver framework, functional component implementation, and service nodes.
155
156![Audio driver framework](figures/isoftstone/yangfan-Audio-ADM.png)
157
1581. Audio Driver Model (ADM)
159
160   The ADM helps system developers to develop scenario-specific applications for the multimedia audio subsystem. With the ADM, codec and DSP device vendors can adapt their driver code based on the APIs provided by the ADM and implement quick development and easy adaptation to HarmonyOS.
161
1622. Audio Control Dispatch
163
164   The Audio Control Dispatch dispatches the control instructions from the Audio Interface Lib to the driver layer.
165
1663. Audio Stream Dispatch
167
168   The Audio Control Dispatch receives data streams from the Audio Interface Lib and distributes the data streams to the driver layer.
169
1704. Card Manager
171
172   The Card Manager manages multiple audio adapters. Each audio adapter consists of the digital audio interface (DAI), platform, codec, accessory, DSP, and Smart Audio Power Manager (SAPM) modules.
173
1745. Platform Driver
175
176   The Platform Driver is the driver adaptation layer.
177
1786. Smart Audio Power Manager (SAPM)
179
180   The SAPM is the power manager module that optimizes the power consumption policies of the entire ADM power.
181
182### Audio Driver Introduction
183
184#### Code Directory
185
186```
187drivers
188	├── framework
189	│	└── model
190	│	│	└── audio					# Framework code
191	│	│		├─── common				# Common implementation
192	│	│		├─── core				# Core
193	│	│		├─── dispatch			# Control stream and data stream implementation
194	│	│		└── sapm				# Power manager
195	│	└── include
196	│		└── audio					# External API
197	├── adapter
198    │	└──khdf
199	│		└── linux
200	│			└── model
201	│				└── audio			# Compilation file
202	└── peripheral
203		└── audio
204			└── chipsets
205				└── rk3399				# Driver implementation
206					├── accessory		#SmartPA driver
207					├── dai				#I2S driver
208					└── soc				#Dma driver
209```
210
211#### Audio Process Description
212
213##### Startup Process
214
215![](figures/isoftstone/yangfan-Audio-start.png)
216
2171. When the system starts, the platform, codec, accessory, DSP, and DAI drivers of the audio module are loaded first. Each driver obtains the configuration information from its configuration file and saves the obtained information to the data structures.
2182. Each driver module calls the ADM registration interface to add itself to the linked list of the driver module.
2193. The ADM module reads configurations of hdf_audio_driver_0 (audio card_0) and hdf_audio_driver_1 (audio card_1), and loads specific devices of each module.
2204. The ADM module initializes each module device by calling the initialization API of the respective module.
2215. The initialized audio devices are added to the **cardManager** linked list.
222
223##### Playback Process
224
225![](figures/isoftstone/yangfan-Audio-play.png)
226
2271. The Interface Lib dispatches the **Render Open** instruction through the service launched by the driver for handling the playback streaming (referred to as driver service hereinafter). Upon receiving the instruction, the Stream Dispatch service calls the API of each module to deliver the instruction.
2282. The Audio Interface Lib sends a path selection instruction to the Control Dispatch service. The Control Dispatch service calls the DAI API to set the path.
2293. The Interface Lib dispatches hardware parameters through the driver service. Upon receiving the parameters, the Stream Dispatch service calls the API of each module to set hardware parameters.
2304. The Interface Lib dispatches the start playing instruction through the driver service. Upon receiving the instruction, the Stream Dispatch service calls the API of each module to perform related settings for each module.
2315. The Interface Lib dispatches audio data through the driver service. Upon receiving the data, the Stream Dispatch service calls the **Platform AudioPcmWrite** API to send the audio data to direct memory access (DMA).
2326. The Interface Lib dispatches the stop playing instruction through the driver service. Upon receiving the instruction, the Stream Dispatch service calls the stop API of each module to perform related settings for each module.
2337. The Interface Lib dispatches the **Render Close** instruction through the driver service. Upon receiving the instruction, the Stream Dispatch service calls the **Platform AudioRenderClose** API to release resources.
234
235##### Control Process
236
237![](figures/isoftstone/yangfan-Audio-commond.png)
238
2391. To adjust the volume, the Audio Interface Lib sends an instruction for obtaining the volume range to the Control Dispatch service. The Control Dispatch service parses the instruction and calls **get()** of the codec module to obtain the volume range.
2402. The Audio Interface Lib sends an instruction for setting the volume to the Control Dispatch service. The Control Dispatch service parses the instruction and calls **Set()** of the codec module to set the volume.
241
242#### Implementation Description
243
2441. Driver registration
245
246   Take the registration function of codec as an example. When the codec driver is initialized, the following codec registration function is called to register codec with the **codecController** linked list.
247
248   ```c
249   int32_t AudioRegisterCodec(struct HdfDeviceObject *device, struct CodecData *codecData, struct DaiData *daiData)
250   {
251   ...
252
253       codec = (struct CodecDevice *)OsalMemCalloc(sizeof(*codec));
254   ...
255
256       OsalMutexInit(&codec->mutex);
257       codec->devCodecName = codecData->drvCodecName;
258       codec->devData = codecData;
259       codec->device = device;
260
261       ret = AudioSocRegisterDai(device, daiData);
262   ...
263       DListInsertHead(&codec->list, &codecController);
264   ...
265   }
266   ```
267
2682. Data stream data distribution
269
270   During audio recording or playback, the Lib layer distributes or reads data using Dispatch. After receiving the request from the Lib layer, the API distributes or returns the data.
271
272   ```c
273   static int32_t StreamDispatch(struct HdfDeviceIoClient *client, int cmdId,
274       struct HdfSBuf *data, struct HdfSBuf *reply)
275   {
276       unsigned int count = sizeof(g_streamDispCmdHandle) / sizeof(g_streamDispCmdHandle[0]);
277       for (unsigned int i = 0; i < count; ++i) {
278           if ((cmdId == (int)(g_streamDispCmdHandle[i].cmd)) && (g_streamDispCmdHandle[i].func != NULL)) {
279               return g_streamDispCmdHandle[i].func(client, data, reply);
280           }
281       }
282       ADM_LOG_ERR("invalid [cmdId=%d]", cmdId);
283       return HDF_FAILURE;
284   }
285   ```
286
2873. Control function registration API
288
289   Control functions such as volume control, gain control, and channel control are added to the audio adapter control list using this API.
290
291   ```c
292   int32_t AudioAddControls(struct AudioCard *audioCard, const struct AudioKcontrol *controls, int32_t controlMaxNum)
293   {
294   ...
295
296       for (i = 0; i < controlMaxNum; i++) {
297           control = AudioAddControl(audioCard, &controls[i]);
298           if (control == NULL) {
299               ADM_LOG_ERR("Add control fail!");
300               return HDF_FAILURE;
301           }
302           DListInsertHead(&control->list, &audioCard->controls);
303       }
304       ADM_LOG_DEBUG("Success.");
305       return HDF_SUCCESS;
306   }
307   ```
308
3094. Power management API
310
311   Add component implementation:
312
313   ```c
314   int32_t AudioSapmNewComponents(struct AudioCard *audioCard,
315       const struct AudioSapmComponent *component, int32_t cptMaxNum)
316   {
317   ...
318
319       for (i = 0; i < cptMaxNum; i++) {
320           ret = AudioSapmNewComponent(audioCard, component);
321           if (ret != HDF_SUCCESS) {
322               ADM_LOG_ERR("AudioSapmNewComponent fail!");
323               return HDF_FAILURE;
324           }
325           component++;
326       }
327
328       return HDF_SUCCESS;
329   }
330
331   ```
332
333   Add channel implementation:
334
335   ```c
336
337   int32_t AudioSapmAddRoutes(struct AudioCard *audioCard, const struct AudioSapmRoute *route, int32_t routeMaxNum)
338   {
339   ...
340
341       for (i = 0; i < routeMaxNum; i++) {
342           ret = AudioSapmAddRoute(audioCard, route);
343           if (ret != HDF_SUCCESS) {
344               ADM_LOG_ERR("AudioSapmAddRoute failed!");
345               return HDF_FAILURE;
346           }
347           route++;
348       }
349       return HDF_SUCCESS;
350   }
351
352   ```
353
354   Add control function implementation:
355
356   ```c
357
358   int32_t AudioSapmNewControls(struct AudioCard *audioCard)
359   {
360   ...
361
362       DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
363           if (sapmComponent->newCpt) {
364               continue;
365           }
366           if (sapmComponent->kcontrolsNum > 0) {
367               sapmComponent->kcontrols = OsalMemCalloc(sizeof(struct AudioKcontrol*) * sapmComponent->kcontrolsNum);
368               if (sapmComponent->kcontrols == NULL) {
369                   ADM_LOG_ERR("malloc kcontrols fail!");
370                   return HDF_FAILURE;
371               }
372           }
373
374           switch (sapmComponent->sapmType) {
375               case AUDIO_SAPM_ANALOG_SWITCH:
376               case AUDIO_SAPM_MIXER:
377               case AUDIO_SAPM_MIXER_NAMED_CTRL:
378               case AUDIO_SAPM_SPK:
379               case AUDIO_SAPM_PGA:
380                   ret = AudioSapmNewMixerControls(sapmComponent, audioCard);
381                   break;
382               case AUDIO_SAPM_MUX:
383               case AUDIO_SAPM_VIRT_MUX:
384               case AUDIO_SAPM_VALUE_MUX:
385                   ret = AudioSapmNewMuxControls(sapmComponent, audioCard);
386                   break;
387               default:
388                   ret = HDF_SUCCESS;
389                   break;
390           }
391   ...
392
393           ReadInitComponentPowerStatus(sapmComponent);
394           sapmComponent->newCpt = 1;
395           DListInsertTail(&sapmComponent->dirty, &audioCard->sapmDirty);
396       }
397
398       ret = AudioSapmPowerComponents(audioCard);
399   ...
400
401       return HDF_SUCCESS;
402   }
403
404   ```
405
4065. Control stream data distribution
407
408   During audio recording or playback, the Lib layer delivers the control instruction using Dispatch. After receiving the instruction, the API distributes the instruction to each driver module.
409
410   ```c
411   static int32_t ControlDispatch(struct HdfDeviceIoClient *client, int cmdId,
412       struct HdfSBuf *data, struct HdfSBuf *reply)
413   {
414   ...
415
416       if (cmdId >= AUDIODRV_CTRL_IOCTRL_ELEM_BUTT || cmdId < 0) {
417           ADM_LOG_ERR("Invalid [cmdId=%d].", cmdId);
418           return HDF_FAILURE;
419       }
420
421       for (i = 0; i < HDF_ARRAY_SIZE(g_controlDispCmdHandle); ++i) {
422           if ((cmdId == (int)(g_controlDispCmdHandle[i].cmd)) && (g_controlDispCmdHandle[i].func != NULL)) {
423               return g_controlDispCmdHandle[i].func(client, data, reply);
424           }
425       }
426       return HDF_FAILURE;
427   }
428   ```
429
430### Audio Service Introduction
431
432#### Service Node
433
434Three services are provided for the HDI layer based on the audio driver of the ADM framework: hdf_audio_render, hdf_audio_capture, and hdf_audio_control.
435The audio driver service nodes of the development board are as follows:
436
437```
438console:/dev # ls -al hdf_audio_*
439crw------- 1 system system 249,   5 1970-01-01 00:21 hdf_audio_capture  // Audio recording data stream service.
440crw------- 1 system system 249,   3 1970-01-01 00:21 hdf_audio_codec_dev0  // Audio device name.
441crw------- 1 system system 249,   4 1970-01-01 00:21 hdf_audio_control  // Audio control stream service.
442crw------- 1 system system 249,   6 1970-01-01 00:21 hdf_audio_render  // Playback data stream service.
443```
444
4451. Audio control stream service
446
447   This service receives control instructions from the Lib layer, including the volume control, gain control, and channel control instructions. These control instructions are distributed to the driver through the control stream service.
448
4492. Audio data playback service
450
451   This service receives audio data and playback parameters from the Lib layer, as well as instructions for starting, pausing, resuming, and stopping the playback. These instructions are distributed to the driver through the audio data and playback service.
452
4533. Audio recording service
454
455   This service transmits audio data to the Lib layer and receives audio recording parameters from the Lib layer, as well as receive instructions for starting, pausing, resuming, and stopping audio recording. These instructions are distributed to the driver through the audio recording service.
456
457#### Driver Service
458
459Each audio device includes the following services.
460
461| **hdf_audio_codec_dev0** | **Audio Device**      |
462| ------------------------ | ---------------------- |
463| dma_service_0            | DMA driver service          |
464| dai_service              | CPU DAI driver service      |
465| codec_service_0          | Codec driver service        |
466| dsp_service_0            | (Optional) DSP driver service|
467
468| **hdf_audio_codec_dev1** | **Audio Device**                 |
469| ------------------------ | --------------------------------- |
470| dma_service_0            | DMA driver service                     |
471| dai_service              | CPU DAI driver service                 |
472| codec_service_1          | Accessory driver service (SmartPA)|
473| dsp_service_0            | (Optional) DSP driver service           |
474
475#### Code Path
476
477```
478vendor/rockchip/rk3399/hdf_config/khdf
479├── audio 							# Audio private configuration file
480├── device_info
481|	└── device_info.hcs				# Device configuration file
482└── hdf.hcs							# Reference the HCS configuration file
483```
484
485#### Configuration Node Description
486
487Take the codec driver as an example. Add the codec node information to the **audio host** node in the **device_info.hcs** file.
488
489```
490        audio :: host {
491            hostName = "audio_host";
492            priority = 60;
493...
494            device_codec :: device {
495                device0 :: deviceNode {
496                    policy = 1;
497                    priority = 50;
498                    preload = 0;
499                    permission = 0666;
500                    moduleName = "CODEC_ES8316";
501                    serviceName = "codec_service_0";
502                    deviceMatchAttr = "hdf_codec_driver";
503                }
504            }
505...
506        }
507```
508
509#### Driver Implementation
510
511Modify the driver file to implement the driver logic that is the same as that of **moduleName** of **device_info.hcs**.
512
513```
514/* HdfDriverEntry implementations */
515static int32_t Es8316DriverBind(struct HdfDeviceObject *device)
516{
517...
518    return HDF_SUCCESS;
519}
520
521static int32_t Es8316DriverInit(struct HdfDeviceObject *device)
522{
523...
524    return HDF_SUCCESS;
525}
526
527/* HdfDriverEntry definitions */
528struct HdfDriverEntry g_es8316DriverEntry = {
529    .moduleVersion = 1,
530    .moduleName = "CODEC_ES8316",
531    .Bind = Es8316DriverBind,
532    .Init = Es8316DriverInit,
533    .Release = NULL,
534};
535HDF_INIT(g_es8316DriverEntry);
536```
537
538### Summary
539
540		A unified architecture is provided for audio development of OpenHarmony and unified APIs are provided for audio drivers of various platforms based on the ADM of the HDF framework. Audio drivers developed for one platform can be applied to multiple platforms, improving the development efficiency. This document briefly introduces the ADM to help developers develop their applications.
541
542## **Camera**
543
544### Introduction
545
546This section describes how to develop the audio driver framework based on the Hardware Driver Foundation (HDF) in OpenHarmony 3.0, including detailed introduction to the composition of the camera driver framework, functional component implementation, and service nodes.
547
548### Camera driver framework
549
550                                                                  OpenHarmony HDF camera driver module architecture
551
552![img](https://gitee.com/openharmony/drivers_peripheral/raw/master/camera/figures/logic-view-of-modules-related-to-this-repository_zh.png)
553
554The following uses the camera host as an example:
555
5561. HDI implementation: implements standard device APIs for OpenHarmony cameras.
5572. PipelineCorer: connects to the HDI implementation layer for control instruction and stream transfer, establishes data channels, and manages camera devices.
5583. Platform Adaptation: shields the differences between bottom-layer chips and OSs for multi-platform adaptation.
559
560According to analysis of the USB camera of RK3399E/T, Linux 4.19 is used as the kernel. The USB camera depends on the UVC of V4L2 under Linux. According to the architecture diagram, the HDF camera is compatible with the UVC of V4L2 under Linux. Therefore, you need to ensure that the USB and camera drivers required by the UVC are normal before debugging.
561
562
563### Camera Driver Introduction
564
565#### Configuration
566
567arch/arm64/configs/rockchip_linux_defconfig
568
569```c
570CONFIG_VIDEO_V4L2_SUBDEV_API=y
571CONFIG_MEDIA_USB_SUPPORT=y
572CONFIG_USB_VIDEO_CLASS=y
573```
574
575#### Node Information
576
577Before inserting the USB camera:
578
579```
580# ls -l dev/video*
581crw-rw---- 1 root root 81,   0 2013-01-18 10:59 dev/video0
582crw-rw---- 1 root root 81,   1 2013-01-18 10:59 dev/video1
583crw-rw---- 1 root root 81,   2 2013-01-18 10:59 dev/video2
584crw-rw---- 1 root root 81,   3 2013-01-18 10:59 dev/video3
585crw-rw---- 1 root root 81,   4 2013-01-18 10:59 dev/video4
586crw-rw---- 1 root root 81,   5 2013-01-18 10:59 dev/video5
587crw-rw---- 1 root root 81,   6 2013-01-18 10:59 dev/video6
588crw-rw---- 1 root root 81,   7 2013-01-18 10:59 dev/video7
589crw-rw---- 1 root root 81,   8 2013-01-18 10:59 dev/video8
590crw-rw---- 1 root root 81,   9 2013-01-18 10:59 dev/video9
591#
592```
593
594After inserting the USB camera, add the **dev/video10** and **dev/video11** nodes.
595
596```
597# ls -l dev/video*
598crw-rw---- 1 root root 81,   0 2013-01-18 10:59 dev/video0
599crw-rw---- 1 root root 81,   1 2013-01-18 10:59 dev/video1
600crw------- 1 root root 81,  10 2013-01-18 11:01 dev/video10
601crw------- 1 root root 81,  11 2013-01-18 11:01 dev/video11
602crw-rw---- 1 root root 81,   2 2013-01-18 10:59 dev/video2
603crw-rw---- 1 root root 81,   3 2013-01-18 10:59 dev/video3
604crw-rw---- 1 root root 81,   4 2013-01-18 10:59 dev/video4
605crw-rw---- 1 root root 81,   5 2013-01-18 10:59 dev/video5
606crw-rw---- 1 root root 81,   6 2013-01-18 10:59 dev/video6
607crw-rw---- 1 root root 81,   7 2013-01-18 10:59 dev/video7
608crw-rw---- 1 root root 81,   8 2013-01-18 10:59 dev/video8
609crw-rw---- 1 root root 81,   9 2013-01-18 10:59 dev/video9
610#
611```
612
613#### Opening a Device Node
614
615In the code environment of OpenHarmony, compile the following code as an executable program and execute the program on the development board. The node is opened successfully if no error is reported.
616
617```c
618#include <stdio.h>
619#include <sys/types.h>
620#include <sys/stat.h>
621#include <fcntl.h>
622#include <stdlib.h>
623#include <unistd.h>
624#include <sys/ioctl.h>
625#include <linux/videodev2.h>
626#include <string.h>
627#include <sys/mman.h>
628
629int main(void)
630{
631	// 1. Open the device.
632	int fd = open("/dev/video10", O_RDWR);
633	if (fd < 0) {
634		printf("open device fail\n");
635		return -1;
636	}
637
638    close(fd);
639    return 0;
640}
641```
642
643#### Obtaining Parameters
644
645```c
646#include <stdio.h>
647#include <sys/types.h>
648#include <sys/stat.h>
649#include <fcntl.h>
650#include <stdlib.h>
651#include <unistd.h>
652#include <sys/ioctl.h>
653#include <linux/videodev2.h>
654#include <string.h>
655#include <sys/mman.h>
656
657int main(void)
658{
659	// 1. Open the device.
660	int fd = open("/dev/video10", O_RDWR);
661	if (fd < 0) {
662		printf("open device fail\n");
663		return -1;
664	}
665
666	// 2. Obtain the format ioctl (file descriptor, command, and structure corresponding to the command) supported by the camera.
667    struct v4l2_fmtdesc v4fmt;
668	v4fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
669    int i = 0;
670    while(1) {
671		v4fmt.index = i++;
672		int ret = ioctl(fd, VIDIOC_ENUM_FMT, &v4fmt);
673		if (ret < 0) {
674			printf("get fmt fail\n");
675		}
676		unsigned char *p = (unsigned char*)&v4fmt.pixelformat;
677		printf("index=%d\n", v4fmt.index);
678		printf("flags=%d\n", v4fmt.flags);
679		printf("description=%s\n", v4fmt.description);
680		printf("pixelformat=%c%c%c%c\n", p[0], p[1], p[2], p[3]);
681		printf("reserved=%d\n", v4fmt.reserved[0]);
682	}
683
684    close(fd);
685    return 0;
686}
687```
688
689In the code environment of OpenHarmony, compile the preceding code as an executable program and execute the program on the development board. The result shows that the YUYV and MJPEG formats are supported.
690
691		index=0
692		flags=0
693		description=YUYV 4:2:2
694		pixelformat=YUYV
695		reserved=0
696
697		index=1
698		flags=1
699		description=Motion-JPEG
700		pixelformat=MJPG
701		reserved=0
702#### Setting the Buffer Queue
703
704```c
705#include <stdio.h>
706#include <sys/types.h>
707#include <sys/stat.h>
708#include <fcntl.h>
709#include <stdlib.h>
710#include <unistd.h>
711#include <sys/ioctl.h>
712#include <linux/videodev2.h>
713#include <string.h>
714#include <sys/mman.h>
715
716int main(void)
717{
718	// 1. Open the device.
719	int fd = open("/dev/video10", O_RDWR);
720	if (fd < 0) {
721		printf("open device fail\n");
722		return -1;
723	}
724
725	// 2. Set the collection format.
726	struct v4l2_format vfmt;
727	vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
728	vfmt.fmt.pix.width = 640;
729	vfmt.fmt.pix.height = 480;
730	vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; // Set the video capture format (which must be the same as the one obtained above).
731	int ret = ioctl(fd, VIDIOC_S_FMT, &vfmt); // Set the format.
732	if (ret < 0) {
733		printf("set fmt fail\n");
734        return -1;
735	}
736	memset(&vfmt, 0, sizeof(vfmt));
737	vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
738	ret = ioctl(fd, VIDIOC_G_FMT, &vfmt); // Obtain the format.
739	if (ret < 0) {
740		printf("set->get fmt fail\n");
741        return -1;
742	}
743
744    // 3. Apply for the kernel buffer queue.
745    struct v4l2_requestbuffers reqbuffer;
746    reqbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
747    reqbuffer.count = 4; // Apply for four buffers.
748    reqbuffer.memory = V4L2_MEMORY_MMAP; // Memory mapping method: MMAP/USERPTR
749    ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuffer); // Allocate memory.
750    if (ret < 0) {
751        printf("req buffer fail\n");
752        return -1;
753    }
754
755    // 4. Stop the device.
756    close(fd);
757    return 0;
758}
759```
760
761In the code environment of OpenHarmony, compile the preceding code as an executable program and execute the program on the development board.
762
763Execution result: **req buffer fail**
764
765Cause analysis: ioctl(fd, VIDIOC_REQBUFS, &reqbuffer); failure
766
767Troubleshooting method 1: Add logs to the kernel to locate the position where **VIDIOC_REQBUFS** fails. After the **ioctl** command is delivered, the **video_usercopy** API in **drivers/media/v4l2-core/v4l2-ioctl.c** will be used. However, the specific failure cause is still not found.
768
769Troubleshooting method 2: Contact Smart Device Tech to check whether the USB camera of the debian version of the Linux 4.19 kernel works properly. Result: After using the **gst-launch-1.0 v4l2src device=/dev/video10 ! image/jpeg, width= 1280, height=720, framerate=30/1 ! jpegparse ! mppjpegdec ! kmssink sync=false** command in the debian version, the HDMI screen can display the preview image properly.
770
771Through the preceding operations, you can determine that the UVC driver of V4L2 under Linux and the external USB camera driver work properly. Next, you need to debug the HDF camera of OpenHarmony.
772
773#### API Introduction
774
775Check the camera-related executable programs in OpenHarmony: **ohos_camera_demo** and **v4l2_main**.
776
777##### ohos_camera_demo
778
779Execution result: After you enter **o**, no preview image is displayed and no error logs are recorded.
780
781```
782# ohos_camera_demo
783GetUintParameter debug.bytrace.tags.enableflags error.
784Options:
785-h | --help          Print this message
786-o | --offline       stream offline test
787-c | --capture       capture one picture
788-w | --set WB        Set white balance Cloudy
789-v | --video         capture Viedeo of 10s
790-a | --Set AE        Set Auto exposure
791-f | --Set Flashlight        Set flashlight ON 5s OFF
792-q | --quit          stop preview and quit this app
793o
794Options:
795-h | --help          Print this message
796-o | --offline       stream offline test
797-c | --capture       capture one picture
798-w | --set WB        Set white balance Cloudy
799-v | --video         capture Viedeo of 10s
800-a | --Set AE        Set Auto exposure
801-f | --Set Flashlight        Set flashlight ON 5s OFF
802-q | --quit          stop preview and quit this app
803
804```
805
806Cause analysis: Currently, **ohos_camera_demo** supports only MPP and does not support V4L2. Therefore, the debugging of this demo is canceled.
807
808##### v4l2_main
809
810Execution result: After you enter **u**, error message **ERROR:main test:cannot open framebuffer /dev/fb0 file node** is displayed.
811
812```
813Options:
814-h | --help          Print this message
815-p | --preview       start preview on platform sensor
816-c | --capture       capture one picture
817-w | --set WB        Set white balance Cloudy
818-e | --Set AE        Set exposure time
819-v | --video         capture Viedeo of 10s
820-u | --uvc           start preview on uvc preview
821-a | --Set ATE       Set Auto exposure
822-q | --quit          stop preview and quit this app
823INFO:please input command(input -q exit this app)
824
825u
826ERROR:main test:cannot open framebuffer /dev/fb0 file node
827
828INFO:V4L2OpenDevice /dev/video10
829```
830
831Cause analysis: Check whether the **dev/fb0** node exists. The **fb0** node does not exist. Check whether there are other **fb0** nodes in the root directory. The **dev/graphics/fb0** node exists.
832
833```
834# ls -l dev/fb0
835ls: dev/fb0: No such file or directory
836
837# find -name fb0
838./dev/graphics/fb0
839./sys/class/graphics/fb0
840./sys/devices/platform/display-subsystem/graphics/fb0
841```
842
843You need to change **dev/fb0** in the executable program **v4l2_main** to **dev/graphics/fb0**. Here, **fb0** is **framebuffer**, which is used to display the preview image on the screen.
844
845Modification: drivers/peripheral
846
847```diff
848diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp b/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp
849index b351f49..d9c4cb3 100755
850--- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp
851+++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp
852@@ -186,9 +186,9 @@ RetCode FBInit()
853     if (g_fbFd)
854         return RC_OK;
855
856-    g_fbFd = open("/dev/fb0", O_RDWR);
857+    g_fbFd = open("/dev/graphics/fb0", O_RDWR);
858     if (g_fbFd < 0) {
859-        CAMERA_LOGE("main test:cannot open framebuffer %s file node\n", "/dev/fb0");
860+        CAMERA_LOGE("main test:cannot open framebuffer %s file node\n", "/dev/graphics/fb0");
861         return RC_ERROR;
862     }
863
864diff --git a/camera/hal/test/v4l2/src/test_display.cpp b/camera/hal/test/v4l2/src/test_display.cpp
865index db908e7..7025deb 100644
866--- a/camera/hal/test/v4l2/src/test_display.cpp
867+++ b/camera/hal/test/v4l2/src/test_display.cpp
868@@ -114,9 +114,9 @@ void TestDisplay::FBLog()
869
870 RetCode TestDisplay::FBInit()
871 {
872-    fbFd_ = open("/dev/fb0", O_RDWR);
873+    fbFd_ = open("/dev/graphics/fb0", O_RDWR);
874     if (fbFd_ < 0) {
875-        CAMERA_LOGE("main test:cannot open framebuffer %s file node\n", "/dev/fb0");
876+        CAMERA_LOGE("main test:cannot open framebuffer %s file node\n", "/dev/graphics/fb0");
877         return RC_ERROR;
878     }
879
880@@ -439,4 +439,4 @@ void TestDisplay::StopStream(std::vector<int>& captureIds, std::vector<int>& str
881             std::cout << "==========[test log]check Capture: ReleaseStreams fail, rc = " << rc << std::endl;
882         }
883     }
884-}
885\ No newline at end of file
886+}
887diff --git a/display/hal/default/display_layer.c b/display/hal/default/display_layer.c
888index ee7a825..e12a653 100644
889--- a/display/hal/default/display_layer.c
890+++ b/display/hal/default/display_layer.c
891@@ -24,7 +24,7 @@
892
893 #define DEV_ID             0
894 #define LAYER_ID           0
895-#define FB_PATH            "/dev/fb0"
896+#define FB_PATH            "/dev/graphics/fb0"
897 #define DISP_WIDTH         800
898 #define DISP_HEIGHT        480
899 #define BITS_PER_PIXEL     32
900```
901
902Run the **./build.sh --product-name rk3399 --ccache --build-target v4l2_main** command to recompile **v4l2_main** after modification.
903
904The executable program path after successful compilation is **./out/rk3399/hdf/hdf/v4l2_main**.
905
906Push the newly compiled **v4l2_main** to the **system/bin** directory on the development board.
907
908```
909hdc shell "mount -o rw,remount /"
910hdc file send D:\cyyanl\work\RockChip\bin\v4l2_main /system/bin
911```
912
913Continue to execute **v4l2_main**. If no **framebuffer** error is reported, the issue has been resolved. (Another idea is to analyze why **fb0** is in **/dev/graphics/fb0** instead of **/dev/fb0**, and then change **fb0** to **/dev/fb0**. This idea will be debugged later.)
914
915New error: **ERROR:error: ioctl VIDIOC_QUERYBUF failed.**
916
917```
918Options:
919-h | --help          Print this message
920-p | --preview       start preview on platform sensor
921-c | --capture       capture one picture
922-w | --set WB        Set white balance Cloudy
923-e | --Set AE        Set exposure time
924-v | --video         capture Viedeo of 10s
925-u | --uvc           start preview on uvc preview
926-a | --Set ATE       Set Auto exposure
927-q | --quit          stop preview and quit this app
928INFO:please input command(input -q exit this app)
929u
930INFO:the fixed information is as follow:
931INFO:id=
932INFO:sem_start=0
933INFO:smem_len=2457600
934...
935INFO:V4L2AllocBuffer
936INFO:V4L2AllocBuffer:memoryType_ = 2
937INFO:V4L2AllocBuffer:V4L2_MEMORY_USERPTR = 2
938INFO:V4L2AllocBuffer:VIDIOC_QUERYBUF = 3226490377
939ERROR:error: ioctl VIDIOC_QUERYBUF failed.
940ERROR:error: Creatbuffer: V4L2AllocBuffer error
941ERROR:main test:V4L2PreviewThread CreatBuffer fail i = 0
942```
943
944Cause analysis: ioctl(fd, VIDIOC_QUERYBUF, &buf) failure. In the section for setting the format and applying for the buffer queue in the Linux L4V2 UVC driver chapter, the following error is reported:
945
946ioctl(fd, VIDIOC_REQBUFS, &reqbuffer). Therefore, we can conclude that **ioctl VIDIOC_REQBUFS** on OpenHarmony will always report an error. The differences between the two failures are as follows:
947
948The memory mapping methods are different: V4L2_MEMORY_MMAP and V4L2_MEMORY_USERPTR
949
950According to issues of OpenHarmony, memory mapping method V4L2_MEMORY_MMAP is not supported. Next, we still use V4L2_MEMORY_USERPTR of **v4l2_main** for debugging and analysis.
951
952For details, see [Method of Applying for Memory by Adding MMAP on V4L2 Devices](https://gitee.com/openharmony/drivers_peripheral/issues/I4EFWP).
953
954
955Now, analyze the **ioctl(fd, VIDIOC_QUERYBUF, &buf)** failure. View the definition of VIDIOC_QUERYBUF: **videodev2.h**
956
957```c
958#define VIDIOC_QUERYBUF_IOWR('V',  9, struct v4l2_buffer)
959```
960
961Insert the **ioctl** definition **int ioctl(int fd, int cmd, …); VIDIOC_QUERYBUF** as the input parameter of **cmd**. The input parameter is of the **int** type. This is a digital command code. After the code is sent to the kernel using **ioctl**, the corresponding function operation will be performed. Therefore, the command code delivered in the user state must be consistent with that received by the kernel. Next, let's check the command code consistency.
962
963**videodev2.h** contains 77 command codes for interaction with the kernel. Print the command codes in kernel state and compare them with those in the user state.
964
965Printing in user state: drivers/peripheral
966
967```diff
968diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cpp b/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cpp
969index d7dd15f..f7254b4 100644
970--- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cpp
971+++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cpp
972@@ -162,37 +162,119 @@ RetCode HosV4L2Buffers::V4L2DequeueBuffer(int fd)
973     return RC_OK;
974 }
975
976+static void cyyanl_printf_cmd(void)
977+{
978+#if 1
979+    CAMERA_LOGD("*************************************************************************************");
980+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYCAP           ) = 0x%x\n", VIDIOC_QUERYCAP           );
981+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_FMT           ) = 0x%x\n", VIDIOC_ENUM_FMT           );
982+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_FMT              ) = 0x%x\n", VIDIOC_G_FMT              );
983+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_FMT              ) = 0x%x\n", VIDIOC_S_FMT              );
984+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_REQBUFS            ) = 0x%x\n", VIDIOC_REQBUFS            );
985+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYBUF           ) = 0x%x\n", VIDIOC_QUERYBUF           );
986+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_FBUF             ) = 0x%x\n", VIDIOC_G_FBUF             );
987+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_FBUF             ) = 0x%x\n", VIDIOC_S_FBUF             );
988+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_OVERLAY            ) = 0x%x\n", VIDIOC_OVERLAY            );
989+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_QBUF               ) = 0x%x\n", VIDIOC_QBUF               );
990+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_EXPBUF             ) = 0x%x\n", VIDIOC_EXPBUF             );
991+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_DQBUF              ) = 0x%x\n", VIDIOC_DQBUF              );
992+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_STREAMON           ) = 0x%x\n", VIDIOC_STREAMON           );
993+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_STREAMOFF          ) = 0x%x\n", VIDIOC_STREAMOFF          );
994+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_PARM             ) = 0x%x\n", VIDIOC_G_PARM             );
995+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_PARM             ) = 0x%x\n", VIDIOC_S_PARM             );
996+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_STD              ) = 0x%x\n", VIDIOC_G_STD              );
997+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_STD              ) = 0x%x\n", VIDIOC_S_STD              );
998+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMSTD            ) = 0x%x\n", VIDIOC_ENUMSTD            );
999+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMINPUT          ) = 0x%x\n", VIDIOC_ENUMINPUT          );
1000+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_CTRL             ) = 0x%x\n", VIDIOC_G_CTRL             );
1001+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_CTRL             ) = 0x%x\n", VIDIOC_S_CTRL             );
1002+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_TUNER            ) = 0x%x\n", VIDIOC_G_TUNER            );
1003+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_TUNER            ) = 0x%x\n", VIDIOC_S_TUNER            );
1004+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_AUDIO            ) = 0x%x\n", VIDIOC_G_AUDIO            );
1005+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_AUDIO            ) = 0x%x\n", VIDIOC_S_AUDIO            );
1006+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYCTRL          ) = 0x%x\n", VIDIOC_QUERYCTRL          );
1007+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYMENU          ) = 0x%x\n", VIDIOC_QUERYMENU          );
1008+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_INPUT            ) = 0x%x\n", VIDIOC_G_INPUT            );
1009+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_INPUT            ) = 0x%x\n", VIDIOC_S_INPUT            );
1010+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_EDID             ) = 0x%x\n", VIDIOC_G_EDID             );
1011+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_EDID             ) = 0x%x\n", VIDIOC_S_EDID             );
1012+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_OUTPUT           ) = 0x%x\n", VIDIOC_G_OUTPUT           );
1013+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_OUTPUT           ) = 0x%x\n", VIDIOC_S_OUTPUT           );
1014+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMOUTPUT         ) = 0x%x\n", VIDIOC_ENUMOUTPUT         );
1015+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_AUDOUT           ) = 0x%x\n", VIDIOC_G_AUDOUT           );
1016+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_AUDOUT           ) = 0x%x\n", VIDIOC_S_AUDOUT           );
1017+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_MODULATOR        ) = 0x%x\n", VIDIOC_G_MODULATOR        );
1018+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_MODULATOR        ) = 0x%x\n", VIDIOC_S_MODULATOR        );
1019+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_FREQUENCY        ) = 0x%x\n", VIDIOC_G_FREQUENCY        );
1020+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_FREQUENCY        ) = 0x%x\n", VIDIOC_S_FREQUENCY        );
1021+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_CROPCAP            ) = 0x%x\n", VIDIOC_CROPCAP            );
1022+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_CROP             ) = 0x%x\n", VIDIOC_G_CROP             );
1023+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_CROP             ) = 0x%x\n", VIDIOC_S_CROP             );
1024+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_JPEGCOMP         ) = 0x%x\n", VIDIOC_G_JPEGCOMP         );
1025+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_JPEGCOMP         ) = 0x%x\n", VIDIOC_S_JPEGCOMP         );
1026+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYSTD           ) = 0x%x\n", VIDIOC_QUERYSTD           );
1027+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_TRY_FMT            ) = 0x%x\n", VIDIOC_TRY_FMT            );
1028+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMAUDIO          ) = 0x%x\n", VIDIOC_ENUMAUDIO          );
1029+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMAUDOUT         ) = 0x%x\n", VIDIOC_ENUMAUDOUT         );
1030+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_PRIORITY         ) = 0x%x\n", VIDIOC_G_PRIORITY         );
1031+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_PRIORITY         ) = 0x%x\n", VIDIOC_S_PRIORITY         );
1032+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_SLICED_VBI_CAP   ) = 0x%x\n", VIDIOC_G_SLICED_VBI_CAP   );
1033+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_LOG_STATUS         ) = 0x%x\n", VIDIOC_LOG_STATUS         );
1034+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_EXT_CTRLS        ) = 0x%x\n", VIDIOC_G_EXT_CTRLS        );
1035+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_EXT_CTRLS        ) = 0x%x\n", VIDIOC_S_EXT_CTRLS        );
1036+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_TRY_EXT_CTRLS      ) = 0x%x\n", VIDIOC_TRY_EXT_CTRLS      );
1037+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_FRAMESIZES    ) = 0x%x\n", VIDIOC_ENUM_FRAMESIZES    );
1038+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_FRAMEINTERVALS) = 0x%x\n", VIDIOC_ENUM_FRAMEINTERVALS);
1039+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_ENC_INDEX        ) = 0x%x\n", VIDIOC_G_ENC_INDEX        );
1040+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENCODER_CMD        ) = 0x%x\n", VIDIOC_ENCODER_CMD        );
1041+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_TRY_ENCODER_CMD    ) = 0x%x\n", VIDIOC_TRY_ENCODER_CMD    );
1042+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_HW_FREQ_SEEK     ) = 0x%x\n", VIDIOC_S_HW_FREQ_SEEK     );
1043+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_CREATE_BUFS        ) = 0x%x\n", VIDIOC_CREATE_BUFS        );
1044+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_PREPARE_BUF        ) = 0x%x\n", VIDIOC_PREPARE_BUF        );
1045+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_G_SELECTION        ) = 0x%x\n", VIDIOC_G_SELECTION        );
1046+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_S_SELECTION        ) = 0x%x\n", VIDIOC_S_SELECTION        );
1047+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_DECODER_CMD        ) = 0x%x\n", VIDIOC_DECODER_CMD        );
1048+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_TRY_DECODER_CMD    ) = 0x%x\n", VIDIOC_TRY_DECODER_CMD    );
1049+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_DV_TIMINGS    ) = 0x%x\n", VIDIOC_ENUM_DV_TIMINGS    );
1050+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_QUERY_DV_TIMINGS   ) = 0x%x\n", VIDIOC_QUERY_DV_TIMINGS   );
1051+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_DV_TIMINGS_CAP     ) = 0x%x\n", VIDIOC_DV_TIMINGS_CAP     );
1052+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_FREQ_BANDS    ) = 0x%x\n", VIDIOC_ENUM_FREQ_BANDS    );
1053+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_DBG_G_CHIP_INFO    ) = 0x%x\n", VIDIOC_DBG_G_CHIP_INFO    );
1054+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(VIDIOC_QUERY_EXT_CTRL     ) = 0x%x\n", VIDIOC_QUERY_EXT_CTRL     );
1055+    CAMERA_LOGD("cyyanl v4l2 ioctl cmd(BASE_VIDIOC_PRIVATE       ) = 0x%x\n", BASE_VIDIOC_PRIVATE       );
1056+    CAMERA_LOGD("*************************************************************************************");
1057+#endif
1058+}
1059+
1060 RetCode HosV4L2Buffers::V4L2AllocBuffer(int fd, const std::shared_ptr<FrameSpec>& frameSpec)
1061 {
1062     struct v4l2_buffer buf = {};
1063     struct v4l2_plane planes[1] = {};
1064-    CAMERA_LOGD("V4L2AllocBuffer\n");
1065+    CAMERA_LOGD("V4L2AllocBuffer enter\n");
1066
1067+    cyyanl_printf_cmd();
1068     if (frameSpec == nullptr) {
1069         CAMERA_LOGE("V4L2AllocBuffer frameSpec is NULL\n");
1070         return RC_ERROR;
1071     }
1072-
1073     switch (memoryType_) {
1074         case V4L2_MEMORY_MMAP:
1075             // to do something
1076             break;
1077         case V4L2_MEMORY_USERPTR:
1078+            CAMERA_LOGD("V4L2AllocBuffer:V4L2_MEMORY_USERPTR = %d\n", V4L2_MEMORY_USERPTR);
1079             buf.type = bufferType_;
1080             buf.memory = memoryType_;
1081             buf.index = (uint32_t)frameSpec->buffer_->GetIndex();
1082-
1083             if (bufferType_ == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1084+                CAMERA_LOGD("V4L2AllocBuffer:V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = %d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
1085                 buf.m.planes = planes;
1086                 buf.length = 1;
1087             }
1088```
1089
1090Printing in kernel state: kernel/linux/linux-4.19/
1091
1092```diff
1093diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
1094index 0842a47c6..8aa60407f 100644
1095--- a/drivers/media/usb/uvc/uvc_driver.c
1096+++ b/drivers/media/usb/uvc/uvc_driver.c
1097@@ -2902,10 +2902,93 @@ struct uvc_driver uvc_driver = {
1098 	},
1099 };
1100
1101+static void cyyanl_printk_cmd(void)
1102+{
1103+    printk("*************************************************************************************");
1104+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYCAP           ) = %ld\n", VIDIOC_QUERYCAP           );
1105+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_FMT           ) = %ld\n", VIDIOC_ENUM_FMT           );
1106+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_FMT              ) = %ld\n", VIDIOC_G_FMT              );
1107+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_FMT              ) = %ld\n", VIDIOC_S_FMT              );
1108+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_REQBUFS            ) = %ld\n", VIDIOC_REQBUFS            );
1109+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYBUF           ) = %ld\n", VIDIOC_QUERYBUF           );
1110+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_FBUF             ) = %ld\n", VIDIOC_G_FBUF             );
1111+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_FBUF             ) = %ld\n", VIDIOC_S_FBUF             );
1112+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_OVERLAY            ) = %ld\n", VIDIOC_OVERLAY            );
1113+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_QBUF               ) = %ld\n", VIDIOC_QBUF               );
1114+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_EXPBUF             ) = %ld\n", VIDIOC_EXPBUF             );
1115+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_DQBUF              ) = %ld\n", VIDIOC_DQBUF              );
1116+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_STREAMON           ) = %ld\n", VIDIOC_STREAMON           );
1117+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_STREAMOFF          ) = %ld\n", VIDIOC_STREAMOFF          );
1118+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_PARM             ) = %ld\n", VIDIOC_G_PARM             );
1119+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_PARM             ) = %ld\n", VIDIOC_S_PARM             );
1120+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_STD              ) = %ld\n", VIDIOC_G_STD              );
1121+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_STD              ) = %ld\n", VIDIOC_S_STD              );
1122+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMSTD            ) = %ld\n", VIDIOC_ENUMSTD            );
1123+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMINPUT          ) = %ld\n", VIDIOC_ENUMINPUT          );
1124+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_CTRL             ) = %ld\n", VIDIOC_G_CTRL             );
1125+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_CTRL             ) = %ld\n", VIDIOC_S_CTRL             );
1126+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_TUNER            ) = %ld\n", VIDIOC_G_TUNER            );
1127+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_TUNER            ) = %ld\n", VIDIOC_S_TUNER            );
1128+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_AUDIO            ) = %ld\n", VIDIOC_G_AUDIO            );
1129+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_AUDIO            ) = %ld\n", VIDIOC_S_AUDIO            );
1130+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYCTRL          ) = %ld\n", VIDIOC_QUERYCTRL          );
1131+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYMENU          ) = %ld\n", VIDIOC_QUERYMENU          );
1132+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_INPUT            ) = %ld\n", VIDIOC_G_INPUT            );
1133+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_INPUT            ) = %ld\n", VIDIOC_S_INPUT            );
1134+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_EDID             ) = %ld\n", VIDIOC_G_EDID             );
1135+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_EDID             ) = %ld\n", VIDIOC_S_EDID             );
1136+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_OUTPUT           ) = %ld\n", VIDIOC_G_OUTPUT           );
1137+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_OUTPUT           ) = %ld\n", VIDIOC_S_OUTPUT           );
1138+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMOUTPUT         ) = %ld\n", VIDIOC_ENUMOUTPUT         );
1139+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_AUDOUT           ) = %ld\n", VIDIOC_G_AUDOUT           );
1140+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_AUDOUT           ) = %ld\n", VIDIOC_S_AUDOUT           );
1141+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_MODULATOR        ) = %ld\n", VIDIOC_G_MODULATOR        );
1142+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_MODULATOR        ) = %ld\n", VIDIOC_S_MODULATOR        );
1143+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_FREQUENCY        ) = %ld\n", VIDIOC_G_FREQUENCY        );
1144+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_FREQUENCY        ) = %ld\n", VIDIOC_S_FREQUENCY        );
1145+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_CROPCAP            ) = %ld\n", VIDIOC_CROPCAP            );
1146+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_CROP             ) = %ld\n", VIDIOC_G_CROP             );
1147+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_CROP             ) = %ld\n", VIDIOC_S_CROP             );
1148+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_JPEGCOMP         ) = %ld\n", VIDIOC_G_JPEGCOMP         );
1149+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_JPEGCOMP         ) = %ld\n", VIDIOC_S_JPEGCOMP         );
1150+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_QUERYSTD           ) = %ld\n", VIDIOC_QUERYSTD           );
1151+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_TRY_FMT            ) = %ld\n", VIDIOC_TRY_FMT            );
1152+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMAUDIO          ) = %ld\n", VIDIOC_ENUMAUDIO          );
1153+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUMAUDOUT         ) = %ld\n", VIDIOC_ENUMAUDOUT         );
1154+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_PRIORITY         ) = %ld\n", VIDIOC_G_PRIORITY         );
1155+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_PRIORITY         ) = %ld\n", VIDIOC_S_PRIORITY         );
1156+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_SLICED_VBI_CAP   ) = %ld\n", VIDIOC_G_SLICED_VBI_CAP   );
1157+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_LOG_STATUS         ) = %ld\n", VIDIOC_LOG_STATUS         );
1158+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_EXT_CTRLS        ) = %ld\n", VIDIOC_G_EXT_CTRLS        );
1159+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_EXT_CTRLS        ) = %ld\n", VIDIOC_S_EXT_CTRLS        );
1160+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_TRY_EXT_CTRLS      ) = %ld\n", VIDIOC_TRY_EXT_CTRLS      );
1161+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_FRAMESIZES    ) = %ld\n", VIDIOC_ENUM_FRAMESIZES    );
1162+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_FRAMEINTERVALS) = %ld\n", VIDIOC_ENUM_FRAMEINTERVALS);
1163+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_ENC_INDEX        ) = %ld\n", VIDIOC_G_ENC_INDEX        );
1164+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENCODER_CMD        ) = %ld\n", VIDIOC_ENCODER_CMD        );
1165+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_TRY_ENCODER_CMD    ) = %ld\n", VIDIOC_TRY_ENCODER_CMD    );
1166+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_HW_FREQ_SEEK     ) = %ld\n", VIDIOC_S_HW_FREQ_SEEK     );
1167+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_CREATE_BUFS        ) = %ld\n", VIDIOC_CREATE_BUFS        );
1168+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_PREPARE_BUF        ) = %ld\n", VIDIOC_PREPARE_BUF        );
1169+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_G_SELECTION        ) = %ld\n", VIDIOC_G_SELECTION        );
1170+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_S_SELECTION        ) = %ld\n", VIDIOC_S_SELECTION        );
1171+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_DECODER_CMD        ) = %ld\n", VIDIOC_DECODER_CMD        );
1172+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_TRY_DECODER_CMD    ) = %ld\n", VIDIOC_TRY_DECODER_CMD    );
1173+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_DV_TIMINGS    ) = %ld\n", VIDIOC_ENUM_DV_TIMINGS    );
1174+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_QUERY_DV_TIMINGS   ) = %ld\n", VIDIOC_QUERY_DV_TIMINGS   );
1175+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_DV_TIMINGS_CAP     ) = %ld\n", VIDIOC_DV_TIMINGS_CAP     );
1176+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_ENUM_FREQ_BANDS    ) = %ld\n", VIDIOC_ENUM_FREQ_BANDS    );
1177+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_DBG_G_CHIP_INFO    ) = %ld\n", VIDIOC_DBG_G_CHIP_INFO    );
1178+    printk("cyyanl v4l2 ioctl cmd(VIDIOC_QUERY_EXT_CTRL     ) = %ld\n", VIDIOC_QUERY_EXT_CTRL     );
1179+    printk("cyyanl v4l2 ioctl cmd(BASE_VIDIOC_PRIVATE       ) = %ld\n", BASE_VIDIOC_PRIVATE       );
1180+    printk("*************************************************************************************");
1181+}
1182+
1183 static int __init uvc_init(void)
1184 {
1185 	int ret;
1186-
1187+    printk("cyyanl enter uvc_init\n");
1188+    cyyanl_printk_cmd();
1189 	uvc_debugfs_init();
1190
1191 	ret = usb_register(&uvc_driver.driver);
1192```
1193
1194Printing result comparison: **VIDIOC_QUERYBUF** is **0xc0505609** in user state and **0xc0585609** in kernel state. There are several other inconsistent command codes.
1195
1196![](figures/isoftstone/yangfan-print-01.png)
1197
1198Analyze the cause for command code inconsistency. First, find the differences during compilation of **VIDIOC_QUERYBUF** in user state and kernel state.
1199
1200User state: kernel/linux/patches/linux-5.10/prebuilts/usr/include/linux/videodev2.h +1358
1201
1202Kernel state: kernel/linux/linux-4.19/include/uapi/linux/videodev2.h +2361
1203
1204The possible cause is that **VIDIOC_QUERYBUF** inconsistency is caused by header file differences. (Currently, whether the issue can be solved by using linux-4.19 is not verified.) Seek help from the customer and check whether there are similar issues in OpenHarmony.
1205
1206A similar issue is found: https://gitee.com/openharmony/drivers_peripheral/issues/I4NI4M?from=project-issue
1207
1208
1209Now, there are two debugging ideas:
1210
12111. Unify **VIDIOC_QUERYBUF** in user state with that in kernel state.
1212
1213   Solution: Change **0xc0505609** in user state to **0xc0585609** in kernel state.
1214
1215   Modification: drivers/peripheral
1216
1217   ```diff
1218   diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cpp b/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cpp
1219   index d7dd15f..f7254b4 100644
1220   --- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cpp
1221   +++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cpp
1222                    buf.m.planes = planes;
1223                    buf.length = 1;
1224                }
1225   -            CAMERA_LOGD("V4L2_MEMORY_USERPTR Print the cnt: %{public}d\n", buf.index);
1226   -
1227   -            if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) {
1228   -                CAMERA_LOGE("error: ioctl VIDIOC_QUERYBUF failed: %{public}s\n", strerror(errno));
1229   +            if (ioctl(fd, /*VIDIOC_QUERYBUF*/0xc0585609, &buf) < 0) {
1230   +                CAMERA_LOGE("error: ioctl VIDIOC_QUERYBUF failed.\n");
1231                    return RC_ERROR;
1232                }
1233   ```
1234
1235   Run **v4l2_main** again. Result: Signal 4 reports an error.
1236
1237   Cause analysis: **ioctl(fd, /*****VIDIOC_QUERYBUF*****/0xc0585609, &buf)** is successful. According to Signal 4 analysis, the error is possibly still caused by the command codes of **cmd**.
1238
1239   This idea can solve the current issue, but it will cause a new Signal 4 error.
1240
1241   ```
1242   INFO:main test:allocating display buffer memory
1243   INFO:main test:do_mmap: pmem mmap fd 5 ptr 0xf7508000 len 2457600
1244   INFO:V4L2OpenDevice /dev/video10
1245   INFO:V4L2ReqBuffers buffCont 4
1246   INFO:Creatbuffer frameSpec->buffer index == 0
1247   INFO:V4L2AllocBuffer
1248   Signal 4
1249   ```
1250
12512. Analyze the root cause of command code inconsistency and make modifications.
1252
1253   Cause analysis: The size of the structure varies according to the 32-bit and 64-bit compilation, which affects the value of **VIDIOC_QUERYBUF**.
1254
1255   Modification: Modify the timestamp definition of the **v4l2_buffer** structure compiled in user state, and replace the header file **#include <linux/videodev2.h>** compiled in user state with
1256
1257   the modified **videodev2.h** file, that is, **#include "videodev2.h"**. (The actual operation is to copy the modified **videodev2.h** file to the **v4l2_main** compilation directory.)
1258
1259   kernel/linux/linux-4.19/
1260
1261   ```diff
1262   diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
1263   index ba548d7f0..b0fb48f65 100644
1264   --- a/include/uapi/linux/videodev2.h
1265   +++ b/include/uapi/linux/videodev2.h
1266   @@ -958,13 +958,20 @@ struct v4l2_plane {
1267     * Contains data exchanged by application and driver using one of the Streaming
1268     * I/O methods.
1269     */
1270   +
1271   +struct timeval_user {
1272   +    long tv_sec;
1273   +    long tv_usec;
1274   +};
1275   +
1276    struct v4l2_buffer {
1277           __u32                   index;
1278           __u32                   type;
1279           __u32                   bytesused;
1280           __u32                   flags;
1281           __u32                   field;
1282   -       struct timeval          timestamp;
1283   +       //struct timeval                timestamp;
1284   +       struct timeval_user             timestamp;
1285           struct v4l2_timecode    timecode;
1286           __u32                   sequence;
1287
1288   ```
1289
1290   drivers/peripheral
1291
1292   ```diff
1293   diff --git a/camera/hal/adapter/chipset/rpi/rpi3/device/camera/src/driver_adapter/main_test/project_v4l2_main.h b/camera/hal/adapter/chipset/rpi/rpi3/device/camera/src/driver_adapter/main_test/project_v4l2_main.h
1294   index 00ddea7..962ebc3 100755
1295   --- a/camera/hal/adapter/chipset/rpi/rpi3/device/camera/src/driver_adapter/main_test/project_v4l2_main.h
1296   +++ b/camera/hal/adapter/chipset/rpi/rpi3/device/camera/src/driver_adapter/main_test/project_v4l2_main.h
1297   @@ -15,7 +15,8 @@
1298
1299    #ifndef HOS_CAMERA_PROJET_HARDWARE_H
1300    #define HOS_CAMERA_PROJET_HARDWARE_H
1301   -#include <linux/videodev2.h>
1302   +//#include <linux/videodev2.h>
1303   +#include "videodev2.h"
1304
1305    namespace OHOS::Camera {
1306    #define PREVIEW_PIXEL_FORMAT V4L2_PIX_FMT_YUV420
1307   diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_buffer.h b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_buffer.h
1308   index 6f45882..a8d6819 100644
1309   --- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_buffer.h
1310   +++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_buffer.h
1311   @@ -19,7 +19,8 @@
1312    #include <mutex>
1313    #include <map>
1314    #include <cstring>
1315   -#include <linux/videodev2.h>
1316   +//#include <linux/videodev2.h>
1317   +#include "videodev2.h"
1318    #include <sys/ioctl.h>
1319    #include "v4l2_common.h"
1320    #if defined(V4L2_UTEST) || defined (V4L2_MAIN_TEST)
1321   diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_control.h b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_control.h
1322   index 5b93f36..05191a7 100644
1323   --- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_control.h
1324   +++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_control.h
1325   @@ -16,7 +16,8 @@
1326    #ifndef HOS_CAMERA_V4L2_CONTROL_H
1327    #define HOS_CAMERA_V4L2_CONTROL_H
1328
1329   -#include <linux/videodev2.h>
1330   +//#include <linux/videodev2.h>
1331   +#include "videodev2.h"
1332    #include <errno.h>
1333    #include <sys/ioctl.h>
1334    #include "v4l2_common.h"
1335   diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_dev.h b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_dev.h
1336   index 10dc9b4..e3b3056 100644
1337   --- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_dev.h
1338   +++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_dev.h
1339   @@ -19,7 +19,8 @@
1340    #include <mutex>
1341    #include <thread>
1342    #include <vector>
1343   -#include <linux/videodev2.h>
1344   +//#include <linux/videodev2.h>
1345   +#include "videodev2.h"
1346    #include <sys/epoll.h>
1347    #include <sys/ioctl.h>
1348    #include <sys/types.h>
1349   diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_fileformat.h b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_fileformat.h
1350   index de892e9..44bb1b4 100644
1351   --- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_fileformat.h
1352   +++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_fileformat.h
1353   @@ -19,7 +19,8 @@
1354    #include <vector>
1355    #include <cstring>
1356    #include <fcntl.h>
1357   -#include <linux/videodev2.h>
1358   +//#include <linux/videodev2.h>
1359   +#include "videodev2.h"
1360    #include <sys/ioctl.h>
1361    #include <sys/stat.h>
1362    #include <unistd.h>
1363   diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_uvc.h b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_uvc.h
1364   index 1a62f37..96c70aa 100644
1365   --- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_uvc.h
1366   +++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/v4l2_uvc.h
1367   @@ -18,7 +18,8 @@
1368    #include <thread>
1369    #include <fcntl.h>
1370    #include <linux/netlink.h>
1371   -#include <linux/videodev2.h>
1372   +//#include <linux/videodev2.h>
1373   +#include "videodev2.h"
1374    #include <sys/ioctl.h>
1375    #include <sys/select.h>
1376    #include <linux/netlink.h>zz
1377   diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp b/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp
1378   index b351f49..5483b85 100755
1379   --- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp
1380   +++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp
1381   @@ -22,7 +22,8 @@
1382    #include <sys/mman.h>
1383    #include <sys/time.h>
1384    #include <linux/fb.h>
1385   -#include <linux/videodev2.h>
1386   +//#include <linux/videodev2.h>
1387   +#include "videodev2.h"
1388    #include "securec.h"
1389    #include "v4l2_uvc.h"
1390    #include "v4l2_dev.h"
1391   diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_stream.cpp b/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_stream.cpp
1392   index 778cf05..96618be 100644
1393   --- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_stream.cpp
1394   +++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/src/v4l2_stream.cpp
1395   @@ -14,7 +14,8 @@
1396     */
1397
1398    #include <cstring>
1399   -#include <linux/videodev2.h>
1400   +//#include <linux/videodev2.h>
1401   +#include "videodev2.h"
1402    #include <sys/ioctl.h>
1403
1404    #include "v4l2_stream.h"
1405   diff --git a/camera/hal/test/v4l2/include/test_display.h b/camera/hal/test/v4l2/include/test_display.h
1406   index d437e26..8e5205e 100644
1407   --- a/camera/hal/test/v4l2/include/test_display.h
1408   +++ b/camera/hal/test/v4l2/include/test_display.h
1409   @@ -44,7 +44,8 @@
1410    #include <errno.h>
1411    #include <getopt.h>
1412    #include <linux/fb.h>
1413   -#include <linux/videodev2.h>
1414   +//#include <linux/videodev2.h>
1415   +#include "videodev2.h"
1416    #include <mutex>
1417    #include <pthread.h>
1418    #include <stdlib.h>
1419   @@ -138,4 +139,4 @@ public:
1420        void StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming);
1421        float calTime(struct timeval start, struct timeval end);
1422    };
1423   -#endif
1424   \ No newline at end of file
1425   +#endif
1426   ```
1427
1428   Compile **v4l2_main** again and execute it. No error is recorded in logs. The HDMI screen displays the preview image.
1429
1430
1431
1432According to the entire debugging process, the camera supports the YUYV and MJPEG formats. By default, preview in **v4l2_main** uses the YUYV format. Change the format to MJPEG and try again.
1433
1434Modification:
1435
1436```diff
1437diff --git a/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp b/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp
1438index b351f49..5483b85 100755
1439--- a/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp
1440+++ b/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test/v4l2_main.cpp
1441@@ -394,7 +395,9 @@ void V4L2SetDeviceFormat(DeviceFormat& format, const std::string devname)
1442
1443     if (devname == "uvcvideo" || devname == "uvcvideo1") {
1444         if (g_isPreviewOnUvc) {
1445-            format.fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
1446+            CAMERA_LOGD("cyyanl enter V4L2SetDeviceFormat : g_isPreviewOnUvc\n");
1447+            //format.fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
1448+            format.fmtdesc.pixelformat = V4L2_PIX_FMT_MJPEG;
1449             format.fmtdesc.width = width;
1450             format.fmtdesc.height = height;
1451         }
1452```
1453
1454Execution result of **v4l2_main**: The display is abnormal. Currently, do not analyze the MJPEG format.
1455
1456![](figures/isoftstone/yangfan-picture-v4l2_main.png)
1457
1458
1459
1460So far, **v4l2_main** runs properly and images can be previewed. (The abnormal color of the preview image is related to the screen display format and does not need to be modified currently.) Next, debug photographing and video recording.
1461
1462After **v4l2_main** is executed, enter **u** to preview the UVC, run **c** to take photos, and then run **v** to record videos. The photo and video files are generated in the current execution path.
1463
1464```
1465# ls -l *.jpeg
1466-rwxrw-rw- 1 root 29034400 614400 2013-01-18 15:20 UVC0.jpeg
1467-rwxrw-rw- 1 root 29034400 614400 2013-01-18 15:20 UVC1.jpeg
1468-rwxrw-rw- 1 root 29034400 614400 2013-01-18 15:20 UVC2.jpeg
1469-rwxrw-rw- 1 root 29034400 614400 2013-01-18 15:20 UVC3.jpeg
1470#
1471# ls -l *.h264
1472-rwxrw-rw- 1 root 29034400 85401600 2013-01-18 15:20 uvc.h264
1473```
1474
1475Export the preceding files to the PC and check them.
1476
1477image **uvc0.jpeg**
1478
1479![](figures/isoftstone/yangfan-picture-uvc0.png)
1480
1481The video file **uvc.h264** can be viewed on the mobile phone and played properly.
1482
1483### Appendixes
1484
1485```c
1486/**
1487 * struct v4l2_buffer - video buffer info
1488 * @index:  id number of the buffer
1489 * @type:   enum v4l2_buf_type; buffer type (type == *_MPLANE for
1490 *      multiplanar buffers);
1491 * @bytesused:  number of bytes occupied by data in the buffer (payload);
1492 *      unused (set to 0) for multiplanar buffers
1493 * @flags:  buffer informational flags
1494 * @field:  enum v4l2_field; field order of the image in the buffer
1495 * @timestamp:  frame timestamp
1496 * @timecode:   frame timecode
1497 * @sequence:   sequence count of this frame
1498 * @memory: enum v4l2_memory; the method, in which the actual video data is
1499 *      passed
1500 * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
1501 *      offset from the start of the device memory for this plane,
1502 *      (or a "cookie" that should be passed to mmap() as offset)
1503 * @userptr:    for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
1504 *      a userspace pointer pointing to this buffer
1505 * @fd:     for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF;
1506 *      a userspace file descriptor associated with this buffer
1507 * @planes: for multiplanar buffers; userspace pointer to the array of plane
1508 *      info structs for this buffer
1509 * @length: size in bytes of the buffer (NOT its payload) for single-plane
1510 *      buffers (when type != *_MPLANE); number of elements in the
1511 *      planes array for multi-plane buffers
1512 *
1513 * Contains data exchanged by application and driver using one of the Streaming
1514 * I/O methods.
1515 */
1516
1517struct v4l2_buffer {
1518    __u32           index;
1519    __u32           type;
1520    __u32           bytesused;
1521    __u32           flags;
1522    __u32           field;
1523    struct timeval    timestamp;
1524    struct v4l2_timecode    timecode;
1525    __u32           sequence;
1526
1527    /* memory location */
1528    __u32           memory;
1529    union {
1530        __u32           offset;
1531        unsigned long   userptr;
1532        struct v4l2_plane *planes;
1533        __s32       fd;
1534    } m;
1535    __u32           length;
1536    __u32           reserved2;
1537    __u32           reserved;
1538}
1539```
1540
1541##     TP
1542
1543### TP Driver Model
1544
1545This model mainly defines and implements the following types of Hardware Driver Interfaces (HDIs) of the input module, allowing upper-layer input services to perform operations for the input devices:
1546
1547- **Input Manager**: manages input devices, including enabling and disabling input devices and obtaining the device list.
1548- **Input Reporter**: reports input events, including registering and unregistering data reporting callbacks.
1549- **Input Controller**: controls input devices, including obtaining the device information and device type, and setting power status.
1550
1551**Figure 1** HDI architecture of the input module
1552
1553![dayu200-tp-01.png](figures/dayu200/dayu200-tp-01.png)
1554
1555The source code directory structure is as follows:
1556
1557```
1558/drivers/peripheral/input
1559├── hal                # HAL code
1560│   └── include       # HAL header files
1561│   └── src           # HAL code implementation
1562├── interfaces         # Driver capability APIs provided for upper-layer services
1563│   └── include       # APIs exposed
1564├── test               # Test code
1565│   └── unittest      # Unit test code
1566```
1567
1568For details, see [README](https://gitee.com/openharmony/drivers_peripheral/blob/master/input/README_zh.md) of the input subsystem.
1569
1570### TP HDF Driver Adaptation
1571
1572#### Configuration Adaptation
1573
1574Disable the Linux TP driver by disabling **TOUCHSCREEN_GT9XX** in the **<rockchip_linux_defconfig>** file. Specifically, change **CONFIG_TOUCHSCREEN_GT9XX=y** as follows:
1575```makefile
1576# CONFIG_TOUCHSCREEN_GT9XX is not set
1577```
1578#### Driver Adaptation
1579
15801. Modify content in **vendor/rockchip/rk3399/hdf_config/khdf/device_info/device_info.hcs** as follows or add the following content to the file:
1581
1582   ```json
1583   	device_touch_chip :: device {
1584               device0 :: deviceNode {
1585                   policy = 0;
1586                   priority = 130;
1587                   preload = 0;
1588                   permission = 0660;
1589                   moduleName = "HDF_TOUCH_GT911";
1590                   serviceName = "hdf_touch_gt911_service";
1591                   deviceMatchAttr = "zsj_gt911_5p5";
1592               }
1593           }
1594   ```
1595
1596
1597
15982. Modify content in **vendor/rockchip/rk3399/hdf_config/khdf/input/input_config.hcs** as follows or add the following content to the file:
1599
1600   ```json
1601    busConfig {
1602        // 0:i2c 1:spi
1603        busType = 0;                            // I2C communication method
1604        busNum = 7;							 // I2C code of the touch chip corresponding to the CPU
1605        clkGpio = 72;							 // I/O pin code corresponding to I2C clk
1606        dataGpio = 71;							 // I/O pin code corresponding to I2C data
1607        i2cClkIomux = [0xFF77E004, 0x2];		 // I2C [reuse register corresponding to the clk pin, which is configured to the I2C7_clk function]
1608        i2cDataIomux = [0xFF77E000, 0x8000];	 // I2C [reuse register corresponding to the data pin, which is configured to the I2C7_DATA function]
1609    }
1610
1611    pinConfig {
1612        rstGpio = 150;							// I/O pin code corresponding to rst of the touch chip
1613        intGpio = 52;							// I/O pin code corresponding to int of the touch chip
1614        rstRegCfg = [0xFF77E028, 0x00000000];	// Reuse register corresponding to the rst pin, which is configured to the common I/O port
1615        intRegCfg = [0xFF770018, 0x00000000];	// Reuse register corresponding to the int pin, which is configured to the common I/O port
1616    }
1617   ```
1618#### FAQs
1619
1620##### How to solve the problem that the portrait and landscape modes are reversed for the touchscreen?
1621
1622Modify the **ParsePointData** function in **drivers/framework/model/input/driver/touchscreen/touch_gt911.c** to exchange the position of **x** and **y**.
1623
1624##### Modify the **InputPinMuxCfg** function:
1625
1626```c
1627static int32_t InputPinMuxCfg(uint32_t regAddr, int32_t regSize, uint32_t regValue)
1628{
1629    uint8_t *base = NULL;
1630    uint32_t data = 0;
1631    if (regAddr == 0) {
1632        HDF_LOGE("%s: regAddr invalid", __func__);
1633        return HDF_FAILURE;
1634    }
1635
1636    HDF_LOGE("regAddr = 0x%x, regSize = 0x%x", regAddr, regSize);
1637    base = OsalIoRemap(regAddr, regSize);
1638    if (base == NULL) {
1639        HDF_LOGE("%s: ioremap failed", __func__);
1640        return HDF_FAILURE;
1641    }
1642    // Read and save the original configurations before writing new configurations to the register. Modify the original other pin function configurations.
1643    data = OSAL_READL(base);
1644    data |= regValue;
1645    OSAL_WRITEL(data, base);
1646    OsalIoUnmap((void *)base);
1647    return HDF_SUCCESS;
1648}
1649```
1650
1651##### How to determine the pin GPIOn_KK code of RK3399?
1652
1653```shell
1654num = 32n+(K-A)8+X
1655# GPIO1_B2 = 1 * 32 + (B-A)*8 + 2 = 32 + 8 + 1 = 42
1656```
1657
1658| Function  | I/O Name  | I/O Code|
1659| ------ | -------- | ------ |
1660| TP_INT | GPIO1_C4 | 52     |
1661| TP_RST | GPIO4_C6 | 150    |
1662| TP_SDA | GPIO2_A7 | 71     |
1663| TP_SCL | GPIO2_B0 | 72     |
1664
1665
1666
1667##### How to configure the pin GPIOn_KX reuse function of RK3399?
1668
16691. Find the base address of the GPIO reuse function register, which is **FF77_0000**.
16702. Find the register offset of the GPIOn_K reuse function.
16713. Determine the GPIOn_K reuse function register by **adding the base address and offset**.
16724. Write the reuse function of the corresponding pin based on the reuse function register introduction.
1673
1674| Function  | I/O Name  | Reuse Register Address| Control Bit| Value           |
1675| ------ | -------- | -------------- | ------ | ------------------- |
1676| TP_INT | GPIO1_C4 | 0xFF770018     | 9:8    | 2'b00: GPIO        |
1677| TP_RST | GPIO4_C6 | 0xFF77E028     | 13:12  | 2'b00: GPIO        |
1678| TP_SDA | GPIO2_A7 | 0xFF77E000     | 15:14  | 2'b10: i2c7nfc_sda|
1679| TP_SCL | GPIO2_B0 | 0xFF77E004     | 1:0    | 2'b10: i2c7nfc_scl|
1680