slpi_proc/ssc/sensors/ams_tmd3702/build/sns_tmd3702.scons
一.配置文件:
if 'USES_SSC_STATIC_LIB_BUILDER' in env:
if 'SSC_TARGET_HEXAGON' in env['CPPDEFINES']:
env.AddSSCSU(inspect.getfile(inspect.currentframe()),
flavor = ["hexagon"],
register_func_name = "sns_register_tmd3702",
binary_lib = False,
add_island_files = tmd3702_island_enable,
diag_ssid = "MSG_SSID_SNS_SENSOR_EXT")
这里向系统注册了sns_register_tmd3702方法,该模块第一个被调用的方法是sns_register_tmd3702。
二:程序入口:
1.sensor 模块入口
前边说了sns_register_tmd3702是该模块第一个被调用的方法,我们接下来看一下为什么它是第一个被调用的方法。在SLPI目录下有一个ssc_static_lib_builder.py脚本,这个脚本负责解析sns_tmd3702.scons(xxx.scons)配置文件,并且自动生成对应的代码。在ssc_static_lib_builder.py里边,有个generate_static_sensor_list()函数,这个是构建静态注册的sensor list:
def generate_static_sensor_list(env, tags):
global static_sensors
if env.IsKeyEnable(tags) is True:
logger.info("generate_static_sensor_list() called with %d sensors" % len(static_sensors))
#dest = os.path.join(env.subst('${SSC_ROOT}'), 'framework', 'src')
#if not os.path.isdir(dest) or not os.listdir(dest):
# return None
if len(static_sensors) == 0:
logger.error("There are no static sensors?!!!")
return None
static_sensors_file = os.path.join(env.subst('${SSC_ROOT}'),
'framework', 'src', 'sns_static_sensors.c')
dirname = os.path.dirname(static_sensors_file)
if not os.path.exists(dirname):
os.makedirs(dirname)
fo = open(static_sensors_file, "w")
fo.write("/* Autogenerated file. Manual modification is pointless. */\n\n")
fo.write("#include \"sns_rc.h\"\n")
fo.write("#include \"sns_register.h\"\n")
fo.write("#include \"sns_types.h\"\n")
fo.write("\n")
for reg_func,reg_cnt in static_sensors:
fo.write("sns_rc %s(sns_register_cb const *register_api);\n" % reg_func)
fo.write("\nconst sns_register_entry sns_register_sensor_list[] =\n{\n")
reg_cnt_1 = -1
reg_cnt_2 = -1
reg_cnt_3 = -1
reg_cnt_4 = -1
reg_cnt_5 = -1
reg_cnt_6 = -1
....
这段代码主要就是解析我们的配置文件,然后把解析出来的内容写到sns_static_sensors.c,我们打开看一下(需要先编译生成文件):
/* Autogenerated file. Manual modification is pointless. */
#include "sns_rc.h"
#include "sns_register.h"
#include "sns_types.h"
sns_rc sns_register_suid_sensor(sns_register_cb const *register_api);
......
sns_rc sns_register_tmd3702(sns_register_cb const *register_api);
......
sns_rc sns_register_vl53l1(sns_register_cb const *register_api);
const sns_register_entry sns_register_sensor_list[] =
{
{ sns_register_suid_sensor, 1},
......
{ sns_register_tmd3702, 1},
......
{ sns_fusion_sensor_register, 1},
};
const uint32_t sns_register_sensor_list_len = ARR_SIZE(sns_register_sensor_list);
我们能看到我们之前配置的sns_register_tmd3702方法已经写到了sns_static_sensors.c文件中,后边会通过遍历sns_register_sensor_list来逐个初始化sensor。
2.SLPI调用sensor模块入口方法
高通开放给客户的入口方法是sns_user_pd_init.c中的sns_user_pd_init方法,我们就从这开始看一下:
sns_rc sns_user_pd_init()
{
......
//Map SDC TCM region
sns_sdc_init();
sns_osa_init();
sns_timer_init();
sns_fw_init(); //NO.1
sns_heap_init_delayed();
sns_init_done = true;
return SNS_RC_SUCCESS;
}
return SNS_RC_FAILED;
}
NO.1这里主要是去初始化framework:
int
sns_fw_init(void)
{
sns_rc rc;
SNS_PRINTF(LOW, sns_fw_printf, "Init started");
rc = sns_island_init();
SNS_ASSERT(SNS_RC_SUCCESS == rc);
rc = sns_thread_manager_init();
SNS_ASSERT(SNS_RC_SUCCESS == rc);
rc = sns_sensor_init_fw();
SNS_ASSERT(SNS_RC_SUCCESS == rc);
rc = sns_pwr_sleep_mgr_init();
SNS_ASSERT(SNS_RC_SUCCESS == rc);
rc = sns_pwr_scpm_mgr_init();
SNS_ASSERT(SNS_RC_SUCCESS == rc);
rc = sns_service_manager_init();
SNS_ASSERT(SNS_RC_SUCCESS == rc);
rc = sns_sensor_instance_init_fw();
SNS_ASSERT(SNS_RC_SUCCESS == rc);
rc = register_static_sensors(); //NO.1
SNS_ASSERT(SNS_RC_SUCCESS == rc);
SNS_PRINTF(LOW, sns_fw_printf, "Init Finished");
// Re-enable the thread manager; disabled by default in sns_thread_manager_init
sns_thread_manager_disable(false);
return 0;
}
NO.1调用了register_static_sensors方法,然后我们继续跟进到register_static_sensors方法中:
static sns_rc
register_static_sensors(void)
{
sns_register_cb reg_cb = (sns_register_cb)
{
.struct_len = sizeof(reg_cb),
.init_sensor = &sns_sensor_init
};
for(int i = 0; i < sns_register_sensor_list_len; i++)
{
SNS_PRINTF(LOW, sns_fw_printf, "Register Sensor from static list %i",
sns_register_sensor_list[i].cnt);
for(int j = 0; j < sns_register_sensor_list[i].cnt; j++)
{
sns_isafe_list_iter iter;
sns_sensor_library *library =
sns_sensor_library_init(sns_register_sensor_list[i].func, j);
sns_osa_lock_acquire(library->library_lock);
sns_register_sensor_list[i].func(®_cb); //NO.1
library->removing = SNS_LIBRARY_ACTIVE;
sns_sensor_library_start(library); //NO.2
sns_isafe_list_iter_init(&iter, &library->sensors, true);
if(0 == sns_isafe_list_iter_len(&iter))
{
sns_sensor_library_deinit(library);
sns_thread_manager_remove(library);
sns_osa_lock_release(library->library_lock);
sns_sensor_library_delete(library);
}
else
sns_osa_lock_release(library->library_lock);
}
}
return SNS_RC_SUCCESS;
}
NO.1会调用我们之前静态注册的sensor方法,例如tmd3702:
sns_tmd3702.scons配置的方法是sns_register_tmd3702,因此md3702模块第一个被调用的方法是sns_register_tmd3702。
NO.2会调用对应的的sns_sensor_api init方法,会在后边继续分析。