android的底层驱动调试心得

一、串口

1、验证小系统是否跑起来,如果没反应,可以多尝试几个串口,有的串口可能不支持这个,注意看波特率,一般会在dts文件有个debugger函数。上面有这个波特率的说明,包含115200 1500000等。然后就看打印信息,查看TX、RX线对了吗。

二、查看gpio的状态

进入adb shell抓取gpio的状态
先要切换为su模式

cat sys/kernel/debug/gpio
或者在根目录下
cat /d/gpio

就能看到下面这些东西,对应的gpio的状态

k66_qls_cnt:/ # cat /d/gpio
gpiochip0: GPIOs 0-31, parent: platform/fdd60000.gpio, gpio0:
 gpio-5   (                    |vcc5v0_otg          ) out lo    
 gpio-13  (                    |gsl-irq-port        ) in  lo    
 gpio-14  (                    |gsl-wake-port       ) out hi       
 gpio-21  (                    |pwrg-int            ) out hi    

gpiochip1: GPIOs 32-63, parent: platform/fe740000.gpio, gpio1:
 gpio-61  (                    |eeprom-wp           ) out lo    
 gpio-62  (                    |led_r               ) out lo    
 gpio-63  (                    |led_g               ) out hi    

gpiochip2: GPIOs 64-95, parent: platform/fe750000.gpio, gpio2:
 gpio-73  (                    |reset               ) out lo    
 gpio-77  (                    |bt_default_rts      ) in  hi    

gpiochip3: GPIOs 96-127, parent: platform/fe760000.gpio, gpio3:
 gpio-98  (                    |bat_det_gpio        ) in  lo    
 gpio-100 (                    |lte-usben           ) out hi   

这些gpio都是通过pinctrl控制了的,我们不能通过命令行改变状态的。
还有一些gpio我们可以控制

rk66_qls_cnt:/ # cd sys/class/gpio/ 

在这个目录下有一些gpio我们可以通过以下命令控制

rk66_qls_cnt:/sys/class/gpio # ls
export  gpiochip0  gpiochip128  gpiochip255  gpiochip32  gpiochip64  gpiochip96  unexport

我们想要取控制gpio88就只需要去加载这个gpio

rk66_qls_cnt:/sys/class/gpio # echo 88 > export 

当然这个gpio是通过刚才那个cat /d/gpio不能看到的

rk66_qls_cnt:/sys/class/gpio # ls                                                                                                                   
export  gpio88  gpiochip0  gpiochip128  gpiochip255  gpiochip32  gpiochip64  gpiochip96  unexport

可以看到在这个gpio下面多了一个gpio88我们进入这个gpio88
设置输入输出模式

rk66_qls_cnt:/sys/class/gpio/gpio88 # echo out/in > direction

设置高低电平

rk66_qls_cnt:/sys/class/gpio/gpio88 # echo 0/1 > value

再去测量板子上对应的gpio就会看到电平的变化

三、gpio的计算

在rockchip里面,gpio分组为32一组,每组4对,每队8个
举个例子:

GPIO0_B4 被描述为:<&gpio0 12 >
GPIO0对应gpio0,B4对应12。
计算公式:(x)*8+(y)=12这里的x对应GOIO的ABCD组(A为0,B为1,C为2,D为3)(y)是组数后面的数字,这里为4。
GPIO3_A3 = <&gpio3 3>;GPIO3_C5= <&gpio3 21>
之前说过的gpio100这个只需要把gpio换成对应的数字就好。
比如 <&gpio3 3>
gpio3的开头是96,所以GPIO3_A3也可以说是gpio99。
GPIO0_B4对应gpio12。

gpiochip0: GPIOs 0-31,
gpiochip1: GPIOs 32-63
gpiochip2: GPIOs 64-95
gpiochip3: GPIOs 96-127
gpiochip4: GPIOs 128-159

这里就是每组32个,每一组的开头和结尾都写出来了

四、调试背光

核对GPIO口,找到使能gpio.
相关代码

