printk打印
P.S.关于调试信息,一般rk自己的相关驱动在.c前面会有个debug全局变量,讲这个初始值改为3以上即可以打开所有编译条件。
关于dev_dbg,可以参考http://blog.chinaunix.net/uid-20672559-id-3383042.html
用户态更改调试打印等级,通过读写/proc/sys/kernel/printk文件可读取和修改控制台的日志级别。查看这个文件的方法如下:
cat /proc/sys/kernel/printk
6 6 1 7
上面显示的4个数据分别对应:
#define KERN_SOH "\001" /* ASCII Start Of Header */
#define KERN_SOH_ASCII '\001'
#define KERN_EMERG KERN_SOH "0" /* system is unusable */
#define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */
#define KERN_CRIT KERN_SOH "2" /* critical conditions */
#define KERN_ERR KERN_SOH "3" /* error conditions */
#define KERN_WARNING KERN_SOH "4" /* warning conditions */
#define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */
#define KERN_INFO KERN_SOH "6" /* informational */
#define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
#define KERN_DEFAULT KERN_SOH "d" /* the default kernel loglevel */
console_loglevel /* 当前控制台日志级别,所有printk打印级别必须小于(不包含等于)这个等级才能被输出,比如当前为6,则KERN_INFO级别不能被输出*/
default_message_loglevel /* KERN_DEFAULT或者不指定等级如printk(“HelloWorld”)对应的等级 */
minimum_console_loglevel /* 支持的最小等级 */
default_console_loglevel /* 默认为7,与console_loglevel的默认值一致 */
可用下面的命令设置当前日志级别:
echo “7 6 1 7” > /proc/sys/kernel/printk
kmesg打印增加打印缓冲大小
make menuconfig -> General Setup -> Kernel log buffer size
1.摄像头
随着视频设备功能复杂化(音视频合成,编解码等),v4l2的框架也越来越复杂,在linux3.0中用一个比较粗糙的图来表现他们之间的关系,大致为:
设备实例(v4l2_device)
|______子设备实例(v4l2_subdev)
|______视频设备节点(video_device)
|______文件访问控制(v4l2_fh)
|______视频缓冲的处理(videobuf/videobuf2)
详细框架可以参考http://blog.csdn.net/rubyboss/article/details/14053523
①rk3128_cif_sensor.dtsi中有“rockchip,sensor”的设备描述符,主要描述IIC地址、通道、cif时钟频率等等信息;
rk312x.dtsi中有"rockchip,cif"的设备描述符,主要描述rk312x的时钟名、中断号等;
②rk_camera.c中主要就是“rockchip,sensor”和"rockchip,cif"的驱动;
其中rk_dts_sensor_probe主要完成IIC地址、通道、时钟频率的获取,并且创建new_camera,填充信息后被链接到new_camera_head队列,这个结构体中有rk_sensor_ioctrl这个函数,可以完成摄像头的时钟设定、电源开关、复位功能,时钟在rk_sensor_pwrseq被调用的时候设定,rk_sensor_power在软件上规定只能是24M或者48M;
而rk_dts_cif_probe相对简单,主要完成中断等等其他硬件资源的获取;
③rk30_camera.c调用rk_camera_platform_data.sensor_register,会将new_camera_head队列中的所有camera都以"soc-camera-pdrv"作为platform设备名注册;soc_camera.c中的"soc-camera-pdrv"驱动主要任务就是为每一个new_camera节点创建一个icd设备并且加入到icd设备列表,icd中有video_device(v4l2标准设备);
④rk_camera中注册的两个driver获取到的信息最终都会保存在rk_device_camera_host_0这个platform_device,其名字为RK29_CAM_DRV_NAME(它在rk30_camera.c文件中被注册).
RK29_CAM_DRV_NAME对应的platform_driver有两个(只选其中一个):
rk30_camera_pingpong.c
rk30_camera_oneframe.c
以上两个driver在probe函数中调用soc_camera_host_register(soc_camera.c),作用为遍历icd设备列表,依次注册标准的v4l2_device(包含于soc_camera_host *ici),接下来,通过scan_add_host注册video_device (包含于soc_camera_device *icd,icd中有soc_camera_desc,这个结构体分为host_desc,代指的是总线adapter,subdev_desc代指的就是摄像头i2c或者spi控制器),并且添加v4l2标准fops操作函数。scan_add_host中还会以subdev_desc中的i2c地址信息,进行i2c_new_probed_device,创建i2c设备。
⑤ov5640.c这样的文件通过文件尾部的宏定义,最终会生成以SENSOR_NAME(如“ov5640_front_3”)为id_table的i2c_driver,当存在对应的subdev时,驱动执行,作用为向对应的subdev中注册subdev_ops;在ov5640.c中主要就是几组寄存器的配置,他们分别对应SEQUENCE_INIT、SEQUENCE_PREVIEW等各个显示模式,他们有各自有独立的分辨率跟帧率,这些寄存器组会被generic_sensor.h转化成二维数组群,存放在senser_seriers中;另外还有几组色彩配置寄存器值,用于相应ctrl_cmd。
综上,可以认为rk_camera.c和rk30_camera.c为设备侧文件,而rk30_camera_pingpong.c/rk30_camera_oneframe.c、soc_camera.c和ov5640.c为驱动侧文件。其中可以在soc_camera.c中找到最直观的v4l2操作函数,这些函数大部分都是对rk30_camera_pingpong.c/rk30_camera_oneframe.c中的rk_soc_camera_host_ops进行封装,而rk_soc_camera_host_ops中的关于调光、白平衡等控制操作,实际上是通过subdev_fops的i2c传输完成。
另外,分析驱动,发现rk只做了yuv输入,并没有做jpeg的支持,如果需要添加,可能涉及的文件:
1.添加ov5640.c的寄存器组;
2.对于rk30_camera_oneframe.c,rk_camera_setup_format需要先添加对应格式的cif寄存器设置;
3.在rk_camera_get_formats中添加对应的上报数据格式。
摄像头借口
一般使用CIF或者RGB作为接口的摄像头模块上面都会集成ISP
一般使用MIPI作为接口的摄像头都需要主控芯片内置ISP或者外置ISP,对于rk3288的Android系统,ISP的支持都存放在camera的Hal层:
hardware/rockchip/camera/SiliconImage/isi/drv/
关于usb摄像头的镜像问题,尝试过在rockchip的hal上面修改,无效,最终在framework中修改:
/frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp 中的getOrientation返回,强行设置为HAL_TRANSFORM_FLIP_H
2.DTS分析
3.GPIO
4.FB
显示屏驱动分成四大块:
①Linux标准的屏幕驱动fb;
②lcdc,液晶控制接口,包括一些电源控制等的硬件操作;
③screen结构是一个屏幕的抽象,里面包含了屏幕的display_timing;
④收发器:常见的收发器包括edp、mipi:
edp的时钟一般为1.62G或者2.7G;
mipi的时钟(dsi_host_clk)可以是90M~1.5G,且这个频率必须根据屏幕数据量计算得出:100+H_totalV_totalfps38/lanes,其中100是rk3288由于时钟误差原因而需要添加的修正,H_total是 水平有效像素+水平前沿+水平后延+水平同步时钟长度,V_total同理,fps是屏幕的刷新频率,可以根据screen中的像素时钟计算得出,lanes是实际mipi借口的数据线宽,3代表一个像素大小是3Bytes。
5.PMU
以RK818作为例子,首先rk818作为一个IIC设备,在rk3128-sdk.dts中的i2c0总线上有作为子节点的设备描述符,其