01 功能概述
本文的 demo sample 主要描述当前 camera 相关外设诊断的当前状态,并提供自定义实现的方法及使用说明。
1.1 软件架构说明
本 sample 基于现已实现的 camera 诊断架构,libcam 内的外设诊断功能对外设硬件状态进行监测,并支持将故障状态发送给 MCU 处理,或通过事件回调方式通知应用处理。
若打开诊断功能且使能诊断报告发送时,在 libcam.so 中会引用 libdiaglib.so 中的诊断发送 API,将诊断信息发送给 MCU,再由 MCU 侧进行处理。
若应用通过 API 注册了 camera 的事件回调处理函数,则会在故障状态变化时,通过该回调通知到应用进行处理。
Camera 外设诊断数据通路,默认支持应用注册的事件回调通知,但不发送诊断报告给 MCU,此处以 sample 形式提供,用户可根据实际项目或应用需要,进行定制,本文提供相应的定制使用说明。
1.2 诊断功能说明
Camera 外设诊断在 libcam 内实现,默认已实现了部分 Sensor/Serdes/Poc 设备的诊断功能,其在内部进行了诊断功能预定义,并以 diag_id 作为唯一识别索引,由诊断功能实现及实际硬件使用情况决定其值,可描述一个指定外设硬件的相应故障,关于其定义可参见: :ref:camera diag id。
此处定义的 camera 外设诊断,在 libcam 主体库中实现了框架,具体的外设诊断则由各 Sensor/Deserial 等子库定制实现:按主体框架的要求及外设功能安全手册描述,定义诊断 node 并向主体框架注册。
用户可根据实际应用需求,进行自定义定制开发与使用:
- 提供诊断功能的开关,默认打开状态,支持主动关闭诊断功能。
- 内部有默认的诊断信息隐射关系,可进行诊断信息的自定义诊断信息映射。
- 支持配置打开或关闭发送与回调功能。
1.3 代码位置与目录结构
API 流程说明
以下为 camera 诊断中相关的 API 调用流程:
此处的 :ref:hb_cam_set_event_callback 为可选调用,若应用需要处理 camera 诊断事件,可在初始化完成之后通过该 API 进行回调注册,之后在有故障发生或恢复时会通过该回调通知应用处理。
02 定制开发
本文中的 camera 外设诊断功能已在 libcam 库中实现,并默认打开编译集成,若有相应的定制需求,可参考下文进行开发。
2.1 诊断编译配置
该 camera 外设诊断功能由 libcam 中 Kconfig 的编译配置选项 HB_PKG_LIBCAM_DIAG 决定是否编译使能,其默认值为 y,集成使用,若需要关闭该功能可按下操作:
# 在配置文件(此处为默认,请按项目实际使用选择)中:
# horizon/j6/defconfig/j6e_debug_defconfig
# 默认为y,可配置n关闭编译集成:
export HB_PKG_LIBCAM_DIAG=n
在关闭该诊断功能之后,src/diag 目录中的代码则直接不会编译集成到 libcam 库中,关闭诊断功能不影响正常数据处理功能。
camera 的自恢复功能依赖诊断功能,若关闭诊断功能,则自恢复功能也将失效。
此处 libcam 中的诊断报告默认使用诊断 API 进行诊断状态报告,因此在应用集成时若编译报错,需注意对该 libdiaglib 库的引用。
LIBS += -ldiaglib
上述诊断报告的发送,可通过配置头文件 src/inc/private/cam_config.h 中的宏 CAM_CONFIG_LIBDIAG_EN 关闭:
/* #define CAM_CONFIG_LIBDIAG_EN */
注释该宏 CAM_CONFIG_LIBDIAG_EN 的定义即可关闭诊断发送功能,关闭后将不会发送诊断信息到 MCU,而由一行打印替代。
2.2 诊断信息映射
camera 诊断内部由 diag_id 唯一定义,在报告给 MCU 或用户时,可根据实际需要进行映射,将其转换为 module_id/event_id 进行报告。
目前内默认有一组映射关系,详见: :ref:诊断报告映射关系说明 。
该组默认的映射关系由 2 部分组成,用户可根据实际需要进行修改:按诊断类型定义了 module_id 的 BASE 值,定义在 src/diag/report/report.h 内:
#define CAM_DIAG_SERDES_BASE 0xC010u
#define CAM_DIAG_SENSOR_BASE 0xC000u
#define CAM_DIAG_POC_BASE 0xC020u
若要完全修改映射的对应关系,也可以直接修改 src/diag/report/report.c 内的 cam_diag_mapping() 函数实现,目前默认为:
int32_t cam_diag_mapping(uint32_t diag_id, cam_diag_map_s *map_info, void *spec_mapping)
{
uint16_t base_id = 0;
if (spec_mapping != NULL) {
vin_info("use spec mapping function\n");
return RET_OK;
}
/* modify those mapping code if need /
* /* user-defined mapping start /
* /* here is default camera diag mapping: diag_id -> module_id / event_id /
if (DIAG_DEVTYPE(diag_id) == (uint32_t)CAM_DES) {
base_id = CAM_DIAG_SERDES_BASE;
} else if (DIAG_DEVTYPE(diag_id) == (uint32_t)CAM_SNR) {
base_id = CAM_DIAG_SENSOR_BASE;
} else if (DIAG_DEVTYPE(diag_id) == (uint32_t)CAM_POC) {
ba