backlight: backlight {
		compatible = "pwm-backlight";
		pwms = <&pwm4 0 25000 0>;
		brightness-levels = <
			  0  20  20  21  21  22  22  23
			 23  24  24  25  25  26  26  27
			 27  28  28  29  29  30  30  31
			 31  32  32  33  33  34  34  35
			 35  36  36  37  37  38  38  39
			 40  41  42  43  44  45  46  47
			 48  49  50  50  51  52  53  54
			 55  55  56  57  58  59  60  61
			 62  63  64  64  65  65  66  67
			 68  69  70  71  71  72  73  74
			 75  76  77  78  79  79  80  81
			 82  83  84  85  86  86  87  88
			 89  90  91  92  93  94  94  95
			 96  97  98  99 100 101 101 102
			103 104 105 106 107 107 108 109
			110 111 112 113 114 115 115 116
			117 118 119 120 121 122 123 123
			124 125 126 127 128 129 130 130
			131 132 133 134 135 136 136 137
			138 139 140 141 142 143 143 144
			145 146 147 147 148 149 150 151
			152 153 154 155 156 156 157 158
			159 157 158 159 160 161 162 162
			163 164 165 166 167 168 169 169
			170 171 172 173 174 175 175 176
			177 178 179 180 181 182 182 183
			184 185 186 187 188 189 190 190
			191 192 193 194 195 196 197 197
			198 199 200 201 202 203 204 204
			205 206 207 208 209 209 210 211
			212 213 213 214 214 215 215 216
			216 217 217 218 218 219 219 220
		>;
		default-brightness-level = <200>;
		/*自己设置GPIO,也要看驱动里面使用没有这个GPIO,或者硬件怎么连接的*/
        	enable-gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;		
    };

可以自己取通过cat对应的gpio的状态;然后看屏幕的背光是否亮起来。

五、调试屏幕

1)判断是mipi的屏幕还是lvds或者都要使用
如如果是mipi则需要向厂家要开屏指令

adb查看对应的驱动是否挂载
cat /sys/class/graphics/fb0 查看lvds的驱动是否挂载如果有则会出现fb0(目前来看是这样)
也可以在驱动里面增加打印信息,判断你的驱动是否加载,然后就看接口是否打开。
比如lvds_phy0或者lvds_phy1这些是的状态是okay还是disabled

首先你的屏幕亮起来在去看这个屏幕参数,出现花频闪屏就是参数有问题,如果屏幕都没亮就是gpio或者上电时序都没对,然后就可找硬件同事去查看电压对不对,最后调参数。

&lvds_phy0 {
	status = "okay";
};

屏幕参数的代码

