当前位置:网站首页>【Camera专题】OTP数据如何保存在自定义节点中
【Camera专题】OTP数据如何保存在自定义节点中
2022-07-03 01:21:00 【c枫_撸码的日子】
一、前言
之前因为lsc导致出现的绿屏问题,模组厂说是lsc数据出了异常,
sensor厂fae也没有后续配合,就扯了一句,让我们保存otp数据,
方便出问题时对比,然后就没有然后了。支持不给力,态度还差。
若对OTP不太熟悉,先读一下以前的文章!
OTP编程完全指南分上、下2篇。
上:主要讲OTP的知识和调试流程。
下:主要讲OTP的源码。
Qcom-高通OTP编程调试指南-上
Qcom-高通OTP编程调试指南-下
二、知识点
其实呢,这些数据在kernel层是有打印出来的,如图:
但是系统组的人说这些log太多了,影响kernel的启动,要我们保存在节点中,通过cat命令去获得。
2.1 总体思路
- 1.创建节点
- 2.实现read函数(使用cat命令时会主动调read函数)
2.2 具体实现
kernel/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
#include <linux/debugfs.h> //需要的头文件
#define OTP_SZIE_S5K4H7 400 //otp数据大小
static uint8_t otp_lsc_temp[OTP_SZIE_S5K4H7];//数组,用于保存数据
char otp_lsc_buffer[1024];//数组,用于保存数据
#define OTP_LSC_DATA "data"
#define OTP_LSC_PATH "/sys/kernel/debug/otp/lsc_data" //节点路径
//读函数
ssize_t read_otp_lsc(struct file *filp, char __user *userbuf,
size_t count, loff_t *ppos)
{
int i;
int j = 1;
char temp[OTP_SZIE_S5K4H7] = {
0};
CDBG("zcf read_otp_lsc enter\n");
memset(otp_lsc_buffer, 0, sizeof(otp_lsc_buffer));
strlcat(otp_lsc_buffer, "AWB:\n", sizeof(otp_lsc_buffer));//AWB数据
for (i = 0; i < OTP_SZIE_S5K4H7; i++) {
snprintf(temp, sizeof(temp), "%02x", otp_lsc_temp[i]);
strlcat(otp_lsc_buffer, temp, sizeof(otp_lsc_buffer));
strlcat(otp_lsc_buffer, " ", sizeof(otp_lsc_buffer));
if(i == 59)//前60个是AWB数据
strlcat(otp_lsc_buffer, "\nLSC:\n", sizeof(otp_lsc_buffer));
if(i == 10*j-1)//每打印10个数字就换行
{
j++;
strlcat(otp_lsc_buffer, "\r\n", sizeof(otp_lsc_buffer));
}
}
strlcat(otp_lsc_buffer, "\r\n", sizeof(otp_lsc_buffer));//换行
return simple_read_from_buffer(userbuf, count,
ppos, otp_lsc_buffer, strlen(otp_lsc_buffer));
}
static const struct file_operations otp_lsc_fops = {
.read = read_otp_lsc,//赋值读函数
};
//创建节点 /sys/kernel/debug/otp/lsc_data
static int otp_init_debugfs(void)
{
int ret = 0;
struct dentry *root;
root = debugfs_create_dir("otp", NULL);
if(!root)
{
CDBG("zcf %s debugfs_create_dir(otp) failed\n", __func__);
ret = -ENOMEM;
return ret;
}
if (!debugfs_create_file(OTP_LSC_DATA,
0666,
root,
NULL,
&otp_lsc_fops));
{
CDBG("zcf %s failed to create lsc_data debugfs file\n", __func__);
ret = -ENOMEM;
return ret;
}
return ret;
}
调用的地方
static int msm_eeprom_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
···省略部分代码
//在probe中创建节点
++ otp_init_debugfs();
···省略部分代码
rc = read_eeprom_memory(e_ctrl, &e_ctrl->cal_data);//这里会读取数据
++ if(0 == strcmp(eb_info->eeprom_name,"sunwin_s5k4h7")){
++ pr_err("zcf [sensor: s5k4h7]save the otp data\n");
++ for (j = 0; j < e_ctrl->cal_data.num_data; j++)
//把读出来的数据保存在临时数组otp_lsc_temp中
++ otp_lsc_temp[j] = e_ctrl->cal_data.mapdata[j];
++ }
···省略部分代码
}
结果

