我是靠谱客的博主 怕孤单鞋子,最近开发中收集的这篇文章主要介绍MTK平台如何通过adb动态读写sensor寄存器的值,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

(1)源码参考

本篇文章实作环境是:调试效果或debug sensor register时需要动态读写sensor寄存器应该怎样修改代码?

目前参考的代码是Kernel-4.19,具体每个kernel版本可能都差不多,这里我们只看Main Sensor。

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_proc.c

enum IMGSENSOR_RETURN imgsensor_proc_init(void)
{
	memset(mtk_ccm_name, 0, camera_info_size);

	//proc/driver/下创建相关的节点
	proc_create("driver/camsensor", 0664, NULL, &fcamera_proc_fops);
	proc_create("driver/camsensor2", 0664, NULL, &fcamera_proc_fops2);
	proc_create("driver/camsensor3", 0664, NULL, &fcamera_proc_fops3);
	proc_create("driver/camsensor4", 0664, NULL, &fcamera_proc_fops4);
	proc_create(
	    "driver/pdaf_type", 0664, NULL, &fcamera_proc_fops_set_pdaf_type);
	proc_create(PROC_SENSOR_STAT, 0664, NULL, &fcamera_proc_fops_status);

	/* Camera information */
	proc_create(PROC_CAMERA_INFO, 0664, NULL, &fcamera_proc_fops1);

	return IMGSENSOR_RETURN_SUCCESS;
}

//proc/driver/camsensor节点
static const struct file_operations fcamera_proc_fops = {
	.owner = THIS_MODULE,
	.read = seq_read,
	.open = proc_camsensor_open,
	.write = CAMERA_HW_Reg_Debug
};

/************************************************************************
 * CAMERA_HW_Reg_Debug()
 * Used for sensor register read/write by proc file
 ************************************************************************/
static ssize_t CAMERA_HW_Reg_Debug(
	struct file *file,
	const char *buffer,
	size_t count,
	loff_t *data)
{
	char regBuf[64] = { '' };
	int ret = 0;
	u32 u4CopyBufSize =
	    (count < (sizeof(regBuf) - 1)) ? (count) : (sizeof(regBuf) - 1);

	//表示后摄IMGSENSOR_SENSOR_IDX_MAIN
	struct IMGSENSOR_SENSOR *psensor =
	    &pgimgsensor->sensor[IMGSENSOR_SENSOR_IDX_MAIN];

	MSDK_SENSOR_REG_INFO_STRUCT sensorReg;

	memset(&sensorReg, 0, sizeof(MSDK_SENSOR_REG_INFO_STRUCT));

	if (psensor == NULL || copy_from_user(regBuf, buffer, u4CopyBufSize))
		return -EFAULT;
	//(1)读取到的输入regBuf
	printk("dxf_hw1 regBuf = %sn",regBuf);

	//(2)输入两个参数走的flow(write flow),将输入的regBuf提取赋值给RegAddr和RegData
	if (sscanf(
	    regBuf,
	    "%x %x",
	    &sensorReg.RegAddr,
	    &sensorReg.RegData) == 2) {

		imgsensor_sensor_feature_control(
		    psensor,
		    SENSOR_FEATURE_SET_REGISTER,
		    (MUINT8 *) &sensorReg,
		    (MUINT32 *) sizeof(MSDK_SENSOR_REG_INFO_STRUCT));

		imgsensor_sensor_feature_control(
		    psensor, SENSOR_FEATURE_GET_REGISTER,
		    (MUINT8 *) &sensorReg,
		    (MUINT32 *) sizeof(MSDK_SENSOR_REG_INFO_STRUCT));

		printk(
		    "write addr = 0x%08x, data = 0x%08xn",
		    sensorReg.RegAddr,
		    sensorReg.RegData);

		ret = snprintf(
		    mtk_i2c_dump,
		    sizeof(mtk_i2c_dump),
		    "addr = 0x%08x, data = 0x%08xn",
		    sensorReg.RegAddr,
		    sensorReg.RegData);

		printk("dxf_hw2  %s, ret = %dn",mtk_i2c_dump,ret);

		if (ret == 0) {
			pr_info("Error! snprintf allocate 0");
			ret = IMGSENSOR_RETURN_ERROR;
			return ret;
		}

	//(3)输入一个参数走的flow(read flow),将输入的regBuf提取赋值给RegAddr
	} else if (kstrtouint(regBuf, 16, &sensorReg.RegAddr) == 0) {
		imgsensor_sensor_feature_control(
		    psensor,
		    SENSOR_FEATURE_GET_REGISTER,
		    (MUINT8 *) &sensorReg,
		    (MUINT32 *) sizeof(MSDK_SENSOR_REG_INFO_STRUCT));

		printk(
		    "read addr = 0x%08x, data = 0x%08xn",
		    sensorReg.RegAddr,
		    sensorReg.RegData);

		ret = snprintf(
		    mtk_i2c_dump,
		    sizeof(mtk_i2c_dump),
		    "addr = 0x%08x, data = 0x%08xn",
		    sensorReg.RegAddr,
		    sensorReg.RegData);

		printk("dxf_hw3  %s, ret = %dn",mtk_i2c_dump,ret);

		if (ret == 0) {
			pr_info("Error! snprintf allocate 0");
			ret = IMGSENSOR_RETURN_ERROR;
			return ret;
		}
	}
	return count;
}