panel@0 {
		compatible = "aoly,sl008pa21y1285-b00", "simple-panel-dsi";
		/* 这个一般是默认,不会改*/
		reg = <0>;
		backlight = <&backlight>;
		/*需要自己取核对IO口,注意是高有效还是低有效*/
		enable-gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
		reset-gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>;
		pinctrl-names = "default";
		pinctrl-0 = <&lcd_enable_gpio>, <&lcd_rst_gpio>;
		/*这个是上电时序*/
		prepare-delay-ms = <120>;
		reset-delay-ms = <120>;
		init-delay-ms = <120>;
		stbyb-delay-ms = <120>;
		enable-delay-ms = <120>;
		disable-delay-ms = <120>;
		unprepare-delay-ms = <120>;
		/*屏幕的宽和高需要看对应的手册*/
		width-mm = <229>;
		height-mm = <143>;
		
		dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
			      MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
		dsi,format = <MIPI_DSI_FMT_RGB888>;
		dsi,lanes = <4>;
		/*如果是mipi的屏幕就需要原厂提供参数,如果是lvds则不需要*/
		panel-init-sequence = [
			23 00 02 B0 01
			23 00 02 C3 0F
			23 00 02 C4 00
			23 00 02 C5 00
			23 00 02 C6 00
			23 00 02 C7 00
			23 00 02 C8 0D
			23 00 02 C9 12
			23 00 02 CA 11
			23 00 02 CD 1D
			23 00 02 CE 1B
			23 00 02 CF 0B
			23 00 02 D0 09
			23 00 02 D1 07
			23 00 02 D2 05
			23 00 02 D3 01
			23 00 02 D7 10
			23 00 02 D8 00
			23 00 02 D9 00
			23 00 02 DA 00
			23 00 02 DB 00
			23 00 02 DC 0E
			23 00 02 DD 12
			23 00 02 DE 11
			23 00 02 E1 1E
			23 00 02 E2 1C
			23 00 02 E3 0C
			23 00 02 E4 0A
			23 00 02 E5 08
			23 00 02 E6 06
			23 00 02 E7 02
			23 00 02 B0 03
			23 00 02 BE 03
			23 00 02 CC 44
			23 00 02 C8 07
			23 00 02 C9 05
			23 00 02 CA 42
			23 00 02 CD 3E
			23 00 02 CF 60
			23 00 02 D2 04
			23 00 02 D3 04
			23 00 02 D4 01
			23 00 02 D5 00
			23 00 02 D6 03
			23 00 02 D7 04
			23 00 02 D9 01
			23 00 02 DB 01
			23 00 02 E4 F0
			23 00 02 E5 0A
			23 00 02 B0 00
			23 00 02 BA 8F
			23 00 02 BD 63
			23 00 02 C2 08
			23 00 02 C4 10
			23 00 02 B0 02
			23 00 02 C0 00
			23 00 02 C1 0A
			23 00 02 C2 20
			23 00 02 C3 24
			23 00 02 C4 23
			23 00 02 C5 29
			23 00 02 C6 23
			23 00 02 C7 1C
			23 00 02 C8 19
			23 00 02 C9 17
			23 00 02 CA 17
			23 00 02 CB 18
			23 00 02 CC 1A
			23 00 02 CD 1E
			23 00 02 CE 20
			23 00 02 CF 23
			23 00 02 D0 07
			23 00 02 D1 00
			23 00 02 D2 00
			23 00 02 D3 0A
			23 00 02 D4 13
			23 00 02 D5 1C
			23 00 02 D6 1A
			23 00 02 D7 13
			23 00 02 D8 17
			23 00 02 D9 1C
			23 00 02 DA 19
			23 00 02 DB 17
			23 00 02 DC 17
			23 00 02 DD 18
			23 00 02 DE 1A
			23 00 02 DF 1E
			23 00 02 E0 20
			23 00 02 E1 23
			23 00 02 E2 07

			05 78 01 11
			05 32 01 29
		];
		
		panel-exit-sequence = [
			05 dc 01 28
			05 78 01 10
		];
		/*下面需要自己查看手册*/
		display-timings {
			native-mode = <&timing0>;
			timing0: timing0 {
				/* 时钟频率*/
				clock-frequency = <512000000>;
				/*这个就是屏幕的分辨率*/
				hactive = <1024>;
				vactive = <600>;
				/*对应的参数,需要修改*/
				hsync-len = <140>;
				hback-porch = <160>;
				hfront-porch = <160>;

				vsync-len = <20>;
				vback-porch = <23>;
				vfront-porch = <12>;
				/*默认低电平有效*/
				hsync-active = <0>;
				vsync-active = <0>;
				de-active = <0>;
				pixelclk-active = <0>;
			};
		};

2)、找到自己的屏幕的手册
其中以下参数根据屏的规格书填写:

hactive = <480>;        // 分辨率-宽
vactive = <854>;        // 分辨率-高

hsync-len = <24>;       // 行同步肪冲宽度	单位:像素时钟周期	也有手册简称为HWH(HSYNC width)	
hback-porch = <24>;     // 行可视范围前肩	HBP在每行或每列的象素数据开始输出时要插入的象素时钟周期数
hfront-porch = <72>;    // 行可视范围后肩	HFP在每行或每列的象素结束到LCD 行时钟输出脉冲之间的象素时钟数

vsync-len = <2>;        // 场同步脉冲宽度	单位:显示一行的时间th	也有手册简称为VWH(VSYNC width)
vback-porch = <10>;     // 帧可视前肩		vbp在垂直同步周期之后帧开头时的无效行数
vfront-porch = <12>;    // 帧可视后肩		vfp本帧数据输出结束到下一帧垂直同步周期开始之前的无效行数