三、创建一个camera 节点,保存sensor名称
kernel/msm-4.9/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
/* * 创建节点 * 1. /sys/kernel/debug/bbk_camera/back_cam_name * 2. /sys/kernel/debug/bbk_camera/front_cam_name */
char front_name_buffer[32]="NULL";//前摄名称
char back_name_buffer[32]="NULL";//后摄名称
ssize_t read_front_name(struct file *filp, char __user *userbuf,
size_t count, loff_t *ppos)
{
char kbuf[32]="NULL";
sprintf(kbuf, "%s\n", front_name_buffer);
return simple_read_from_buffer(userbuf, count,ppos, kbuf, strlen(kbuf));
}
ssize_t read_back_name(struct file *filp, char __user *userbuf,
size_t count, loff_t *ppos)
{
char kbuf[32]="NULL";
sprintf(kbuf, "%s\n", back_name_buffer);
return simple_read_from_buffer(userbuf, count,ppos, kbuf, strlen(kbuf));
}
static const struct file_operations front_camera_fops = {
.read = read_front_name,//赋值读函数
};
static const struct file_operations back_camera_fops = {
.read = read_back_name,//赋值读函数
};
static int camera_node_create(void)
{
int ret = 0;
struct dentry *root;
root = debugfs_create_dir("bbk_camera", NULL);
if(!root)
{
CDBG("zcf %s debugfs_create_dir(bbk_camera) failed\n", __func__);
ret = -ENOMEM;
return ret;
}
if(root){
debugfs_create_file("front_cam_name",
0666,
root,
NULL,
&front_camera_fops);
debugfs_create_file("back_cam_name",
0666,
root,
NULL,
&back_camera_fops);
}
return ret;
}
int32_t msm_sensor_driver_probe(void *setting,
struct msm_sensor_info_t *probed_info, char *entity_name)
{
···
camera_node_create();
pr_err("%s probe succeeded", slave_info->sensor_name);
···
if(slave_info->sensor_init_params.position == 1) {
strlcpy(front_name_buffer, slave_info->sensor_name,
sizeof(front_name_buffer));
CDBG("front_name_buffer= %s\n",front_name_buffer);
}else {
strlcpy(back_name_buffer, slave_info->sensor_name,
sizeof(back_name_buffer));
CDBG("back_name_buffer= %s\n",back_name_buffer);
}
···
}
结果

Stay Hungry,Stay Foolish!
边栏推荐
- 7-25 read numbers (loop switch)
- Smart management of Green Cities: Digital twin underground integrated pipe gallery platform
- [error record] the shutter component reports an error (no directionality widget found. | richtext widgets require a directionality)
- [data mining] task 1: distance calculation
- Network security - vulnerabilities and Trojans
- Network security OpenVAS
- Virtual list
- 数学知识:能被整除的数—容斥原理
- 【数据挖掘】任务1:距离计算
- Mathematical Knowledge: Steps - Nim Games - Game Theory
猜你喜欢

Three core issues of concurrent programming - "deep understanding of high concurrent programming"

High resolution network (Part 1): Principle Analysis

Pytest learning notes (12) -allure feature · @allure Step () and allure attach

LeetCode 987. Vertical order transverse of a binary tree - Binary Tree Series Question 7

Why can't the start method be called repeatedly? But the run method can?

Leetcode skimming questions_ Sum of two numbers II - enter an ordered array

Learn the five skills you need to master in cloud computing application development
![[North Asia data recovery] data recovery case of raid crash caused by hard disk disconnection during data synchronization of hot spare disk of RAID5 disk array](/img/2a/98400b0d0b5eda1e52abae30746f2b.jpg)
[North Asia data recovery] data recovery case of raid crash caused by hard disk disconnection during data synchronization of hot spare disk of RAID5 disk array

STM32 - GPIO input / output mode

Introduction to flask tutorial
随机推荐
PS remove watermark details
C#应用程序界面开发基础——窗体控制(4)——选择类控件
[data mining] task 4:20newsgroups clustering
网络安全-最简单的病毒
[shutter] animation animation (the core class of shutter animation | animation | curvedanimation | animationcontroller | tween)
String splicing function of MySQL
Scheme and practice of cold and hot separation of massive data
Using tensorboard to visualize the model, data and training process
Network security ACL access control list
GDB 在嵌入式中的相关概念
Using tensorboard to visualize the model, data and training process
Everything文件搜索工具
What is tone. Diao's story
网络安全-钓鱼
[technology development-23]: application of DSP in future converged networks
小程序开发的部分功能
电信客户流失预测挑战赛
简易分析fgui依赖关系工具
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance o
Tâche 6: regroupement DBSCAN