如何在 kernel 和 hal 层读取同一个标志

很多时候我们需要从 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);  

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

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

原文地址:https://www.cnblogs.com/zl1991/p/5203477.html