以下参数表示对应信号的有效电平,默认为低电平(0):

hsync-active = <0>;     // 行同步信号
vsync-active = <0>;     // 场同步信号
de-active = <0>;        // de信号
pixelclk-active = <0>;  // clk信号

pinctrl的配置

    lcd {
        lcd_rst_gpio: lcd-rst-gpio {
            rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;    
        };

        lcd_enable_gpio: lcd-enable-gpio {
            rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;    
        };

        lcd_stb_gpio: lcd_stb_gpio {
                rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;   
            };
    }; 

4、调试wifi蓝牙模块

相关代码:

sdio_pwrseq: sdio-pwrseq {
		compatible = "mmc-pwrseq-simple";
		/*不同的pmic这里不一样*/		
		clocks = <&rk817 1>;
		clock-names = "ext_clock";
		pinctrl-names = "default";
		pinctrl-0 = <&wifi_enable_h>;

		/*
		 * On the module itself this is one of these (depending
		 * on the actual card populated):
		 * - SDIO_RESET_L_WL_REG_ON
		 * - PDN (power down when low)
		 */
		 post-power-on-delay-ms = <200>;
		/*这个reg-on的gpio比较重要,这个一定要配置对,注意看上面的注释,低有效还是高有效*/
		 reset-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>;     
		 
	/*这个是wifi唤醒角,这个看你自己的需求*/
	wireless-wlan {
		compatible = "wlan-platdata";
		rockchip,grf = <&grf>;
		wifi_chip_type = "ap6256";
		pinctrl-names = "default";
		pinctrl-0 = <&wifi_host_wake_irq>;
		WIFI,host_wake_irq = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;		
		status = "okay";
	};
	/*这是蓝牙的gpio配置*/
	wireless-bluetooth {
		compatible = "bluetooth-platdata";
		clocks = <&rk817 1>;
		clock-names = "ext_clock";
		//wifi-bt-power-toggle;
		uart_rts_gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>;		
		pinctrl-names = "default", "rts_gpio";
		pinctrl-0 = <&uart1m0_rtsn>,
                   	<&bt_reset_gpio>,
			<&bt_wake_gpio>,
			<&bt_irq_gpio>;
		pinctrl-1 = <&uart1_gpios>;
		BT,reset_gpio    = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;	
		BT,wake_gpio     = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;	
		BT,wake_host_irq = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;	
		status = "okay";
	};

/*这是pinctrl的相关配置*/
&pinctrl {
	sdio-pwrseq {
		wifi_enable_h: wifi-enable-h {
			rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;	
		};
	};

	wireless-wlan {
		wifi_host_wake_irq: wifi-host-wake-irq {
			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;	
		};
	};

	wireless-bluetooth {
		uart1_gpios: uart1-gpios {
			rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;	
		};

		bt_reset_gpio: bt-reset-gpio {
			rockchip,pins =
				<2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;	
		};

		bt_wake_gpio: bt-wake-gpio {
			rockchip,pins =
				<2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;	
		};

		bt_irq_gpio: bt-irq-gpio {
			rockchip,pins =
				<2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;			
		};
	};
};

这里其实就差不多配置完了,我这里wifi还是不能用,是因为这里还需要改一些

首先查看自己的wifi是否在自己的板卡里面有对应的模块

rk66_qls:/ # ifconfig -a
sit0      Link encap:IPv6-in-IPv4  
          NOARP  MTU:1480  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:1000 
          RX bytes:0 TX bytes:0 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0 
          inet6 addr: ::1/128 Scope: Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:1000 
          RX bytes:0 TX bytes:0 
/*这就是你的wifi模块*/
wlan0     Link encap:Ethernet  HWaddr 10:2c:6b:69:14:c2  Driver bcmsdh_sdmmc
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:1000 
          RX bytes:0 TX bytes:0 

如果这里都没,那么先把这个弄出来,查看电压,时钟是否有输出,对应的通道是否打开,这个没出来一般是时钟有问题。

3)驱动改动了一部分