需要在对应的sensor drv(XXX_sensor.c)中正确实现相应的feature control。

static kal_uint32 feature_control(MSDK_SENSOR_FEATURE_ENUM feature_id,
							 UINT8 *feature_para,UINT32 *feature_para_len)
{
	//...
	switch (feature_id) {
			case SENSOR_FEATURE_SET_REGISTER:
					write_cmos_sensor(sensor_reg_data->RegAddr, sensor_reg_data->RegData);
			break;
		case SENSOR_FEATURE_GET_REGISTER:
					sensor_reg_data->RegData = read_cmos_sensor(sensor_reg_data->RegAddr);
			break;
	}
	//...
}

(2)函数解释

(A)sscanf

//C 库函数 int sscanf(const char *str, const char *format, ...) 从字符串读取格式化输入。
/*
str:待解析的字符串;
format:字符串格式描述;
返回值:如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。
*/
int sscanf(const char *str, const char *format, ...)

//示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
   int day, year;
   char weekday[20], month[20], dtm[100];

   strcpy( dtm, "Saturday March 25 1989" );
   sscanf( dtm, "%s %s %d  %d", weekday, month, &day, &year );

   printf("%s %d, %d = %sn", month, day, year, weekday );
    
   return(0);
}

//结果
March 25, 1989 = Saturday

(B)snprintf

//C 库函数 int snprintf(char *str, size_t size, const char *format, ...) 设将可变参数(...)按照 format 格式化成字符串,并将字符串复制到 str 中,size 为要写入的字符的最大数目,超过 size 会被截断。
/*
str:目标字符串;
size:拷贝字节数(Bytes);
format:格式化成字符串;
...:可变参数;
返回值:
1、如果格式化后的字符串长度小于 size,则会把字符串全部复制到 str 中,并给其后添加一个字符串结束符 ;
2、如果格式化后的字符串长度大于等于 size,超过 size 的部分会被截断,只将其中的 (size-1) 个字符复制到 str 中,并给其后添加一个字符串结束符 ,返回值为欲写入的字符串长度。
*/
int snprintf ( char * str, size_t size, const char * format, ... );

//示例
#include <stdio.h>
 
int main()
{
    char buffer[50];
    char* s = "runoobcom";
 
    // 读取字符串并存储在 buffer 中
    int j = snprintf(buffer, 6, "%sn", s);
    // 输出 buffer及字符数
    printf("string:n%sncharacter count = %dn", buffer, j);
 
    return 0;
}

//结果
string:
runoo
character count = 10

(C)kstrtouint

//kstrtouint函数定义在文件kstrtox.c中
/*
s:输入字符串;
base:是10(10进制)或16(16进制),或者是0自动识别;
res:存放转换后的整形值;
返回值:当没有错误时返回值是0;
*/
int kstrtouint(const char *s, unsigned int base, unsigned int *res)

//示例
kstrtoint(receive_data, 16, &write_data);

(3)测试

这里以0x0202寄存器为例,进行读写操作。

//write addr
adb shell echo 0x0202 0x1234 > proc/driver/camsensor  //将0x0202地址的值设置为0x1234

4,79095,1690141545,-; (7)[9410:sh]dxf_hw1 regBuf = 0x0202 0x1234x0a
4,79096,1690142202,-; (7)[9410:sh]write addr = 0x00000202, data = 0x00001234
4,79097,1690142427,-; (7)[9410:sh]dxf_hw2  addr = 0x00000202, data = 0x00001234x0a, ret = 37

//read addr
adb shell echo 0x0202 > proc/driver/camsensor	//读取0x0202地址的值

4,79309,1691998102,-; (4)[9410:sh]dxf_hw1 regBuf = 0x0202x0a
4,79310,1691998599,-; (4)[9410:sh]read addr = 0x00000202, data = 0x00000860
4,79311,1691998641,-; (4)[9410:sh]dxf_hw3  addr = 0x00000202, data = 0x00000860x0a, ret = 37

顺便说明一下直接编译kernel生成boot.img的命令:

./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-full_xxx.ninja bootimage

最后

以上就是怕孤单鞋子为你收集整理的MTK平台如何通过adb动态读写sensor寄存器的值的全部内容,希望文章能够帮你解决MTK平台如何通过adb动态读写sensor寄存器的值所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(75)

评论列表共有 0 条评论

立即
投稿
返回
顶部