很多时候我们需要从 HAL 层(Hardware Abstract Layer)传一个标志给 kernel 层。一般这种传递是不能直接通过定义全局变量来实现的。

此时可以通过读写文件来实现该标志。

譬如我们有这样一个需求,在录像过程中去掉持续对焦功能,而录像预览时开启持续对焦功能。

 

在 HAL 层中有开始录像和停止录像的接口。

/trunk/ALPS.JB3.TDD.MP.V2_TD_xxx/mediatek/platform/mt6572/hardware/camera/hal/client/CamClient/Record/RecordClient.cpp 文件中

在 /sys/devices/platform/lens_actuator/ 目录下创建一个 VideoRec_Flag 这样的文件,在开始录像时将该文件中写入一个字节的值为1,而在停止录像时将该文件中写入一个字节的值为0。



1 bool  
2 RecordClient::
3 startRecording()
4 {
5 bool ret = false;
6 //
7 MY_LOGD("+");
8 //
9 Mutex::Autolock _l(mModuleMtx);
10 //
11 #if 1
12 int flag[1]= {1};
13
14 FILE *fd = NULL;
15 fd = fopen("/sys/devices/platform/lens_actuator/VideoRec_Flag","w");
16
17 if(fd == NULL)
18 MY_LOGD("BBN_TestMode open failed");
19 else{
20 MY_LOGD("BBN_TestMode open ok");
21 fwrite(&flag,1,1,fd);
22 fclose(fd);
23 }
24 #endif
25
26 if(isEnabledState())
27 {
28 MY_LOGE("Recording has been started");
29 goto lbExit;
30 }
31 //
32 MY_LOGD("+ current mIsRecStarted=%d", mIsRecStarted);
33 ::android_atomic_write(1, &mIsRecStarted);
34 //
35 mpParamsMgr->getVideoSize(&mi4RecWidth, &mi4RecHeight);
36 MY_LOGD("+ record: WxH=%dx%d, format(%s)", mi4RecWidth, mi4RecHeight, MtkCameraParameters::PIXEL_FORMAT_YUV420I);//CameraParameters::PIXEL_FORMAT_YUV420P);
37 //
38 mTimeStart = systemTime();
39 mTimeEnd = mTimeStart;
40 mFrameCount = 0;
41 mLastTimeStamp = 0;
42 //
43 ret = onStateChanged();
44 //
45 lbExit:
46 //
47 MY_LOGD("-");
48 //
49 return ret;
50 }
51
52
53 /******************************************************************************
54 *
55 ******************************************************************************/
56 bool
57 RecordClient::
58 stopRecording()
59 {
60 bool ret = false;
61 status_t status = NO_ERROR;
62 //
63 MY_LOGD("+");
64 //
65 #if 1
66 int flag[1]= {0};
67
68 FILE *fd = NULL;
69 fd = fopen("/sys/devices/platform/lens_actuator/VideoRec_Flag","w");
70
71 if(fd == NULL)
72 MY_LOGD("BBN_TestMode open failed");
73 else{
74 MY_LOGD("BBN_TestMode open ok");
75 fwrite(&flag,1,1,fd);
76 fclose(fd);
77 }
78 #endif
79
80 Mutex::Autolock _l(mModuleMtx);
81 //
82 if(!isEnabledState())
83 {
84 MY_LOGE("Recording has been stopped");
85 goto lbExit;
86 }
87 //
88 MY_LOGD("getThreadId(%d), getStrongCount(%d), this(%p)", getThreadId(), getStrongCount(), this);
89 //
90 MY_LOGD("+ current mIsRecStarted=%d", mIsRecStarted);
91 ::android_atomic_write(0, &mIsRecStarted);
92 //
93 ret = onStateChanged();
94 //
95 mpImgBufQueue->pauseProcessor();
96 //
97 lbExit:
98 //
99 MY_LOGD("-");
100 //
101 return ret;
102 }


在/trunk/ALPS.JB3.TDD.MP.V2_TD_xxx/mediatek/custom/common/kernel/imgsensor/ov5645_mipi_yuv/ov5645mipiyuv_Sensor.c 文件中

在 OV5645_FOCUS_OVT_AFC_Constant_Focus() 函数中读取之前VideoRec_Flag那个文件中的值,若为1,则进行持续对焦,否则,放弃持续对焦。在驱动文件中是通过写寄存器来实现的。



1 static void OV5645_FOCUS_OVT_AFC_Constant_Focus(void)  
2 {
3 printk("FM50AF_VideoRec_Flag=%d \n",FM50AF_VideoRec_Flag);
4
5 if(FM50AF_VideoRec_Flag)
6 {
7 OV5645MIPI_write_cmos_sensor(0x3023,0x01);
8 OV5645MIPI_write_cmos_sensor(0x3022,0x06);
9 }
10 else{
11 OV5645MIPI_write_cmos_sensor(0x3023,0x01);
12 OV5645MIPI_write_cmos_sensor(0x3022,0x80);
13 mDELAY(10);
14 OV5645MIPI_write_cmos_sensor(0x3024,0x00);
15 OV5645MIPI_write_cmos_sensor(0x3023,0x01);
16 OV5645MIPI_write_cmos_sensor(0x3022,0x04);
17 }
18 }


具体的读取方式如下:



1 int FM50AF_VideoRec_Flag;  
2
3 EXPORT_SYMBOL(FM50AF_VideoRec_Flag);
4
5 static ssize_t show_VideoRec_Flag(struct device *dev,struct device_attribute *attr, char *buf)
6 {
7 // xlog_printk(ANDROID_LOG_DEBUG, "show_VideoRec_Flag test", "[Battery] show_BN_TestMode : %x\n", g_BN_TestMode);
8
9 printk("show_VideoRec_Flag FM50AF_VideoRec_Flag=%d \n",FM50AF_VideoRec_Flag);
10 return sprintf(buf, "%u\n", FM50AF_VideoRec_Flag);
11
12
13 }
14 static ssize_t store_VideoRec_Flag(struct device *dev,struct device_attribute *attr, const char *buf, size_t size)
15 {
16 char *pvalue = NULL;
17 unsigned int reg_BN_TestMode = 0;
18 printk( "store_VideoRec_Flag \n");
19 if(buf != NULL && size != 0)
20 {
21 printk("store_VideoRec_Flag test111", "[Battery] buf is =%s , size is =%d \n",buf,size);
22 printk("store_VideoRec_Flag buf= %d ,size=%d \n", *buf,size);
23 // reg_BN_TestMode = simple_strtoul(buf,&pvalue,10);
24 FM50AF_VideoRec_Flag=*buf;
25 }
26 // return size;
27 return FM50AF_VideoRec_Flag;
28 }
29 static DEVICE_ATTR(VideoRec_Flag, 0777, show_VideoRec_Flag, store_VideoRec_Flag);


这其中涉及到一些驱动文件中读写文件的格式的写法需要注意下。

至此,就可以实现该需求了。