#if 0
#ifdef HW_OOB
	host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE;
	irq_flags = rockchip_wifi_get_oob_irq_flag();
	if (irq_flags == 1)
		host_oob_irq_flags |= IORESOURCE_IRQ_HIGHLEVEL;
	else if (irq_flags == 0)
		host_oob_irq_flags |= IORESOURCE_IRQ_LOWLEVEL;
	else
		pr_warn("%s: unknown oob irqflags !\n", __func__);
#else
	host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_SHAREABLE;
#endif
#endif


/*将原来的注释掉,新增这些 记得在头文件定义*/
----------------------
#define HW_OOB_LOW_LEVEL
----------------------
#ifdef HW_OOB
#ifdef HW_OOB_LOW_LEVEL
        host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_SHAREABLE;
#else
        host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE;
#endif
#else
        host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_SHAREABLE;
#endif

如果有一样的wifi模块可以直接把之前的驱动直接复制过去,主要就是这里不一样。
是在不行就去问之前的调试过的同事。没有什么比这个直接有效。

六、摄像头调试

首先查看i2c能否读取到摄像头的设备,
如果不能就看摄像头这边的电压是不是正确的,查看摄像头是否连接好,可以叫硬件的同事帮你看看,就是看看自己的设备树配置是否正确,对应的GPIO的是不是正确,对应的状态是不是正确的。
软硬联调。

追主要的就是查看开机的log信息
根据不同的信息去查看自己的报错,这样就很快定位错误的地点以一一排查。

下面几个命令可以帮助你查看是否有错误

dumpsys media.camera

查看是否有相机设备

== Service global info: ==

Number of camera devices: 1
Number of normal camera devices: 1
Number of public camera devices visible to API1: 1
    Device 0 maps to "0"
Active Camera Clients:
[]
Allowed user IDs: 0

== Camera service events log (most recent at top): ==
  11-26 02:31:53 : USER_SWITCH previous allowed user IDs: <None>, current allowed user IDs: 0
  11-26 02:31:41 : ADD device 0, reason: (Device added)

== Camera device 0 dynamic info: ==
  Device 0 is closed, no client instance
== Camera Provider HAL external/0 (v2.5, remote) static info: 0 devices: ==
== Camera Provider HAL legacy/0 (v2.5, remote) static info: 1 devices: ==
== Camera HAL device device@3.3/legacy/0 (v3.3) static information: ==
  Resource cost: 50
  Conflicting devices: None
  API1 info:
    Has a flash unit: false
    Facing: Front
    Orientation: 90
  API2 camera characteristics:
    Dumping camera metadata array: 71 / 71 entries, 2184 / 2184 bytes of extra data.
      Version: 1, Flags: 00000000
      android.colorCorrection.availableAberrationModes (00004): byte[1]
        [0 ]
      android.control.aeAvailableAntibandingModes (10012): byte[4]
        [0 1 2 3 ]
      android.control.aeAvailableModes (10013): byte[2]
        [1 0 ]
      android.control.aeAvailableTargetFpsRanges (10014): int32[6]
        [15 15 15 30 ]
        [30 30 ]
      android.control.aeCompensationRange (10015): int32[2]
        [-6 6 ]
      android.control.aeCompensationStep (10016): rational[1]
        [(1 / 3) ]
      android.control.afAvailableModes (10017): byte[6]
        [0 1 2 3 4 5 ]
      android.control.availableEffects (10018): byte[1]
        [0 ]
      android.control.availableSceneModes (10019): byte[1]
        [0 ]
      android.control.availableVideoStabilizationModes (1001a): byte[1]
        [0 ]
      android.control.awbAvailableModes (1001b): byte[5]
        [1 2 3 5 6 ]
      android.control.maxRegions (1001c): int32[3]
        [1 0 1 ]
      android.control.aeLockAvailable (10024): byte[1]
        [FALSE ]
      android.control.awbLockAvailable (10025): byte[1]
        [TRUE ]

抓取底层数据流

