码字不易,多谢支持
camera hal3 service启动
十分感谢Android 10.0系统启动之init进程-[Android取经之路]https://blog.csdn.net/yiranfeng/article/details/103549394
《Android Q 之MTK代码分析(一)--Camera Hal3 Service》
《Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor》
《Android Q 之MTK代码分析(三)--Camera Hal3 Open/Close》
《Android Q 之MTK代码分析(四)--Camera Hal3 configure_Streams》
《Android Q 之MTK代码分析(五)--Camera Hal3 process_capture_request》
《Android Q 之MTK代码分析(六)--Camera Hal3 process_capture_result》
备忘:
文末支持一波,感谢鞠躬
1、Android系统系统简述
1.1 MTK Camera HAL层的框架
大概了解关联部分有camea service、camera provider、camera hal service、 camera device manager、camera device这五部分。
frameworks/av/services/camera/libcameraservice/CameraService.cpp
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/provider/2.4/CameraProviderImpl.cpp
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/service.cpp
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/CameraDeviceManagerBase.cpp
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3Impl.cpp
1.2 Android框架启动过程
原文链接:https://blog.csdn.net/yiranfeng/article/details/103549290
Android 系统启动流程:
第一步:手机开机后,引导芯片启动,引导芯片开始从固化在ROM里的预设代码执行,加载引导程序到到RAM,bootloader检查RAM,初始化硬件参数等功能;
第二步:硬件等参数初始化完成后,进入到Kernel层,Kernel层主要加载一些硬件设备驱动,初始化进程管理等操作。在Kernel中首先启动swapper进程(pid=0),用于初始化进程管理、内管管理、加载Driver等操作,再启动kthread进程(pid=2),这些linux系统的内核进程,kthread是所有内核进程的鼻祖;
第三步:Kernel层加载完毕后,硬件设备驱动与HAL层进行交互。初始化进程管理等操作会启动INIT进程 ,这些在Native层中;
第四步:init进程(pid=1,init进程是所有进程的鼻祖,第一个启动)启动后,会启动adbd,logd等用户守护进程,并且会启动servicemanager(binder服务管家)等重要服务,同时孵化出zygote进程,这里属于C++ Framework,代码为C++程序;,CameraHalServer进程就是在这时启动的。
各字段的含义:
USER 进程当前用户
PID 进程ID
PPID 父进程ID
VSIZE 进程的虚拟内存大小,以KB为单位
RSS 实际占用的内存大小,以KB为单位
WCHAN 进程正在睡眠的内核函数名称;该函数的名称是从/root/system.map文件中获得的。
PC Program Counter
NAME 进程状态及名称
第五步:zygote进程是由init进程解析init.rc文件后fork生成,它会加载虚拟机,启动System Server(zygote孵化的第一个进程);System Server负责启动和管理整个Java Framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务;
第六步:zygote同时会启动相关的APP进程,它启动的第一个APP进程为Launcher,然后启动Email,SMS等进程,所有的APP进程都有zygote fork生成。
。
1.3 Init进程 启动
start_kernel()->rest_init()-kernel_thread(kernel_init)->kernel_init(),如图所示init进程就这样启动了
init.rc有两个,使用场景不一样,分别位于:
./system/core/rootdir/init.rc //一个是正常启动用到的.
./bootable/recovery/etc/init.rc //一个是刷机用到的,也就是进入recorvery模式,
1.4 rc文件加载
在SecondStageMain()->LoadBootScripts()
解析init.rc等文件,建立rc文件的action 、service,启动其他进程
*/
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
LoadBootScripts(am, sm);
Android7.0后,init.rc进行了拆分,每个服务都有自己的rc文件,他们基本上都被加载到/system/etc/init,/vendor/etc/init, /odm/etc/init等目录,等init.rc解析完成后,会来解析这些目录中的rc文件,用来执行相关的动作
因为camera hal server 是因为用rc文件文件启动,接下来分析什么rc文件?
2、rc文件简介
android rc文件分析
具体分析在上面的链接中,现在简单分析下上图rc提到中的语法
service关键字声明了你要定义一个service,而servicehalserver就是这个service的名字,至于后面的目录则是这个service对应的可执行文件在系统中的位置。注意:这里是说在系统中的位置,也就是在开发板运行你的Android源码编译的系统后的目录,而不是源码的目录。本文位置在vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/下
定义为核心service,当main服务启动时,这个camerahalserver启动。
rc文件中使用Init进程启动camerahalserver,意思就是说在init进程中camerahalserver.rc文件如何加载以至于启动hal服务
3、camera hal service启动
下图是mt6873 Camera Server Init时序图(https://www.jianshu.com/p/22714702b7f2),其实和mt6765差不多,这块还是来简单疏通一下
当init进程加载camerahalserver.rc文件之后,
CameraHalService和Camera Hal Server.rc文件:
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/service.cpp
vendor/mediatek/proprietary/hardware/mtkcam/main/hal/service/camerahalserver.rc
这里简单说下 Camera Service 文件和cameraserver.rc文件
frameworks/av/services/camera/libcameraservice/CameraService.cpp
frameworks/av/camera/cameraserver/cameraserver.rc
在main函数中,先分析signal()的功用,见Signal ()函数用法和总结。从下图可以看到,signal函数在这块没有实际意义。继续溜代码...
1、Camera Hal Service通过registerPassthroughServiceImplementation()函数来向Camera Provider发起调用注册
main()中最后是joinRpcThreadpool(); // joinRpcThreadpool() 其实就是把主线程也放入线程池中等待请求,防止这个进程退出。
2、LegacySupport.h
在这里面做两件事:1、获取ICameraProvider接口类对象 2、将CameraProvider注册到ServiceManager
本地代码没有找到CameraProviderAll.cpp这个文件的Interface:: getService(),在这块就不继续贴图片。但是还是要Init过程的逻辑搞清楚。
3、“CameraProviderAll.cpp”这块有Interface:: getService()的实现
4、“mtkcam3.instance.cpp”也找不见。主要做的是创建CameraDeviceManager、Provider
5、“mtkcam3.instance.cpp” 主要做serarch sensor、new IMetadataProvider、createVirtualCameraDevice()、CameraDevice3、 CameraDevice3Session
6、“CameraProviderImpl.cpp”创建CameraProvider实例
7、“CameraProviderAll.cpp”调用LegacySupport.h中的registerAsService(
8、ServiceManagement.cpp
将provider以服务形式注册到HWServiceManager中,之后createCameraDevice3Session可以通过getService来获取该服务。
4、CameraService和CameraHalService之间联系
CameraService和Camerahalservice之间还有CameraProviderManager和ICameraProvider
我们都知道CameraService服务开始于:
1、frameworks/av/services/camera/libcameraservice/CameraService.cpp
CameraService::CameraService(){
ALOGI("CameraService started (pid=%d)", getpid());
}
-->
frameworks/av/services/camera/libcameraservice/CameraService.cpp
void CameraService::onFirstRef(){
ALOGI("CameraService process starting");
res = enumerateProviders();
}
-->
frameworks/av/services/camera/libcameraservice/CameraService.cpp
status_t CameraService::enumerateProviders() {
mCameraProviderManager = new CameraProviderManager();
res = mCameraProviderManager->initialize(this);
deviceIds = mCameraProviderManager->getCameraDeviceIds(); //这块回去获取device Id
}
-->
2、frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
status_t CameraProviderManager::ProviderInfo::initialize(
sp& interface,
hardware::hidl_bitfield currentDeviceState) {
ALOGI("Connecting to new camera provider: %s, isRemote? %d",
hardware::Return ret = interface->getCameraIdList([&status, this, &devices](
mIsRemote = interface->isRemote();
// cameraDeviceStatusChange callbacks may be called (and causing new devices added)
// before setCallback returns. setCallback must be called after addDevice so that
// the physical camera status callback can look up available regular
// cameras.
hardware::Return st = interface->setCallback(this);//这块就把ICameraProvider接口注册回调
}
-->
3、hardware/interfaces/camera/provider/2.4/ICameraProvider.hal
interface ICameraProvider {
setCallback(ICameraProviderCallback callback) generates (Status status);
getVendorTags() generates (Status status, vec sections);
getCameraIdList()
generates (Status status, vec cameraDeviceNames);
isSetTorchModeSupported() generates (Status status, bool support);
getCameraDeviceInterface_V1_x(string cameraDeviceName) generates
(Status status,
[email protected]::ICameraDevice device);
getCameraDeviceInterface_V3_x(string cameraDeviceName) generates
(Status status,
[email protected]::ICameraDevice device);
};
Camera Provider提供一个回调接口ICameraProvider,给Hal Provider来通知Framework异步相机事件,到这块Framework“接通”HAL
下面这块是HAL“接通” Framework,
1、定义一个接口ICameraDevice
hardware/interfaces/camera/device/3.2/ICameraDevice.hal
interface ICameraDevice {
getResourceCost() generates (Status status, CameraResourceCost resourceCost);
getCameraCharacteristics() generates
setTorchMode(TorchMode mode) generates (Status status);
open(ICameraDeviceCallback callback) generates
(Status status, ICameraDeviceSession session);
dumpState(handle fd);
};
2、frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
在MTK文档中Framework层在这块是以关联的形式“连接”ICameraDevice
#include
3、vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3Impl.cpp
Hal层继承ICameraDevice接口
CameraDevice3Impl::
CameraDevice3Impl(
ICameraDeviceManager* deviceManager,
IMetadataProvider* metadataProvider,
std::map>const& physicalMetadataProviders,
char const* deviceType,
int32_t instanceId,
int32_t virtualInstanceId
)
: ICameraDevice() //继承ICameraDevice接口
, mLogLevel(0)
, mDeviceManager(deviceManager)
, mStaticDeviceInfo(nullptr)
, mMetadataProvider(metadataProvider)
, mPhysicalMetadataProviders(physicalMetadataProviders)
, mMetadataConverter(IMetadataConverter::createInstance(IDefaultMetadataTagSet::singleton()->getTagSet()))
{
}
举个实现的例子
Return
CameraDevice3Impl::
getCameraCharacteristics(getCameraCharacteristics_cb _hidl_cb)
{
CameraMetadata cameraCharacteristics;
{
camera_metadata const* p_camera_metadata = mMetadataProvider->getStaticCharacteristics();
size_t size = mMetadataConverter->getCameraMetadataSize(p_camera_metadata);
cameraCharacteristics.setToExternal((uint8_t *)p_camera_metadata, size, false/*shouldOwn*/);
}
_hidl_cb(Status::OK, cameraCharacteristics);
return Void();
}
后面这些去操作camera
5、log
MTK 平台的log需要打开log开关,这个文档MTK_Camera_Introduction有具体介绍。
cameraServer 和camereahalServer服务在开机的时候已经启动,需要kill掉重启
×××××××/ # ps -d | grep camera
cameraserver 4144 1 88020 34736 binder_ioctl_write_read 0 S cameraserver
cameraserver 4145 1 11483128 151420 binder_ioctl_write_read 0 S camerahalserver
u0_a118 4971 504 14389020 108064 SyS_epoll_wait 0 S com.mediatek.camera
开启log之后,打开MTK 的driveronly版本的DebugLoggerUI 抓取log
6、结语
代码熟练度还不够溜,MTK Code细节不够火候,还需继续深入。我会不定期分享,以便查漏补缺,相互学习。奥里给!!!