很多时候我们需要从 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 ",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 ", g_BN_TestMode); 8 9 printk("show_VideoRec_Flag FM50AF_VideoRec_Flag=%d ",FM50AF_VideoRec_Flag); 10 return sprintf(buf, "%u ", 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 "); 19 if(buf != NULL && size != 0) 20 { 21 printk("store_VideoRec_Flag test111", "[Battery] buf is =%s , size is =%d ",buf,size); 22 printk("store_VideoRec_Flag buf= %d ,size=%d ", *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);
这其中涉及到一些驱动文件中读写文件的格式的写法需要注意下。
至此,就可以实现该需求了。