v4l2-ctl --verbose -d /dev/video0 --set-fmt-video=width=2592,height=1944,pixelformat='NV12' --stream-mmap=4 --set-selection=target=crop,flags=0,top=0,left=0,width=2592,height=1944
log
VIDIOC_QUERYCAP: ok
VIDIOC_G_FMT: ok
VIDIOC_S_FMT: ok
Format Video Capture Multiplanar:
	Width/Height      : 2592/1944
	Pixel Format      : 'NV12'
	Field             : None
	Number of planes  : 1
	Flags             : 
	Colorspace        : Default
	Transfer Function : Default
	YCbCr Encoding    : Default
	Quantization      : Full Range
	Plane 0           :
	   Bytes per Line : 2592
	   Size Image     : 7558272
VIDIOC_G_SELECTION: ok
VIDIOC_S_SELECTION: ok
VIDIOC_REQBUFS: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_STREAMON: ok
idx: 0 seq:      0 bytesused: 7558272 ts: 1018.141298
idx: 1 seq:      1 bytesused: 7558272 ts: 1018.207808 delta: 66.510 ms
idx: 2 seq:      2 bytesused: 7558272 ts: 1018.274311 delta: 66.503 ms
idx: 3 seq:      3 bytesused: 7558272 ts: 1018.340820 delta: 66.509 ms
idx: 0 seq:      4 bytesused: 7558272 ts: 1018.407341 delta: 66.521 ms fps: 15.04
idx: 1 seq:      5 bytesused: 7558272 ts: 1018.473840 delta: 66.499 ms fps: 15.04
idx: 2 seq:      6 bytesused: 7558272 ts: 1018.540351 delta: 66.511 ms fps: 15.04
idx: 3 seq:      7 bytesused: 7558272 ts: 1018.606875 delta: 66.524 ms fps: 15.04
idx: 0 seq:      8 bytesused: 7558272 ts: 1018.673394 delta: 66.519 ms fps: 15.03
idx: 1 seq:      9 bytesused: 7558272 ts: 1018.739885 delta: 66.491 ms fps: 15.04
idx: 2 seq:     10 bytesused: 7558272 ts: 1018.806394 delta: 66.509 ms fps: 15.04
idx: 3 seq:     11 bytesused: 7558272 ts: 1018.872923 delta: 66.529 ms fps: 15.04
idx: 0 seq:     12 bytesused: 7558272 ts: 1018.939433 delta: 66.510 ms fps: 15.04
idx: 1 seq:     13 bytesused: 7558272 ts: 1019.005943 delta: 66.510 ms fps: 15.04
idx: 2 seq:     14 bytesused: 7558272 ts: 1019.072455 delta: 66.512 ms fps: 15.04
idx: 3 seq:     15 bytesused: 7558272 ts: 1019.139004 delta: 66.549 ms fps: 15.03
idx: 0 seq:     16 bytesused: 7558272 ts: 1019.205477 delta: 66.473 ms fps: 15.04
idx: 1 seq:     17 bytesused: 7558272 ts: 1019.271977 delta: 66.500 ms fps: 15.04
idx: 2 seq:     18 bytesused: 7558272 ts: 1019.338498 delta: 66.521 ms fps: 15.04
idx: 3 seq:     19 bytesused: 7558272 ts: 1019.404995 delta: 66.497 ms fps: 15.04
idx: 0 seq:     20 bytesused: 7558272 ts: 1019.471524 delta: 66.529 ms fps: 15.04
idx: 1 seq:     21 bytesused: 7558272 ts: 1019.538018 delta: 66.494 ms fps: 15.04
idx: 2 seq:     22 bytesused: 7558272 ts: 1019.604544 delta: 66.526 ms fps: 15.04
idx: 3 seq:     23 bytesused: 7558272 ts: 1019.671058 delta: 66.514 ms fps: 15.04
idx: 0 seq:     24 bytesused: 7558272 ts: 1019.737569 delta: 66.511 ms fps: 15.04
idx: 1 seq:     25 bytesused: 7558272 ts: 1019.804076 delta: 66.507 ms fps: 15.04
idx: 2 seq:     26 bytesused: 7558272 ts: 1019.870593 delta: 66.517 ms fps: 15.04
idx: 3 seq:     27 bytesused: 7558272 ts: 1019.937099 delta: 66.506 ms fps: 15.04
idx: 0 seq:     28 bytesused: 7558272 ts: 1020.003612 delta: 66.513 ms fps: 15.04
idx: 1 seq:     29 bytesused: 7558272 ts: 1020.070108 delta: 66.496 ms fps: 15.04
idx: 2 seq:     30 bytesused: 7558272 ts: 1020.136621 delta: 66.513 ms fps: 15.04
idx: 3 seq:     31 bytesused: 7558272 ts: 1020.203148 delta: 66.527 ms fps: 15.04
idx: 0 seq:     32 bytesused: 7558272 ts: 1020.269644 delta: 66.496 ms fps: 15.04
idx: 1 seq:     33 bytesused: 7558272 ts: 1020.336167 delta: 66.523 ms fps: 15.04
idx: 2 seq:     34 bytesused: 7558272 ts: 1020.402681 delta: 66.514 ms fps: 15.04
idx: 3 seq:     35 bytesused: 7558272 ts: 1020.469177 delta: 66.496 ms fps: 15.04
idx: 0 seq:     36 bytesused: 7558272 ts: 1020.535740 delta: 66.563 ms fps: 15.03
idx: 1 seq:     37 bytesused: 7558272 ts: 1020.602202 delta: 66.462 ms fps: 15.04
idx: 2 seq:     38 bytesused: 7558272 ts: 1020.668712 delta: 66.510 ms fps: 15.04
idx: 3 seq:     39 bytesused: 7558272 ts: 1020.735222 delta: 66.510 ms fps: 15.04
idx: 0 seq:     40 bytesused: 7558272 ts: 1020.801751 delta: 66.529 ms fps: 15.04
idx: 1 seq:     41 bytesused: 7558272 ts: 1020.868258 delta: 66.507 ms fps: 15.04
idx: 2 seq:     42 bytesused: 7558272 ts: 1020.934769 delta: 66.511 ms fps: 15.04
idx: 3 seq:     43 bytesused: 7558272 ts: 1021.001264 delta: 66.495 ms fps: 15.04
idx: 0 seq:     44 bytesused: 7558272 ts: 1021.067792 delta: 66.528 ms fps: 15.04
idx: 1 seq:     45 bytesused: 7558272 ts: 1021.134339 delta: 66.547 ms fps: 15.03
idx: 2 seq:     46 bytesused: 7558272 ts: 1021.200803 delta: 66.464 ms fps: 15.04
idx: 3 seq:     47 bytesused: 7558272 ts: 1021.267327 delta: 66.524 ms fps: 15.04
idx: 0 seq:     48 bytesused: 7558272 ts: 1021.333837 delta: 66.510 ms fps: 15.04
idx: 1 seq:     49 bytesused: 7558272 ts: 1021.400348 delta: 66.511 ms fps: 15.04
idx: 2 seq:     50 bytesused: 7558272 ts: 1021.466859 delta: 66.511 ms fps: 15.04
idx: 3 seq:     51 bytesused: 7558272 ts: 1021.533357 delta: 66.498 ms fps: 15.04

没有打印的可以看看摄像头时钟有数据没,我之前没调试出来是因为时钟没有数据流出。需要对应的时钟配置。
就先写到这里吧。

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Android是一种广泛使用的移动操作系统,其开发涉及到多个层次,其中底层驱动开发是其中重要的一环。底层驱动开发是指为Android设备上的硬件提供驱动程序的开发过程。驱动程序是操作系统与硬件之间的桥梁,它们负责管理和控制硬件设备的工作。 在Android底层驱动开发的过程中,首先需要了解设备的硬件结构和规格,以及相应的硬件接口和协议。根据硬件设备的不同,可能包括显示器、触摸屏、摄像头、声卡等各种设备。开发者需要研究硬件设备的工作原理和特性,以便编写相应的驱动程序。 其次,开发者需要熟悉Android底层的相关开发工具和API,如HAL(硬件抽象层)、Binder IPC(进程间通信)等,以便与操作系统和应用程序进行交互。底层驱动开发还需要理解Linux内核的相关知识,因为Android是基于Linux内核开发的。 在实际的驱动开发过程中,开发者需要根据硬件设备的特性和要求,编写对应的设备驱动程序。这些驱动程序通常使用C或C++语言编写,并需要遵循一定的编程规范和命名规则。开发者需要确保驱动程序的正确性和稳定性,以及与操作系统的兼容性。 总之,Android底层驱动开发是一项复杂且技术要求较高的工作。它需要开发者具备扎实的硬件和软件知识,以及良好的编程能力。只有通过深入研究和实践,才能开发出高质量的驱动程序,为Android设备的稳定运行做出贡献。 ### 回答2: Android 底层驱动开发是指在 Android 操作系统中编写和调试设备驱动程序的过程。设备驱动程序是连接硬件和操作系统之间的桥梁,能使操作系统识别和与硬件进行通信。对于 Android 应用程序开发人员来说,了解底层驱动开发至关重要,因为它可以帮助他们更好地理解系统的工作原理,并在需要时进行定制和优化。 编写 Android 底层驱动程序需要掌握 C/C++ 编程语言、Linux 内核知识和硬件架构相关概念。在开发过程中,需要了解设备的硬件接口和规范,包括寄存器配置、中断处理、数据传输等。通过编写驱动程序,开发人员可以为设备提供访问系统资源的接口,并处理各种硬件事件和数据传输。 开发 Android 底层驱动程序的主要步骤包括以下几个方面: 1. 硬件初始化:配置设备的寄存器、中断等硬件资源,并注册到操作系统中。这包括初始化 I/O 端口、设备中断控制器、时钟和 DMA 控制器等。 2. 中断处理:在中断发生时,驱动程序需要对中断进行处理。处理中断的程序需要根据中断的类型和来源来执行相应的操作。例如,处理数据接收中断、数据发送中断等。 3. 数据传输:驱动程序需要实现对设备的数据传输功能。这包括读取和写入设备的数据。数据传输可以使用 DMA、中断或轮询方式进行。 4. 设备控制:驱动程序需要实现对设备的控制功能。这包括设置设备的工作模式、参数调整和状态查询等。通过提供合适的接口,应用程序可以通过系统调用来与设备进行交互和控制。 5. 调试和优化:在驱动程序开发的过程中,需要使用调试工具进行问题排查和性能优化。这包括使用 printk() 输出调试信息、使用 gdb 进行调试和性能剖析等。 总之,Android 底层驱动开发涉及到多个技术领域和专业知识,需要开发人员具备扎实的编程基础和理解操作系统和硬件的能力。掌握底层驱动开发可以帮助开发人员更好地理解系统的工作原理,并在需求变化时进行相应的定制和优化。 ### 回答3: Android是目前最流行的移动操作系统之一,其特点是开放源代码、可定制性强以及适应性广泛。在Android系统中,底层驱动开发是非常重要的一部分,它涉及到硬件和操作系统之间的交互。 Android底层驱动开发PDF主要介绍了Android系统中的底层驱动开发相关知识和技术。这些知识和技术包括硬件抽象层(HAL)、内核驱动开发、设备树(Device Tree)、引导加载程序(Bootloader)等。 首先,硬件抽象层(HAL)是Android系统的一个重要组成部分,用于提供硬件与操作系统之间的接口。通过HAL,Android系统可以与各种硬件设备进行通信和交互。PDF中会介绍如何编写和调试HAL,以及如何实现硬件的适配和兼容性。 其次,内核驱动开发Android底层驱动开发的核心之一。PDF中将详细介绍如何编写设备驱动程序,如独立设备驱动和平台设备驱动。此外,还会涉及到设备树(Device Tree)的使用,设备树用于描述硬件设备的信息和属性。 另外,引导加载程序(Bootloader)也是Android底层驱动开发的重要环节之一。PDF中会介绍如何编写和调试引导加载程序,以及如何通过引导加载程序来引导Android系统。 总之,Android底层驱动开发PDF会全面介绍Android系统中的底层驱动开发相关知识和技术,包括HAL、内核驱动开发、设备树、引导加载程序等。对于想要深入了解Android系统底层开发开发者来说,这本PDF是一本非常有价值的参考书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永不秃头的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值